[subset] GPOS Lookup Type 2: PairPos
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 2b535af..e129ae4 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -558,7 +558,7 @@
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto it =
@@ -647,7 +647,7 @@
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
unsigned sub_length = valueFormat.get_len ();
@@ -761,6 +761,18 @@
{
friend struct PairSet;
+ bool serialize (hb_serialize_context_t *c,
+ unsigned size,
+ const hb_map_t &glyph_map) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *out = c->start_embed (*this);
+ if (unlikely (!c->extend_min (out))) return_trace (false);
+
+ out->secondGlyph = glyph_map[secondGlyph];
+ return_trace (c->copy (values, size));
+ }
+
protected:
HBGlyphID secondGlyph; /* GlyphID of second glyph in the
* pair--first glyph is listed in the
@@ -846,6 +858,37 @@
return_trace (false);
}
+ bool subset (hb_subset_context_t *c,
+ const ValueFormat valueFormats[2]) const
+ {
+ TRACE_SUBSET (this);
+ auto snap = c->serializer->snapshot ();
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->len = 0;
+
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ unsigned len1 = valueFormats[0].get_size ();
+ unsigned len2 = valueFormats[1].get_size ();
+ unsigned record_size = HBUINT16::static_size + len1 + len2;
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned count = len, num = 0;
+ for (unsigned i = 0; i < count; i++)
+ {
+ if (!glyphset.has (record->secondGlyph)) continue;
+ if (record->serialize (c->serializer, record_size, glyph_map)) num++;
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+
+ out->len = num;
+ if (!num) c->serializer->revert (snap);
+ return_trace (num);
+ }
+
struct sanitize_closure_t
{
const void *base;
@@ -919,8 +962,43 @@
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+ out->valueFormat[0] = valueFormat[0];
+ out->valueFormat[1] = valueFormat[1];
+
+ hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+
+ + hb_zip (this+coverage, pairSet)
+ | hb_filter (glyphset, hb_first)
+ | hb_filter ([this, c, out] (const OffsetTo<PairSet>& _)
+ {
+ auto *o = out->pairSet.serialize_append (c->serializer);
+ if (unlikely (!o)) return false;
+ auto snap = c->serializer->snapshot ();
+ bool ret = o->serialize_subset (c, _, this, out, valueFormat);
+ if (!ret)
+ {
+ out->pairSet.pop ();
+ c->serializer->revert (snap);
+ }
+ return ret;
+ },
+ hb_second)
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ out->coverage.serialize (c->serializer, out)
+ .serialize (c->serializer, new_coverage.iter ());
+
+ return_trace (bool (new_coverage));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -1011,8 +1089,49 @@
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+ out->valueFormat1 = valueFormat1;
+ out->valueFormat2 = valueFormat2;
+
+ hb_map_t klass1_map;
+ out->classDef1.serialize_subset (c, classDef1, this, out, &klass1_map);
+ out->class1Count = klass1_map.get_population ();
+
+ hb_map_t klass2_map;
+ out->classDef2.serialize_subset (c, classDef2, this, out, &klass2_map);
+ out->class2Count = klass2_map.get_population ();
+
+ unsigned record_len = valueFormat1.get_len () + valueFormat2.get_len ();
+
+ + hb_range ((unsigned) class1Count)
+ | hb_filter (klass1_map)
+ | hb_apply ([&] (const unsigned class1_idx)
+ {
+ + hb_range ((unsigned) class2Count)
+ | hb_filter (klass2_map)
+ | hb_apply ([&] (const unsigned class2_idx)
+ {
+ unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_len;
+ for (unsigned i = 0; i < record_len; i++)
+ c->serializer->copy (values[idx+i]);
+ })
+ ;
+ })
+ ;
+
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto it =
+ + hb_iter (this+coverage)
+ | hb_filter (glyphset)
+ | hb_map_retains_sorting (glyph_map)
+ ;
+
+ out->coverage.serialize (c->serializer, out).serialize (c->serializer, it);
+ return_trace (out->class1Count && out->class2Count && bool (it));
}
bool sanitize (hb_sanitize_context_t *c) const
diff --git a/test/subset/data/Makefile.am b/test/subset/data/Makefile.am
index b50029f..4508fcd 100644
--- a/test/subset/data/Makefile.am
+++ b/test/subset/data/Makefile.am
@@ -14,6 +14,7 @@
expected/cff-japanese \
expected/layout \
expected/layout.gpos \
+ expected/layout.gpos2 \
expected/layout.gpos3 \
expected/layout.gsub6 \
expected/cmap14 \
diff --git a/test/subset/data/Makefile.sources b/test/subset/data/Makefile.sources
index ccc0cdc..5b93f27 100644
--- a/test/subset/data/Makefile.sources
+++ b/test/subset/data/Makefile.sources
@@ -6,6 +6,7 @@
tests/cff-japanese.tests \
tests/layout.tests \
tests/layout.gpos.tests \
+ tests/layout.gpos2.tests \
tests/layout.gpos3.tests \
tests/layout.gsub6.tests \
tests/cmap14.tests \
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23,25.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23,25.otf
new file mode 100644
index 0000000..49039fe
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23,25.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23.otf
new file mode 100644
index 0000000..68cb0ec
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644
index 0000000..8f18b89
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otf
new file mode 100644
index 0000000..47fea1a
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otf
new file mode 100644
index 0000000..99e813f
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otf
new file mode 100644
index 0000000..8f18b89
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf
new file mode 100644
index 0000000..b34a49f
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf
new file mode 100644
index 0000000..2ad1d29
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644
index 0000000..88e6046
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf
new file mode 100644
index 0000000..195c8dc
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf
new file mode 100644
index 0000000..d10d362
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf
Binary files differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf
new file mode 100644
index 0000000..88e6046
--- /dev/null
+++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf
Binary files differ
diff --git a/test/subset/data/fonts/gpos2_1_font7.otf b/test/subset/data/fonts/gpos2_1_font7.otf
new file mode 100644
index 0000000..22b54ea
--- /dev/null
+++ b/test/subset/data/fonts/gpos2_1_font7.otf
Binary files differ
diff --git a/test/subset/data/fonts/gpos2_2_font5.otf b/test/subset/data/fonts/gpos2_2_font5.otf
new file mode 100644
index 0000000..63af3bc
--- /dev/null
+++ b/test/subset/data/fonts/gpos2_2_font5.otf
Binary files differ
diff --git a/test/subset/data/tests/layout.gpos2.tests b/test/subset/data/tests/layout.gpos2.tests
new file mode 100644
index 0000000..94fe78a
--- /dev/null
+++ b/test/subset/data/tests/layout.gpos2.tests
@@ -0,0 +1,12 @@
+FONTS:
+gpos2_1_font7.otf
+gpos2_2_font5.otf
+
+PROFILES:
+keep-layout.txt
+keep-layout-retain-gids.txt
+
+SUBSETS:
+!#
+!#%
+*