From 8ffc9add2237899afc57184ad3297404659bc1cd Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Thu, 31 Oct 2019 15:59:02 -0700 Subject: [PATCH] [subset] layout closure_features and store them in subset-plan --- docs/harfbuzz-sections.txt | 1 + src/hb-ot-layout-common.hh | 35 +++++++++++++++++++++++ src/hb-ot-layout-gsubgpos.hh | 14 +++++++++ src/hb-ot-layout.cc | 21 ++++++++++++++ src/hb-ot-layout.h | 6 ++++ src/hb-subset-plan.cc | 55 +++++++++++++++++++++++++----------- src/hb-subset-plan.hh | 4 +++ 7 files changed, 120 insertions(+), 16 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 1cf731c26..a6f75bf68 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -552,6 +552,7 @@ HB_OT_TAG_GSUB HB_OT_TAG_JSTF hb_ot_layout_baseline_tag_t hb_ot_layout_closure_lookups +hb_ot_layout_closure_features hb_ot_layout_collect_lookups hb_ot_layout_collect_features hb_ot_layout_feature_get_characters diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index fec8f1ec5..880b58217 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -289,6 +289,9 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, RangeRecord); struct IndexArray : ArrayOf { + bool intersects (const hb_map_t *indexes) const + { return hb_any (*this, indexes); } + unsigned int get_indexes (unsigned int start_offset, unsigned int *_count /* IN/OUT */, unsigned int *_indexes /* OUT */) const @@ -682,6 +685,9 @@ struct Feature const FeatureParams &get_feature_params () const { return this+featureParams; } + bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const + { return lookupIndex.intersects (lookup_indexes); } + bool subset (hb_subset_context_t *c, RecordList_subset_context_t *r) const { TRACE_SUBSET (this); @@ -2304,6 +2310,14 @@ struct FeatureTableSubstitutionRecord return (base+feature).add_lookup_indexes_to (lookup_indexes); } + void closure_features (const void *base, + const hb_map_t *lookup_indexes, + hb_set_t *feature_indexes /* OUT */) const + { + if ((base+feature).intersects_lookup_indexes (lookup_indexes)) + feature_indexes->add (featureIndex); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -2343,6 +2357,13 @@ struct FeatureTableSubstitution ; } + void closure_features (const hb_map_t *lookup_indexes, + hb_set_t *feature_indexes /* OUT */) const + { + for (const FeatureTableSubstitutionRecord& record : substitutions) + record.closure_features (this, lookup_indexes, feature_indexes); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -2370,6 +2391,13 @@ struct FeatureVariationRecord return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes); } + void closure_features (const void *base, + const hb_map_t *lookup_indexes, + hb_set_t *feature_indexes /* OUT */) const + { + (base+substitutions).closure_features (lookup_indexes, feature_indexes); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -2427,6 +2455,13 @@ struct FeatureVariations r.collect_lookups (this, feature_indexes, lookup_indexes); } + void closure_features (const hb_map_t *lookup_indexes, + hb_set_t *feature_indexes /* OUT */) const + { + for (const FeatureVariationRecord& record : varRecords) + record.closure_features (this, lookup_indexes, feature_indexes); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 78f2bf374..7cc691d47 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -3083,6 +3083,20 @@ struct GSUBGPOS return_trace (true); } + void closure_features (const hb_map_t *lookup_indexes, /* IN */ + hb_set_t *feature_indexes /* OUT */) const + { + for (unsigned i = 0; i < get_feature_count (); i++) + { + if (get_feature (i).intersects_lookup_indexes (lookup_indexes)) + feature_indexes->add (i); + } +#ifndef HB_NO_VAR + if (version.to_int () >= 0x00010001u) + (this+featureVars).closure_features (lookup_indexes, feature_indexes); +#endif + } + unsigned int get_size () const { return min_size + diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 7ba33c5b4..c165b1ecf 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1238,6 +1238,27 @@ hb_ot_layout_closure_lookups (hb_face_t *face, hb_set_subtract (lookup_indexes, &inactive_lookups); } +/** + * hb_ot_layout_closure_features: + * @face: #hb_face_t to work upon + * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @lookup_indexes: (in): collected active lookup_indices + * @feature_indexes: (out): all active feature indexes collected + * + * Returns all active feature indexes + * + * Since: REPLACEME + **/ +void +hb_ot_layout_closure_features (hb_face_t *face, + hb_tag_t table_tag, + const hb_map_t *lookup_indexes, /* IN */ + hb_set_t *feature_indexes /* OUT */) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + g.closure_features (lookup_indexes, feature_indexes); +} + #ifndef HB_NO_LAYOUT_COLLECT_GLYPHS /** diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 3fc22b788..c0cb2a523 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -269,6 +269,12 @@ hb_ot_layout_closure_lookups (hb_face_t *face, const hb_set_t *glyphs, hb_set_t *lookup_indexes /* IN/OUT */); +HB_EXTERN void +hb_ot_layout_closure_features (hb_face_t *face, + hb_tag_t table_tag, + const hb_map_t *lookup_indexes, /* IN */ + hb_set_t *feature_indexes /* OUT */); + HB_EXTERN void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 063b2839d..beb044760 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -51,20 +51,21 @@ _add_cff_seac_components (const OT::cff1::accelerator_t &cff, #ifndef HB_NO_SUBSET_LAYOUT static void -_remap_lookups (const hb_set_t *lookup_indices, - hb_map_t *lookups /* OUT */) +_remap_indexes (const hb_set_t *indexes, + hb_map_t *mapping /* OUT */) { - unsigned count = lookup_indices->get_population (); + unsigned count = indexes->get_population (); - for (auto _ : + hb_zip (lookup_indices->iter (), hb_range (count))) - lookups->set (_.first, _.second); + for (auto _ : + hb_zip (indexes->iter (), hb_range (count))) + mapping->set (_.first, _.second); } static inline void -_gsub_closure_glyphs_and_lookups (hb_face_t *face, - hb_set_t *gids_to_retain, - hb_map_t *gsub_lookups) +_gsub_closure_glyphs_lookups_features (hb_face_t *face, + hb_set_t *gids_to_retain, + hb_map_t *gsub_lookups, + hb_map_t *gsub_features) { hb_set_t lookup_indices; hb_ot_layout_collect_lookups (face, @@ -80,13 +81,22 @@ _gsub_closure_glyphs_and_lookups (hb_face_t *face, HB_OT_TAG_GSUB, gids_to_retain, &lookup_indices); - _remap_lookups (&lookup_indices, gsub_lookups); + _remap_indexes (&lookup_indices, gsub_lookups); + + //closure features + hb_set_t feature_indices; + hb_ot_layout_closure_features (face, + HB_OT_TAG_GSUB, + gsub_lookups, + &feature_indices); + _remap_indexes (&feature_indices, gsub_features); } static inline void -_gpos_closure_lookups (hb_face_t *face, - const hb_set_t *gids_to_retain, - hb_map_t *gpos_lookups) +_gpos_closure_lookups_features (hb_face_t *face, + const hb_set_t *gids_to_retain, + hb_map_t *gpos_lookups, + hb_map_t *gpos_features) { hb_set_t lookup_indices; hb_ot_layout_collect_lookups (face, @@ -99,7 +109,15 @@ _gpos_closure_lookups (hb_face_t *face, HB_OT_TAG_GPOS, gids_to_retain, &lookup_indices); - _remap_lookups (&lookup_indices, gpos_lookups); + _remap_indexes (&lookup_indices, gpos_lookups); + + //closure features + hb_set_t feature_indices; + hb_ot_layout_closure_features (face, + HB_OT_TAG_GPOS, + gpos_lookups, + &feature_indices); + _remap_indexes (&feature_indices, gpos_features); } #endif @@ -165,11 +183,11 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, #ifndef HB_NO_SUBSET_LAYOUT if (close_over_gsub) - // closure all glyphs/lookups needed for GSUB substitutions. - _gsub_closure_glyphs_and_lookups (plan->source, plan->_glyphset_gsub, plan->gsub_lookups); + // closure all glyphs/lookups/features needed for GSUB substitutions. + _gsub_closure_glyphs_lookups_features (plan->source, plan->_glyphset_gsub, plan->gsub_lookups, plan->gsub_features); if (close_over_gpos) - _gpos_closure_lookups (plan->source, plan->_glyphset_gsub, plan->gpos_lookups); + _gpos_closure_lookups_features (plan->source, plan->_glyphset_gsub, plan->gpos_lookups, plan->gpos_features); #endif _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); @@ -274,6 +292,8 @@ hb_subset_plan_create (hb_face_t *face, plan->reverse_glyph_map = hb_map_create (); plan->gsub_lookups = hb_map_create (); plan->gpos_lookups = hb_map_create (); + plan->gsub_features = hb_map_create (); + plan->gpos_features = hb_map_create (); _populate_gids_to_retain (plan, input->unicodes, @@ -313,6 +333,9 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_set_destroy (plan->_glyphset_gsub); hb_map_destroy (plan->gsub_lookups); hb_map_destroy (plan->gpos_lookups); + hb_map_destroy (plan->gsub_features); + hb_map_destroy (plan->gpos_features); + free (plan); } diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index 3c5b66b04..22bbac980 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -71,6 +71,10 @@ struct hb_subset_plan_t hb_map_t *gsub_lookups; hb_map_t *gpos_lookups; + //active features we'd like to retain + hb_map_t *gsub_features; + hb_map_t *gpos_features; + public: /*