From c5a85a73fa66fee7524f5e39ba5751e25b5b0f49 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Fri, 3 May 2024 09:44:14 -0700 Subject: [PATCH] [instancer] support BASE table --- src/hb-ot-layout-base-table.hh | 64 +++++++++++++++++++++++++++---- src/hb-subset-plan-member-list.hh | 2 +- src/hb-subset-plan.cc | 10 +++-- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh index 183c1ea73..98ab2c6a3 100644 --- a/src/hb-ot-layout-base-table.hh +++ b/src/hb-ot-layout-base-table.hh @@ -125,6 +125,20 @@ struct BaseCoordFormat3 auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); + if (!c->plan->pinned_at_default) + { + unsigned var_idx = (this+deviceTable).get_variation_index (); + if (var_idx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + { + hb_pair_t *v; + if (!c->plan->base_variation_idx_map.has (var_idx, &v)) + return_trace (false); + + if (unlikely (!c->serializer->check_assign (out->coordinate, coordinate + hb_second (*v), + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); + } + } return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this, 0, hb_serialize_context_t::Head, @@ -706,6 +720,46 @@ struct BASE (this+vAxis).collect_variation_indices (plan, varidx_set); } + bool subset_varstore (hb_subset_context_t *c, + BASE *out /* OUT */) const + { + TRACE_SUBSET (this); + if (!c->serializer->allocate_size> (Offset32To::static_size)) + return_trace (false); + if (!c->plan->normalized_coords) + return_trace (out->varStore.serialize_subset (c, varStore, this, c->plan->base_varstore_inner_maps.as_array ())); + + if (c->plan->all_axes_pinned) + return_trace (true); + + item_variations_t item_vars; + if (!item_vars.instantiate (this+varStore, c->plan, true, true, + c->plan->base_varstore_inner_maps.as_array ())) + return_trace (false); + + if (!out->varStore.serialize_serialize (c->serializer, + item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ())) + return_trace (false); + + const hb_map_t &varidx_map = item_vars.get_varidx_map (); + /* base_variation_idx_map in the plan is old_varidx->(varidx, delta) + * mapping, new varidx is generated for subsetting, we need to remap this + * after instancing */ + for (auto _ : c->plan->base_variation_idx_map.iter_ref ()) + { + uint32_t varidx = _.second.first; + uint32_t *new_varidx; + if (varidx_map.has (varidx, &new_varidx)) + _.second.first = *new_varidx; + else + _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + } + return_trace (true); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -713,19 +767,15 @@ struct BASE if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); out->version = version; + if (has_var_store () && !subset_varstore (c, out)) + return_trace (false); + if (hAxis && !out->hAxis.serialize_subset (c, hAxis, this)) return_trace (false); if (vAxis && !out->vAxis.serialize_subset (c, vAxis, this)) return_trace (false); - if (has_var_store ()) - { - if (!c->serializer->allocate_size> (Offset32To::static_size)) - return_trace (false); - return_trace (out->varStore.serialize_subset (c, varStore, this, c->plan->base_varstore_inner_maps.as_array ())); - } - return_trace (true); } diff --git a/src/hb-subset-plan-member-list.hh b/src/hb-subset-plan-member-list.hh index 4651f14d8..b02c33e92 100644 --- a/src/hb-subset-plan-member-list.hh +++ b/src/hb-subset-plan-member-list.hh @@ -146,7 +146,7 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E( (New varidx, 0) mapping -HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E()>), base_variation_idx_map) +HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), base_variation_idx_map) //BASE table varstore retained varidx mapping HB_SUBSET_PLAN_MEMBER (hb_vector_t, base_varstore_inner_maps) diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index a84062025..b13e3a917 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -489,13 +489,15 @@ _collect_base_variation_indices (hb_subset_plan_t* plan) hb_set_t varidx_set; base->collect_variation_indices (plan, varidx_set); - unsigned subtable_count = base->get_var_store ().get_sub_table_count (); + const OT::ItemVariationStore &var_store = base->get_var_store (); base.destroy (); + unsigned subtable_count = var_store.get_sub_table_count (); - /* TODO: support instancing for BASE table */ - _remap_variation_indices (base->get_var_store (), varidx_set, + _remap_variation_indices (var_store, varidx_set, plan->normalized_coords, - false, false, plan->base_variation_idx_map); + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->base_variation_idx_map); _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); }