From be8e8e8c80cc69d9d3a02f357a3ef252738d96e6 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Thu, 30 Jun 2022 14:24:36 -0700 Subject: [PATCH] [instance] prune name tables after axes pinned at fixed locations Restricting axes to ranges is not supported yet. --- src/hb-ot-stat-table.hh | 19 +++++++++++++- src/hb-ot-var-fvar-table.hh | 51 +++++++++++++++++++++++++++---------- src/hb-subset-plan.cc | 11 +++++--- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh index e3a2e89a0..95d2a4bd5 100644 --- a/src/hb-ot-stat-table.hh +++ b/src/hb-ot-stat-table.hh @@ -401,6 +401,18 @@ struct AxisValue } } + bool keep_axis_value (const hb_array_t axis_records, + hb_hashmap_t *user_axes_location) const + { + switch (u.format) + { + case 1: return u.format1.keep_axis_value (axis_records, user_axes_location); + case 2: return u.format2.keep_axis_value (axis_records, user_axes_location); + case 3: return u.format3.keep_axis_value (axis_records, user_axes_location); + case 4: return u.format4.keep_axis_value (axis_records, user_axes_location); + default:return false; + } + } bool sanitize (hb_sanitize_context_t *c) const { @@ -505,7 +517,8 @@ struct STAT return axis_value.get_value_name_id (); } - void collect_name_ids (hb_set_t *nameids_to_retain) const + void collect_name_ids (hb_hashmap_t *user_axes_location, + hb_set_t *nameids_to_retain /* OUT */) const { if (!has_data ()) return; @@ -514,8 +527,12 @@ struct STAT | hb_sink (nameids_to_retain) ; + auto designAxes = get_design_axes (); + + get_axis_value_offsets () | hb_map (hb_add (&(this + offsetToAxisValueOffsets))) + | hb_filter ([&] (const AxisValue& _) + { return _.keep_axis_value (designAxes, user_axes_location); }) | hb_map (&AxisValue::get_value_name_id) | hb_sink (nameids_to_retain) ; diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 6300a42b8..77bb551e2 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -272,24 +272,49 @@ struct fvar return axisCount; } - void collect_name_ids (hb_set_t *nameids) const + void collect_name_ids (hb_hashmap_t *user_axes_location, + hb_set_t *nameids /* IN/OUT */) const { if (!has_data ()) return; + hb_map_t pinned_axes; - + get_axes () - | hb_map (&AxisRecord::get_name_id) - | hb_sink (nameids) - ; + auto axis_records = get_axes (); + for (unsigned i = 0 ; i < (unsigned)axisCount; i++) + { + hb_tag_t axis_tag = axis_records[i].get_axis_tag (); + if (user_axes_location->has (axis_tag)) + { + pinned_axes.set (i, axis_tag); + continue; + } - + hb_range ((unsigned) instanceCount) - | hb_map ([this] (const unsigned _) { return get_instance_subfamily_name_id (_); }) - | hb_sink (nameids) - ; + nameids->add (axis_records[i].get_name_id ()); + } - + hb_range ((unsigned) instanceCount) - | hb_map ([this] (const unsigned _) { return get_instance_postscript_name_id (_); }) - | hb_sink (nameids) - ; + for (unsigned i = 0 ; i < (unsigned)instanceCount; i++) + { + const InstanceRecord *instance = get_instance (i); + + if (hb_any (+ hb_zip (instance->get_coordinates (axisCount), hb_range ((unsigned)axisCount)) + | hb_filter (pinned_axes, hb_second) + | hb_map ([&] (const hb_pair_t& _) + { + hb_tag_t axis_tag = pinned_axes.get (_.second); + float location = user_axes_location->get (axis_tag); + if (fabs ((double)location - (double)_.first.to_float ()) > 0.001) return true; + return false; + }) + )) + continue; + + nameids->add (instance->subfamilyNameID); + + if (instanceSize >= axisCount * 4 + 6) + { + unsigned post_script_name_id = StructAfter (instance->get_coordinates (axisCount)); + if (post_script_name_id != HB_OT_NAME_ID_INVALID) nameids->add (post_script_name_id); + } + } } public: diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 6dd0a2880..29b89c774 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -576,13 +576,16 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, static void _nameid_closure (hb_face_t *face, - hb_set_t *nameids) + hb_set_t *nameids, + bool all_axes_pinned, + hb_hashmap_t *user_axes_location) { #ifndef HB_NO_STYLE - face->table.STAT->collect_name_ids (nameids); + face->table.STAT->collect_name_ids (user_axes_location, nameids); #endif #ifndef HB_NO_VAR - face->table.fvar->collect_name_ids (nameids); + if (!all_axes_pinned) + face->table.fvar->collect_name_ids (user_axes_location, nameids); #endif } @@ -658,7 +661,6 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->unicode_to_new_gid_list.init (); plan->name_ids = hb_set_copy (input->sets.name_ids); - _nameid_closure (face, plan->name_ids); plan->name_languages = hb_set_copy (input->sets.name_languages); plan->layout_features = hb_set_copy (input->sets.layout_features); plan->layout_scripts = hb_set_copy (input->sets.layout_scripts); @@ -733,6 +735,7 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->axes_location, plan->all_axes_pinned); + _nameid_closure (face, plan->name_ids, plan->all_axes_pinned, plan->user_axes_location); if (unlikely (plan->in_error ())) { hb_subset_plan_destroy (plan); return nullptr;