diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 131ded282..b2b2f0ef0 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -566,6 +566,26 @@ struct AnchorMatrix return_trace (true); } + bool subset (hb_subset_context_t *c, + unsigned cols, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + + auto indexes = + + hb_range (rows * cols) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % cols); }) + ; + + out->serialize (c->serializer, + (unsigned) rows, + this, + c->plan->layout_variation_idx_map, + indexes); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const { TRACE_SANITIZE (this); @@ -2025,10 +2045,40 @@ typedef AnchorMatrix LigatureAttach; /* component-major-- * mark-minor-- * ordered by class--zero-based. */ -typedef OffsetListOf LigatureArray; - /* Array of LigatureAttach - * tables ordered by - * LigatureCoverage Index */ +/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ +struct LigatureArray : OffsetListOf +{ + template + bool subset (hb_subset_context_t *c, + Iterator coverage, + unsigned class_count, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + unsigned ligature_count = 0; + for (hb_codepoint_t gid : coverage) + { + ligature_count++; + if (!glyphset.has (gid)) continue; + + auto *matrix = out->serialize_append (c->serializer); + if (unlikely (!matrix)) return_trace (false); + + matrix->serialize_subset (c, + this->arrayZ[ligature_count - 1], + this, + class_count, + klass_mapping); + } + return_trace (this->len); + } +}; struct MarkLigPosFormat1 { @@ -2130,8 +2180,56 @@ struct MarkLigPosFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + 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; + + hb_map_t klass_mapping; + Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping); + + if (!klass_mapping.get_population ()) return_trace (false); + out->classCount = klass_mapping.get_population (); + + auto mark_iter = + + hb_zip (this+markCoverage, this+markArray) + | hb_filter (glyphset, hb_first) + ; + + auto new_mark_coverage = + + mark_iter + | hb_map_retains_sorting (hb_first) + | hb_map_retains_sorting (glyph_map) + ; + + if (!out->markCoverage.serialize (c->serializer, out) + .serialize (c->serializer, new_mark_coverage)) + return_trace (false); + + out->markArray.serialize (c->serializer, out) + .serialize (c->serializer, + &klass_mapping, + c->plan->layout_variation_idx_map, + &(this+markArray), + + mark_iter + | hb_map (hb_second)); + + auto new_ligature_coverage = + + hb_iter (this + ligatureCoverage) + | hb_filter (glyphset) + | hb_map_retains_sorting (glyph_map) + ; + + if (!out->ligatureCoverage.serialize (c->serializer, out) + .serialize (c->serializer, new_ligature_coverage)) + return_trace (false); + + out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), classCount, &klass_mapping); + + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const @@ -2164,6 +2262,7 @@ struct MarkLigPosFormat1 DEFINE_SIZE_STATIC (12); }; + struct MarkLigPos { template diff --git a/test/subset/data/Makefile.am b/test/subset/data/Makefile.am index d921f724c..133971a1a 100644 --- a/test/subset/data/Makefile.am +++ b/test/subset/data/Makefile.am @@ -17,6 +17,7 @@ EXTRA_DIST += \ expected/layout.gpos2 \ expected/layout.gpos3 \ expected/layout.gpos4 \ + expected/layout.gpos5 \ expected/layout.gpos6 \ expected/layout.gpos8 \ expected/layout.gpos8.amiri \ diff --git a/test/subset/data/Makefile.sources b/test/subset/data/Makefile.sources index 58ba1082c..46680a59d 100644 --- a/test/subset/data/Makefile.sources +++ b/test/subset/data/Makefile.sources @@ -16,6 +16,7 @@ TESTS = \ tests/layout.gpos2.tests \ tests/layout.gpos3.tests \ tests/layout.gpos4.tests \ + tests/layout.gpos5.tests \ tests/layout.gpos6.tests \ tests/layout.gpos8.tests \ tests/layout.gpos8.amiri.tests \ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43,44.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43,44.otf new file mode 100644 index 000000000..13a1fb785 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43,44.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43,45.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43,45.otf new file mode 100644 index 000000000..51533581f Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43,45.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43.otf new file mode 100644 index 000000000..b7a0bc625 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,43.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,44.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,44.otf new file mode 100644 index 000000000..bb7d74b52 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,44.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,45.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,45.otf new file mode 100644 index 000000000..0da7880e3 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42,45.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42.otf new file mode 100644 index 000000000..9b6e1589f Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,42.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,43.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,43.otf new file mode 100644 index 000000000..c28bed156 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41,43.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41.otf new file mode 100644 index 000000000..7878d4b8f Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.41.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.42.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.42.otf new file mode 100644 index 000000000..f5824e480 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.42.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.retain-all-codepoint.otf new file mode 100644 index 000000000..b7c424ec6 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout-retain-gids.retain-all-codepoint.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43,44.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43,44.otf new file mode 100644 index 000000000..3749d3545 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43,44.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43,45.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43,45.otf new file mode 100644 index 000000000..5d4fcee06 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43,45.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43.otf new file mode 100644 index 000000000..54fc0684b Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,43.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,44.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,44.otf new file mode 100644 index 000000000..d4c95a645 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,44.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,45.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,45.otf new file mode 100644 index 000000000..656792d72 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42,45.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42.otf new file mode 100644 index 000000000..cc2f5f7ee Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,42.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,43.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,43.otf new file mode 100644 index 000000000..946c63c68 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41,43.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41.otf new file mode 100644 index 000000000..093f4eef0 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.41.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.42.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.42.otf new file mode 100644 index 000000000..9e1aabf1c Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.42.otf differ diff --git a/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.retain-all-codepoint.otf new file mode 100644 index 000000000..b7c424ec6 Binary files /dev/null and b/test/subset/data/expected/layout.gpos5/gpos5_font1.keep-layout.retain-all-codepoint.otf differ diff --git a/test/subset/data/fonts/gpos5_font1.otf b/test/subset/data/fonts/gpos5_font1.otf new file mode 100644 index 000000000..c7e2132bd Binary files /dev/null and b/test/subset/data/fonts/gpos5_font1.otf differ diff --git a/test/subset/data/tests/layout.gpos5.tests b/test/subset/data/tests/layout.gpos5.tests new file mode 100644 index 000000000..3f5ef0c41 --- /dev/null +++ b/test/subset/data/tests/layout.gpos5.tests @@ -0,0 +1,18 @@ +FONTS: +gpos5_font1.otf + +PROFILES: +keep-layout.txt +keep-layout-retain-gids.txt + +SUBSETS: +A +B +AB +AC +ABC +ABE +ABCE +ABD +ABCD +* diff --git a/test/subset/meson.build b/test/subset/meson.build index 8d3d58bd4..de28fda2c 100644 --- a/test/subset/meson.build +++ b/test/subset/meson.build @@ -9,6 +9,7 @@ tests = [ 'layout.gpos2', 'layout.gpos3', 'layout.gpos4', + 'layout.gpos5', 'layout.gpos6', 'layout.gpos8', 'layout.gpos8.amiri',