From 7b77cd198c0352b6ed2a0adbee68bb3e246b9658 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Mon, 13 Mar 2023 12:45:43 -0700 Subject: [PATCH 1/5] [subset] fix bug in CPAL V1tail serialization We should serialize nameIDs rather than retained color index --- src/OT/Color/CPAL/CPAL.hh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/OT/Color/CPAL/CPAL.hh b/src/OT/Color/CPAL/CPAL.hh index 4914a0ed5..6646b083e 100644 --- a/src/OT/Color/CPAL/CPAL.hh +++ b/src/OT/Color/CPAL/CPAL.hh @@ -95,13 +95,10 @@ struct CPALV1Tail if (colorLabelsZ) { c->push (); - for (const auto _ : colorLabels) + for (unsigned i = 0; i < color_count; i++) { - const hb_codepoint_t *v; - if (!color_index_map->has (_, &v)) continue; - NameID new_color_idx; - new_color_idx = *v; - if (!c->copy (new_color_idx)) + if (!color_index_map->has (i)) continue; + if (!c->copy (colorLabels[i])) { c->pop_discard (); return_trace (false); From de6533d8850944e71d5d69c6257ef85f1bf16b1f Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Mon, 13 Mar 2023 13:36:00 -0700 Subject: [PATCH 2/5] [subset] collect name_ids from CPAL table --- src/OT/Color/CPAL/CPAL.hh | 31 +++++++++++++++++++++++++++++ src/hb-subset-plan.cc | 41 ++++++++++++++++++++++++--------------- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/OT/Color/CPAL/CPAL.hh b/src/OT/Color/CPAL/CPAL.hh index 6646b083e..c07716c1c 100644 --- a/src/OT/Color/CPAL/CPAL.hh +++ b/src/OT/Color/CPAL/CPAL.hh @@ -73,6 +73,30 @@ struct CPALV1Tail } public: + void collect_name_ids (const void *base, + unsigned palette_count, + unsigned color_count, + const hb_map_t *color_index_map, + hb_set_t *nameids_to_retain /* OUT */) const + { + if (paletteLabelsZ) + { + + (base+paletteLabelsZ).as_array (palette_count) + | hb_sink (nameids_to_retain) + ; + } + + if (colorLabelsZ) + { + const hb_array_t colorLabels = (base+colorLabelsZ).as_array (color_count); + for (unsigned i = 0; i < color_count; i++) + { + if (!color_index_map->has (i)) continue; + nameids_to_retain->add (colorLabels[i]); + } + } + } + bool serialize (hb_serialize_context_t *c, unsigned palette_count, unsigned color_count, @@ -186,6 +210,13 @@ struct CPAL return numColors; } + void collect_name_ids (const hb_map_t *color_index_map, + hb_set_t *nameids_to_retain /* OUT */) const + { + if (version == 1) + v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain); + } + private: const CPALV1Tail& v1 () const { diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 088fdca07..bf6fe1784 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -38,6 +38,7 @@ #include "hb-ot-cff1-table.hh" #include "OT/Color/COLR/COLR.hh" #include "OT/Color/COLR/colrv1-closure.hh" +#include "OT/Color/CPAL/CPAL.hh" #include "hb-ot-var-fvar-table.hh" #include "hb-ot-var-avar-table.hh" #include "hb-ot-stat-table.hh" @@ -620,6 +621,26 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, return operation_count; } +static void +_nameid_closure (hb_face_t *face, + hb_set_t *nameids, + bool all_axes_pinned, + hb_hashmap_t *user_axes_location, + bool collect_cpal_name_ids, + const hb_map_t *color_index_map) +{ +#ifndef HB_NO_STYLE + face->table.STAT->collect_name_ids (user_axes_location, nameids); +#endif +#ifndef HB_NO_VAR + if (!all_axes_pinned) + face->table.fvar->collect_name_ids (user_axes_location, nameids); +#endif + + if (collect_cpal_name_ids) + face->table.CPAL->collect_name_ids (color_index_map, nameids); +} + static void _populate_gids_to_retain (hb_subset_plan_t* plan, hb_set_t* drop_tables) @@ -673,6 +694,10 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, plan->_glyphset_colred = cur_glyphset; + _nameid_closure (plan->source, &(plan->name_ids), + plan->all_axes_pinned, &(plan->user_axes_location), + !drop_tables->has (HB_OT_TAG_CPAL), + &(plan->colr_palettes)); /* Populate a full set of glyphs to retain by adding all referenced * composite glyphs. */ if (glyf.has_data ()) @@ -756,21 +781,6 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, ; } -static void -_nameid_closure (hb_face_t *face, - hb_set_t *nameids, - bool all_axes_pinned, - hb_hashmap_t *user_axes_location) -{ -#ifndef HB_NO_STYLE - face->table.STAT->collect_name_ids (user_axes_location, nameids); -#endif -#ifndef HB_NO_VAR - if (!all_axes_pinned) - face->table.fvar->collect_name_ids (user_axes_location, nameids); -#endif -} - #ifndef HB_NO_VAR static void _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) @@ -905,7 +915,6 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second); } - _nameid_closure (face, &name_ids, all_axes_pinned, &user_axes_location); if (unlikely (in_error ())) return; From 125450d2f220821e63fe748475611c66905904e8 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Mon, 13 Mar 2023 15:43:29 -0700 Subject: [PATCH 3/5] [subset] collect name_ids for FeratureParams --- src/hb-ot-layout-common.hh | 39 ++++++++++++++++++++++++++++++++++++ src/hb-ot-layout-gsubgpos.hh | 12 +++++++++++ src/hb-subset-plan.cc | 38 +++++++++++++++++++++-------------- 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index b53f2e927..9d1c10582 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -529,6 +529,9 @@ struct FeatureParamsSize return_trace (true); } + void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const + { nameids_to_retain->add (subfamilyNameID); } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -585,6 +588,9 @@ struct FeatureParamsStylisticSet return_trace (c->check_struct (this)); } + void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const + { nameids_to_retain->add (uiNameID); } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -632,6 +638,20 @@ struct FeatureParamsCharacterVariants unsigned get_size () const { return min_size + characters.len * HBUINT24::static_size; } + void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const + { + if (featUILableNameID) nameids_to_retain->add (featUILableNameID); + if (featUITooltipTextNameID) nameids_to_retain->add (featUITooltipTextNameID); + if (sampleTextNameID) nameids_to_retain->add (sampleTextNameID); + + if (!firstParamUILabelNameID || !numNamedParameters || numNamedParameters >= 0x7FFF) + return; + + unsigned last_name_id = (unsigned) firstParamUILabelNameID + (unsigned) numNamedParameters - 1; + if (last_name_id >= 256 && last_name_id <= 32767) + nameids_to_retain->add_range (firstParamUILabelNameID, last_name_id); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -694,6 +714,19 @@ struct FeatureParams return_trace (true); } + void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const + { +#ifdef HB_NO_LAYOUT_FEATURE_PARAMS + return; +#endif + if (tag == HB_TAG ('s','i','z','e')) + return (u.size.collect_name_ids (nameids_to_retain)); + if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ + return (u.stylisticSet.collect_name_ids (nameids_to_retain)); + if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ + return (u.characterVariants.collect_name_ids (nameids_to_retain)); + } + bool subset (hb_subset_context_t *c, const Tag* tag) const { TRACE_SUBSET (this); @@ -762,6 +795,12 @@ struct Feature bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const { return lookupIndex.intersects (lookup_indexes); } + void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const + { + if (featureParams) + get_feature_params ().collect_name_ids (tag, nameids_to_retain); + } + bool subset (hb_subset_context_t *c, hb_subset_layout_context_t *l, const Tag *tag = nullptr) const diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 10cc105de..07a6db777 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -4461,6 +4461,18 @@ struct GSUBGPOS } } + void collect_name_ids (const hb_map_t *feature_index_map, + hb_set_t *nameids_to_retain /* OUT */) const + { + unsigned count = get_feature_count (); + for (unsigned i = 0 ; i < count; i++) + { + if (!feature_index_map->has (i)) continue; + hb_tag_t tag = get_feature_tag (i); + get_feature (i).collect_name_ids (tag, nameids_to_retain); + } + } + template struct accelerator_t { diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index bf6fe1784..5ac22e7c8 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -622,23 +622,34 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, } static void -_nameid_closure (hb_face_t *face, - hb_set_t *nameids, - bool all_axes_pinned, - hb_hashmap_t *user_axes_location, - bool collect_cpal_name_ids, - const hb_map_t *color_index_map) +_nameid_closure (hb_subset_plan_t* plan, + hb_set_t* drop_tables) { #ifndef HB_NO_STYLE - face->table.STAT->collect_name_ids (user_axes_location, nameids); + plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids); #endif #ifndef HB_NO_VAR - if (!all_axes_pinned) - face->table.fvar->collect_name_ids (user_axes_location, nameids); + if (!plan->all_axes_pinned) + plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids); #endif - if (collect_cpal_name_ids) - face->table.CPAL->collect_name_ids (color_index_map, nameids); + if (!drop_tables->has (HB_OT_TAG_CPAL)) + plan->source->table.CPAL->collect_name_ids (&plan->colr_palettes, &plan->name_ids); + +#ifndef HB_NO_SUBSET_LAYOUT + if (!drop_tables->has (HB_OT_TAG_GPOS)) + { + hb_blob_ptr_t gpos = plan->source_table (); + gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids); + gpos.destroy (); + } + if (!drop_tables->has (HB_OT_TAG_GSUB)) + { + hb_blob_ptr_t gsub = plan->source_table (); + gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids); + gsub.destroy (); + } +#endif } static void @@ -694,10 +705,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, plan->_glyphset_colred = cur_glyphset; - _nameid_closure (plan->source, &(plan->name_ids), - plan->all_axes_pinned, &(plan->user_axes_location), - !drop_tables->has (HB_OT_TAG_CPAL), - &(plan->colr_palettes)); + _nameid_closure (plan, drop_tables); /* Populate a full set of glyphs to retain by adding all referenced * composite glyphs. */ if (glyf.has_data ()) From 0d65738633f84cfbf69325edb8189ee0184d50cf Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Mon, 13 Mar 2023 15:51:45 -0700 Subject: [PATCH 4/5] [subset] collect elidedFallbackNameID in STAT table --- src/hb-ot-stat-table.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh index 2006f677d..de553dd72 100644 --- a/src/hb-ot-stat-table.hh +++ b/src/hb-ot-stat-table.hh @@ -536,6 +536,8 @@ struct STAT | hb_map (&AxisValue::get_value_name_id) | hb_sink (nameids_to_retain) ; + + nameids_to_retain->add (elidedFallbackNameID); } bool subset (hb_subset_context_t *c) const From 204e155acbf6a9311a13efd4400d2a7b52ca609a Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Tue, 14 Mar 2023 10:25:31 -0700 Subject: [PATCH 5/5] [subset] Add tests for collecting name_ids from STAT and FeatureParams --- test/subset/data/Makefile.am | 1 + test/subset/data/Makefile.sources | 1 + ...all-layout-features.retain-all-codepoint.otf | Bin 0 -> 12796 bytes .../fonts/SourceSerif4Variable-Roman_subset.otf | Bin 0 -> 12784 bytes test/subset/data/tests/collect_name_ids.tests | 11 +++++++++++ test/subset/meson.build | 1 + 6 files changed, 14 insertions(+) create mode 100644 test/subset/data/expected/collect_name_ids/SourceSerif4Variable-Roman_subset.keep-all-layout-features.retain-all-codepoint.otf create mode 100644 test/subset/data/fonts/SourceSerif4Variable-Roman_subset.otf create mode 100644 test/subset/data/tests/collect_name_ids.tests diff --git a/test/subset/data/Makefile.am b/test/subset/data/Makefile.am index 5eee05780..864db2d86 100644 --- a/test/subset/data/Makefile.am +++ b/test/subset/data/Makefile.am @@ -67,6 +67,7 @@ EXTRA_DIST += \ expected/instance_comp_glyph_empty_child \ expected/post_apply_mvar_delta \ expected/apply_cvar_delta \ + expected/collect_name_ids \ fonts \ profiles \ $(NULL) diff --git a/test/subset/data/Makefile.sources b/test/subset/data/Makefile.sources index 6fbb6ff53..6437c00d3 100644 --- a/test/subset/data/Makefile.sources +++ b/test/subset/data/Makefile.sources @@ -58,6 +58,7 @@ TESTS = \ tests/instance_comp_glyph_empty_child.tests \ tests/post_apply_mvar_delta.tests \ tests/apply_cvar_delta.tests \ + tests/collect_name_ids.tests \ $(NULL) # TODO: re-enable once colrv1 subsetting is stabilized. diff --git a/test/subset/data/expected/collect_name_ids/SourceSerif4Variable-Roman_subset.keep-all-layout-features.retain-all-codepoint.otf b/test/subset/data/expected/collect_name_ids/SourceSerif4Variable-Roman_subset.keep-all-layout-features.retain-all-codepoint.otf new file mode 100644 index 0000000000000000000000000000000000000000..c375eaa4407f63491d5251ce67ca265151eade0c GIT binary patch literal 12796 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 literal 0 HcmV?d00001 diff --git a/test/subset/data/fonts/SourceSerif4Variable-Roman_subset.otf b/test/subset/data/fonts/SourceSerif4Variable-Roman_subset.otf new file mode 100644 index 0000000000000000000000000000000000000000..e3a9f7b091e05f8cae06cd4e1228c17f248d80a0 GIT binary patch literal 12784 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 literal 0 HcmV?d00001 diff --git a/test/subset/data/tests/collect_name_ids.tests b/test/subset/data/tests/collect_name_ids.tests new file mode 100644 index 000000000..06b5cf703 --- /dev/null +++ b/test/subset/data/tests/collect_name_ids.tests @@ -0,0 +1,11 @@ +FONTS: +SourceSerif4Variable-Roman_subset.otf + +PROFILES: +keep-all-layout-features.txt + +SUBSETS: +* + +OPTIONS: +no_fonttools diff --git a/test/subset/meson.build b/test/subset/meson.build index cf3e80be1..4f360a34f 100644 --- a/test/subset/meson.build +++ b/test/subset/meson.build @@ -60,6 +60,7 @@ tests = [ 'instance_comp_glyph_empty_child', 'post_apply_mvar_delta', 'apply_cvar_delta', + 'collect_name_ids', ] repack_tests = [