diff options
Diffstat (limited to 'src/OT/Layout')
-rw-r--r-- | src/OT/Layout/GDEF/GDEF.hh | 115 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/AnchorFormat3.hh | 23 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/AnchorMatrix.hh | 5 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/CursivePosFormat1.hh | 33 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/LigatureArray.hh | 13 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/MarkArray.hh | 6 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/MarkBasePosFormat1.hh | 15 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/MarkLigPosFormat1.hh | 19 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/MarkMarkPosFormat1.hh | 14 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/MarkRecord.hh | 11 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/PairPosFormat1.hh | 2 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/PairPosFormat2.hh | 4 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/PairValueRecord.hh | 1 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/Ligature.hh | 1 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/LigatureSet.hh | 19 |
15 files changed, 193 insertions, 88 deletions
diff --git a/src/OT/Layout/GDEF/GDEF.hh b/src/OT/Layout/GDEF/GDEF.hh index d995ba0d4..dd025c128 100644 --- a/src/OT/Layout/GDEF/GDEF.hh +++ b/src/OT/Layout/GDEF/GDEF.hh @@ -29,7 +29,7 @@ #ifndef OT_LAYOUT_GDEF_GDEF_HH #define OT_LAYOUT_GDEF_GDEF_HH -#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-var-common.hh" #include "../../../hb-font.hh" #include "../../../hb-cache.hh" @@ -204,17 +204,19 @@ struct CaretValueFormat3 if (!c->serializer->embed (coordinate)) return_trace (false); unsigned varidx = (this+deviceTable).get_variation_index (); - if (c->plan->layout_variation_idx_delta_map.has (varidx)) + hb_pair_t<unsigned, int> *new_varidx_delta; + if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) + return_trace (false); + + uint32_t new_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); + if (delta != 0) { - int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx)); - if (delta != 0) - { - if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); - } + if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); } - if (c->plan->all_axes_pinned) + if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); if (!c->serializer->embed (deviceTable)) @@ -439,6 +441,16 @@ struct MarkGlyphSetsFormat1 bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } + template <typename set_t> + void collect_coverage (hb_vector_t<set_t> &sets) const + { + for (const auto &offset : coverage) + { + const auto &cov = this+offset; + cov.collect_coverage (sets.push ()); + } + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -492,6 +504,15 @@ struct MarkGlyphSets } } + template <typename set_t> + void collect_coverage (hb_vector_t<set_t> &sets) const + { + switch (u.format) { + case 1: u.format1.collect_coverage (sets); return; + default:return; + } + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -583,6 +604,26 @@ struct GDEFVersion1_2 (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); } + static void remap_varidx_after_instantiation (const hb_map_t& varidx_map, + hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>>& layout_variation_idx_delta_map /* IN/OUT */) + { + /* varidx_map is empty which means varstore is empty after instantiation, + * no variations, map all varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX. + * varidx_map doesn't have original varidx, indicating delta row is all + * zeros, map varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ + for (auto _ : layout_variation_idx_delta_map.iter_ref ()) + { + /* old_varidx->(varidx, delta) mapping generated for subsetting, then this + * varidx is used as key of varidx_map during instantiation */ + uint32_t varidx = _.second.first; + uint32_t *new_varidx; + if (varidx_map.has (varidx, &new_varidx)) + _.second.first = *new_varidx; + else + _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + } + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -605,6 +646,22 @@ struct GDEFVersion1_2 { if (c->plan->all_axes_pinned) out->varStore = 0; + else if (c->plan->normalized_coords) + { + if (varStore) + { + item_variations_t item_vars; + if (item_vars.instantiate (this+varStore, c->plan, true, true, + c->plan->gdef_varstore_inner_maps.as_array ())) + subset_varstore = out->varStore.serialize_serialize (c->serializer, + item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ()); + remap_varidx_after_instantiation (item_vars.get_varidx_map (), + c->plan->layout_variation_idx_delta_map); + } + } else subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ()); } @@ -856,6 +913,10 @@ struct GDEF hb_blob_destroy (table.get_blob ()); table = hb_blob_get_empty (); } + +#ifndef HB_NO_GDEF_CACHE + table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests); +#endif } ~accelerator_t () { table.destroy (); } @@ -879,8 +940,18 @@ struct GDEF } + bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const + { + return +#ifndef HB_NO_GDEF_CACHE + mark_glyph_set_digests[set_index].may_have (glyph_id) && +#endif + table->mark_set_covers (set_index, glyph_id); + } + hb_blob_ptr_t<GDEF> table; #ifndef HB_NO_GDEF_CACHE + hb_vector_t<hb_set_digest_t> mark_glyph_set_digests; mutable hb_cache_t<21, 3, 8> glyph_props_cache; #endif }; @@ -889,17 +960,32 @@ struct GDEF { get_lig_caret_list ().collect_variation_indices (c); } void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, + const hb_vector_t<int>& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const { if (!has_var_store ()) return; - if (layout_variation_indices->is_empty ()) return; - + const VariationStore &var_store = get_var_store (); + float *store_cache = var_store.create_cache (); + unsigned new_major = 0, new_minor = 0; unsigned last_major = (layout_variation_indices->get_min ()) >> 16; for (unsigned idx : layout_variation_indices->iter ()) { + int delta = 0; + if (calculate_delta) + delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, + normalized_coords.length, store_cache)); + + if (no_variations) + { + layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); + continue; + } + uint16_t major = idx >> 16; - if (major >= get_var_store ().get_sub_table_count ()) break; + if (major >= var_store.get_sub_table_count ()) break; if (major != last_major) { new_minor = 0; @@ -907,14 +993,11 @@ struct GDEF } unsigned new_idx = (new_major << 16) + new_minor; - if (!layout_variation_idx_delta_map->has (idx)) - continue; - int delta = hb_second (layout_variation_idx_delta_map->get (idx)); - layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta)); ++new_minor; last_major = major; } + var_store.destroy_cache (store_cache); } protected: diff --git a/src/OT/Layout/GPOS/AnchorFormat3.hh b/src/OT/Layout/GPOS/AnchorFormat3.hh index 8684f60ca..56eda4a57 100644 --- a/src/OT/Layout/GPOS/AnchorFormat3.hh +++ b/src/OT/Layout/GPOS/AnchorFormat3.hh @@ -52,9 +52,14 @@ struct AnchorFormat3 if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false); unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; - if (c->plan->layout_variation_idx_delta_map.has (x_varidx)) + if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) { - int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx)); + hb_pair_t<unsigned, int> *new_varidx_delta; + if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta)) + return_trace (false); + + x_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); if (delta != 0) { if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta, @@ -64,9 +69,14 @@ struct AnchorFormat3 } unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; - if (c->plan->layout_variation_idx_delta_map.has (y_varidx)) + if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) { - int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx)); + hb_pair_t<unsigned, int> *new_varidx_delta; + if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta)) + return_trace (false); + + y_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); if (delta != 0) { if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta, @@ -75,7 +85,10 @@ struct AnchorFormat3 } } - if (c->plan->all_axes_pinned) + /* in case that all axes are pinned or no variations after instantiation, + * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ + if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX && + y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); if (!c->serializer->embed (xDeviceTable)) return_trace (false); diff --git a/src/OT/Layout/GPOS/AnchorMatrix.hh b/src/OT/Layout/GPOS/AnchorMatrix.hh index bd9b18973..37ba7916f 100644 --- a/src/OT/Layout/GPOS/AnchorMatrix.hh +++ b/src/OT/Layout/GPOS/AnchorMatrix.hh @@ -65,14 +65,15 @@ struct AnchorMatrix if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->rows = num_rows; + bool ret = false; for (const unsigned i : index_iter) { auto *offset = c->serializer->embed (matrixZ[i]); if (!offset) return_trace (false); - offset->serialize_subset (c, matrixZ[i], this); + ret |= offset->serialize_subset (c, matrixZ[i], this); } - return_trace (true); + return_trace (ret); } }; diff --git a/src/OT/Layout/GPOS/CursivePosFormat1.hh b/src/OT/Layout/GPOS/CursivePosFormat1.hh index a459124df..7c42c3f77 100644 --- a/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -24,16 +24,17 @@ struct EntryExitRecord (src_base+exitAnchor).collect_variation_indices (c); } - EntryExitRecord* subset (hb_subset_context_t *c, - const void *src_base) const + bool subset (hb_subset_context_t *c, + const void *src_base) const { TRACE_SERIALIZE (this); auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (nullptr); + if (unlikely (!out)) return_trace (false); - out->entryAnchor.serialize_subset (c, entryAnchor, src_base); - out->exitAnchor.serialize_subset (c, exitAnchor, src_base); - return_trace (out); + bool ret = false; + ret |= out->entryAnchor.serialize_subset (c, entryAnchor, src_base); + ret |= out->exitAnchor.serialize_subset (c, exitAnchor, src_base); + return_trace (ret); } protected: @@ -91,7 +92,13 @@ struct CursivePosFormat1 bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); + if (unlikely (!coverage.sanitize (c, this))) + return_trace (false); + + if (c->lazy_some_gpos) + return_trace (entryExitRecord.sanitize_shallow (c)); + else + return_trace (entryExitRecord.sanitize (c, this)); } bool intersects (const hb_set_t *glyphs) const @@ -119,10 +126,11 @@ struct CursivePosFormat1 hb_buffer_t *buffer = c->buffer; const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; - if (!this_record.entryAnchor) return_trace (false); + if (!this_record.entryAnchor || + unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; - skippy_iter.reset_fast (buffer->idx, 1); + skippy_iter.reset_fast (buffer->idx); unsigned unsafe_from; if (unlikely (!skippy_iter.prev (&unsafe_from))) { @@ -131,7 +139,8 @@ struct CursivePosFormat1 } const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; - if (!prev_record.exitAnchor) + if (!prev_record.exitAnchor || + unlikely (!prev_record.exitAnchor.sanitize (&c->sanitizer, this))) { buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); return_trace (false); @@ -200,8 +209,8 @@ struct CursivePosFormat1 * Arabic. */ unsigned int child = i; unsigned int parent = j; - hb_position_t x_offset = entry_x - exit_x; - hb_position_t y_offset = entry_y - exit_y; + hb_position_t x_offset = roundf (entry_x - exit_x); + hb_position_t y_offset = roundf (entry_y - exit_y); if (!(c->lookup_props & LookupFlag::RightToLeft)) { unsigned int k = child; diff --git a/src/OT/Layout/GPOS/LigatureArray.hh b/src/OT/Layout/GPOS/LigatureArray.hh index a2d807cc3..59cca40aa 100644 --- a/src/OT/Layout/GPOS/LigatureArray.hh +++ b/src/OT/Layout/GPOS/LigatureArray.hh @@ -27,6 +27,7 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach> auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + bool ret = false; for (const auto _ : + hb_zip (coverage, *this) | hb_filter (glyphset, hb_first)) { @@ -38,13 +39,13 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach> + hb_range (src.rows * class_count) | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) ; - matrix->serialize_subset (c, - _.second, - this, - src.rows, - indexes); + ret |= matrix->serialize_subset (c, + _.second, + this, + src.rows, + indexes); } - return_trace (this->len); + return_trace (ret); } }; diff --git a/src/OT/Layout/GPOS/MarkArray.hh b/src/OT/Layout/GPOS/MarkArray.hh index 34e2ab8f6..0887cc158 100644 --- a/src/OT/Layout/GPOS/MarkArray.hh +++ b/src/OT/Layout/GPOS/MarkArray.hh @@ -82,10 +82,10 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove | hb_map (hb_second) ; + bool ret = false; unsigned new_length = 0; for (const auto& mark_record : mark_iter) { - if (unlikely (!mark_record.subset (c, this, klass_mapping))) - return_trace (false); + ret |= mark_record.subset (c, this, klass_mapping); new_length++; } @@ -93,7 +93,7 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return_trace (false); - return_trace (true); + return_trace (ret); } }; diff --git a/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/src/OT/Layout/GPOS/MarkBasePosFormat1.hh index eb4712049..1b8f3c80a 100644 --- a/src/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/src/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -197,9 +197,10 @@ struct MarkBasePosFormat1_2 if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); - out->markArray.serialize_subset (c, markArray, this, - (this+markCoverage).iter (), - &klass_mapping); + if (unlikely (!out->markArray.serialize_subset (c, markArray, this, + (this+markCoverage).iter (), + &klass_mapping))) + return_trace (false); unsigned basecount = (this+baseArray).rows; auto base_iter = @@ -228,11 +229,9 @@ struct MarkBasePosFormat1_2 ; } - out->baseArray.serialize_subset (c, baseArray, this, - base_iter.len (), - base_indexes.iter ()); - - return_trace (true); + return_trace (out->baseArray.serialize_subset (c, baseArray, this, + base_iter.len (), + base_indexes.iter ())); } }; diff --git a/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/src/OT/Layout/GPOS/MarkLigPosFormat1.hh index 92e83a0e9..d6bee277c 100644 --- a/src/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/src/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -169,7 +169,7 @@ struct MarkLigPosFormat1_2 { TRACE_SUBSET (this); const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; + const hb_map_t &glyph_map = c->plan->glyph_map_gsub; auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); @@ -195,23 +195,24 @@ struct MarkLigPosFormat1_2 if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage)) return_trace (false); - out->markArray.serialize_subset (c, markArray, this, - (this+markCoverage).iter (), - &klass_mapping); + if (unlikely (!out->markArray.serialize_subset (c, markArray, this, + (this+markCoverage).iter (), + &klass_mapping))) + return_trace (false); auto new_ligature_coverage = + hb_iter (this + ligatureCoverage) - | hb_filter (glyphset) + | hb_take ((this + ligatureArray).len) | hb_map_retains_sorting (glyph_map) + | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; }) ; if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage)) return_trace (false); - out->ligatureArray.serialize_subset (c, ligatureArray, this, - hb_iter (this+ligatureCoverage), classCount, &klass_mapping); - - return_trace (true); + return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), + classCount, &klass_mapping)); } }; diff --git a/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index 9dae5ce5d..70cf07166 100644 --- a/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -100,7 +100,7 @@ struct MarkMarkPosFormat1_2 /* now we search backwards for a suitable mark glyph until a non-mark glyph */ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; - skippy_iter.reset_fast (buffer->idx, 1); + skippy_iter.reset_fast (buffer->idx); skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); unsigned unsafe_from; if (unlikely (!skippy_iter.prev (&unsafe_from))) @@ -183,9 +183,10 @@ struct MarkMarkPosFormat1_2 if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); - out->mark1Array.serialize_subset (c, mark1Array, this, - (this+mark1Coverage).iter (), - &klass_mapping); + if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this, + (this+mark1Coverage).iter (), + &klass_mapping))) + return_trace (false); unsigned mark2count = (this+mark2Array).rows; auto mark2_iter = @@ -214,9 +215,10 @@ struct MarkMarkPosFormat1_2 ; } - out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ()); + return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, + mark2_iter.len (), + mark2_indexes.iter ())); - return_trace (true); } }; diff --git a/src/OT/Layout/GPOS/MarkRecord.hh b/src/OT/Layout/GPOS/MarkRecord.hh index a7d489d2a..3d11c7773 100644 --- a/src/OT/Layout/GPOS/MarkRecord.hh +++ b/src/OT/Layout/GPOS/MarkRecord.hh @@ -24,17 +24,16 @@ struct MarkRecord return_trace (c->check_struct (this) && markAnchor.sanitize (c, base)); } - MarkRecord *subset (hb_subset_context_t *c, - const void *src_base, - const hb_map_t *klass_mapping) const + bool subset (hb_subset_context_t *c, + const void *src_base, + const hb_map_t *klass_mapping) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (nullptr); + if (unlikely (!out)) return_trace (false); out->klass = klass_mapping->get (klass); - out->markAnchor.serialize_subset (c, markAnchor, src_base); - return_trace (out); + return_trace (out->markAnchor.serialize_subset (c, markAnchor, src_base)); } void collect_variation_indices (hb_collect_variation_indices_context_t *c, diff --git a/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/OT/Layout/GPOS/PairPosFormat1.hh index 714b4bec7..e4a2006fb 100644 --- a/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -110,7 +110,7 @@ struct PairPosFormat1_3 if (likely (index == NOT_COVERED)) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; - skippy_iter.reset_fast (buffer->idx, 1); + skippy_iter.reset_fast (buffer->idx); unsigned unsafe_to; if (unlikely (!skippy_iter.next (&unsafe_to))) { diff --git a/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/OT/Layout/GPOS/PairPosFormat2.hh index 05e6c0fa5..4adb1ef60 100644 --- a/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -131,7 +131,7 @@ struct PairPosFormat2_4 if (likely (index == NOT_COVERED)) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; - skippy_iter.reset_fast (buffer->idx, 1); + skippy_iter.reset_fast (buffer->idx); unsigned unsafe_to; if (unlikely (!skippy_iter.next (&unsafe_to))) { @@ -163,7 +163,7 @@ struct PairPosFormat2_4 /* Isolate simple kerning and apply it half to each side. - * Results in better cursor positinoing / underline drawing. + * Results in better cursor positioning / underline drawing. * * Disabled, because causes issues... :-( * https://github.com/harfbuzz/harfbuzz/issues/3408 diff --git a/src/OT/Layout/GPOS/PairValueRecord.hh b/src/OT/Layout/GPOS/PairValueRecord.hh index c99a38699..72bf0e99b 100644 --- a/src/OT/Layout/GPOS/PairValueRecord.hh +++ b/src/OT/Layout/GPOS/PairValueRecord.hh @@ -23,7 +23,6 @@ struct PairValueRecord * followed by for second glyph */ public: DEFINE_SIZE_ARRAY (Types::HBGlyphID::static_size, values); - DEFINE_SIZE_MAX (Types::HBGlyphID::static_size + 2 * Value::static_size * 8 * sizeof (ValueFormat)); int cmp (hb_codepoint_t k) const { return secondGlyph.cmp (k); } diff --git a/src/OT/Layout/GSUB/Ligature.hh b/src/OT/Layout/GSUB/Ligature.hh index db3fc55f7..402ed12ae 100644 --- a/src/OT/Layout/GSUB/Ligature.hh +++ b/src/OT/Layout/GSUB/Ligature.hh @@ -19,7 +19,6 @@ struct Ligature * in writing direction */ public: DEFINE_SIZE_ARRAY (Types::size + 2, component); - DEFINE_SIZE_MAX (65536 * Types::HBGlyphID::static_size); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/src/OT/Layout/GSUB/LigatureSet.hh b/src/OT/Layout/GSUB/LigatureSet.hh index 0ba262e90..08665438c 100644 --- a/src/OT/Layout/GSUB/LigatureSet.hh +++ b/src/OT/Layout/GSUB/LigatureSet.hh @@ -72,19 +72,14 @@ struct LigatureSet ; } - static bool match_always (hb_glyph_info_t &info HB_UNUSED, unsigned value HB_UNUSED, const void *data HB_UNUSED) - { - return true; - } - bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int num_ligs = ligature.len; -#ifndef HB_NO_OT_LIGATURES_FAST_PATH - if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 2) +#ifndef HB_NO_OT_RULESETS_FAST_PATH + if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4) #endif { slow: @@ -97,10 +92,12 @@ struct LigatureSet } /* This version is optimized for speed by matching the first component - * of the ligature here, instead of calling into the ligation code. */ + * of the ligature here, instead of calling into the ligation code. + * + * This is replicated in ChainRuleSet and RuleSet. */ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; - skippy_iter.reset (c->buffer->idx, 1); + skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); unsigned unsafe_to; @@ -118,6 +115,8 @@ struct LigatureSet goto slow; } } + else + goto slow; bool unsafe_to_concat = false; @@ -125,7 +124,7 @@ struct LigatureSet { const auto &lig = this+ligature.arrayZ[i]; if (unlikely (lig.component.lenP1 <= 1) || - lig.component[1] == first) + lig.component.arrayZ[0] == first) { if (lig.apply (c)) { |