diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index fde273e69..59abdf737 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -3658,24 +3658,33 @@ struct GSUBGPOS const hb_set_t *feature_indices, hb_map_t *duplicate_feature_map /* OUT */) const { - hb_set_t unique_features; - hb_tag_t prev_t = get_feature_tag (feature_indices->get_min ()); + if (feature_indices->is_empty ()) return; + hb_hashmap_t unique_features; //find out duplicate features after subset for (unsigned i : feature_indices->iter ()) { hb_tag_t t = get_feature_tag (i); - if (t != prev_t) + if (!unique_features.has (t)) { - prev_t = t; - unique_features.clear (); - unique_features.add (i); + hb_set_t* indices = hb_set_create (); + if (unlikely (indices == hb_set_get_empty () || + !unique_features.set (t, indices))) + { + hb_set_destroy (indices); + for (auto _ : unique_features.iter ()) + hb_set_destroy (_.second); + return; + } + if (unique_features.get (t)) + unique_features.get (t)->add (i); duplicate_feature_map->set (i, i); continue; } bool found = false; - for (unsigned other_f_index : unique_features.iter ()) + hb_set_t* same_tag_features = unique_features.get (t); + for (unsigned other_f_index : same_tag_features->iter ()) { const Feature& f = get_feature (i); const Feature& other_f = get_feature (other_f_index); @@ -3707,10 +3716,13 @@ struct GSUBGPOS if (found == false) { - unique_features.add (i); + same_tag_features->add (i); duplicate_feature_map->set (i, i); } } + + for (auto _ : unique_features.iter ()) + hb_set_destroy (_.second); } void prune_features (const hb_map_t *lookup_indices, /* IN */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index d02a3c0ea..1e446c66f 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1013,24 +1013,15 @@ struct hb_collect_features_context_t } has_feature_filter = true; + hb_set_t features_set; for (; *features; features++) + features_set.add (*features); + + for (unsigned i = 0; i < g.get_feature_count (); i++) { - hb_tag_t tag = *features; - unsigned index; - g.find_feature_index (tag, &index); - if (index == OT::Index::NOT_FOUND_INDEX) continue; - - feature_indices_filter.add(index); - for (int i = (int) index - 1; i >= 0; i--) - { - if (g.get_feature_tag (i) != tag) break; + hb_tag_t tag = g.get_feature_tag (i); + if (features_set.has (tag)) feature_indices_filter.add(i); - } - for (unsigned i = index + 1; i < g.get_feature_count (); i++) - { - if (g.get_feature_tag (i) != tag) break; - feature_indices_filter.add(i); - } } } diff --git a/test/subset/data/Makefile.am b/test/subset/data/Makefile.am index f530fad28..33ffb9eda 100644 --- a/test/subset/data/Makefile.am +++ b/test/subset/data/Makefile.am @@ -36,6 +36,7 @@ EXTRA_DIST += \ expected/layout.notonastaliqurdu \ expected/layout.tinos \ expected/layout.duplicate_features \ + expected/layout.unsorted_featurelist \ expected/cmap \ expected/cmap14 \ expected/sbix \ diff --git a/test/subset/data/Makefile.sources b/test/subset/data/Makefile.sources index 2ed10567f..34f2f0708 100644 --- a/test/subset/data/Makefile.sources +++ b/test/subset/data/Makefile.sources @@ -34,6 +34,7 @@ TESTS = \ tests/layout.tests \ tests/layout.tinos.tests \ tests/layout.duplicate_features.tests \ + tests/layout.unsorted_featurelist.tests \ tests/sbix.tests \ tests/variable.tests \ tests/glyph_names.tests \ diff --git a/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.default.392,3a7,3b2,3c7.ttf b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.default.392,3a7,3b2,3c7.ttf new file mode 100644 index 000000000..3fb42c6a3 Binary files /dev/null and b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.default.392,3a7,3b2,3c7.ttf differ diff --git a/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.default.retain-all-codepoint.ttf b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.default.retain-all-codepoint.ttf new file mode 100644 index 000000000..decba004d Binary files /dev/null and b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.default.retain-all-codepoint.ttf differ diff --git a/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.layout-test.392,3a7,3b2,3c7.ttf b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.layout-test.392,3a7,3b2,3c7.ttf new file mode 100644 index 000000000..a0b6145f0 Binary files /dev/null and b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.layout-test.392,3a7,3b2,3c7.ttf differ diff --git a/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.layout-test.retain-all-codepoint.ttf b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.layout-test.retain-all-codepoint.ttf new file mode 100644 index 000000000..2d76b5afc Binary files /dev/null and b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.layout-test.retain-all-codepoint.ttf differ diff --git a/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.retain-gids.392,3a7,3b2,3c7.ttf b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.retain-gids.392,3a7,3b2,3c7.ttf new file mode 100644 index 000000000..012bb1646 Binary files /dev/null and b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.retain-gids.392,3a7,3b2,3c7.ttf differ diff --git a/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.retain-gids.retain-all-codepoint.ttf new file mode 100644 index 000000000..7ddb09ac2 Binary files /dev/null and b/test/subset/data/expected/layout.unsorted_featurelist/NotoIKEAHebrewLatin-Regular.retain-gids.retain-all-codepoint.ttf differ diff --git a/test/subset/data/fonts/NotoIKEAHebrewLatin-Regular.ttf b/test/subset/data/fonts/NotoIKEAHebrewLatin-Regular.ttf new file mode 100644 index 000000000..756680813 Binary files /dev/null and b/test/subset/data/fonts/NotoIKEAHebrewLatin-Regular.ttf differ diff --git a/test/subset/data/tests/layout.unsorted_featurelist.tests b/test/subset/data/tests/layout.unsorted_featurelist.tests new file mode 100644 index 000000000..9c77a7ade --- /dev/null +++ b/test/subset/data/tests/layout.unsorted_featurelist.tests @@ -0,0 +1,11 @@ +FONTS: +NotoIKEAHebrewLatin-Regular.ttf + +PROFILES: +layout-test.txt +default.txt +retain-gids.txt + +SUBSETS: +U+392,U+3a7,U+3b2,U+3c7 +* diff --git a/test/subset/meson.build b/test/subset/meson.build index 9a5377c9e..a287136a9 100644 --- a/test/subset/meson.build +++ b/test/subset/meson.build @@ -28,6 +28,7 @@ tests = [ 'layout.notonastaliqurdu', 'layout.tinos', 'layout.duplicate_features', + 'layout.unsorted_featurelist', 'cmap', 'cmap14', 'sbix',