[instancer] update fvar table to accept Tripe for axes positions

pull/4235/head
Qunxin Liu 2 years ago committed by Garret Rieger
parent bf46d566f9
commit 51c7451bb5
  1. 2
      src/hb-ot-stat-table.hh
  2. 78
      src/hb-ot-var-fvar-table.hh
  3. 2
      src/hb-subset-plan.cc

@ -59,7 +59,7 @@ enum
#ifndef HB_NO_VAR
static bool axis_value_is_outside_axis_range (hb_tag_t axis_tag, float axis_value,
const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location)
{
if (!user_axes_location->has (axis_tag))
return false;

@ -47,6 +47,37 @@ struct InstanceRecord
hb_array_t<const F16DOT16> get_coordinates (unsigned int axis_count) const
{ return coordinatesZ.as_array (axis_count); }
bool keep_instance (unsigned axis_count,
const hb_map_t *axes_index_tag_map,
const hb_hashmap_t<hb_tag_t, Triple> *axes_location) const
{
if (axes_location->is_empty ()) return true;
const hb_array_t<const F16DOT16> coords = get_coordinates (axis_count);
for (unsigned i = 0 ; i < axis_count; i++)
{
uint32_t *axis_tag;
if (!axes_index_tag_map->has (i, &axis_tag))
return false;
if (!axes_location->has (*axis_tag))
continue;
Triple axis_limit = axes_location->get (*axis_tag);
float axis_coord = coords[i].to_float ();
if (axis_limit.is_point ())
{
if (axis_limit.minimum != axis_coord)
return false;
}
else
{
if (axis_coord < axis_limit.minimum ||
axis_coord > axis_limit.maximum)
return false;
}
}
return true;
}
bool subset (hb_subset_context_t *c,
unsigned axis_count,
bool has_postscript_nameid) const
@ -56,19 +87,29 @@ struct InstanceRecord
if (unlikely (!c->serializer->embed (flags))) return_trace (false);
const hb_array_t<const F16DOT16> coords = get_coordinates (axis_count);
const hb_hashmap_t<hb_tag_t, float> *axes_location = &c->plan->user_axes_location;
const hb_hashmap_t<hb_tag_t, Triple> *axes_location = &c->plan->user_axes_location;
for (unsigned i = 0 ; i < axis_count; i++)
{
uint32_t *axis_tag;
// only keep instances whose coordinates == pinned axis location
if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) continue;
if (axes_location->has (*axis_tag) &&
fabsf (axes_location->get (*axis_tag) - coords[i].to_float ()) > 0.001f)
return_trace (false);
if (!c->plan->axes_index_map.has (i))
continue;
if (axes_location->has (*axis_tag))
{
Triple axis_limit = axes_location->get (*axis_tag);
float axis_coord = coords[i].to_float ();
if (axis_limit.is_point ())
{
if (axis_limit.minimum != axis_coord)
return_trace (false);
continue;
}
else
{
if (axis_coord < axis_limit.minimum ||
axis_coord > axis_limit.maximum)
return_trace (false);
}
}
if (!c->serializer->embed (coords[i]))
return_trace (false);
@ -314,21 +355,19 @@ struct fvar
return axisCount;
}
void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location,
void collect_name_ids (hb_hashmap_t<hb_tag_t, Triple> *user_axes_location,
hb_map_t *axes_old_index_tag_map,
hb_set_t *nameids /* IN/OUT */) const
{
if (!has_data ()) return;
hb_map_t pinned_axes;
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);
if (user_axes_location->has (axis_tag) &&
user_axes_location->get (axis_tag).is_point ())
continue;
}
nameids->add (axis_records[i].get_name_id ());
}
@ -337,16 +376,7 @@ struct fvar
{
const InstanceRecord *instance = get_instance (i);
if (hb_any (+ hb_enumerate (instance->get_coordinates (axisCount))
| hb_filter (pinned_axes, hb_first)
| hb_map ([&] (const hb_pair_t<unsigned, const F16DOT16&>& _)
{
hb_tag_t axis_tag = pinned_axes.get (_.first);
float location = user_axes_location->get (axis_tag);
if (fabs ((double)location - (double)_.second.to_float ()) > 0.001) return true;
return false;
})
))
if (!instance->keep_instance (axisCount, axes_old_index_tag_map, user_axes_location))
continue;
nameids->add (instance->subfamilyNameID);

@ -648,7 +648,7 @@ _nameid_closure (hb_subset_plan_t* plan,
#endif
#ifndef HB_NO_VAR
if (!plan->all_axes_pinned)
plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
plan->source->table.fvar->collect_name_ids (&plan->axes_old_index_tag_map, &plan->user_axes_location, &plan->name_ids);
#endif
#ifndef HB_NO_COLOR
if (!drop_tables->has (HB_OT_TAG_CPAL))

Loading…
Cancel
Save