[subset] ChainContext subsetting fix: add lookup index remapping

This commit is contained in:
Qunxin Liu 2020-05-20 18:00:25 -07:00 committed by Garret Rieger
parent e3af529e51
commit 593e58c842
25 changed files with 53 additions and 19 deletions

View File

@ -2323,6 +2323,7 @@ struct ChainRule
}
ChainRule* copy (hb_serialize_context_t *c,
const hb_map_t *lookup_map,
const hb_map_t *backtrack_map,
const hb_map_t *input_map = nullptr,
const hb_map_t *lookahead_map = nullptr) const
@ -2345,13 +2346,19 @@ struct ChainRule
serialize_array (c, lookahead.len, + lookahead.iter ()
| hb_map (mapping));
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
c->copy (lookup);
const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead);
HBUINT16 lookupCount;
lookupCount = lookupRecord.len;
if (!c->copy (lookupCount)) return_trace (nullptr);
for (unsigned i = 0; i < (unsigned) lookupCount; i++)
if (!c->copy (lookupRecord[i], lookup_map)) return_trace (nullptr);
return_trace (out);
}
bool subset (hb_subset_context_t *c,
const hb_map_t *lookup_map,
const hb_map_t *backtrack_map = nullptr,
const hb_map_t *input_map = nullptr,
const hb_map_t *lookahead_map = nullptr) const
@ -2369,7 +2376,7 @@ struct ChainRule
!hb_all (lookahead, glyphset))
return_trace (false);
copy (c->serializer, c->plan->glyph_map);
copy (c->serializer, lookup_map, c->plan->glyph_map);
}
else
{
@ -2378,7 +2385,7 @@ struct ChainRule
!hb_all (lookahead, lookahead_map))
return_trace (false);
copy (c->serializer, backtrack_map, input_map, lookahead_map);
copy (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map);
}
return_trace (true);
@ -2479,6 +2486,7 @@ struct ChainRuleSet
}
bool subset (hb_subset_context_t *c,
const hb_map_t *lookup_map,
const hb_map_t *backtrack_klass_map = nullptr,
const hb_map_t *input_klass_map = nullptr,
const hb_map_t *lookahead_klass_map = nullptr) const
@ -2497,6 +2505,7 @@ struct ChainRuleSet
auto o_snap = c->serializer->snapshot ();
if (!o->serialize_subset (c, _, this,
lookup_map,
backtrack_klass_map,
input_klass_map,
lookahead_klass_map))
@ -2621,10 +2630,11 @@ struct ChainContextFormat1
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
out->format = format;
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, ruleSet)
| hb_filter (glyphset, hb_first)
| hb_filter (subset_offset_array (c, out->ruleSet, this), hb_second)
| hb_filter (subset_offset_array (c, out->ruleSet, this, lookup_map), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
@ -2795,8 +2805,9 @@ struct ChainContextFormat2
hb_map_t lookahead_klass_map;
out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, &lookahead_klass_map);
hb_vector_t<unsigned> rulesets;
unsigned non_zero_index = 0, index = 0;
bool ret = true;
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
for (const OffsetTo<ChainRuleSet>& _ : + hb_enumerate (ruleSet)
| hb_filter (input_klass_map, hb_first)
| hb_map (hb_second))
@ -2807,24 +2818,24 @@ struct ChainContextFormat2
ret = false;
break;
}
if (!o->serialize_subset (c, _, this,
&backtrack_klass_map,
&input_klass_map,
&lookahead_klass_map))
{
rulesets.push (0);
}
else rulesets.push (1);
if (o->serialize_subset (c, _, this,
lookup_map,
&backtrack_klass_map,
&input_klass_map,
&lookahead_klass_map))
non_zero_index = index;
index++;
}
if (!ret) return_trace (ret);
//prune empty trailing ruleSets
unsigned count = rulesets.length;
while (count > 0 && rulesets[count-1] == 0)
--index;
while (index > non_zero_index)
{
out->ruleSet.pop ();
count--;
index--;
}
return_trace (bool (out->ruleSet));
@ -3014,8 +3025,16 @@ struct ChainContextFormat3
if (!serialize_coverage_offsets (c, lookahead.iter (), this))
return_trace (false);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
return_trace (c->serializer->copy (lookup));
const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead);
HBUINT16 lookupCount;
lookupCount = lookupRecord.len;
if (!c->serializer->copy (lookupCount)) return_trace (false);
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
for (unsigned i = 0; i < (unsigned) lookupCount; i++)
if (!c->serializer->copy (lookupRecord[i], lookup_map)) return_trace (false);
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const

View File

@ -18,6 +18,7 @@ EXTRA_DIST += \
expected/layout.gpos3 \
expected/layout.gpos4 \
expected/layout.gpos6 \
expected/layout.gpos8 \
expected/layout.gsub3 \
expected/layout.gsub6 \
expected/layout.gdef \

View File

@ -18,6 +18,7 @@ DISABLED_TESTS = \
tests/layout.gpos3.tests \
tests/layout.gpos4.tests \
tests/layout.gpos6.tests \
tests/layout.gpos8.tests \
tests/layout.gsub3.tests \
tests/layout.gsub6.tests \
tests/layout.gdef.tests \

Binary file not shown.

View File

@ -0,0 +1,13 @@
FONTS:
gpos_chaining1_multiple_subrules_f1.otf
gpos_chaining2_multiple_subrules_f1.otf
gpos_chaining3_simple_f1.otf
PROFILES:
keep-layout.txt
keep-layout-retain-gids.txt
SUBSETS:
0123
ABC
*