summaryrefslogtreecommitdiff
path: root/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2023-02-27 12:11:51 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2023-03-01 19:15:38 +0100
commit13549fa7c2d27ba588471f97a640f4dbcf86b10c (patch)
treee9cddcf9f9c384a62b032db392883817f876c667 /src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
parentcdbdd05fd9bd60322cb10b47614ed61035ddb8ed (diff)
downloadqtbase-13549fa7c2d27ba588471f97a640f4dbcf86b10c.tar.gz
Update Harfbuzz to 7.0.1
This is the 6.4-specific update of Harfbuzz, since Harfbuzz was currently on an older version in 6.4 compared to other branches. This also backports the change to the qtextlayout test that was done on other branches for the 6.0.0 update. Pick-to: 6.4.3 Fixes: QTBUG-111535 Change-Id: Ie8217f1541a02d3800142b88cf0007be0ed0d1e2 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
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.hh179
1 files changed, 134 insertions, 45 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 d5e1fc91d2..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"
/*
@@ -43,11 +44,11 @@
#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')
-HB_INTERNAL int
-_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
+HB_INTERNAL bool
+_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, int *lsb);
HB_INTERNAL unsigned
-_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
+_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
namespace OT {
@@ -62,7 +63,7 @@ struct LongMetric
};
-template <typename T, typename H>
+template <typename T/*Data table type*/, typename H/*Header table type*/, typename V/*Var table type*/>
struct hmtxvmtx
{
bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
@@ -73,11 +74,15 @@ struct hmtxvmtx
return_trace (true);
}
+ 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);
@@ -89,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;
@@ -130,14 +184,15 @@ struct hmtxvmtx
accelerator_t _mtx (c->plan->source);
unsigned num_long_metrics;
+ 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;
+
num_long_metrics = plan->num_output_glyphs ();
- hb_codepoint_t old_gid = 0;
- unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0;
+ unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx);
while (num_long_metrics > 1 &&
- last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0))
+ last_advance == get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 2, _mtx))
{
num_long_metrics--;
}
@@ -145,12 +200,18 @@ struct hmtxvmtx
auto it =
+ hb_range (c->plan->num_output_glyphs ())
- | hb_map ([c, &_mtx] (unsigned _)
+ | hb_map ([c, &_mtx, mtx_map] (unsigned _)
{
- hb_codepoint_t old_gid;
- if (!c->plan->old_gid_for_new_gid (_, &old_gid))
- return hb_pair (0u, 0);
- return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
+ if (!mtx_map->has (_))
+ {
+ hb_codepoint_t old_gid;
+ if (!c->plan->old_gid_for_new_gid (_, &old_gid))
+ return hb_pair (0u, 0);
+ int lsb = 0;
+ (void) _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb);
+ return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb);
+ }
+ return mtx_map->get (_);
})
;
@@ -160,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);
@@ -173,7 +235,7 @@ struct hmtxvmtx
accelerator_t (hb_face_t *face)
{
table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag);
- var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag);
+ var_table = hb_sanitize_context_t ().reference_table<V> (face, T::variationsTag);
default_advance = T::is_horizontal ? hb_face_get_upem (face) / 2 : hb_face_get_upem (face);
@@ -221,36 +283,46 @@ struct hmtxvmtx
bool has_data () const { return (bool) num_bearings; }
- int get_side_bearing (hb_codepoint_t glyph) const
+ bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph,
+ int *lsb) const
{
if (glyph < num_long_metrics)
- return table->longMetricZ[glyph].sb;
+ {
+ *lsb = table->longMetricZ[glyph].sb;
+ return true;
+ }
if (unlikely (glyph >= num_bearings))
- return 0;
+ return false;
const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
- return bearings[glyph - num_long_metrics];
+ *lsb = bearings[glyph - num_long_metrics];
+ return true;
}
- int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
+ bool get_leading_bearing_with_var_unscaled (hb_font_t *font,
+ hb_codepoint_t glyph,
+ int *lsb) const
{
- int side_bearing = get_side_bearing (glyph);
+ if (!font->num_coords)
+ return get_leading_bearing_without_var_unscaled (glyph, lsb);
#ifndef HB_NO_VAR
- if (unlikely (glyph >= num_bearings) || !font->num_coords)
- return side_bearing;
-
- if (var_table.get_length ())
- return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
+ float delta;
+ if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) &&
+ get_leading_bearing_without_var_unscaled (glyph, lsb))
+ {
+ *lsb += roundf (delta);
+ return true;
+ }
- return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
+ return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx, lsb);
#else
- return side_bearing;
+ return false;
#endif
}
- unsigned int get_advance (hb_codepoint_t glyph) const
+ unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const
{
/* OpenType case. */
if (glyph < num_bearings)
@@ -262,7 +334,7 @@ struct hmtxvmtx
if (unlikely (!num_advances))
return default_advance;
-#ifdef HB_NO_BORING_EXPANSION
+#ifdef HB_NO_BEYOND_64K
return 0;
#endif
@@ -272,10 +344,8 @@ struct hmtxvmtx
/* num_bearings <= glyph < num_glyphs;
* num_bearings <= num_advances */
- /* TODO Optimize */
-
if (num_bearings == num_advances)
- return get_advance (num_bearings - 1);
+ return get_advance_without_var_unscaled (num_bearings - 1);
const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
const UFWORD *advances = (const UFWORD *) &bearings[num_bearings - num_long_metrics];
@@ -283,19 +353,22 @@ struct hmtxvmtx
return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)];
}
- unsigned int get_advance (hb_codepoint_t glyph,
- hb_font_t *font) const
+ unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph,
+ hb_font_t *font,
+ VariationStore::cache_t *store_cache = nullptr) const
{
- unsigned int advance = get_advance (glyph);
+ unsigned int advance = get_advance_without_var_unscaled (glyph);
#ifndef HB_NO_VAR
if (unlikely (glyph >= num_bearings) || !font->num_coords)
return advance;
if (var_table.get_length ())
- return advance + roundf (var_table->get_advance_var (glyph, font)); // TODO Optimize?!
+ return advance + roundf (var_table->get_advance_delta_unscaled (glyph,
+ font->coords, font->num_coords,
+ store_cache));
- return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
+ return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
#else
return advance;
#endif
@@ -310,11 +383,27 @@ struct hmtxvmtx
unsigned int default_advance;
- private:
+ public:
hb_blob_ptr_t<hmtxvmtx> table;
- hb_blob_ptr_t<HVARVVAR> var_table;
+ hb_blob_ptr_t<V> var_table;
};
+ /* 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<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map,
+ unsigned new_gid,
+ const accelerator_t &_mtx) const
+ {
+ 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;
+ }
+ return mtx_map->get (new_gid).first;
+ }
+
protected:
UnsizedArrayOf<LongMetric>
longMetricZ; /* Paired advance width and leading
@@ -345,12 +434,12 @@ struct hmtxvmtx
DEFINE_SIZE_ARRAY (0, longMetricZ);
};
-struct hmtx : hmtxvmtx<hmtx, hhea> {
+struct hmtx : hmtxvmtx<hmtx, hhea, HVAR> {
static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx;
static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR;
static constexpr bool is_horizontal = true;
};
-struct vmtx : hmtxvmtx<vmtx, vhea> {
+struct vmtx : hmtxvmtx<vmtx, vhea, VVAR> {
static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx;
static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR;
static constexpr bool is_horizontal = false;