[instance] prune name tables after axes pinned at fixed locations

Restricting axes to ranges is not supported yet.
This commit is contained in:
Qunxin Liu 2022-06-30 14:24:36 -07:00 committed by Garret Rieger
parent df55f840cb
commit be8e8e8c80
3 changed files with 63 additions and 18 deletions

View File

@ -401,6 +401,18 @@ struct AxisValue
} }
} }
bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
hb_hashmap_t<hb_tag_t, float> *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 bool sanitize (hb_sanitize_context_t *c) const
{ {
@ -505,7 +517,8 @@ struct STAT
return axis_value.get_value_name_id (); 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<hb_tag_t, float> *user_axes_location,
hb_set_t *nameids_to_retain /* OUT */) const
{ {
if (!has_data ()) return; if (!has_data ()) return;
@ -514,8 +527,12 @@ struct STAT
| hb_sink (nameids_to_retain) | hb_sink (nameids_to_retain)
; ;
auto designAxes = get_design_axes ();
+ get_axis_value_offsets () + get_axis_value_offsets ()
| hb_map (hb_add (&(this + offsetToAxisValueOffsets))) | 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_map (&AxisValue::get_value_name_id)
| hb_sink (nameids_to_retain) | hb_sink (nameids_to_retain)
; ;

View File

@ -272,24 +272,49 @@ struct fvar
return axisCount; return axisCount;
} }
void collect_name_ids (hb_set_t *nameids) const void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location,
hb_set_t *nameids /* IN/OUT */) const
{ {
if (!has_data ()) return; if (!has_data ()) return;
hb_map_t pinned_axes;
+ get_axes () auto axis_records = get_axes ();
| hb_map (&AxisRecord::get_name_id) for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
| hb_sink (nameids) {
; 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) nameids->add (axis_records[i].get_name_id ());
| hb_map ([this] (const unsigned _) { return get_instance_subfamily_name_id (_); }) }
| hb_sink (nameids)
;
+ hb_range ((unsigned) instanceCount) for (unsigned i = 0 ; i < (unsigned)instanceCount; i++)
| hb_map ([this] (const unsigned _) { return get_instance_postscript_name_id (_); }) {
| hb_sink (nameids) 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<const HBFixed&, unsigned>& _)
{
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<NameID> (instance->get_coordinates (axisCount));
if (post_script_name_id != HB_OT_NAME_ID_INVALID) nameids->add (post_script_name_id);
}
}
} }
public: public:

View File

@ -576,13 +576,16 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
static void static void
_nameid_closure (hb_face_t *face, _nameid_closure (hb_face_t *face,
hb_set_t *nameids) hb_set_t *nameids,
bool all_axes_pinned,
hb_hashmap_t<hb_tag_t, float> *user_axes_location)
{ {
#ifndef HB_NO_STYLE #ifndef HB_NO_STYLE
face->table.STAT->collect_name_ids (nameids); face->table.STAT->collect_name_ids (user_axes_location, nameids);
#endif #endif
#ifndef HB_NO_VAR #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 #endif
} }
@ -658,7 +661,6 @@ hb_subset_plan_create_or_fail (hb_face_t *face,
plan->unicode_to_new_gid_list.init (); plan->unicode_to_new_gid_list.init ();
plan->name_ids = hb_set_copy (input->sets.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->sets.name_languages); plan->name_languages = hb_set_copy (input->sets.name_languages);
plan->layout_features = hb_set_copy (input->sets.layout_features); plan->layout_features = hb_set_copy (input->sets.layout_features);
plan->layout_scripts = hb_set_copy (input->sets.layout_scripts); 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->axes_location,
plan->all_axes_pinned); plan->all_axes_pinned);
_nameid_closure (face, plan->name_ids, plan->all_axes_pinned, plan->user_axes_location);
if (unlikely (plan->in_error ())) { if (unlikely (plan->in_error ())) {
hb_subset_plan_destroy (plan); hb_subset_plan_destroy (plan);
return nullptr; return nullptr;