aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2023-09-20 14:37:42 -0600
committerGitHub <noreply@github.com>2023-09-20 14:37:42 -0600
commit4b3aa0104ea4c7859095b0e78662e440483068da (patch)
tree3264dfbb063b63a6f498d602dd78f428b02d9302
parentda2c59d71f687c38a29389d81d6d6f911994c403 (diff)
parentef4ff1d6a4f2343440e278ef1177b07f6af8f5dc (diff)
downloadharfbuzz_ng-4b3aa0104ea4c7859095b0e78662e440483068da.tar.gz
Merge pull request #4410 from googlefonts/HVAR_instance
[instancer] instantiate HVAR/VVAR
-rw-r--r--src/hb-ot-var-common.hh49
-rw-r--r--src/hb-ot-var-hvar-table.hh87
-rw-r--r--src/hb-ot-var-mvar-table.hh2
-rw-r--r--src/test-item-varstore.cc2
-rw-r--r--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.ttfbin8256 -> 8432 bytes
-rw-r--r--test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.ABC.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttfbin7244 -> 7336 bytes
-rw-r--r--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.ttfbin7292 -> 7484 bytes
-rw-r--r--test/subset/data/expected/glyf_partial_instancing/Roboto-Variable.composite.no-tables-with-item-variations.retain-all-codepoint.wght=300-600,wdth=85.ttfbin6760 -> 6848 bytes
-rw-r--r--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.ttfbin3800 -> 4108 bytes
-rw-r--r--test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttfbin6280 -> 6616 bytes
-rw-r--r--test/subset/data/expected/mvar_partial_instance/NotoSans-VF.abc.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttfbin6760 -> 7096 bytes
-rw-r--r--test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=300-600.ttfbin194432 -> 197056 bytes
-rw-r--r--test/subset/data/expected/update_def_wght/SourceSerifVariable-Roman.no-tables-with-item-variations.retain-all-codepoint.wght=500-800.ttfbin143840 -> 145004 bytes
-rw-r--r--test/subset/data/profiles/no-tables-with-item-variations.txt2
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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