From c38bd4025f3f6ff4c1a39cc106b8618361a0c62b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 24 Jul 2018 09:43:27 -0700 Subject: [PATCH] [closure] Separate in and out glyphs Fixes https://github.com/harfbuzz/harfbuzz/issues/1107 --- src/hb-ot-layout-gsub-table.hh | 26 ++++++++++++++++++-------- src/hb-ot-layout-gsubgpos-private.hh | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 91b898b63..eef8dc546 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -47,7 +47,7 @@ struct SingleSubstFormat1 * https://github.com/harfbuzz/harfbuzz/issues/363 */ hb_codepoint_t glyph_id = iter.get_glyph (); if (c->glyphs->has (glyph_id)) - c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu); + c->out->add ((glyph_id + deltaGlyphID) & 0xFFFFu); } } @@ -132,7 +132,7 @@ struct SingleSubstFormat2 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->glyphs->add (substitute[iter.get_coverage ()]); + c->out->add (substitute[iter.get_coverage ()]); } } @@ -263,7 +263,7 @@ struct Sequence TRACE_CLOSURE (this); unsigned int count = substitute.len; for (unsigned int i = 0; i < count; i++) - c->glyphs->add (substitute[i]); + c->out->add (substitute[i]); } inline void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -464,7 +464,7 @@ struct AlternateSubstFormat1 const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; unsigned int count = alt_set.len; for (unsigned int i = 0; i < count; i++) - c->glyphs->add (alt_set[i]); + c->out->add (alt_set[i]); } } } @@ -605,7 +605,7 @@ struct Ligature for (unsigned int i = 1; i < count; i++) if (!c->glyphs->has (component[i])) return; - c->glyphs->add (ligGlyph); + c->out->add (ligGlyph); } inline void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -957,7 +957,7 @@ struct ReverseChainSingleSubstFormat1 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->glyphs->add (substitute[iter.get_coverage ()]); + c->out->add (substitute[iter.get_coverage ()]); } } @@ -1163,7 +1163,12 @@ struct SubstLookup : Lookup return_trace (HB_VOID); c->set_recurse_func (dispatch_closure_recurse_func); - return_trace (dispatch (c)); + + hb_closure_context_t::return_t ret = dispatch (c); + + c->flush (); + + return_trace (ret); } inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -1265,7 +1270,12 @@ struct SubstLookup : Lookup { if (!c->should_visit_lookup (lookup_index)) return HB_VOID; - return dispatch_recurse_func (c, lookup_index); + + hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index); + + c->flush (); + + return ret; } template diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index aed00f151..c03e03356 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -69,12 +69,13 @@ struct hb_closure_context_t : bool is_lookup_done (unsigned int lookup_index) { - // Have we visited this lookup with the current set of glyphs? + /* Have we visited this lookup with the current set of glyphs? */ return done_lookups->get (lookup_index) == glyphs->get_population (); } hb_face_t *face; hb_set_t *glyphs; + hb_set_t *out; recurse_func_t recurse_func; unsigned int nesting_level_left; unsigned int debug_depth; @@ -85,13 +86,26 @@ struct hb_closure_context_t : unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), + out (hb_set_create ()), recurse_func (nullptr), nesting_level_left (nesting_level_left_), debug_depth (0), done_lookups (done_lookups_) {} + ~hb_closure_context_t (void) + { + flush (); + hb_set_destroy (out); + } + void set_recurse_func (recurse_func_t func) { recurse_func = func; } + void flush (void) + { + hb_set_union (glyphs, out); + hb_set_clear (out); + } + private: hb_map_t *done_lookups; };