diff --git a/src/3rdparty/harfbuzz-ng/CMakeLists.txt b/src/3rdparty/harfbuzz-ng/CMakeLists.txt index c23642e17dc..6db3ce881bb 100644 --- a/src/3rdparty/harfbuzz-ng/CMakeLists.txt +++ b/src/3rdparty/harfbuzz-ng/CMakeLists.txt @@ -44,6 +44,7 @@ qt_internal_add_3rdparty_library(BundledHarfbuzz src/hb-open-type.hh src/hb-outline.cc src/hb-outline.hh src/hb-paint.cc src/hb-paint.h src/hb-paint.hh + src/hb-paint-bounded.cc src/hb-paint-bounded.hh src/hb-paint-extents.cc src/hb-paint-extents.hh src/hb-priority-queue.hh src/hb-repacker.hh diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json index 93fc920ed2f..f4ab0d9329e 100644 --- a/src/3rdparty/harfbuzz-ng/qt_attribution.json +++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json @@ -7,8 +7,8 @@ "Description": "HarfBuzz is an OpenType text shaping engine.", "Homepage": "http://harfbuzz.org", - "Version": "11.1.0", - "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/11.1.0", + "Version": "11.2.1", + "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/11.2.1", "PURL": "pkg:github/harfbuzz/harfbuzz@$", "CPE": "cpe:2.3:a:harfbuzz_project:harfbuzz:$:*:*:*:*:*:*:*", "License": "MIT License", diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh index 50550e81106..2d8f1da52dd 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh @@ -949,25 +949,25 @@ struct CBDT hb_glyph_extents_t extents; hb_glyph_extents_t pixel_extents; - hb_blob_t *blob = reference_png (font, glyph); - - if (unlikely (blob == hb_blob_get_empty ())) - return false; - - if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) + if (unlikely (!font->get_glyph_extents (glyph, &extents, false))) return false; if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) return false; + hb_blob_t *blob = reference_png (font, glyph); + if (unlikely (hb_blob_is_immutable (blob))) + return false; + bool ret = funcs->image (data, blob, pixel_extents.width, -pixel_extents.height, HB_PAINT_IMAGE_FORMAT_PNG, - font->slant_xy, + 0.f, &extents); hb_blob_destroy (blob); + return ret; } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh index 16cd96e32d2..448c1e4a0bd 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh @@ -33,6 +33,7 @@ #include "../../../hb-open-type.hh" #include "../../../hb-ot-var-common.hh" #include "../../../hb-paint.hh" +#include "../../../hb-paint-bounded.hh" #include "../../../hb-paint-extents.hh" #include "../CPAL/CPAL.hh" @@ -49,6 +50,7 @@ struct hb_paint_context_t; struct hb_colr_scratch_t { + hb_paint_bounded_context_t paint_bounded; hb_paint_extents_context_t paint_extents; }; @@ -101,7 +103,21 @@ public: ), foreground (foreground_), instancer (instancer_) - { } + { + if (font->is_synthetic ()) + { + font = hb_font_create_sub_font (font); + hb_font_set_synthetic_bold (font, 0, 0, true); + hb_font_set_synthetic_slant (font, 0); + } + else + hb_font_reference (font); + } + + ~hb_paint_context_t () + { + hb_font_destroy (font); + } hb_color_t get_color (unsigned int color_index, float alpha, hb_bool_t *is_foreground) { @@ -1620,7 +1636,7 @@ struct ClipBox void closurev1 (hb_colrv1_closure_context_t* c) const { switch (u.format) { - case 2: u.format2.closurev1 (c); + case 2: u.format2.closurev1 (c); return; default:return; } } @@ -2230,7 +2246,7 @@ struct COLR public: hb_blob_ptr_t colr; private: - hb_atomic_t cached_scratch; + mutable hb_atomic_t cached_scratch; }; void closure_glyphs (hb_codepoint_t glyph, @@ -2632,7 +2648,6 @@ struct COLR } else { - // Ugh. We need to undo the synthetic slant here. Leave it for now. :-(. extents->x_bearing = e.xmin; extents->y_bearing = e.ymax; extents->width = e.xmax - e.xmin; @@ -2700,7 +2715,6 @@ struct COLR if (get_clip (glyph, &extents, instancer)) { font->scale_glyph_extents (&extents); - font->synthetic_glyph_extents (&extents); c.funcs->push_clip_rectangle (c.data, extents.x_bearing, extents.y_bearing + extents.height, @@ -2709,23 +2723,22 @@ struct COLR } else { - auto *extents_funcs = hb_paint_extents_get_funcs (); - scratch.paint_extents.clear (); + clip = false; + is_bounded = false; + } + + if (!is_bounded) + { + auto *bounded_funcs = hb_paint_bounded_get_funcs (); + scratch.paint_bounded.clear (); paint_glyph (font, glyph, - extents_funcs, &scratch.paint_extents, + bounded_funcs, &scratch.paint_bounded, palette_index, foreground, false, scratch); - auto extents = scratch.paint_extents.get_extents (); - is_bounded = scratch.paint_extents.is_bounded (); - - c.funcs->push_clip_rectangle (c.data, - extents.xmin, - extents.ymin, - extents.xmax, - extents.ymax); + is_bounded = scratch.paint_bounded.is_bounded (); } } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh index 51ae1a9c63b..bb0e83e2eba 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh @@ -237,27 +237,28 @@ struct sbix int x_offset = 0, y_offset = 0; unsigned int strike_ppem = 0; - hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); hb_glyph_extents_t extents; hb_glyph_extents_t pixel_extents; - if (blob == hb_blob_get_empty ()) - return false; - - if (!hb_font_get_glyph_extents (font, glyph, &extents)) + if (!font->get_glyph_extents (glyph, &extents, false)) return false; if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) return false; + hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); + if (hb_blob_is_immutable (blob)) + return false; + bool ret = funcs->image (data, blob, pixel_extents.width, -pixel_extents.height, HB_PAINT_IMAGE_FORMAT_PNG, - font->slant_xy, + 0.f, &extents); hb_blob_destroy (blob); + return ret; } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh index 2e1f935109d..d6aca4a60e7 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh @@ -104,15 +104,16 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, - blob, - 0, 0, - HB_PAINT_IMAGE_FORMAT_SVG, - font->slant_xy, - nullptr); + bool ret = funcs->image (data, + blob, + 0, 0, + HB_PAINT_IMAGE_FORMAT_SVG, + 0.f, + nullptr); hb_blob_destroy (blob); - return true; + + return ret; } private: diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh index 6b019ac513b..404ab7a33bf 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -130,7 +130,7 @@ struct CursivePosFormat1 unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); hb_barrier (); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_from; if (unlikely (!skippy_iter.prev (&unsafe_from))) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh index f4af98b25fd..ce3f74d8c3b 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh @@ -152,8 +152,11 @@ GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) for (unsigned i = 0; i < len; i++) propagate_attachment_offsets (pos, len, i, direction); - if (unlikely (font->slant)) + if (unlikely (font->slant_xy) && + HB_DIRECTION_IS_HORIZONTAL (direction)) { + /* Slanting shaping results is only supported for horizontal text, + * as it gets weird otherwise. */ for (unsigned i = 0; i < len; i++) if (unlikely (pos[i].y_offset)) pos[i].x_offset += roundf (font->slant_xy * pos[i].y_offset); diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh index 1b8f3c80a9a..ab1378e615c 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -119,7 +119,7 @@ struct MarkBasePosFormat1_2 /* Now we search backwards for a non-mark glyph. * We don't use skippy_iter.prev() to avoid O(n^2) behavior. */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (c->last_base_until > buffer->idx) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh index d6bee277c70..46013c613b0 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -101,7 +101,7 @@ struct MarkLigPosFormat1_2 /* Now we search backwards for a non-mark glyph */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (c->last_base_until > buffer->idx) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index 57eb782a958..c4d129f2cb0 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -100,7 +100,7 @@ struct MarkMarkPosFormat1_2 if (likely (mark1_index == NOT_COVERED)) return_trace (false); /* now we search backwards for a suitable mark glyph until a non-mark glyph */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); unsigned unsafe_from; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh index 5e3ac43f414..a8ea5f96c05 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -148,7 +148,7 @@ struct PairPosFormat1_3 #endif if (index == NOT_COVERED) return_trace (false); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_to; if (unlikely (!skippy_iter.next (&unsafe_to))) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh index f30148ab686..59c018b9276 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -179,7 +179,7 @@ struct PairPosFormat2_4 : ValueBase #endif if (index == NOT_COVERED) return_trace (false); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_to; if (unlikely (!skippy_iter.next (&unsafe_to))) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh index 08665438c4a..17ae38766ae 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh @@ -96,7 +96,7 @@ struct LigatureSet * * This is replicated in ChainRuleSet and RuleSet. */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc index 6dade65f371..d121c12c296 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc +++ b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc @@ -355,12 +355,12 @@ VARC::get_path_at (const hb_varc_context_t &c, hb_draw_session_t transformer_session {transformer_funcs, &context}; hb_draw_session_t &shape_draw_session = transform.is_identity () ? *c.draw_session : transformer_session; - if (!c.font->face->table.glyf->get_path_at (c.font, glyph, shape_draw_session, coords, c.scratch.glyf_scratch)) + if (c.font->face->table.glyf->get_path_at (c.font, glyph, shape_draw_session, coords, c.scratch.glyf_scratch)) return true; #ifndef HB_NO_CFF - if (!c.font->face->table.cff2->get_path_at (c.font, glyph, shape_draw_session, coords)) - if (!c.font->face->table.cff1->get_path (c.font, glyph, shape_draw_session)) // Doesn't have variations + if (c.font->face->table.cff2->get_path_at (c.font, glyph, shape_draw_session, coords)) return true; + if (c.font->face->table.cff1->get_path (c.font, glyph, shape_draw_session)) return true; // Doesn't have variations #endif - return false; + return false; } else if (c.extents) { diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh index 22cfbb8ca81..0ce2ee5f10a 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh @@ -235,7 +235,7 @@ struct VARC private: hb_blob_ptr_t table; - hb_atomic_t cached_scratch; + mutable hb_atomic_t cached_scratch; }; bool has_data () const { return version.major != 0; } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh index b136b150282..16bd26eae2b 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh @@ -543,7 +543,7 @@ struct glyf_accelerator_t unsigned int num_glyphs; hb_blob_ptr_t loca_table; hb_blob_ptr_t glyf_table; - hb_atomic_t cached_scratch; + mutable hb_atomic_t cached_scratch; }; diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc index 91aa91f8a9d..79fac9e62d5 100644 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc +++ b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc @@ -43,6 +43,7 @@ #include "hb-ot-tag.cc" #include "hb-ot-var.cc" #include "hb-outline.cc" +#include "hb-paint-bounded.cc" #include "hb-paint-extents.cc" #include "hb-paint.cc" #include "hb-set.cc" diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc b/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc index 985797df492..471942c551c 100644 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc +++ b/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc @@ -52,6 +52,7 @@ #include "hb-ot-tag.cc" #include "hb-ot-var.cc" #include "hb-outline.cc" +#include "hb-paint-bounded.cc" #include "hb-paint-extents.cc" #include "hb-paint.cc" #include "hb-set.cc" diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh index 03f84725d45..45071ef6310 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh @@ -194,7 +194,7 @@ struct hb_atomic_t void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } - bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + bool cmpexch (const T *old, T *new_) { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } operator bool () const { return get_acquire () != nullptr; } T * operator -> () const { return get_acquire (); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh index 8a520512036..1a534aad2c8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh @@ -410,6 +410,9 @@ struct hb_buffer_t bool interior = false, bool from_out_buffer = false) { + if (unlikely (end != (unsigned) -1 && end - start > 255)) + return; + end = hb_min (end, len); if (interior && !from_out_buffer && end - start < 2) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.cc b/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.cc index 85c62d39a95..daf72b03c8e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.cc @@ -31,8 +31,6 @@ #include "hb-cairo-utils.hh" -#include - /* Some routines in this file were ported from BlackRenderer by Black Foundry. * Used by permission to relicense to HarfBuzz license. * @@ -101,7 +99,7 @@ _hb_cairo_paint_glyph_image (hb_cairo_context_t *c, unsigned width, unsigned height, hb_tag_t format, - float slant, + HB_UNUSED float slant_deprecated, hb_glyph_extents_t *extents) { cairo_t *cr = c->cr; @@ -186,12 +184,6 @@ _hb_cairo_paint_glyph_image (hb_cairo_context_t *c, cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; cairo_pattern_set_matrix (pattern, &matrix); - /* Undo slant in the extents and apply it in the context. */ - extents->width -= extents->height * slant; - extents->x_bearing -= extents->y_bearing * slant; - cairo_matrix_t cairo_matrix = {1., 0., (double) slant, 1., 0., 0.}; - cairo_transform (cr, &cairo_matrix); - cairo_translate (cr, extents->x_bearing, extents->y_bearing); cairo_scale (cr, extents->width, extents->height); cairo_set_source (cr, pattern); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cairo.cc b/src/3rdparty/harfbuzz-ng/src/hb-cairo.cc index 89332d71519..76aebaab25f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cairo.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-cairo.cc @@ -204,7 +204,9 @@ hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, cairo_save (cr); cairo_new_path (cr); + hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr); + cairo_close_path (cr); cairo_clip (cr); } @@ -572,9 +574,12 @@ hb_cairo_text_to_glyphs (cairo_scaled_font_t *scaled_font, hb_buffer_guess_segment_properties (buffer); hb_shape (font, buffer, nullptr, 0); + int x_scale, y_scale; + hb_font_get_scale (font, &x_scale, &y_scale); + hb_cairo_glyphs_from_buffer (buffer, true, - font->x_scale, font->y_scale, + x_scale, y_scale, 0., 0., utf8, utf8_len, glyphs, (unsigned *) num_glyphs, @@ -601,10 +606,11 @@ hb_cairo_render_glyph (cairo_scaled_font_t *scaled_font, +1. / (x_scale ? x_scale : 1), -1. / (y_scale ? y_scale : 1)); - hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr); - - cairo_fill (cr); + if (hb_font_draw_glyph_or_fail (font, glyph, hb_cairo_draw_get_funcs (), cr)) + cairo_fill (cr); + // If draw fails, we still return SUCCESS, as we want empty drawing, not + // setting the cairo object into error. return CAIRO_STATUS_SUCCESS; } @@ -639,8 +645,8 @@ hb_cairo_render_color_glyph (cairo_scaled_font_t *scaled_font, c.cr = cr; c.color_cache = (hb_map_t *) cairo_scaled_font_get_user_data (scaled_font, &color_cache_key); - hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), &c, palette, color); - + if (!hb_font_paint_glyph_or_fail (font, glyph, hb_cairo_paint_get_funcs (), &c, palette, color)) + return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; return CAIRO_STATUS_SUCCESS; } @@ -657,8 +663,7 @@ user_font_face_create (hb_face_t *face) cairo_user_font_face_set_text_to_glyphs_func (cairo_face, hb_cairo_text_to_glyphs); cairo_user_font_face_set_render_glyph_func (cairo_face, hb_cairo_render_glyph); #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC - if (hb_ot_color_has_png (face) || hb_ot_color_has_layers (face) || hb_ot_color_has_paint (face)) - cairo_user_font_face_set_render_color_glyph_func (cairo_face, hb_cairo_render_color_glyph); + cairo_user_font_face_set_render_color_glyph_func (cairo_face, hb_cairo_render_color_glyph); #endif if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face, @@ -689,7 +694,8 @@ hb_cairo_font_face_create_for_font (hb_font_t *font) { hb_font_make_immutable (font); - auto *cairo_face = user_font_face_create (font->face); + auto *hb_face = hb_font_get_face (font); + auto *cairo_face = user_font_face_create (hb_face); if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face, &hb_cairo_font_user_data_key, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext-font.cc index 9a6bf0bf9c0..a0a250e44e8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext-font.cc @@ -365,12 +365,12 @@ ct_apply_func (void *info, const CGPathElement *element) } } -static void -hb_coretext_draw_glyph (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data) +static hb_bool_t +hb_coretext_draw_glyph_or_fail (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) { CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; @@ -383,13 +383,15 @@ hb_coretext_draw_glyph (hb_font_t *font, CGPathRef path = CTFontCreatePathForGlyph (ct_font, glyph, &transform); if (!path) - return; + return false; - hb_draw_session_t drawing = {draw_funcs, draw_data, font->slant}; + hb_draw_session_t drawing {draw_funcs, draw_data}; CGPathApply (path, &drawing, ct_apply_func); CFRelease (path); + + return true; } #endif @@ -469,7 +471,7 @@ static struct hb_coretext_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t #endif #ifndef HB_NO_DRAW - hb_font_funcs_set_draw_glyph_func (funcs, hb_coretext_draw_glyph, nullptr, nullptr); + hb_font_funcs_set_draw_glyph_or_fail_func (funcs, hb_coretext_draw_glyph_or_fail, nullptr, nullptr); #endif hb_font_funcs_set_glyph_extents_func (funcs, hb_coretext_get_glyph_extents, nullptr, nullptr); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index 7d7dfc0a8dc..ea2d5b6e978 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -205,10 +205,18 @@ create_cg_font (hb_blob_t *blob, unsigned int index) if (unlikely (named_instance_index != 0)) { + // https://github.com/harfbuzz/harfbuzz/issues/5300 +#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) || \ + (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || \ + (defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= 110000) || \ + (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __WATCH_OS_VERSION_MIN_REQUIRED >= 40000) || \ + (defined(__MACCATALYST_VERSION_MIN_REQUIRED) && __MACCATALYST_VERSION_MIN_REQUIRED >= 130100) || \ + (defined(__VISION_OS_VERSION_MIN_REQUIRED) && __VISION_OS_VERSION_MIN_REQUIRED >= 10000) auto ct_font_desc_array = CTFontManagerCreateFontDescriptorsFromData (CFDataCreate (kCFAllocatorDefault, (const UInt8 *) blob_data, blob_length)); - if (unlikely (!ct_font_desc_array)) - return nullptr; - return create_cg_font (ct_font_desc_array, named_instance_index); + if (likely (ct_font_desc_array)) + return create_cg_font (ct_font_desc_array, named_instance_index); +#endif + return nullptr; } hb_blob_reference (blob); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h index ad19f9a3e94..62911bba795 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h @@ -275,6 +275,48 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data); +/** + * hb_font_draw_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @draw_funcs: The draw functions to send the shape data to + * @draw_data: The data accompanying the draw functions + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: 7.0.0 + * XDeprecated: REPLACEME: Use hb_font_draw_glyph_func_or_fail_t instead. + **/ +typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data); + +/** + * hb_font_paint_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @paint_funcs: The paint functions to use + * @paint_data: The data accompanying the paint functions + * @palette_index: The color palette to use + * @foreground: The foreground color + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: 7.0.0 + * XDeprecated: REPLACEME: Use hb_font_paint_glyph_or_fail_func_t instead. + */ +typedef hb_bool_t (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data); + /** * hb_font_funcs_set_glyph_shape_func: * @ffuncs: A font-function structure @@ -288,13 +330,49 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data * Since: 4.0.0 * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead **/ -HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_func) +HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_or_fail_func) HB_EXTERN void hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_shape_func_t func, void *user_data, hb_destroy_func_t destroy); -HB_DEPRECATED_FOR (hb_font_draw_glyph) +/** + * hb_font_funcs_set_draw_glyph_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_font_draw_glyph_func_t. + * + * Since: 7.0.0 + * XDeprecated: REPLACEME: Use hb_font_funcs_set_draw_glyph_or_fail_func instead. + **/ +HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_or_fail_func) +HB_EXTERN void +hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_paint_glyph_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is no longer needed + * + * Sets the implementation function for #hb_font_paint_glyph_func_t. + * + * Since: 7.0.0 + * XDeprecated: REPLACEME: Use hb_font_funcs_set_paint_glyph_or_fail_func() instead. + */ +HB_DEPRECATED_FOR (hb_font_funcs_set_paint_glyph_or_fail_func) +HB_EXTERN void +hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_paint_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + +HB_DEPRECATED_FOR (hb_font_draw_glyph_or_fail) HB_EXTERN void hb_font_get_glyph_shape (hb_font_t *font, hb_codepoint_t glyph, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-directwrite-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-directwrite-font.cc index 9752110e474..2ebda19bfc3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-directwrite-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-directwrite-font.cc @@ -114,6 +114,8 @@ hb_directwrite_get_glyph_h_advances (hb_font_t* font, dw_face->QueryInterface (__uuidof(IDWriteFontFace1), (void**)&dw_face1); assert (dw_face1); + unsigned int num_glyphs = font->face->get_num_glyphs (); + for (unsigned i = 0; i < count;) { UINT16 gids[MAX_GLYPHS]; @@ -130,7 +132,9 @@ hb_directwrite_get_glyph_h_advances (hb_font_t* font, dw_face1->GetDesignGlyphAdvances (n, gids, advances, false); for (unsigned j = 0; j < n; j++) { - *first_advance = font->em_scale_x (advances[j]); + // https://github.com/harfbuzz/harfbuzz/issues/5319 + auto advance = gids[j] < num_glyphs ? advances[j] : 0; + *first_advance = font->em_scale_x (advance); first_advance = &StructAtOffset (first_advance, advance_stride); } @@ -238,7 +242,7 @@ public: GeometrySink(hb_font_t *font, hb_draw_funcs_t *draw_funcs, void *draw_data) - : font (font), drawing ({draw_funcs, draw_data, font->slant}) {} + : font (font), drawing ({draw_funcs, draw_data}) {} virtual ~GeometrySink() {} @@ -275,12 +279,12 @@ public: } }; -static void -hb_directwrite_draw_glyph (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data) +static hb_bool_t +hb_directwrite_draw_glyph_or_fail (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) { IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; @@ -288,11 +292,11 @@ hb_directwrite_draw_glyph (hb_font_t *font, UINT16 gid = static_cast(glyph); unsigned upem = font->face->get_upem(); - (void) dw_face->GetGlyphRunOutline (upem, - &gid, nullptr, nullptr, - 1, - false, false, - &sink); + return S_OK == dw_face->GetGlyphRunOutline (upem, + &gid, nullptr, nullptr, + 1, + false, false, + &sink); } #endif @@ -317,7 +321,7 @@ static struct hb_directwrite_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loade #endif #ifndef HB_NO_DRAW - hb_font_funcs_set_draw_glyph_func (funcs, hb_directwrite_draw_glyph, nullptr, nullptr); + hb_font_funcs_set_draw_glyph_or_fail_func (funcs, hb_directwrite_draw_glyph_or_fail, nullptr, nullptr); #endif hb_font_funcs_set_glyph_extents_func (funcs, hb_directwrite_get_glyph_extents, nullptr, nullptr); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.cc b/src/3rdparty/harfbuzz-ng/src/hb-draw.cc index f204f56bc7a..eec3b0bb9f0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-draw.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-draw.cc @@ -28,6 +28,11 @@ #include "hb-draw.hh" +#include "hb-geometry.hh" + +#include "hb-machinery.hh" + + /** * SECTION:hb-draw * @title: hb-draw @@ -455,4 +460,92 @@ hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data, } +static void +hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t *extents = (hb_extents_t *) data; + + extents->add_point (to_x, to_y); +} + +static void +hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t *extents = (hb_extents_t *) data; + + extents->add_point (to_x, to_y); +} + +static void +hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float control_x, float control_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t *extents = (hb_extents_t *) data; + + extents->add_point (control_x, control_y); + extents->add_point (to_x, to_y); +} + +static void +hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t *extents = (hb_extents_t *) data; + + extents->add_point (control1_x, control1_y); + extents->add_point (control2_x, control2_y); + extents->add_point (to_x, to_y); +} + +static inline void free_static_draw_extents_funcs (); + +static struct hb_draw_extents_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t +{ + static hb_draw_funcs_t *create () + { + hb_draw_funcs_t *funcs = hb_draw_funcs_create (); + + hb_draw_funcs_set_move_to_func (funcs, hb_draw_extents_move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, hb_draw_extents_line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, hb_draw_extents_quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, hb_draw_extents_cubic_to, nullptr, nullptr); + + hb_draw_funcs_make_immutable (funcs); + + hb_atexit (free_static_draw_extents_funcs); + + return funcs; + } +} static_draw_extents_funcs; + +static inline +void free_static_draw_extents_funcs () +{ + static_draw_extents_funcs.free_instance (); +} + +hb_draw_funcs_t * +hb_draw_extents_get_funcs () +{ + return static_draw_extents_funcs.get_unconst (); +} + + #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.h b/src/3rdparty/harfbuzz-ng/src/hb-draw.h index 02107845582..76aa93f110a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-draw.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-draw.h @@ -41,16 +41,9 @@ HB_BEGIN_DECLS * @path_start_y: Y component of the start of current path * @current_x: X component of current point * @current_y: Y component of current point - * @slant_xy: Slanting factor for synthetic oblique, Since: 11.0.0 * * Current drawing state. * - * The @slant_xy is a slanting factor for synthetic oblique. If the font's - * oblique angle is not 0, this factor is used to slant the drawing. For - * fonts with uniform x and y scales, this factor is calculated as - * tan(oblique_angle). For fonts with non-uniform scales, this factor is - * calculated as tan(oblique_angle) * x_scale / y_scale, or 0 if y_scale is 0. - * * Since: 4.0.0 **/ typedef struct hb_draw_state_t { @@ -62,8 +55,6 @@ typedef struct hb_draw_state_t { float current_x; float current_y; - float slant_xy; - /*< private >*/ hb_var_num_t reserved1; hb_var_num_t reserved2; @@ -71,6 +62,7 @@ typedef struct hb_draw_state_t { hb_var_num_t reserved4; hb_var_num_t reserved5; hb_var_num_t reserved6; + hb_var_num_t reserved7; } hb_draw_state_t; /** @@ -78,7 +70,7 @@ typedef struct hb_draw_state_t { * * The default #hb_draw_state_t at the start of glyph drawing. */ -#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}} +#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0}, {0}, {0}, {0}, {0}, {0}, {0}} /** diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.hh b/src/3rdparty/harfbuzz-ng/src/hb-draw.hh index 15978cdf0a3..201f2202e85 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-draw.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-draw.hh @@ -100,9 +100,6 @@ struct hb_draw_funcs_t { if (unlikely (st.path_open)) close_path (draw_data, st); - if (st.slant_xy) - to_x += to_y * st.slant_xy; - st.current_x = to_x; st.current_y = to_y; } @@ -114,9 +111,6 @@ struct hb_draw_funcs_t { if (unlikely (!st.path_open)) start_path (draw_data, st); - if (st.slant_xy) - to_x += to_y * st.slant_xy; - emit_line_to (draw_data, st, to_x, to_y); st.current_x = to_x; @@ -131,12 +125,6 @@ struct hb_draw_funcs_t { if (unlikely (!st.path_open)) start_path (draw_data, st); - if (st.slant_xy) - { - control_x += control_y * st.slant_xy; - to_x += to_y * st.slant_xy; - } - emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y); st.current_x = to_x; @@ -152,13 +140,6 @@ struct hb_draw_funcs_t { if (unlikely (!st.path_open)) start_path (draw_data, st); - if (st.slant_xy) - { - control1_x += control1_y * st.slant_xy; - control2_x += control2_y * st.slant_xy; - to_x += to_y * st.slant_xy; - } - emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); st.current_x = to_x; @@ -194,9 +175,9 @@ DECLARE_NULL_INSTANCE (hb_draw_funcs_t); struct hb_draw_session_t { - hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_xy = 0.f) + hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_) : funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT - { st.slant_xy = slant_xy; } + {} ~hb_draw_session_t () { close_path (); } @@ -244,4 +225,9 @@ struct hb_draw_session_t hb_draw_state_t st; }; + +HB_INTERNAL hb_draw_funcs_t * +hb_draw_extents_get_funcs (); + + #endif /* HB_DRAW_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc index 4e2adbb788b..3a2b645b66e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc @@ -103,7 +103,7 @@ hb_font_get_font_h_extents_default (hb_font_t *font, hb_font_extents_t *extents, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_font_h_extents (extents); + hb_bool_t ret = font->parent->get_font_h_extents (extents, false); if (ret) { extents->ascender = font->parent_scale_y_distance (extents->ascender); extents->descender = font->parent_scale_y_distance (extents->descender); @@ -128,7 +128,7 @@ hb_font_get_font_v_extents_default (hb_font_t *font, hb_font_extents_t *extents, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_font_v_extents (extents); + hb_bool_t ret = font->parent->get_font_v_extents (extents, false); if (ret) { extents->ascender = font->parent_scale_x_distance (extents->ascender); extents->descender = font->parent_scale_x_distance (extents->descender); @@ -234,10 +234,10 @@ hb_font_get_glyph_h_advance_default (hb_font_t *font, if (font->has_glyph_h_advances_func_set ()) { hb_position_t ret; - font->get_glyph_h_advances (1, &glyph, 0, &ret, 0); + font->get_glyph_h_advances (1, &glyph, 0, &ret, 0, false); return ret; } - return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); + return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph, false)); } static hb_position_t @@ -259,10 +259,10 @@ hb_font_get_glyph_v_advance_default (hb_font_t *font, if (font->has_glyph_v_advances_func_set ()) { hb_position_t ret; - font->get_glyph_v_advances (1, &glyph, 0, &ret, 0); + font->get_glyph_v_advances (1, &glyph, 0, &ret, 0, false); return ret; } - return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); + return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph, false)); } #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default @@ -281,7 +281,7 @@ hb_font_get_glyph_h_advances_default (hb_font_t* font, { for (unsigned int i = 0; i < count; i++) { - *first_advance = font->get_glyph_h_advance (*first_glyph); + *first_advance = font->get_glyph_h_advance (*first_glyph, false); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } @@ -290,7 +290,8 @@ hb_font_get_glyph_h_advances_default (hb_font_t* font, font->parent->get_glyph_h_advances (count, first_glyph, glyph_stride, - first_advance, advance_stride); + first_advance, advance_stride, + false); for (unsigned int i = 0; i < count; i++) { *first_advance = font->parent_scale_x_distance (*first_advance); @@ -313,7 +314,7 @@ hb_font_get_glyph_v_advances_default (hb_font_t* font, { for (unsigned int i = 0; i < count; i++) { - *first_advance = font->get_glyph_v_advance (*first_glyph); + *first_advance = font->get_glyph_v_advance (*first_glyph, false); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } @@ -322,7 +323,8 @@ hb_font_get_glyph_v_advances_default (hb_font_t* font, font->parent->get_glyph_v_advances (count, first_glyph, glyph_stride, - first_advance, advance_stride); + first_advance, advance_stride, + false); for (unsigned int i = 0; i < count; i++) { *first_advance = font->parent_scale_y_distance (*first_advance); @@ -442,7 +444,7 @@ hb_font_get_glyph_extents_default (hb_font_t *font, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); + hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents, false); if (ret) { font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); font->parent_scale_distance (&extents->width, &extents->height); @@ -472,7 +474,7 @@ hb_font_get_glyph_contour_point_default (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); + hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y, false); if (ret) font->parent_scale_position (x, y); return ret; @@ -524,26 +526,28 @@ hb_font_get_glyph_from_name_default (hb_font_t *font, return font->parent->get_glyph_from_name (name, len, glyph); } -static void -hb_font_draw_glyph_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, - void *draw_data, - void *user_data HB_UNUSED) +static hb_bool_t +hb_font_draw_glyph_or_fail_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, + void *draw_data, + void *user_data HB_UNUSED) { + return false; } -static void -hb_font_paint_glyph_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - hb_paint_funcs_t *paint_funcs HB_UNUSED, - void *paint_data HB_UNUSED, - unsigned int palette HB_UNUSED, - hb_color_t foreground HB_UNUSED, - void *user_data HB_UNUSED) +static hb_bool_t +hb_font_paint_glyph_or_fail_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_paint_funcs_t *paint_funcs HB_UNUSED, + void *paint_data HB_UNUSED, + unsigned int palette HB_UNUSED, + hb_color_t foreground HB_UNUSED, + void *user_data HB_UNUSED) { + return false; } typedef struct hb_font_draw_glyph_default_adaptor_t { @@ -551,7 +555,6 @@ typedef struct hb_font_draw_glyph_default_adaptor_t { void *draw_data; float x_scale; float y_scale; - float slant; } hb_font_draw_glyph_default_adaptor_t; static void @@ -564,10 +567,9 @@ hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; - float slant = adaptor->slant; adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st, - x_scale * to_x + slant * to_y, y_scale * to_y); + x_scale * to_x, y_scale * to_y); } static void @@ -579,13 +581,12 @@ hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; - float slant = adaptor->slant; - st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_x = st->current_x * x_scale; st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st, - x_scale * to_x + slant * to_y, y_scale * to_y); + x_scale * to_x, y_scale * to_y); } static void @@ -598,14 +599,13 @@ hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; - float slant = adaptor->slant; - st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_x = st->current_x * x_scale; st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st, - x_scale * control_x + slant * control_y, y_scale * control_y, - x_scale * to_x + slant * to_y, y_scale * to_y); + x_scale * control_x, y_scale * control_y, + x_scale * to_x, y_scale * to_y); } static void @@ -619,15 +619,14 @@ hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; - float slant = adaptor->slant; - st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_x = st->current_x * x_scale; st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st, - x_scale * control1_x + slant * control1_y, y_scale * control1_y, - x_scale * control2_x + slant * control2_y, y_scale * control2_y, - x_scale * to_x + slant * to_y, y_scale * to_y); + x_scale * control1_x, y_scale * control1_y, + x_scale * control2_x, y_scale * control2_y, + x_scale * to_x, y_scale * to_y); } static void @@ -650,49 +649,47 @@ static const hb_draw_funcs_t _hb_draw_funcs_default = { } }; -static void -hb_font_draw_glyph_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, - void *draw_data, - void *user_data HB_UNUSED) +static hb_bool_t +hb_font_draw_glyph_or_fail_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, + void *draw_data, + void *user_data HB_UNUSED) { hb_font_draw_glyph_default_adaptor_t adaptor = { draw_funcs, draw_data, font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, - font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, - font->parent->y_scale ? (font->slant - font->parent->slant) * - (float) font->x_scale / (float) font->parent->y_scale : 0.f + font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f }; - font->parent->draw_glyph (glyph, - const_cast (&_hb_draw_funcs_default), - &adaptor); + return font->parent->draw_glyph_or_fail (glyph, + const_cast (&_hb_draw_funcs_default), + &adaptor, + false); } -static void -hb_font_paint_glyph_default (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, - void *paint_data, - unsigned int palette, - hb_color_t foreground, - void *user_data) +static hb_bool_t +hb_font_paint_glyph_or_fail_default (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, + void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) { paint_funcs->push_transform (paint_data, - font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, - font->parent->y_scale ? (font->slant - font->parent->slant) * - (float) font->x_scale / (float) font->parent->y_scale : 0.f, - 0.f, - font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, - 0.f, 0.f); + font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0, 0, + 0, font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0, + 0, 0); - font->parent->paint_glyph (glyph, paint_funcs, paint_data, palette, foreground); + bool ret = font->parent->paint_glyph_or_fail (glyph, paint_funcs, paint_data, palette, foreground); paint_funcs->pop_transform (paint_data); + + return ret; } DEFINE_NULL_INSTANCE (hb_font_funcs_t) = @@ -1429,6 +1426,92 @@ hb_font_get_glyph_shape (hb_font_t *font, } #endif +/** + * hb_font_draw_glyph_or_fail: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID + * @dfuncs: #hb_draw_funcs_t to draw to + * @draw_data: User data to pass to draw callbacks + * + * Draws the outline that corresponds to a glyph in the specified @font. + * + * This is a newer name for hb_font_draw_glyph(), that returns `false` + * if the font has no outlines for the glyph. + * + * The outline is returned by way of calls to the callbacks of the @dfuncs + * objects, with @draw_data passed to them. + * + * Return value: `true` if glyph was drawn, `false` otherwise + * + * XSince: REPLACEME + **/ +hb_bool_t +hb_font_draw_glyph_or_fail (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + return font->draw_glyph_or_fail (glyph, dfuncs, draw_data); +} + +/** + * hb_font_paint_glyph_or_fail: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID + * @pfuncs: #hb_paint_funcs_t to paint with + * @paint_data: User data to pass to paint callbacks + * @palette_index: The index of the font's color palette to use + * @foreground: The foreground color, unpremultipled + * + * Paints a color glyph. + * + * This function is similar to, but lower-level than, + * hb_font_paint_glyph(). It is suitable for clients that + * need more control. If there are no color glyphs available, + * it will return `false`. The client can then fall back to + * hb_font_draw_glyph_or_fail() for the monochrome outline glyph. + * + * The painting instructions are returned by way of calls to + * the callbacks of the @funcs object, with @paint_data passed + * to them. + * + * If the font has color palettes (see hb_ot_color_has_palettes()), + * then @palette_index selects the palette to use. If the font only + * has one palette, this will be 0. + * + * Return value: `true` if glyph was painted, `false` otherwise + * + * XSince: REPLACEME + */ +hb_bool_t +hb_font_paint_glyph_or_fail (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground) +{ + return font->paint_glyph_or_fail (glyph, pfuncs, paint_data, palette_index, foreground); +} + +/* A bit higher-level, and with fallback */ + +void +hb_font_t::paint_glyph (hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground) +{ + if (paint_glyph_or_fail (glyph, + paint_funcs, paint_data, + palette, foreground)) + return; + + /* Fallback for outline glyph. */ + paint_funcs->push_clip_glyph (paint_data, glyph, this); + paint_funcs->color (paint_data, true, foreground); + paint_funcs->pop_clip (paint_data); +} + + /** * hb_font_draw_glyph: * @font: #hb_font_t to work upon @@ -1438,6 +1521,9 @@ hb_font_get_glyph_shape (hb_font_t *font, * * Draws the outline that corresponds to a glyph in the specified @font. * + * This is an older name for hb_font_draw_glyph_or_fail(), with no + * return value. + * * The outline is returned by way of calls to the callbacks of the @dfuncs * objects, with @draw_data passed to them. * @@ -1445,10 +1531,10 @@ hb_font_get_glyph_shape (hb_font_t *font, **/ void hb_font_draw_glyph (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_funcs_t *dfuncs, void *draw_data) + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data) { - font->draw_glyph (glyph, dfuncs, draw_data); + (void) hb_font_draw_glyph_or_fail (font, glyph, dfuncs, draw_data); } /** @@ -1460,7 +1546,10 @@ hb_font_draw_glyph (hb_font_t *font, * @palette_index: The index of the font's color palette to use * @foreground: The foreground color, unpremultipled * - * Paints the glyph. + * Paints the glyph. This function is similar to + * hb_font_paint_glyph_or_fail(), but if painting a color glyph + * failed, it will fall back to painting an outline monochrome + * glyph. * * The painting instructions are returned by way of calls to * the callbacks of the @funcs object, with @paint_data passed @@ -1482,8 +1571,6 @@ hb_font_paint_glyph (hb_font_t *font, font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground); } -/* A bit higher-level, and with fallback */ - /** * hb_font_get_extents_for_direction: * @font: #hb_font_t to work upon @@ -2608,6 +2695,23 @@ hb_font_get_ptem (hb_font_t *font) return font->ptem; } +/** + * hb_font_is_synthetic: + * @font: #hb_font_t to work upon + * + * Tests whether a font is synthetic. A synthetic font is one + * that has either synthetic slant or synthetic bold set on it. + * + * Return value: `true` if the font is synthetic, `false` otherwise. + * + * XSince: REPLACEME + */ +hb_bool_t +hb_font_is_synthetic (hb_font_t *font) +{ + return font->is_synthetic (); +} + /** * hb_font_set_synthetic_bold: * @font: #hb_font_t to work upon @@ -2625,7 +2729,7 @@ hb_font_get_ptem (hb_font_t *font) * points of the glyph shape. * * Synthetic boldness is applied when rendering a glyph via - * hb_font_draw_glyph(). + * hb_font_draw_glyph_or_fail(). * * If @in_place is `false`, then glyph advance-widths are also * adjusted, otherwise they are not. The in-place mode is @@ -2689,7 +2793,7 @@ hb_font_get_synthetic_bold (hb_font_t *font, * HarfBuzz needs to know this value to adjust shaping results, * metrics, and style values to match the slanted rendering. * - * Note: The glyph shape fetched via the hb_font_draw_glyph() + * Note: The glyph shape fetched via the hb_font_draw_glyph_or_fail() * function is slanted to reflect this value as well. * * Note: The slant value is a ratio. For example, a @@ -3195,12 +3299,134 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, #ifndef HB_DISABLE_DEPRECATED + +struct hb_draw_glyph_closure_t +{ + hb_font_draw_glyph_func_t func; + void *user_data; + hb_destroy_func_t destroy; +}; +static hb_bool_t +hb_font_draw_glyph_trampoline (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, + void *draw_data, + void *user_data) +{ + hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) user_data; + closure->func (font, font_data, glyph, draw_funcs, draw_data, closure->user_data); + return true; +} +static void +hb_font_draw_glyph_closure_destroy (void *user_data) +{ + hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) user_data; + + if (closure->destroy) + closure->destroy (closure->user_data); + hb_free (closure); +} +static void +_hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy /* May be NULL. */) +{ + if (hb_object_is_immutable (ffuncs)) + { + if (destroy) + destroy (user_data); + return; + } + hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) hb_calloc (1, sizeof (hb_draw_glyph_closure_t)); + if (unlikely (!closure)) + { + if (destroy) + destroy (user_data); + return; + } + closure->func = func; + closure->user_data = user_data; + closure->destroy = destroy; + + hb_font_funcs_set_draw_glyph_or_fail_func (ffuncs, + hb_font_draw_glyph_trampoline, + closure, + hb_font_draw_glyph_closure_destroy); +} +void +hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy /* May be NULL. */) +{ + _hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); +} void hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_shape_func_t func, void *user_data, hb_destroy_func_t destroy /* May be NULL. */) { - hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); + _hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); +} + +struct hb_paint_glyph_closure_t +{ + hb_font_paint_glyph_func_t func; + void *user_data; + hb_destroy_func_t destroy; +}; +static hb_bool_t +hb_font_paint_glyph_trampoline (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, + void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) +{ + hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) user_data; + closure->func (font, font_data, glyph, paint_funcs, paint_data, palette, foreground, closure->user_data); + return true; +} +static void +hb_font_paint_glyph_closure_destroy (void *user_data) +{ + hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) user_data; + + if (closure->destroy) + closure->destroy (closure->user_data); + hb_free (closure); +} +void +hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_paint_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy /* May be NULL. */) +{ + if (hb_object_is_immutable (ffuncs)) + { + if (destroy) + destroy (user_data); + return; + } + hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) hb_calloc (1, sizeof (hb_paint_glyph_closure_t)); + if (unlikely (!closure)) + { + if (destroy) + destroy (user_data); + return; + } + closure->func = func; + closure->user_data = user_data; + closure->destroy = destroy; + + hb_font_funcs_set_paint_glyph_or_fail_func (ffuncs, + hb_font_paint_glyph_trampoline, + closure, + hb_font_paint_glyph_closure_destroy); } #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h index 478c808e128..77178bf8472 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h @@ -486,7 +486,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * void *user_data); /** - * hb_font_draw_glyph_func_t: + * hb_font_draw_glyph_or_fail_func_t: * @font: #hb_font_t to work upon * @font_data: @font user data pointer * @glyph: The glyph ID to query @@ -496,16 +496,17 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * Since: 7.0.0 + * Return value: `true` if glyph was drawn, `false` otherwise * + * XSince: REPLACEME **/ -typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data); +typedef hb_bool_t (*hb_font_draw_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data); /** - * hb_font_paint_glyph_func_t: + * hb_font_paint_glyph_or_fail_func_t: * @font: #hb_font_t to work upon * @font_data: @font user data pointer * @glyph: The glyph ID to query @@ -517,14 +518,16 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * Since: 7.0.0 + * Return value: `true` if glyph was painted, `false` otherwise + * + * XSince: REPLACEME */ -typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette_index, - hb_color_t foreground, - void *user_data); +typedef hb_bool_t (*hb_font_paint_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data); /* func setters */ @@ -785,36 +788,36 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, void *user_data, hb_destroy_func_t destroy); /** - * hb_font_funcs_set_draw_glyph_func: + * hb_font_funcs_set_draw_glyph_or_fail_func: * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * Sets the implementation function for #hb_font_draw_glyph_func_t. + * Sets the implementation function for #hb_font_draw_glyph_or_fail_func_t. * - * Since: 7.0.0 + * XSince: REPLACEME **/ HB_EXTERN void -hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, - hb_font_draw_glyph_func_t func, - void *user_data, hb_destroy_func_t destroy); +hb_font_funcs_set_draw_glyph_or_fail_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_or_fail_func_t func, + void *user_data, hb_destroy_func_t destroy); /** - * hb_font_funcs_set_paint_glyph_func: + * hb_font_funcs_set_paint_glyph_or_fail_func: * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func * @destroy: (nullable): The function to call when @user_data is no longer needed * - * Sets the implementation function for #hb_font_paint_glyph_func_t. + * Sets the implementation function for #hb_font_paint_glyph_or_fail_func_t. * - * Since: 7.0.0 + * XSince: REPLACEME */ HB_EXTERN void -hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, - hb_font_paint_glyph_func_t func, - void *user_data, hb_destroy_func_t destroy); +hb_font_funcs_set_paint_glyph_or_fail_func (hb_font_funcs_t *ffuncs, + hb_font_paint_glyph_or_fail_func_t func, + void *user_data, hb_destroy_func_t destroy); /* func dispatch */ @@ -896,17 +899,17 @@ hb_font_get_glyph_from_name (hb_font_t *font, const char *name, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph); -HB_EXTERN void -hb_font_draw_glyph (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_funcs_t *dfuncs, void *draw_data); +HB_EXTERN hb_bool_t +hb_font_draw_glyph_or_fail (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data); -HB_EXTERN void -hb_font_paint_glyph (hb_font_t *font, - hb_codepoint_t glyph, - hb_paint_funcs_t *pfuncs, void *paint_data, - unsigned int palette_index, - hb_color_t foreground); +HB_EXTERN hb_bool_t +hb_font_paint_glyph_or_fail (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground); /* high-level funcs, with fallback */ @@ -979,6 +982,19 @@ hb_font_glyph_from_string (hb_font_t *font, const char *s, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph); +/* Older alias for hb_font_draw_glyph_or_fail() with no return value. */ +HB_EXTERN void +hb_font_draw_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data); + +/* Paints color glyph; if failed, draws outline glyph. */ +HB_EXTERN void +hb_font_paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground); /* * hb_font_t @@ -1092,6 +1108,9 @@ hb_font_set_ptem (hb_font_t *font, float ptem); HB_EXTERN float hb_font_get_ptem (hb_font_t *font); +HB_EXTERN hb_bool_t +hb_font_is_synthetic (hb_font_t *font); + HB_EXTERN void hb_font_set_synthetic_bold (hb_font_t *font, float x_embolden, float y_embolden, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.hh b/src/3rdparty/harfbuzz-ng/src/hb-font.hh index 5e23bd04050..b64b19bc9fc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.hh @@ -33,6 +33,8 @@ #include "hb-face.hh" #include "hb-atomic.hh" +#include "hb-draw.hh" +#include "hb-paint-extents.hh" #include "hb-shaper.hh" #include "hb-outline.hh" @@ -59,8 +61,8 @@ HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \ - HB_FONT_FUNC_IMPLEMENT (,draw_glyph) \ - HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \ + HB_FONT_FUNC_IMPLEMENT (,draw_glyph_or_fail) \ + HB_FONT_FUNC_IMPLEMENT (,paint_glyph_or_fail) \ /* ^--- Add new callbacks here */ struct hb_font_funcs_t @@ -206,7 +208,7 @@ struct hb_font_t void synthetic_glyph_extents (hb_glyph_extents_t *extents) { - /* Apply slant. */ + /* Slant. */ if (slant_xy) { hb_position_t x1 = extents->x_bearing; @@ -221,6 +223,7 @@ struct hb_font_t extents->width = x2 - extents->x_bearing; } + /* Embolden. */ if (x_strength || y_strength) { /* Y */ @@ -263,19 +266,45 @@ struct hb_font_t HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT - hb_bool_t get_font_h_extents (hb_font_extents_t *extents) + hb_bool_t get_font_h_extents (hb_font_extents_t *extents, + bool synthetic = true) { hb_memset (extents, 0, sizeof (*extents)); - return klass->get.f.font_h_extents (this, user_data, - extents, - !klass->user_data ? nullptr : klass->user_data->font_h_extents); + bool ret = klass->get.f.font_h_extents (this, user_data, + extents, + !klass->user_data ? nullptr : klass->user_data->font_h_extents); + + if (synthetic && ret) + { + /* Embolden */ + int y_shift = y_scale < 0 ? -y_strength : y_strength; + extents->ascender += y_shift; + } + + return ret; } - hb_bool_t get_font_v_extents (hb_font_extents_t *extents) + hb_bool_t get_font_v_extents (hb_font_extents_t *extents, + bool synthetic = true) { hb_memset (extents, 0, sizeof (*extents)); - return klass->get.f.font_v_extents (this, user_data, - extents, - !klass->user_data ? nullptr : klass->user_data->font_v_extents); + bool ret = klass->get.f.font_v_extents (this, user_data, + extents, + !klass->user_data ? nullptr : klass->user_data->font_v_extents); + + if (synthetic && ret) + { + /* Embolden */ + int x_shift = x_scale < 0 ? -x_strength : x_strength; + if (embolden_in_place) + { + extents->ascender += x_shift / 2; + extents->descender -= x_shift - x_shift / 2; + } + else + extents->ascender += x_shift; + } + + return ret; } bool has_glyph (hb_codepoint_t unicode) @@ -316,15 +345,16 @@ struct hb_font_t !klass->user_data ? nullptr : klass->user_data->variation_glyph); } - hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) + hb_position_t get_glyph_h_advance (hb_codepoint_t glyph, + bool synthetic = true) { hb_position_t advance = klass->get.f.glyph_h_advance (this, user_data, glyph, !klass->user_data ? nullptr : klass->user_data->glyph_h_advance); - if (x_strength && !embolden_in_place) + if (synthetic && x_strength && !embolden_in_place) { - /* Emboldening. */ + /* Embolden */ hb_position_t strength = x_scale >= 0 ? x_strength : -x_strength; advance += advance ? strength : 0; } @@ -332,15 +362,16 @@ struct hb_font_t return advance; } - hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) + hb_position_t get_glyph_v_advance (hb_codepoint_t glyph, + bool synthetic = true) { hb_position_t advance = klass->get.f.glyph_v_advance (this, user_data, glyph, !klass->user_data ? nullptr : klass->user_data->glyph_v_advance); - if (y_strength && !embolden_in_place) + if (synthetic && y_strength && !embolden_in_place) { - /* Emboldening. */ + /* Embolden */ hb_position_t strength = y_scale >= 0 ? y_strength : -y_strength; advance += advance ? strength : 0; } @@ -352,7 +383,8 @@ struct hb_font_t const hb_codepoint_t *first_glyph, unsigned int glyph_stride, hb_position_t *first_advance, - unsigned int advance_stride) + unsigned int advance_stride, + bool synthetic = true) { klass->get.f.glyph_h_advances (this, user_data, count, @@ -360,9 +392,9 @@ struct hb_font_t first_advance, advance_stride, !klass->user_data ? nullptr : klass->user_data->glyph_h_advances); - if (x_strength && !embolden_in_place) + if (synthetic && x_strength && !embolden_in_place) { - /* Emboldening. */ + /* Embolden */ hb_position_t strength = x_scale >= 0 ? x_strength : -x_strength; for (unsigned int i = 0; i < count; i++) { @@ -376,7 +408,8 @@ struct hb_font_t const hb_codepoint_t *first_glyph, unsigned int glyph_stride, hb_position_t *first_advance, - unsigned int advance_stride) + unsigned int advance_stride, + bool synthetic = true) { klass->get.f.glyph_v_advances (this, user_data, count, @@ -384,9 +417,9 @@ struct hb_font_t first_advance, advance_stride, !klass->user_data ? nullptr : klass->user_data->glyph_v_advances); - if (y_strength && !embolden_in_place) + if (synthetic && y_strength && !embolden_in_place) { - /* Emboldening. */ + /* Embolden */ hb_position_t strength = y_scale >= 0 ? y_strength : -y_strength; for (unsigned int i = 0; i < count; i++) { @@ -439,9 +472,51 @@ struct hb_font_t } hb_bool_t get_glyph_extents (hb_codepoint_t glyph, - hb_glyph_extents_t *extents) + hb_glyph_extents_t *extents, + bool synthetic = true) { hb_memset (extents, 0, sizeof (*extents)); + + /* This is rather messy, but necessary. */ + + if (!synthetic) + { + return klass->get.f.glyph_extents (this, user_data, + glyph, + extents, + !klass->user_data ? nullptr : klass->user_data->glyph_extents); + } + if (!is_synthetic () && + klass->get.f.glyph_extents (this, user_data, + glyph, + extents, + !klass->user_data ? nullptr : klass->user_data->glyph_extents)) + return true; + + /* Try getting extents from paint(), then draw(), *then* get_extents() + * and apply synthetic settings in the last case. */ + +#ifndef HB_NO_PAINT + hb_paint_extents_context_t paint_extents; + if (paint_glyph_or_fail (glyph, + hb_paint_extents_get_funcs (), &paint_extents, + 0, 0)) + { + *extents = paint_extents.get_extents ().to_glyph_extents (); + return true; + } +#endif + +#ifndef HB_NO_DRAW + hb_extents_t draw_extents; + if (draw_glyph_or_fail (glyph, + hb_draw_extents_get_funcs (), &draw_extents)) + { + *extents = draw_extents.to_glyph_extents (); + return true; + } +#endif + bool ret = klass->get.f.glyph_extents (this, user_data, glyph, extents, @@ -453,13 +528,30 @@ struct hb_font_t } hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, - hb_position_t *x, hb_position_t *y) + hb_position_t *x, hb_position_t *y, + bool synthetic = true) { *x = *y = 0; - return klass->get.f.glyph_contour_point (this, user_data, - glyph, point_index, - x, y, - !klass->user_data ? nullptr : klass->user_data->glyph_contour_point); + bool ret = klass->get.f.glyph_contour_point (this, user_data, + glyph, point_index, + x, y, + !klass->user_data ? nullptr : klass->user_data->glyph_contour_point); + + if (synthetic && ret) + { + /* Slant */ + if (slant_xy) + *x += roundf (*y * slant_xy); + + /* Embolden */ + if (!embolden_in_place) + { + int x_shift = x_scale < 0 ? -x_strength : x_strength; + *x += x_shift; + } + } + + return ret; } hb_bool_t get_glyph_name (hb_codepoint_t glyph, @@ -483,56 +575,94 @@ struct hb_font_t !klass->user_data ? nullptr : klass->user_data->glyph_from_name); } - void draw_glyph (hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data) + bool draw_glyph_or_fail (hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + bool synthetic = true) { +#ifndef HB_NO_DRAW #ifndef HB_NO_OUTLINE bool embolden = x_strength || y_strength; + bool slanted = slant_xy; + synthetic = synthetic && (embolden || slanted); #else - constexpr bool embolden = false; + synthetic = false; #endif - if (!embolden) + if (!synthetic) { - klass->get.f.draw_glyph (this, user_data, - glyph, - draw_funcs, draw_data, - !klass->user_data ? nullptr : klass->user_data->draw_glyph); - return; + return klass->get.f.draw_glyph_or_fail (this, user_data, + glyph, + draw_funcs, draw_data, + !klass->user_data ? nullptr : klass->user_data->draw_glyph_or_fail); } #ifndef HB_NO_OUTLINE - /* Emboldening. */ - hb_outline_t outline; - klass->get.f.draw_glyph (this, user_data, - glyph, - hb_outline_recording_pen_get_funcs (), &outline, - !klass->user_data ? nullptr : klass->user_data->draw_glyph); - float x_shift = embolden_in_place ? 0 : (float) x_strength / 2; - float y_shift = (float) y_strength / 2; - if (x_scale < 0) x_shift = -x_shift; - if (y_scale < 0) y_shift = -y_shift; - outline.embolden (x_strength, y_strength, x_shift, y_shift); + hb_outline_t outline; + if (!klass->get.f.draw_glyph_or_fail (this, user_data, + glyph, + hb_outline_recording_pen_get_funcs (), &outline, + !klass->user_data ? nullptr : klass->user_data->draw_glyph_or_fail)) + return false; + + // Slant before embolden; produces nicer results. + + if (slanted) + outline.slant (slant_xy); + + if (embolden) + { + float x_shift = embolden_in_place ? 0 : (float) x_strength / 2; + float y_shift = (float) y_strength / 2; + if (x_scale < 0) x_shift = -x_shift; + if (y_scale < 0) y_shift = -y_shift; + outline.embolden (x_strength, y_strength, x_shift, y_shift); + } outline.replay (draw_funcs, draw_data); + + return true; #endif +#endif + return false; } - void paint_glyph (hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette, - hb_color_t foreground) + bool paint_glyph_or_fail (hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, + bool synthetic = true) { - klass->get.f.paint_glyph (this, user_data, - glyph, - paint_funcs, paint_data, - palette, foreground, - !klass->user_data ? nullptr : klass->user_data->paint_glyph); +#ifndef HB_NO_PAINT + /* Slant */ + if (synthetic && slant_xy) + hb_paint_push_transform (paint_funcs, paint_data, + 1.f, 0.f, + slant_xy, 1.f, + 0.f, 0.f); + + bool ret = klass->get.f.paint_glyph_or_fail (this, user_data, + glyph, + paint_funcs, paint_data, + palette, foreground, + !klass->user_data ? nullptr : klass->user_data->paint_glyph_or_fail); + + if (synthetic && slant_xy) + hb_paint_pop_transform (paint_funcs, paint_data); + + return ret; +#endif + return false; } /* A bit higher-level, and with fallback */ + HB_INTERNAL + void paint_glyph (hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground); + void get_h_extents_with_fallback (hb_font_extents_t *extents) { if (!get_font_h_extents (extents)) @@ -770,6 +900,11 @@ struct hb_font_t return false; } + bool is_synthetic () const + { + return x_embolden || y_embolden || slant; + } + void changed () { float upem = face->get_upem (); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft-colr.hh b/src/3rdparty/harfbuzz-ng/src/hb-ft-colr.hh index b41d5555374..cb9e4985442 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ft-colr.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ft-colr.hh @@ -28,7 +28,7 @@ #include "hb.hh" #include "hb-decycler.hh" -#include "hb-paint-extents.hh" +#include "hb-paint-bounded.hh" #include FT_COLOR_H @@ -80,15 +80,30 @@ _hb_ft_paint (hb_ft_paint_context_t *c, struct hb_ft_paint_context_t { - hb_ft_paint_context_t (const hb_ft_font_t *ft_font, - hb_font_t *font, + hb_ft_paint_context_t (const hb_ft_font_t *ft_font_, + hb_font_t *font_, hb_paint_funcs_t *paint_funcs, void *paint_data, hb_array_t palette, unsigned palette_index, hb_color_t foreground) : - ft_font (ft_font), font(font), + ft_font (ft_font_), font (font_), funcs (paint_funcs), data (paint_data), - palette (palette), palette_index (palette_index), foreground (foreground) {} + palette (palette), palette_index (palette_index), foreground (foreground) + { + if (font->is_synthetic ()) + { + font = hb_font_create_sub_font (font); + hb_font_set_synthetic_bold (font, 0, 0, true); + hb_font_set_synthetic_slant (font, 0); + } + else + hb_font_reference (font); + } + + ~hb_ft_paint_context_t () + { + hb_font_destroy (font); + } void recurse (FT_OpaquePaint paint) { @@ -512,52 +527,41 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_decycler_node_t node (c.glyphs_decycler); node.visit (gid); - bool is_bounded = true; + bool clip = false; + bool is_bounded = false; FT_ClipBox clip_box; if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box)) { c.funcs->push_clip_rectangle (c.data, - clip_box.bottom_left.x + - roundf (hb_min (font->slant_xy * clip_box.bottom_left.y, - font->slant_xy * clip_box.top_left.y)), + clip_box.bottom_left.x, clip_box.bottom_left.y, - clip_box.top_right.x + - roundf (hb_max (font->slant_xy * clip_box.bottom_right.y, - font->slant_xy * clip_box.top_right.y)), + clip_box.top_right.x, clip_box.top_right.y); + clip = true; + is_bounded = true; } - else + if (!is_bounded) { - - auto *extents_funcs = hb_paint_extents_get_funcs (); - hb_paint_extents_context_t extents_data; + auto *bounded_funcs = hb_paint_bounded_get_funcs (); + hb_paint_bounded_context_t bounded_data; hb_ft_paint_context_t ce (ft_font, font, - extents_funcs, &extents_data, + bounded_funcs, &bounded_data, palette_array, palette_index, foreground); hb_decycler_node_t node2 (ce.glyphs_decycler); node2.visit (gid); - ce.funcs->push_font_transform (ce.data, font); ce.recurse (paint); - ce.funcs->pop_transform (ce.data); - hb_extents_t extents = extents_data.get_extents (); - is_bounded = extents_data.is_bounded (); - - c.funcs->push_clip_rectangle (c.data, - extents.xmin, - extents.ymin, - extents.xmax, - extents.ymax); + is_bounded = bounded_data.is_bounded (); } c.funcs->push_font_transform (c.data, font); if (is_bounded) - { c.recurse (paint); - } c.funcs->pop_transform (c.data); - c.funcs->pop_clip (c.data); + + if (clip) + c.funcs->pop_clip (c.data); return true; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc index 0c0e6938665..9287118594d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc @@ -626,6 +626,41 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font, } #endif +static bool +hb_ft_is_colr_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t gid) +{ +#ifndef HB_NO_PAINT +#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300 + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + FT_Face ft_face = ft_font->ft_face; + + + /* COLRv1 */ + FT_OpaquePaint paint = {0}; + if (FT_Get_Color_Glyph_Paint (ft_face, gid, + FT_COLOR_NO_ROOT_TRANSFORM, + &paint)) + return true; + + /* COLRv0 */ + FT_LayerIterator iterator; + FT_UInt layer_glyph_index; + FT_UInt layer_color_index; + iterator.p = NULL; + if (FT_Get_Color_Glyph_Layer (ft_face, + gid, + &layer_glyph_index, + &layer_color_index, + &iterator)) + return true; +#endif +#endif + + return false; +} + static hb_bool_t hb_ft_get_glyph_extents (hb_font_t *font, void *font_data, @@ -633,6 +668,10 @@ hb_ft_get_glyph_extents (hb_font_t *font, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { + // FreeType doesn't return COLR glyph extents. + if (hb_ft_is_colr_glyph (font, font_data, glyph)) + return false; + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; _hb_ft_hb_font_check_changed (font, ft_font); @@ -797,7 +836,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, metrics->line_gap = ft_face->size->metrics.height - (metrics->ascender - metrics->descender); } - metrics->ascender = (hb_position_t) (y_mult * (metrics->ascender + font->y_strength)); + metrics->ascender = (hb_position_t) (y_mult * metrics->ascender); metrics->descender = (hb_position_t) (y_mult * metrics->descender); metrics->line_gap = (hb_position_t) (y_mult * metrics->line_gap); @@ -848,12 +887,12 @@ _hb_ft_cubic_to (const FT_Vector *control1, return FT_Err_Ok; } -static void -hb_ft_draw_glyph (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data HB_UNUSED) +static hb_bool_t +hb_ft_draw_glyph_or_fail (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; _hb_ft_hb_font_check_changed (font, ft_font); @@ -863,10 +902,10 @@ hb_ft_draw_glyph (hb_font_t *font, if (unlikely (FT_Load_Glyph (ft_face, glyph, FT_LOAD_NO_BITMAP | ft_font->load_flags))) - return; + return false; if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) - return; + return false; const FT_Outline_Funcs outline_funcs = { _hb_ft_move_to, @@ -877,11 +916,13 @@ hb_ft_draw_glyph (hb_font_t *font, 0, /* delta */ }; - hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); + hb_draw_session_t draw_session {draw_funcs, draw_data}; FT_Outline_Decompose (&ft_face->glyph->outline, &outline_funcs, &draw_session); + + return true; } #endif @@ -890,14 +931,14 @@ hb_ft_draw_glyph (hb_font_t *font, #include "hb-ft-colr.hh" -static void -hb_ft_paint_glyph (hb_font_t *font, - void *font_data, - hb_codepoint_t gid, - hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette_index, - hb_color_t foreground, - void *user_data) +static hb_bool_t +hb_ft_paint_glyph_or_fail (hb_font_t *font, + void *font_data, + hb_codepoint_t gid, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; _hb_ft_hb_font_check_changed (font, ft_font); @@ -905,7 +946,7 @@ hb_ft_paint_glyph (hb_font_t *font, hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; - FT_Long load_flags = ft_font->load_flags | FT_LOAD_NO_BITMAP | FT_LOAD_COLOR; + FT_Long load_flags = ft_font->load_flags | FT_LOAD_COLOR; #if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21301 load_flags |= FT_LOAD_NO_SVG; #endif @@ -914,7 +955,7 @@ hb_ft_paint_glyph (hb_font_t *font, * eg. draw API can call back into the face.*/ if (unlikely (FT_Load_Glyph (ft_face, gid, load_flags))) - return; + return false; if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { @@ -922,26 +963,21 @@ hb_ft_paint_glyph (hb_font_t *font, paint_funcs, paint_data, palette_index, foreground, user_data)) - return; + return true; - /* Simple outline. */ - ft_font->lock.unlock (); - paint_funcs->push_clip_glyph (paint_data, gid, font); - ft_font->lock.lock (); - paint_funcs->color (paint_data, true, foreground); - paint_funcs->pop_clip (paint_data); - - return; + // Outline glyph + return false; } auto *glyph = ft_face->glyph; if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { + bool ret = false; auto &bitmap = glyph->bitmap; if (bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { if (bitmap.pitch != (signed) bitmap.width * 4) - return; + return ret; ft_font->lock.unlock (); @@ -951,27 +987,26 @@ hb_ft_paint_glyph (hb_font_t *font, nullptr, nullptr); hb_glyph_extents_t extents; - if (!hb_font_get_glyph_extents (font, gid, &extents)) + if (!font->get_glyph_extents (gid, &extents, false)) goto out; - if (!paint_funcs->image (paint_data, - blob, - bitmap.width, - bitmap.rows, - HB_PAINT_IMAGE_FORMAT_BGRA, - font->slant_xy, - &extents)) - { - /* TODO Try a forced outline load and paint? */ - } + if (paint_funcs->image (paint_data, + blob, + bitmap.width, + bitmap.rows, + HB_PAINT_IMAGE_FORMAT_BGRA, + 0.f, + &extents)) + ret = true; out: hb_blob_destroy (blob); ft_font->lock.lock (); } - return; + return ret; } + return false; } #endif #endif @@ -1006,12 +1041,12 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t= 21300 - hb_font_funcs_set_paint_glyph_func (funcs, hb_ft_paint_glyph, nullptr, nullptr); + hb_font_funcs_set_paint_glyph_or_fail_func (funcs, hb_ft_paint_glyph_or_fail, nullptr, nullptr); #endif #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-harfruzz.cc b/src/3rdparty/harfbuzz-ng/src/hb-harfruzz.cc new file mode 100644 index 00000000000..e6d5881db36 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-harfruzz.cc @@ -0,0 +1,150 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#ifdef HAVE_HARFRUZZ + +#include "hb-shaper-impl.hh" + + +/* + * shaper face data + */ + +extern "C" void * +_hb_harfruzz_shaper_face_data_create_rs (hb_face_t *face); + +hb_harfruzz_face_data_t * +_hb_harfruzz_shaper_face_data_create (hb_face_t *face) +{ + return (hb_harfruzz_face_data_t *) _hb_harfruzz_shaper_face_data_create_rs (face); +} + +extern "C" void +_hb_harfruzz_shaper_face_data_destroy_rs (void *data); + +void +_hb_harfruzz_shaper_face_data_destroy (hb_harfruzz_face_data_t *data) +{ + _hb_harfruzz_shaper_face_data_destroy_rs (data); +} + + +/* + * shaper font data + */ + +extern "C" void * +_hb_harfruzz_shaper_font_data_create_rs (hb_font_t *font, const void *face_data); + +hb_harfruzz_font_data_t * +_hb_harfruzz_shaper_font_data_create (hb_font_t *font) +{ + const hb_harfruzz_face_data_t *face_data = font->face->data.harfruzz; + return (hb_harfruzz_font_data_t *) _hb_harfruzz_shaper_font_data_create_rs (font, face_data); +} + +extern "C" void +_hb_harfruzz_shaper_font_data_destroy_rs (void *data); + +void +_hb_harfruzz_shaper_font_data_destroy (hb_harfruzz_font_data_t *data) +{ + _hb_harfruzz_shaper_font_data_destroy_rs (data); +} + +/* + * shape plan + */ + +extern "C" void * +_hb_harfruzz_shape_plan_create_rs (const void *font_data, + hb_script_t script, + hb_language_t language, + hb_direction_t direction); + +extern "C" void +_hb_harfruzz_shape_plan_destroy_rs (void *data); + + +/* + * shaper + */ + +extern "C" hb_bool_t +_hb_harfruzz_shape_rs (const void *face_data, + const void *rs_shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features); + +static hb_user_data_key_t hr_shape_plan_key = {0}; + +hb_bool_t +_hb_harfruzz_shape (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + const hb_harfruzz_font_data_t *font_data = font->data.harfruzz; + + void *hr_shape_plan = nullptr; + + if (!num_features) + { + retry: + hr_shape_plan = hb_shape_plan_get_user_data (shape_plan, + &hr_shape_plan_key); + if (unlikely (!hr_shape_plan)) + { + hr_shape_plan = _hb_harfruzz_shape_plan_create_rs (font_data, + shape_plan->key.props.script, + shape_plan->key.props.language, + shape_plan->key.props.direction); + if (hr_shape_plan && + !hb_shape_plan_set_user_data (shape_plan, + &hr_shape_plan_key, + hr_shape_plan, + _hb_harfruzz_shape_plan_destroy_rs, + false)) + { + _hb_harfruzz_shape_plan_destroy_rs (hr_shape_plan); + goto retry; + } + } + } + + return _hb_harfruzz_shape_rs (font_data, + hr_shape_plan, + font, + buffer, + features, + num_features); +} + + +#endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh index 6127c4d0ce5..4b76f91c7aa 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh @@ -273,7 +273,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t private: /* Must only have one pointer. */ - hb_atomic_t instance; + mutable hb_atomic_t instance; }; /* Specializations. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc index 17e56dbc481..2785f626a7c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc @@ -412,15 +412,15 @@ hb_ot_get_glyph_extents (hb_font_t *font, const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; -#ifndef HB_NO_VAR_COMPOSITES - if (ot_face->VARC->get_extents (font, glyph, extents)) return true; -#endif #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) if (ot_face->sbix->get_extents (font, glyph, extents)) return true; if (ot_face->CBDT->get_extents (font, glyph, extents)) return true; #endif #if !defined(HB_NO_COLOR) && !defined(HB_NO_PAINT) if (ot_face->COLR->get_extents (font, glyph, extents)) return true; +#endif +#ifndef HB_NO_VAR_COMPOSITES + if (ot_face->VARC->get_extents (font, glyph, extents)) return true; #endif if (ot_face->glyf->get_extents (font, glyph, extents)) return true; #ifndef HB_NO_OT_FONT_CFF @@ -472,16 +472,9 @@ hb_ot_get_font_h_extents (hb_font_t *font, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - bool ret = _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) && - _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) && - _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); - - /* Embolden */ - int y_shift = font->y_strength; - if (font->y_scale < 0) y_shift = -y_shift; - metrics->ascender += y_shift; - - return ret; + return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) && + _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) && + _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); } #ifndef HB_NO_VERTICAL @@ -498,50 +491,46 @@ hb_ot_get_font_v_extents (hb_font_t *font, #endif #ifndef HB_NO_DRAW -static void -hb_ot_draw_glyph (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data) +static hb_bool_t +hb_ot_draw_glyph_or_fail (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) { - hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); + hb_draw_session_t draw_session {draw_funcs, draw_data}; #ifndef HB_NO_VAR_COMPOSITES - if (!font->face->table.VARC->get_path (font, glyph, draw_session)) + if (font->face->table.VARC->get_path (font, glyph, draw_session)) return true; #endif // Keep the following in synch with VARC::get_path_at() - if (!font->face->table.glyf->get_path (font, glyph, draw_session)) + if (font->face->table.glyf->get_path (font, glyph, draw_session)) return true; #ifndef HB_NO_CFF - if (!font->face->table.cff2->get_path (font, glyph, draw_session)) - if (!font->face->table.cff1->get_path (font, glyph, draw_session)) + if (font->face->table.cff2->get_path (font, glyph, draw_session)) return true; + if (font->face->table.cff1->get_path (font, glyph, draw_session)) return true; #endif - {} + return false; } #endif #ifndef HB_NO_PAINT -static void -hb_ot_paint_glyph (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette, - hb_color_t foreground, - void *user_data) +static hb_bool_t +hb_ot_paint_glyph_or_fail (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) { #ifndef HB_NO_COLOR - if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return; - if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return true; + if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return true; #ifndef HB_NO_OT_FONT_BITMAP - if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return; - if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return; + if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return true; + if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return true; #endif #endif - - // Outline glyph - paint_funcs->push_clip_glyph (paint_data, glyph, font); - paint_funcs->color (paint_data, true, foreground); - paint_funcs->pop_clip (paint_data); + return false; } #endif @@ -568,11 +557,11 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t +struct matcher_t { - struct matcher_t + typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); + + template + void init (const context_t *c, bool context_match = false) { - typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); + set_match_func (nullptr, nullptr); + lookup_props = c->lookup_props; + /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ + ignore_zwnj = c->table_index == 1 || (context_match && c->auto_zwnj); + /* Ignore ZWJ if we are matching context, or asked to. */ + ignore_zwj = context_match || c->auto_zwj; + /* Ignore hidden glyphs (like CGJ) during GPOS. */ + ignore_hidden = c->table_index == 1; + mask = context_match ? -1 : c->lookup_mask; + /* Per syllable matching is only for GSUB. */ + per_syllable = c->table_index == 0 && c->per_syllable; + syllable = 0; + } - void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } - void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } - void set_ignore_hidden (bool ignore_hidden_) { ignore_hidden = ignore_hidden_; } - void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } - void set_mask (hb_mask_t mask_) { mask = mask_; } - void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; } - void set_syllable (uint8_t syllable_) { syllable = per_syllable ? syllable_ : 0; } - void set_match_func (match_func_t match_func_, - const void *match_data_) - { match_func = match_func_; match_data = match_data_; } + void set_match_func (match_func_t match_func_, + const void *match_data_) + { match_func = match_func_; match_data = match_data_; } - enum may_match_t { - MATCH_NO, - MATCH_YES, - MATCH_MAYBE - }; - -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - may_match_t may_match (hb_glyph_info_t &info, - hb_codepoint_t glyph_data) const - { - if (!(info.mask & mask) || - (syllable && syllable != info.syllable ())) - return MATCH_NO; - - if (match_func) - return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; - - return MATCH_MAYBE; - } - - enum may_skip_t { - SKIP_NO, - SKIP_YES, - SKIP_MAYBE - }; - -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - may_skip_t may_skip (const hb_ot_apply_context_t *c, - const hb_glyph_info_t &info) const - { - if (!c->check_glyph_property (&info, lookup_props)) - return SKIP_YES; - - if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && - (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && - (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && - (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) - return SKIP_MAYBE; - - return SKIP_NO; - } - - protected: - unsigned int lookup_props = 0; - hb_mask_t mask = -1; - bool ignore_zwnj = false; - bool ignore_zwj = false; - bool ignore_hidden = false; - bool per_syllable = false; - uint8_t syllable = 0; - match_func_t match_func = nullptr; - const void *match_data = nullptr; + enum may_match_t { + MATCH_NO, + MATCH_YES, + MATCH_MAYBE }; - struct skipping_iterator_t +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + may_match_t may_match (hb_glyph_info_t &info, + hb_codepoint_t glyph_data) const { - void init (hb_ot_apply_context_t *c_, bool context_match = false) - { - c = c_; - end = c->buffer->len; - match_glyph_data16 = nullptr; + if (!(info.mask & mask) || + (per_syllable && syllable && syllable != info.syllable ())) + return MATCH_NO; + + if (match_func) + return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; + + return MATCH_MAYBE; + } + + enum may_skip_t { + SKIP_NO, + SKIP_YES, + SKIP_MAYBE + }; + + template +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + may_skip_t may_skip (const context_t *c, + const hb_glyph_info_t &info) const + { + if (!c->check_glyph_property (&info, lookup_props)) + return SKIP_YES; + + if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && + (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && + (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && + (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) + return SKIP_MAYBE; + + return SKIP_NO; + } + + public: + unsigned int lookup_props = 0; + hb_mask_t mask = -1; + bool ignore_zwnj = false; + bool ignore_zwj = false; + bool ignore_hidden = false; + bool per_syllable = false; + uint8_t syllable = 0; + match_func_t match_func = nullptr; + const void *match_data = nullptr; +}; + +template +struct skipping_iterator_t +{ + void init (context_t *c_, bool context_match = false) + { + c = c_; + end = c->buffer->len; + match_glyph_data16 = nullptr; #ifndef HB_NO_BEYOND_64K - match_glyph_data24 = nullptr; + match_glyph_data24 = nullptr; #endif - matcher.set_match_func (nullptr, nullptr); - matcher.set_lookup_props (c->lookup_props); - /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ - matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); - /* Ignore ZWJ if we are matching context, or asked to. */ - matcher.set_ignore_zwj (context_match || c->auto_zwj); - /* Ignore hidden glyphs (like CGJ) during GPOS. */ - matcher.set_ignore_hidden (c->table_index == 1); - matcher.set_mask (context_match ? -1 : c->lookup_mask); - /* Per syllable matching is only for GSUB. */ - matcher.set_per_syllable (c->table_index == 0 && c->per_syllable); - matcher.set_syllable (0); - } - void set_lookup_props (unsigned int lookup_props) - { - matcher.set_lookup_props (lookup_props); - } - void set_match_func (matcher_t::match_func_t match_func_, - const void *match_data_) - { - matcher.set_match_func (match_func_, match_data_); - } - void set_glyph_data (const HBUINT16 glyph_data[]) - { - match_glyph_data16 = glyph_data; + matcher.init (c, context_match); + } + void set_lookup_props (unsigned int lookup_props) + { + matcher.lookup_props = lookup_props; + } + void set_match_func (matcher_t::match_func_t match_func_, + const void *match_data_) + { + matcher.set_match_func (match_func_, match_data_); + } + void set_glyph_data (const HBUINT16 glyph_data[]) + { + match_glyph_data16 = glyph_data; #ifndef HB_NO_BEYOND_64K - match_glyph_data24 = nullptr; + match_glyph_data24 = nullptr; #endif - } + } #ifndef HB_NO_BEYOND_64K - void set_glyph_data (const HBUINT24 glyph_data[]) - { - match_glyph_data16 = nullptr; - match_glyph_data24 = glyph_data; - } + void set_glyph_data (const HBUINT24 glyph_data[]) + { + match_glyph_data16 = nullptr; + match_glyph_data24 = glyph_data; + } #endif #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - void reset (unsigned int start_index_) - { - idx = start_index_; - end = c->buffer->len; - matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); - } - -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - void reset_fast (unsigned int start_index_) - { - // Doesn't set end or syllable. Used by GPOS which doesn't care / change. - idx = start_index_; - } - - void reject () - { - backup_glyph_data (); - } - - matcher_t::may_skip_t -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - may_skip (const hb_glyph_info_t &info) const - { return matcher.may_skip (c, info); } - - enum match_t { - MATCH, - NOT_MATCH, - SKIP - }; - -#ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE -#endif - match_t match (hb_glyph_info_t &info) - { - matcher_t::may_skip_t skip = matcher.may_skip (c, info); - if (unlikely (skip == matcher_t::SKIP_YES)) - return SKIP; - - matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); - if (match == matcher_t::MATCH_YES || - (match == matcher_t::MATCH_MAYBE && - skip == matcher_t::SKIP_NO)) - return MATCH; - - if (skip == matcher_t::SKIP_NO) - return NOT_MATCH; - - return SKIP; + void reset (unsigned int start_index_) + { + idx = start_index_; + end = c->buffer->len; + matcher.syllable = start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0; } #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - bool next (unsigned *unsafe_to = nullptr) - { - const signed stop = (signed) end - 1; - while ((signed) idx < stop) - { - idx++; - switch (match (c->buffer->info[idx])) - { - case MATCH: - { - advance_glyph_data (); - return true; - } - case NOT_MATCH: - { - if (unsafe_to) - *unsafe_to = idx + 1; - return false; - } - case SKIP: - continue; - } - } - if (unsafe_to) - *unsafe_to = end; - return false; - } + void reset_fast (unsigned int start_index_) + { + // Doesn't set end or syllable. Used by GPOS which doesn't care / change. + idx = start_index_; + } + #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - bool prev (unsigned *unsafe_from = nullptr) - { - const unsigned stop = 0; - while (idx > stop) - { - idx--; - switch (match (c->buffer->out_info[idx])) - { - case MATCH: - { - advance_glyph_data (); - return true; - } - case NOT_MATCH: - { - if (unsafe_from) - *unsafe_from = hb_max (1u, idx) - 1u; - return false; - } - case SKIP: - continue; - } - } - if (unsafe_from) - *unsafe_from = 0; - return false; - } + matcher_t::may_skip_t may_skip (const hb_glyph_info_t &info) const + { return matcher.may_skip (c, info); } - HB_ALWAYS_INLINE - hb_codepoint_t - get_glyph_data () - { - if (match_glyph_data16) return *match_glyph_data16; -#ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) return *match_glyph_data24; -#endif - return 0; - } - HB_ALWAYS_INLINE - void - advance_glyph_data () - { - if (match_glyph_data16) match_glyph_data16++; -#ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) match_glyph_data24++; -#endif - } - void - backup_glyph_data () - { - if (match_glyph_data16) match_glyph_data16--; -#ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) match_glyph_data24--; -#endif - } - - unsigned int idx; - protected: - hb_ot_apply_context_t *c; - matcher_t matcher; - const HBUINT16 *match_glyph_data16; -#ifndef HB_NO_BEYOND_64K - const HBUINT24 *match_glyph_data24; -#endif - - unsigned int end; + enum match_t { + MATCH, + NOT_MATCH, + SKIP }; +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + match_t match (hb_glyph_info_t &info) + { + matcher_t::may_skip_t skip = matcher.may_skip (c, info); + if (unlikely (skip == matcher_t::SKIP_YES)) + return SKIP; + matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); + if (match == matcher_t::MATCH_YES || + (match == matcher_t::MATCH_MAYBE && + skip == matcher_t::SKIP_NO)) + return MATCH; + + if (skip == matcher_t::SKIP_NO) + return NOT_MATCH; + + return SKIP; + } + +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + bool next (unsigned *unsafe_to = nullptr) + { + const signed stop = (signed) end - 1; + while ((signed) idx < stop) + { + idx++; + switch (match (c->buffer->info[idx])) + { + case MATCH: + { + advance_glyph_data (); + return true; + } + case NOT_MATCH: + { + if (unsafe_to) + *unsafe_to = idx + 1; + return false; + } + case SKIP: + continue; + } + } + if (unsafe_to) + *unsafe_to = end; + return false; + } +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif + bool prev (unsigned *unsafe_from = nullptr) + { + const unsigned stop = 0; + while (idx > stop) + { + idx--; + switch (match (c->buffer->out_info[idx])) + { + case MATCH: + { + advance_glyph_data (); + return true; + } + case NOT_MATCH: + { + if (unsafe_from) + *unsafe_from = hb_max (1u, idx) - 1u; + return false; + } + case SKIP: + continue; + } + } + if (unsafe_from) + *unsafe_from = 0; + return false; + } + + HB_ALWAYS_INLINE + hb_codepoint_t + get_glyph_data () + { + if (match_glyph_data16) return *match_glyph_data16; +#ifndef HB_NO_BEYOND_64K + else + if (match_glyph_data24) return *match_glyph_data24; +#endif + return 0; + } + HB_ALWAYS_INLINE + void + advance_glyph_data () + { + if (match_glyph_data16) match_glyph_data16++; +#ifndef HB_NO_BEYOND_64K + else + if (match_glyph_data24) match_glyph_data24++; +#endif + } + + unsigned int idx; + protected: + context_t *c; + matcher_t matcher; + const HBUINT16 *match_glyph_data16; +#ifndef HB_NO_BEYOND_64K + const HBUINT24 *match_glyph_data24; +#endif + + unsigned int end; +}; + +struct hb_ot_apply_context_t : + hb_dispatch_context_t +{ const char *get_name () { return "APPLY"; } typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); template @@ -703,7 +688,7 @@ struct hb_ot_apply_context_t : return ret; } - skipping_iterator_t iter_input, iter_context; + skipping_iterator_t iter_input, iter_context; unsigned int table_index; /* GSUB/GPOS */ hb_font_t *font; @@ -1270,7 +1255,7 @@ static bool match_input (hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (input); @@ -1349,7 +1334,7 @@ static bool match_input (hb_ot_apply_context_t *c, j--; } - if (found && skippy_iter.may_skip (out[j]) == hb_ot_apply_context_t::matcher_t::SKIP_YES) + if (found && skippy_iter.may_skip (out[j]) == matcher_t::SKIP_YES) ligbase = LIGBASE_MAY_SKIP; else ligbase = LIGBASE_MAY_NOT_SKIP; @@ -1512,7 +1497,7 @@ static bool match_backtrack (hb_ot_apply_context_t *c, { TRACE_APPLY (nullptr); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + auto &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->backtrack_len ()); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (backtrack); @@ -1545,7 +1530,7 @@ static bool match_lookahead (hb_ot_apply_context_t *c, { TRACE_APPLY (nullptr); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + auto &skippy_iter = c->iter_context; assert (start_index >= 1); skippy_iter.reset (start_index - 1); skippy_iter.set_match_func (match_func, match_data); @@ -2209,7 +2194,7 @@ struct RuleSet * * Replicated from LigatureSet::apply(). */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); @@ -3420,7 +3405,7 @@ struct ChainRuleSet if (!c->auto_zwnj || !c->auto_zwj) goto slow; - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh index c8a58bdf85e..2d8acd825b9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh @@ -290,7 +290,7 @@ struct post const Array16Of *glyphNameIndex = nullptr; hb_vector_t index_to_offset; const uint8_t *pool = nullptr; - hb_atomic_t gids_sorted_by_name; + mutable hb_atomic_t gids_sorted_by_name; }; bool has_data () const { return version.to_int (); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc index 44b670fcc02..d25a3f6f480 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc @@ -260,7 +260,7 @@ struct arabic_shape_plan_t * mask_array[NONE] == 0. */ hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1]; - hb_atomic_t fallback_plan; + mutable hb_atomic_t fallback_plan; unsigned int do_fallback : 1; unsigned int has_stch : 1; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-table.hh index 9cd4469c646..9f9b5c6e5f6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-table.hh @@ -222,60 +222,60 @@ hb_use_u8[3345] = 133, 134, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, 99, 76, 135, 136, 137, 0, 0, 0, 0, 2, 138, 2, 2, 2, 2, 139, 0, 30, 2, 42, 5, 0, 79, 15, - 2, 53, 22, 140, 52, 53, 2, 2, 105, 10, 9, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 141, 21, 25, 0, 0, 142, 143, 0, 0, 0, - 0, 2, 65, 45, 23, 80, 47, 144, 0, 81, 81, 81, 81, 81, 81, 81, + 2, 140, 20, 53, 128, 140, 2, 2, 141, 10, 9, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 142, 21, 25, 0, 0, 143, 144, 0, 0, 0, + 0, 2, 65, 45, 23, 80, 47, 145, 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 6, 120, 120, 120, 120, 121, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, - 2, 2, 30, 2, 2, 2, 30, 9, 0, 128, 20, 27, 31, 0, 0, 145, - 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, - 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 2, 2, 30, 2, 2, 2, 30, 9, 0, 128, 20, 27, 31, 0, 0, 146, + 147, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, + 148, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, - 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, + 116, 149, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, - 0, 149, 150, 151, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20, - 20, 20, 22, 22, 134, 0, 0, 0, 0, 0, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0, - 153, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, + 0, 150, 151, 152, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20, + 20, 20, 22, 22, 134, 0, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0, + 154, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 11, 49, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 128, 20, 22, 154, 22, 21, 155, 156, 2, 2, 2, 2, - 2, 0, 0, 65, 157, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, - 0, 2, 65, 25, 20, 20, 20, 22, 22, 108, 158, 0, 0, 56, 159, 31, - 160, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, - 19, 22, 22, 161, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 128, 20, 22, 155, 22, 21, 156, 157, 2, 2, 2, 2, + 2, 0, 0, 65, 158, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, + 0, 2, 65, 25, 20, 20, 20, 22, 22, 108, 159, 0, 0, 56, 160, 31, + 161, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, + 19, 22, 22, 162, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, - 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 162, 31, 0, + 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 163, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20, - 20, 31, 33, 32, 32, 25, 163, 29, 164, 165, 37, 0, 0, 0, 0, 0, + 20, 31, 33, 32, 32, 25, 164, 29, 165, 166, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, - 166, 167, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, - 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 65, 25, 20, 20, 0, 48, 48, 11, 169, 37, 0, 0, 0, 0, 0, 0, + 167, 168, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, + 161, 11, 169, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 65, 25, 20, 20, 0, 48, 48, 11, 170, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, - 169, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 170, - 25, 20, 22, 22, 168, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, + 170, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 171, + 25, 20, 22, 22, 169, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 169, 37, 0, + 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 170, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, - 2, 23, 23, 18, 32, 33, 12, 171, 165, 172, 173, 0, 0, 0, 0, 0, + 2, 23, 23, 18, 32, 33, 12, 172, 166, 173, 174, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, - 2, 2, 174, 175, 11, 15, 176, 61, 177, 0, 0, 1, 147, 0, 0, 0, - 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 178, 178, + 2, 2, 175, 141, 11, 15, 176, 61, 177, 0, 0, 1, 148, 0, 0, 0, + 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 159, 159, 159, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, - 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, + 170, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, - 27, 11, 159, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 27, 11, 160, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2, - 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 156, 0, 0, 184, 184, 184, 184, 184, 184, 184, + 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 144, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 157, 0, 0, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0, 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 192, 193, @@ -306,11 +306,11 @@ hb_use_u8[3345] = CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B, CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, - FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, - IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, - IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, - O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, - VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, + FPst, VBlw, B, VBlw,VMAbv, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw, + VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, + VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv, + CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, + VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, @@ -528,60 +528,60 @@ hb_use_u8[3657] = 2, 2, 131, 23, 22, 20, 48, 132, 133, 134, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, 99, 76, 135, 136, 137, 0, 0, 0, 0, 2, 138, 2, 2, 2, 2, 139, - 0, 30, 2, 42, 5, 0, 79, 15, 2, 53, 22, 140, 52, 53, 2, 2, - 105, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, - 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, + 0, 30, 2, 42, 5, 0, 79, 15, 2, 140, 20, 53, 128, 140, 2, 2, + 141, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 142, 21, + 25, 0, 0, 143, 144, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 145, 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 6, 120, 120, 120, 120, 121, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, - 0, 128, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, - 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, + 0, 128, 20, 27, 31, 0, 0, 146, 147, 2, 2, 30, 2, 30, 2, 2, + 2, 2, 2, 2, 0, 14, 37, 0, 148, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, - 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 116, 116, 116, 116, 116, 149, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, - 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, + 2, 30, 2, 9, 0, 30, 2, 0, 0, 150, 151, 152, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 134, 0, 0, 0, - 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, - 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, + 0, 0, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 2, 2, 2, 2, + 2, 53, 52, 53, 0, 0, 0, 0, 154, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, - 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 20, 22, 154, - 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, + 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 20, 22, 155, + 22, 21, 156, 157, 2, 2, 2, 2, 2, 0, 0, 65, 158, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, - 22, 108, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, + 22, 108, 159, 0, 0, 56, 160, 31, 161, 30, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 162, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, - 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, + 10, 18, 19, 21, 22, 163, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, - 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, - 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, + 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 164, 29, + 165, 166, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, - 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 168, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 167, 168, 0, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 20, 66, 99, 25, 161, 11, 169, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, - 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, - 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, + 170, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, + 0, 23, 19, 20, 20, 21, 16, 82, 170, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 10, 171, 25, 20, 22, 22, 169, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, - 19, 20, 21, 22, 105, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, - 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, - 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 19, 20, 21, 22, 105, 170, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 172, + 166, 173, 174, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, - 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 174, 175, 11, 15, 176, 61, - 177, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, - 2, 2, 2, 158, 158, 158, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, - 0, 22, 20, 20, 31, 22, 22, 11, 169, 0, 61, 61, 61, 61, 61, 61, + 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 175, 141, 11, 15, 176, 61, + 177, 0, 0, 1, 148, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, + 2, 2, 2, 159, 159, 159, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, + 0, 22, 20, 20, 31, 22, 22, 11, 170, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, - 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 180, 181, 0, 0, 0, + 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 160, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, - 48, 16, 143, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 156, 0, + 48, 16, 144, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 157, 0, 0, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0, 0, 2, 2, 2, 2, 2, 2, 2, @@ -612,12 +612,12 @@ hb_use_u8[3657] = IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv, VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, - MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, - O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, - B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, - VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, - CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw, - VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R, + MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, VBlw,VMAbv, B, VPre, O, + VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, + CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, + R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, + B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B, + FMBlw, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R, VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc index f000f272636..45424f79957 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc @@ -117,7 +117,7 @@ hb_ot_var_get_axes (hb_face_t *face, * in the specified face. * * Since: 1.4.2 - * Deprecated: 2.2.0 - use hb_ot_var_find_axis_info() instead + * Deprecated: 2.2.0: use hb_ot_var_find_axis_info() instead **/ hb_bool_t hb_ot_var_find_axis (hb_face_t *face, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-outline.cc b/src/3rdparty/harfbuzz-ng/src/hb-outline.cc index 29b1f530d5a..d180e7c4f94 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-outline.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-outline.cc @@ -84,6 +84,12 @@ void hb_outline_t::replay (hb_draw_funcs_t *pen, void *pen_data) const } } +void hb_outline_t::slant (float slant_xy) +{ + for (auto &p : points) + p.x += slant_xy * p.y; +} + float hb_outline_t::control_area () const { float a = 0; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-outline.hh b/src/3rdparty/harfbuzz-ng/src/hb-outline.hh index c43c06596bb..060ad775f1b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-outline.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-outline.hh @@ -69,6 +69,7 @@ struct hb_outline_t HB_INTERNAL void replay (hb_draw_funcs_t *pen, void *pen_data) const; HB_INTERNAL float control_area () const; + HB_INTERNAL void slant (float slant_xy); HB_INTERNAL void embolden (float x_strength, float y_strength, float x_shift, float y_shift); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint-bounded.cc b/src/3rdparty/harfbuzz-ng/src/hb-paint-bounded.cc new file mode 100644 index 00000000000..ca1b6161597 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-paint-bounded.cc @@ -0,0 +1,207 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb.hh" + +#ifndef HB_NO_PAINT + +#include "hb-paint-bounded.hh" + +#include "hb-machinery.hh" + + +/* + * This file implements boundedness computation of COLRv1 fonts as described in: + * + * https://learn.microsoft.com/en-us/typography/opentype/spec/colr#glyph-metrics-and-boundedness + */ + +static void +hb_paint_bounded_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->push_clip (); +} + +static void +hb_paint_bounded_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->push_clip (); +} + +static void +hb_paint_bounded_pop_clip (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->pop_clip (); +} + +static void +hb_paint_bounded_push_group (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->push_group (); +} + +static void +hb_paint_bounded_pop_group (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->pop_group (mode); +} + +static hb_bool_t +hb_paint_bounded_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_blob_t *blob HB_UNUSED, + unsigned int width HB_UNUSED, + unsigned int height HB_UNUSED, + hb_tag_t format HB_UNUSED, + float slant HB_UNUSED, + hb_glyph_extents_t *glyph_extents, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->push_clip (); + c->paint (); + c->pop_clip (); + + return true; +} + +static void +hb_paint_bounded_paint_color (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_bool_t use_foreground HB_UNUSED, + hb_color_t color HB_UNUSED, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->paint (); +} + +static void +hb_paint_bounded_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float x0 HB_UNUSED, float y0 HB_UNUSED, + float x1 HB_UNUSED, float y1 HB_UNUSED, + float x2 HB_UNUSED, float y2 HB_UNUSED, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->paint (); +} + +static void +hb_paint_bounded_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float x0 HB_UNUSED, float y0 HB_UNUSED, float r0 HB_UNUSED, + float x1 HB_UNUSED, float y1 HB_UNUSED, float r1 HB_UNUSED, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->paint (); +} + +static void +hb_paint_bounded_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float cx HB_UNUSED, float cy HB_UNUSED, + float start_angle HB_UNUSED, + float end_angle HB_UNUSED, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->paint (); +} + +static inline void free_static_paint_bounded_funcs (); + +static struct hb_paint_bounded_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t +{ + static hb_paint_funcs_t *create () + { + hb_paint_funcs_t *funcs = hb_paint_funcs_create (); + + hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_paint_bounded_push_clip_glyph, nullptr, nullptr); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_paint_bounded_push_clip_rectangle, nullptr, nullptr); + hb_paint_funcs_set_pop_clip_func (funcs, hb_paint_bounded_pop_clip, nullptr, nullptr); + hb_paint_funcs_set_push_group_func (funcs, hb_paint_bounded_push_group, nullptr, nullptr); + hb_paint_funcs_set_pop_group_func (funcs, hb_paint_bounded_pop_group, nullptr, nullptr); + hb_paint_funcs_set_color_func (funcs, hb_paint_bounded_paint_color, nullptr, nullptr); + hb_paint_funcs_set_image_func (funcs, hb_paint_bounded_paint_image, nullptr, nullptr); + hb_paint_funcs_set_linear_gradient_func (funcs, hb_paint_bounded_paint_linear_gradient, nullptr, nullptr); + hb_paint_funcs_set_radial_gradient_func (funcs, hb_paint_bounded_paint_radial_gradient, nullptr, nullptr); + hb_paint_funcs_set_sweep_gradient_func (funcs, hb_paint_bounded_paint_sweep_gradient, nullptr, nullptr); + + hb_paint_funcs_make_immutable (funcs); + + hb_atexit (free_static_paint_bounded_funcs); + + return funcs; + } +} static_paint_bounded_funcs; + +static inline +void free_static_paint_bounded_funcs () +{ + static_paint_bounded_funcs.free_instance (); +} + +hb_paint_funcs_t * +hb_paint_bounded_get_funcs () +{ + return static_paint_bounded_funcs.get_unconst (); +} + + +#endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint-bounded.hh b/src/3rdparty/harfbuzz-ng/src/hb-paint-bounded.hh new file mode 100644 index 00000000000..2fbef3ada93 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-paint-bounded.hh @@ -0,0 +1,117 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_PAINT_BOUNDED_HH +#define HB_PAINT_BOUNDED_HH + +#include "hb.hh" +#include "hb-paint.h" + +#include "hb-geometry.hh" + + +typedef struct hb_paint_bounded_context_t hb_paint_bounded_context_t; + +struct hb_paint_bounded_context_t +{ + void clear () + { + clips = 0; + bounded = true; + groups.clear (); + } + + hb_paint_bounded_context_t () + { + clear (); + } + + bool is_bounded () + { + return bounded; + } + + void push_clip () + { + clips++; + } + + void pop_clip () + { + if (clips == 0) return; + clips--; + } + + void push_group () + { + groups.push (bounded); + bounded = true; + } + + void pop_group (hb_paint_composite_mode_t mode) + { + const bool src_bounded = bounded; + bounded = groups.pop (); + bool &backdrop_bounded = bounded; + + // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite + switch ((int) mode) + { + case HB_PAINT_COMPOSITE_MODE_CLEAR: + backdrop_bounded = true; + break; + case HB_PAINT_COMPOSITE_MODE_SRC: + case HB_PAINT_COMPOSITE_MODE_SRC_OUT: + backdrop_bounded = src_bounded; + break; + case HB_PAINT_COMPOSITE_MODE_DEST: + case HB_PAINT_COMPOSITE_MODE_DEST_OUT: + break; + case HB_PAINT_COMPOSITE_MODE_SRC_IN: + case HB_PAINT_COMPOSITE_MODE_DEST_IN: + backdrop_bounded = backdrop_bounded && src_bounded; + break; + default: + backdrop_bounded = backdrop_bounded || src_bounded; + break; + } + } + + void paint () + { + if (!clips) + bounded = false; + } + + protected: + bool bounded; // true if current drawing bounded + unsigned clips; // number of active clips + hb_vector_t groups; // true if group bounded +}; + +HB_INTERNAL hb_paint_funcs_t * +hb_paint_bounded_get_funcs (); + + +#endif /* HB_PAINT_BOUNDED_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.cc b/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.cc index 2393322b715..35dcb76f2a7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.cc @@ -28,14 +28,13 @@ #include "hb-paint-extents.hh" -#include "hb-draw.h" +#include "hb-draw.hh" #include "hb-machinery.hh" /* - * This file implements bounds-extraction as well as boundedness - * computation of COLRv1 fonts as described in: + * This file implements bounds-extraction computation of COLRv1 fonts as described in: * * https://learn.microsoft.com/en-us/typography/opentype/spec/colr#glyph-metrics-and-boundedness */ @@ -63,93 +62,6 @@ hb_paint_extents_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED, c->pop_transform (); } -static void -hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, - void *data, - hb_draw_state_t *st, - float to_x, float to_y, - void *user_data HB_UNUSED) -{ - hb_extents_t *extents = (hb_extents_t *) data; - - extents->add_point (to_x, to_y); -} - -static void -hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, - void *data, - hb_draw_state_t *st, - float to_x, float to_y, - void *user_data HB_UNUSED) -{ - hb_extents_t *extents = (hb_extents_t *) data; - - extents->add_point (to_x, to_y); -} - -static void -hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, - void *data, - hb_draw_state_t *st, - float control_x, float control_y, - float to_x, float to_y, - void *user_data HB_UNUSED) -{ - hb_extents_t *extents = (hb_extents_t *) data; - - extents->add_point (control_x, control_y); - extents->add_point (to_x, to_y); -} - -static void -hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, - void *data, - hb_draw_state_t *st, - float control1_x, float control1_y, - float control2_x, float control2_y, - float to_x, float to_y, - void *user_data HB_UNUSED) -{ - hb_extents_t *extents = (hb_extents_t *) data; - - extents->add_point (control1_x, control1_y); - extents->add_point (control2_x, control2_y); - extents->add_point (to_x, to_y); -} - -static inline void free_static_draw_extents_funcs (); - -static struct hb_draw_extents_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t -{ - static hb_draw_funcs_t *create () - { - hb_draw_funcs_t *funcs = hb_draw_funcs_create (); - - hb_draw_funcs_set_move_to_func (funcs, hb_draw_extents_move_to, nullptr, nullptr); - hb_draw_funcs_set_line_to_func (funcs, hb_draw_extents_line_to, nullptr, nullptr); - hb_draw_funcs_set_quadratic_to_func (funcs, hb_draw_extents_quadratic_to, nullptr, nullptr); - hb_draw_funcs_set_cubic_to_func (funcs, hb_draw_extents_cubic_to, nullptr, nullptr); - - hb_draw_funcs_make_immutable (funcs); - - hb_atexit (free_static_draw_extents_funcs); - - return funcs; - } -} static_draw_extents_funcs; - -static inline -void free_static_draw_extents_funcs () -{ - static_draw_extents_funcs.free_instance (); -} - -static hb_draw_funcs_t * -hb_draw_extents_get_funcs () -{ - return static_draw_extents_funcs.get_unconst (); -} - static void hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data, @@ -221,6 +133,9 @@ hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; + if (!glyph_extents) + return false; // Happens with SVG images. + hb_extents_t extents = {(float) glyph_extents->x_bearing, (float) glyph_extents->y_bearing + glyph_extents->height, (float) glyph_extents->x_bearing + glyph_extents->width, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint.cc b/src/3rdparty/harfbuzz-ng/src/hb-paint.cc index 755b181696e..5dd97d5bb1b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-paint.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-paint.cc @@ -87,7 +87,7 @@ hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, unsigned int width, unsigned int height, hb_tag_t format, - float slant_xy, + float slant_xy_deprecated, hb_glyph_extents_t *extents, void *user_data) { return false; } @@ -615,7 +615,7 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, * @width: width of the raster image in pixels, or 0 * @height: height of the raster image in pixels, or 0 * @format: the image format as a tag - * @slant: the synthetic slant ratio to be applied to the image during rendering + * @slant: Deprecated. set to 0.0 * @extents: (nullable): the extents of the glyph * * Perform a "image" paint operation. @@ -628,10 +628,10 @@ hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, unsigned int width, unsigned int height, hb_tag_t format, - float slant, + HB_UNUSED float slant, hb_glyph_extents_t *extents) { - funcs->image (paint_data, image, width, height, format, slant, extents); + funcs->image (paint_data, image, width, height, format, 0.f, extents); } /** diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint.h b/src/3rdparty/harfbuzz-ng/src/hb-paint.h index 309213e2d7a..37850772981 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-paint.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-paint.h @@ -167,8 +167,10 @@ typedef hb_bool_t (*hb_paint_color_glyph_func_t) (hb_paint_funcs_t *funcs, * A virtual method for the #hb_paint_funcs_t to clip * subsequent paint calls to the outline of a glyph. * - * The coordinates of the glyph outline are interpreted according - * to the current transform. + * The coordinates of the glyph outline are expected in the + * current @font scale (ie. the results of calling + * hb_font_draw_glyph() with @font). The outline is + * transformed by the current transform. * * This clip is applied in addition to the current clip, * and remains in effect until a matching call to @@ -281,7 +283,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @width: width of the raster image in pixels, or 0 * @height: height of the raster image in pixels, or 0 * @format: the image format as a tag - * @slant: the synthetic slant ratio to be applied to the image during rendering + * @slant: Deprecated. Always set to 0.0. * @extents: (nullable): glyph extents for desired rendering * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint.hh b/src/3rdparty/harfbuzz-ng/src/hb-paint.hh index 5a7b903a072..6ad365a79fd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-paint.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-paint.hh @@ -162,10 +162,11 @@ struct hb_paint_funcs_t { float upem = font->face->get_upem (); int xscale = font->x_scale, yscale = font->y_scale; - float slant = font->slant_xy; push_transform (paint_data, - xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0); + xscale/upem, 0, + 0, yscale/upem, + 0, 0); } void push_inverse_font_transform (void *paint_data, @@ -174,10 +175,11 @@ struct hb_paint_funcs_t float upem = font->face->get_upem (); int xscale = font->x_scale ? font->x_scale : upem; int yscale = font->y_scale ? font->y_scale : upem; - float slant = font->slant_xy; push_transform (paint_data, - upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0); + upem/xscale, 0, + 0, upem/yscale, + 0, 0); } HB_NODISCARD diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh index f079caf4d35..dc494d236af 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh @@ -57,6 +57,10 @@ HB_SHAPER_IMPLEMENT (directwrite) HB_SHAPER_IMPLEMENT (coretext) #endif +#ifdef HAVE_HARFRUZZ +HB_SHAPER_IMPLEMENT (harfruzz) +#endif + #ifndef HB_NO_FALLBACK_SHAPE HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */ #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index 885434adc91..85d760b5f85 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -47,20 +47,20 @@ HB_BEGIN_DECLS * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 1 +#define HB_VERSION_MINOR 2 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 0 +#define HB_VERSION_MICRO 1 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "11.1.0" +#define HB_VERSION_STRING "11.2.1" /** * HB_VERSION_ATLEAST: