diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc index ad2d6b3fc..d459bb7eb 100644 --- a/src/hb-subset-input.cc +++ b/src/hb-subset-input.cc @@ -45,23 +45,10 @@ hb_subset_input_create_or_fail (void) if (unlikely (!input)) return nullptr; - input->unicodes = hb_set_create (); - input->glyphs = hb_set_create (); - input->name_ids = hb_set_create (); - hb_set_add_range (input->name_ids, 0, 6); - input->name_languages = hb_set_create (); - hb_set_add (input->name_languages, 0x0409); - input->layout_features = hb_set_create (); - input->drop_tables = hb_set_create (); - input->no_subset_tables = hb_set_create (); + for (auto& set : input->sets_iter ()) + set = hb_set_create (); - if (unlikely (input->unicodes->in_error () - || input->glyphs->in_error () - || input->name_ids->in_error () - || input->name_languages->in_error () - || input->layout_features->in_error () - || input->drop_tables->in_error () - || input->no_subset_tables->in_error ())) + if (input->in_error ()) { hb_subset_input_destroy (input); return nullptr; @@ -69,6 +56,9 @@ hb_subset_input_create_or_fail (void) input->flags = HB_SUBSET_FLAGS_DEFAULT; + hb_set_add_range (input->sets.name_ids, 0, 6); + hb_set_add (input->sets.name_languages, 0x0409); + hb_tag_t default_drop_tables[] = { // Layout disabled by default HB_TAG ('m', 'o', 'r', 'x'), @@ -93,7 +83,7 @@ hb_subset_input_create_or_fail (void) HB_TAG ('S', 'i', 'l', 'f'), HB_TAG ('S', 'i', 'l', 'l'), }; - input->drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables)); + input->sets.drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables)); hb_tag_t default_no_subset_tables[] = { HB_TAG ('a', 'v', 'a', 'r'), @@ -108,8 +98,8 @@ hb_subset_input_create_or_fail (void) HB_TAG ('c', 'v', 'a', 'r'), HB_TAG ('S', 'T', 'A', 'T'), }; - input->no_subset_tables->add_array (default_no_subset_tables, - ARRAY_LENGTH (default_no_subset_tables)); + input->sets.no_subset_tables->add_array (default_no_subset_tables, + ARRAY_LENGTH (default_no_subset_tables)); //copied from _layout_features_groups in fonttools hb_tag_t default_layout_features[] = { @@ -198,7 +188,13 @@ hb_subset_input_create_or_fail (void) HB_TAG ('b', 'l', 'w', 'm'), }; - input->layout_features->add_array (default_layout_features, ARRAY_LENGTH (default_layout_features)); + input->sets.layout_features->add_array (default_layout_features, ARRAY_LENGTH (default_layout_features)); + + if (input->in_error ()) + { + hb_subset_input_destroy (input); + return nullptr; + } return input; } @@ -232,13 +228,8 @@ hb_subset_input_destroy (hb_subset_input_t *input) { if (!hb_object_destroy (input)) return; - hb_set_destroy (input->unicodes); - hb_set_destroy (input->glyphs); - hb_set_destroy (input->name_ids); - hb_set_destroy (input->name_languages); - hb_set_destroy (input->drop_tables); - hb_set_destroy (input->layout_features); - hb_set_destroy (input->no_subset_tables); + for (hb_set_t* set : input->sets_iter ()) + hb_set_destroy (set); hb_free (input); } @@ -258,7 +249,7 @@ hb_subset_input_destroy (hb_subset_input_t *input) HB_EXTERN hb_set_t * hb_subset_input_unicode_set (hb_subset_input_t *input) { - return input->unicodes; + return input->sets.unicodes; } /** @@ -275,7 +266,7 @@ hb_subset_input_unicode_set (hb_subset_input_t *input) HB_EXTERN hb_set_t * hb_subset_input_glyph_set (hb_subset_input_t *input) { - return input->glyphs; + return input->sets.glyphs; } /** @@ -292,7 +283,7 @@ hb_subset_input_glyph_set (hb_subset_input_t *input) HB_EXTERN hb_set_t * hb_subset_input_nameid_set (hb_subset_input_t *input) { - return input->name_ids; + return input->sets.name_ids; } /** @@ -309,7 +300,7 @@ hb_subset_input_nameid_set (hb_subset_input_t *input) HB_EXTERN hb_set_t * hb_subset_input_namelangid_set (hb_subset_input_t *input) { - return input->name_languages; + return input->sets.name_languages; } @@ -327,7 +318,7 @@ hb_subset_input_namelangid_set (hb_subset_input_t *input) HB_EXTERN hb_set_t * hb_subset_input_layout_features_set (hb_subset_input_t *input) { - return input->layout_features; + return input->sets.layout_features; } /** @@ -344,7 +335,24 @@ hb_subset_input_layout_features_set (hb_subset_input_t *input) HB_EXTERN hb_set_t * hb_subset_input_drop_tables_set (hb_subset_input_t *input) { - return input->drop_tables; + return input->sets.drop_tables; +} + +/** + * hb_subset_input_set: + * @input: a #hb_subset_input_t object. + * @set_type: a #hb_subset_sets_t set type. + * + * Gets the set of the specified type. + * + * Return value: (transfer none): pointer to the #hb_set_t of the specified type. + * + * Since: REPLACEME + **/ +HB_EXTERN hb_set_t * +hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type) +{ + return input->sets_iter () [set_type]; } /** @@ -361,7 +369,7 @@ hb_subset_input_drop_tables_set (hb_subset_input_t *input) HB_EXTERN hb_set_t * hb_subset_input_no_subset_tables_set (hb_subset_input_t *input) { - return input->no_subset_tables; + return input->sets.no_subset_tables; } diff --git a/src/hb-subset-input.hh b/src/hb-subset-input.hh index ddc35f287..a3e28b056 100644 --- a/src/hb-subset-input.hh +++ b/src/hb-subset-input.hh @@ -31,6 +31,8 @@ #include "hb.hh" #include "hb-subset.h" +#include "hb-map.hh" +#include "hb-set.hh" #include "hb-font.hh" @@ -40,23 +42,40 @@ struct hb_subset_input_t { hb_object_header_t header; - hb_set_t *unicodes; // invert safe - hb_set_t *glyphs; // invert safe - hb_set_t *name_ids; // invert safe - hb_set_t *name_languages; // invert safe - hb_set_t *no_subset_tables; // invert safe - hb_set_t *drop_tables; // invert safe - hb_set_t *layout_features; // invert safe + union { + struct { + hb_set_t *glyphs; + hb_set_t *unicodes; + hb_set_t *no_subset_tables; + hb_set_t *drop_tables; + hb_set_t *name_ids; + hb_set_t *name_languages; + hb_set_t *layout_features; + } sets; + hb_set_t* set_ptrs[sizeof (sets) / sizeof (hb_set_t*)]; + }; unsigned flags; - /* TODO - * - * features - * lookups - * name_ids - * ... - */ + inline unsigned num_sets () const + { + return sizeof (set_ptrs) / sizeof (hb_set_t*); + } + + inline hb_array_t sets_iter () + { + return hb_array_t (set_ptrs, num_sets ()); + } + + bool in_error () const + { + for (unsigned i = 0; i < num_sets (); i++) + { + if (unlikely (set_ptrs[i]->in_error ())) + return true; + } + return false; + } }; diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index fb23a6488..677df35fa 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -456,13 +456,13 @@ hb_subset_plan_create (hb_face_t *face, plan->successful = true; plan->flags = input->flags; plan->unicodes = hb_set_create (); - plan->name_ids = hb_set_copy (input->name_ids); + plan->name_ids = hb_set_copy (input->sets.name_ids); _nameid_closure (face, plan->name_ids); - plan->name_languages = hb_set_copy (input->name_languages); - plan->layout_features = hb_set_copy (input->layout_features); - plan->glyphs_requested = hb_set_copy (input->glyphs); - plan->drop_tables = hb_set_copy (input->drop_tables); - plan->no_subset_tables = hb_set_copy (input->no_subset_tables); + plan->name_languages = hb_set_copy (input->sets.name_languages); + plan->layout_features = hb_set_copy (input->sets.layout_features); + plan->glyphs_requested = hb_set_copy (input->sets.glyphs); + plan->drop_tables = hb_set_copy (input->sets.drop_tables); + plan->no_subset_tables = hb_set_copy (input->sets.no_subset_tables); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); @@ -490,12 +490,12 @@ hb_subset_plan_create (hb_face_t *face, return plan; } - _populate_unicodes_to_retain (input->unicodes, input->glyphs, plan); + _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan); _populate_gids_to_retain (plan, - !input->drop_tables->has (HB_OT_TAG_GSUB), - !input->drop_tables->has (HB_OT_TAG_GPOS), - !input->drop_tables->has (HB_OT_TAG_GDEF)); + !input->sets.drop_tables->has (HB_OT_TAG_GSUB), + !input->sets.drop_tables->has (HB_OT_TAG_GPOS), + !input->sets.drop_tables->has (HB_OT_TAG_GDEF)); _create_old_gid_to_new_gid_map (face, input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS, diff --git a/src/hb-subset.h b/src/hb-subset.h index 4f17bc5b8..07ca4c241 100644 --- a/src/hb-subset.h +++ b/src/hb-subset.h @@ -79,6 +79,33 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, } hb_subset_flags_t; +/** + * hb_subset_sets_t: + * HB_SUBSET_SETS_GLYPH_INDEX: the set of glyph indexes to retain in the subset. + * HB_SUBSET_SETS_UNICODE: the set of unicode codepoints to retain in the subset. + * @HB_SUBSET_SETS_NO_SUBSET_TABLE_TAG: the set of table tags which specifies tables that should not be + * subsetted. + * @HB_SUBSET_SETS_DROP_TABLE_TAG: the set of table tags which specifies tables which will be dropped + * in the subset. + * @HB_SUBSET_SETS_NAME_ID: the set of name ids that will be retained. + * @HB_SUBSET_SETS_NAME_LANG_ID: the set of name lang ids that will be retained. + * @HB_SUBSET_SETS_LAYOUT_FEATURE_TAG: the set of layout feature tags that will be retained + * in the subset. + * + * List of sets that can be configured on the subset input. + * + * Since: REPLACEME + **/ +typedef enum { + HB_SUBSET_SETS_GLYPH_INDEX = 0, + HB_SUBSET_SETS_UNICODE, + HB_SUBSET_SETS_NO_SUBSET_TABLE_TAG, + HB_SUBSET_SETS_DROP_TABLE_TAG, + HB_SUBSET_SETS_NAME_ID, + HB_SUBSET_SETS_NAME_LANG_ID, + HB_SUBSET_SETS_LAYOUT_FEATURE_TAG, +} hb_subset_sets_t; + HB_EXTERN hb_subset_input_t * hb_subset_input_create_or_fail (void); @@ -120,6 +147,9 @@ hb_subset_input_no_subset_tables_set (hb_subset_input_t *input); HB_EXTERN hb_set_t * hb_subset_input_drop_tables_set (hb_subset_input_t *input); +HB_EXTERN hb_set_t * +hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type); + HB_EXTERN hb_subset_flags_t hb_subset_input_get_flags (hb_subset_input_t *input); diff --git a/test/api/test-subset.c b/test/api/test-subset.c index 89894f5c9..41017bc2f 100644 --- a/test/api/test-subset.c +++ b/test/api/test-subset.c @@ -127,6 +127,35 @@ test_subset_set_flags (void) } +static void +test_subset_sets (void) +{ + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t* set = hb_set_create (); + + hb_set_add (hb_subset_input_set (input, HB_SUBSET_SETS_GLYPH_INDEX), 83); + hb_set_add (hb_subset_input_set (input, HB_SUBSET_SETS_UNICODE), 85); + + hb_set_clear (hb_subset_input_set (input, HB_SUBSET_SETS_LAYOUT_FEATURE_TAG)); + hb_set_add (hb_subset_input_set (input, HB_SUBSET_SETS_LAYOUT_FEATURE_TAG), 87); + + hb_set_add (set, 83); + g_assert (hb_set_is_equal (hb_subset_input_glyph_set (input), set)); + hb_set_clear (set); + + hb_set_add (set, 85); + g_assert (hb_set_is_equal (hb_subset_input_unicode_set (input), set)); + hb_set_clear (set); + + hb_set_add (set, 87); + g_assert (hb_set_is_equal (hb_subset_input_layout_features_set (input), set)); + hb_set_clear (set); + + hb_set_destroy (set); + hb_subset_input_destroy (input); +} + + static void test_subset_legacy_api (void) { @@ -185,6 +214,7 @@ main (int argc, char **argv) hb_test_add (test_subset_no_inf_loop); hb_test_add (test_subset_crash); hb_test_add (test_subset_set_flags); + hb_test_add (test_subset_sets); hb_test_add (test_subset_legacy_api); return hb_test_run();