[subset] check that sub rules in ContextFormat 1 and 2 intersect the glyphs set before recursing during closure lookups.
This commit is contained in:
parent
a5c0ec7516
commit
9fad540245
|
@ -1389,9 +1389,11 @@ struct Rule
|
||||||
lookup_context);
|
lookup_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
void closure_lookups (hb_closure_lookups_context_t *c,
|
||||||
|
ContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
if (unlikely (c->lookup_limit_exceeded ())) return;
|
if (unlikely (c->lookup_limit_exceeded ())) return;
|
||||||
|
if (!intersects (c->glyphs, lookup_context)) return;
|
||||||
|
|
||||||
const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
|
const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
|
||||||
(inputZ.as_array (inputCount ? inputCount - 1 : 0));
|
(inputZ.as_array (inputCount ? inputCount - 1 : 0));
|
||||||
|
@ -1521,14 +1523,13 @@ struct RuleSet
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
void closure_lookups (hb_closure_lookups_context_t *c,
|
||||||
|
ContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
if (unlikely (c->lookup_limit_exceeded ())) return;
|
if (unlikely (c->lookup_limit_exceeded ())) return;
|
||||||
|
|
||||||
return
|
|
||||||
+ hb_iter (rule)
|
+ hb_iter (rule)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([&] (const Rule &_) { _.closure_lookups (c); })
|
| hb_apply ([&] (const Rule &_) { return _.closure_lookups (c, lookup_context); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1647,9 +1648,16 @@ struct ContextFormat1
|
||||||
|
|
||||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||||
{
|
{
|
||||||
+ hb_iter (ruleSet)
|
struct ContextClosureLookupContext lookup_context = {
|
||||||
|
{intersects_glyph},
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
+ hb_zip (this+coverage, ruleSet)
|
||||||
|
| hb_filter (*c->glyphs, hb_first)
|
||||||
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c); })
|
| hb_apply ([&] (const RuleSet &_) { return _.closure_lookups (c, lookup_context); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1791,10 +1799,24 @@ struct ContextFormat2
|
||||||
|
|
||||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||||
{
|
{
|
||||||
|
if (!(this+coverage).intersects (c->glyphs))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ClassDef &class_def = this+classDef;
|
||||||
|
|
||||||
|
struct ContextClosureLookupContext lookup_context = {
|
||||||
|
{intersects_class},
|
||||||
|
&class_def
|
||||||
|
};
|
||||||
|
|
||||||
+ hb_iter (ruleSet)
|
+ hb_iter (ruleSet)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c); })
|
| hb_enumerate
|
||||||
;
|
| hb_filter ([&] (const hb_pair_t<unsigned, const RuleSet &> p)
|
||||||
|
{ return class_def.intersects_class (c->glyphs, p.first); })
|
||||||
|
| hb_map (hb_second)
|
||||||
|
| hb_apply ([&] (const RuleSet & _)
|
||||||
|
{ _.closure_lookups (c, lookup_context); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
|
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
|
||||||
|
|
|
@ -11,6 +11,7 @@ tests = [
|
||||||
'layout.gpos4',
|
'layout.gpos4',
|
||||||
'layout.gpos6',
|
'layout.gpos6',
|
||||||
'layout.gpos8',
|
'layout.gpos8',
|
||||||
|
'layout.gpos8.amiri',
|
||||||
'layout.gsub3',
|
'layout.gsub3',
|
||||||
'layout.gsub6',
|
'layout.gsub6',
|
||||||
'layout.gdef',
|
'layout.gdef',
|
||||||
|
|
Loading…
Reference in New Issue