From 92122421c951f6f126eff902f917b403bdf027a5 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Fri, 13 Jan 2023 11:42:58 -0800 Subject: [PATCH] [instancer] update vhea/hhea tables --- src/OT/glyf/Glyph.hh | 11 +++++++++-- src/hb-ot-hmtx-table.hh | 43 +++++++++++++++++++++++++++++++++++------ src/hb-subset-plan.hh | 4 ++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/OT/glyf/Glyph.hh b/src/OT/glyf/Glyph.hh index 1fcad8d86..edbe4b87d 100644 --- a/src/OT/glyf/Glyph.hh +++ b/src/OT/glyf/Glyph.hh @@ -80,13 +80,20 @@ struct Glyph } void update_mtx (const hb_subset_plan_t *plan, - int xMin, int yMax, + int xMin, int xMax, + int yMin, int yMax, const contour_point_vector_t &all_points) const { hb_codepoint_t new_gid = 0; if (!plan->new_gid_for_old_gid (gid, &new_gid)) return; + if (type != EMPTY) + { + plan->bounds_width_map.set (new_gid, xMax - xMin); + plan->bounds_height_map.set (new_gid, yMax - yMin); + } + unsigned len = all_points.length; float leftSideX = all_points[len - 4].x; float rightSideX = all_points[len - 3].x; @@ -133,7 +140,7 @@ struct Glyph yMax = hb_max (yMax, y); } - update_mtx (plan, roundf (xMin), roundf (yMax), all_points); + update_mtx (plan, roundf (xMin), roundf (xMax), roundf (yMin), roundf (yMax), all_points); /*for empty glyphs: all_points only include phantom points. *just update metrics and then return */ diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index d35c60126..9e92c2b71 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -78,7 +78,9 @@ struct hmtxvmtx { return T::is_horizontal ? &plan->hmtx_map : &plan->vmtx_map; } bool subset_update_header (hb_subset_context_t *c, - unsigned int num_hmetrics) const + unsigned int num_hmetrics, + const hb_hashmap_t> *mtx_map, + const hb_map_t *bounds_map) const { hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table (c->plan->source, H::tableTag); hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob); @@ -108,6 +110,36 @@ struct hmtxvmtx 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_training_sb = 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_training_sb = hb_min (min_training_sb, rsb); + max_extent = hb_max (max_extent, extent); + } + } + + table->advanceMax = max_adv; + if (!bounds_map->is_empty ()) + { + table->minLeadingBearing = min_lsb; + table->minTrailingBearing = min_training_sb; + table->maxExtent = max_extent; + } } #endif @@ -189,7 +221,8 @@ struct hmtxvmtx return_trace (false); // Amend header num hmetrics - if (unlikely (!subset_update_header (c, 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); @@ -362,15 +395,13 @@ struct hmtxvmtx 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: diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index d7979b8a7..124369a49 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -163,6 +163,10 @@ struct hb_subset_plan_t mutable hb_hashmap_t> hmtx_map; //vmtx metrics map: new gid->(advance, lsb) mutable hb_hashmap_t> vmtx_map; + //boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin + mutable hb_map_t bounds_width_map; + //boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin + mutable hb_map_t bounds_height_map; #ifdef HB_EXPERIMENTAL_API // name table overrides map: hb_ot_name_record_ids_t-> name string new value or