summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
diff options
context:
space:
mode:
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.hh81
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: