From efc77dc68fea89e8ddc03d09b605e7d6ad6ff240 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Thu, 4 May 2023 10:59:09 -0700 Subject: [PATCH] [instancer] update code for collecting FeatureVariationRecord --- src/hb-ot-layout-common.hh | 95 ++++++++++++++++++++++++-------------- src/hb-subset-plan.cc | 27 ++++++++--- 2 files changed, 80 insertions(+), 42 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 36f123b55..ead57b2de 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -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 *axes_location; + const hb_hashmap_t *axes_location; hb_hashmap_t> *record_cond_idx_map; hb_hashmap_t *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, 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 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 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 diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 15e039f89..ea17f8d08 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -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> *feature_record_cond_idx_map, /* OUT */ - hb_hashmap_t *feature_substitutes_map /* OUT */) + hb_hashmap_t *feature_substitutes_map, /* OUT */ + bool& insert_catch_all_feature_variation_record) { unsigned num_features = table.get_feature_count (); hb_vector_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> *feature_record_cond_idx_map, - hb_hashmap_t *feature_substitutes_map) + hb_hashmap_t *feature_substitutes_map, + bool& insert_catch_all_feature_variation_record) { hb_blob_ptr_t table = plan->source_table (); 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 ( @@ -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;