[instancer] add create_from_item_varstore () method
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index 744684e..2f73c58 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -2552,6 +2552,45 @@
return_trace (true);
}
+ bool get_var_region (unsigned region_index,
+ const hb_map_t& axes_old_index_tag_map,
+ hb_hashmap_t<hb_tag_t, Triple>& axis_tuples /* OUT */) const
+ {
+ if (region_index >= regionCount) return false;
+ const VarRegionAxis* axis_region = axesZ.arrayZ + (region_index * axisCount);
+ for (unsigned i = 0; i < axisCount; i++)
+ {
+ hb_tag_t *axis_tag;
+ if (!axes_old_index_tag_map.has (i, &axis_tag))
+ return false;
+
+ float min_val = axis_region->startCoord.to_float ();
+ float def_val = axis_region->peakCoord.to_float ();
+ float max_val = axis_region->endCoord.to_float ();
+
+ if (def_val != 0.f)
+ axis_tuples.set (*axis_tag, Triple (min_val, def_val, max_val));
+ axis_region++;
+ }
+ return !axis_tuples.in_error ();
+ }
+
+ bool get_var_regions (const hb_map_t& axes_old_index_tag_map,
+ hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>>& regions /* OUT */) const
+ {
+ if (!regions.alloc (regionCount))
+ return false;
+
+ for (unsigned i = 0; i < regionCount; i++)
+ {
+ hb_hashmap_t<hb_tag_t, Triple> axis_tuples;
+ if (!get_var_region (i, axes_old_index_tag_map, axis_tuples))
+ return false;
+ regions.push (std::move (axis_tuples));
+ }
+ return !regions.in_error ();
+ }
+
unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; }
public:
@@ -2571,6 +2610,9 @@
unsigned int get_region_index_count () const
{ return regionIndices.len; }
+
+ unsigned get_region_index (unsigned i) const
+ { return i >= regionIndices.len ? -1 : regionIndices[i]; }
unsigned int get_row_size () const
{ return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); }
@@ -2766,13 +2808,15 @@
}
}
- protected:
+ public:
const HBUINT8 *get_delta_bytes () const
{ return &StructAfter<HBUINT8> (regionIndices); }
+ protected:
HBUINT8 *get_delta_bytes ()
{ return &StructAfter<HBUINT8> (regionIndices); }
+ public:
int32_t get_item_delta_fast (unsigned int item, unsigned int region,
const HBUINT8 *delta_bytes, unsigned row_size) const
{
@@ -2845,6 +2889,7 @@
struct VariationStore
{
+ friend struct item_variations_t;
using cache_t = VarRegionList::cache_t;
cache_t *create_cache () const
@@ -3044,6 +3089,22 @@
return dataSets.len;
}
+ const VarData& get_sub_table (unsigned i) const
+ {
+#ifdef HB_NO_VAR
+ return Null (VarData);
+#endif
+ return this+dataSets[i];
+ }
+
+ const VarRegionList& get_region_list () const
+ {
+#ifdef HB_NO_VAR
+ return Null (VarRegionList);
+#endif
+ return this+regions;
+ }
+
protected:
HBUINT16 format;
Offset32To<VarRegionList> regions;
diff --git a/src/hb-ot-var-common.hh b/src/hb-ot-var-common.hh
index d6bf44c..4a3eb03 100644
--- a/src/hb-ot-var-common.hh
+++ b/src/hb-ot-var-common.hh
@@ -1171,6 +1171,45 @@
return true;
}
+ 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)
+ {
+ /* NULL offset, to keep original varidx valid, just return */
+ if (&var_data == &Null (VarData))
+ return true;
+
+ 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 row_size = var_data.get_row_size ();
+ const HBUINT8 *delta_bytes = var_data.get_delta_bytes ();
+
+ for (unsigned r = 0; r < num_regions; r++)
+ {
+ /* In VarData, deltas are organized in rows, convert them into
+ * column(region) based tuples, resize deltas_x first */
+ tuple_delta_t tuple;
+ if (!tuple.deltas_x.resize (item_count, false) ||
+ !tuple.indices.resize (item_count, false))
+ return false;
+
+ 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);
+ }
+
+ unsigned region_index = var_data.get_region_index (r);
+ if (region_index >= regions.length) return false;
+ tuple.axis_tuples = regions.arrayZ[region_index];
+
+ tuple_vars.push (std::move (tuple));
+ }
+ return !tuple_vars.in_error ();
+ }
+
private:
void change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances)
@@ -1750,6 +1789,29 @@
const hb_map_t& get_varidx_map () const
{ return varidx_map; }
+
+ bool create_from_item_varstore (const VariationStore& varStore,
+ const hb_map_t& axes_old_index_tag_map)
+ {
+ 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 (!vars.alloc (num_var_data)) return false;
+
+ for (unsigned i = 0; i < num_var_data; i++)
+ {
+ 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))
+ return false;
+
+ vars.push (std::move (var_data_tuples));
+ }
+ return !vars.in_error ();
+ }
};
} /* namespace OT */