[instancer] update code for collecting FeatureVariationRecord

pull/4235/head
Qunxin Liu 2 years ago committed by Garret Rieger
parent bf298e5050
commit efc77dc68f
  1. 95
      src/hb-ot-layout-common.hh
  2. 27
      src/hb-subset-plan.cc

@ -61,13 +61,16 @@ static bool ClassDef_remap_and_serialize (
struct hb_collect_feature_substitutes_with_var_context_t
{
const hb_map_t *axes_index_tag_map;
const hb_hashmap_t<hb_tag_t, int> *axes_location;
const hb_hashmap_t<hb_tag_t, Triple> *axes_location;
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *record_cond_idx_map;
hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
bool& insert_catch_all_feature_variation_record;
// not stored in subset_plan
hb_set_t *feature_indices;
bool apply;
bool variation_applied;
bool universal;
unsigned cur_record_idx;
hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> *conditionset_map;
};
@ -2905,9 +2908,9 @@ struct VariationStore
enum Cond_with_Var_flag_t
{
KEEP_COND_WITH_VAR = 0,
DROP_COND_WITH_VAR = 1,
DROP_RECORD_WITH_VAR = 2,
MEM_ERR_WITH_VAR = 3,
KEEP_RECORD_WITH_VAR = 1,
DROP_COND_WITH_VAR = 2,
DROP_RECORD_WITH_VAR = 3,
};
struct ConditionFormat1
@ -2940,29 +2943,42 @@ struct ConditionFormat1
hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex);
//axis not pinned, keep the condition
if (!c->axes_location->has (axis_tag))
Triple axis_range (-1.f, 0.f, 1.f);
if (c->axes_location->has (axis_tag))
axis_range = c->axes_location->get (axis_tag);
int axis_min_val = axis_range.minimum;
int axis_default_val = axis_range.middle;
int axis_max_val = axis_range.maximum;
int16_t filter_min_val = filterRangeMinValue.to_int ();
int16_t filter_max_val = filterRangeMaxValue.to_int ();
if (axis_default_val < filter_min_val ||
axis_default_val > filter_max_val)
c->apply = false;
//condition not met, drop the entire record
if (axis_min_val > filter_max_val || axis_max_val < filter_min_val ||
filter_min_val > filter_max_val)
return DROP_RECORD_WITH_VAR;
//condition met and axis pinned, drop the condition
if (c->axes_location->has (axis_tag) &&
c->axes_location->get (axis_tag).is_point ())
return DROP_COND_WITH_VAR;
if (filter_max_val != axis_max_val || filter_min_val != axis_min_val)
{
// add axisIndex->value into the hashmap so we can check if the record is
// unique with variations
int16_t min_val = filterRangeMinValue.to_int ();
int16_t max_val = filterRangeMaxValue.to_int ();
hb_codepoint_t val = (max_val << 16) + min_val;
hb_codepoint_t val = (filter_max_val << 16) + filter_min_val;
condition_map->set (axisIndex, val);
return KEEP_COND_WITH_VAR;
}
//axis pinned, check if condition is met
//TODO: add check for axis Ranges
int v = c->axes_location->get (axis_tag);
//condition not met, drop the entire record
if (v < filterRangeMinValue.to_int () || v > filterRangeMaxValue.to_int ())
return DROP_RECORD_WITH_VAR;
//axis pinned and condition met, drop the condition
return DROP_COND_WITH_VAR;
return KEEP_RECORD_WITH_VAR;
}
bool evaluate (const int *coords, unsigned int coord_len) const
@ -3001,7 +3017,7 @@ struct Condition
{
switch (u.format) {
case 1: return u.format1.keep_with_variations (c, condition_map);
default:return KEEP_COND_WITH_VAR;
default: c->apply = false; return KEEP_COND_WITH_VAR;
}
}
@ -3046,45 +3062,50 @@ struct ConditionSet
return true;
}
Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
void keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
{
hb_map_t *condition_map = hb_map_create ();
if (unlikely (!condition_map)) return MEM_ERR_WITH_VAR;
if (unlikely (!condition_map)) return;
hb::shared_ptr<hb_map_t> p {condition_map};
hb_set_t *cond_set = hb_set_create ();
if (unlikely (!cond_set)) return MEM_ERR_WITH_VAR;
if (unlikely (!cond_set)) return;
hb::shared_ptr<hb_set_t> s {cond_set};
c->apply = true;
bool should_keep = false;
unsigned num_kept_cond = 0, cond_idx = 0;
for (const auto& offset : conditions)
{
Cond_with_Var_flag_t ret = (this+offset).keep_with_variations (c, condition_map);
// one condition is not met, drop the entire record
// condition is not met or condition out of range, drop the entire record
if (ret == DROP_RECORD_WITH_VAR)
return DROP_RECORD_WITH_VAR;
return;
// axis not pinned, keep this condition
if (ret == KEEP_COND_WITH_VAR)
{
should_keep = true;
cond_set->add (cond_idx);
num_kept_cond++;
}
if (ret == KEEP_RECORD_WITH_VAR)
should_keep = true;
cond_idx++;
}
// all conditions met
if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
if (!should_keep) return;
//check if condition_set is unique with variations
if (c->conditionset_map->has (p))
//duplicate found, drop the entire record
return DROP_RECORD_WITH_VAR;
return;
c->conditionset_map->set (p, 1);
c->record_cond_idx_map->set (c->cur_record_idx, s);
return KEEP_COND_WITH_VAR;
if (should_keep && num_kept_cond == 0)
c->universal = true;
}
bool subset (hb_subset_context_t *c,
@ -3289,12 +3310,11 @@ struct FeatureVariationRecord
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
const void *base) const
{
// ret == 1, all conditions met
if ((base+conditions).keep_with_variations (c) == DROP_COND_WITH_VAR &&
c->apply)
(base+conditions).keep_with_variations (c);
if (c->apply && !c->variation_applied)
{
(base+substitutions).collect_feature_substitutes_with_variations (c);
c->apply = false; // set variations only once
c->variation_applied = true; // set variations only once
}
}
@ -3361,7 +3381,12 @@ struct FeatureVariations
{
c->cur_record_idx = i;
varRecords[i].collect_feature_substitutes_with_variations (c, this);
if (c->universal)
break;
}
if (c->variation_applied && !c->universal &&
!c->record_cond_idx_map->is_empty ())
c->insert_catch_all_feature_variation_record = true;
}
FeatureVariations* copy (hb_serialize_context_t *c) const

@ -135,7 +135,8 @@ static void _collect_layout_indices (hb_subset_plan_t *plan,
hb_set_t *lookup_indices, /* OUT */
hb_set_t *feature_indices, /* OUT */
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map, /* OUT */
hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map /* OUT */)
hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map, /* OUT */
bool& insert_catch_all_feature_variation_record)
{
unsigned num_features = table.get_feature_count ();
hb_vector_t<hb_tag_t> features;
@ -171,12 +172,18 @@ static void _collect_layout_indices (hb_subset_plan_t *plan,
&plan->axes_location,
feature_record_cond_idx_map,
feature_substitutes_map,
insert_catch_all_feature_variation_record,
feature_indices,
true,
false,
false,
false,
0,
&conditionset_map
};
table.collect_feature_substitutes_with_variations (&c);
if (c.insert_catch_all_feature_variation_record)
{
}
}
#endif
@ -283,7 +290,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan,
hb_map_t *features,
script_langsys_map *langsys_map,
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map,
hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map)
hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map,
bool& insert_catch_all_feature_variation_record)
{
hb_blob_ptr_t<T> table = plan->source_table<T> ();
hb_tag_t table_tag = table->tableTag;
@ -293,7 +301,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan,
&lookup_indices,
&feature_indices,
feature_record_cond_idx_map,
feature_substitutes_map);
feature_substitutes_map,
insert_catch_all_feature_variation_record);
if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE))
hb_ot_layout_lookups_substitute_closure (plan->source,
@ -648,7 +657,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->axes_old_index_tag_map, &plan->user_axes_location, &plan->name_ids);
plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->axes_old_index_tag_map, &plan->name_ids);
#endif
#ifndef HB_NO_COLOR
if (!drop_tables->has (HB_OT_TAG_CPAL))
@ -694,7 +703,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
&plan->gsub_features,
&plan->gsub_langsys,
&plan->gsub_feature_record_cond_idx_map,
&plan->gsub_feature_substitutes_map);
&plan->gsub_feature_substitutes_map,
plan->gsub_insert_catch_all_feature_variation_rec);
if (!drop_tables->has (HB_OT_TAG_GPOS))
_closure_glyphs_lookups_features<GPOS> (
@ -704,7 +714,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
&plan->gpos_features,
&plan->gpos_langsys,
&plan->gpos_feature_record_cond_idx_map,
&plan->gpos_feature_substitutes_map);
&plan->gpos_feature_substitutes_map,
plan->gpos_insert_catch_all_feature_variation_rec);
#endif
_remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ());
@ -1029,6 +1040,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
glyph_map = hb_map_create ();
reverse_glyph_map = hb_map_create ();
gsub_insert_catch_all_feature_variation_rec = false;
gpos_insert_catch_all_feature_variation_rec = false;
gdef_varstore_inner_maps.init ();
user_axes_location = input->axes_location;

Loading…
Cancel
Save