diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index cdcffd424..e4f3e06f7 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -2603,9 +2603,11 @@ struct VarRegionAxis struct VarRegionList { + using cache_t = float; + float evaluate (unsigned int region_index, const int *coords, unsigned int coord_len, - hb_vector_t *cache = nullptr) const + cache_t *cache = nullptr) const { if (unlikely (region_index >= regionCount)) return 0.; @@ -2613,11 +2615,9 @@ struct VarRegionList float *cached = nullptr; if (cache) { - cached = &((*cache)[region_index]); + cached = &(cache[region_index]); if (!std::isnan (*cached)) - { return *cached; - } } const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); @@ -2636,6 +2636,7 @@ struct VarRegionList } v *= factor; } + if (cached) *cached = v; return v; @@ -2696,7 +2697,7 @@ struct VarData float get_delta (unsigned int inner, const int *coords, unsigned int coord_count, const VarRegionList ®ions, - hb_vector_t *regions_cache = nullptr) const + VarRegionList::cache_t *cache = nullptr) const { if (unlikely (inner >= itemCount)) return 0.; @@ -2713,13 +2714,13 @@ struct VarData const HBINT16 *scursor = reinterpret_cast (row); for (; i < scount; i++) { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, regions_cache); + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); delta += scalar * *scursor++; } const HBINT8 *bcursor = reinterpret_cast (scursor); for (; i < count; i++) { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, regions_cache); + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); delta += scalar * *bcursor++; } @@ -2864,10 +2865,28 @@ struct VarData struct VariationStore { + using cache_t = VarRegionList::cache_t; + + cache_t *create_cache () const + { + auto &r = this+regions; + unsigned count = r.regionCount; + + float *cache = (float *) hb_malloc (sizeof (float) * count); + if (unlikely (!cache)) return nullptr; + + for (unsigned i = 0; i < count; i++) + cache[i] = NAN; + + return cache; + } + + static void destroy_cache (cache_t *cache) { hb_free (cache); } + private: float get_delta (unsigned int outer, unsigned int inner, const int *coords, unsigned int coord_count, - hb_vector_t *regions_cache = nullptr) const + VarRegionList::cache_t *cache = nullptr) const { #ifdef HB_NO_VAR return 0.f; @@ -2879,17 +2898,17 @@ struct VariationStore return (this+dataSets[outer]).get_delta (inner, coords, coord_count, this+regions, - regions_cache); + cache); } public: float get_delta (unsigned int index, const int *coords, unsigned int coord_count, - hb_vector_t *regions_cache = nullptr) const + VarRegionList::cache_t *cache = nullptr) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; - return get_delta (outer, inner, coords, coord_count, regions_cache); + return get_delta (outer, inner, coords, coord_count, cache); } bool sanitize (hb_sanitize_context_t *c) const @@ -3010,9 +3029,7 @@ struct VariationStore protected: HBUINT16 format; - public: Offset32To regions; - protected: Array16OfOffset32To dataSets; public: DEFINE_SIZE_ARRAY_SIZED (8, dataSets); @@ -3487,13 +3504,13 @@ struct VariationDevice hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store, - hb_vector_t *regions_cache = nullptr) const - { return font->em_scalef_x (get_delta (font, store, regions_cache)); } + void *store_cache = nullptr) const + { return font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store, - hb_vector_t *regions_cache = nullptr) const - { return font->em_scalef_y (get_delta (font, store, regions_cache)); } + void *store_cache = nullptr) const + { return font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map) const { @@ -3529,9 +3546,9 @@ struct VariationDevice float get_delta (hb_font_t *font, const VariationStore &store, - hb_vector_t *regions_cache = nullptr) const + void *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords, regions_cache); + return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache); } protected: @@ -3556,7 +3573,7 @@ struct Device { hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore), - hb_vector_t *regions_cache = nullptr) const + void *store_cache = nullptr) const { switch (u.b.format) { @@ -3566,7 +3583,7 @@ struct Device #endif #ifndef HB_NO_VAR case 0x8000: - return u.variation.get_x_delta (font, store, regions_cache); + return u.variation.get_x_delta (font, store, store_cache); #endif default: return 0; @@ -3574,7 +3591,7 @@ struct Device } hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore), - hb_vector_t *regions_cache = nullptr) const + void *store_cache = nullptr) const { switch (u.b.format) { @@ -3584,7 +3601,7 @@ struct Device #endif #ifndef HB_NO_VAR case 0x8000: - return u.variation.get_y_delta (font, store, regions_cache); + return u.variation.get_y_delta (font, store, store_cache); #endif default: return 0; diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 4d1872493..0dbfa016a 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -146,7 +146,7 @@ struct ValueFormat : HBUINT16 if (!use_x_device && !use_y_device) return ret; const VariationStore &store = c->var_store; - auto *cache = &c->regions_cache; + auto *cache = c->var_store_cache; /* pixel -> fractional pixel */ if (format & xPlaDevice) { @@ -466,9 +466,9 @@ struct AnchorFormat3 *y = font->em_fscale_y (yCoordinate); if (font->x_ppem || font->num_coords) - *x += (this+xDeviceTable).get_x_delta (font, c->var_store, &c->regions_cache); + *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); if (font->y_ppem || font->num_coords) - *y += (this+yDeviceTable).get_y_delta (font, c->var_store, &c->regions_cache); + *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); } bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 74922b3da..c2e043a60 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -621,17 +621,17 @@ struct hb_ot_apply_context_t : skipping_iterator_t iter_input, iter_context; + unsigned int table_index; /* GSUB/GPOS */ hb_font_t *font; hb_face_t *face; hb_buffer_t *buffer; recurse_func_t recurse_func; const GDEF &gdef; const VariationStore &var_store; - hb_vector_t regions_cache; + VariationStore::cache_t *var_store_cache; hb_direction_t direction; hb_mask_t lookup_mask; - unsigned int table_index; /* GSUB/GPOS */ unsigned int lookup_index; unsigned int lookup_props; unsigned int nesting_level_left; @@ -649,6 +649,7 @@ struct hb_ot_apply_context_t : hb_font_t *font_, hb_buffer_t *buffer_) : iter_input (), iter_context (), + table_index (table_index_), font (font_), face (font->face), buffer (buffer_), recurse_func (nullptr), gdef ( @@ -659,9 +660,9 @@ struct hb_ot_apply_context_t : #endif ), var_store (gdef.get_var_store ()), + var_store_cache (table_index == 1 && font->num_coords ? var_store.create_cache () : nullptr), direction (buffer_->props.direction), lookup_mask (1), - table_index (table_index_), lookup_index ((unsigned int) -1), lookup_props (0), nesting_level_left (HB_MAX_NESTING_LEVEL), @@ -671,15 +672,9 @@ struct hb_ot_apply_context_t : per_syllable (false), random (false), random_state (1) - { - init_iters (); - if (table_index == 1 && font->num_coords) /* GPOS */ - { - regions_cache.resize ((&var_store+var_store.regions).regionCount); - for (auto &f : regions_cache.writer ()) - f = NAN; - } - } + { init_iters (); } + + ~hb_ot_apply_context_t () { VariationStore::destroy_cache (var_store_cache); } void init_iters () {