diff options
author | Behdad Esfahbod <behdad@behdad.org> | 2023-09-20 14:37:42 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-20 14:37:42 -0600 |
commit | 4b3aa0104ea4c7859095b0e78662e440483068da (patch) | |
tree | 3264dfbb063b63a6f498d602dd78f428b02d9302 | |
parent | da2c59d71f687c38a29389d81d6d6f911994c403 (diff) | |
parent | ef4ff1d6a4f2343440e278ef1177b07f6af8f5dc (diff) | |
download | harfbuzz_ng-4b3aa0104ea4c7859095b0e78662e440483068da.tar.gz |
Merge pull request #4410 from googlefonts/HVAR_instance
[instancer] instantiate HVAR/VVAR
14 files changed, 127 insertions, 15 deletions
diff --git a/src/hb-ot-var-common.hh b/src/hb-ot-var-common.hh index aeb0097ba..00bea20ac 100644 --- a/src/hb-ot-var-common.hh +++ b/src/hb-ot-var-common.hh @@ -1174,7 +1174,8 @@ struct TupleVariationData bool create_from_item_var_data (const VarData &var_data, const hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>>& regions, - const hb_map_t& axes_old_index_tag_map) + const hb_map_t& axes_old_index_tag_map, + const hb_inc_bimap_t* inner_map = nullptr) { /* NULL offset, to keep original varidx valid, just return */ if (&var_data == &Null (VarData)) @@ -1183,7 +1184,7 @@ struct TupleVariationData unsigned num_regions = var_data.get_region_index_count (); if (!tuple_vars.alloc (num_regions)) return false; - unsigned item_count = var_data.get_item_count (); + unsigned item_count = inner_map ? inner_map->get_population () : var_data.get_item_count (); unsigned row_size = var_data.get_row_size (); const HBUINT8 *delta_bytes = var_data.get_delta_bytes (); @@ -1199,7 +1200,8 @@ struct TupleVariationData for (unsigned i = 0; i < item_count; i++) { tuple.indices.arrayZ[i] = true; - tuple.deltas_x.arrayZ[i] = var_data.get_item_delta_fast (i, r, delta_bytes, row_size); + tuple.deltas_x.arrayZ[i] = var_data.get_item_delta_fast (inner_map ? inner_map->backward (i) : i, + r, delta_bytes, row_size); } unsigned region_index = var_data.get_region_index (r); @@ -1811,21 +1813,26 @@ struct item_variations_t { return varidx_map; } bool create_from_item_varstore (const VariationStore& varStore, - const hb_map_t& axes_old_index_tag_map) + const hb_map_t& axes_old_index_tag_map, + const hb_array_t <const hb_inc_bimap_t> inner_maps = hb_array_t<const hb_inc_bimap_t> ()) { const VarRegionList& regionList = varStore.get_region_list (); if (!regionList.get_var_regions (axes_old_index_tag_map, orig_region_list)) return false; unsigned num_var_data = varStore.get_sub_table_count (); + if (inner_maps && inner_maps.length != num_var_data) return false; if (!vars.alloc (num_var_data)) return false; for (unsigned i = 0; i < num_var_data; i++) { + if (inner_maps && !inner_maps.arrayZ[i].get_population ()) + continue; tuple_variations_t var_data_tuples; if (!var_data_tuples.create_from_item_var_data (varStore.get_sub_table (i), orig_region_list, - axes_old_index_tag_map)) + axes_old_index_tag_map, + inner_maps ? &(inner_maps.arrayZ[i]) : nullptr)) return false; vars.push (std::move (var_data_tuples)); @@ -1915,8 +1922,9 @@ struct item_variations_t return (!region_list.in_error ()) && (!region_map.in_error ()); } - /* main algorithm ported from fonttools VarStore_optimize() method */ - bool optimize (bool use_no_variation_idx=true) + /* main algorithm ported from fonttools VarStore_optimize() method, optimize + * varstore by default */ + bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true) { unsigned num_cols = region_list.length; /* pre-alloc a 2D vector for all sub_table's VarData rows */ @@ -1966,6 +1974,19 @@ struct item_variations_t } } + if (!optimize) + { + /* assemble a delta_row_encoding_t for this subtable, skip optimization so + * chars is not initialized, we only need delta rows for serialization */ + delta_row_encoding_t obj; + for (unsigned r = start_row; r < start_row + num_rows; r++) + obj.add_row (&(delta_rows.arrayZ[r])); + + encodings.push (std::move (obj)); + start_row += num_rows; + continue; + } + for (unsigned minor = 0; minor < num_rows; minor++) { const hb_vector_t<int>& row = delta_rows[start_row + minor]; @@ -2012,6 +2033,11 @@ struct item_variations_t start_row += num_rows; } + + /* return directly if no optimization, maintain original VariationIndex so + * varidx_map would be empty */ + if (!optimize) return !encodings.in_error (); + /* sort encoding_objs */ encoding_objs.qsort (); @@ -2148,7 +2174,14 @@ struct item_variations_t const hb_vector_t<int>** a = (const hb_vector_t<int>**) pa; const hb_vector_t<int>** b = (const hb_vector_t<int>**) pb; - return ((*b)->as_array ()).cmp ((*a)->as_array ()); + for (unsigned i = 0; i < (*b)->length; i++) + { + int va = (*a)->arrayZ[i]; + int vb = (*b)->arrayZ[i]; + if (va != vb) + return va < vb ? -1 : 1; + } + return 0; } }; diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index 490f883fc..e944ff13a 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh @@ -134,6 +134,36 @@ struct index_map_subset_plan_t } } + bool remap_after_instantiation (const hb_subset_plan_t *plan, + const hb_map_t& varidx_map) + { + /* recalculate bit_count after remapping */ + outer_bit_count = 1; + inner_bit_count = 1; + + for (const auto &_ : plan->new_to_old_gid_list) + { + hb_codepoint_t new_gid = _.first; + if (unlikely (new_gid >= map_count)) break; + + uint32_t v = output_map.arrayZ[new_gid]; + uint32_t *new_varidx; + if (!varidx_map.has (v, &new_varidx)) + return false; + + output_map.arrayZ[new_gid] = *new_varidx; + + unsigned outer = (*new_varidx) >> 16; + unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer); + outer_bit_count = hb_max (bit_count, outer_bit_count); + + unsigned inner = (*new_varidx) & 0xFFFF; + bit_count = (inner == 0) ? 1 : hb_bit_storage (inner); + inner_bit_count = hb_max (bit_count, inner_bit_count); + } + return true; + } + unsigned int get_inner_bit_count () const { return inner_bit_count; } unsigned int get_width () const { return ((outer_bit_count + inner_bit_count + 7) / 8); } unsigned int get_map_count () const { return map_count; } @@ -211,6 +241,16 @@ struct hvarvvar_subset_plan_t index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan); } + /* remap */ + bool remap_index_map_plans (const hb_subset_plan_t *plan, + const hb_map_t& varidx_map) + { + for (unsigned i = 0; i < index_map_plans.length; i++) + if (!index_map_plans[i].remap_after_instantiation (plan, varidx_map)) + return false; + return true; + } + void fini () { for (unsigned int i = 0; i < inner_sets.length; i++) @@ -289,6 +329,9 @@ struct HVARVVAR bool _subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); + if (c->plan->all_axes_pinned) + return_trace (false); + hvarvvar_subset_plan_t hvar_plan; hb_vector_t<const DeltaSetIndexMap *> index_maps; @@ -302,11 +345,47 @@ struct HVARVVAR out->version.major = 1; out->version.minor = 0; - if (unlikely (!out->varStore - .serialize_serialize (c->serializer, - hvar_plan.var_store, - hvar_plan.inner_maps.as_array ()))) + if (c->plan->normalized_coords) + { + /* TODO: merge these 3 calls into 1 call that executes all 3 + * functions */ + item_variations_t item_vars; + if (!item_vars.create_from_item_varstore (this+varStore, + c->plan->axes_old_index_tag_map, + hvar_plan.inner_maps.as_array ())) + return_trace (false); + + if (!item_vars.instantiate (c->plan->axes_location, c->plan->axes_triple_distances)) + return_trace (false); + + /* if glyph indices are used as implicit delta-set indices, no need to + * optimiza varstore, maintain original variation indices */ + if (!item_vars.as_item_varstore (advMap == 0 ? false : true, + false /* use_no_variation_idx = false */)) + 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); + + /* if varstore is optimized, remap output_map */ + if (advMap) + { + if (!hvar_plan.remap_index_map_plans (c->plan, item_vars.get_varidx_map ())) + return_trace (false); + } + } + else + { + if (unlikely (!out->varStore + .serialize_serialize (c->serializer, + hvar_plan.var_store, + hvar_plan.inner_maps.as_array ()))) return_trace (false); + } return_trace (out->T::serialize_index_maps (c->serializer, hvar_plan.index_map_plans.as_array ())); diff --git a/src/hb-ot-var-mvar-table.hh b/src/hb-ot-var-mvar-table.hh index a41e57880..9bbd904c5 100644 --- a/src/hb-ot-var-mvar-table.hh +++ b/src/hb-ot-var-mvar-table.hh @@ -111,7 +111,7 @@ struct MVAR if (!item_vars.instantiate (c->plan->axes_location, c->plan->axes_triple_distances)) return_trace (false); - if (!item_vars.optimize ()) + if (!item_vars.as_item_varstore ()) return_trace (false); /* serialize varstore */ diff --git a/src/test-item-varstore.cc b/src/test-item-varstore.cc index d1600d560..60ba81280 100644 --- a/src/test-item-varstore.cc +++ b/src/test-item-varstore.cc @@ -54,7 +54,7 @@ test_item_variations () result = item_vars.instantiate (normalized_axes_location, axes_triple_distances); assert (result); - result = item_vars.optimize (); + result = item_vars.as_item_varstore (false); assert (result); assert (item_vars.get_region_list().length == 8); } diff --git a/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf b/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf Binary files differindex 92b190bed..0d9701714 100644 --- a/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf +++ b/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf diff --git a/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttf b/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttf Binary files differindex 7fa245244..ef2b65b78 100644 --- a/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttf +++ b/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttf diff --git a/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf b/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf Binary files differindex 2e5565305..2e34bb887 100644 --- a/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf +++ b/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf diff --git a/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttf b/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttf Binary files differindex fc890fb96..95bf757e3 100644 --- a/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttf +++ b/test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttf diff --git a/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=200-600,wdth=80-90,CTGR=20-60.ttf b/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=200-600,wdth=80-90,CTGR=20-60.ttf Binary files differindex 679e6c721..2cf4eb41b 100644 --- a/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=200-600,wdth=80-90,CTGR=20-60.ttf +++ b/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=200-600,wdth=80-90,CTGR=20-60.ttf diff --git a/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttf b/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttf Binary files differindex 3508c732c..d09940a82 100644 --- a/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttf +++ b/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttf diff --git a/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttf b/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttf Binary files differindex a14e79ed7..b1564ad81 100644 --- a/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttf +++ b/test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttf diff --git a/test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttf b/test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttf Binary files differindex 5f6b2a0b4..b26b28aa2 100644 --- a/test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttf +++ b/test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttf diff --git a/test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttf b/test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttf Binary files differindex edd451312..c5d37c547 100644 --- a/test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttf +++ b/test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttf diff --git a/test/subset/data/profiles/no-tables-with-item-variations.txt b/test/subset/data/profiles/no-tables-with-item-variations.txt index 2a5aa1892..d4ed0585e 100644 --- a/test/subset/data/profiles/no-tables-with-item-variations.txt +++ b/test/subset/data/profiles/no-tables-with-item-variations.txt @@ -1 +1 @@ ---drop-tables+=HVAR,VVAR,GDEF,COLR,GPOS +--drop-tables+=GDEF,COLR,GPOS |