[closure] Separate in and out glyphs

Fixes https://github.com/harfbuzz/harfbuzz/issues/1107
This commit is contained in:
Behdad Esfahbod 2018-07-24 09:43:27 -07:00
parent 85646fdadb
commit c38bd4025f
2 changed files with 33 additions and 9 deletions

View File

@ -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 <typename context_t>

View File

@ -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;
};