From 2ddd1a279a1e85167e4af38be0903cb5c6106b67 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 15 Mar 2024 12:27:44 -0600 Subject: [PATCH] [varc] Add MultiVarData --- src/hb-ot-layout-common.hh | 73 +++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 389dcf890..d0e80cff2 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -2421,12 +2421,12 @@ struct delta_row_encoding_t int combined_width = 0; for (unsigned i = 0; i < chars.length; i++) combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]); - + hb_vector_t combined_columns; combined_columns.alloc (columns.length); for (unsigned i = 0; i < columns.length; i++) combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]); - + int combined_overhead = get_chars_overhead (combined_columns); int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead - (combined_width - (int) width) * items.length @@ -2766,7 +2766,7 @@ struct VarData unsigned int get_region_index_count () const { return regionIndices.len; } - + unsigned get_region_index (unsigned i) const { return i >= regionIndices.len ? -1 : regionIndices[i]; } @@ -3120,6 +3120,69 @@ struct VarData DEFINE_SIZE_ARRAY (6, regionIndices); }; +struct MultiVarData +{ + unsigned int get_size () const + { return min_size + - regionIndices.min_size + regionIndices.get_size () + + StructAfter (regionIndices).get_size (); + } + + void get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const SparseVarRegionList ®ions, + hb_array_t out, + SparseVarRegionList::cache_t *cache = nullptr) const + { + auto &deltaSets = StructAfter (regionIndices); + if (unlikely (inner >= deltaSets.count)) + return; + + auto bytes = deltaSets[inner]; + + const HBUINT8 *p = (const HBUINT8 *) bytes.arrayZ; + const HBUINT8 *end = (const HBUINT8 *) (bytes.arrayZ + bytes.length); + hb_vector_t values_vector; + TupleValues::decompile (p, values_vector, end, true); + + hb_array_t values = values_vector; + + unsigned regionCount = regionIndices.len; + unsigned tupleLength = values.length / regionCount; + unsigned count = hb_min (tupleLength, out.length); + for (unsigned regionIndex = 0; regionIndex < regionCount; regionIndex++) + { + float scalar = regions.evaluate (regionIndices[regionIndex], + coords, coord_count, + cache); + if (scalar) + { + for (unsigned i = 0; i < count; i++) + { + out[i] += values.arrayZ[i] * scalar; + } + } + values += tupleLength; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + regionIndices.sanitize (c) && + hb_barrier () && + StructAfter (regionIndices).sanitize (c)); + } + + protected: + HBUINT16 format; // 1 + Array16Of regionIndices; + CFF2Index deltaSetsX; // Of + public: + DEFINE_SIZE_MIN (4 + CFF2Index::min_size); +}; + struct ItemVariationStore { friend struct item_variations_t; @@ -3205,7 +3268,7 @@ struct ItemVariationStore return_trace (false); #endif if (unlikely (!c->extend_min (this))) return_trace (false); - + format = 1; if (!regions.serialize_serialize (c, axis_tags, region_list)) return_trace (false); @@ -3220,7 +3283,7 @@ struct ItemVariationStore for (unsigned i = 0; i < num_var_data; i++) if (!dataSets[i].serialize_serialize (c, has_long, vardata_encodings[i].items)) return_trace (false); - + return_trace (true); }