diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh | 523 |
1 files changed, 246 insertions, 277 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh index cc10634759b..0e1966e98e8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh @@ -34,10 +34,12 @@ namespace OT { +typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t; +template<typename Iterator> static inline void SingleSubst_serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, - hb_array_t<const GlyphID> substitutes); + Iterator it); + struct SingleSubstFormat1 { @@ -46,35 +48,28 @@ struct SingleSubstFormat1 void closure (hb_closure_context_t *c) const { - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - /* TODO Switch to range-based API to work around malicious fonts. - * https://github.com/harfbuzz/harfbuzz/issues/363 */ - hb_codepoint_t glyph_id = iter.get_glyph (); - if (c->glyphs->has (glyph_id)) - c->out->add ((glyph_id + deltaGlyphID) & 0xFFFFu); - } + unsigned d = deltaGlyphID; + + hb_iter (this+coverage) + | hb_filter (*c->glyphs) + | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) + | hb_sink (c->output) + ; } void collect_glyphs (hb_collect_glyphs_context_t *c) const { if (unlikely (!(this+coverage).add_coverage (c->input))) return; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - /* TODO Switch to range-based API to work around malicious fonts. - * https://github.com/harfbuzz/harfbuzz/issues/363 */ - hb_codepoint_t glyph_id = iter.get_glyph (); - c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu); - } + unsigned d = deltaGlyphID; + + hb_iter (this+coverage) + | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) + | hb_sink (c->output) + ; } const Coverage &get_coverage () const { return this+coverage; } bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); - return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } + { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } bool apply (hb_ot_apply_context_t *c) const { @@ -91,34 +86,39 @@ struct SingleSubstFormat1 return_trace (true); } + template<typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, + hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, - int delta) + Iterator glyphs, + unsigned delta) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false); - deltaGlyphID.set (delta); /* TODO(serialize) overflow? */ + c->check_assign (deltaGlyphID, delta); return_trace (true); } bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - hb_vector_t<GlyphID> from; - hb_vector_t<GlyphID> to; + hb_codepoint_t delta = deltaGlyphID; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (!glyphset.has (iter.get_glyph ())) continue; - from.push ()->set (glyph_map[iter.get_glyph ()]); - to.push ()->set (glyph_map[(iter.get_glyph () + delta) & 0xFFFF]); - } - c->serializer->propagate_error (from, to); - SingleSubst_serialize (c->serializer, from, to); - return_trace (from.length); + + auto it = + + hb_iter (this+coverage) + | hb_filter (glyphset) + | hb_map_retains_sorting ([&] (hb_codepoint_t g) { + return hb_codepoint_pair_t (glyph_map[g], + glyph_map[(g + delta) & 0xFFFF]); }) + ; + + bool ret = bool (it); + SingleSubst_serialize (c->serializer, it); + return_trace (ret); } bool sanitize (hb_sanitize_context_t *c) const @@ -132,8 +132,8 @@ struct SingleSubstFormat1 OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - HBINT16 deltaGlyphID; /* Add to original GlyphID to get - * substitute GlyphID */ + HBUINT16 deltaGlyphID; /* Add to original GlyphID to get + * substitute GlyphID, modulo 0x10000 */ public: DEFINE_SIZE_STATIC (6); }; @@ -145,35 +145,26 @@ struct SingleSubstFormat2 void closure (hb_closure_context_t *c) const { - unsigned int count = substitute.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - if (c->glyphs->has (iter.get_glyph ())) - c->out->add (substitute[iter.get_coverage ()]); - } + + hb_zip (this+coverage, substitute) + | hb_filter (*c->glyphs, hb_first) + | hb_map (hb_second) + | hb_sink (c->output) + ; } void collect_glyphs (hb_collect_glyphs_context_t *c) const { if (unlikely (!(this+coverage).add_coverage (c->input))) return; - unsigned int count = substitute.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - c->output->add (substitute[iter.get_coverage ()]); - } + + hb_zip (this+coverage, substitute) + | hb_map (hb_second) + | hb_sink (c->output) + ; } const Coverage &get_coverage () const { return this+coverage; } bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); - return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } + { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } bool apply (hb_ot_apply_context_t *c) const { @@ -188,11 +179,21 @@ struct SingleSubstFormat2 return_trace (true); } + template<typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, + const hb_codepoint_pair_t))> bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, - hb_array_t<const GlyphID> substitutes) + Iterator it) { TRACE_SERIALIZE (this); + auto substitutes = + + it + | hb_map (hb_second) + ; + auto glyphs = + + it + | hb_map_retains_sorting (hb_first) + ; if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false); if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false); @@ -202,19 +203,19 @@ struct SingleSubstFormat2 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - hb_vector_t<GlyphID> from; - hb_vector_t<GlyphID> to; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (!glyphset.has (iter.get_glyph ())) continue; - from.push ()->set (glyph_map[iter.get_glyph ()]); - to.push ()->set (glyph_map[substitute[iter.get_coverage ()]]); - } - c->serializer->propagate_error (from, to); - SingleSubst_serialize (c->serializer, from, to); - return_trace (from.length); + + auto it = + + hb_zip (this+coverage, substitute) + | hb_filter (glyphset, hb_first) + | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const GlyphID &> p) -> hb_codepoint_pair_t + { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) + ; + + bool ret = bool (it); + SingleSubst_serialize (c->serializer, it); + return_trace (ret); } bool sanitize (hb_sanitize_context_t *c) const @@ -237,41 +238,45 @@ struct SingleSubstFormat2 struct SingleSubst { + + template<typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, + const hb_codepoint_pair_t))> bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, - hb_array_t<const GlyphID> substitutes) + Iterator glyphs) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); - unsigned int format = 2; - int delta = 0; - if (glyphs.length) + unsigned format = 2; + unsigned delta = 0; + if (glyphs.len ()) { format = 1; - /* TODO(serialize) check for wrap-around */ - delta = substitutes[0] - glyphs[0]; - for (unsigned int i = 1; i < glyphs.length; i++) - if (delta != (int) (substitutes[i] - glyphs[i])) { - format = 2; - break; - } + auto get_delta = [=] (hb_codepoint_pair_t _) { + return (unsigned) (_.second - _.first) & 0xFFFF; + }; + delta = get_delta (*glyphs); + if (!hb_all (++(+glyphs), delta, get_delta)) format = 2; } - u.format.set (format); + u.format = format; switch (u.format) { - case 1: return_trace (u.format1.serialize (c, glyphs, delta)); - case 2: return_trace (u.format2.serialize (c, glyphs, substitutes)); + case 1: return_trace (u.format1.serialize (c, + + glyphs + | hb_map_retains_sorting (hb_first), + delta)); + case 2: return_trace (u.format2.serialize (c, glyphs)); default:return_trace (false); } } - template <typename context_t> - typename context_t::return_t dispatch (context_t *c) const + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); - case 2: return_trace (c->dispatch (u.format2)); + case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -284,11 +289,11 @@ struct SingleSubst } u; }; +template<typename Iterator> static inline void SingleSubst_serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, - hb_array_t<const GlyphID> substitutes) -{ c->start_embed<SingleSubst> ()->serialize (c, glyphs, substitutes); } + Iterator it) +{ c->start_embed<SingleSubst> ()->serialize (c, it); } struct Sequence { @@ -296,7 +301,7 @@ struct Sequence { unsigned int count = substitute.len; for (unsigned int i = 0; i < count; i++) - c->out->add (substitute[i]); + c->output->add (substitute[i]); } void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -335,10 +340,10 @@ struct Sequence } bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs) + hb_array_t<const GlyphID> subst) { TRACE_SERIALIZE (this); - return_trace (substitute.serialize (c, glyphs)); + return_trace (substitute.serialize (c, subst)); } bool sanitize (hb_sanitize_context_t *c) const @@ -361,31 +366,28 @@ struct MultipleSubstFormat1 void closure (hb_closure_context_t *c) const { - unsigned int count = sequence.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - if (c->glyphs->has (iter.get_glyph ())) - (this+sequence[iter.get_coverage ()]).closure (c); - } + + hb_zip (this+coverage, sequence) + | hb_filter (*c->glyphs, hb_first) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([c] (const Sequence &_) { _.closure (c); }) + ; } void collect_glyphs (hb_collect_glyphs_context_t *c) const { if (unlikely (!(this+coverage).add_coverage (c->input))) return; - unsigned int count = sequence.len; - for (unsigned int i = 0; i < count; i++) - (this+sequence[i]).collect_glyphs (c); + + hb_zip (this+coverage, sequence) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); }) + ; } const Coverage &get_coverage () const { return this+coverage; } bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); - return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } + { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } bool apply (hb_ot_apply_context_t *c) const { @@ -398,7 +400,7 @@ struct MultipleSubstFormat1 } bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, + hb_sorted_array_t<const GlyphID> glyphs, hb_array_t<const unsigned int> substitute_len_list, hb_array_t<const GlyphID> substitute_glyphs_list) { @@ -444,27 +446,27 @@ struct MultipleSubstFormat1 struct MultipleSubst { bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, + hb_sorted_array_t<const GlyphID> glyphs, hb_array_t<const unsigned int> substitute_len_list, hb_array_t<const GlyphID> substitute_glyphs_list) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); unsigned int format = 1; - u.format.set (format); + u.format = format; switch (u.format) { case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, substitute_glyphs_list)); default:return_trace (false); } } - template <typename context_t> - typename context_t::return_t dispatch (context_t *c) const + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -482,7 +484,7 @@ struct AlternateSet { unsigned int count = alternates.len; for (unsigned int i = 0; i < count; i++) - c->out->add (alternates[i]); + c->output->add (alternates[i]); } void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -502,7 +504,7 @@ struct AlternateSet unsigned int shift = hb_ctz (lookup_mask); unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift); - /* If alt_index is MAX, randomize feature if it is the rand feature. */ + /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */ if (alt_index == HB_OT_MAP_MAX_VALUE && c->random) alt_index = c->random_number () % count + 1; @@ -514,10 +516,10 @@ struct AlternateSet } bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs) + hb_array_t<const GlyphID> alts) { TRACE_SERIALIZE (this); - return_trace (alternates.serialize (c, glyphs)); + return_trace (alternates.serialize (c, alts)); } bool sanitize (hb_sanitize_context_t *c) const @@ -541,35 +543,27 @@ struct AlternateSubstFormat1 void closure (hb_closure_context_t *c) const { - unsigned int count = alternateSet.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - if (c->glyphs->has (iter.get_glyph ())) - (this+alternateSet[iter.get_coverage ()]).closure (c); - } + + hb_zip (this+coverage, alternateSet) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([c] (const AlternateSet &_) { _.closure (c); }) + ; } void collect_glyphs (hb_collect_glyphs_context_t *c) const { if (unlikely (!(this+coverage).add_coverage (c->input))) return; - unsigned int count = alternateSet.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - (this+alternateSet[iter.get_coverage ()]).collect_glyphs (c); - } + + hb_zip (this+coverage, alternateSet) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); }) + ; } const Coverage &get_coverage () const { return this+coverage; } bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); - return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } + { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } bool apply (hb_ot_apply_context_t *c) const { @@ -582,7 +576,7 @@ struct AlternateSubstFormat1 } bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, + hb_sorted_array_t<const GlyphID> glyphs, hb_array_t<const unsigned int> alternate_len_list, hb_array_t<const GlyphID> alternate_glyphs_list) { @@ -628,27 +622,27 @@ struct AlternateSubstFormat1 struct AlternateSubst { bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> glyphs, + hb_sorted_array_t<const GlyphID> glyphs, hb_array_t<const unsigned int> alternate_len_list, hb_array_t<const GlyphID> alternate_glyphs_list) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); unsigned int format = 1; - u.format.set (format); + u.format = format; switch (u.format) { case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list)); default:return_trace (false); } } - template <typename context_t> - typename context_t::return_t dispatch (context_t *c) const + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -668,17 +662,14 @@ struct Ligature unsigned int count = component.lenP1; for (unsigned int i = 1; i < count; i++) if (!glyphs->has (component[i])) - return false; + return false; return true; } void closure (hb_closure_context_t *c) const { - unsigned int count = component.lenP1; - for (unsigned int i = 1; i < count; i++) - if (!c->glyphs->has (component[i])) - return; - c->out->add (ligGlyph); + if (!intersects (c->glyphs)) return; + c->output->add (ligGlyph); } void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -689,15 +680,14 @@ struct Ligature bool would_apply (hb_would_apply_context_t *c) const { - TRACE_WOULD_APPLY (this); if (c->len != component.lenP1) - return_trace (false); + return false; for (unsigned int i = 1; i < c->len; i++) if (likely (c->glyphs[i] != component[i])) - return_trace (false); + return false; - return_trace (true); + return true; } bool apply (hb_ot_apply_context_t *c) const @@ -771,38 +761,38 @@ struct LigatureSet { bool intersects (const hb_set_t *glyphs) const { - unsigned int num_ligs = ligature.len; - for (unsigned int i = 0; i < num_ligs; i++) - if ((this+ligature[i]).intersects (glyphs)) - return true; - return false; + return + + hb_iter (ligature) + | hb_map (hb_add (this)) + | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); }) + | hb_any + ; } void closure (hb_closure_context_t *c) const { - unsigned int num_ligs = ligature.len; - for (unsigned int i = 0; i < num_ligs; i++) - (this+ligature[i]).closure (c); + + hb_iter (ligature) + | hb_map (hb_add (this)) + | hb_apply ([c] (const Ligature &_) { _.closure (c); }) + ; } void collect_glyphs (hb_collect_glyphs_context_t *c) const { - unsigned int num_ligs = ligature.len; - for (unsigned int i = 0; i < num_ligs; i++) - (this+ligature[i]).collect_glyphs (c); + + hb_iter (ligature) + | hb_map (hb_add (this)) + | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); }) + ; } bool would_apply (hb_would_apply_context_t *c) const { - TRACE_WOULD_APPLY (this); - unsigned int num_ligs = ligature.len; - for (unsigned int i = 0; i < num_ligs; i++) - { - const Ligature &lig = this+ligature[i]; - if (lig.would_apply (c)) - return_trace (true); - } - return_trace (false); + return + + hb_iter (ligature) + | hb_map (hb_add (this)) + | hb_map ([c] (const Ligature &_) { return _.would_apply (c); }) + | hb_any + ; } bool apply (hb_ot_apply_context_t *c) const @@ -828,7 +818,7 @@ struct LigatureSet if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false); for (unsigned int i = 0; i < ligatures.length; i++) { - unsigned int component_count = MAX<int> (component_count_list[i] - 1, 0); + unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0); if (unlikely (!ligature[i].serialize (c, this) .serialize (c, ligatures[i], @@ -857,52 +847,46 @@ struct LigatureSubstFormat1 { bool intersects (const hb_set_t *glyphs) const { - unsigned int count = ligatureSet.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - if (glyphs->has (iter.get_glyph ()) && - (this+ligatureSet[iter.get_coverage ()]).intersects (glyphs)) - return true; - } - return false; + return + + hb_zip (this+coverage, ligatureSet) + | hb_filter (*glyphs, hb_first) + | hb_map (hb_second) + | hb_map ([this, glyphs] (const OffsetTo<LigatureSet> &_) + { return (this+_).intersects (glyphs); }) + | hb_any + ; } void closure (hb_closure_context_t *c) const { - unsigned int count = ligatureSet.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - if (c->glyphs->has (iter.get_glyph ())) - (this+ligatureSet[iter.get_coverage ()]).closure (c); - } + + hb_zip (this+coverage, ligatureSet) + | hb_filter (*c->glyphs, hb_first) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([c] (const LigatureSet &_) { _.closure (c); }) + ; } void collect_glyphs (hb_collect_glyphs_context_t *c) const { if (unlikely (!(this+coverage).add_coverage (c->input))) return; - unsigned int count = ligatureSet.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c); - } + + + hb_zip (this+coverage, ligatureSet) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); }) + ; } const Coverage &get_coverage () const { return this+coverage; } bool would_apply (hb_would_apply_context_t *c) const { - TRACE_WOULD_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->glyphs[0]); - if (likely (index == NOT_COVERED)) return_trace (false); + if (likely (index == NOT_COVERED)) return false; const LigatureSet &lig_set = this+ligatureSet[index]; - return_trace (lig_set.would_apply (c)); + return lig_set.would_apply (c); } bool apply (hb_ot_apply_context_t *c) const @@ -917,7 +901,7 @@ struct LigatureSubstFormat1 } bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> first_glyphs, + hb_sorted_array_t<const GlyphID> first_glyphs, hb_array_t<const unsigned int> ligature_per_first_glyph_count_list, hb_array_t<const GlyphID> ligatures_list, hb_array_t<const unsigned int> component_count_list, @@ -968,7 +952,7 @@ struct LigatureSubstFormat1 struct LigatureSubst { bool serialize (hb_serialize_context_t *c, - hb_array_t<const GlyphID> first_glyphs, + hb_sorted_array_t<const GlyphID> first_glyphs, hb_array_t<const unsigned int> ligature_per_first_glyph_count_list, hb_array_t<const GlyphID> ligatures_list, hb_array_t<const unsigned int> component_count_list, @@ -977,7 +961,7 @@ struct LigatureSubst TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); unsigned int format = 1; - u.format.set (format); + u.format = format; switch (u.format) { case 1: return_trace (u.format1.serialize (c, first_glyphs, @@ -989,13 +973,13 @@ struct LigatureSubst } } - template <typename context_t> - typename context_t::return_t dispatch (context_t *c) const + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1027,48 +1011,35 @@ struct ReverseChainSingleSubstFormat1 if (!(this+coverage).intersects (glyphs)) return false; - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); unsigned int count; count = backtrack.len; for (unsigned int i = 0; i < count; i++) if (!(this+backtrack[i]).intersects (glyphs)) - return false; + return false; count = lookahead.len; for (unsigned int i = 0; i < count; i++) if (!(this+lookahead[i]).intersects (glyphs)) - return false; + return false; return true; } void closure (hb_closure_context_t *c) const { - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); + if (!intersects (c->glyphs)) return; - unsigned int count; + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead); - count = backtrack.len; - for (unsigned int i = 0; i < count; i++) - if (!(this+backtrack[i]).intersects (c->glyphs)) - return; - - count = lookahead.len; - for (unsigned int i = 0; i < count; i++) - if (!(this+lookahead[i]).intersects (c->glyphs)) - return; - - const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); - count = substitute.len; - for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) - { - if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ - if (c->glyphs->has (iter.get_glyph ())) - c->out->add (substitute[iter.get_coverage ()]); - } + + hb_zip (this+coverage, substitute) + | hb_filter (*c->glyphs, hb_first) + | hb_map (hb_second) + | hb_sink (c->output) + ; } void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -1081,12 +1052,12 @@ struct ReverseChainSingleSubstFormat1 for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return; - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); count = lookahead.len; for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return; - const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); + const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead); count = substitute.len; c->output->add_array (substitute.arrayZ, substitute.len); } @@ -1094,10 +1065,7 @@ struct ReverseChainSingleSubstFormat1 const Coverage &get_coverage () const { return this+coverage; } bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); - return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } + { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } bool apply (hb_ot_apply_context_t *c) const { @@ -1108,15 +1076,15 @@ struct ReverseChainSingleSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); - const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead); unsigned int start_index = 0, end_index = 0; if (match_backtrack (c, backtrack.len, (HBUINT16 *) backtrack.arrayZ, match_coverage, this, &start_index) && - match_lookahead (c, + match_lookahead (c, lookahead.len, (HBUINT16 *) lookahead.arrayZ, match_coverage, this, 1, &end_index)) @@ -1144,10 +1112,10 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); - const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); + const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead); return_trace (substitute.sanitize (c)); } @@ -1173,13 +1141,13 @@ struct ReverseChainSingleSubstFormat1 struct ReverseChainSingleSubst { - template <typename context_t> - typename context_t::return_t dispatch (context_t *c) const + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1213,19 +1181,19 @@ struct SubstLookupSubTable ReverseChainSingle = 8 }; - template <typename context_t> - typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const { TRACE_DISPATCH (this, lookup_type); switch (lookup_type) { - case Single: return_trace (u.single.dispatch (c)); - case Multiple: return_trace (u.multiple.dispatch (c)); - case Alternate: return_trace (u.alternate.dispatch (c)); - case Ligature: return_trace (u.ligature.dispatch (c)); - case Context: return_trace (u.context.dispatch (c)); - case ChainContext: return_trace (u.chainContext.dispatch (c)); - case Extension: return_trace (u.extension.dispatch (c)); - case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c)); + case Single: return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...)); + case Multiple: return_trace (u.multiple.dispatch (c, hb_forward<Ts> (ds)...)); + case Alternate: return_trace (u.alternate.dispatch (c, hb_forward<Ts> (ds)...)); + case Ligature: return_trace (u.ligature.dispatch (c, hb_forward<Ts> (ds)...)); + case Context: return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...)); + case ChainContext: return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...)); + case Extension: return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...)); + case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c, hb_forward<Ts> (ds)...)); default: return_trace (c->default_return_value ()); } } @@ -1253,7 +1221,7 @@ struct SubstLookup : Lookup const SubTable& get_subtable (unsigned int i) const { return Lookup::get_subtable<SubTable> (i); } - static bool lookup_type_is_reverse (unsigned int lookup_type) + HB_INTERNAL static bool lookup_type_is_reverse (unsigned int lookup_type) { return lookup_type == SubTable::ReverseChainSingle; } bool is_reverse () const @@ -1306,13 +1274,12 @@ struct SubstLookup : Lookup bool would_apply (hb_would_apply_context_t *c, const hb_ot_layout_lookup_accelerator_t *accel) const { - TRACE_WOULD_APPLY (this); - if (unlikely (!c->len)) return_trace (false); - if (!accel->may_have (c->glyphs[0])) return_trace (false); - return_trace (dispatch (c)); + if (unlikely (!c->len)) return false; + if (!accel->may_have (c->glyphs[0])) return false; + return dispatch (c); } - static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); + HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); SubTable& serialize_subtable (hb_serialize_context_t *c, unsigned int i) @@ -1320,17 +1287,19 @@ struct SubstLookup : Lookup bool serialize_single (hb_serialize_context_t *c, uint32_t lookup_props, - hb_array_t<const GlyphID> glyphs, - hb_array_t<const GlyphID> substitutes) + hb_sorted_array_t<const GlyphID> glyphs, + hb_array_t<const GlyphID> substitutes) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false); - return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes)); + + return_trace (serialize_subtable (c, 0).u.single + .serialize (c, hb_zip (glyphs, substitutes))); } bool serialize_multiple (hb_serialize_context_t *c, uint32_t lookup_props, - hb_array_t<const GlyphID> glyphs, + hb_sorted_array_t<const GlyphID> glyphs, hb_array_t<const unsigned int> substitute_len_list, hb_array_t<const GlyphID> substitute_glyphs_list) { @@ -1344,7 +1313,7 @@ struct SubstLookup : Lookup bool serialize_alternate (hb_serialize_context_t *c, uint32_t lookup_props, - hb_array_t<const GlyphID> glyphs, + hb_sorted_array_t<const GlyphID> glyphs, hb_array_t<const unsigned int> alternate_len_list, hb_array_t<const GlyphID> alternate_glyphs_list) { @@ -1358,7 +1327,7 @@ struct SubstLookup : Lookup bool serialize_ligature (hb_serialize_context_t *c, uint32_t lookup_props, - hb_array_t<const GlyphID> first_glyphs, + hb_sorted_array_t<const GlyphID> first_glyphs, hb_array_t<const unsigned int> ligature_per_first_glyph_count_list, hb_array_t<const GlyphID> ligatures_list, hb_array_t<const unsigned int> component_count_list, @@ -1375,12 +1344,12 @@ struct SubstLookup : Lookup } template <typename context_t> - static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); + HB_INTERNAL static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); - static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) + HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) { if (!c->should_visit_lookup (lookup_index)) - return HB_VOID; + return hb_empty_t (); hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index); @@ -1392,9 +1361,9 @@ struct SubstLookup : Lookup return ret; } - template <typename context_t> - typename context_t::return_t dispatch (context_t *c) const - { return Lookup::dispatch<SubTable> (c); } + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); } bool subset (hb_subset_context_t *c) const { return Lookup::subset<SubTable> (c); } |