diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 62b3b0aad..2c0631206 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -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 &lookup = StructAfter> (lookahead); - c->copy (lookup); + const ArrayOf &lookupRecord = StructAfter> (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 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 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& _ : + 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 &lookup = StructAfter> (lookahead); - return_trace (c->serializer->copy (lookup)); + const ArrayOf &lookupRecord = StructAfter> (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 61e5594fe..ef915b175 100644 --- a/test/subset/data/Makefile.am +++ b/test/subset/data/Makefile.am @@ -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 \ diff --git a/test/subset/data/Makefile.sources b/test/subset/data/Makefile.sources index a42321fef..5a63081bc 100644 --- a/test/subset/data/Makefile.sources +++ b/test/subset/data/Makefile.sources @@ -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 \ 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 000000000..61f41df10 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf 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 000000000..319094281 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.41,42,43.otf 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 000000000..3fabe7185 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf 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 000000000..34966da1d Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.30,31,32,33.otf 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 000000000..206062b21 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.41,42,43.otf 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 000000000..3fabe7185 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining1_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf 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 000000000..4c3af1350 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf 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 000000000..4a10c7683 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.41,42,43.otf 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 000000000..53dccf982 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf 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 000000000..7130a4c6c Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.30,31,32,33.otf 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 000000000..b64fb14ce Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.41,42,43.otf 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 000000000..53dccf982 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining2_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf 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 000000000..9bc50e5aa Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.30,31,32,33.otf 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 000000000..66b19412b Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.41,42,43.otf 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 000000000..e7cc68d15 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout-retain-gids.retain-all-codepoint.otf 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 000000000..55f3f6655 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.30,31,32,33.otf 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 000000000..5f69d873a Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.41,42,43.otf 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 000000000..e7cc68d15 Binary files /dev/null and b/test/subset/data/expected/layout.gpos8/gpos_chaining3_simple_f1.keep-layout.retain-all-codepoint.otf 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 000000000..721115e7b Binary files /dev/null and b/test/subset/data/fonts/gpos_chaining1_multiple_subrules_f1.otf 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 000000000..ef7f63510 Binary files /dev/null and b/test/subset/data/fonts/gpos_chaining2_multiple_subrules_f1.otf 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 000000000..b6f1863fb Binary files /dev/null and b/test/subset/data/fonts/gpos_chaining3_simple_f1.otf differ diff --git a/test/subset/data/tests/layout.gpos8.tests b/test/subset/data/tests/layout.gpos8.tests new file mode 100644 index 000000000..1e0579177 --- /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 +*