[instancer] update vhea/hhea tables

This commit is contained in:
Qunxin Liu 2023-01-13 11:42:58 -08:00
parent fcb5111cc6
commit 92122421c9
3 changed files with 50 additions and 8 deletions

View File

@ -80,13 +80,20 @@ struct Glyph
} }
void update_mtx (const hb_subset_plan_t *plan, 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 const contour_point_vector_t &all_points) const
{ {
hb_codepoint_t new_gid = 0; hb_codepoint_t new_gid = 0;
if (!plan->new_gid_for_old_gid (gid, &new_gid)) if (!plan->new_gid_for_old_gid (gid, &new_gid))
return; 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; unsigned len = all_points.length;
float leftSideX = all_points[len - 4].x; float leftSideX = all_points[len - 4].x;
float rightSideX = all_points[len - 3].x; float rightSideX = all_points[len - 3].x;
@ -133,7 +140,7 @@ struct Glyph
yMax = hb_max (yMax, y); 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. /*for empty glyphs: all_points only include phantom points.
*just update metrics and then return */ *just update metrics and then return */

View File

@ -78,7 +78,9 @@ struct hmtxvmtx
{ return T::is_horizontal ? &plan->hmtx_map : &plan->vmtx_map; } { return T::is_horizontal ? &plan->hmtx_map : &plan->vmtx_map; }
bool subset_update_header (hb_subset_context_t *c, bool subset_update_header (hb_subset_context_t *c,
unsigned int num_hmetrics) const 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> (c->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_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_RUN, caretSlopeRun);
HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET, caretOffset); 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 #endif
@ -189,7 +221,8 @@ struct hmtxvmtx
return_trace (false); return_trace (false);
// Amend header num hmetrics // 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 (false);
return_trace (true); return_trace (true);
@ -362,15 +395,13 @@ struct hmtxvmtx
unsigned new_gid, unsigned new_gid,
const accelerator_t &_mtx) const const accelerator_t &_mtx) const
{ {
if (mtx_map->is_empty () || if (mtx_map->is_empty ())
(new_gid == 0 && !mtx_map->has (new_gid)))
{ {
hb_codepoint_t old_gid = 0; hb_codepoint_t old_gid = 0;
return plan->old_gid_for_new_gid (new_gid, &old_gid) ? return plan->old_gid_for_new_gid (new_gid, &old_gid) ?
_mtx.get_advance_without_var_unscaled (old_gid) : 0; _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: protected:

View File

@ -163,6 +163,10 @@ struct hb_subset_plan_t
mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> hmtx_map; mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> hmtx_map;
//vmtx metrics map: new gid->(advance, lsb) //vmtx metrics map: new gid->(advance, lsb)
mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> vmtx_map; mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> 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 #ifdef HB_EXPERIMENTAL_API
// name table overrides map: hb_ot_name_record_ids_t-> name string new value or // name table overrides map: hb_ot_name_record_ids_t-> name string new value or