[subset] ChainContext subsetting fix: add lookup index remapping
diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 62b3b0a..2c06312 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh
@@ -2323,6 +2323,7 @@ } 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 @@ 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 @@ !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 @@ !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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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
diff --git a/test/subset/data/Makefile.am b/test/subset/data/Makefile.am index 61e5594..ef915b1 100644 --- a/test/subset/data/Makefile.am +++ b/test/subset/data/Makefile.am
@@ -18,6 +18,7 @@ expected/layout.gpos3 \ expected/layout.gpos4 \ expected/layout.gpos6 \ + expected/layout.gpos8 \ expected/layout.gsub3 \ expected/layout.gsub6 \ expected/layout.gdef \
diff --git a/test/subset/data/Makefile.sources b/test/subset/data/Makefile.sources index a42321f..5a63081 100644 --- a/test/subset/data/Makefile.sources +++ b/test/subset/data/Makefile.sources
@@ -18,6 +18,7 @@ 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 \
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf new file mode 100644 index 0000000..61f41df --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.41,42,43.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.41,42,43.otf new file mode 100644 index 0000000..3190942 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.41,42,43.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf new file mode 100644 index 0000000..3fabe71 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.30,31,32,33.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.30,31,32,33.otf new file mode 100644 index 0000000..34966da --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.30,31,32,33.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.41,42,43.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.41,42,43.otf new file mode 100644 index 0000000..206062b --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.41,42,43.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf new file mode 100644 index 0000000..3fabe71 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf new file mode 100644 index 0000000..4c3af13 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.41,42,43.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.41,42,43.otf new file mode 100644 index 0000000..4a10c76 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.41,42,43.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf new file mode 100644 index 0000000..53dccf9 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.30,31,32,33.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.30,31,32,33.otf new file mode 100644 index 0000000..7130a4c --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.30,31,32,33.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.41,42,43.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.41,42,43.otf new file mode 100644 index 0000000..b64fb14 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.41,42,43.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf new file mode 100644 index 0000000..53dccf9 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.30,31,32,33.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.30,31,32,33.otf new file mode 100644 index 0000000..9bc50e5 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.30,31,32,33.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.41,42,43.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.41,42,43.otf new file mode 100644 index 0000000..66b1941 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.41,42,43.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.retain-all-codepoint.otf new file mode 100644 index 0000000..e7cc68d --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.retain-all-codepoint.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.30,31,32,33.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.30,31,32,33.otf new file mode 100644 index 0000000..55f3f66 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.30,31,32,33.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.41,42,43.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.41,42,43.otf new file mode 100644 index 0000000..5f69d87 --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.41,42,43.otf Binary files differ
diff --git a/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.retain-all-codepoint.otf new file mode 100644 index 0000000..e7cc68d --- /dev/null +++ b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.retain-all-codepoint.otf Binary files differ
diff --git a/test/subset/data/fonts/gpos_chaining1_multiple_subrules_f1.otf b/test/subset/data/fonts/gpos_chaining1_multiple_subrules_f1.otf new file mode 100644 index 0000000..721115e --- /dev/null +++ b/test/subset/data/fonts/gpos_chaining1_multiple_subrules_f1.otf Binary files differ
diff --git a/test/subset/data/fonts/gpos_chaining2_multiple_subrules_f1.otf b/test/subset/data/fonts/gpos_chaining2_multiple_subrules_f1.otf new file mode 100644 index 0000000..ef7f635 --- /dev/null +++ b/test/subset/data/fonts/gpos_chaining2_multiple_subrules_f1.otf Binary files differ
diff --git a/test/subset/data/fonts/gpos_chaining3_simple_f1.otf b/test/subset/data/fonts/gpos_chaining3_simple_f1.otf new file mode 100644 index 0000000..b6f1863 --- /dev/null +++ b/test/subset/data/fonts/gpos_chaining3_simple_f1.otf Binary files differ
diff --git a/test/subset/data/tests/layout.gpos8.tests b/test/subset/data/tests/layout.gpos8.tests new file mode 100644 index 0000000..1e05791 --- /dev/null +++ b/test/subset/data/tests/layout.gpos8.tests
@@ -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 +*