From f2441a4b65288dfc1c17a52bb31d694fb3e3ce08 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Tue, 24 Aug 2021 15:53:32 -0700 Subject: [PATCH] [subset] Remove retain all layout features flag. Instead use inverted sets to handle requesting all features. Modifies feature collection in subset plan to intersect the set of requested features against the features in the font. This prevents iterating a fully filled feature tag set. --- src/hb-subset-input.cc | 15 --------- src/hb-subset-plan.cc | 74 +++++++++++++++++++++--------------------- src/hb-subset.h | 11 ------- test/api/test-subset.c | 4 +-- util/hb-subset.cc | 12 ++----- 5 files changed, 42 insertions(+), 74 deletions(-) diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc index e2c6d9cab..ad2d6b3fc 100644 --- a/src/hb-subset-input.cc +++ b/src/hb-subset-input.cc @@ -450,21 +450,6 @@ static void set_flag_value (hb_subset_input_t *input, hb_subset_flags_t flag, hb : hb_subset_input_get_flags (input) & ~flag); } -void -hb_subset_input_set_retain_all_features (hb_subset_input_t *subset_input, - hb_bool_t value) -{ - return set_flag_value (subset_input, - HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES, - value); -} - -hb_bool_t -hb_subset_input_get_retain_all_features (hb_subset_input_t *subset_input) -{ - return (bool) (hb_subset_input_get_flags (subset_input) & HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES); -} - void hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input, hb_bool_t drop_hints) diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index aab78c5f0..af06d5638 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -87,43 +87,48 @@ _remap_indexes (const hb_set_t *indexes, #ifndef HB_NO_SUBSET_LAYOUT typedef void (*layout_collect_func_t) (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *scripts, const hb_tag_t *languages, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */); +template static void _collect_subset_layout (hb_face_t *face, - hb_tag_t table_tag, + const T& table, const hb_set_t *layout_features_to_retain, - bool retain_all_features, layout_collect_func_t layout_collect_func, hb_set_t *lookup_indices /* OUT */) { - if (retain_all_features) - { - layout_collect_func (face, - table_tag, - nullptr, - nullptr, - nullptr, - lookup_indices); + hb_vector_t features; + if (!features.alloc (table.get_feature_count () + 1)) return; + + for (unsigned i = 0; i < table.get_feature_count (); i++) + { + hb_tag_t tag = table.get_feature_tag (i); + if (tag && layout_features_to_retain->has (tag)) + features.push (tag); } - if (hb_set_is_empty (layout_features_to_retain)) return; - unsigned num = layout_features_to_retain->get_population () + 1; - hb_tag_t *features = (hb_tag_t *) hb_malloc (num * sizeof (hb_tag_t)); - if (!features) return; + if (!features) + return; - unsigned i = 0; - for (hb_tag_t f : layout_features_to_retain->iter ()) - features[i++] = f; + // The collect function needs a null element to signal end of the array. + features.push (0); - features[i] = 0; + if (features.get_size () == table.get_feature_count () + 1) + { + // Looking for all features, trigger the faster collection method. + layout_collect_func (face, + T::tableTag, + nullptr, + nullptr, + nullptr, + lookup_indices); + return; + } layout_collect_func (face, - table_tag, + T::tableTag, nullptr, nullptr, - features, + features.arrayZ, lookup_indices); - - hb_free (features); } template @@ -131,7 +136,6 @@ static inline void _closure_glyphs_lookups_features (hb_face_t *face, hb_set_t *gids_to_retain, const hb_set_t *layout_features_to_retain, - bool retain_all_features, hb_map_t *lookups, hb_map_t *features, script_langsys_map *langsys_map) @@ -139,12 +143,11 @@ _closure_glyphs_lookups_features (hb_face_t *face, hb_blob_ptr_t table = hb_sanitize_context_t ().reference_table (face); hb_tag_t table_tag = table->tableTag; hb_set_t lookup_indices; - _collect_subset_layout (face, - table_tag, - layout_features_to_retain, - retain_all_features, - hb_ot_layout_collect_lookups, - &lookup_indices); + _collect_subset_layout (face, + *table, + layout_features_to_retain, + hb_ot_layout_collect_lookups, + &lookup_indices); if (table_tag == HB_OT_TAG_GSUB) hb_ot_layout_lookups_substitute_closure (face, @@ -157,12 +160,11 @@ _closure_glyphs_lookups_features (hb_face_t *face, // Collect and prune features hb_set_t feature_indices; - _collect_subset_layout (face, - table_tag, - layout_features_to_retain, - retain_all_features, - hb_ot_layout_collect_features, - &feature_indices); + _collect_subset_layout (face, + *table, + layout_features_to_retain, + hb_ot_layout_collect_features, + &feature_indices); table->prune_features (lookups, &feature_indices); hb_map_t duplicate_feature_map; @@ -300,7 +302,6 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, plan->source, plan->_glyphset_gsub, plan->layout_features, - plan->flags & HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES, plan->gsub_lookups, plan->gsub_features, plan->gsub_langsys); @@ -310,7 +311,6 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, plan->source, plan->_glyphset_gsub, plan->layout_features, - plan->flags & HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES, plan->gpos_lookups, plan->gpos_features, plan->gpos_langsys); diff --git a/src/hb-subset.h b/src/hb-subset.h index 164a6f936..4f17bc5b8 100644 --- a/src/hb-subset.h +++ b/src/hb-subset.h @@ -61,10 +61,6 @@ typedef struct hb_subset_input_t hb_subset_input_t; * in the final subset. * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in * OS/2 will not be recalculated. - * @HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES: If set all layout features will be - * retained. If unset then the set accessed by - * hb_subset_input_layout_features_set() will be used to determine the features - * to be retained. * * List of boolean properties that can be configured on the subset input. * @@ -81,7 +77,6 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NOTDEF_OUTLINE = 0x00000040u, HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u, HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, - HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES = 0x00000200u, } hb_subset_flags_t; HB_EXTERN hb_subset_input_t * @@ -142,12 +137,6 @@ hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input); * Removed as of version 3.0.0 */ -HB_EXTERN void -hb_subset_input_set_retain_all_features (hb_subset_input_t *subset_input, - hb_bool_t value); -HB_EXTERN hb_bool_t -hb_subset_input_get_retain_all_features (hb_subset_input_t *subset_input); - HB_EXTERN void hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input, hb_bool_t drop_hints); diff --git a/test/api/test-subset.c b/test/api/test-subset.c index 31a03d180..89894f5c9 100644 --- a/test/api/test-subset.c +++ b/test/api/test-subset.c @@ -114,13 +114,13 @@ test_subset_set_flags (void) hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NAME_LEGACY | HB_SUBSET_FLAGS_NOTDEF_OUTLINE | - HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES); + HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES); g_assert (hb_subset_input_get_flags (input) == (hb_subset_flags_t) ( HB_SUBSET_FLAGS_NAME_LEGACY | HB_SUBSET_FLAGS_NOTDEF_OUTLINE | - HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES)); + HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)); hb_subset_input_destroy (input); diff --git a/util/hb-subset.cc b/util/hb-subset.cc index be135d1ba..8456ae93a 100644 --- a/util/hb-subset.cc +++ b/util/hb-subset.cc @@ -492,15 +492,9 @@ parse_layout_features (const char *name, if (0 == strcmp (arg, "*")) { - if (last_name_char == '-') - { - hb_set_clear (layout_features); - hb_subset_input_set_flags (subset_main->input, - hb_subset_input_get_flags (subset_main->input) & ~HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES); - } else { - hb_subset_input_set_flags (subset_main->input, - hb_subset_input_get_flags (subset_main->input) | HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES); - } + hb_set_clear (layout_features); + if (last_name_char != '-') + hb_set_invert (layout_features); return true; }