diff options
author | Qunxin Liu <qxliu@google.com> | 2019-09-17 11:10:08 -0700 |
---|---|---|
committer | Garret Rieger <grieger@google.com> | 2019-10-21 12:35:28 -0700 |
commit | 1f0a9d9be979de01527c05f4dbe6fbc62799597c (patch) | |
tree | 7836c8087a54431198f75001c64fb5c802801231 | |
parent | e766783152b91fb20baf0c657586628fd7959b1b (diff) | |
download | harfbuzz_ng-1f0a9d9be979de01527c05f4dbe6fbc62799597c.tar.gz |
[subset] GPOS Lookup Type 2: PairPos
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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew file mode 100644 index 000000000..47fea1ac6 --- /dev/null +++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otf 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 Binary files differnew file mode 100644 index 000000000..99e813fc5 --- /dev/null +++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otf 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 Binary files differnew file mode 100644 index 000000000..8f18b89c6 --- /dev/null +++ b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otf 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew file mode 100644 index 000000000..195c8dc32 --- /dev/null +++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf 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 Binary files differnew file mode 100644 index 000000000..d10d3621b --- /dev/null +++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf 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 Binary files differnew file mode 100644 index 000000000..88e60461c --- /dev/null +++ b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf diff --git a/test/subset/data/fonts/gpos2_1_font7.otf b/test/subset/data/fonts/gpos2_1_font7.otf Binary files differnew file mode 100644 index 000000000..22b54ea7e --- /dev/null +++ b/test/subset/data/fonts/gpos2_1_font7.otf diff --git a/test/subset/data/fonts/gpos2_2_font5.otf b/test/subset/data/fonts/gpos2_2_font5.otf Binary files differnew file mode 100644 index 000000000..63af3bca1 --- /dev/null +++ b/test/subset/data/fonts/gpos2_2_font5.otf 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: +!# +!#% +* |