diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 0ba7e3c06..a5d7804c7 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -88,10 +88,10 @@ static inline void ClassDef_serialize (hb_serialize_context_t *c, Iterator it); static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, - const hb_set_t &glyphset, const hb_map_t &gid_klass_map, hb_sorted_vector_t &glyphs, const hb_set_t &klasses, + bool use_class_zero, hb_map_t *klass_map /*INOUT*/); struct hb_subset_layout_context_t : @@ -1645,10 +1645,10 @@ Coverage_serialize (hb_serialize_context_t *c, { c->start_embed ()->serialize (c, it); } static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, - const hb_set_t &glyphset, const hb_map_t &gid_klass_map, hb_sorted_vector_t &glyphs, const hb_set_t &klasses, + bool use_class_zero, hb_map_t *klass_map /*INOUT*/) { if (!klass_map) @@ -1660,7 +1660,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, /* any glyph not assigned a class value falls into Class zero (0), * if any glyph assigned to class 0, remapping must start with 0->0*/ - if (glyphset.get_population () > gid_klass_map.get_population ()) + if (!use_class_zero) klass_map->set (0, 0); unsigned idx = klass_map->has (0) ? 1 : 0; @@ -1730,7 +1730,9 @@ struct ClassDefFormat1 } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/, + bool use_class_zero = true, + const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); const hb_set_t &glyphset = *c->plan->glyphset_gsub (); @@ -1742,9 +1744,12 @@ struct ClassDefFormat1 hb_codepoint_t start = startGlyph; hb_codepoint_t end = start + classValue.len; + for (const hb_codepoint_t gid : + hb_range (start, end) - | hb_filter (glyphset)) + | hb_filter (glyphset)) { + if (glyph_filter && !glyph_filter->has(gid)) continue; + unsigned klass = classValue[gid - start]; if (!klass) continue; @@ -1753,8 +1758,12 @@ struct ClassDefFormat1 orig_klasses.add (klass); } - ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map, - glyphs, orig_klasses, klass_map); + unsigned glyph_count = glyph_filter + ? hb_len (hb_iter (glyphset) | hb_filter (glyph_filter)) + : glyphset.get_population (); + use_class_zero = use_class_zero && glyph_count <= gid_org_klass_map.get_population (); + ClassDef_remap_and_serialize (c->serializer, gid_org_klass_map, + glyphs, orig_klasses, use_class_zero, klass_map); return_trace ((bool) glyphs); } @@ -1903,7 +1912,9 @@ struct ClassDefFormat2 } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/, + bool use_class_zero = true, + const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); const hb_set_t &glyphset = *c->plan->glyphset_gsub (); @@ -1923,14 +1934,19 @@ struct ClassDefFormat2 for (hb_codepoint_t g = start; g < end; g++) { if (!glyphset.has (g)) continue; + if (glyph_filter && !glyph_filter->has (g)) continue; glyphs.push (glyph_map[g]); gid_org_klass_map.set (glyph_map[g], klass); orig_klasses.add (klass); } } - ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map, - glyphs, orig_klasses, klass_map); + unsigned glyph_count = glyph_filter + ? hb_len (hb_iter (glyphset) | hb_filter (glyph_filter)) + : glyphset.get_population (); + use_class_zero = use_class_zero && glyph_count <= gid_org_klass_map.get_population (); + ClassDef_remap_and_serialize (c->serializer, gid_org_klass_map, + glyphs, orig_klasses, use_class_zero, klass_map); return_trace ((bool) glyphs); } @@ -2045,10 +2061,9 @@ struct ClassDef if (likely (it)) { hb_codepoint_t glyph_min = (*it).first; - hb_codepoint_t glyph_max = + it - | hb_map (hb_first) - | hb_reduce (hb_max, 0u); + hb_codepoint_t glyph_max = glyph_min; + unsigned num_glyphs = 0; unsigned num_ranges = 1; hb_codepoint_t prev_gid = glyph_min; unsigned prev_klass = (*it).second; @@ -2057,7 +2072,9 @@ struct ClassDef { hb_codepoint_t cur_gid = gid_klass_pair.first; unsigned cur_klass = gid_klass_pair.second; + if (cur_klass) num_glyphs++; if (cur_gid == glyph_min || !cur_klass) continue; + if (cur_gid > glyph_max) glyph_max = cur_gid; if (cur_gid != prev_gid + 1 || cur_klass != prev_klass) num_ranges++; @@ -2066,7 +2083,7 @@ struct ClassDef prev_klass = cur_klass; } - if (1 + (glyph_max - glyph_min + 1) <= num_ranges * 3) + if (num_glyphs && 1 + (glyph_max - glyph_min + 1) <= num_ranges * 3) format = 1; } u.format = format; @@ -2080,12 +2097,14 @@ struct ClassDef } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/, + bool use_class_zero = true, + const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); switch (u.format) { - case 1: return_trace (u.format1.subset (c, klass_map)); - case 2: return_trace (u.format2.subset (c, klass_map)); + case 1: return_trace (u.format1.subset (c, klass_map, use_class_zero, glyph_filter)); + case 2: return_trace (u.format2.subset (c, klass_map, use_class_zero, glyph_filter)); default:return_trace (false); } } diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index f523e35c0..85ff4bc84 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1358,7 +1358,7 @@ struct PairPosFormat2 if ((!valueFormat1.has_device ()) && (!valueFormat2.has_device ())) return; hb_set_t class1_set, class2_set; - for (const unsigned cp : c->glyph_set->iter ()) + for (const unsigned cp : + c->glyph_set->iter () | hb_filter (this + coverage)) { unsigned klass1 = (this+classDef1).get (cp); unsigned klass2 = (this+classDef2).get (cp); @@ -1366,7 +1366,10 @@ struct PairPosFormat2 class2_set.add (klass2); } - if (class1_set.is_empty () || class2_set.is_empty ()) return; + if (class1_set.is_empty () + || class2_set.is_empty () + || (class2_set.get_population() == 1 && class2_set.has(0))) + return; unsigned len1 = valueFormat1.get_len (); unsigned len2 = valueFormat2.get_len (); @@ -1435,11 +1438,11 @@ struct PairPosFormat2 out->valueFormat2 = valueFormat2; hb_map_t klass1_map; - out->classDef1.serialize_subset (c, classDef1, this, &klass1_map); + out->classDef1.serialize_subset (c, classDef1, this, &klass1_map, true, &(this + coverage)); out->class1Count = klass1_map.get_population (); hb_map_t klass2_map; - out->classDef2.serialize_subset (c, classDef2, this, &klass2_map); + out->classDef2.serialize_subset (c, classDef2, this, &klass2_map, false); out->class2Count = klass2_map.get_population (); unsigned len1 = valueFormat1.get_len (); diff --git a/test/api/fonts/AdobeVFPrototype.WA.gpos.otf b/test/api/fonts/AdobeVFPrototype.WA.gpos.otf index 967ef2554..31c9970fd 100644 Binary files a/test/api/fonts/AdobeVFPrototype.WA.gpos.otf and b/test/api/fonts/AdobeVFPrototype.WA.gpos.otf differ diff --git a/test/api/fonts/Roboto-Regular-gpos-aw.ttf b/test/api/fonts/Roboto-Regular-gpos-aw.ttf index 1b34d0551..8dfa99a1b 100644 Binary files a/test/api/fonts/Roboto-Regular-gpos-aw.ttf and b/test/api/fonts/Roboto-Regular-gpos-aw.ttf differ diff --git a/test/api/test-subset-gpos.c b/test/api/test-subset-gpos.c index 5c2fe2ed0..e1b3d0091 100644 --- a/test/api/test-subset-gpos.c +++ b/test/api/test-subset-gpos.c @@ -32,7 +32,6 @@ static void test_subset_gpos_lookup_subtable (void) { -#ifdef HB_EXPERIMENTAL_API hb_face_t *face_pwa = hb_test_open_font_file ("fonts/Roboto-Regular-gpos-.aw.ttf"); hb_face_t *face_wa = hb_test_open_font_file ("fonts/Roboto-Regular-gpos-aw.ttf"); @@ -53,14 +52,11 @@ test_subset_gpos_lookup_subtable (void) hb_face_destroy (face_pwa_subset); hb_face_destroy (face_pwa); hb_face_destroy (face_wa); -#endif } -/* TODO: Once GDEF subsetting is implemented, this test may fail & expected result need update. */ static void test_subset_gpos_pairpos1_vf (void) { -#ifdef HB_EXPERIMENTAL_API hb_face_t *face_wav = hb_test_open_font_file ("fonts/AdobeVFPrototype.WAV.gpos.otf"); hb_face_t *face_wa = hb_test_open_font_file ("fonts/AdobeVFPrototype.WA.gpos.otf"); @@ -81,7 +77,6 @@ test_subset_gpos_pairpos1_vf (void) hb_face_destroy (face_wav_subset); hb_face_destroy (face_wav); hb_face_destroy (face_wa); -#endif } int diff --git a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42,43,57.otf b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42,43,57.otf index cf686c366..f46824945 100644 Binary files a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42,43,57.otf and b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42,43,57.otf differ diff --git a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42,43.otf b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42,43.otf index dc41ad4b1..ff8afb9a7 100644 Binary files a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42,43.otf and b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42,43.otf differ diff --git a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42.otf b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42.otf index 749daaf4d..5e81cb486 100644 Binary files a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42.otf and b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,42.otf differ diff --git a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,56,57.otf b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,56,57.otf index a178115b4..04dfad564 100644 Binary files a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,56,57.otf and b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41,56,57.otf differ diff --git a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41.otf b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41.otf index 96374c4b7..5c166ed64 100644 Binary files a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41.otf and b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.41.otf differ diff --git a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.42,57.otf b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.42,57.otf index e17e1ec73..43a416592 100644 Binary files a/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.42,57.otf and b/test/subset/data/expected/layout.gdef-varstore/AdobeVFPrototype.keep-gdef-gpos.42,57.otf differ diff --git a/test/subset/data/expected/layout.gdef/Roboto-Regular.keep-gdef-gpos.1E00,303.ttf b/test/subset/data/expected/layout.gdef/Roboto-Regular.keep-gdef-gpos.1E00,303.ttf index b7411bb4d..a398c6f96 100644 Binary files a/test/subset/data/expected/layout.gdef/Roboto-Regular.keep-gdef-gpos.1E00,303.ttf and b/test/subset/data/expected/layout.gdef/Roboto-Regular.keep-gdef-gpos.1E00,303.ttf differ diff --git a/test/subset/data/expected/layout.gdef/Roboto-Regular.keep-gdef-gpos.41,42,43.ttf b/test/subset/data/expected/layout.gdef/Roboto-Regular.keep-gdef-gpos.41,42,43.ttf index 0ad253258..fcfc584b7 100644 Binary files a/test/subset/data/expected/layout.gdef/Roboto-Regular.keep-gdef-gpos.41,42,43.ttf and b/test/subset/data/expected/layout.gdef/Roboto-Regular.keep-gdef-gpos.41,42,43.ttf differ diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.2E,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.2E,23.otf new file mode 100644 index 000000000..849a7c5b1 Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.2E,23.otf differ diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.2E,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.2E,23.otf new file mode 100644 index 000000000..7ffd4689a Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.2E,23.otf 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 index b34a49fa0..77c408cd1 100644 Binary files a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf 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 index 2ad1d293d..9abdd3204 100644 Binary files a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf differ diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.2E,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.2E,23.otf new file mode 100644 index 000000000..786de3028 Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.2E,23.otf differ diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.41,42,43.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.41,42,43.otf index 5d9fe7725..1fb3d12e8 100644 Binary files a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.41,42,43.otf and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.41,42,43.otf 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 index 88e60461c..aebc39673 100644 Binary files a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf 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 index 195c8dc32..f227d5ad6 100644 Binary files a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf 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 index d10d3621b..a785d4967 100644 Binary files a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf differ diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.2E,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.2E,23.otf new file mode 100644 index 000000000..a80ccfcbc Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.2E,23.otf differ diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.41,42,43.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.41,42,43.otf index 83e2e61da..3766e7f65 100644 Binary files a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.41,42,43.otf and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.41,42,43.otf 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 index 88e60461c..aebc39673 100644 Binary files a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf differ diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,623,62D,644,627,645,2E.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,623,62D,644,627,645,2E.ttf index f361131df..7ae9c56be 100644 Binary files a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,623,62D,644,627,645,2E.ttf and b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout-retain-gids.627,644,623,62D,644,627,645,2E.ttf differ diff --git a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,623,62D,644,627,645,2E.ttf b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,623,62D,644,627,645,2E.ttf index 57ef1910e..3a64b97a6 100644 Binary files a/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,623,62D,644,627,645,2E.ttf and b/test/subset/data/expected/layout.gpos8.amiri/Amiri-Regular.keep-layout.627,644,623,62D,644,627,645,2E.ttf differ diff --git a/test/subset/data/fonts/gpos2_2_font5.otf b/test/subset/data/fonts/gpos2_2_font5.otf index 63af3bca1..19833cf8f 100644 Binary files a/test/subset/data/fonts/gpos2_2_font5.otf and b/test/subset/data/fonts/gpos2_2_font5.otf differ diff --git a/test/subset/data/tests/layout.gpos2.tests b/test/subset/data/tests/layout.gpos2.tests index 5d3a0bb6e..08799946b 100644 --- a/test/subset/data/tests/layout.gpos2.tests +++ b/test/subset/data/tests/layout.gpos2.tests @@ -9,5 +9,6 @@ keep-layout-retain-gids.txt SUBSETS: !# !#% +.# ABC *