aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQunxin Liu <qxliu@google.com>2019-09-17 11:10:08 -0700
committerGarret Rieger <grieger@google.com>2019-10-21 12:35:28 -0700
commit1f0a9d9be979de01527c05f4dbe6fbc62799597c (patch)
tree7836c8087a54431198f75001c64fb5c802801231
parente766783152b91fb20baf0c657586628fd7959b1b (diff)
downloadharfbuzz_ng-1f0a9d9be979de01527c05f4dbe6fbc62799597c.tar.gz
[subset] GPOS Lookup Type 2: PairPos
-rw-r--r--src/hb-ot-layout-gpos-table.hh131
-rw-r--r--test/subset/data/Makefile.am1
-rw-r--r--test/subset/data/Makefile.sources1
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23,25.otfbin0 -> 1764 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23.otfbin0 -> 1632 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.retain-all-codepoint.otfbin0 -> 3688 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otfbin0 -> 1428 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otfbin0 -> 1308 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otfbin0 -> 3688 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otfbin0 -> 1776 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otfbin0 -> 1644 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otfbin0 -> 3684 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otfbin0 -> 1440 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otfbin0 -> 1320 bytes
-rw-r--r--test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otfbin0 -> 3684 bytes
-rw-r--r--test/subset/data/fonts/gpos2_1_font7.otfbin0 -> 4584 bytes
-rw-r--r--test/subset/data/fonts/gpos2_2_font5.otfbin0 -> 4580 bytes
-rw-r--r--test/subset/data/tests/layout.gpos2.tests12
18 files changed, 139 insertions, 6 deletions
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 2b535af2f..e129ae418 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -558,7 +558,7 @@ struct SinglePosFormat1
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 @@ struct SinglePosFormat2
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 @@ struct PairValueRecord
{
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 @@ struct PairSet
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 @@ struct PairPosFormat1
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 @@ struct PairPosFormat2
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 b50029f5e..4508fcde8 100644
--- a/test/subset/data/Makefile.am
+++ b/test/subset/data/Makefile.am
@@ -14,6 +14,7 @@ EXTRA_DIST += \
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 ccc0cdce5..5b93f27df 100644
--- a/test/subset/data/Makefile.sources
+++ b/test/subset/data/Makefile.sources
@@ -6,6 +6,7 @@ TESTS = \
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 000000000..49039feeb
--- /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 000000000..68cb0ec5d
--- /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 000000000..8f18b89c6
--- /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 000000000..47fea1ac6
--- /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 000000000..99e813fc5
--- /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 000000000..8f18b89c6
--- /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 000000000..b34a49fa0
--- /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 000000000..2ad1d293d
--- /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 000000000..88e60461c
--- /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 000000000..195c8dc32
--- /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 000000000..d10d3621b
--- /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 000000000..88e60461c
--- /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 000000000..22b54ea7e
--- /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 000000000..63af3bca1
--- /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 000000000..94fe78a56
--- /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:
+!#
+!#%
+*