diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index 96a394ba42..16eb1eb912 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -31,6 +31,7 @@ #include "hb-ot-maxp-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-var-hvar-table.hh" +#include "hb-ot-var-mvar-table.hh" #include "hb-ot-metrics.hh" /* @@ -73,13 +74,15 @@ struct hmtxvmtx return_trace (true); } - const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>>* get_mtx_map (const hb_subset_plan_t *plan) const - { return T::is_horizontal ? plan->hmtx_map : plan->vmtx_map; } + const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>>* get_mtx_map (const hb_subset_plan_t *plan) const + { return T::is_horizontal ? &plan->hmtx_map : &plan->vmtx_map; } - bool subset_update_header (hb_subset_plan_t *plan, - unsigned int num_hmetrics) const + bool subset_update_header (hb_subset_context_t *c, + unsigned int num_hmetrics, + const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map, + const hb_map_t *bounds_map) const { - hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (plan->source, H::tableTag); + hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (c->plan->source, H::tableTag); hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob); hb_blob_destroy (src_blob); @@ -91,7 +94,56 @@ struct hmtxvmtx H *table = (H *) hb_blob_get_data (dest_blob, &length); table->numberOfLongMetrics = num_hmetrics; - bool result = plan->add_table (H::tableTag, dest_blob); +#ifndef HB_NO_VAR + if (c->plan->normalized_coords) + { + auto &MVAR = *c->plan->source->table.MVAR; + if (T::is_horizontal) + { + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE, caretSlopeRise); + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN, caretSlopeRun); + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET, caretOffset); + } + else + { + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_RISE, caretSlopeRise); + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_RUN, caretSlopeRun); + HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET, caretOffset); + } + + int min_lsb = 0x7FFF; + int min_rsb = 0x7FFF; + int max_extent = -0x7FFF; + unsigned max_adv = 0; + for (const auto _ : *mtx_map) + { + hb_codepoint_t gid = _.first; + unsigned adv = _.second.first; + int lsb = _.second.second; + max_adv = hb_max (max_adv, adv); + + if (bounds_map->has (gid)) + { + unsigned bound_width = bounds_map->get (gid); + int rsb = adv - lsb - bound_width; + int extent = lsb + bound_width; + min_lsb = hb_min (min_lsb, lsb); + min_rsb = hb_min (min_rsb, rsb); + max_extent = hb_max (max_extent, extent); + } + } + + table->advanceMax = max_adv; + if (!bounds_map->is_empty ()) + { + table->minLeadingBearing = min_lsb; + table->minTrailingBearing = min_rsb; + table->maxExtent = max_extent; + } + } +#endif + + bool result = c->plan->add_table (H::tableTag, dest_blob); hb_blob_destroy (dest_blob); return result; @@ -132,7 +184,7 @@ struct hmtxvmtx accelerator_t _mtx (c->plan->source); unsigned num_long_metrics; - const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *mtx_map = get_mtx_map (c->plan); + const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map = get_mtx_map (c->plan); { /* Determine num_long_metrics to encode. */ auto& plan = c->plan; @@ -169,7 +221,8 @@ struct hmtxvmtx return_trace (false); // Amend header num hmetrics - if (unlikely (!subset_update_header (c->plan, num_long_metrics))) + if (unlikely (!subset_update_header (c, num_long_metrics, mtx_map, + T::is_horizontal ? &c->plan->bounds_width_map : &c->plan->bounds_height_map))) return_trace (false); return_trace (true); @@ -291,8 +344,6 @@ struct hmtxvmtx /* num_bearings <= glyph < num_glyphs; * num_bearings <= num_advances */ - /* TODO Optimize */ - if (num_bearings == num_advances) return get_advance_without_var_unscaled (num_bearings - 1); @@ -315,7 +366,7 @@ struct hmtxvmtx if (var_table.get_length ()) return advance + roundf (var_table->get_advance_delta_unscaled (glyph, font->coords, font->num_coords, - store_cache)); // TODO Optimize?! + store_cache)); return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); #else @@ -340,19 +391,17 @@ struct hmtxvmtx /* get advance: when no variations, call get_advance_without_var_unscaled. * when there're variations, get advance value from mtx_map in subset_plan*/ unsigned get_new_gid_advance_unscaled (const hb_subset_plan_t *plan, - const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *mtx_map, + const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map, unsigned new_gid, const accelerator_t &_mtx) const { - if (mtx_map->is_empty () || - (new_gid == 0 && !mtx_map->has (new_gid))) + if (mtx_map->is_empty ()) { hb_codepoint_t old_gid = 0; return plan->old_gid_for_new_gid (new_gid, &old_gid) ? _mtx.get_advance_without_var_unscaled (old_gid) : 0; } - else - { return mtx_map->get (new_gid).first; } + return mtx_map->get (new_gid).first; } protected: |