From b72995ff162c6318a84b6ae9d43a9a247f2ad01d Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Mon, 1 Aug 2022 14:48:01 -0700 Subject: [PATCH] [instance] GDEF table: collect both varidxes and deltas --- src/OT/Layout/GPOS/AnchorFormat3.hh | 4 +-- src/OT/Layout/GPOS/ValueFormat.hh | 8 +++--- src/hb-ot-layout-common.hh | 32 +++++++++++++++++---- src/hb-ot-layout-gdef-table.hh | 18 +++++++----- src/hb-subset-plan.cc | 44 ++++++++++++++++++++++++++++- 5 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/OT/Layout/GPOS/AnchorFormat3.hh b/src/OT/Layout/GPOS/AnchorFormat3.hh index d77b4699b..593ae3939 100644 --- a/src/OT/Layout/GPOS/AnchorFormat3.hh +++ b/src/OT/Layout/GPOS/AnchorFormat3.hh @@ -57,8 +57,8 @@ struct AnchorFormat3 void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { - (this+xDeviceTable).collect_variation_indices (c->layout_variation_indices); - (this+yDeviceTable).collect_variation_indices (c->layout_variation_indices); + (this+xDeviceTable).collect_variation_indices (c); + (this+yDeviceTable).collect_variation_indices (c); } }; diff --git a/src/OT/Layout/GPOS/ValueFormat.hh b/src/OT/Layout/GPOS/ValueFormat.hh index 38758a163..e94461915 100644 --- a/src/OT/Layout/GPOS/ValueFormat.hh +++ b/src/OT/Layout/GPOS/ValueFormat.hh @@ -201,27 +201,27 @@ struct ValueFormat : HBUINT16 if (format & yAdvance) i++; if (format & xPlaDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } if (format & ValueFormat::yPlaDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } if (format & ValueFormat::xAdvDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } if (format & ValueFormat::yAdvDevice) { - (base + get_device (&(values[i]))).collect_variation_indices (c->layout_variation_indices); + (base + get_device (&(values[i]))).collect_variation_indices (c); i++; } } diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index ce8ddffbb..35f38c2c7 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -186,6 +186,7 @@ struct hb_subset_layout_context_t : unsigned lookup_index_count; }; +struct VariationStore; struct hb_collect_variation_indices_context_t : hb_dispatch_context_t { @@ -194,15 +195,27 @@ struct hb_collect_variation_indices_context_t : static return_t default_return_value () { return hb_empty_t (); } hb_set_t *layout_variation_indices; + hb_hashmap_t> *varidx_delta_map; + hb_font_t *font; + const VariationStore *var_store; const hb_set_t *glyph_set; const hb_map_t *gpos_lookups; + float *store_cache; hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_, + hb_hashmap_t> *varidx_delta_map_, + hb_font_t *font_, + const VariationStore *var_store_, const hb_set_t *glyph_set_, - const hb_map_t *gpos_lookups_) : + const hb_map_t *gpos_lookups_, + float *store_cache_) : layout_variation_indices (layout_variation_indices_), + varidx_delta_map (varidx_delta_map_), + font (font_), + var_store (var_store_), glyph_set (glyph_set_), - gpos_lookups (gpos_lookups_) {} + gpos_lookups (gpos_lookups_), + store_cache (store_cache_) {} }; template @@ -3172,9 +3185,16 @@ struct VariationDevice return_trace (out); } - void record_variation_index (hb_set_t *layout_variation_indices) const + void collect_variation_index (hb_collect_variation_indices_context_t *c) const { - layout_variation_indices->add (varIdx); + c->layout_variation_indices->add (varIdx); + int delta = 0; + if (c->font && c->var_store) + delta = roundf (get_delta (c->font, *c->var_store, c->store_cache)); + + /* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap + * varidx later*/ + c->varidx_delta_map->set (varIdx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); } bool sanitize (hb_sanitize_context_t *c) const @@ -3286,7 +3306,7 @@ struct Device } } - void collect_variation_indices (hb_set_t *layout_variation_indices) const + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { switch (u.b.format) { #ifndef HB_NO_HINTING @@ -3297,7 +3317,7 @@ struct Device #endif #ifndef HB_NO_VAR case 0x8000: - u.variation.record_variation_index (layout_variation_indices); + u.variation.collect_variation_index (c); return; #endif default: diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 11fdf2a24..0ca67bd6c 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -207,8 +207,8 @@ struct CaretValueFormat3 hb_serialize_context_t::Head, c->plan->layout_variation_idx_map)); } - void collect_variation_indices (hb_set_t *layout_variation_indices) const - { (this+deviceTable).collect_variation_indices (layout_variation_indices); } + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const + { (this+deviceTable).collect_variation_indices (c); } bool sanitize (hb_sanitize_context_t *c) const { @@ -255,14 +255,14 @@ struct CaretValue } } - void collect_variation_indices (hb_set_t *layout_variation_indices) const + void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { switch (u.format) { case 1: case 2: return; case 3: - u.format3.collect_variation_indices (layout_variation_indices); + u.format3.collect_variation_indices (c); return; default: return; } @@ -329,7 +329,7 @@ struct LigGlyph void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { for (const Offset16To& offset : carets.iter ()) - (this+offset).collect_variation_indices (c->layout_variation_indices); + (this+offset).collect_variation_indices (c); } bool sanitize (hb_sanitize_context_t *c) const @@ -846,7 +846,7 @@ struct GDEF { get_lig_caret_list ().collect_variation_indices (c); } void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, - hb_map_t *layout_variation_idx_map /* OUT */) const + hb_hashmap_t> *layout_variation_idx_delta_map /* OUT */) const { if (!has_var_store ()) return; if (layout_variation_indices->is_empty ()) return; @@ -864,7 +864,11 @@ struct GDEF } unsigned new_idx = (new_major << 16) + new_minor; - layout_variation_idx_map->set (idx, new_idx); + if (!layout_variation_idx_delta_map->has (idx)) + continue; + int delta = hb_second (layout_variation_idx_delta_map->get (idx)); + + layout_variation_idx_delta_map->set (idx, hb_pair_t (new_idx, delta)); ++new_minor; last_major = major; } diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 500fe7f2c..4faca1ee9 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -287,6 +287,26 @@ _generate_varstore_inner_maps (const hb_set_t& varidx_set, } } +static inline hb_font_t* +_get_hb_font_with_variations (const hb_subset_plan_t *plan) +{ + hb_font_t *font = hb_font_create (plan->source); + + hb_vector_t vars; + vars.alloc (plan->user_axes_location->get_population ()); + + for (auto _ : *plan->user_axes_location) + { + hb_variation_t var; + var.tag = _.first; + var.value = _.second; + vars.push (var); + } + + hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ()); + return font; +} + static inline void _collect_layout_variation_indices (hb_subset_plan_t* plan) { @@ -300,13 +320,35 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) return; } + const OT::VariationStore *var_store = nullptr; hb_set_t varidx_set; - OT::hb_collect_variation_indices_context_t c (&varidx_set, plan->_glyphset_gsub, plan->gpos_lookups); + hb_font_t *font = nullptr; + float *store_cache = nullptr; + bool collect_delta = plan->pinned_at_default ? false : true; + if (collect_delta) + { + font = _get_hb_font_with_variations (plan); + if (gdef->has_var_store ()) + { + var_store = &(gdef->get_var_store ()); + store_cache = var_store->create_cache (); + } + } + + OT::hb_collect_variation_indices_context_t c (&varidx_set, + plan->layout_variation_idx_delta_map, + font, var_store, + plan->_glyphset_gsub, + plan->gpos_lookups, + store_cache); gdef->collect_variation_indices (&c); if (hb_ot_layout_has_positioning (plan->source)) gpos->collect_variation_indices (&c); + hb_font_destroy (font); + var_store->destroy_cache (store_cache); + gdef->remap_layout_variation_indices (&varidx_set, plan->layout_variation_idx_delta_map); unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0;