[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
+*