mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-14 17:13:40 +00:00
[instancer] update code for collecting FeatureVariationRecord
This commit is contained in:
parent
bf298e5050
commit
efc77dc68f
2 changed files with 80 additions and 42 deletions
|
@ -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…
Add table
Reference in a new issue