From d21e5f050d23a607a23951ddbc95f84c052b9b27 Mon Sep 17 00:00:00 2001 From: duke Date: Tue, 15 Jul 2025 19:02:58 +0000 Subject: [PATCH] Backport b21b3a38a5dbc7eb23c4bd1fd5c0900a3a1b470b --- src/java.desktop/share/legal/harfbuzz.md | 2 +- .../native/libharfbuzz/OT/Color/CBDT/CBDT.hh | 12 +- .../native/libharfbuzz/OT/Color/COLR/COLR.hh | 158 +++- .../native/libharfbuzz/OT/Color/sbix/sbix.hh | 11 +- .../native/libharfbuzz/OT/Color/svg/svg.hh | 15 +- .../OT/Layout/Common/CoverageFormat1.hh | 2 +- .../OT/Layout/Common/CoverageFormat2.hh | 2 +- .../native/libharfbuzz/OT/Layout/GDEF/GDEF.hh | 24 +- .../native/libharfbuzz/OT/Layout/GPOS/GPOS.hh | 5 +- .../OT/Layout/GPOS/PairPosFormat1.hh | 2 +- .../native/libharfbuzz/OT/Var/VARC/VARC.hh | 160 ++-- .../share/native/libharfbuzz/OT/glyf/glyf.hh | 21 +- .../libharfbuzz/hb-aat-layout-common.hh | 144 ++- .../libharfbuzz/hb-aat-layout-kerx-table.hh | 62 +- .../libharfbuzz/hb-aat-layout-morx-table.hh | 84 +- .../libharfbuzz/hb-aat-layout-trak-table.hh | 47 +- .../share/native/libharfbuzz/hb-aat-layout.cc | 59 +- .../share/native/libharfbuzz/hb-aat-layout.hh | 8 +- .../share/native/libharfbuzz/hb-aat-map.cc | 5 + .../share/native/libharfbuzz/hb-atomic.hh | 78 +- .../share/native/libharfbuzz/hb-bit-set.hh | 4 +- .../share/native/libharfbuzz/hb-bit-vector.hh | 195 ++++ .../libharfbuzz/hb-buffer-deserialize-json.hh | 602 ++++++------- .../hb-buffer-deserialize-text-glyphs.hh | 843 ++++++++---------- .../hb-buffer-deserialize-text-unicode.hh | 192 ++-- .../native/libharfbuzz/hb-buffer-serialize.cc | 22 +- .../native/libharfbuzz/hb-buffer-verify.cc | 35 +- .../share/native/libharfbuzz/hb-buffer.cc | 16 +- .../share/native/libharfbuzz/hb-buffer.h | 61 +- .../share/native/libharfbuzz/hb-buffer.hh | 5 + .../share/native/libharfbuzz/hb-cache.hh | 37 +- .../native/libharfbuzz/hb-cff2-interp-cs.hh | 66 +- .../share/native/libharfbuzz/hb-common.cc | 63 +- .../share/native/libharfbuzz/hb-common.h | 443 +-------- .../share/native/libharfbuzz/hb-config.hh | 2 +- .../share/native/libharfbuzz/hb-debug.hh | 6 +- .../share/native/libharfbuzz/hb-deprecated.h | 82 +- .../share/native/libharfbuzz/hb-draw.cc | 93 ++ .../share/native/libharfbuzz/hb-draw.h | 2 +- .../share/native/libharfbuzz/hb-draw.hh | 60 +- .../share/native/libharfbuzz/hb-face.cc | 228 ++++- .../share/native/libharfbuzz/hb-face.h | 16 +- .../share/native/libharfbuzz/hb-face.hh | 6 +- .../share/native/libharfbuzz/hb-font.cc | 611 ++++++++++--- .../share/native/libharfbuzz/hb-font.h | 97 +- .../share/native/libharfbuzz/hb-font.hh | 355 ++++++-- .../share/native/libharfbuzz/hb-ft.cc | 348 ++++---- .../share/native/libharfbuzz/hb-ft.h | 4 + .../share/native/libharfbuzz/hb-geometry.hh | 30 +- .../share/native/libharfbuzz/hb-machinery.hh | 2 +- .../share/native/libharfbuzz/hb-mutex.hh | 6 + .../share/native/libharfbuzz/hb-object.hh | 6 +- .../share/native/libharfbuzz/hb-open-type.hh | 14 +- .../native/libharfbuzz/hb-ot-cff1-table.hh | 10 +- .../native/libharfbuzz/hb-ot-cff2-table.cc | 10 +- .../native/libharfbuzz/hb-ot-cff2-table.hh | 18 +- .../native/libharfbuzz/hb-ot-cmap-table.hh | 83 +- .../share/native/libharfbuzz/hb-ot-color.cc | 8 +- .../libharfbuzz/hb-ot-face-table-list.hh | 2 +- .../share/native/libharfbuzz/hb-ot-face.cc | 1 + .../share/native/libharfbuzz/hb-ot-font.cc | 395 ++++---- .../native/libharfbuzz/hb-ot-hmtx-table.hh | 8 +- .../native/libharfbuzz/hb-ot-kern-table.hh | 2 + .../libharfbuzz/hb-ot-layout-base-table.hh | 2 +- .../native/libharfbuzz/hb-ot-layout-common.hh | 55 +- .../libharfbuzz/hb-ot-layout-gsubgpos.hh | 22 +- .../share/native/libharfbuzz/hb-ot-layout.cc | 17 +- .../share/native/libharfbuzz/hb-ot-layout.hh | 17 +- .../native/libharfbuzz/hb-ot-math-table.hh | 18 + .../share/native/libharfbuzz/hb-ot-math.cc | 14 + .../native/libharfbuzz/hb-ot-post-table.hh | 2 +- .../libharfbuzz/hb-ot-shape-fallback.cc | 9 +- .../share/native/libharfbuzz/hb-ot-shape.cc | 44 +- .../share/native/libharfbuzz/hb-ot-shape.hh | 4 + .../native/libharfbuzz/hb-ot-shaper-arabic.cc | 2 +- .../native/libharfbuzz/hb-ot-shaper-hangul.cc | 6 +- .../native/libharfbuzz/hb-ot-shaper-indic.cc | 2 +- .../native/libharfbuzz/hb-ot-shaper-thai.cc | 2 +- .../share/native/libharfbuzz/hb-ot-tag.cc | 2 +- .../libharfbuzz/hb-ot-var-gvar-table.hh | 10 +- .../share/native/libharfbuzz/hb-ot-var.cc | 2 +- .../share/native/libharfbuzz/hb-outline.cc | 6 + .../share/native/libharfbuzz/hb-outline.hh | 1 + .../native/libharfbuzz/hb-paint-bounded.cc | 207 +++++ .../native/libharfbuzz/hb-paint-bounded.hh | 117 +++ .../native/libharfbuzz/hb-paint-extents.cc | 95 +- .../native/libharfbuzz/hb-paint-extents.hh | 11 +- .../share/native/libharfbuzz/hb-paint.cc | 46 +- .../share/native/libharfbuzz/hb-paint.h | 16 +- .../share/native/libharfbuzz/hb-paint.hh | 16 +- .../share/native/libharfbuzz/hb-script-list.h | 484 ++++++++++ .../share/native/libharfbuzz/hb-set-digest.hh | 9 +- .../share/native/libharfbuzz/hb-set.hh | 1 + .../share/native/libharfbuzz/hb-shape.cc | 6 +- .../share/native/libharfbuzz/hb-static.cc | 1 + .../libharfbuzz/hb-subset-cff-common.hh | 2 +- .../native/libharfbuzz/hb-subset-input.cc | 2 +- .../native/libharfbuzz/hb-subset-plan.cc | 772 ++-------------- .../native/libharfbuzz/hb-subset-plan.hh | 70 ++ .../share/native/libharfbuzz/hb-subset.cc | 104 +++ .../share/native/libharfbuzz/hb-subset.h | 24 +- .../share/native/libharfbuzz/hb-vector.hh | 9 +- .../share/native/libharfbuzz/hb-version.h | 6 +- .../share/native/libharfbuzz/hb.hh | 55 +- 104 files changed, 4873 insertions(+), 3407 deletions(-) create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-bit-vector.hh create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-paint-bounded.cc create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-paint-bounded.hh create mode 100644 src/java.desktop/share/native/libharfbuzz/hb-script-list.h diff --git a/src/java.desktop/share/legal/harfbuzz.md b/src/java.desktop/share/legal/harfbuzz.md index 2d0a28ed310..e0c40705ed6 100644 --- a/src/java.desktop/share/legal/harfbuzz.md +++ b/src/java.desktop/share/legal/harfbuzz.md @@ -1,4 +1,4 @@ -## Harfbuzz v10.4.0 +## Harfbuzz 11.2.0 ### Harfbuzz License diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh index 43a611a0058..b8f6fa4054b 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh +++ b/src/java.desktop/share/native/libharfbuzz/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 ())) + if (unlikely (!font->get_glyph_extents (glyph, &extents, false))) return false; - if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) return false; - if (unlikely (!get_extents (font, glyph, &pixel_extents, 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/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh index 4d6272d05cb..73e6b4c305b 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh +++ b/src/java.desktop/share/native/libharfbuzz/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" @@ -47,6 +48,12 @@ namespace OT { struct hb_paint_context_t; } +struct hb_colr_scratch_t +{ + hb_paint_bounded_context_t paint_bounded; + hb_paint_extents_context_t paint_extents; +}; + namespace OT { struct COLR; @@ -90,12 +97,27 @@ public: font (font_), palette ( #ifndef HB_NO_COLOR - font->face->table.CPAL->get_palette_colors (palette_) + // https://github.com/harfbuzz/harfbuzz/issues/5116 + font->face->table.CPAL->get_palette_colors (palette_ < font->face->table.CPAL->get_palette_count () ? palette_ : 0) #endif ), 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) { @@ -932,9 +954,9 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); c->funcs->push_clip_glyph (c->data, gid, c->font); - c->funcs->push_root_transform (c->data, c->font); + c->funcs->push_font_transform (c->data, c->font); c->recurse (this+paint); c->funcs->pop_transform (c->data); c->funcs->pop_clip (c->data); @@ -1511,10 +1533,12 @@ struct PaintComposite void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); + c->funcs->push_group (c->data); c->recurse (this+backdrop); c->funcs->push_group (c->data); c->recurse (this+src); c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } HBUINT8 format; /* format = 32 */ @@ -1612,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; } } @@ -2079,6 +2103,8 @@ struct COLR { static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR; + bool has_data () const { return has_v0_data () || version; } + bool has_v0_data () const { return numBaseGlyphs; } bool has_v1_data () const { @@ -2112,7 +2138,53 @@ struct COLR { accelerator_t (hb_face_t *face) { colr = hb_sanitize_context_t ().reference_table (face); } - ~accelerator_t () { this->colr.destroy (); } + + ~accelerator_t () + { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_colr_scratch_t (); + hb_free (scratch); + } + + colr.destroy (); + } + + + bool has_data () const { return colr->has_data (); } + +#ifndef HB_NO_PAINT + bool + get_extents (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + if (unlikely (!has_data ())) return false; + + hb_colr_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = colr->get_extents (font, glyph, extents, *scratch); + release_scratch (scratch); + return ret; + } + + bool paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *data, + unsigned int palette_index, + hb_color_t foreground, + bool clip = true) const + { + if (unlikely (!has_data ())) return false; + + hb_colr_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = colr->paint_glyph (font, glyph, funcs, data, palette_index, foreground, clip, *scratch); + release_scratch (scratch); + return ret; + } +#endif bool is_valid () { return colr.get_blob ()->length; } @@ -2148,7 +2220,33 @@ struct COLR { return colr->get_delta_set_index_map_ptr (); } private: + + hb_colr_scratch_t *acquire_scratch () const + { + hb_colr_scratch_t *scratch = cached_scratch.get_acquire (); + + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_colr_scratch_t *) hb_calloc (1, sizeof (hb_colr_scratch_t)); + if (unlikely (!scratch)) + return nullptr; + } + + return scratch; + } + void release_scratch (hb_colr_scratch_t *scratch) const + { + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_colr_scratch_t (); + hb_free (scratch); + } + } + + public: hb_blob_ptr_t colr; + private: + mutable hb_atomic_t cached_scratch; }; void closure_glyphs (hb_codepoint_t glyph, @@ -2520,7 +2618,10 @@ struct COLR #ifndef HB_NO_PAINT bool - get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + get_extents (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_colr_scratch_t &scratch) const { ItemVarStoreInstancer instancer (get_var_store_ptr (), @@ -2534,10 +2635,10 @@ struct COLR } auto *extents_funcs = hb_paint_extents_get_funcs (); - hb_paint_extents_context_t extents_data; - bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0)); + scratch.paint_extents.clear (); + bool ret = paint_glyph (font, glyph, extents_funcs, &scratch.paint_extents, 0, HB_COLOR(0,0,0,0), true, scratch); - hb_extents_t e = extents_data.get_extents (); + auto e = scratch.paint_extents.get_extents (); if (e.is_void ()) { extents->x_bearing = 0; @@ -2583,7 +2684,12 @@ struct COLR #ifndef HB_NO_PAINT bool - paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const + paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *data, + unsigned int palette_index, hb_color_t foreground, + bool clip, + hb_colr_scratch_t &scratch) const { ItemVarStoreInstancer instancer (get_var_store_ptr (), get_delta_set_index_map_ptr (), @@ -2617,26 +2723,26 @@ struct COLR } else { - auto *extents_funcs = hb_paint_extents_get_funcs (); - hb_paint_extents_context_t extents_data; + 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, &extents_data, + bounded_funcs, &scratch.paint_bounded, palette_index, foreground, - false); - - hb_extents_t extents = extents_data.get_extents (); - is_bounded = extents_data.is_bounded (); + false, + scratch); - c.funcs->push_clip_rectangle (c.data, - extents.xmin, - extents.ymin, - extents.xmax, - extents.ymax); + is_bounded = scratch.paint_bounded.is_bounded (); } } - c.funcs->push_root_transform (c.data, font); + c.funcs->push_font_transform (c.data, font); if (is_bounded) c.recurse (*paint); @@ -2714,9 +2820,7 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const return; const Paint &paint = paint_offset_lists.get_paint (i); - c->funcs->push_group (c->data); c->recurse (paint); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } } @@ -2728,7 +2832,7 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (unlikely (!node.visit (gid))) return; - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->funcs->pop_transform (c->data); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh index e95d8c13a44..b77486a4340 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh +++ b/src/java.desktop/share/native/libharfbuzz/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 ()) + if (!font->get_glyph_extents (glyph, &extents, false)) return false; - if (!hb_font_get_glyph_extents (font, glyph, &extents)) + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) return false; - if (unlikely (!get_extents (font, glyph, &pixel_extents, 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/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh index 9f676f9689e..9249abf7075 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh index 4a925763bd7..97ea51089ec 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh @@ -77,7 +77,7 @@ struct CoverageFormat1_3 bool intersects (const hb_set_t *glyphs) const { - if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2) + if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len)) { for (auto g : *glyphs) if (get_coverage (g) != NOT_COVERED) diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh index 247b7274b14..0c9bd09cbf7 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh @@ -120,7 +120,7 @@ struct CoverageFormat2_4 bool intersects (const hb_set_t *glyphs) const { - if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) + if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len)) { for (auto g : *glyphs) if (get_coverage (g) != NOT_COVERED) diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh index 542480d2dd0..ceba37b0619 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh @@ -205,20 +205,19 @@ struct CaretValueFormat3 unsigned varidx = (this+deviceTable).get_variation_index (); hb_pair_t *new_varidx_delta; - if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) - return_trace (false); + if (c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) { + uint32_t new_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); + if (delta != 0) + { + if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + } - uint32_t new_varidx = hb_first (*new_varidx_delta); - int delta = hb_second (*new_varidx_delta); - if (delta != 0) - { - if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); + if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } - if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) - return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); - if (!c->serializer->embed (deviceTable)) return_trace (false); @@ -1015,7 +1014,8 @@ struct GDEF hb_blob_ptr_t table; #ifndef HB_NO_GDEF_CACHE hb_vector_t mark_glyph_set_digests; - mutable hb_cache_t<21, 3, 8> glyph_props_cache; + mutable hb_cache_t<21, 3> glyph_props_cache; + static_assert (sizeof (glyph_props_cache) == 512, ""); #endif }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh index f4af98b25fd..ce3f74d8c3b 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh index 597ff4c088a..2748882f527 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh @@ -54,7 +54,7 @@ struct PairPosFormat1_3 { auto &cov = this+coverage; - if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4) + if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len)) { for (hb_codepoint_t g : glyphs->iter()) { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh index dbbbec9eee0..2ea1b6bca32 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh @@ -21,6 +21,24 @@ namespace OT { #ifndef HB_NO_VAR_COMPOSITES +struct hb_varc_scratch_t +{ + hb_vector_t axisIndices; + hb_vector_t axisValues; + hb_glyf_scratch_t glyf_scratch; +}; + +struct hb_varc_context_t +{ + hb_font_t *font; + hb_draw_session_t *draw_session; + hb_extents_t *extents; + mutable hb_decycler_t decycler; + mutable signed edges_left; + mutable signed depth_left; + hb_varc_scratch_t &scratch; +}; + struct VarComponent { enum class flags_t : uint32_t @@ -44,41 +62,32 @@ struct VarComponent }; HB_INTERNAL hb_ubytes_t - get_path_at (hb_font_t *font, + get_path_at (const hb_varc_context_t &c, hb_codepoint_t parent_gid, - hb_draw_session_t &draw_session, hb_array_t coords, hb_transform_t transform, hb_ubytes_t record, - hb_decycler_t *decycler, - signed *edges_left, - signed depth_left, - hb_glyf_scratch_t &scratch, VarRegionList::cache_t *cache = nullptr) const; }; struct VarCompositeGlyph { static void - get_path_at (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_session_t &draw_session, + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t gid, hb_array_t coords, hb_transform_t transform, hb_ubytes_t record, - hb_decycler_t *decycler, - signed *edges_left, - signed depth_left, - hb_glyf_scratch_t &scratch, - VarRegionList::cache_t *cache = nullptr) + VarRegionList::cache_t *cache) { while (record) { const VarComponent &comp = * (const VarComponent *) (record.arrayZ); - record = comp.get_path_at (font, glyph, - draw_session, coords, transform, + record = comp.get_path_at (c, + gid, + coords, transform, record, - decycler, edges_left, depth_left, scratch, cache); + cache); } } }; @@ -92,36 +101,47 @@ struct VARC static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C'); HB_INTERNAL bool - get_path_at (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_session_t &draw_session, + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t gid, hb_array_t coords, - hb_transform_t transform, - hb_codepoint_t parent_glyph, - hb_decycler_t *decycler, - signed *edges_left, - signed depth_left, - hb_glyf_scratch_t &scratch) const; + hb_transform_t transform = HB_TRANSFORM_IDENTITY, + hb_codepoint_t parent_gid = HB_CODEPOINT_INVALID, + VarRegionList::cache_t *parent_cache = nullptr) const; bool get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, - hb_glyf_scratch_t &scratch) const + hb_varc_scratch_t &scratch) const { - hb_decycler_t decycler; - signed edges = HB_MAX_GRAPH_EDGE_COUNT; - - return get_path_at (font, - gid, - draw_session, - hb_array (font->coords, font->num_coords), - HB_TRANSFORM_IDENTITY, - HB_CODEPOINT_INVALID, - &decycler, - &edges, - HB_MAX_NESTING_LEVEL, - scratch); + hb_varc_context_t c {font, + &draw_session, + nullptr, + hb_decycler_t {}, + HB_MAX_GRAPH_EDGE_COUNT, + HB_MAX_NESTING_LEVEL, + scratch}; + + return get_path_at (c, gid, + hb_array (font->coords, font->num_coords)); + } + + bool + get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_extents_t *extents, + hb_varc_scratch_t &scratch) const + { + hb_varc_context_t c {font, + nullptr, + extents, + hb_decycler_t {}, + HB_MAX_GRAPH_EDGE_COUNT, + HB_MAX_NESTING_LEVEL, + scratch}; + + return get_path_at (c, gid, + hb_array (font->coords, font->num_coords)); } bool sanitize (hb_sanitize_context_t *c) const @@ -150,7 +170,7 @@ struct VARC auto *scratch = cached_scratch.get_relaxed (); if (scratch) { - scratch->~hb_glyf_scratch_t (); + scratch->~hb_varc_scratch_t (); hb_free (scratch); } @@ -162,34 +182,60 @@ struct VARC { if (!table->has_data ()) return false; - hb_glyf_scratch_t *scratch; + auto *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = table->get_path (font, gid, draw_session, *scratch); + release_scratch (scratch); + return ret; + } + + bool + get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents) const + { + if (!table->has_data ()) return false; + + hb_extents_t f_extents; + + auto *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = table->get_extents (font, gid, &f_extents, *scratch); + release_scratch (scratch); + + if (ret) + *extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0); + + return ret; + } + + private: - // Borrow the cached strach buffer. + hb_varc_scratch_t *acquire_scratch () const + { + hb_varc_scratch_t *scratch = cached_scratch.get_acquire (); + + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) { - scratch = cached_scratch.get_acquire (); - if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) - { - scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); - if (unlikely (!scratch)) - return true; - } + scratch = (hb_varc_scratch_t *) hb_calloc (1, sizeof (hb_varc_scratch_t)); + if (unlikely (!scratch)) + return nullptr; } - bool ret = table->get_path (font, gid, draw_session, *scratch); - - // Put it back. + return scratch; + } + void release_scratch (hb_varc_scratch_t *scratch) const + { if (!cached_scratch.cmpexch (nullptr, scratch)) { - scratch->~hb_glyf_scratch_t (); + scratch->~hb_varc_scratch_t (); hb_free (scratch); } - - return ret; } private: hb_blob_ptr_t table; - hb_atomic_ptr_t cached_scratch; + mutable hb_atomic_t cached_scratch; }; bool has_data () const { return version.major != 0; } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh index 681c3b9a007..d9e5fedfa92 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh @@ -429,16 +429,27 @@ struct glyf_accelerator_t } public: - bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const + + bool get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents) const + { return get_extents_at (font, gid, extents, hb_array (font->coords, font->num_coords)); } + + bool get_extents_at (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents, + hb_array_t coords) const { if (unlikely (gid >= num_glyphs)) return false; #ifndef HB_NO_VAR - if (font->num_coords) + if (coords) { hb_glyf_scratch_t scratch; - return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true), - hb_array (font->coords, font->num_coords), + return get_points (font, + gid, + points_aggregator_t (font, extents, nullptr, true), + coords, scratch); } #endif @@ -532,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_ptr_t cached_scratch; + mutable hb_atomic_t cached_scratch; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh index 673c7fbe945..d5a44bf473c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh @@ -29,6 +29,8 @@ #include "hb-aat-layout.hh" #include "hb-aat-map.hh" +#include "hb-ot-layout-common.hh" +#include "hb-ot-layout-gdef-table.hh" #include "hb-open-type.hh" #include "hb-cache.hh" #include "hb-bit-set.hh" @@ -48,6 +50,61 @@ struct ankr; using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; static_assert (sizeof (hb_aat_class_cache_t) == 256, ""); +struct hb_aat_scratch_t +{ + hb_aat_scratch_t () = default; + hb_aat_scratch_t (const hb_aat_scratch_t &) = delete; + + hb_aat_scratch_t (hb_aat_scratch_t &&o) + { + buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ()); + o.buffer_glyph_set.set_relaxed (nullptr); + } + hb_aat_scratch_t & operator = (hb_aat_scratch_t &&o) + { + buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ()); + o.buffer_glyph_set.set_relaxed (nullptr); + return *this; + } + ~hb_aat_scratch_t () + { + auto *s = buffer_glyph_set.get_relaxed (); + if (unlikely (!s)) + return; + s->fini (); + hb_free (s); + } + + hb_bit_set_t *create_buffer_glyph_set () const + { + hb_bit_set_t *s = buffer_glyph_set.get_acquire (); + if (s && buffer_glyph_set.cmpexch (s, nullptr)) + return s; + + s = (hb_bit_set_t *) hb_calloc (1, sizeof (hb_bit_set_t)); + if (unlikely (!s)) + return nullptr; + s->init (); + + return s; + } + void destroy_buffer_glyph_set (hb_bit_set_t *s) const + { + if (unlikely (!s)) + return; + if (buffer_glyph_set.cmpexch (nullptr, s)) + return; + s->fini (); + hb_free (s); + } + + mutable hb_atomic_t buffer_glyph_set; +}; + +enum { DELETED_GLYPH = 0xFFFF }; + +#define HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED HB_BUFFER_SCRATCH_FLAG_SHAPER0 + struct hb_aat_apply_context_t : hb_dispatch_context_t { @@ -64,10 +121,11 @@ struct hb_aat_apply_context_t : hb_buffer_t *buffer; hb_sanitize_context_t sanitizer; const ankr *ankr_table; - const OT::GDEF *gdef_table; + const OT::GDEF &gdef; + bool has_glyph_classes; const hb_sorted_vector_t *range_flags = nullptr; bool using_buffer_glyph_set = false; - hb_bit_set_t buffer_glyph_set; + hb_bit_set_t *buffer_glyph_set = nullptr; const hb_bit_set_t *left_set = nullptr; const hb_bit_set_t *right_set = nullptr; const hb_bit_set_t *machine_glyph_set = nullptr; @@ -90,15 +148,15 @@ struct hb_aat_apply_context_t : void setup_buffer_glyph_set () { - using_buffer_glyph_set = buffer->len >= 4; + using_buffer_glyph_set = buffer->len >= 4 && buffer_glyph_set; - if (using_buffer_glyph_set) - buffer->collect_codepoints (buffer_glyph_set); + if (likely (using_buffer_glyph_set)) + buffer->collect_codepoints (*buffer_glyph_set); } bool buffer_intersects_machine () const { - if (using_buffer_glyph_set) - return buffer_glyph_set.intersects (*machine_glyph_set); + if (likely (using_buffer_glyph_set)) + return buffer_glyph_set->intersects (*machine_glyph_set); // Faster for shorter buffers. for (unsigned i = 0; i < buffer->len; i++) @@ -106,6 +164,69 @@ struct hb_aat_apply_context_t : return true; return false; } + + template + HB_NODISCARD bool output_glyphs (unsigned int count, + const T *glyphs) + { + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add_array (glyphs, count); + for (unsigned int i = 0; i < count; i++) + { + if (glyphs[i] == DELETED_GLYPH) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + } + else + { +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->cur(), + gdef.get_glyph_props (glyphs[i])); +#endif + } + if (unlikely (!buffer->output_glyph (glyphs[i]))) return false; + } + return true; + } + + HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph) + { + if (glyph == DELETED_GLYPH) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + } + + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add (glyph); +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->cur(), + gdef.get_glyph_props (glyph)); +#endif + return buffer->replace_glyph (glyph); + } + + HB_NODISCARD bool delete_glyph () + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + return buffer->replace_glyph (DELETED_GLYPH); + } + + void replace_glyph_inplace (unsigned i, hb_codepoint_t glyph) + { + buffer->info[i].codepoint = glyph; + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add (glyph); +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->info[i], + gdef.get_glyph_props (glyph)); +#endif + } }; @@ -113,8 +234,6 @@ struct hb_aat_apply_context_t : * Lookup Table */ -enum { DELETED_GLYPH = 0xFFFF }; - template struct Lookup; template @@ -179,6 +298,7 @@ struct LookupSegmentSingle template void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const { + if (first == DELETED_GLYPH) return; if (!filter (value)) return; glyphs.add_range (first, last); } @@ -268,6 +388,7 @@ struct LookupSegmentArray template void collect_glyphs_filtered (set_t &glyphs, const void *base, const filter_t &filter) const { + if (first == DELETED_GLYPH) return; const auto &values = base+valuesZ; for (hb_codepoint_t i = first; i <= last; i++) if (filter (values[i - first])) @@ -368,6 +489,7 @@ struct LookupSingle template void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const { + if (glyph == DELETED_GLYPH) return; if (!filter (value)) return; glyphs.add (glyph); } @@ -746,6 +868,10 @@ struct StateTable } // And glyphs in those classes. + + if (filter (CLASS_DELETED_GLYPH)) + glyphs.add (DELETED_GLYPH); + (this+classTable).collect_glyphs_filtered (glyphs, num_glyphs, filter); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh index a091b05660c..ca4f2243346 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh @@ -185,6 +185,9 @@ struct Format1Entry DEFINE_SIZE_STATIC (2); }; + static bool initiateAction (const Entry &entry) + { return entry.flags & Push; } + static bool performAction (const Entry &entry) { return entry.data.kernActionIndex != 0xFFFF; } @@ -325,8 +328,9 @@ struct KerxSubTableFormat1 } else if (buffer->info[idx].mask & kern_mask) { - o.x_advance += c->font->em_scale_x (v); - o.x_offset += c->font->em_scale_x (v); + auto scaled = c->font->em_scale_x (v); + o.x_advance += scaled; + o.x_offset += scaled; } } else @@ -394,10 +398,8 @@ struct KerxSubTableFormat1 template void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const { - set_t set; - machine.collect_glyphs (set, num_glyphs); - left_set.union_ (set); - right_set.union_ (set); + machine.collect_initial_glyphs (left_set, num_glyphs, *this); + //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning } protected: @@ -671,10 +673,8 @@ struct KerxSubTableFormat4 template void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const { - set_t set; - machine.collect_glyphs (set, num_glyphs); - left_set.union_ (set); - right_set.union_ (set); + machine.collect_initial_glyphs (left_set, num_glyphs, *this); + //machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning } protected: @@ -921,7 +921,18 @@ struct KerxSubTable * The 'kerx' Table */ -using kern_accelerator_data_t = hb_vector_t>; +struct kern_subtable_accelerator_data_t +{ + hb_bit_set_t left_set; + hb_bit_set_t right_set; + mutable hb_aat_class_cache_t class_cache; +}; + +struct kern_accelerator_data_t +{ + hb_vector_t subtable_accels; + hb_aat_scratch_t scratch; +}; template struct KerxTable @@ -985,6 +996,8 @@ struct KerxTable { c->buffer->unsafe_to_concat (); + c->setup_buffer_glyph_set (); + typedef typename T::SubTable SubTable; bool ret = false; @@ -996,12 +1009,25 @@ struct KerxTable { bool reverse; + auto &subtable_accel = accel_data.subtable_accels[i]; + if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation)) goto skip; if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) goto skip; + c->left_set = &subtable_accel.left_set; + c->right_set = &subtable_accel.right_set; + c->machine_glyph_set = &subtable_accel.left_set; + c->machine_class_cache = &subtable_accel.class_cache; + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped subtable %u because no glyph matches", c->lookup_index); + goto skip; + } + reverse = bool (st->u.header.coverage & st->u.header.Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); @@ -1028,9 +1054,6 @@ struct KerxTable if (reverse) c->buffer->reverse (); - c->left_set = &accel_data[i].first; - c->right_set = &accel_data[i].second; - { /* See comment in sanitize() for conditional here. */ hb_sanitize_with_object_t with (&c->sanitizer, i < count - 1 ? st : (const SubTable *) nullptr); @@ -1106,9 +1129,13 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - hb_bit_set_t left_set, right_set; - st->collect_glyphs (left_set, right_set, num_glyphs); - accel_data.push (hb_pair (left_set, right_set)); + auto &subtable_accel = *accel_data.subtable_accels.push (); + if (unlikely (accel_data.subtable_accels.in_error ())) + return accel_data; + + st->collect_glyphs (subtable_accel.left_set, subtable_accel.right_set, num_glyphs); + subtable_accel.class_cache.clear (); + st = &StructAfter (*st); } @@ -1137,6 +1164,7 @@ struct KerxTable hb_blob_ptr_t table; kern_accelerator_data_t accel_data; + hb_aat_scratch_t scratch; }; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh index cabdc0eb555..92b07eec6e5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh @@ -30,8 +30,6 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" #include "hb-ot-layout.hh" -#include "hb-ot-layout-common.hh" -#include "hb-ot-layout-gdef-table.hh" #include "hb-aat-map.hh" /* @@ -178,12 +176,6 @@ struct RearrangementSubtable StateTableDriver driver (machine, c->face); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - driver.drive (&dc, c); return_trace (dc.ret); @@ -242,9 +234,7 @@ struct ContextualSubtable ret (false), c (c_), table (table_), - gdef (*c->gdef_table), mark_set (false), - has_glyph_classes (gdef.has_glyph_classes ()), mark (0), subs (table+table->substitutionTables) {} @@ -281,12 +271,7 @@ struct ContextualSubtable if (replacement) { buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); - hb_codepoint_t glyph = *replacement; - buffer->info[mark].codepoint = glyph; - c->buffer_glyph_set.add (glyph); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&buffer->info[mark], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (mark, *replacement); ret = true; } @@ -312,12 +297,7 @@ struct ContextualSubtable } if (replacement) { - hb_codepoint_t glyph = *replacement; - buffer->info[idx].codepoint = glyph; - c->buffer_glyph_set.add (glyph); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&buffer->info[idx], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (idx, *replacement); ret = true; } @@ -333,9 +313,7 @@ struct ContextualSubtable hb_aat_apply_context_t *c; const ContextualSubtable *table; private: - const OT::GDEF &gdef; bool mark_set; - bool has_glyph_classes; unsigned int mark; const UnsizedListOfOffset16To, HBUINT, void, false> &subs; }; @@ -348,12 +326,6 @@ struct ContextualSubtable StateTableDriver driver (machine, c->face); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - driver.drive (&dc, c); return_trace (dc.ret); @@ -581,7 +553,7 @@ struct LigatureSubtable hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); - if (unlikely (!buffer->replace_glyph (lig))) return; + if (unlikely (!c->replace_glyph (lig))) return; unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u; /* Now go and delete all subsequent components. */ @@ -589,8 +561,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; - _hb_glyph_info_set_default_ignorable (&buffer->cur()); - if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; + if (!c->delete_glyph ()) return; } if (unlikely (!buffer->move_to (lig_end))) return; @@ -624,12 +595,6 @@ struct LigatureSubtable StateTableDriver driver (machine, c->face); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - driver.drive (&dc, c); return_trace (dc.ret); @@ -665,15 +630,6 @@ struct NoncontextualSubtable { TRACE_APPLY (this); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - - const OT::GDEF &gdef (*c->gdef_table); - bool has_glyph_classes = gdef.has_glyph_classes (); - bool ret = false; unsigned int num_glyphs = c->face->get_num_glyphs (); @@ -703,12 +659,7 @@ struct NoncontextualSubtable const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs); if (replacement) { - hb_codepoint_t glyph = *replacement; - info[i].codepoint = glyph; - c->buffer_glyph_set.add (glyph); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&info[i], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (i, *replacement); ret = true; } } @@ -850,9 +801,7 @@ struct InsertionSubtable if (buffer->idx < buffer->len && !before) if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; - for (unsigned int i = 0; i < count; i++) - c->buffer_glyph_set.add (glyphs[i]); + if (unlikely (!c->output_glyphs (count, glyphs))) return; ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -881,7 +830,8 @@ struct InsertionSubtable if (buffer->idx < buffer->len && !before) if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; + if (unlikely (!c->output_glyphs (count, glyphs))) return; + ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -921,12 +871,6 @@ struct InsertionSubtable StateTableDriver driver (machine, c->face); - if (!c->buffer_intersects_machine ()) - { - (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); - return_trace (false); - } - driver.drive (&dc, c); return_trace (dc.ret); @@ -1224,6 +1168,7 @@ struct Chain if (hb_none (hb_iter (c->range_flags) | hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; + c->subtable_flags = subtable_flags; c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; @@ -1233,6 +1178,12 @@ struct Chain bool (coverage & ChainSubtable::Vertical)) goto skip; + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable %u because no glyph matches", c->lookup_index); + goto skip; + } + /* Buffer contents is always in logical direction. Determine if * we need to reverse before applying this subtable. We reverse * back after if we did reverse indeed. @@ -1376,7 +1327,7 @@ struct mortmorx this->chain_count = table->get_chain_count (); - this->accels = (hb_atomic_ptr_t *) hb_calloc (this->chain_count, sizeof (*accels)); + this->accels = (hb_atomic_t *) hb_calloc (this->chain_count, sizeof (*accels)); if (unlikely (!this->accels)) { this->chain_count = 0; @@ -1423,7 +1374,8 @@ struct mortmorx hb_blob_ptr_t table; unsigned int chain_count; - hb_atomic_ptr_t *accels; + hb_atomic_t *accels; + hb_aat_scratch_t scratch; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh index 0db4035fd8c..4ee73ecee69 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh @@ -31,6 +31,7 @@ #include "hb-aat-layout-common.hh" #include "hb-ot-layout.hh" #include "hb-open-type.hh" +#include "hb-ot-stat-table.hh" /* * trak -- Tracking @@ -115,7 +116,7 @@ struct TrackTableEntry protected: F16DOT16 track; /* Track value for this record. */ - NameID trackNameID; /* The 'name' table index for this track. + OT::NameID trackNameID; /* The 'name' table index for this track. * (a short word or phrase like "loose" * or "very tight") */ NNOffset16To> @@ -142,9 +143,9 @@ struct TrackData unsigned j = count - 1; // Find the two entries that track is between. - while (i + 1 < count && trackTable[i + 1].get_track_value () < track) + while (i + 1 < count && trackTable[i + 1].get_track_value () <= track) i++; - while (j > 0 && trackTable[j - 1].get_track_value () > track) + while (j > 0 && trackTable[j - 1].get_track_value () >= track) j--; // Exact match. @@ -200,6 +201,46 @@ struct trak float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; return font->em_scalef_y ((this+vertData).get_tracking (this, ptem, track)); } + hb_position_t get_tracking (hb_font_t *font, hb_direction_t dir, float track = 0.f) const + { +#ifndef HB_NO_STYLE + if (!font->face->table.STAT->has_data ()) + return 0; + return HB_DIRECTION_IS_HORIZONTAL (dir) ? + get_h_tracking (font, track) : + get_v_tracking (font, track); +#else + return 0; +#endif + } + + bool apply (hb_aat_apply_context_t *c, float track = 0.f) const + { + TRACE_APPLY (this); + + float ptem = c->font->ptem; + if (unlikely (ptem <= 0.f)) + { + /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ + ptem = HB_CORETEXT_DEFAULT_FONT_SIZE; + } + + hb_buffer_t *buffer = c->buffer; + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + { + hb_position_t advance_to_add = get_h_tracking (c->font, track); + foreach_grapheme (buffer, start, end) + buffer->pos[start].x_advance += advance_to_add; + } + else + { + hb_position_t advance_to_add = get_v_tracking (c->font, track); + foreach_grapheme (buffer, start, end) + buffer->pos[start].y_advance += advance_to_add; + } + + return_trace (true); + } bool sanitize (hb_sanitize_context_t *c) const { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc index 2cc94257aa7..b349c3026b6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc @@ -34,7 +34,7 @@ #include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" -#include "hb-aat-layout-trak-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-layout-trak-table.hh" #include "hb-aat-ltag-table.hh" #include "hb-ot-layout-gsub-table.hh" @@ -58,13 +58,14 @@ AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *p buffer (buffer_), sanitizer (), ankr_table (&Null (AAT::ankr)), - gdef_table ( + gdef ( #ifndef HB_NO_OT_LAYOUT - face->table.GDEF->table + *face->table.GDEF->table #else - &Null (GDEF) + Null (GDEF) #endif ), + has_glyph_classes (gdef.has_glyph_classes ()), lookup_index (0) { sanitizer.init (blob); @@ -203,7 +204,7 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) #endif -#ifndef HB_NO_AAT +#ifndef HB_NO_AAT_SHAPE /* * mort/morx/kerx/trak @@ -287,11 +288,14 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, const hb_feature_t *features, unsigned num_features) { - hb_aat_map_builder_t builder (font->face, plan->props); - for (unsigned i = 0; i < num_features; i++) - builder.add_feature (features[i]); hb_aat_map_t map; - builder.compile (map); + if (num_features) + { + hb_aat_map_builder_t builder (font->face, plan->props); + for (unsigned i = 0; i < num_features; i++) + builder.add_feature (features[i]); + builder.compile (map); + } { auto &accel = *font->face->table.morx; @@ -300,7 +304,10 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, { AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table morx")) return; - morx.apply (&c, map, accel); + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); + morx.apply (&c, num_features ? map : plan->aat_map, accel); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); + c.buffer_glyph_set = nullptr; (void) buffer->message (font, "end table morx"); return; } @@ -313,34 +320,24 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, { AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table mort")) return; - mort.apply (&c, map, accel); + mort.apply (&c, num_features ? map : plan->aat_map, accel); (void) buffer->message (font, "end table mort"); return; } } } -void -hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer) -{ - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - for (unsigned int i = 0; i < count; i++) - if (unlikely (info[i].codepoint == AAT::DELETED_GLYPH)) - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; -} - static bool is_deleted_glyph (const hb_glyph_info_t *info) { - return info->codepoint == AAT::DELETED_GLYPH; + return _hb_glyph_info_is_aat_deleted (info); } void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) { - buffer->delete_glyphs_inplace (is_deleted_glyph); + if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED) + buffer->delete_glyphs_inplace (is_deleted_glyph); } /** @@ -371,8 +368,11 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table kerx")) return; + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); c.set_ankr_table (font->face->table.ankr.get ()); accel.apply (&c); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); + c.buffer_glyph_set = nullptr; (void) buffer->message (font, "end table kerx"); } @@ -394,6 +394,17 @@ hb_aat_layout_has_tracking (hb_face_t *face) return face->table.trak->has_data (); } +void +hb_aat_layout_track (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + const AAT::trak& trak = *font->face->table.trak; + + AAT::hb_aat_apply_context_t c (plan, font, buffer); + trak.apply (&c); +} + /** * hb_aat_layout_get_feature_types: * @face: #hb_face_t to work upon diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh index ee33223651a..ffa54408ebf 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh @@ -60,9 +60,6 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, const hb_feature_t *features, unsigned num_features); -HB_INTERNAL void -hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer); - HB_INTERNAL void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer); @@ -71,5 +68,10 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); +HB_INTERNAL void +hb_aat_layout_track (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + #endif /* HB_AAT_LAYOUT_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc b/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc index e0e9d14d9b8..306a95b7c4b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc @@ -85,6 +85,11 @@ void hb_aat_map_builder_t::compile (hb_aat_map_t &m) { /* Compute active features per range, and compile each. */ + if (!features.length) + { + hb_aat_layout_compile_map (this, &m); + return; + } /* Sort features by start/end events. */ hb_vector_t feature_events; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh index d2de5f693f0..80bd90e87dc 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh @@ -80,15 +80,14 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #include -#define _hb_memory_barrier() std::atomic_thread_fence(std::memory_order_ack_rel) #define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire) #define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release) -#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) -#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) -#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) -#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) +#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) +#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) +#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) +#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) +#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) #define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast *> (P)->store ((V), std::memory_order_relaxed)) #define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast const *> (P)->load (std::memory_order_relaxed)) @@ -149,68 +148,53 @@ static inline void _hb_compiler_memory_r_barrier () {} #define hb_atomic_ptr_impl_get_relaxed(P) (*(P)) #endif #ifndef hb_atomic_int_impl_set -inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; } -inline void hb_atomic_int_impl_set (short *AI, short v) { _hb_memory_w_barrier (); *AI = v; } +template +inline void hb_atomic_int_impl_set (T *AI, T v) { _hb_memory_w_barrier (); *AI = v; } #endif #ifndef hb_atomic_int_impl_get -inline int hb_atomic_int_impl_get (const int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; } -inline short hb_atomic_int_impl_get (const short *AI) { short v = *AI; _hb_memory_r_barrier (); return v; } +template +inline T hb_atomic_int_impl_get (const T *AI) { T v = *AI; _hb_memory_r_barrier (); return v; } #endif #ifndef hb_atomic_ptr_impl_get inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; } #endif -struct hb_atomic_short_t +template +struct hb_atomic_t { - hb_atomic_short_t () = default; - constexpr hb_atomic_short_t (short v) : v (v) {} + hb_atomic_t () = default; + constexpr hb_atomic_t (T v) : v (v) {} - hb_atomic_short_t& operator = (short v_) { set_relaxed (v_); return *this; } - operator short () const { return get_relaxed (); } + hb_atomic_t& operator = (T v_) { set_relaxed (v_); return *this; } + operator T () const { return get_relaxed (); } - void set_relaxed (short v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } - void set_release (short v_) { hb_atomic_int_impl_set (&v, v_); } - short get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } - short get_acquire () const { return hb_atomic_int_impl_get (&v); } - short inc () { return hb_atomic_int_impl_add (&v, 1); } - short dec () { return hb_atomic_int_impl_add (&v, -1); } + void set_relaxed (T v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } + void set_release (T v_) { hb_atomic_int_impl_set (&v, v_); } + T get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } + T get_acquire () const { return hb_atomic_int_impl_get (&v); } + T inc () { return hb_atomic_int_impl_add (&v, 1); } + T dec () { return hb_atomic_int_impl_add (&v, -1); } - short v = 0; -}; - -struct hb_atomic_int_t -{ - hb_atomic_int_t () = default; - constexpr hb_atomic_int_t (int v) : v (v) {} + int operator ++ (int) { return inc (); } + int operator -- (int) { return dec (); } + long operator |= (long v_) { set_relaxed (get_relaxed () | v_); return *this; } - hb_atomic_int_t& operator = (int v_) { set_relaxed (v_); return *this; } - operator int () const { return get_relaxed (); } - - void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } - void set_release (int v_) { hb_atomic_int_impl_set (&v, v_); } - int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } - int get_acquire () const { return hb_atomic_int_impl_get (&v); } - int inc () { return hb_atomic_int_impl_add (&v, 1); } - int dec () { return hb_atomic_int_impl_add (&v, -1); } - - int v = 0; + T v = 0; }; -template -struct hb_atomic_ptr_t +template +struct hb_atomic_t { - typedef hb_remove_pointer

T; - - hb_atomic_ptr_t () = default; - constexpr hb_atomic_ptr_t (T* v) : v (v) {} - hb_atomic_ptr_t (const hb_atomic_ptr_t &other) = delete; + hb_atomic_t () = default; + constexpr hb_atomic_t (T* v) : v (v) {} + hb_atomic_t (const hb_atomic_t &other) = delete; void init (T* v_ = nullptr) { set_relaxed (v_); } 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/java.desktop/share/native/libharfbuzz/hb-bit-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh index c42e617f67a..799c3607599 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh @@ -77,7 +77,7 @@ struct hb_bit_set_t bool successful = true; /* Allocations successful */ mutable unsigned int population = 0; - mutable hb_atomic_int_t last_page_lookup = 0; + mutable hb_atomic_t last_page_lookup = 0; hb_sorted_vector_t page_map; hb_vector_t pages; @@ -88,7 +88,7 @@ struct hb_bit_set_t { if (unlikely (!successful)) return false; - if (pages.length < count && count <= 2) + if (pages.length < count && (unsigned) pages.allocated < count && count <= 2) exact_size = true; // Most sets are small and local if (unlikely (!pages.resize (count, clear, exact_size) || diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-vector.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-vector.hh new file mode 100644 index 00000000000..2a0ec3a0710 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-vector.hh @@ -0,0 +1,195 @@ +/* + * 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 + */ + +#ifndef HB_BIT_VECTOR_HH +#define HB_BIT_VECTOR_HH + +#include "hb.hh" + +#include "hb-atomic.hh" + +struct hb_min_max_t +{ + void add (hb_codepoint_t v) { min_v = hb_min (min_v, v); max_v = hb_max (max_v, v); } + void add_range (hb_codepoint_t a, hb_codepoint_t b) + { + min_v = hb_min (min_v, a); + max_v = hb_max (max_v, b); + } + + template + void union_ (const set_t &set) + { + hb_codepoint_t set_min = set.get_min (); + if (unlikely (set_min == HB_CODEPOINT_INVALID)) + return; + hb_codepoint_t set_max = set.get_max (); + min_v = hb_min (min_v, set_min); + max_v = hb_max (max_v, set_max); + } + + hb_codepoint_t get_min () const { return min_v; } + hb_codepoint_t get_max () const { return max_v; } + + private: + hb_codepoint_t min_v = HB_CODEPOINT_INVALID; + hb_codepoint_t max_v = 0; +}; + +template +struct hb_bit_vector_t +{ + using int_t = uint64_t; + using elt_t = typename std::conditional, int_t>::type; + + hb_bit_vector_t () = delete; + hb_bit_vector_t (const hb_bit_vector_t &other) = delete; + hb_bit_vector_t &operator= (const hb_bit_vector_t &other) = delete; + + // Move + hb_bit_vector_t (hb_bit_vector_t &&other) + : min_v (other.min_v), max_v (other.max_v), count (other.count), elts (other.elts) + { + other.min_v = other.max_v = other.count = 0; + other.elts = nullptr; + } + hb_bit_vector_t &operator= (hb_bit_vector_t &&other) + { + hb_swap (min_v, other.min_v); + hb_swap (max_v, other.max_v); + hb_swap (count, other.count); + hb_swap (elts, other.elts); + return *this; + } + + hb_bit_vector_t (unsigned min_v, unsigned max_v) + : min_v (min_v), max_v (max_v) + { + if (unlikely (min_v >= max_v)) + { + min_v = max_v = count = 0; + return; + } + + unsigned num = (max_v - min_v + sizeof (int_t) * 8) / (sizeof (int_t) * 8); + elts = (elt_t *) hb_calloc (num, sizeof (int_t)); + if (unlikely (!elts)) + { + min_v = max_v = count = 0; + return; + } + + count = max_v - min_v + 1; + } + ~hb_bit_vector_t () + { + hb_free (elts); + } + + void add (hb_codepoint_t g) { elt (g) |= mask (g); } + void del (hb_codepoint_t g) { elt (g) &= ~mask (g); } + void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); } + bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } + bool has (hb_codepoint_t g) const { return get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } + + bool operator [] (hb_codepoint_t g) const { return get (g); } + bool operator () (hb_codepoint_t g) const { return get (g); } + + void add_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (!count || a > b || a < min_v || b > max_v)) + return; + + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la |= (mask (b) << 1) - mask(a); + else + { + *la |= ~(mask (a) - 1llu); + la++; + + hb_memset (la, 0xff, (char *) lb - (char *) la); + + *lb |= ((mask (b) << 1) - 1llu); + } + } + void del_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (!count || a > b || a < min_v || b > max_v)) + return; + + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la &= ~((mask (b) << 1llu) - mask(a)); + else + { + *la &= mask (a) - 1; + la++; + + hb_memset (la, 0, (char *) lb - (char *) la); + + *lb &= ~((mask (b) << 1) - 1llu); + } + } + void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v) + { if (v) add_range (a, b); else del_range (a, b); } + + template + void union_ (const set_t &set) + { + for (hb_codepoint_t g : set) + add (g); + } + + static const unsigned int ELT_BITS = sizeof (elt_t) * 8; + static constexpr unsigned ELT_MASK = ELT_BITS - 1; + + static constexpr elt_t zero = 0; + + elt_t &elt (hb_codepoint_t g) + { + g -= min_v; + if (unlikely (g >= count)) + return Crap(elt_t); + return elts[g / ELT_BITS]; + } + const elt_t& elt (hb_codepoint_t g) const + { + g -= min_v; + if (unlikely (g >= count)) + return Null(elt_t); + return elts[g / ELT_BITS]; + } + + static constexpr int_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); } + + hb_codepoint_t min_v = 0, max_v = 0, count = 0; + elt_t *elts = nullptr; +}; + + +#endif /* HB_BIT_VECTOR_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh index 69cc1640230..255497b652d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh @@ -32,62 +32,68 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-json.hh" +#line 33 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, - 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, - 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, - 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, - 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 93u, 9u, 123u, 0u, 0u, 0 + 0u, 0u, 9u, 34u, 97u, 121u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, + 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, + 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, + 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, + 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, + 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 98u, 98u, 9u, 123u, 9u, 123u, 9u, 123u, + 0 }; static const char _deserialize_json_key_spans[] = { - 0, 115, 115, 26, 21, 2, 1, 50, - 49, 10, 117, 117, 117, 1, 50, 49, - 10, 117, 117, 1, 1, 50, 49, 117, - 117, 2, 1, 50, 49, 10, 117, 117, - 1, 50, 49, 10, 117, 117, 1, 1, - 50, 49, 117, 117, 1, 50, 49, 59, - 117, 59, 117, 117, 1, 50, 49, 117, - 85, 115, 0 + 0, 26, 25, 2, 1, 50, 49, 10, + 117, 117, 85, 117, 1, 50, 49, 10, + 117, 117, 1, 1, 50, 49, 117, 117, + 2, 1, 50, 49, 10, 117, 117, 1, + 50, 49, 10, 117, 117, 1, 1, 50, + 49, 117, 117, 1, 50, 49, 59, 117, + 59, 117, 117, 1, 50, 49, 10, 117, + 1, 50, 49, 117, 1, 115, 115, 115 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 232, 259, 281, 284, 286, - 337, 387, 398, 516, 634, 752, 754, 805, - 855, 866, 984, 1102, 1104, 1106, 1157, 1207, - 1325, 1443, 1446, 1448, 1499, 1549, 1560, 1678, - 1796, 1798, 1849, 1899, 1910, 2028, 2146, 2148, - 2150, 2201, 2251, 2369, 2487, 2489, 2540, 2590, - 2650, 2768, 2828, 2946, 3064, 3066, 3117, 3167, - 3285, 3371, 3487 + 0, 0, 27, 53, 56, 58, 109, 159, + 170, 288, 406, 492, 610, 612, 663, 713, + 724, 842, 960, 962, 964, 1015, 1065, 1183, + 1301, 1304, 1306, 1357, 1407, 1418, 1536, 1654, + 1656, 1707, 1757, 1768, 1886, 2004, 2006, 2008, + 2059, 2109, 2227, 2345, 2347, 2398, 2448, 2508, + 2626, 2686, 2804, 2922, 2924, 2975, 3025, 3036, + 3154, 3156, 3207, 3257, 3375, 3377, 3493, 3609 }; static const char _deserialize_json_indicies[] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 2, 1, 3, 1, 4, 5, + 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 9, 1, 8, 10, 10, 1, 11, 12, + 1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 14, 1, 14, 14, + 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 2, 2, 2, - 2, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 15, 1, 1, 16, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 1, + 18, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 1, 20, 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 20, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -95,48 +101,41 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, - 1, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 5, 1, 6, 1, 7, 8, - 1, 9, 10, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 22, + 1, 23, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 11, 1, 12, 13, 1, 14, 1, 14, - 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 14, 1, + 23, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 15, 1, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 15, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 16, 1, - 1, 17, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 1, 19, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 1, 21, - 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 24, 1, 24, + 24, 24, 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 23, 1, 24, 24, 24, - 24, 24, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 25, 1, 20, 20, 20, + 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 24, 1, 1, 1, + 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 1, 1, 1, 1, 1, 1, + 21, 1, 1, 1, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -145,43 +144,42 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 22, 1, 26, 1, 26, 26, 26, + 26, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 25, 1, 21, 21, 21, 21, 21, + 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 21, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 22, 1, - 1, 1, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 27, 1, + 27, 27, 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 28, 1, 1, 29, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 1, 31, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 1, 33, 33, 33, + 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 23, - 1, 26, 1, 26, 26, 26, 26, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 27, 1, 27, 27, - 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 28, 1, 1, 29, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 1, - 31, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 1, 33, 33, 33, 33, 33, + 1, 35, 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 34, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -190,39 +188,41 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 35, - 1, 33, 33, 33, 33, 33, 1, 1, + 1, 36, 1, 37, 1, 37, 37, 37, + 37, 37, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 33, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 34, 1, 1, 1, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 38, 1, + 38, 38, 38, 38, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 38, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 39, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 1, 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 41, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 35, 1, 36, - 1, 37, 1, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 38, 1, 38, 38, - 38, 38, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 39, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 1, + 1, 1, 1, 1, 1, 1, 43, 1, 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 42, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -230,43 +230,43 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 43, 1, 45, 46, + 1, 47, 1, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 43, 1, 41, 41, - 41, 41, 41, 1, 1, 1, 1, 1, + 1, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 42, 1, 1, 1, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 1, + 1, 1, 1, 1, 48, 1, 48, 48, + 48, 48, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 49, 1, 1, 50, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 1, + 52, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 54, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 43, 1, 45, 46, 1, 47, - 1, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 48, 1, 48, 48, 48, 48, - 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 48, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 49, 1, 1, 50, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 1, 52, 53, - 53, 53, 53, 53, 53, 53, 53, 53, + 1, 1, 1, 1, 1, 1, 1, 56, 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 1, 1, 1, + 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -274,44 +274,42 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 56, 1, 57, + 1, 57, 57, 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 56, 1, 54, - 54, 54, 54, 54, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 54, 1, + 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 55, 1, 1, 1, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 58, 1, 58, 58, 58, 58, + 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 59, 1, 1, 60, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 1, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 1, 64, 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 64, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 56, 1, 57, 1, 57, - 57, 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 58, 1, 58, 58, 58, 58, 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 58, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 59, 1, - 1, 60, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 1, 62, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 1, 64, + 1, 1, 1, 1, 1, 66, 1, 64, 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 65, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 65, 1, 1, 1, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -320,39 +318,41 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 66, 1, 64, 64, 64, - 64, 64, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 66, 1, 67, 1, 68, + 1, 68, 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 65, 1, 1, 1, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 1, 1, + 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 69, 1, 69, 69, 69, 69, + 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 70, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 1, 72, 72, + 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 66, 1, 67, 1, 68, 1, 68, - 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 69, 1, 69, 69, 69, 69, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 70, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 1, 72, 72, 72, 72, + 1, 1, 74, 1, 72, 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 73, + 1, 1, 1, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -361,71 +361,70 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 74, 1, 76, 1, 76, 76, 76, 76, + 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 74, 1, 72, 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 77, 1, 77, + 77, 77, 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 72, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 73, 1, 1, - 1, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 77, 1, + 78, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 79, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 1, 82, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 83, 81, 84, 84, 84, + 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 74, 1, - 76, 1, 76, 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 77, 1, 77, 77, 77, - 77, 77, 1, 1, 1, 1, 1, 1, + 1, 86, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 78, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 79, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 1, 82, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, - 81, 83, 81, 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 84, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 81, 1, 87, + 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 86, - 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 81, 1, 87, 87, 87, + 1, 1, 1, 89, 1, 87, 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 88, 1, 1, 1, 1, 1, 1, 1, + 88, 1, 1, 1, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -434,118 +433,151 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 89, 1, 91, 1, 91, 91, 91, + 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 89, 1, 87, 87, 87, 87, 87, + 1, 1, 1, 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 87, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 88, 1, - 1, 1, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 92, 1, + 92, 92, 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 93, 1, 1, 94, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 1, 23, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 1, 23, 23, 23, + 23, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 89, - 1, 91, 1, 91, 91, 91, 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 92, 1, 92, 92, - 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 92, 1, 1, + 1, 24, 1, 97, 1, 97, 97, 97, + 97, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 93, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 1, - 87, 87, 87, 87, 87, 1, 1, 1, + 1, 1, 1, 1, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 88, 1, 1, 1, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 98, 1, + 98, 98, 98, 98, 98, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 98, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 99, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 1, 87, 87, 87, 87, 87, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 87, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 88, 1, 1, + 1, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 89, 1, + 8, 1, 102, 102, 102, 102, 102, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 102, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 103, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 89, 1, 96, 96, - 96, 96, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 97, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 104, 1, 103, 103, + 103, 103, 103, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 103, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 98, 1, 2, 2, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 104, 1, 25, 25, 25, 25, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, - 1, 0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 104, 1, 0 }; static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 3, 3, 4, 5, 19, - 25, 38, 44, 52, 6, 13, 7, 8, - 9, 10, 12, 10, 12, 11, 3, 56, - 11, 56, 14, 15, 16, 17, 18, 17, - 18, 11, 3, 56, 20, 21, 22, 23, - 24, 11, 3, 56, 24, 26, 32, 27, - 28, 29, 30, 31, 30, 31, 11, 3, - 56, 33, 34, 35, 36, 37, 36, 37, - 11, 3, 56, 39, 40, 41, 42, 43, - 11, 3, 56, 43, 45, 46, 47, 50, - 51, 47, 48, 49, 11, 3, 56, 11, - 3, 56, 51, 53, 54, 50, 55, 55, - 56, 57, 58 + 1, 0, 2, 3, 18, 24, 37, 43, + 51, 56, 60, 4, 12, 5, 6, 7, + 8, 11, 8, 11, 9, 1, 10, 9, + 10, 63, 13, 14, 15, 16, 17, 16, + 17, 9, 1, 10, 19, 20, 21, 22, + 23, 9, 1, 10, 23, 25, 31, 26, + 27, 28, 29, 30, 29, 30, 9, 1, + 10, 32, 33, 34, 35, 36, 35, 36, + 9, 1, 10, 38, 39, 40, 41, 42, + 9, 1, 10, 42, 44, 45, 46, 49, + 50, 46, 47, 48, 9, 1, 10, 9, + 1, 10, 50, 52, 53, 54, 9, 55, + 55, 57, 58, 49, 59, 59, 61, 62, + 1 }; static const char _deserialize_json_trans_actions[] = { - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 0, 0, 3, 3, 4, - 0, 5, 0, 0, 2, 2, 2, 0, - 0, 6, 6, 7, 0, 0, 0, 2, - 2, 8, 8, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 0, 0, 10, 10, - 11, 0, 0, 2, 2, 2, 0, 0, - 12, 12, 13, 0, 0, 0, 2, 2, - 14, 14, 15, 0, 0, 0, 2, 16, - 16, 0, 17, 0, 18, 18, 19, 20, - 20, 21, 17, 0, 0, 22, 22, 23, - 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 2, 2, 2, 0, + 0, 3, 0, 0, 1, 1, 1, 0, + 0, 4, 4, 4, 0, 0, 0, 1, + 1, 5, 5, 5, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 6, 6, + 6, 0, 0, 1, 1, 1, 0, 0, + 7, 7, 7, 0, 0, 0, 1, 1, + 8, 8, 8, 0, 0, 0, 1, 9, + 9, 0, 10, 0, 11, 11, 11, 12, + 12, 12, 10, 0, 0, 1, 1, 1, + 0, 0, 0, 13, 13, 14, 0, 0, + 15 }; -static const int deserialize_json_start = 1; -static const int deserialize_json_first_final = 56; +static const int deserialize_json_start = 61; +static const int deserialize_json_first_final = 61; static const int deserialize_json_error = 0; -static const int deserialize_json_en_main = 1; +static const int deserialize_json_en_main = 61; -#line 111 "hb-buffer-deserialize-json.rl" +#line 115 "hb-buffer-deserialize-json.rl" static hb_bool_t @@ -565,12 +597,12 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 569 "hb-buffer-deserialize-json.hh" +#line 594 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 574 "hb-buffer-deserialize-json.hh" +#line 597 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -595,14 +627,14 @@ _resume: goto _again; switch ( _deserialize_json_trans_actions[_trans] ) { - case 1: + case 15: #line 38 "hb-buffer-deserialize-json.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } break; - case 5: + case 3: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); @@ -612,21 +644,21 @@ _resume: *end_ptr = p; } break; - case 2: + case 1: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; } break; - case 17: + case 10: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 23: + case 14: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 18: + case 11: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ @@ -636,35 +668,35 @@ _resume: return false; } break; - case 20: + case 12: #line 66 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.codepoint)) return false; } break; - case 8: + case 5: #line 67 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; - case 10: + case 6: #line 68 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; - case 12: + case 7: #line 69 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 3: + case 2: #line 70 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 6: + case 4: #line 71 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; - case 14: + case 8: #line 72 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.mask )) return false; } break; - case 16: + case 9: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -672,7 +704,7 @@ _resume: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 22: + case 13: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -680,109 +712,7 @@ _resume: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 19: -#line 58 "hb-buffer-deserialize-json.rl" - { - /* TODO Unescape \" and \\ if found. */ - if (!hb_font_glyph_from_string (font, - tok+1, p - tok - 2, /* Skip "" */ - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 21: -#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 68 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 69 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 4: -#line 70 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 7: -#line 71 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 15: -#line 72 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 786 "hb-buffer-deserialize-json.hh" +#line 689 "hb-buffer-deserialize-json.hh" } _again: @@ -794,12 +724,12 @@ _again: _out: {} } -#line 132 "hb-buffer-deserialize-json.rl" +#line 136 "hb-buffer-deserialize-json.rl" *end_ptr = p; - return p == pe && *(p-1) != ']'; + return p == pe; } #endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh index 8e526ce4e2a..78570486376 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh @@ -32,287 +32,344 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text-glyphs.hh" +#line 33 "hb-buffer-deserialize-text-glyphs.hh" static const unsigned char _deserialize_text_glyphs_trans_keys[] = { - 0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, - 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 0 + 0u, 0u, 35u, 124u, 48u, 57u, 60u, 124u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, + 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 62u, 62u, + 93u, 124u, 45u, 57u, 48u, 57u, 35u, 124u, 45u, 57u, 48u, 57u, 35u, 124u, 35u, 124u, + 35u, 124u, 35u, 124u, 35u, 124u, 35u, 124u, 48u, 57u, 35u, 124u, 45u, 57u, 48u, 57u, + 44u, 44u, 45u, 57u, 48u, 57u, 35u, 124u, 35u, 124u, 44u, 57u, 35u, 124u, 43u, 124u, + 35u, 124u, 48u, 62u, 44u, 57u, 44u, 57u, 44u, 57u, 48u, 124u, 35u, 124u, 35u, 124u, + 35u, 124u, 0 }; static const char _deserialize_text_glyphs_key_spans[] = { - 0, 10, 13, 10, 13, 10, 10, 13, - 10, 1, 13, 10, 14, 82, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116 + 0, 90, 10, 65, 13, 10, 1, 13, + 10, 1, 13, 10, 1, 13, 10, 1, + 32, 13, 10, 90, 13, 10, 90, 90, + 90, 90, 90, 90, 10, 90, 13, 10, + 1, 13, 10, 90, 90, 14, 90, 82, + 90, 15, 14, 14, 14, 77, 90, 90, + 90 }; static const short _deserialize_text_glyphs_index_offsets[] = { - 0, 0, 11, 25, 36, 50, 61, 72, - 86, 97, 99, 113, 124, 139, 222, 339, - 456, 573, 690, 807, 924, 1041, 1158, 1275, - 1392, 1509, 1626 + 0, 0, 91, 102, 168, 182, 193, 195, + 209, 220, 222, 236, 247, 249, 263, 274, + 276, 309, 323, 334, 425, 439, 450, 541, + 632, 723, 814, 905, 996, 1007, 1098, 1112, + 1123, 1125, 1139, 1150, 1241, 1332, 1347, 1438, + 1521, 1612, 1628, 1643, 1658, 1673, 1751, 1842, + 1933 }; static const char _deserialize_text_glyphs_indicies[] = { - 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 1, 3, 1, 1, 4, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 1, 6, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 1, 8, 1, 1, - 9, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 1, 11, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 1, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 1, 15, 1, 1, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 1, 18, + 1, 0, 0, 0, 0, 0, 0, + 0, 2, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 3, 11, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 12, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 12, + 3, 13, 3, 3, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 3, 14, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 3, 16, 3, 17, 3, 3, 18, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 1, 20, 1, 21, 1, 1, 22, - 23, 23, 23, 23, 23, 23, 23, 23, - 23, 1, 24, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 1, 20, 1, 1, - 1, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 1, 26, 26, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 26, 1, - 1, 26, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 26, 26, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 26, 1, 28, - 28, 28, 28, 28, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 28, 27, - 27, 29, 27, 27, 27, 27, 27, 27, - 27, 30, 1, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 31, 27, 27, 32, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 33, 1, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 28, 27, 34, 34, 34, 34, - 34, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 34, 26, 26, 35, 26, - 26, 26, 26, 26, 26, 26, 36, 1, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 37, 26, 26, 38, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 39, - 1, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 40, - 26, 41, 41, 41, 41, 41, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 41, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 42, 1, 43, 43, - 43, 43, 43, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 43, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 44, 1, 41, 41, 41, 41, 41, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 41, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 42, 1, - 46, 46, 46, 46, 46, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 46, - 1, 1, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 48, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 49, 1, 50, 50, 50, - 50, 50, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 1, 51, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 52, 1, 50, 50, 50, 50, 50, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 50, 1, 1, 51, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 52, 1, 46, - 46, 46, 46, 46, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 46, 1, - 1, 47, 1, 1, 1, 1, 1, 1, - 1, 1, 48, 1, 1, 1, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 49, 1, 53, 53, 53, 53, - 53, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 1, 54, 1, - 1, 1, 1, 1, 1, 1, 55, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 56, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 57, - 1, 58, 58, 58, 58, 58, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 58, 1, 1, 59, 1, 1, 1, 1, - 1, 1, 1, 60, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 61, 1, 58, 58, - 58, 58, 58, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 58, 1, 1, - 59, 1, 1, 1, 1, 1, 1, 1, - 60, 1, 1, 1, 1, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 61, 1, 53, 53, 53, 53, 53, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 53, 1, 1, 54, 1, 1, - 1, 1, 1, 1, 1, 55, 1, 1, - 1, 1, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 1, 1, 1, 1, - 1, 1, 56, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, - 0 + 19, 3, 18, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 3, 20, 3, 21, + 3, 3, 22, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 3, 22, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 3, + 24, 3, 25, 3, 3, 26, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 3, + 26, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 3, 28, 3, 29, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 29, 3, 30, 3, + 3, 31, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 3, 33, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 3, 35, + 3, 3, 3, 3, 3, 3, 3, 3, + 36, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 37, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 38, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 38, 3, 39, 3, 3, 40, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 3, + 42, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 3, 44, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 45, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 46, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 46, 3, 44, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 3, 3, 45, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 46, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 46, + 3, 35, 3, 3, 3, 3, 3, 3, + 3, 3, 36, 3, 3, 3, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 3, 3, 37, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 38, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 38, 3, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 3, 47, 0, + 0, 48, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 0, 0, 4, 5, 0, + 0, 6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, + 3, 0, 0, 0, 48, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 0, 0, + 4, 5, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 5, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 50, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 3, + 52, 3, 3, 3, 3, 3, 3, 3, + 53, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 54, 3, 3, 3, 55, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 56, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 56, 3, 57, 3, 3, 58, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 3, 60, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 3, 62, 3, 63, 3, + 3, 64, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 3, 66, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 3, 68, + 3, 3, 3, 3, 3, 3, 3, 69, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 70, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 71, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 71, 3, 68, 3, 3, 3, 3, 3, + 3, 3, 69, 3, 3, 3, 3, 67, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 3, 3, 70, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 71, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 71, 3, 62, 3, 3, + 3, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 3, 52, 3, 3, 3, + 3, 3, 3, 3, 53, 3, 3, 3, + 3, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 3, 3, 54, 3, 3, + 3, 55, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 56, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 56, 3, 0, + 0, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 0, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 0, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 16, 0, 0, 0, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 0, 0, 4, 5, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 3, + 3, 3, 3, 28, 3, 24, 3, 3, + 3, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 3, 20, 3, 3, 3, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 3, 16, 3, 3, 3, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 3, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 3, 3, 11, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 12, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 12, 3, + 75, 74, 74, 74, 74, 74, 74, 74, + 76, 3, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 77, 78, 74, 74, 79, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 80, 81, 82, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 82, 74, 84, 83, 83, 83, 83, + 83, 83, 83, 85, 3, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 86, 87, 83, 83, + 88, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 89, 90, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 90, 83, 91, 74, + 74, 74, 74, 74, 74, 74, 92, 3, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 93, + 94, 74, 74, 95, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 81, + 96, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 96, + 74, 0 }; static const char _deserialize_text_glyphs_trans_targs[] = { - 16, 0, 18, 3, 19, 22, 19, 22, - 5, 20, 21, 20, 21, 23, 26, 8, - 9, 12, 9, 12, 10, 11, 24, 25, - 24, 25, 15, 15, 14, 1, 2, 6, - 7, 13, 15, 1, 2, 6, 7, 13, - 14, 17, 14, 17, 14, 18, 17, 1, - 4, 14, 17, 1, 14, 17, 1, 2, - 7, 14, 17, 1, 2, 14, 26 + 1, 2, 17, 0, 25, 28, 30, 39, + 47, 3, 45, 4, 47, 5, 6, 44, + 7, 8, 9, 43, 10, 11, 12, 42, + 13, 14, 15, 41, 16, 47, 18, 19, + 24, 19, 24, 2, 20, 4, 47, 21, + 22, 23, 22, 23, 2, 4, 47, 26, + 27, 40, 29, 38, 2, 17, 4, 30, + 47, 31, 32, 37, 32, 37, 33, 34, + 35, 36, 35, 36, 2, 17, 4, 47, + 38, 45, 1, 2, 17, 25, 28, 30, + 48, 39, 47, 1, 2, 17, 25, 28, + 30, 39, 47, 2, 17, 25, 28, 30, + 47 }; static const char _deserialize_text_glyphs_trans_actions[] = { - 1, 0, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 2, 1, 1, 1, - 0, 0, 0, 4, 3, 5, 5, 5, - 5, 4, 6, 7, 7, 7, 7, 0, - 6, 8, 8, 0, 0, 0, 9, 10, - 10, 9, 11, 12, 11, 13, 14, 14, - 14, 13, 15, 16, 16, 15, 0 + 0, 1, 1, 0, 1, 1, 1, 0, + 1, 2, 2, 3, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 4, 4, 4, 4, 2, + 2, 2, 0, 0, 5, 5, 5, 0, + 0, 0, 2, 2, 6, 6, 6, 6, + 6, 2, 2, 2, 0, 0, 7, 2, + 2, 2, 0, 0, 8, 8, 8, 8, + 0, 0, 9, 10, 10, 10, 10, 10, + 9, 9, 10, 12, 13, 13, 13, 13, + 13, 12, 13, 14, 14, 14, 14, 14, + 14 }; static const char _deserialize_text_glyphs_eof_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 6, - 8, 0, 8, 9, 11, 11, 9, 13, - 15, 15, 13 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, + 0 }; -static const int deserialize_text_glyphs_start = 14; -static const int deserialize_text_glyphs_first_final = 14; +static const int deserialize_text_glyphs_start = 46; +static const int deserialize_text_glyphs_first_final = 46; static const int deserialize_text_glyphs_error = 0; -static const int deserialize_text_glyphs_en_main = 14; +static const int deserialize_text_glyphs_en_main = 46; -#line 98 "hb-buffer-deserialize-text-glyphs.rl" +#line 101 "hb-buffer-deserialize-text-glyphs.rl" static hb_bool_t @@ -322,39 +379,22 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; + const char *p = buf, *pe = buf + buf_len, *eof = pe; /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '[')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, ']'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 353 "hb-buffer-deserialize-text-glyphs.hh" +#line 386 "hb-buffer-deserialize-text-glyphs.hh" { cs = deserialize_text_glyphs_start; } -#line 358 "hb-buffer-deserialize-text-glyphs.hh" +#line 389 "hb-buffer-deserialize-text-glyphs.hh" { int _slen; int _trans; @@ -379,14 +419,14 @@ _resume: goto _again; switch ( _deserialize_text_glyphs_trans_actions[_trans] ) { - case 1: -#line 51 "hb-buffer-deserialize-text-glyphs.rl" + case 2: +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } break; - case 7: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" + case 1: +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ if (!hb_font_glyph_from_string (font, @@ -395,162 +435,124 @@ _resume: return false; } break; - case 14: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" + case 6: +#line 62 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; - case 2: -#line 64 "hb-buffer-deserialize-text-glyphs.rl" + case 7: +#line 63 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; - case 16: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" + case 8: +#line 64 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 10: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" + case 4: +#line 65 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 12: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" + case 5: +#line 66 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; - case 4: + case 3: +#line 67 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } + break; + case 9: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } break; - case 6: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" + case 10: +#line 38 "hb-buffer-deserialize-text-glyphs.rl" { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; + tok = p; } - break; - case 13: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; } break; - case 15: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } + case 12: #line 43 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); + buffer->add_info_and_pos (info, pos); if (unlikely (!buffer->successful)) return false; - buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } - break; - case 9: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" +#line 38 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } - break; - case 11: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; + tok = p; } break; - case 8: -#line 68 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" + case 14: +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; } - break; - case 5: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } -#line 55 "hb-buffer-deserialize-text-glyphs.rl" + break; + case 13: +#line 43 "hb-buffer-deserialize-text-glyphs.rl" { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) + buffer->add_info_and_pos (info, pos); + if (unlikely (!buffer->successful)) return false; + *end_ptr = p; } - break; - case 3: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } -#line 55 "hb-buffer-deserialize-text-glyphs.rl" +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ if (!hb_font_glyph_from_string (font, tok, p - tok, &info.codepoint)) return false; -} -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; } break; -#line 554 "hb-buffer-deserialize-text-glyphs.hh" +#line 523 "hb-buffer-deserialize-text-glyphs.hh" } _again: @@ -562,127 +564,24 @@ _again: if ( p == eof ) { switch ( _deserialize_text_glyphs_eof_actions[cs] ) { - case 6: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 15: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; case 11: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 8: -#line 68 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 3: -#line 38 "hb-buffer-deserialize-text-glyphs.rl" - { - hb_memset (&info, 0, sizeof (info)); - hb_memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text-glyphs.rl" - { - tok = p; -} -#line 55 "hb-buffer-deserialize-text-glyphs.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} #line 43 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); + buffer->add_info_and_pos (info, pos); if (unlikely (!buffer->successful)) return false; - buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } break; -#line 671 "hb-buffer-deserialize-text-glyphs.hh" +#line 542 "hb-buffer-deserialize-text-glyphs.hh" } } _out: {} } -#line 136 "hb-buffer-deserialize-text-glyphs.rl" - +#line 122 "hb-buffer-deserialize-text-glyphs.rl" - if (pe < orig_pe && *pe == ']') - { - pe++; - if (p == pe) - p++; - } *end_ptr = p; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh index 6a1706ccb72..9e21beebd34 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh @@ -34,135 +34,106 @@ #line 36 "hb-buffer-deserialize-text-unicode.hh" static const unsigned char _deserialize_text_unicode_trans_keys[] = { - 0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 0 + 0u, 0u, 43u, 102u, 48u, 102u, 48u, 124u, 48u, 57u, 62u, 124u, 48u, 124u, 60u, 117u, + 85u, 117u, 85u, 117u, 0 }; static const char _deserialize_text_unicode_key_spans[] = { - 0, 109, 60, 55, 10, 116, 116, 116, - 116 + 0, 60, 55, 77, 10, 63, 77, 58, + 33, 33 }; static const short _deserialize_text_unicode_index_offsets[] = { - 0, 0, 110, 171, 227, 238, 355, 472, - 589 + 0, 0, 61, 117, 195, 206, 270, 348, + 407, 441 }; static const char _deserialize_text_unicode_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, + 0, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 4, 5, 1, 1, 3, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 5, 1, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 3, - 1, 1, 1, 1, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 1, 7, - 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 7, 1, + 1, 1, 1, 1, 1, 8, 1, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 1, 1, 1, 9, 1, 1, 1, 8, - 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 8, - 8, 8, 8, 8, 8, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 10, 1, 11, 11, 11, 11, - 11, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 11, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 12, 12, 12, 12, 12, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 12, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 8, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 13, 1, 12, 12, - 12, 12, 12, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 12, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 11, 1, + 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 13, 1, 0 + 1, 1, 12, 1, 0 }; static const char _deserialize_text_unicode_trans_targs[] = { - 1, 0, 2, 3, 5, 7, 8, 6, - 5, 4, 1, 6, 6, 1, 8 + 2, 0, 3, 3, 4, 9, 5, 6, + 9, 6, 8, 1, 1 }; static const char _deserialize_text_unicode_trans_actions[] = { - 0, 0, 1, 0, 2, 2, 2, 3, - 0, 4, 3, 0, 5, 5, 0 + 0, 0, 1, 0, 2, 2, 1, 1, + 3, 0, 0, 4, 6 }; static const char _deserialize_text_unicode_eof_actions[] = { - 0, 0, 0, 0, 0, 3, 0, 5, - 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5 }; -static const int deserialize_text_unicode_start = 1; -static const int deserialize_text_unicode_first_final = 5; +static const int deserialize_text_unicode_start = 7; +static const int deserialize_text_unicode_first_final = 7; static const int deserialize_text_unicode_error = 0; -static const int deserialize_text_unicode_en_main = 1; +static const int deserialize_text_unicode_en_main = 7; -#line 79 "hb-buffer-deserialize-text-unicode.rl" +#line 80 "hb-buffer-deserialize-text-unicode.rl" static hb_bool_t @@ -172,37 +143,19 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '<')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, '>'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - + const char *p = buf, *pe = buf + buf_len, *eof = pe; const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; const hb_glyph_position_t pos = {0}; -#line 201 "hb-buffer-deserialize-text-unicode.hh" +#line 154 "hb-buffer-deserialize-text-unicode.hh" { cs = deserialize_text_unicode_start; } -#line 206 "hb-buffer-deserialize-text-unicode.hh" +#line 159 "hb-buffer-deserialize-text-unicode.hh" { int _slen; int _trans; @@ -227,38 +180,27 @@ _resume: goto _again; switch ( _deserialize_text_unicode_trans_actions[_trans] ) { - case 1: + case 4: #line 38 "hb-buffer-deserialize-text-unicode.rl" { hb_memset (&info, 0, sizeof (info)); } break; - case 2: + case 1: #line 51 "hb-buffer-deserialize-text-unicode.rl" { tok = p; } break; - case 4: + case 2: #line 55 "hb-buffer-deserialize-text-unicode.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } break; case 3: -#line 55 "hb-buffer-deserialize-text-unicode.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } -#line 42 "hb-buffer-deserialize-text-unicode.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - if (buffer->have_positions) - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 5: #line 57 "hb-buffer-deserialize-text-unicode.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 6: #line 42 "hb-buffer-deserialize-text-unicode.rl" { buffer->add_info (info); @@ -267,9 +209,13 @@ _resume: if (buffer->have_positions) buffer->pos[buffer->len - 1] = pos; *end_ptr = p; +} +#line 38 "hb-buffer-deserialize-text-unicode.rl" + { + hb_memset (&info, 0, sizeof (info)); } break; -#line 273 "hb-buffer-deserialize-text-unicode.hh" +#line 219 "hb-buffer-deserialize-text-unicode.hh" } _again: @@ -281,22 +227,7 @@ _again: if ( p == eof ) { switch ( _deserialize_text_unicode_eof_actions[cs] ) { - case 3: -#line 55 "hb-buffer-deserialize-text-unicode.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } -#line 42 "hb-buffer-deserialize-text-unicode.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - if (buffer->have_positions) - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; case 5: -#line 57 "hb-buffer-deserialize-text-unicode.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } #line 42 "hb-buffer-deserialize-text-unicode.rl" { buffer->add_info (info); @@ -307,22 +238,15 @@ _again: *end_ptr = p; } break; -#line 311 "hb-buffer-deserialize-text-unicode.hh" +#line 242 "hb-buffer-deserialize-text-unicode.hh" } } _out: {} } -#line 115 "hb-buffer-deserialize-text-unicode.rl" - +#line 98 "hb-buffer-deserialize-text-unicode.rl" - if (pe < orig_pe && *pe == '>') - { - pe++; - if (p == pe) - p++; - } *end_ptr = p; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc index bb2cddcb655..763172818c4 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-serialize.cc @@ -169,11 +169,13 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; - hb_font_get_glyph_extents(font, info[i].codepoint, &extents); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", - extents.x_bearing, extents.y_bearing)); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", - extents.width, extents.height)); + if (hb_font_get_glyph_extents(font, info[i].codepoint, &extents)) + { + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", + extents.x_bearing, extents.y_bearing)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", + extents.width, extents.height)); + } } *p++ = '}'; @@ -318,8 +320,8 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; - hb_font_get_glyph_extents(font, info[i].codepoint, &extents); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); + if (hb_font_get_glyph_extents(font, info[i].codepoint, &extents)) + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); } if (i == end-1) { @@ -737,8 +739,7 @@ parse_hex (const char *pp, const char *end, uint32_t *pv) * Deserializes glyphs @buffer from textual representation in the format * produced by hb_buffer_serialize_glyphs(). * - * Return value: `true` if parse was successful, `false` if an error - * occurred. + * Return value: `true` if the full string was parsed, `false` otherwise. * * Since: 0.9.7 **/ @@ -810,8 +811,7 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, * Deserializes Unicode @buffer from textual representation in the format * produced by hb_buffer_serialize_unicode(). * - * Return value: `true` if parse was successful, `false` if an error - * occurred. + * Return value: `true` if the full string was parsed, `false` otherwise. * * Since: 2.7.3 **/ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc index 3a4c9c9f317..56299d9b7e0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc @@ -63,23 +63,24 @@ static bool buffer_verify_monotone (hb_buffer_t *buffer, hb_font_t *font) { - /* Check that clusters are monotone. */ - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES || - buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { - bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer)); + /* Cannot perform this check without monotone clusters. */ + return true; + } - unsigned int num_glyphs; - hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); + bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer)); - for (unsigned int i = 1; i < num_glyphs; i++) - if (info[i-1].cluster != info[i].cluster && - (info[i-1].cluster < info[i].cluster) != is_forward) - { - buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "clusters are not monotone."); - return false; - } - } + unsigned int num_glyphs; + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); + + for (unsigned int i = 1; i < num_glyphs; i++) + if (info[i-1].cluster != info[i].cluster && + (info[i-1].cluster < info[i].cluster) != is_forward) + { + buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "clusters are not monotone."); + return false; + } return true; } @@ -92,8 +93,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, unsigned int num_features, const char * const *shapers) { - if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES && - buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { /* Cannot perform this check without monotone clusters. */ return true; @@ -207,8 +207,7 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, unsigned int num_features, const char * const *shapers) { - if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES && - buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { /* Cannot perform this check without monotone clusters. */ return true; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc index 72970c9c2f7..c0600fd839b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc @@ -370,6 +370,18 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info) len++; } +void +hb_buffer_t::add_info_and_pos (const hb_glyph_info_t &glyph_info, + const hb_glyph_position_t &glyph_pos) +{ + if (unlikely (!ensure (len + 1))) return; + + info[len] = glyph_info; + assert (have_positions); + pos[len] = glyph_pos; + + len++; +} void @@ -518,7 +530,7 @@ void hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { - if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (cluster_level)) { unsafe_to_break (start, end); return; @@ -551,7 +563,7 @@ void hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) { - if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (cluster_level)) return; if (unlikely (end - start < 2)) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.h b/src/java.desktop/share/native/libharfbuzz/hb-buffer.h index d2258634ff4..332001ef171 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.h @@ -422,6 +422,7 @@ hb_buffer_get_flags (const hb_buffer_t *buffer); * @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values. * @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level, * equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES. + * @HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES: Only group clusters, but don't enforce monotone order. * * Data type for holding HarfBuzz's clustering behavior options. The cluster level * dictates one aspect of how HarfBuzz will treat non-base characters @@ -429,11 +430,26 @@ hb_buffer_get_flags (const hb_buffer_t *buffer); * * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES, non-base * characters are merged into the cluster of the base character that precedes them. + * There is also cluster merging every time the clusters will otherwise become non-monotone. * * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, non-base characters are initially * assigned their own cluster values, which are not merged into preceding base * clusters. This allows HarfBuzz to perform additional operations like reorder - * sequences of adjacent marks. + * sequences of adjacent marks. The output is still monotone, but the cluster + * values are more granular. + * + * In @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS, non-base characters are assigned their + * own cluster values, which are not merged into preceding base clusters. Moreover, + * the cluster values are not merged into monotone order. This is the most granular + * cluster level, and it is useful for clients that need to know the exact cluster + * values of each character, but is harder to use for clients, since clusters + * might appear in any order. + * + * In @HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES, non-base characters are merged into the + * cluster of the base character that precedes them. This is similar to the Unicode + * Grapheme Cluster algorithm, but it is not exactly the same. The output is + * not forced to be monotone. This is useful for clients that want to use HarfBuzz + * as a cheap implementation of the Unicode Grapheme Cluster algorithm. * * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES is the default, because it maintains * backward compatibility with older versions of HarfBuzz. New client programs that @@ -446,9 +462,52 @@ typedef enum { HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, + HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES = 3, HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES } hb_buffer_cluster_level_t; +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE: + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level groups cluster values into monotone order. + * Requires that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)))) + +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES: + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level groups cluster values by graphemes. Requires + * that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES)))) + +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level does not group cluster values by graphemes. + * Requires that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARCATERS) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)))) + HB_EXTERN void hb_buffer_set_cluster_level (hb_buffer_t *buffer, hb_buffer_cluster_level_t cluster_level); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh index c92e7df320e..81c0f4a72e3 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh @@ -229,6 +229,8 @@ struct hb_buffer_t HB_INTERNAL void add (hb_codepoint_t codepoint, unsigned int cluster); HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info); + HB_INTERNAL void add_info_and_pos (const hb_glyph_info_t &glyph_info, + const hb_glyph_position_t &glyph_pos); void reverse_range (unsigned start, unsigned end) { @@ -410,6 +412,9 @@ struct hb_buffer_t { end = hb_min (end, len); + if (unlikely (end - start > 255)) + return; + if (interior && !from_out_buffer && end - start < 2) return; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cache.hh b/src/java.desktop/share/native/libharfbuzz/hb-cache.hh index 8c7e0c655e6..7d09ca89d7f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cache.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cache.hh @@ -30,18 +30,31 @@ #include "hb.hh" -/* Implements a lockfree cache for int->int functions. +/* Implements a lockfree and thread-safe cache for int->int functions, + * using (optionally) _relaxed_ atomic integer operations. * - * The cache is a fixed-size array of 16-bit or 32-bit integers. - * The key is split into two parts: the cache index and the rest. + * The cache is a fixed-size array of 16-bit or 32-bit integers, + * typically 256 elements. * - * The cache index is used to index into the array. The rest is used - * to store the key and the value. + * The key is split into two parts: the cache index (high bits) + * and the rest (low bits). + * + * The cache index is used to index into the array. The array + * member is a 16-bit or 32-bit integer that is used *both* + * to store the low bits of the key, and the value. * * The value is stored in the least significant bits of the integer. - * The key is stored in the most significant bits of the integer. - * The key is shifted by cache_bits to the left to make room for the - * value. + * The low bits of the key are stored in the most significant bits + * of the integer. + * + * A cache hit is detected by comparing the low bits of the key + * with the high bits of the integer at the array position indexed + * by the high bits of the key. If they match, the value is extracted + * from the least significant bits of the integer and returned. + * Otherwise, a cache miss is reported. + * + * Cache operations (storage and retrieval) involve just a few + * arithmetic operations and a single memory access. */ template ::type, + hb_atomic_t, + hb_atomic_t>::type, typename std::conditional::type + unsigned short, + unsigned int>::type >::type; static_assert ((key_bits >= cache_bits), ""); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh index ab17d68318b..0eacdd92ab8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh @@ -71,7 +71,8 @@ struct cff2_cs_interp_env_t : cs_interp_env_t template cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd, const int *coords_=nullptr, unsigned int num_coords_=0) - : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs) + : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs), + cached_scalars_vector (&acc.cached_scalars_vector) { coords = coords_; num_coords = num_coords_; @@ -80,9 +81,39 @@ struct cff2_cs_interp_env_t : cs_interp_env_t set_ivs (acc.privateDicts[fd].ivs); } - void fini () + ~cff2_cs_interp_env_t () { - SUPER::fini (); + release_scalars_vector (scalars); + } + + hb_vector_t *acquire_scalars_vector () const + { + hb_vector_t *scalars = cached_scalars_vector->get_acquire (); + + if (!scalars || !cached_scalars_vector->cmpexch (scalars, nullptr)) + { + scalars = (hb_vector_t *) hb_calloc (1, sizeof (hb_vector_t)); + if (unlikely (!scalars)) + return nullptr; + scalars->init (); + } + + return scalars; + } + + void release_scalars_vector (hb_vector_t *scalars) const + { + if (!scalars) + return; + + scalars->clear (); + + if (!cached_scalars_vector->cmpexch (nullptr, scalars)) + { + scalars->fini (); + hb_free (scalars); + } + scalars = nullptr; } op_code_t fetch_op () @@ -111,14 +142,20 @@ struct cff2_cs_interp_env_t : cs_interp_env_t { if (!seen_blend) { - region_count = varStore->varStore.get_region_index_count (get_ivs ()); - if (do_blend) + scalars = acquire_scalars_vector (); + if (unlikely (!scalars)) + SUPER::set_error (); + else { - if (unlikely (!scalars.resize_exact (region_count))) - SUPER::set_error (); - else - varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords, - &scalars[0], region_count); + region_count = varStore->varStore.get_region_index_count (get_ivs ()); + if (do_blend) + { + if (unlikely (!scalars->resize_exact (region_count))) + SUPER::set_error (); + else + varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords, + &(*scalars)[0], region_count); + } } seen_blend = true; } @@ -149,11 +186,11 @@ struct cff2_cs_interp_env_t : cs_interp_env_t double v = 0; if (do_blend) { - if (likely (scalars.length == deltas.length)) + if (likely (scalars && scalars->length == deltas.length)) { - unsigned count = scalars.length; + unsigned count = scalars->length; for (unsigned i = 0; i < count; i++) - v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real (); + v += (double) scalars->arrayZ[i] * deltas.arrayZ[i].to_real (); } } return v; @@ -167,7 +204,8 @@ struct cff2_cs_interp_env_t : cs_interp_env_t const CFF2ItemVariationStore *varStore; unsigned int region_count; unsigned int ivs; - hb_vector_t scalars; + hb_vector_t *scalars = nullptr; + hb_atomic_t *> *cached_scalars_vector = nullptr; bool do_blend; bool seen_vsindex_ = false; bool seen_blend = false; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.cc b/src/java.desktop/share/native/libharfbuzz/hb-common.cc index bce0d09d20a..5c8546a378c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-common.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-common.cc @@ -42,7 +42,7 @@ /* hb_options_t */ -hb_atomic_int_t _hb_options; +hb_atomic_t _hb_options; void _hb_options_init () @@ -273,7 +273,7 @@ struct hb_language_item_t { /* Thread-safe lockfree language list */ -static hb_atomic_ptr_t langs; +static hb_atomic_t langs; static inline void free_langs () @@ -403,7 +403,7 @@ hb_language_to_string (hb_language_t language) hb_language_t hb_language_get_default () { - static hb_atomic_ptr_t default_language; + static hb_atomic_t default_language; hb_language_t language = default_language; if (unlikely (language == HB_LANGUAGE_INVALID)) @@ -968,6 +968,9 @@ hb_feature_from_string (const char *str, int len, * understood by hb_feature_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * + * Note that the feature value will be omitted if it is '1', but the + * string won't include any whitespace. + * * Since: 0.9.5 **/ void @@ -1121,6 +1124,8 @@ get_C_locale () * understood by hb_variation_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * + * Note that the string won't include any whitespace. + * * Since: 1.4.2 */ void @@ -1212,6 +1217,58 @@ uint8_t return hb_color_get_blue (color); } +/** + * hb_malloc: + * @size: The size of the memory to allocate. + * + * Allocates @size bytes of memory, using the allocator set at + * compile-time. Typically just malloc(). + * + * Return value: A pointer to the allocated memory. + * + * Since: 11.0.0 + **/ +void* hb_malloc(size_t size) { return hb_malloc_impl (size); } + +/** + * hb_calloc: + * @nmemb: The number of elements to allocate. + * @size: The size of each element. + * + * Allocates @nmemb elements of @size bytes each, initialized to zero, + * using the allocator set at compile-time. Typically just calloc(). + * + * Return value: A pointer to the allocated memory. + * + * Since: 11.0.0 + **/ +void* hb_calloc(size_t nmemb, size_t size) { return hb_calloc_impl (nmemb, size); } + +/** + * hb_realloc: + * @ptr: The pointer to the memory to reallocate. + * @size: The new size of the memory. + * + * Reallocates the memory pointed to by @ptr to @size bytes, using the + * allocator set at compile-time. Typically just realloc(). + * + * Return value: A pointer to the reallocated memory. + * + * Since: 11.0.0 + **/ +void* hb_realloc(void *ptr, size_t size) { return hb_realloc_impl (ptr, size); } + +/** + * hb_free: + * @ptr: The pointer to the memory to free. + * + * Frees the memory pointed to by @ptr, using the allocator set at + * compile-time. Typically just free(). + * + * Since: 11.0.0 + **/ +void hb_free(void *ptr) { hb_free_impl (ptr); } + /* If there is no visibility control, then hb-static.cc will NOT * define anything. Instead, we get it to define one set in here diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.h b/src/java.desktop/share/native/libharfbuzz/hb-common.h index a8bae366f7e..5a0ef65392d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-common.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-common.h @@ -65,6 +65,7 @@ typedef unsigned __int64 uint64_t; #else # include #endif +#include #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define HB_DEPRECATED __attribute__((__deprecated__)) @@ -337,437 +338,7 @@ HB_EXTERN hb_bool_t hb_language_matches (hb_language_t language, hb_language_t specific); -/** - * hb_script_t: - * @HB_SCRIPT_COMMON: `Zyyy` - * @HB_SCRIPT_INHERITED: `Zinh` - * @HB_SCRIPT_UNKNOWN: `Zzzz` - * @HB_SCRIPT_ARABIC: `Arab` - * @HB_SCRIPT_ARMENIAN: `Armn` - * @HB_SCRIPT_BENGALI: `Beng` - * @HB_SCRIPT_CYRILLIC: `Cyrl` - * @HB_SCRIPT_DEVANAGARI: `Deva` - * @HB_SCRIPT_GEORGIAN: `Geor` - * @HB_SCRIPT_GREEK: `Grek` - * @HB_SCRIPT_GUJARATI: `Gujr` - * @HB_SCRIPT_GURMUKHI: `Guru` - * @HB_SCRIPT_HANGUL: `Hang` - * @HB_SCRIPT_HAN: `Hani` - * @HB_SCRIPT_HEBREW: `Hebr` - * @HB_SCRIPT_HIRAGANA: `Hira` - * @HB_SCRIPT_KANNADA: `Knda` - * @HB_SCRIPT_KATAKANA: `Kana` - * @HB_SCRIPT_LAO: `Laoo` - * @HB_SCRIPT_LATIN: `Latn` - * @HB_SCRIPT_MALAYALAM: `Mlym` - * @HB_SCRIPT_ORIYA: `Orya` - * @HB_SCRIPT_TAMIL: `Taml` - * @HB_SCRIPT_TELUGU: `Telu` - * @HB_SCRIPT_THAI: `Thai` - * @HB_SCRIPT_TIBETAN: `Tibt` - * @HB_SCRIPT_BOPOMOFO: `Bopo` - * @HB_SCRIPT_BRAILLE: `Brai` - * @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans` - * @HB_SCRIPT_CHEROKEE: `Cher` - * @HB_SCRIPT_ETHIOPIC: `Ethi` - * @HB_SCRIPT_KHMER: `Khmr` - * @HB_SCRIPT_MONGOLIAN: `Mong` - * @HB_SCRIPT_MYANMAR: `Mymr` - * @HB_SCRIPT_OGHAM: `Ogam` - * @HB_SCRIPT_RUNIC: `Runr` - * @HB_SCRIPT_SINHALA: `Sinh` - * @HB_SCRIPT_SYRIAC: `Syrc` - * @HB_SCRIPT_THAANA: `Thaa` - * @HB_SCRIPT_YI: `Yiii` - * @HB_SCRIPT_DESERET: `Dsrt` - * @HB_SCRIPT_GOTHIC: `Goth` - * @HB_SCRIPT_OLD_ITALIC: `Ital` - * @HB_SCRIPT_BUHID: `Buhd` - * @HB_SCRIPT_HANUNOO: `Hano` - * @HB_SCRIPT_TAGALOG: `Tglg` - * @HB_SCRIPT_TAGBANWA: `Tagb` - * @HB_SCRIPT_CYPRIOT: `Cprt` - * @HB_SCRIPT_LIMBU: `Limb` - * @HB_SCRIPT_LINEAR_B: `Linb` - * @HB_SCRIPT_OSMANYA: `Osma` - * @HB_SCRIPT_SHAVIAN: `Shaw` - * @HB_SCRIPT_TAI_LE: `Tale` - * @HB_SCRIPT_UGARITIC: `Ugar` - * @HB_SCRIPT_BUGINESE: `Bugi` - * @HB_SCRIPT_COPTIC: `Copt` - * @HB_SCRIPT_GLAGOLITIC: `Glag` - * @HB_SCRIPT_KHAROSHTHI: `Khar` - * @HB_SCRIPT_NEW_TAI_LUE: `Talu` - * @HB_SCRIPT_OLD_PERSIAN: `Xpeo` - * @HB_SCRIPT_SYLOTI_NAGRI: `Sylo` - * @HB_SCRIPT_TIFINAGH: `Tfng` - * @HB_SCRIPT_BALINESE: `Bali` - * @HB_SCRIPT_CUNEIFORM: `Xsux` - * @HB_SCRIPT_NKO: `Nkoo` - * @HB_SCRIPT_PHAGS_PA: `Phag` - * @HB_SCRIPT_PHOENICIAN: `Phnx` - * @HB_SCRIPT_CARIAN: `Cari` - * @HB_SCRIPT_CHAM: `Cham` - * @HB_SCRIPT_KAYAH_LI: `Kali` - * @HB_SCRIPT_LEPCHA: `Lepc` - * @HB_SCRIPT_LYCIAN: `Lyci` - * @HB_SCRIPT_LYDIAN: `Lydi` - * @HB_SCRIPT_OL_CHIKI: `Olck` - * @HB_SCRIPT_REJANG: `Rjng` - * @HB_SCRIPT_SAURASHTRA: `Saur` - * @HB_SCRIPT_SUNDANESE: `Sund` - * @HB_SCRIPT_VAI: `Vaii` - * @HB_SCRIPT_AVESTAN: `Avst` - * @HB_SCRIPT_BAMUM: `Bamu` - * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp` - * @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi` - * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli` - * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti` - * @HB_SCRIPT_JAVANESE: `Java` - * @HB_SCRIPT_KAITHI: `Kthi` - * @HB_SCRIPT_LISU: `Lisu` - * @HB_SCRIPT_MEETEI_MAYEK: `Mtei` - * @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb` - * @HB_SCRIPT_OLD_TURKIC: `Orkh` - * @HB_SCRIPT_SAMARITAN: `Samr` - * @HB_SCRIPT_TAI_THAM: `Lana` - * @HB_SCRIPT_TAI_VIET: `Tavt` - * @HB_SCRIPT_BATAK: `Batk` - * @HB_SCRIPT_BRAHMI: `Brah` - * @HB_SCRIPT_MANDAIC: `Mand` - * @HB_SCRIPT_CHAKMA: `Cakm` - * @HB_SCRIPT_MEROITIC_CURSIVE: `Merc` - * @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero` - * @HB_SCRIPT_MIAO: `Plrd` - * @HB_SCRIPT_SHARADA: `Shrd` - * @HB_SCRIPT_SORA_SOMPENG: `Sora` - * @HB_SCRIPT_TAKRI: `Takr` - * @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30 - * @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30 - * @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30 - * @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30 - * @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30 - * @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30 - * @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30 - * @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30 - * @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30 - * @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30 - * @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30 - * @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30 - * @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30 - * @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30 - * @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30 - * @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30 - * @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30 - * @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30 - * @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30 - * @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30 - * @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30 - * @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30 - * @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30 - * @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30 - * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30 - * @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30 - * @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30 - * @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30 - * @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30 - * @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0 - * @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0 - * @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0 - * @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0 - * @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0 - * @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0 - * @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0 - * @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0 - * @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0 - * @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0 - * @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0 - * @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0 - * @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0 - * @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0 - * @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0 - * @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0 - * @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0 - * @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0 - * @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0 - * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0 - * @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0 - * @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7 - * @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7 - * @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7 - * @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7 - * @HB_SCRIPT_CYPRO_MINOAN: `Cpmn`, Since: 3.0.0 - * @HB_SCRIPT_OLD_UYGHUR: `Ougr`, Since: 3.0.0 - * @HB_SCRIPT_TANGSA: `Tnsa`, Since: 3.0.0 - * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0 - * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0 - * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0 - * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0 - * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0 - * @HB_SCRIPT_GARAY: `Gara`, Since: 10.0.0 - * @HB_SCRIPT_GURUNG_KHEMA: `Gukh`, Since: 10.0.0 - * @HB_SCRIPT_KIRAT_RAI: `Krai`, Since: 10.0.0 - * @HB_SCRIPT_OL_ONAL: `Onao`, Since: 10.0.0 - * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 - * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 - * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 - * @HB_SCRIPT_INVALID: No script set - * - * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding - * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/). - * - * See also the Script (sc) property of the Unicode Character Database. - * - **/ - -/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ -typedef enum -{ - HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), /*1.1*/ - HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), /*1.1*/ - HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), /*5.0*/ - - HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), /*1.1*/ - HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), /*1.1*/ - HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), /*1.1*/ - HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), /*1.1*/ - HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), /*1.1*/ - HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), /*1.1*/ - HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), /*1.1*/ - HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), /*1.1*/ - HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), /*1.1*/ - HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), /*1.1*/ - HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), /*1.1*/ - HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), /*1.1*/ - HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), /*1.1*/ - HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), /*1.1*/ - HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), /*1.1*/ - HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), /*1.1*/ - HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), /*1.1*/ - HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), /*1.1*/ - HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), /*1.1*/ - HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), /*1.1*/ - HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), /*1.1*/ - HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), /*1.1*/ - - HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/ - - HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), /*3.0*/ - HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), /*3.0*/ - HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), /*3.0*/ - HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), /*3.0*/ - HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), /*3.0*/ - HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), /*3.0*/ - HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), /*3.0*/ - HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), /*3.0*/ - HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), /*3.0*/ - HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), /*3.0*/ - HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), /*3.0*/ - HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), /*3.0*/ - HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), /*3.0*/ - HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), /*3.0*/ - - HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), /*3.1*/ - HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), /*3.1*/ - HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), /*3.1*/ - - HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), /*3.2*/ - HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), /*3.2*/ - HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), /*3.2*/ - HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), /*3.2*/ - - HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), /*4.0*/ - HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), /*4.0*/ - HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), /*4.0*/ - HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), /*4.0*/ - HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), /*4.0*/ - HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), /*4.0*/ - HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), /*4.0*/ - - HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), /*4.1*/ - HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), /*4.1*/ - HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), /*4.1*/ - HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), /*4.1*/ - HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), /*4.1*/ - HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), /*4.1*/ - HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), /*4.1*/ - HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), /*4.1*/ - - HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), /*5.0*/ - HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), /*5.0*/ - HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), /*5.0*/ - HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), /*5.0*/ - HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), /*5.0*/ - - HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), /*5.1*/ - HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), /*5.1*/ - HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), /*5.1*/ - HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), /*5.1*/ - HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), /*5.1*/ - HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), /*5.1*/ - HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), /*5.1*/ - HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), /*5.1*/ - HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), /*5.1*/ - HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), /*5.1*/ - HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), /*5.1*/ - - HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), /*5.2*/ - HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), /*5.2*/ - HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), /*5.2*/ - HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), /*5.2*/ - HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), /*5.2*/ - HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), /*5.2*/ - HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), /*5.2*/ - HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), /*5.2*/ - HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), /*5.2*/ - HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), /*5.2*/ - HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), /*5.2*/ - HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), /*5.2*/ - HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), /*5.2*/ - HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), /*5.2*/ - HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), /*5.2*/ - - HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), /*6.0*/ - HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), /*6.0*/ - HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), /*6.0*/ - - HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), /*6.1*/ - HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), /*6.1*/ - HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), /*6.1*/ - HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), /*6.1*/ - HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), /*6.1*/ - HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ - HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/ - - /* - * Since: 0.9.30 - */ - HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ - HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ - HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/ - HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), /*7.0*/ - HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), /*7.0*/ - HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), /*7.0*/ - HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), /*7.0*/ - HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), /*7.0*/ - HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/ - HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/ - HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/ - HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), /*7.0*/ - HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/ - HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/ - HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/ - HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/ - HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/ - HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/ - HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), /*7.0*/ - HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/ - HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), /*7.0*/ - HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ - HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/ - - HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), /*8.0*/ - HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), /*8.0*/ - HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), /*8.0*/ - HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), /*8.0*/ - HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), /*8.0*/ - HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), /*8.0*/ - - /* - * Since 1.3.0 - */ - HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), /*9.0*/ - HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), /*9.0*/ - HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), /*9.0*/ - HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), /*9.0*/ - HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), /*9.0*/ - HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /*9.0*/ - - /* - * Since 1.6.0 - */ - HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), /*10.0*/ - HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), /*10.0*/ - HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), /*10.0*/ - HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), /*10.0*/ - - /* - * Since 1.8.0 - */ - HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), /*11.0*/ - HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), /*11.0*/ - HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), /*11.0*/ - HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), /*11.0*/ - HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), /*11.0*/ - HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), /*11.0*/ - HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), /*11.0*/ - - /* - * Since 2.4.0 - */ - HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), /*12.0*/ - HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), /*12.0*/ - HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), /*12.0*/ - HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), /*12.0*/ - - /* - * Since 2.6.7 - */ - HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/ - HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/ - HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/ - HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/ - - /* - * Since 3.0.0 - */ - HB_SCRIPT_CYPRO_MINOAN = HB_TAG ('C','p','m','n'), /*14.0*/ - HB_SCRIPT_OLD_UYGHUR = HB_TAG ('O','u','g','r'), /*14.0*/ - HB_SCRIPT_TANGSA = HB_TAG ('T','n','s','a'), /*14.0*/ - HB_SCRIPT_TOTO = HB_TAG ('T','o','t','o'), /*14.0*/ - HB_SCRIPT_VITHKUQI = HB_TAG ('V','i','t','h'), /*14.0*/ - - /* - * Since 3.4.0 - */ - HB_SCRIPT_MATH = HB_TAG ('Z','m','t','h'), - - /* - * Since 5.2.0 - */ - HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/ - HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.0*/ - - /* - * Since 10.0.0 - */ - HB_SCRIPT_GARAY = HB_TAG ('G','a','r','a'), /*16.0*/ - HB_SCRIPT_GURUNG_KHEMA = HB_TAG ('G','u','k','h'), /*16.0*/ - HB_SCRIPT_KIRAT_RAI = HB_TAG ('K','r','a','i'), /*16.0*/ - HB_SCRIPT_OL_ONAL = HB_TAG ('O','n','a','o'), /*16.0*/ - HB_SCRIPT_SUNUWAR = HB_TAG ('S','u','n','u'), /*16.0*/ - HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ - HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ - - /* No script set. */ - HB_SCRIPT_INVALID = HB_TAG_NONE, - - /*< private >*/ - - /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t - * without risking undefined behavior. We have two, for historical reasons. - * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed - * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well. - * - * See this thread for technicalities: - * - * https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html - */ - _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/ - _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/ - -} hb_script_t; - +#include "hb-script-list.h" /* Script functions */ @@ -948,6 +519,16 @@ typedef struct hb_glyph_extents_t { */ typedef struct hb_font_t hb_font_t; +/* Not of much use to clients. */ +HB_EXTERN void* +hb_malloc (size_t size); +HB_EXTERN void* +hb_calloc (size_t nmemb, size_t size); +HB_EXTERN void* +hb_realloc (void *ptr, size_t size); +HB_EXTERN void +hb_free (void *ptr); + HB_END_DECLS #endif /* HB_COMMON_H */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-config.hh b/src/java.desktop/share/native/libharfbuzz/hb-config.hh index 40cc2403c18..3956690da35 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-config.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-config.hh @@ -146,6 +146,7 @@ #ifdef HB_NO_DRAW #define HB_NO_OUTLINE +#define HB_NO_PAINT #endif #ifdef HB_NO_GETENV @@ -191,7 +192,6 @@ #ifdef HB_MINIMIZE_MEMORY_USAGE #define HB_NO_GDEF_CACHE #define HB_NO_OT_LAYOUT_LOOKUP_CACHE -#define HB_NO_OT_FONT_ADVANCE_CACHE #define HB_NO_OT_FONT_CMAP_CACHE #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-debug.hh b/src/java.desktop/share/native/libharfbuzz/hb-debug.hh index 341e61e57c6..1e9a18b9326 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-debug.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-debug.hh @@ -49,15 +49,15 @@ struct hb_options_t }; union hb_options_union_t { - int i; + unsigned i; hb_options_t opts; }; -static_assert ((sizeof (hb_atomic_int_t) >= sizeof (hb_options_union_t)), ""); +static_assert ((sizeof (hb_atomic_t) >= sizeof (hb_options_union_t)), ""); HB_INTERNAL void _hb_options_init (); -extern HB_INTERNAL hb_atomic_int_t _hb_options; +extern HB_INTERNAL hb_atomic_t _hb_options; static inline hb_options_t hb_options () diff --git a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h index d854a2b16f5..927563c4c40 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/hb-draw.cc b/src/java.desktop/share/native/libharfbuzz/hb-draw.cc index f2821578b65..8764ffe7129 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-draw.cc +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/hb-draw.h b/src/java.desktop/share/native/libharfbuzz/hb-draw.h index 4556b082d60..06299e17a78 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-draw.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.h @@ -70,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.}, {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/java.desktop/share/native/libharfbuzz/hb-draw.hh b/src/java.desktop/share/native/libharfbuzz/hb-draw.hh index 2c30843de64..224e10939fe 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-draw.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.hh @@ -99,6 +99,7 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (st.path_open)) close_path (draw_data, st); + st.current_x = to_x; st.current_y = to_y; } @@ -109,7 +110,9 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + emit_line_to (draw_data, st, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -121,7 +124,9 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -134,7 +139,9 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -168,9 +175,8 @@ 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_ = 0.f) - : slant {slant_}, not_slanted {slant == 0.f}, - funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT + hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_) + : funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT {} ~hb_draw_session_t () { close_path (); } @@ -178,36 +184,23 @@ struct hb_draw_session_t HB_ALWAYS_INLINE void move_to (float to_x, float to_y) { - if (likely (not_slanted)) - funcs->move_to (draw_data, st, - to_x, to_y); - else - funcs->move_to (draw_data, st, - to_x + to_y * slant, to_y); + funcs->move_to (draw_data, st, + to_x, to_y); } HB_ALWAYS_INLINE void line_to (float to_x, float to_y) { - if (likely (not_slanted)) - funcs->line_to (draw_data, st, - to_x, to_y); - else - funcs->line_to (draw_data, st, - to_x + to_y * slant, to_y); + funcs->line_to (draw_data, st, + to_x, to_y); } void HB_ALWAYS_INLINE quadratic_to (float control_x, float control_y, float to_x, float to_y) { - if (likely (not_slanted)) - funcs->quadratic_to (draw_data, st, - control_x, control_y, - to_x, to_y); - else - funcs->quadratic_to (draw_data, st, - control_x + control_y * slant, control_y, - to_x + to_y * slant, to_y); + funcs->quadratic_to (draw_data, st, + control_x, control_y, + to_x, to_y); } void HB_ALWAYS_INLINE @@ -215,16 +208,10 @@ struct hb_draw_session_t float control2_x, float control2_y, float to_x, float to_y) { - if (likely (not_slanted)) - funcs->cubic_to (draw_data, st, - control1_x, control1_y, - control2_x, control2_y, - to_x, to_y); - else - funcs->cubic_to (draw_data, st, - control1_x + control1_y * slant, control1_y, - control2_x + control2_y * slant, control2_y, - to_x + to_y * slant, to_y); + funcs->cubic_to (draw_data, st, + control1_x, control1_y, + control2_x, control2_y, + to_x, to_y); } HB_ALWAYS_INLINE void close_path () @@ -233,11 +220,14 @@ struct hb_draw_session_t } public: - float slant; - bool not_slanted; hb_draw_funcs_t *funcs; void *draw_data; hb_draw_state_t st; }; + +HB_INTERNAL hb_draw_funcs_t * +hb_draw_extents_get_funcs (); + + #endif /* HB_DRAW_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.cc b/src/java.desktop/share/native/libharfbuzz/hb-face.cc index 7967ae3241b..9d59d7c9468 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.cc @@ -34,6 +34,16 @@ #include "hb-ot-face.hh" #include "hb-ot-cmap-table.hh" +#ifdef HAVE_FREETYPE +#include "hb-ft.h" +#endif +#ifdef HAVE_CORETEXT +#include "hb-coretext.h" +#endif +#ifdef HAVE_DIRECTWRITE +#include "hb-directwrite.h" +#endif + /** * SECTION:hb-face @@ -72,14 +82,14 @@ hb_face_count (hb_blob_t *blob) if (unlikely (!blob)) return 0; - /* TODO We shouldn't be sanitizing blob. Port to run sanitizer and return if not sane. */ - /* Make API signature const after. */ - hb_blob_t *sanitized = hb_sanitize_context_t ().sanitize_blob (hb_blob_reference (blob)); - const OT::OpenTypeFontFile& ot = *sanitized->as (); - unsigned int ret = ot.get_face_count (); - hb_blob_destroy (sanitized); + hb_sanitize_context_t c (blob); + + const char *start = hb_blob_get_data (blob, nullptr); + auto *ot = reinterpret_cast (const_cast (start)); + if (unlikely (!ot->sanitize (&c))) + return 0; - return ret; + return ot->get_face_count (); } /* @@ -318,7 +328,209 @@ hb_face_create_from_file_or_fail (const char *file_name, return face; } + +static struct supported_face_loaders_t { + char name[16]; + hb_face_t * (*from_file) (const char *font_file, unsigned face_index); + hb_face_t * (*from_blob) (hb_blob_t *blob, unsigned face_index); +} supported_face_loaders[] = +{ + {"ot", +#ifndef HB_NO_OPEN + hb_face_create_from_file_or_fail, +#else + nullptr, +#endif + hb_face_create_or_fail + }, +#ifdef HAVE_FREETYPE + {"ft", + hb_ft_face_create_from_file_or_fail, + hb_ft_face_create_from_blob_or_fail + }, +#endif +#ifdef HAVE_CORETEXT + {"coretext", + hb_coretext_face_create_from_file_or_fail, + hb_coretext_face_create_from_blob_or_fail + }, #endif +#ifdef HAVE_DIRECTWRITE + {"directwrite", + hb_directwrite_face_create_from_file_or_fail, + hb_directwrite_face_create_from_blob_or_fail + }, +#endif +}; + +static const char *get_default_loader_name () +{ + static hb_atomic_t static_loader_name; + const char *loader_name = static_loader_name.get_acquire (); + if (!loader_name) + { + loader_name = getenv ("HB_FACE_LOADER"); + if (!loader_name) + loader_name = ""; + if (!static_loader_name.cmpexch (nullptr, loader_name)) + loader_name = static_loader_name.get_acquire (); + } + return loader_name; +} + +/** + * hb_face_create_from_file_or_fail_using: + * @file_name: A font filename + * @index: The index of the face within the file + * @loader_name: (nullable): The name of the loader to use, or `NULL` + * + * A thin wrapper around the face loader functions registered with HarfBuzz. + * If @loader_name is `NULL` or the empty string, the first available loader + * is used. + * + * For example, the FreeType ("ft") loader might be able to load + * WOFF and WOFF2 files if FreeType is built with those features, + * whereas the OpenType ("ot") loader will not. + * + * Return value: (transfer full): The new face object, or `NULL` if + * the file cannot be read or the loader fails to load the face. + * + * Since: 11.0.0 + **/ +hb_face_t * +hb_face_create_from_file_or_fail_using (const char *file_name, + unsigned int index, + const char *loader_name) +{ + // Duplicated in hb_face_create_or_fail_using + bool retry = false; + if (!loader_name || !*loader_name) + { + loader_name = get_default_loader_name (); + retry = true; + } + if (loader_name && !*loader_name) loader_name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + { + if (!loader_name || (supported_face_loaders[i].from_file && !strcmp (supported_face_loaders[i].name, loader_name))) + return supported_face_loaders[i].from_file (file_name, index); + } + + if (retry) + { + retry = false; + loader_name = nullptr; + goto retry; + } + + return nullptr; +} + +/** + * hb_face_create_or_fail_using: + * @blob: #hb_blob_t to work upon + * @index: The index of the face within @blob + * @loader_name: (nullable): The name of the loader to use, or `NULL` + * + * A thin wrapper around the face loader functions registered with HarfBuzz. + * If @loader_name is `NULL` or the empty string, the first available loader + * is used. + * + * For example, the FreeType ("ft") loader might be able to load + * WOFF and WOFF2 files if FreeType is built with those features, + * whereas the OpenType ("ot") loader will not. + * + * Return value: (transfer full): The new face object, or `NULL` if + * the loader fails to load the face. + * + * Since: 11.0.0 + **/ +hb_face_t * +hb_face_create_or_fail_using (hb_blob_t *blob, + unsigned int index, + const char *loader_name) +{ + // Duplicated in hb_face_create_from_file_or_fail_using + bool retry = false; + if (!loader_name || !*loader_name) + { + loader_name = get_default_loader_name (); + retry = true; + } + if (loader_name && !*loader_name) loader_name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + { + if (!loader_name || (supported_face_loaders[i].from_blob && !strcmp (supported_face_loaders[i].name, loader_name))) + return supported_face_loaders[i].from_blob (blob, index); + } + + if (retry) + { + retry = false; + loader_name = nullptr; + goto retry; + } + + return nullptr; +} + +static inline void free_static_face_loader_list (); + +static const char * const nil_face_loader_list[] = {nullptr}; + +static struct hb_face_loader_list_lazy_loader_t : hb_lazy_loader_t +{ + static const char ** create () + { + const char **face_loader_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_face_loaders), sizeof (const char *)); + if (unlikely (!face_loader_list)) + return nullptr; + + unsigned i; + for (i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + face_loader_list[i] = supported_face_loaders[i].name; + face_loader_list[i] = nullptr; + + hb_atexit (free_static_face_loader_list); + + return face_loader_list; + } + static void destroy (const char **l) + { hb_free (l); } + static const char * const * get_null () + { return nil_face_loader_list; } +} static_face_loader_list; + +static inline +void free_static_face_loader_list () +{ + static_face_loader_list.free_instance (); +} + +/** + * hb_face_list_loaders: + * + * Retrieves the list of face loaders supported by HarfBuzz. + * + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported face loaders + * constant strings. The returned array is owned by HarfBuzz + * and should not be modified or freed. + * + * Since: 11.0.0 + **/ +const char ** +hb_face_list_loaders () +{ + return static_face_loader_list.get_unconst (); +} +#endif + /** * hb_face_get_empty: @@ -460,7 +672,7 @@ hb_face_make_immutable (hb_face_t *face) * Since: 0.9.2 **/ hb_bool_t -hb_face_is_immutable (const hb_face_t *face) +hb_face_is_immutable (hb_face_t *face) { return hb_object_is_immutable (face); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.h b/src/java.desktop/share/native/libharfbuzz/hb-face.h index 953298fa50b..2c130f00fee 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.h @@ -63,10 +63,24 @@ HB_EXTERN hb_face_t * hb_face_create_or_fail (hb_blob_t *blob, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_or_fail_using (hb_blob_t *blob, + unsigned int index, + const char *loader_name); + HB_EXTERN hb_face_t * hb_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_from_file_or_fail_using (const char *file_name, + unsigned int index, + const char *loader_name); + +HB_EXTERN const char ** +hb_face_list_loaders (void); + + /** * hb_reference_table_func_t: * @face: an #hb_face_t to reference table for @@ -117,7 +131,7 @@ HB_EXTERN void hb_face_make_immutable (hb_face_t *face); HB_EXTERN hb_bool_t -hb_face_is_immutable (const hb_face_t *face); +hb_face_is_immutable (hb_face_t *face); HB_EXTERN hb_blob_t * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.hh b/src/java.desktop/share/native/libharfbuzz/hb-face.hh index 4d12030f187..e58e8f9b94c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.hh @@ -49,8 +49,8 @@ struct hb_face_t hb_object_header_t header; unsigned int index; /* Face index in a collection, zero-based. */ - mutable hb_atomic_int_t upem; /* Units-per-EM. */ - mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + mutable hb_atomic_t upem; /* Units-per-EM. */ + mutable hb_atomic_t num_glyphs;/* Number of glyphs. */ hb_reference_table_func_t reference_table_func; void *user_data; @@ -70,7 +70,7 @@ struct hb_face_t plan_node_t *next; }; #ifndef HB_NO_SHAPER - hb_atomic_ptr_t shape_plans; + hb_atomic_t shape_plans; #endif hb_blob_t *reference_table (hb_tag_t tag) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-font.cc index 0c9084c574f..849855e2c22 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.cc @@ -38,6 +38,22 @@ #include "hb-ot-var-avar-table.hh" #include "hb-ot-var-fvar-table.hh" +#ifndef HB_NO_OT_FONT +#include "hb-ot.h" +#endif +#ifdef HAVE_FREETYPE +#include "hb-ft.h" +#endif +#ifdef HAVE_FONTATIONS +#include "hb-fontations.h" +#endif +#ifdef HAVE_CORETEXT +#include "hb-coretext.h" +#endif +#ifdef HAVE_DIRECTWRITE +#include "hb-directwrite.h" +#endif + /** * SECTION:hb-font @@ -87,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); @@ -112,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); @@ -218,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 @@ -243,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 @@ -265,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); } @@ -274,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); @@ -297,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); } @@ -306,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); @@ -426,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); @@ -456,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; @@ -508,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 { @@ -535,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 @@ -548,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 @@ -563,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 @@ -582,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 @@ -603,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 @@ -634,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) = @@ -1413,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 @@ -1422,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. * @@ -1429,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); } /** @@ -1444,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 @@ -1466,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 @@ -1854,10 +1957,7 @@ hb_font_create (hb_face_t *face) { hb_font_t *font = _hb_font_create (face); -#ifndef HB_NO_OT_FONT - /* Install our in-house, very lightweight, funcs. */ - hb_ot_font_set_funcs (font); -#endif + hb_font_set_funcs_using (font, nullptr); #ifndef HB_NO_VAR if (face && face->index >> 16) @@ -1880,7 +1980,8 @@ _hb_font_adopt_var_coords (hb_font_t *font, font->design_coords = design_coords; font->num_coords = coords_length; - font->mults_changed (); // Easiest to call this to drop cached data + font->changed (); + font->serial_coords = font->serial; } /** @@ -1935,7 +2036,8 @@ hb_font_create_sub_font (hb_font_t *parent) } } - font->mults_changed (); + font->changed (); + font->serial_coords = font->serial; return font; } @@ -2023,7 +2125,7 @@ hb_font_set_user_data (hb_font_t *font, hb_bool_t replace) { if (!hb_object_is_immutable (font)) - font->serial++; + font->changed (); return hb_object_set_user_data (font, key, data, destroy, replace); } @@ -2098,7 +2200,7 @@ hb_font_is_immutable (hb_font_t *font) unsigned int hb_font_get_serial (hb_font_t *font) { - return font->serial; + return font->serial.get_acquire (); } /** @@ -2117,9 +2219,7 @@ hb_font_changed (hb_font_t *font) if (hb_object_is_immutable (font)) return; - font->serial++; - - font->mults_changed (); + font->changed (); } /** @@ -2141,8 +2241,6 @@ hb_font_set_parent (hb_font_t *font, if (parent == font->parent) return; - font->serial++; - if (!parent) parent = hb_font_get_empty (); @@ -2151,6 +2249,8 @@ hb_font_set_parent (hb_font_t *font, font->parent = hb_font_reference (parent); hb_font_destroy (old); + + font->changed (); } /** @@ -2188,8 +2288,6 @@ hb_font_set_face (hb_font_t *font, if (face == font->face) return; - font->serial++; - if (unlikely (!face)) face = hb_face_get_empty (); @@ -2197,9 +2295,12 @@ hb_font_set_face (hb_font_t *font, hb_face_make_immutable (face); font->face = hb_face_reference (face); - font->mults_changed (); + font->changed (); hb_face_destroy (old); + + font->changed (); + font->serial_coords = font->serial; } /** @@ -2244,8 +2345,6 @@ hb_font_set_funcs (hb_font_t *font, return; } - font->serial++; - if (font->destroy) font->destroy (font->user_data); @@ -2257,6 +2356,8 @@ hb_font_set_funcs (hb_font_t *font, font->klass = klass; font->user_data = font_data; font->destroy = destroy; + + font->changed (); } /** @@ -2283,15 +2384,151 @@ hb_font_set_funcs_data (hb_font_t *font, return; } - font->serial++; - if (font->destroy) font->destroy (font->user_data); font->user_data = font_data; font->destroy = destroy; + + font->changed (); +} + +static struct supported_font_funcs_t { + char name[16]; + void (*func) (hb_font_t *); +} supported_font_funcs[] = +{ +#ifndef HB_NO_OT_FONT + {"ot", hb_ot_font_set_funcs}, +#endif +#ifdef HAVE_FREETYPE + {"ft", hb_ft_font_set_funcs}, +#endif +#ifdef HAVE_FONTATIONS + {"fontations",hb_fontations_font_set_funcs}, +#endif +#ifdef HAVE_CORETEXT + {"coretext", hb_coretext_font_set_funcs}, +#endif +#ifdef HAVE_DIRECTWRITE + {"directwrite",hb_directwrite_font_set_funcs}, +#endif +}; + +static const char *get_default_funcs_name () +{ + static hb_atomic_t static_funcs_name; + const char *name = static_funcs_name.get_acquire (); + if (!name) + { + name = getenv ("HB_FONT_FUNCS"); + if (!name) + name = ""; + if (!static_funcs_name.cmpexch (nullptr, name)) + name = static_funcs_name.get_acquire (); + } + return name; +} + +/** + * hb_font_set_funcs_using: + * @font: #hb_font_t to work upon + * @name: The name of the font-functions structure to use, or `NULL` + * + * Sets the font-functions structure to use for a font, based on the + * specified name. + * + * If @name is `NULL` or the empty string, the default (first) functioning font-functions + * are used. This default can be changed by setting the `HB_FONT_FUNCS` environment + * variable to the name of the desired font-functions. + * + * Return value: `true` if the font-functions was found and set, `false` otherwise + * + * Since: 11.0.0 + **/ +hb_bool_t +hb_font_set_funcs_using (hb_font_t *font, + const char *name) +{ + bool retry = false; + + if (!name || !*name) + { + name = get_default_funcs_name (); + retry = true; + } + if (name && !*name) name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) + if (!name || strcmp (supported_font_funcs[i].name, name) == 0) + { + supported_font_funcs[i].func (font); + if (name || font->klass != hb_font_funcs_get_empty ()) + return true; + } + + if (retry) + { + retry = false; + name = nullptr; + goto retry; + } + + return false; } +static inline void free_static_font_funcs_list (); + +static const char * const nil_font_funcs_list[] = {nullptr}; + +static struct hb_font_funcs_list_lazy_loader_t : hb_lazy_loader_t +{ + static const char ** create () + { + const char **font_funcs_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_font_funcs), sizeof (const char *)); + if (unlikely (!font_funcs_list)) + return nullptr; + + unsigned i; + for (i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) + font_funcs_list[i] = supported_font_funcs[i].name; + font_funcs_list[i] = nullptr; + + hb_atexit (free_static_font_funcs_list); + + return font_funcs_list; + } + static void destroy (const char **l) + { hb_free (l); } + static const char * const * get_null () + { return nil_font_funcs_list; } +} static_font_funcs_list; + +static inline +void free_static_font_funcs_list () +{ + static_font_funcs_list.free_instance (); +} + +/** + * hb_font_list_funcs: + * + * Retrieves the list of font functions supported by HarfBuzz. + * + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported font functions + * constant strings. The returned array is owned by HarfBuzz + * and should not be modified or freed. + * + * Since: 11.0.0 + **/ +const char ** +hb_font_list_funcs () +{ + return static_font_funcs_list.get_unconst (); +} /** * hb_font_set_scale: @@ -2339,11 +2576,10 @@ hb_font_set_scale (hb_font_t *font, if (font->x_scale == x_scale && font->y_scale == y_scale) return; - font->serial++; - font->x_scale = x_scale; font->y_scale = y_scale; - font->mults_changed (); + + font->changed (); } /** @@ -2390,10 +2626,10 @@ hb_font_set_ppem (hb_font_t *font, if (font->x_ppem == x_ppem && font->y_ppem == y_ppem) return; - font->serial++; - font->x_ppem = x_ppem; font->y_ppem = y_ppem; + + font->changed (); } /** @@ -2437,9 +2673,9 @@ hb_font_set_ptem (hb_font_t *font, if (font->ptem == ptem) return; - font->serial++; - font->ptem = ptem; + + font->changed (); } /** @@ -2459,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 @@ -2476,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 @@ -2499,12 +2752,11 @@ hb_font_set_synthetic_bold (hb_font_t *font, font->embolden_in_place == (bool) in_place) return; - font->serial++; - font->x_embolden = x_embolden; font->y_embolden = y_embolden; font->embolden_in_place = in_place; - font->mults_changed (); + + font->changed (); } /** @@ -2541,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 @@ -2558,10 +2810,9 @@ hb_font_set_synthetic_slant (hb_font_t *font, float slant) if (font->slant == slant) return; - font->serial++; - font->slant = slant; - font->mults_changed (); + + font->changed (); } /** @@ -2607,8 +2858,6 @@ hb_font_set_variations (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE) { hb_font_set_var_coords_normalized (font, nullptr, 0); @@ -2677,8 +2926,6 @@ hb_font_set_variation (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - // TODO Share some of this code with set_variations() const OT::fvar &fvar = *font->face->table.fvar; @@ -2749,8 +2996,6 @@ hb_font_set_var_coords_design (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; @@ -2787,8 +3032,6 @@ hb_font_set_var_named_instance (hb_font_t *font, if (font->instance_index == instance_index) return; - font->serial_coords = ++font->serial; - font->instance_index = instance_index; hb_font_set_variations (font, nullptr, 0); } @@ -2834,8 +3077,6 @@ hb_font_set_var_coords_normalized (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr; @@ -3058,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/java.desktop/share/native/libharfbuzz/hb-font.h b/src/java.desktop/share/native/libharfbuzz/hb-font.h index f16658d9d88..4e267ba6a80 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.h +++ b/src/java.desktop/share/native/libharfbuzz/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 @@ -1052,6 +1068,12 @@ hb_font_set_funcs_data (hb_font_t *font, void *font_data, hb_destroy_func_t destroy); +HB_EXTERN hb_bool_t +hb_font_set_funcs_using (hb_font_t *font, + const char *name); + +HB_EXTERN const char ** +hb_font_list_funcs (void); HB_EXTERN void hb_font_set_scale (hb_font_t *font, @@ -1086,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/java.desktop/share/native/libharfbuzz/hb-font.hh b/src/java.desktop/share/native/libharfbuzz/hb-font.hh index 8273f347562..69d8d4b09df 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.hh @@ -32,7 +32,11 @@ #include "hb.hh" #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" /* @@ -57,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 @@ -105,8 +109,8 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t); struct hb_font_t { hb_object_header_t header; - unsigned int serial; - unsigned int serial_coords; + hb_atomic_t serial; + hb_atomic_t serial_coords; hb_font_t *parent; hb_face_t *face; @@ -191,23 +195,35 @@ struct hb_font_t void scale_glyph_extents (hb_glyph_extents_t *extents) { - float x1 = em_fscale_x (extents->x_bearing); - float y1 = em_fscale_y (extents->y_bearing); - float x2 = em_fscale_x (extents->x_bearing + extents->width); - float y2 = em_fscale_y (extents->y_bearing + extents->height); + float x1 = em_scale_x (extents->x_bearing); + float y1 = em_scale_y (extents->y_bearing); + float x2 = em_scale_x (extents->x_bearing + extents->width); + float y2 = em_scale_y (extents->y_bearing + extents->height); - /* Apply slant. */ + extents->x_bearing = roundf (x1); + extents->y_bearing = roundf (y1); + extents->width = roundf (x2) - extents->x_bearing; + extents->height = roundf (y2) - extents->y_bearing; + } + + void synthetic_glyph_extents (hb_glyph_extents_t *extents) + { + /* Slant. */ if (slant_xy) { - x1 += hb_min (y1 * slant_xy, y2 * slant_xy); - x2 += hb_max (y1 * slant_xy, y2 * slant_xy); - } + hb_position_t x1 = extents->x_bearing; + hb_position_t y1 = extents->y_bearing; + hb_position_t x2 = extents->x_bearing + extents->width; + hb_position_t y2 = extents->y_bearing + extents->height; + + x1 += floorf (hb_min (y1 * slant_xy, y2 * slant_xy)); + x2 += ceilf (hb_max (y1 * slant_xy, y2 * slant_xy)); - extents->x_bearing = floorf (x1); - extents->y_bearing = floorf (y1); - extents->width = ceilf (x2) - extents->x_bearing; - extents->height = ceilf (y2) - extents->y_bearing; + extents->x_bearing = x1; + extents->width = x2 - extents->x_bearing; + } + /* Embolden. */ if (x_strength || y_strength) { /* Y */ @@ -250,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) @@ -303,44 +345,88 @@ 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) { - return klass->get.f.glyph_h_advance (this, user_data, - glyph, - !klass->user_data ? nullptr : klass->user_data->glyph_h_advance); + 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 (synthetic && x_strength && !embolden_in_place) + { + /* Embolden */ + hb_position_t strength = x_scale >= 0 ? x_strength : -x_strength; + advance += advance ? strength : 0; + } + + 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) { - return klass->get.f.glyph_v_advance (this, user_data, - glyph, - !klass->user_data ? nullptr : klass->user_data->glyph_v_advance); + 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 (synthetic && y_strength && !embolden_in_place) + { + /* Embolden */ + hb_position_t strength = y_scale >= 0 ? y_strength : -y_strength; + advance += advance ? strength : 0; + } + + return advance; } void get_glyph_h_advances (unsigned int count, 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) { - return klass->get.f.glyph_h_advances (this, user_data, - count, - first_glyph, glyph_stride, - first_advance, advance_stride, - !klass->user_data ? nullptr : klass->user_data->glyph_h_advances); + klass->get.f.glyph_h_advances (this, user_data, + count, + first_glyph, glyph_stride, + first_advance, advance_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_h_advances); + + if (synthetic && x_strength && !embolden_in_place) + { + /* Embolden */ + hb_position_t strength = x_scale >= 0 ? x_strength : -x_strength; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } void get_glyph_v_advances (unsigned int count, 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) { - return klass->get.f.glyph_v_advances (this, user_data, - count, - first_glyph, glyph_stride, - first_advance, advance_stride, - !klass->user_data ? nullptr : klass->user_data->glyph_v_advances); + klass->get.f.glyph_v_advances (this, user_data, + count, + first_glyph, glyph_stride, + first_advance, advance_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_v_advances); + + if (synthetic && y_strength && !embolden_in_place) + { + /* Embolden */ + hb_position_t strength = y_scale >= 0 ? y_strength : -y_strength; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, @@ -386,23 +472,82 @@ 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)); - return klass->get.f.glyph_extents (this, user_data, - glyph, - extents, - !klass->user_data ? nullptr : klass->user_data->glyph_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. */ + + 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; + } + + 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; + } + + bool ret = klass->get.f.glyph_extents (this, user_data, + glyph, + extents, + !klass->user_data ? nullptr : klass->user_data->glyph_extents); + if (ret) + synthetic_glyph_extents (extents); + + return ret; } 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, @@ -426,29 +571,88 @@ 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) { - klass->get.f.draw_glyph (this, user_data, - glyph, - draw_funcs, draw_data, - !klass->user_data ? nullptr : klass->user_data->draw_glyph); +#ifndef HB_NO_OUTLINE + bool embolden = x_strength || y_strength; + bool slanted = slant_xy; + synthetic = synthetic && (embolden || slanted); +#else + synthetic = false; +#endif + + if (!synthetic) + { + 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 + + 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 } - 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); + /* 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; } /* 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)) @@ -686,7 +890,12 @@ struct hb_font_t return false; } - void mults_changed () + bool is_synthetic () const + { + return x_embolden || y_embolden || slant; + } + + void changed () { float upem = face->get_upem (); @@ -697,12 +906,14 @@ struct hb_font_t bool y_neg = y_scale < 0; y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; - x_strength = fabsf (roundf (x_scale * x_embolden)); - y_strength = fabsf (roundf (y_scale * y_embolden)); + x_strength = roundf (abs (x_scale) * x_embolden); + y_strength = roundf (abs (y_scale) * y_embolden); slant_xy = y_scale ? slant * x_scale / y_scale : 0.f; data.fini (); + + serial++; } hb_position_t em_mult (int16_t v, int64_t mult) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc index b126d2022d1..e9c0e734a53 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc @@ -37,11 +37,7 @@ #include "hb-draw.hh" #include "hb-font.hh" #include "hb-machinery.hh" -#ifndef HB_NO_AAT -#include "hb-aat-layout-trak-table.hh" -#endif #include "hb-ot-os2-table.hh" -#include "hb-ot-stat-table.hh" #include "hb-ot-shaper-arabic-pua.hh" #include "hb-paint.hh" @@ -101,7 +97,7 @@ struct hb_ft_font_t mutable hb_mutex_t lock; /* Protects members below. */ FT_Face ft_face; - mutable unsigned cached_serial; + mutable hb_atomic_t cached_serial; mutable hb_ft_advance_cache_t advance_cache; }; @@ -118,7 +114,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; - ft_font->cached_serial = (unsigned) -1; + ft_font->cached_serial = UINT_MAX; new (&ft_font->advance_cache) hb_ft_advance_cache_t; return ft_font; @@ -213,9 +209,10 @@ _hb_ft_hb_font_check_changed (hb_font_t *font, { if (font->serial != ft_font->cached_serial) { + hb_lock_t lock (ft_font->lock); _hb_ft_hb_font_changed (font, ft_font->ft_face); ft_font->advance_cache.clear (); - ft_font->cached_serial = font->serial; + ft_font->cached_serial.set_release (font->serial.get_acquire ()); return true; } return false; @@ -478,7 +475,8 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_position_t *orig_first_advance = first_advance; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; int load_flags = ft_font->load_flags; @@ -519,38 +517,6 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } - - if (font->x_strength && !font->embolden_in_place) - { - /* Emboldening. */ - hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength; - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += *first_advance ? x_strength : 0; - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } - -#ifndef HB_NO_AAT - /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ -#ifndef HB_NO_STYLE - bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); -#else - bool apply_trak = false; -#endif - if (apply_trak) - { - hb_position_t tracking = font->face->table.trak->get_h_tracking (font); - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += tracking; - first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } -#endif } #ifndef HB_NO_VERTICAL @@ -561,6 +527,8 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, 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); + hb_lock_t lock (ft_font->lock); FT_Fixed v; float y_mult; @@ -581,26 +549,11 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) return 0; - v = (int) (y_mult * v); - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates * have a Y growing upward. Hence the extra negation. */ + v = ((-v + (1<<9)) >> 10); - hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - v = ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); - -#ifndef HB_NO_AAT - /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ -#ifndef HB_NO_STYLE - bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); -#else - bool apply_trak = false; -#endif - if (apply_trak) - v += font->face->table.trak->get_v_tracking (font); -#endif - - return v; + return (hb_position_t) (y_mult * v); } #endif @@ -614,6 +567,8 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, 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); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float x_mult, y_mult; @@ -658,6 +613,8 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font, 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); + hb_lock_t lock (ft_font->lock); FT_Vector kerningv; @@ -669,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, @@ -676,11 +668,17 @@ 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); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float x_mult, y_mult; - float slant_xy = font->slant_xy; + #ifdef HAVE_FT_GET_TRANSFORM if (ft_font->transform) { @@ -708,33 +706,10 @@ hb_ft_get_glyph_extents (hb_font_t *font, float x2 = x1 + x_mult * ft_face->glyph->metrics.width; float y2 = y1 + y_mult * -ft_face->glyph->metrics.height; - /* Apply slant. */ - if (slant_xy) - { - x1 += hb_min (y1 * slant_xy, y2 * slant_xy); - x2 += hb_max (y1 * slant_xy, y2 * slant_xy); - } - - extents->x_bearing = floorf (x1); - extents->y_bearing = floorf (y1); - extents->width = ceilf (x2) - extents->x_bearing; - extents->height = ceilf (y2) - extents->y_bearing; - - if (font->x_strength || font->y_strength) - { - /* Y */ - int y_shift = font->y_strength; - if (font->y_scale < 0) y_shift = -y_shift; - extents->y_bearing += y_shift; - extents->height -= y_shift; - - /* X */ - int x_shift = font->x_strength; - if (font->x_scale < 0) x_shift = -x_shift; - if (font->embolden_in_place) - extents->x_bearing -= x_shift / 2; - extents->width += x_shift; - } + extents->x_bearing = roundf (x1); + extents->y_bearing = roundf (y1); + extents->width = roundf (x2) - extents->x_bearing; + extents->height = roundf (y2) - extents->y_bearing; return true; } @@ -749,6 +724,8 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED, 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); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; @@ -826,6 +803,8 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, 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); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float y_mult; @@ -857,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); @@ -908,23 +887,25 @@ _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); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; 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, @@ -935,43 +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); - - /* Embolden */ - if (font->x_strength || font->y_strength) - { - FT_Outline_EmboldenXY (&ft_face->glyph->outline, font->x_strength, font->y_strength); - - int x_shift = 0; - int y_shift = 0; - if (font->embolden_in_place) - { - /* Undo the FreeType shift. */ - x_shift = -font->x_strength / 2; - y_shift = 0; - if (font->y_scale < 0) y_shift = -font->y_strength; - } - else - { - /* FreeType applied things in the wrong direction for negative scale; fix up. */ - if (font->x_scale < 0) x_shift = -font->x_strength; - if (font->y_scale < 0) y_shift = -font->y_strength; - } - if (x_shift || y_shift) - { - auto &outline = ft_face->glyph->outline; - for (auto &point : hb_iter (outline.points, outline.contours[outline.n_contours - 1] + 1)) - { - point.x += x_shift; - point.y += y_shift; - } - } - } - + hb_draw_session_t draw_session {draw_funcs, draw_data}; FT_Outline_Decompose (&ft_face->glyph->outline, &outline_funcs, &draw_session); + + return true; } #endif @@ -980,20 +931,22 @@ 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); + 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 @@ -1002,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) { @@ -1010,26 +963,21 @@ hb_ft_paint_glyph (hb_font_t *font, paint_funcs, paint_data, palette_index, foreground, user_data)) - return; - - /* 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 true; - 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 (); @@ -1039,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 @@ -1079,10 +1026,8 @@ 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 @@ -1456,6 +1400,10 @@ hb_ft_font_changed (hb_font_t *font) * variation-axis settings on the @font. * This call is fast if nothing has changed on @font. * + * Note that as of version 11.0.0, calling this function is not necessary, + * as HarfBuzz will automatically detect changes to the font and update + * the underlying FT_Face as needed. + * * Return value: true if changed, false otherwise * * Since: 4.4.0 @@ -1587,7 +1535,8 @@ destroy_ft_library (void *arg) * font file and face index. * * This is similar in functionality to hb_face_create_from_file_or_fail(), - * but uses the FreeType library for loading the font file. + * but uses the FreeType library for loading the font file. This can + * be useful, for example, to load WOFF and WOFF2 font data. * * Return value: (transfer full): The new face object, or `NULL` if * no face is found at the specified index or the file cannot be read. @@ -1624,6 +1573,75 @@ hb_ft_face_create_from_file_or_fail (const char *file_name, return face; } +static hb_user_data_key_t ft_blob_key = {0}; + +static void +_destroy_blob (void *p) +{ + hb_blob_destroy ((hb_blob_t *) p); +} + +/** + * hb_ft_face_create_from_blob_or_fail: + * @blob: A blob + * @index: The index of the face within the blob + * + * Creates an #hb_face_t face object from the specified + * font blob and face index. + * + * This is similar in functionality to hb_face_create_from_blob_or_fail(), + * but uses the FreeType library for loading the font blob. This can + * be useful, for example, to load WOFF and WOFF2 font data. + * + * Return value: (transfer full): The new face object, or `NULL` if + * loading fails (eg. blob does not contain valid font data). + * + * Since: 11.0.0 + */ +hb_face_t * +hb_ft_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index) +{ + FT_Library ft_library = reference_ft_library (); + if (unlikely (!ft_library)) + { + DEBUG_MSG (FT, ft_library, "reference_ft_library failed"); + return nullptr; + } + + hb_blob_make_immutable (blob); + unsigned blob_size; + const char *blob_data = hb_blob_get_data (blob, &blob_size); + + FT_Face ft_face; + if (unlikely (FT_New_Memory_Face (ft_library, + (const FT_Byte *) blob_data, + blob_size, + index, + &ft_face))) + return nullptr; + + hb_face_t *face = hb_ft_face_create_referenced (ft_face); + FT_Done_Face (ft_face); + + ft_face->generic.data = ft_library; + ft_face->generic.finalizer = finalize_ft_library; + + if (hb_face_is_immutable (face)) + return nullptr; + + // Hook the blob to the hb_face_t, since FT_Face still needs it. + hb_blob_reference (blob); + if (!hb_face_set_user_data (face, &ft_blob_key, blob, _destroy_blob, true)) + { + hb_blob_destroy (blob); + hb_face_destroy (face); + return nullptr; + } + + return face; +} + static void _release_blob (void *arg) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ft.h b/src/java.desktop/share/native/libharfbuzz/hb-ft.h index 94952f48a05..9f83b91abb6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ft.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.h @@ -88,6 +88,10 @@ HB_EXTERN hb_face_t * hb_ft_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_ft_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index); + /* * hb-font from ft-face. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh index e91e371dc0c..795f29f6ab0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh @@ -30,6 +30,11 @@ struct hb_extents_t { hb_extents_t () {} + hb_extents_t (const hb_glyph_extents_t &extents) : + xmin (hb_min (extents.x_bearing, extents.x_bearing + extents.width)), + ymin (hb_min (extents.y_bearing, extents.y_bearing + extents.height)), + xmax (hb_max (extents.x_bearing, extents.x_bearing + extents.width)), + ymax (hb_max (extents.y_bearing, extents.y_bearing + extents.height)) {} hb_extents_t (float xmin, float ymin, float xmax, float ymax) : xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} @@ -38,6 +43,12 @@ struct hb_extents_t void union_ (const hb_extents_t &o) { + if (o.is_empty ()) return; + if (is_empty ()) + { + *this = o; + return; + } xmin = hb_min (xmin, o.xmin); ymin = hb_min (ymin, o.ymin); xmax = hb_max (xmax, o.xmax); @@ -46,6 +57,11 @@ struct hb_extents_t void intersect (const hb_extents_t &o) { + if (o.is_empty () || is_empty ()) + { + *this = hb_extents_t {}; + return; + } xmin = hb_max (xmin, o.xmin); ymin = hb_max (ymin, o.ymin); xmax = hb_min (xmax, o.xmax); @@ -69,6 +85,18 @@ struct hb_extents_t } } + hb_glyph_extents_t to_glyph_extents (bool xneg = false, bool yneg = false) const + { + hb_position_t x0 = (hb_position_t) roundf (xmin); + hb_position_t y0 = (hb_position_t) roundf (ymin); + hb_position_t x1 = (hb_position_t) roundf (xmax); + hb_position_t y1 = (hb_position_t) roundf (ymax); + return hb_glyph_extents_t {xneg ? x1 : x0, + yneg ? y0 : y1, + xneg ? x0 - x1 : x1 - x0, + yneg ? y1 - y0 : y0 - y1}; + } + float xmin = 0.f; float ymin = 0.f; float xmax = -1.f; @@ -218,7 +246,7 @@ struct hb_bounds_t EMPTY, }; - hb_bounds_t (status_t status) : status (status) {} + hb_bounds_t (status_t status = UNBOUNDED) : status (status) {} hb_bounds_t (const hb_extents_t &extents) : status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} diff --git a/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh b/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh index 580c9f0c785..ffbb8f3d301 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh @@ -273,7 +273,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t private: /* Must only have one pointer. */ - hb_atomic_ptr_t instance; + mutable hb_atomic_t instance; }; /* Specializations. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-mutex.hh b/src/java.desktop/share/native/libharfbuzz/hb-mutex.hh index 72012bd2e64..4b6c5a118ae 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-mutex.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-mutex.hh @@ -99,6 +99,8 @@ struct hb_mutex_t hb_mutex_t () { init (); } ~hb_mutex_t () { fini (); } + hb_mutex_t (const hb_mutex_t &) = delete; + hb_mutex_t &operator= (const hb_mutex_t &) = delete; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" @@ -114,6 +116,10 @@ struct hb_lock_t hb_lock_t (hb_mutex_t &mutex_) : mutex (&mutex_) { mutex->lock (); } hb_lock_t (hb_mutex_t *mutex_) : mutex (mutex_) { if (mutex) mutex->lock (); } ~hb_lock_t () { if (mutex) mutex->unlock (); } + + hb_lock_t (const hb_lock_t &) = delete; + hb_lock_t &operator= (const hb_lock_t &) = delete; + private: hb_mutex_t *mutex; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-object.hh b/src/java.desktop/share/native/libharfbuzz/hb-object.hh index c02ec8bfacf..fa9a249b2e2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-object.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-object.hh @@ -142,7 +142,7 @@ struct hb_lockable_set_t struct hb_reference_count_t { - mutable hb_atomic_int_t ref_count; + mutable hb_atomic_t ref_count; void init (int v = 1) { ref_count = v; } int get_relaxed () const { return ref_count; } @@ -213,8 +213,8 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; - mutable hb_atomic_int_t writable = 0; - hb_atomic_ptr_t user_data; + mutable hb_atomic_t writable = false; + hb_atomic_t user_data; bool is_inert () const { return !ref_count.get_relaxed (); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh index 89da9c7bc95..75d87f11ea5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh @@ -1888,7 +1888,7 @@ struct TupleValues bool ensure_run () { - if (likely (run_count > 0)) return true; + if (run_count > 0) return true; if (unlikely (p >= end)) { @@ -1943,6 +1943,11 @@ struct TupleValues unsigned count = hb_min (n - i, (unsigned) run_count); switch (width) { + case 0: + { + arrayZ += count; + break; + } case 1: { const auto *pp = (const HBINT8 *) p; @@ -1958,6 +1963,8 @@ struct TupleValues #endif for (; j < count; j++) *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; } break; case 2: @@ -1975,6 +1982,8 @@ struct TupleValues #endif for (; j < count; j++) *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; } break; case 4: @@ -1982,10 +1991,11 @@ struct TupleValues const auto *pp = (const HBINT32 *) p; for (unsigned j = 0; j < count; j++) *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; } break; } - p += count * width; run_count -= count; i += count; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh index 0116a0c9192..27c4d31b9ce 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh @@ -1073,7 +1073,7 @@ struct cff1 this->blob = sc.reference_table (face); - /* setup for run-time santization */ + /* setup for run-time sanitization */ sc.init (this->blob); sc.start_processing (); @@ -1176,7 +1176,8 @@ struct cff1 if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (unlikely (font->privateDictInfo.size && + privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); priv->init (); @@ -1191,7 +1192,8 @@ struct cff1 PRIVDICTVAL *priv = &privateDicts[0]; const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (font->privateDictInfo.size && + unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env (privDictStr); dict_interpreter_t priv_interp (env); priv->init (); @@ -1483,7 +1485,7 @@ struct cff1 int cmp (const gname_t &a) const { return cmp (&a, this); } }; - mutable hb_atomic_ptr_t> glyph_names; + mutable hb_atomic_t *> glyph_names; typedef accelerator_templ_t SUPER; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc index fce39da21ce..b2702106ecc 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc @@ -102,6 +102,14 @@ struct cff2_cs_opset_extents_t : cff2_cs_opset_tcoords, font->num_coords)); +} + +bool OT::cff2::accelerator_t::get_extents_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_array_t coords) const { #ifdef HB_NO_OT_FONT_CFF /* XXX Remove check when this code moves to .hh file. */ @@ -112,7 +120,7 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, unsigned int fd = fdSelect->get_fd (glyph); const hb_ubytes_t str = (*charStrings)[glyph]; - cff2_cs_interp_env_t env (str, *this, fd, font->coords, font->num_coords); + cff2_cs_interp_env_t env (str, *this, fd, coords.arrayZ, coords.length); cff2_cs_interpreter_t interp (env); cff2_extents_param_t param; if (unlikely (!interp.interpret (param))) return false; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh index 81d30f57a28..7e94e38e115 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh @@ -405,7 +405,7 @@ struct cff2 this->blob = sc.reference_table (face); - /* setup for run-time santization */ + /* setup for run-time sanitization */ sc.init (this->blob); sc.start_processing (); @@ -458,7 +458,8 @@ struct cff2 if (unlikely (!font_interp.interpret (*font))) goto fail; const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (unlikely (font->privateDictInfo.size && + privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); privateDicts[i].init (); @@ -481,6 +482,13 @@ struct cff2 privateDicts.fini (); hb_blob_destroy (blob); blob = nullptr; + + auto *scalars = cached_scalars_vector.get_acquire (); + if (scalars && cached_scalars_vector.cmpexch (scalars, nullptr)) + { + scalars->fini (); + hb_free (scalars); + } } hb_vector_t *create_glyph_to_sid_map () const @@ -508,6 +516,8 @@ struct cff2 hb_vector_t fontDicts; hb_vector_t privateDicts; + mutable hb_atomic_t *> cached_scalars_vector; + unsigned int num_glyphs = 0; }; @@ -518,6 +528,10 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; + HB_INTERNAL bool get_extents_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_array_t coords) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; HB_INTERNAL bool get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t coords) const; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh index 249d4cac5db..6bf37c062fc 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh @@ -2014,7 +2014,8 @@ struct cmap struct accelerator_t { - using cache_t = hb_cache_t<21, 16, 8, true>; + using cache_t = hb_cache_t<21, 19>; + static_assert (sizeof (cache_t) == 1024, ""); accelerator_t (hb_face_t *face) { @@ -2028,6 +2029,14 @@ struct cmap subtable_uvs = &st->u.format14; } +#ifndef HB_NO_OT_FONT_CMAP_CACHE + cache = (cache_t *) hb_malloc (sizeof (cache_t)); + if (cache) + new (cache) cache_t (); + else + return; // Such that get_glyph_funcZ remains null. +#endif + this->get_glyph_data = subtable; #ifndef HB_NO_CMAP_LEGACY_SUBTABLES if (unlikely (symbol)) @@ -2061,62 +2070,71 @@ struct cmap #endif { switch (subtable->u.format) { - /* Accelerate format 4 and format 12. */ - default: - this->get_glyph_funcZ = get_glyph_from; - break; - case 12: - this->get_glyph_funcZ = get_glyph_from; - break; - case 4: - { - this->format4_accel.init (&subtable->u.format4); - this->get_glyph_data = &this->format4_accel; - this->get_glyph_funcZ = this->format4_accel.get_glyph_func; - break; - } + /* Accelerate format 4 and format 12. */ + default: + this->get_glyph_funcZ = get_glyph_from; + break; + case 12: + this->get_glyph_funcZ = get_glyph_from; + break; + case 4: + { + this->format4_accel.init (&subtable->u.format4); + this->get_glyph_data = &this->format4_accel; + this->get_glyph_funcZ = this->format4_accel.get_glyph_func; + break; + } } } } - ~accelerator_t () { this->table.destroy (); } + ~accelerator_t () + { +#ifndef HB_NO_OT_FONT_CMAP_CACHE + hb_free (cache); +#endif + table.destroy (); + } inline bool _cached_get (hb_codepoint_t unicode, - hb_codepoint_t *glyph, - cache_t *cache) const + hb_codepoint_t *glyph) const { +#ifndef HB_NO_OT_FONT_CMAP_CACHE + // cache is always non-null if we have a get_glyph_funcZ unsigned v; - if (cache && cache->get (unicode, &v)) + if (cache->get (unicode, &v)) { *glyph = v; return true; } +#endif bool ret = this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph); - if (cache && ret) +#ifndef HB_NO_OT_FONT_CMAP_CACHE + if (ret) cache->set (unicode, *glyph); +#endif + return ret; } bool get_nominal_glyph (hb_codepoint_t unicode, - hb_codepoint_t *glyph, - cache_t *cache = nullptr) const + hb_codepoint_t *glyph) const { if (unlikely (!this->get_glyph_funcZ)) return false; - return _cached_get (unicode, glyph, cache); + return _cached_get (unicode, glyph); } unsigned int get_nominal_glyphs (unsigned int count, const hb_codepoint_t *first_unicode, unsigned int unicode_stride, hb_codepoint_t *first_glyph, - unsigned int glyph_stride, - cache_t *cache = nullptr) const + unsigned int glyph_stride) const { if (unlikely (!this->get_glyph_funcZ)) return 0; unsigned int done; for (done = 0; - done < count && _cached_get (*first_unicode, first_glyph, cache); + done < count && _cached_get (*first_unicode, first_glyph); done++) { first_unicode = &StructAtOffsetUnaligned (first_unicode, unicode_stride); @@ -2127,8 +2145,7 @@ struct cmap bool get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - cache_t *cache = nullptr) const + hb_codepoint_t *glyph) const { switch (this->subtable_uvs->get_glyph_variant (unicode, variation_selector, @@ -2139,7 +2156,7 @@ struct cmap case GLYPH_VARIANT_USE_DEFAULT: break; } - return get_nominal_glyph (unicode, glyph, cache); + return get_nominal_glyph (unicode, glyph); } void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const @@ -2209,11 +2226,15 @@ struct cmap hb_nonnull_ptr_t subtable; hb_nonnull_ptr_t subtable_uvs; - hb_cmap_get_glyph_func_t get_glyph_funcZ; - const void *get_glyph_data; + hb_cmap_get_glyph_func_t get_glyph_funcZ = nullptr; + const void *get_glyph_data = nullptr; CmapSubtableFormat4::accelerator_t format4_accel; +#ifndef HB_NO_OT_FONT_CMAP_CACHE + cache_t *cache = nullptr; +#endif + public: hb_blob_ptr_t table; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-color.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-color.cc index ef46fe5429a..2d9b8e7cad2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-color.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-color.cc @@ -204,7 +204,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, hb_bool_t hb_ot_color_has_layers (hb_face_t *face) { - return face->table.COLR->has_v0_data (); + return face->table.COLR->colr->has_v0_data (); } /** @@ -221,7 +221,7 @@ hb_ot_color_has_layers (hb_face_t *face) hb_bool_t hb_ot_color_has_paint (hb_face_t *face) { - return face->table.COLR->has_v1_data (); + return face->table.COLR->colr->has_v1_data (); } /** @@ -240,7 +240,7 @@ hb_bool_t hb_ot_color_glyph_has_paint (hb_face_t *face, hb_codepoint_t glyph) { - return face->table.COLR->has_paint_for_glyph (glyph); + return face->table.COLR->colr->has_paint_for_glyph (glyph); } /** @@ -266,7 +266,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, unsigned int *layer_count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */) { - return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers); + return face->table.COLR->colr->get_glyph_layers (glyph, start_offset, layer_count, layers); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh index 97825f4d19c..afc8aa476e2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh @@ -136,7 +136,7 @@ HB_OT_TABLE (AAT, feat) /* OpenType color fonts. */ #ifndef HB_NO_COLOR -HB_OT_CORE_TABLE (OT, COLR) +HB_OT_ACCELERATOR (OT, COLR) HB_OT_CORE_TABLE (OT, CPAL) HB_OT_ACCELERATOR (OT, CBDT) HB_OT_ACCELERATOR (OT, sbix) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc index 1cf14f3ebc6..d17f088073c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc @@ -36,6 +36,7 @@ #include "hb-ot-name-table.hh" #include "hb-ot-post-table.hh" #include "OT/Color/CBDT/CBDT.hh" +#include "OT/Color/COLR/COLR.hh" #include "OT/Color/sbix/sbix.hh" #include "OT/Color/svg/svg.hh" #include "hb-ot-layout-gdef-table.hh" diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc index 2a633c77816..0238bb346a9 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc @@ -34,11 +34,7 @@ #include "hb-font.hh" #include "hb-machinery.hh" #include "hb-ot-face.hh" -#include "hb-outline.hh" -#ifndef HB_NO_AAT -#include "hb-aat-layout-trak-table.hh" -#endif #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-cff2-table.hh" @@ -65,28 +61,111 @@ * never need to call these functions directly. **/ -using hb_ot_font_cmap_cache_t = hb_cache_t<21, 16, 8, true>; -using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>; - -#ifndef HB_NO_OT_FONT_CMAP_CACHE -static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key; -#endif +using hb_ot_font_advance_cache_t = hb_cache_t<24, 16>; +static_assert (sizeof (hb_ot_font_advance_cache_t) == 1024, ""); struct hb_ot_font_t { const hb_ot_face_t *ot_face; -#ifndef HB_NO_AAT - bool apply_trak; -#endif + /* h_advance caching */ + mutable hb_atomic_t cached_coords_serial; + struct advance_cache_t + { + mutable hb_atomic_t advance_cache; + mutable hb_atomic_t varStore_cache; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - hb_ot_font_cmap_cache_t *cmap_cache; -#endif + ~advance_cache_t () + { + clear (); + } - /* h_advance caching */ - mutable hb_atomic_int_t cached_coords_serial; - mutable hb_atomic_ptr_t advance_cache; + hb_ot_font_advance_cache_t *acquire_advance_cache () const + { + retry: + auto *cache = advance_cache.get_acquire (); + if (!cache) + { + cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t)); + if (!cache) + return nullptr; + new (cache) hb_ot_font_advance_cache_t; + return cache; + } + if (advance_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_advance_cache (hb_ot_font_advance_cache_t *cache) const + { + if (!cache) + return; + if (!advance_cache.cmpexch (nullptr, cache)) + hb_free (cache); + } + void clear_advance_cache () const + { + retry: + auto *cache = advance_cache.get_acquire (); + if (!cache) + return; + if (advance_cache.cmpexch (cache, nullptr)) + hb_free (cache); + else + goto retry; + } + + OT::ItemVariationStore::cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return varStore.create_cache (); + if (varStore_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_varStore_cache (OT::ItemVariationStore::cache_t *cache) const + { + if (!cache) + return; + if (!varStore_cache.cmpexch (nullptr, cache)) + OT::ItemVariationStore::destroy_cache (cache); + } + void clear_varStore_cache () const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return; + if (varStore_cache.cmpexch (cache, nullptr)) + OT::ItemVariationStore::destroy_cache (cache); + else + goto retry; + } + + void clear () const + { + clear_advance_cache (); + clear_varStore_cache (); + } + + } h, v; + + void check_serial (hb_font_t *font) const + { + int font_serial = font->serial_coords.get_acquire (); + + if (cached_coords_serial.get_acquire () == font_serial) + return; + + h.clear (); + v.clear (); + + cached_coords_serial.set_release (font_serial); + } }; static hb_ot_font_t * @@ -98,44 +177,6 @@ _hb_ot_font_create (hb_font_t *font) ot_font->ot_face = &font->face->table; -#ifndef HB_NO_AAT - /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ -#ifndef HB_NO_STYLE - ot_font->apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); -#else - ot_font->apply_trak = false; -#endif -#endif - -#ifndef HB_NO_OT_FONT_CMAP_CACHE - // retry: - auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face, - &hb_ot_font_cmap_cache_user_data_key); - if (!cmap_cache) - { - cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t)); - if (unlikely (!cmap_cache)) goto out; - new (cmap_cache) hb_ot_font_cmap_cache_t (); - if (unlikely (!hb_face_set_user_data (font->face, - &hb_ot_font_cmap_cache_user_data_key, - cmap_cache, - hb_free, - false))) - { - hb_free (cmap_cache); - cmap_cache = nullptr; - /* Normally we would retry here, but that would - * infinite-loop if the face is the empty-face. - * Just let it go and this font will be uncached if it - * happened to collide with another thread creating the - * cache at the same time. */ - // goto retry; - } - } - out: - ot_font->cmap_cache = cmap_cache; -#endif - return ot_font; } @@ -144,8 +185,7 @@ _hb_ot_font_destroy (void *font_data) { hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data; - auto *cache = ot_font->advance_cache.get_relaxed (); - hb_free (cache); + ot_font->~hb_ot_font_t (); hb_free (ot_font); } @@ -159,11 +199,7 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, { 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; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif - return ot_face->cmap->get_nominal_glyph (unicode, glyph, cmap_cache); + return ot_face->cmap->get_nominal_glyph (unicode, glyph); } static unsigned int @@ -178,14 +214,9 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, { 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; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif return ot_face->cmap->get_nominal_glyphs (count, first_unicode, unicode_stride, - first_glyph, glyph_stride, - cmap_cache); + first_glyph, glyph_stride); } static hb_bool_t @@ -198,13 +229,8 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, { 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; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif return ot_face->cmap->get_variation_glyph (unicode, - variation_selector, glyph, - cmap_cache); + variation_selector, glyph); } static void @@ -216,47 +242,25 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { + 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; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; - hb_position_t *orig_first_advance = first_advance; - -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) + ot_font->check_serial (font); const OT::HVAR &HVAR = *hmtx.var_table; const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; - OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = ot_font->h.acquire_varStore_cache (varStore); - bool use_cache = font->num_coords; -#else - OT::ItemVariationStore::cache_t *varStore_cache = nullptr; - bool use_cache = false; -#endif + hb_ot_font_advance_cache_t *advance_cache = nullptr; - hb_ot_font_advance_cache_t *cache = nullptr; + bool use_cache = font->num_coords; if (use_cache) { - retry: - cache = ot_font->advance_cache.get_acquire (); - if (unlikely (!cache)) - { - cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t)); - if (unlikely (!cache)) - { - use_cache = false; - goto out; - } - new (cache) hb_ot_font_advance_cache_t; - - if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache))) - { - hb_free (cache); - goto retry; - } - ot_font->cached_coords_serial.set_release (font->serial_coords); - } + advance_cache = ot_font->h.acquire_advance_cache (); + if (!advance_cache) + use_cache = false; } - out: if (!use_cache) { @@ -269,58 +273,26 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, } else { /* Use cache. */ - if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords) - { - ot_font->advance_cache->clear (); - ot_font->cached_coords_serial.set_release (font->serial_coords); - } - for (unsigned int i = 0; i < count; i++) { hb_position_t v; unsigned cv; - if (ot_font->advance_cache->get (*first_glyph, &cv)) + if (advance_cache->get (*first_glyph, &cv)) v = cv; else { v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); - ot_font->advance_cache->set (*first_glyph, v); + advance_cache->set (*first_glyph, v); } *first_advance = font->em_scale_x (v); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } - } - -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::ItemVariationStore::destroy_cache (varStore_cache); -#endif - if (font->x_strength && !font->embolden_in_place) - { - /* Emboldening. */ - hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength; - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += *first_advance ? x_strength : 0; - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } + ot_font->h.release_advance_cache (advance_cache); } -#ifndef HB_NO_AAT - if (ot_font->apply_trak) - { - hb_position_t tracking = font->face->table.trak->get_h_tracking (font); - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += tracking; - first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } -#endif + ot_font->h.release_varStore_cache (varStore_cache); } #ifndef HB_NO_VERTICAL @@ -337,17 +309,13 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - hb_position_t *orig_first_advance = first_advance; - if (vmtx.has_data ()) { -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) + ot_font->check_serial (font); const OT::VVAR &VVAR = *vmtx.var_table; const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; - OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; -#else - OT::ItemVariationStore::cache_t *varStore_cache = nullptr; -#endif + OT::ItemVariationStore::cache_t *varStore_cache = ot_font->v.acquire_varStore_cache (varStore); + // TODO Use advance_cache. for (unsigned int i = 0; i < count; i++) { @@ -356,9 +324,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::ItemVariationStore::destroy_cache (varStore_cache); -#endif + ot_font->v.release_varStore_cache (varStore_cache); } else { @@ -373,32 +339,6 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } - - if (font->y_strength && !font->embolden_in_place) - { - /* Emboldening. */ - hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += *first_advance ? y_strength : 0; - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } - -#ifndef HB_NO_AAT - if (ot_font->apply_trak) - { - hb_position_t tracking = font->face->table.trak->get_v_tracking (font); - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += tracking; - first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } -#endif } #endif @@ -435,7 +375,8 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, } hb_glyph_extents_t extents = {0}; - if (ot_face->glyf->get_extents (font, glyph, &extents)) + + if (hb_font_get_glyph_extents (font, glyph, &extents)) { const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; int tsb = 0; @@ -448,7 +389,7 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, hb_font_extents_t font_extents; font->get_h_extents_with_fallback (&font_extents); hb_position_t advance = font_extents.ascender - font_extents.descender; - int diff = advance - -extents.height; + hb_position_t diff = advance - -extents.height; *y = extents.y_bearing + (diff >> 1); return true; } @@ -477,6 +418,9 @@ hb_ot_get_glyph_extents (hb_font_t *font, #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 @@ -528,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 @@ -554,68 +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) { - bool embolden = font->x_strength || font->y_strength; - hb_outline_t outline; - - { // Need draw_session to be destructed before emboldening. - hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs, - embolden ? &outline : 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)) + // Keep the following in synch with VARC::get_path_at() + 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 - {} - } - - if (embolden) - { - float x_shift = font->embolden_in_place ? 0 : (float) font->x_strength / 2; - float y_shift = (float) font->y_strength / 2; - if (font->x_scale < 0) x_shift = -x_shift; - if (font->y_scale < 0) y_shift = -y_shift; - outline.embolden (font->x_strength, font->y_strength, - x_shift, y_shift); - - outline.replay (draw_funcs, draw_data); - } + 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 @@ -642,11 +557,11 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t table; AAT::kern_accelerator_data_t accel_data; + AAT::hb_aat_scratch_t scratch; }; protected: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh index 5a3679e4bfa..04a79a93a89 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh @@ -182,7 +182,7 @@ struct BaseCoord void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const { switch (u.format) { - case 3: hb_barrier (); u.format3.collect_variation_indices (varidx_set); + case 3: hb_barrier (); u.format3.collect_variation_indices (varidx_set); return; default:return; } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh index f14675295f6..7ee34185575 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh @@ -1850,7 +1850,7 @@ struct ClassDefFormat2_4 hb_sorted_vector_t glyph_and_klass; hb_set_t orig_klasses; - if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2 + if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) < get_population ()) { for (hb_codepoint_t g : glyph_set) @@ -1931,7 +1931,7 @@ struct ClassDefFormat2_4 bool intersects (const hb_set_t *glyphs) const { - if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) + if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len)) { for (auto g : *glyphs) if (get_class (g)) @@ -2000,7 +2000,7 @@ struct ClassDefFormat2_4 } unsigned count = rangeRecord.len; - if (count > glyphs->get_population () * hb_bit_storage (count) * 8) + if (count > glyphs->get_population () * hb_bit_storage (count)) { for (auto g : *glyphs) { @@ -2548,11 +2548,13 @@ struct SparseVarRegionAxis DEFINE_SIZE_STATIC (8); }; -#define REGION_CACHE_ITEM_CACHE_INVALID 2.f +#define REGION_CACHE_ITEM_CACHE_INVALID INT_MIN +#define REGION_CACHE_ITEM_MULTIPLIER (float (1 << ((sizeof (int) * 8) - 2))) +#define REGION_CACHE_ITEM_DIVISOR (1.f / float (1 << ((sizeof (int) * 8) - 2))) struct VarRegionList { - using cache_t = float; + using cache_t = hb_atomic_t; float evaluate (unsigned int region_index, const int *coords, unsigned int coord_len, @@ -2561,12 +2563,12 @@ struct VarRegionList if (unlikely (region_index >= regionCount)) return 0.; - float *cached_value = nullptr; + cache_t *cached_value = nullptr; if (cache) { cached_value = &(cache[region_index]); - if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID)) - return *cached_value; + if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) + return *cached_value * REGION_CACHE_ITEM_DIVISOR; } const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); @@ -2587,7 +2589,7 @@ struct VarRegionList } if (cache) - *cached_value = v; + *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; return v; } @@ -2730,7 +2732,7 @@ struct SparseVariationRegion : Array16Of struct SparseVarRegionList { - using cache_t = float; + using cache_t = hb_atomic_t; float evaluate (unsigned int region_index, const int *coords, unsigned int coord_len, @@ -2739,12 +2741,12 @@ struct SparseVarRegionList if (unlikely (region_index >= regions.len)) return 0.; - float *cached_value = nullptr; + cache_t *cached_value = nullptr; if (cache) { cached_value = &(cache[region_index]); - if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID)) - return *cached_value; + if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) + return *cached_value * REGION_CACHE_ITEM_DIVISOR; } const SparseVariationRegion ®ion = this+regions[region_index]; @@ -2752,7 +2754,7 @@ struct SparseVarRegionList float v = region.evaluate (coords, coord_len); if (cache) - *cached_value = v; + *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; return v; } @@ -2861,8 +2863,13 @@ struct VarData const hb_vector_t*>& rows) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (this))) return_trace (false); unsigned row_count = rows.length; + if (!row_count) { + // Nothing to serialize, will be empty. + return false; + } + + if (unlikely (!c->extend_min (this))) return_trace (false); itemCount = row_count; int min_threshold = has_long ? -65536 : -128; @@ -3187,10 +3194,10 @@ struct ItemVariationStore #ifdef HB_NO_VAR return nullptr; #endif - auto &r = this+regions; - unsigned count = r.regionCount; + unsigned count = (this+regions).regionCount; + if (!count) return nullptr; - float *cache = (float *) hb_malloc (sizeof (float) * count); + cache_t *cache = (cache_t *) hb_malloc (sizeof (float) * count); if (unlikely (!cache)) return nullptr; for (unsigned i = 0; i < count; i++) @@ -3440,7 +3447,7 @@ struct MultiItemVariationStore { using cache_t = SparseVarRegionList::cache_t; - cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const + cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const { #ifdef HB_NO_VAR return nullptr; @@ -3448,12 +3455,12 @@ struct MultiItemVariationStore auto &r = this+regions; unsigned count = r.regions.len; - float *cache; + cache_t *cache; if (count <= static_cache.length) cache = static_cache.arrayZ; else { - cache = (float *) hb_malloc (sizeof (float) * count); + cache = (cache_t *) hb_malloc (sizeof (float) * count); if (unlikely (!cache)) return nullptr; } @@ -3464,7 +3471,7 @@ struct MultiItemVariationStore } static void destroy_cache (cache_t *cache, - hb_array_t static_cache = hb_array_t ()) + hb_array_t static_cache = hb_array_t ()) { if (cache != static_cache.arrayZ) hb_free (cache); @@ -4777,12 +4784,12 @@ struct VariationDevice hb_position_t get_x_delta (hb_font_t *font, const ItemVariationStore &store, ItemVariationStore::cache_t *store_cache = nullptr) const - { return font->em_scalef_x (get_delta (font, store, store_cache)); } + { return !font->num_coords ? 0 : font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, const ItemVariationStore &store, ItemVariationStore::cache_t *store_cache = nullptr) const - { return font->em_scalef_y (get_delta (font, store, store_cache)); } + { return !font->num_coords ? 0 : font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, const hb_hashmap_t> *layout_variation_idx_delta_map) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh index 1a719391b8e..072e5cdba26 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh @@ -737,7 +737,8 @@ struct hb_ot_apply_context_t : hb_ot_apply_context_t (unsigned int table_index_, hb_font_t *font_, hb_buffer_t *buffer_, - hb_blob_t *table_blob_) : + hb_blob_t *table_blob_, + ItemVariationStore::cache_t *var_store_cache_ = nullptr) : table_index (table_index_), font (font_), face (font->face), buffer (buffer_), sanitizer (table_blob_), @@ -756,13 +757,7 @@ struct hb_ot_apply_context_t : #endif ), var_store (gdef.get_var_store ()), - var_store_cache ( -#ifndef HB_NO_VAR - table_index == 1 && font->num_coords ? var_store.create_cache () : nullptr -#else - nullptr -#endif - ), + var_store_cache (var_store_cache_), direction (buffer_->props.direction), has_glyph_classes (gdef.has_glyph_classes ()) { @@ -770,13 +765,6 @@ struct hb_ot_apply_context_t : buffer->collect_codepoints (digest); } - ~hb_ot_apply_context_t () - { -#ifndef HB_NO_VAR - ItemVariationStore::destroy_cache (var_store_cache); -#endif - } - void init_iters () { iter_input.init (this, false); @@ -4900,7 +4888,7 @@ struct GSUBGPOS this->lookup_count = table->get_lookup_count (); - this->accels = (hb_atomic_ptr_t *) hb_calloc (this->lookup_count, sizeof (*accels)); + this->accels = (hb_atomic_t *) hb_calloc (this->lookup_count, sizeof (*accels)); if (unlikely (!this->accels)) { this->lookup_count = 0; @@ -4948,7 +4936,7 @@ struct GSUBGPOS hb_blob_ptr_t table; unsigned int lookup_count; - hb_atomic_ptr_t *accels; + hb_atomic_t *accels; }; protected: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc index 787119dc62b..afe52963201 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc @@ -131,13 +131,15 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *blob = font->face->table.kern.get_blob (); - const auto& kern = *font->face->table.kern; + auto &accel = *font->face->table.kern; + hb_blob_t *blob = accel.get_blob (); AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); if (!buffer->message (font, "start table kern")) return; - kern.apply (&c); + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); + accel.apply (&c); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); (void) buffer->message (font, "end table kern"); } #endif @@ -2013,7 +2015,11 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, { const unsigned int table_index = proxy.table_index; unsigned int i = 0; - OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob ()); + + auto *font_data = font->data.ot.get (); + auto *var_store_cache = font_data == HB_SHAPER_DATA_SUCCEEDED ? nullptr : (OT::ItemVariationStore::cache_t *) font_data; + + OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob (), var_store_cache); c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func); for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++) @@ -2626,7 +2632,8 @@ struct hb_get_glyph_alternates_dispatch_t : * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer. * Alternate glyphs associated with the glyph id. * - * Fetches alternates of a glyph from a given GSUB lookup index. + * Fetches alternates of a glyph from a given GSUB lookup index. Note that for one-to-one GSUB + * glyph substitutions, this function fetches the substituted glyph. * * Return value: Total number of alternates found in the specific lookup index for the given glyph id. * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh index 71074a87401..a68c8421e4c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh @@ -202,7 +202,8 @@ enum hb_unicode_props_flags_t { /* If GEN_CAT=FORMAT, top byte masks: */ UPROPS_MASK_Cf_ZWJ = 0x0100u, UPROPS_MASK_Cf_ZWNJ = 0x0200u, - UPROPS_MASK_Cf_VS = 0x0400u + UPROPS_MASK_Cf_VS = 0x0400u, + UPROPS_MASK_Cf_AAT_DELETED = 0x0800u }; HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); @@ -386,6 +387,8 @@ _hb_grapheme_group_func (const hb_glyph_info_t& a HB_UNUSED, static inline void _hb_ot_layout_reverse_graphemes (hb_buffer_t *buffer) { + // MONOTONE_GRAPHEMES was already applied and is taken care of by _hb_grapheme_group_func. + // So we just check for MONOTONE_CHARACTERS here. buffer->reverse_groups (_hb_grapheme_group_func, buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); } @@ -418,6 +421,18 @@ _hb_glyph_info_flip_joiners (hb_glyph_info_t *info) return; info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ; } +static inline bool +_hb_glyph_info_is_aat_deleted (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_AAT_DELETED); +} +static inline void +_hb_glyph_info_set_aat_deleted (hb_glyph_info_t *info) +{ + _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_FORMAT); + info->unicode_props() |= UPROPS_MASK_Cf_AAT_DELETED; + info->unicode_props() |= UPROPS_MASK_HIDDEN; +} /* lig_props: aka lig_id / lig_comp * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh index c1b2a27b21d..b33e01fd6c9 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh @@ -1104,6 +1104,24 @@ struct MATH mathVariants.sanitize (c, this)); } + // https://github.com/harfbuzz/harfbuzz/issues/4653 + HB_INTERNAL bool is_bad_cambria (hb_font_t *font) const + { +#ifndef HB_NO_MATH + switch HB_CODEPOINT_ENCODE3 (font->face->table.MATH.get_blob ()->length, + get_constant (HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT, font), + get_constant (HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT, font)) + { + /* sha1sum:ab4a4fe054d23061f3c039493d6f665cfda2ecf5 cambria.ttc + * sha1sum:086855301bff644f9d8827b88491fcf73a6d4cb9 cambria.ttc + * sha1sum:b1e5a3feaca2ea3dfcf79ccb377de749ecf60343 cambria.ttc */ + case HB_CODEPOINT_ENCODE3 (25722, 2500, 3000): + return true; + } +#endif + return false; + } + hb_position_t get_constant (hb_ot_math_constant_t constant, hb_font_t *font) const { return (this+mathConstants).get_value (constant, font); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc index 191149964f9..ab1f50c8eb8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc @@ -87,6 +87,20 @@ hb_position_t hb_ot_math_get_constant (hb_font_t *font, hb_ot_math_constant_t constant) { + /* https://github.com/harfbuzz/harfbuzz/issues/4653 + * Cambria Math has incorrect value for displayOperatorMinHeight, and + * apparently Microsoft implementation swaps displayOperatorMinHeight and + * delimitedSubFormulaMinHeight, so we do the same if we detect Cambria Math + * with the swapped values. */ + if ((constant == HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT || + constant == HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT) && + font->face->table.MATH->is_bad_cambria (font)) + { + if (constant == HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT) + constant = HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT; + else + constant = HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT; + } return font->face->table.MATH->get_constant(constant, font); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh index 83d310e16a0..2c4c6c04663 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/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_ptr_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/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc index b74d3104a7e..2401e18f0e6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-fallback.cc @@ -427,8 +427,13 @@ position_cluster (const hb_ot_shape_plan_t *plan, /* Find mark glyphs */ unsigned int j; for (j = i + 1; j < end; j++) + { + if (_hb_glyph_info_is_hidden (&info[j]) || + _hb_glyph_info_is_default_ignorable (&info[j])) + continue; if (!_hb_glyph_info_is_unicode_mark (&info[j])) break; + } position_around_base (plan, font, buffer, i, j, adjust_offsets_when_zeroing); @@ -455,7 +460,9 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]))) { + if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]) && + !_hb_glyph_info_is_hidden (&info[i]) && + !_hb_glyph_info_is_default_ignorable (&info[i]))) { position_cluster (plan, font, buffer, start, i, adjust_offsets_when_zeroing); start = i; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc index 6265f0eb17d..477a7c7fc72 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc @@ -46,6 +46,7 @@ #include "hb-set.hh" #include "hb-aat-layout.hh" +#include "hb-ot-layout-gdef-table.hh" #include "hb-ot-stat-table.hh" @@ -84,6 +85,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac props (props), map (face, props) #ifndef HB_NO_AAT_SHAPE + , aat_map (face, props) , apply_morx (_hb_apply_morx (face, props)) #endif { @@ -106,6 +108,10 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.props = props; plan.shaper = shaper; map.compile (plan.map, key); +#ifndef HB_NO_AAT_SHAPE + if (apply_morx) + aat_map.compile (plan.aat_map); +#endif #ifndef HB_NO_OT_SHAPE_FRACTIONS plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); @@ -205,6 +211,14 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, https://github.com/harfbuzz/harfbuzz/issues/2967. */ if (plan.apply_morx) plan.adjust_mark_positioning_when_zeroing = false; + + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + plan.apply_trak = hb_aat_layout_has_tracking (face) && face->table.STAT->has_data (); +#else + plan.apply_trak = false; +#endif + #endif } @@ -269,6 +283,11 @@ hb_ot_shape_plan_t::position (hb_font_t *font, #endif else if (this->apply_fallback_kern) _hb_ot_shape_fallback_kern (this, font, buffer); + +#ifndef HB_NO_AAT_SHAPE + if (this->apply_trak) + hb_aat_layout_track (this, font, buffer); +#endif } @@ -405,17 +424,26 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data) * shaper font data */ -struct hb_ot_font_data_t {}; +struct hb_ot_font_data_t { + OT::ItemVariationStore::cache_t unused; // Just for alignment +}; hb_ot_font_data_t * -_hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED) +_hb_ot_shaper_font_data_create (hb_font_t *font) { - return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; + if (!font->num_coords) + return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; + + const OT::ItemVariationStore &var_store = font->face->table.GDEF->table->get_var_store (); + auto *cache = (hb_ot_font_data_t *) var_store.create_cache (); + return cache ? cache : (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; } void -_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data HB_UNUSED) +_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data) { + if (data == HB_SHAPER_DATA_SUCCEEDED) return; + OT::ItemVariationStore::destroy_cache ((OT::ItemVariationStore::cache_t *) data); } @@ -551,7 +579,7 @@ hb_form_clusters (hb_buffer_t *buffer) if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) return; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + if (HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (buffer->cluster_level)) foreach_grapheme (buffer, start, end) buffer->merge_clusters (start, end); else @@ -609,7 +637,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Ogham fonts are supposed to be implemented BTT or not. Need to research that * first. */ if ((HB_DIRECTION_IS_HORIZONTAL (direction) && - direction != horiz_dir && horiz_dir != HB_DIRECTION_INVALID) || + direction != horiz_dir && HB_DIRECTION_IS_VALID (horiz_dir)) || (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) { @@ -1109,10 +1137,6 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) /* Finish off. Has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); hb_ot_zero_width_default_ignorables (c->buffer); -#ifndef HB_NO_AAT_SHAPE - if (c->plan->apply_morx) - hb_aat_layout_zero_width_deleted_glyphs (c->buffer); -#endif hb_ot_layout_position_finish_offsets (c->font, c->buffer); /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh index d5ee82d4c0b..068d7192d0d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh @@ -66,6 +66,7 @@ struct hb_ot_shape_plan_t hb_segment_properties_t props; const struct hb_ot_shaper_t *shaper; hb_ot_map_t map; + hb_aat_map_t aat_map; const void *data; #ifndef HB_NO_OT_SHAPE_FRACTIONS hb_mask_t frac_mask, numr_mask, dnom_mask; @@ -108,9 +109,11 @@ struct hb_ot_shape_plan_t #ifndef HB_NO_AAT_SHAPE bool apply_kerx : 1; bool apply_morx : 1; + bool apply_trak : 1; #else static constexpr bool apply_kerx = false; static constexpr bool apply_morx = false; + static constexpr bool apply_trak = false; #endif void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const @@ -141,6 +144,7 @@ struct hb_ot_shape_planner_t hb_segment_properties_t props; hb_ot_map_builder_t map; #ifndef HB_NO_AAT_SHAPE + hb_aat_map_builder_t aat_map; bool apply_morx : 1; #else static constexpr bool apply_morx = false; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc index 67db6cb26c4..7379bb7f15b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc +++ b/src/java.desktop/share/native/libharfbuzz/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_ptr_t fallback_plan; + mutable hb_atomic_t fallback_plan; unsigned int do_fallback : 1; unsigned int has_stch : 1; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc index 8b41e2219b1..5c46ebbc281 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hangul.cc @@ -298,8 +298,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, end = start + 2; if (unlikely (!buffer->successful)) break; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_out_clusters (start, end); + buffer->merge_out_clusters (start, end); continue; } } @@ -372,8 +371,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, if (i < end) info[i++].hangul_shaping_feature() = TJMO; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_out_clusters (start, end); + buffer->merge_out_clusters (start, end); continue; } else if ((!tindex && buffer->idx + 1 < count && isT (buffer->cur(+1).codepoint))) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc index 20007df8963..d78b5670f61 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc @@ -301,7 +301,7 @@ struct indic_shape_plan_t #else static constexpr bool uniscribe_bug_compatible = false; #endif - mutable hb_atomic_int_t virama_glyph; + mutable hb_atomic_t virama_glyph; hb_indic_would_substitute_feature_t rphf; hb_indic_would_substitute_feature_t pref; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc index 68642a5c178..a0ea464e775 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-thai.cc @@ -360,7 +360,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, { /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the * previous cluster. */ - if (start && buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + if (start) buffer->merge_out_clusters (start - 1, end); } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc index 3cdb703203b..786a220b6ec 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc @@ -326,7 +326,7 @@ hb_ot_tags_from_language (const char *lang_str, hb_tag_t lang_tag = hb_tag_from_string (lang_str, first_len); - static hb_atomic_int_t last_tag_idx; /* Poor man's cache. */ + static hb_atomic_t last_tag_idx = 0; /* Poor man's cache. */ unsigned tag_idx = last_tag_idx; if (likely (tag_idx < ot_languages_len && ot_languages[tag_idx].language == lang_tag) || diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh index c3040187f6e..9f9b5be3cbe 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh @@ -53,10 +53,6 @@ struct hb_glyf_scratch_t contour_point_vector_t deltas; hb_vector_t shared_indices; hb_vector_t private_indices; - - // VARC - hb_vector_t axisIndices; - hb_vector_t axisValues; }; namespace OT { @@ -594,9 +590,9 @@ struct gvar_GVAR /* If sanitize failed, set glyphCount to 0. */ glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; - /* For shared tuples that only have one axis active, shared the index of - * that axis as a cache. This will speed up caclulate_scalar() a lot - * for fonts with lots of axes and many "monovar" tuples. */ + /* For shared tuples that only have one or two axes active, shared the index + * of that axis as a cache. This will speed up caclulate_scalar() a lot + * for fonts with lots of axes and many "monovar" or "duovar" tuples. */ hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); unsigned count = table->sharedTupleCount; if (unlikely (!shared_tuple_active_idx.resize (count, false))) return; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc index 82bbbb0b1f2..8c695c41e24 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var.cc +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/hb-outline.cc b/src/java.desktop/share/native/libharfbuzz/hb-outline.cc index a0a6ea156c3..85ffc793678 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-outline.cc +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/hb-outline.hh b/src/java.desktop/share/native/libharfbuzz/hb-outline.hh index c44625da2e1..c5b68c05dd7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-outline.hh +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/hb-paint-bounded.cc b/src/java.desktop/share/native/libharfbuzz/hb-paint-bounded.cc new file mode 100644 index 00000000000..bc7e962bb46 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/hb-paint-bounded.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint-bounded.hh new file mode 100644 index 00000000000..bdcdba76397 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc index 3bbe6351725..bc08c5a9e14 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.cc +++ b/src/java.desktop/share/native/libharfbuzz/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/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh index 18aa638c7ad..60374eaa2d2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh @@ -35,13 +35,22 @@ typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; struct hb_paint_extents_context_t { - hb_paint_extents_context_t () + void clear () { + transforms.clear (); + clips.clear (); + groups.clear (); + transforms.push (hb_transform_t{}); clips.push (hb_bounds_t{hb_bounds_t::UNBOUNDED}); groups.push (hb_bounds_t{hb_bounds_t::EMPTY}); } + hb_paint_extents_context_t () + { + clear (); + } + hb_extents_t get_extents () { return groups.tail().extents; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.cc b/src/java.desktop/share/native/libharfbuzz/hb-paint.cc index 6f2a296744f..094597d6457 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint.cc +++ b/src/java.desktop/share/native/libharfbuzz/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; } @@ -464,6 +464,42 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); } +/** + * hb_paint_push_font_transform: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @font: a font + * + * Push the transform reflecting the font's scale and slant + * settings onto the paint functions. + * + * Since: 11.0.0 + */ +void +hb_paint_push_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font) +{ + funcs->push_font_transform (paint_data, font); +} + +/** + * hb_paint_push_inverse_font_transform: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @font: a font + * + * Push the inverse of the transform reflecting the font's + * scale and slant settings onto the paint functions. + * + * Since: 11.0.0 + */ +void +hb_paint_push_inverse_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font) +{ + funcs->push_inverse_font_transform (paint_data, font); +} + /** * hb_paint_pop_transform: * @funcs: paint functions @@ -579,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. @@ -592,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); } /** @@ -646,7 +682,7 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float r0, float x1, float y1, float r1) { - funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); + funcs->radial_gradient (paint_data, color_line, x0, y0, r0, x1, y1, r1); } /** diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.h b/src/java.desktop/share/native/libharfbuzz/hb-paint.h index f0d9438506d..9827a02887b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint.h +++ b/src/java.desktop/share/native/libharfbuzz/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() * @@ -956,6 +958,14 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xy, float yy, float dx, float dy); +HB_EXTERN void +hb_paint_push_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font); + +HB_EXTERN void +hb_paint_push_inverse_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font); + HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint.hh index fbf4a08cfff..2abadebab3c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint.hh @@ -157,27 +157,29 @@ struct hb_paint_funcs_t /* Internal specializations. */ - void push_root_transform (void *paint_data, + void push_font_transform (void *paint_data, const hb_font_t *font) { 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_root_transform (void *paint_data, - hb_font_t *font) + void push_inverse_font_transform (void *paint_data, + const hb_font_t *font) { 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/java.desktop/share/native/libharfbuzz/hb-script-list.h b/src/java.desktop/share/native/libharfbuzz/hb-script-list.h new file mode 100644 index 00000000000..f811dbc3408 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-script-list.h @@ -0,0 +1,484 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2011,2012 Google, Inc. + * + * 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) +#error "Include instead." +#endif + +#ifndef HB_SCRIPT_LIST_H +#define HB_SCRIPT_LIST_H + +/* This file belongs to the middle of hb-common.h. + * The reason it has been surgically extracted is because + * FreeType imports types and enums from hb-common.h, + * and since this enum is large and growing, we want to + * make it easy to just copy the file over to FreeType. + * https://github.com/harfbuzz/harfbuzz/issues/5271 + */ + +/* Dummy lines to make our checks happy. */ +#if 0 +#include "hb-common.h" +HB_BEGIN_DECLS +HB_END_DECLS +#endif + + +/** + * hb_script_t: + * @HB_SCRIPT_COMMON: `Zyyy` + * @HB_SCRIPT_INHERITED: `Zinh` + * @HB_SCRIPT_UNKNOWN: `Zzzz` + * @HB_SCRIPT_ARABIC: `Arab` + * @HB_SCRIPT_ARMENIAN: `Armn` + * @HB_SCRIPT_BENGALI: `Beng` + * @HB_SCRIPT_CYRILLIC: `Cyrl` + * @HB_SCRIPT_DEVANAGARI: `Deva` + * @HB_SCRIPT_GEORGIAN: `Geor` + * @HB_SCRIPT_GREEK: `Grek` + * @HB_SCRIPT_GUJARATI: `Gujr` + * @HB_SCRIPT_GURMUKHI: `Guru` + * @HB_SCRIPT_HANGUL: `Hang` + * @HB_SCRIPT_HAN: `Hani` + * @HB_SCRIPT_HEBREW: `Hebr` + * @HB_SCRIPT_HIRAGANA: `Hira` + * @HB_SCRIPT_KANNADA: `Knda` + * @HB_SCRIPT_KATAKANA: `Kana` + * @HB_SCRIPT_LAO: `Laoo` + * @HB_SCRIPT_LATIN: `Latn` + * @HB_SCRIPT_MALAYALAM: `Mlym` + * @HB_SCRIPT_ORIYA: `Orya` + * @HB_SCRIPT_TAMIL: `Taml` + * @HB_SCRIPT_TELUGU: `Telu` + * @HB_SCRIPT_THAI: `Thai` + * @HB_SCRIPT_TIBETAN: `Tibt` + * @HB_SCRIPT_BOPOMOFO: `Bopo` + * @HB_SCRIPT_BRAILLE: `Brai` + * @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans` + * @HB_SCRIPT_CHEROKEE: `Cher` + * @HB_SCRIPT_ETHIOPIC: `Ethi` + * @HB_SCRIPT_KHMER: `Khmr` + * @HB_SCRIPT_MONGOLIAN: `Mong` + * @HB_SCRIPT_MYANMAR: `Mymr` + * @HB_SCRIPT_OGHAM: `Ogam` + * @HB_SCRIPT_RUNIC: `Runr` + * @HB_SCRIPT_SINHALA: `Sinh` + * @HB_SCRIPT_SYRIAC: `Syrc` + * @HB_SCRIPT_THAANA: `Thaa` + * @HB_SCRIPT_YI: `Yiii` + * @HB_SCRIPT_DESERET: `Dsrt` + * @HB_SCRIPT_GOTHIC: `Goth` + * @HB_SCRIPT_OLD_ITALIC: `Ital` + * @HB_SCRIPT_BUHID: `Buhd` + * @HB_SCRIPT_HANUNOO: `Hano` + * @HB_SCRIPT_TAGALOG: `Tglg` + * @HB_SCRIPT_TAGBANWA: `Tagb` + * @HB_SCRIPT_CYPRIOT: `Cprt` + * @HB_SCRIPT_LIMBU: `Limb` + * @HB_SCRIPT_LINEAR_B: `Linb` + * @HB_SCRIPT_OSMANYA: `Osma` + * @HB_SCRIPT_SHAVIAN: `Shaw` + * @HB_SCRIPT_TAI_LE: `Tale` + * @HB_SCRIPT_UGARITIC: `Ugar` + * @HB_SCRIPT_BUGINESE: `Bugi` + * @HB_SCRIPT_COPTIC: `Copt` + * @HB_SCRIPT_GLAGOLITIC: `Glag` + * @HB_SCRIPT_KHAROSHTHI: `Khar` + * @HB_SCRIPT_NEW_TAI_LUE: `Talu` + * @HB_SCRIPT_OLD_PERSIAN: `Xpeo` + * @HB_SCRIPT_SYLOTI_NAGRI: `Sylo` + * @HB_SCRIPT_TIFINAGH: `Tfng` + * @HB_SCRIPT_BALINESE: `Bali` + * @HB_SCRIPT_CUNEIFORM: `Xsux` + * @HB_SCRIPT_NKO: `Nkoo` + * @HB_SCRIPT_PHAGS_PA: `Phag` + * @HB_SCRIPT_PHOENICIAN: `Phnx` + * @HB_SCRIPT_CARIAN: `Cari` + * @HB_SCRIPT_CHAM: `Cham` + * @HB_SCRIPT_KAYAH_LI: `Kali` + * @HB_SCRIPT_LEPCHA: `Lepc` + * @HB_SCRIPT_LYCIAN: `Lyci` + * @HB_SCRIPT_LYDIAN: `Lydi` + * @HB_SCRIPT_OL_CHIKI: `Olck` + * @HB_SCRIPT_REJANG: `Rjng` + * @HB_SCRIPT_SAURASHTRA: `Saur` + * @HB_SCRIPT_SUNDANESE: `Sund` + * @HB_SCRIPT_VAI: `Vaii` + * @HB_SCRIPT_AVESTAN: `Avst` + * @HB_SCRIPT_BAMUM: `Bamu` + * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp` + * @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi` + * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli` + * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti` + * @HB_SCRIPT_JAVANESE: `Java` + * @HB_SCRIPT_KAITHI: `Kthi` + * @HB_SCRIPT_LISU: `Lisu` + * @HB_SCRIPT_MEETEI_MAYEK: `Mtei` + * @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb` + * @HB_SCRIPT_OLD_TURKIC: `Orkh` + * @HB_SCRIPT_SAMARITAN: `Samr` + * @HB_SCRIPT_TAI_THAM: `Lana` + * @HB_SCRIPT_TAI_VIET: `Tavt` + * @HB_SCRIPT_BATAK: `Batk` + * @HB_SCRIPT_BRAHMI: `Brah` + * @HB_SCRIPT_MANDAIC: `Mand` + * @HB_SCRIPT_CHAKMA: `Cakm` + * @HB_SCRIPT_MEROITIC_CURSIVE: `Merc` + * @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero` + * @HB_SCRIPT_MIAO: `Plrd` + * @HB_SCRIPT_SHARADA: `Shrd` + * @HB_SCRIPT_SORA_SOMPENG: `Sora` + * @HB_SCRIPT_TAKRI: `Takr` + * @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30 + * @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30 + * @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30 + * @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30 + * @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30 + * @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30 + * @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30 + * @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30 + * @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30 + * @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30 + * @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30 + * @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30 + * @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30 + * @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30 + * @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30 + * @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30 + * @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30 + * @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30 + * @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30 + * @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30 + * @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30 + * @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30 + * @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30 + * @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30 + * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30 + * @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30 + * @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30 + * @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30 + * @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30 + * @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0 + * @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0 + * @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0 + * @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0 + * @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0 + * @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0 + * @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0 + * @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0 + * @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0 + * @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0 + * @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0 + * @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0 + * @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0 + * @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0 + * @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0 + * @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0 + * @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0 + * @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0 + * @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0 + * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0 + * @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0 + * @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7 + * @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7 + * @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7 + * @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7 + * @HB_SCRIPT_CYPRO_MINOAN: `Cpmn`, Since: 3.0.0 + * @HB_SCRIPT_OLD_UYGHUR: `Ougr`, Since: 3.0.0 + * @HB_SCRIPT_TANGSA: `Tnsa`, Since: 3.0.0 + * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0 + * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0 + * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0 + * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0 + * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0 + * @HB_SCRIPT_GARAY: `Gara`, Since: 10.0.0 + * @HB_SCRIPT_GURUNG_KHEMA: `Gukh`, Since: 10.0.0 + * @HB_SCRIPT_KIRAT_RAI: `Krai`, Since: 10.0.0 + * @HB_SCRIPT_OL_ONAL: `Onao`, Since: 10.0.0 + * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 + * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 + * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 + * @HB_SCRIPT_INVALID: No script set + * + * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding + * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/). + * + * See also the Script (sc) property of the Unicode Character Database. + * + **/ + +/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ +typedef enum +{ + HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), /*1.1*/ + HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), /*1.1*/ + HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), /*5.0*/ + + HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), /*1.1*/ + HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), /*1.1*/ + HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), /*1.1*/ + HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), /*1.1*/ + HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), /*1.1*/ + HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), /*1.1*/ + HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), /*1.1*/ + HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), /*1.1*/ + HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), /*1.1*/ + HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), /*1.1*/ + HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), /*1.1*/ + HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), /*1.1*/ + HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), /*1.1*/ + HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), /*1.1*/ + HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), /*1.1*/ + HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), /*1.1*/ + HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), /*1.1*/ + HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), /*1.1*/ + HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), /*1.1*/ + HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), /*1.1*/ + HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), /*1.1*/ + HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), /*1.1*/ + + HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/ + + HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), /*3.0*/ + HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), /*3.0*/ + HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), /*3.0*/ + HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), /*3.0*/ + HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), /*3.0*/ + HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), /*3.0*/ + HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), /*3.0*/ + HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), /*3.0*/ + HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), /*3.0*/ + HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), /*3.0*/ + HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), /*3.0*/ + HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), /*3.0*/ + HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), /*3.0*/ + HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), /*3.0*/ + + HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), /*3.1*/ + HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), /*3.1*/ + HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), /*3.1*/ + + HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), /*3.2*/ + HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), /*3.2*/ + HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), /*3.2*/ + HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), /*3.2*/ + + HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), /*4.0*/ + HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), /*4.0*/ + HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), /*4.0*/ + HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), /*4.0*/ + HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), /*4.0*/ + HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), /*4.0*/ + HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), /*4.0*/ + + HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), /*4.1*/ + HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), /*4.1*/ + HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), /*4.1*/ + HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), /*4.1*/ + HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), /*4.1*/ + HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), /*4.1*/ + HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), /*4.1*/ + HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), /*4.1*/ + + HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), /*5.0*/ + HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), /*5.0*/ + HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), /*5.0*/ + HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), /*5.0*/ + HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), /*5.0*/ + + HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), /*5.1*/ + HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), /*5.1*/ + HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), /*5.1*/ + HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), /*5.1*/ + HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), /*5.1*/ + HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), /*5.1*/ + HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), /*5.1*/ + HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), /*5.1*/ + HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), /*5.1*/ + HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), /*5.1*/ + HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), /*5.1*/ + + HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), /*5.2*/ + HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), /*5.2*/ + HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), /*5.2*/ + HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), /*5.2*/ + HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), /*5.2*/ + HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), /*5.2*/ + HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), /*5.2*/ + HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), /*5.2*/ + HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), /*5.2*/ + HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), /*5.2*/ + HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), /*5.2*/ + HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), /*5.2*/ + HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), /*5.2*/ + HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), /*5.2*/ + HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), /*5.2*/ + + HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), /*6.0*/ + HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), /*6.0*/ + HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), /*6.0*/ + + HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), /*6.1*/ + HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), /*6.1*/ + HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), /*6.1*/ + HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), /*6.1*/ + HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), /*6.1*/ + HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ + HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/ + + /* + * Since: 0.9.30 + */ + HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ + HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ + HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/ + HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), /*7.0*/ + HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), /*7.0*/ + HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), /*7.0*/ + HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), /*7.0*/ + HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), /*7.0*/ + HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/ + HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/ + HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/ + HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), /*7.0*/ + HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/ + HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/ + HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/ + HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/ + HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/ + HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/ + HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), /*7.0*/ + HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/ + HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), /*7.0*/ + HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ + HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/ + + HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), /*8.0*/ + HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), /*8.0*/ + HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), /*8.0*/ + HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), /*8.0*/ + HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), /*8.0*/ + HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), /*8.0*/ + + /* + * Since 1.3.0 + */ + HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), /*9.0*/ + HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), /*9.0*/ + HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), /*9.0*/ + HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), /*9.0*/ + HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), /*9.0*/ + HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /*9.0*/ + + /* + * Since 1.6.0 + */ + HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), /*10.0*/ + HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), /*10.0*/ + HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), /*10.0*/ + HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), /*10.0*/ + + /* + * Since 1.8.0 + */ + HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), /*11.0*/ + HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), /*11.0*/ + HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), /*11.0*/ + HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), /*11.0*/ + HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), /*11.0*/ + HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), /*11.0*/ + HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), /*11.0*/ + + /* + * Since 2.4.0 + */ + HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), /*12.0*/ + HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), /*12.0*/ + HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), /*12.0*/ + HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), /*12.0*/ + + /* + * Since 2.6.7 + */ + HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/ + HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/ + HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/ + HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/ + + /* + * Since 3.0.0 + */ + HB_SCRIPT_CYPRO_MINOAN = HB_TAG ('C','p','m','n'), /*14.0*/ + HB_SCRIPT_OLD_UYGHUR = HB_TAG ('O','u','g','r'), /*14.0*/ + HB_SCRIPT_TANGSA = HB_TAG ('T','n','s','a'), /*14.0*/ + HB_SCRIPT_TOTO = HB_TAG ('T','o','t','o'), /*14.0*/ + HB_SCRIPT_VITHKUQI = HB_TAG ('V','i','t','h'), /*14.0*/ + + /* + * Since 3.4.0 + */ + HB_SCRIPT_MATH = HB_TAG ('Z','m','t','h'), + + /* + * Since 5.2.0 + */ + HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/ + HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.0*/ + + /* + * Since 10.0.0 + */ + HB_SCRIPT_GARAY = HB_TAG ('G','a','r','a'), /*16.0*/ + HB_SCRIPT_GURUNG_KHEMA = HB_TAG ('G','u','k','h'), /*16.0*/ + HB_SCRIPT_KIRAT_RAI = HB_TAG ('K','r','a','i'), /*16.0*/ + HB_SCRIPT_OL_ONAL = HB_TAG ('O','n','a','o'), /*16.0*/ + HB_SCRIPT_SUNUWAR = HB_TAG ('S','u','n','u'), /*16.0*/ + HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ + HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ + + /* No script set. */ + HB_SCRIPT_INVALID = HB_TAG_NONE, + + /*< private >*/ + + /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t + * without risking undefined behavior. We have two, for historical reasons. + * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed + * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well. + * + * See this thread for technicalities: + * + * https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html + */ + _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/ + _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/ + +} hb_script_t; + + +#endif /* HB_SCRIPT_LIST_H */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh index 7bd14a28193..f0416d5fa1d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh @@ -31,11 +31,10 @@ #include "hb-machinery.hh" /* - * The set-digests here implement various "filters" that support - * "approximate member query". Conceptually these are like Bloom - * Filter and Quotient Filter, however, much smaller, faster, and - * designed to fit the requirements of our uses for glyph coverage - * queries. + * The set-digests implement "filters" that support "approximate + * member query". Conceptually these are like Bloom Filter and + * Quotient Filter, however, much smaller, faster, and designed + * to fit the requirements of our uses for glyph coverage queries. * * Our filters are highly accurate if the lookup covers fairly local * set of glyphs, but fully flooded and ineffective if coverage is diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-set.hh index eaa892ab9f5..c5df9b8aec4 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-set.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-set.hh @@ -30,6 +30,7 @@ #include "hb.hh" #include "hb-bit-set-invertible.hh" +#include "hb-bit-vector.hh" // Just to include template diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-shape.cc index 2f7d335ddce..d14f577be00 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-shape.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-shape.cc @@ -91,8 +91,10 @@ void free_static_shaper_list () * * Retrieves the list of shapers supported by HarfBuzz. * - * Return value: (transfer none) (array zero-terminated=1): an array of - * constant strings + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported shapers constant string. + * The returned array is owned by HarfBuzz and should not be + * modified or freed. * * Since: 0.9.2 **/ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-static.cc b/src/java.desktop/share/native/libharfbuzz/hb-static.cc index abdfda9a756..4e70e413651 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-static.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-static.cc @@ -41,6 +41,7 @@ #include "hb-ot-maxp-table.hh" #ifndef HB_NO_VISIBILITY + #include "hb-ot-name-language-static.hh" uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {}; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh index 62206e0f5aa..e7bddaef723 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh @@ -570,7 +570,7 @@ struct cff_subset_accelerator_t parsed_cs_str_vec_t parsed_charstrings; parsed_cs_str_vec_t parsed_global_subrs; hb_vector_t parsed_local_subrs; - mutable hb_atomic_ptr_t glyph_to_sid_map; + mutable hb_atomic_t glyph_to_sid_map; private: hb_blob_t* original_blob; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc index bbe50b1fb36..5de29081cc1 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc @@ -868,7 +868,7 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, src = hb_utf8_t::next (src, src_end, &unicode, replacement); if (unicode >= 0x0080u) { - printf ("Non-ascii character detected, ignored...This API supports ascii characters only for mac platform\n"); + // Non-ascii character detected, ignored... return false; } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc index fb5282916b9..3ba726d925e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc @@ -29,27 +29,21 @@ #include "hb-map.hh" #include "hb-multimap.hh" #include "hb-set.hh" +#include "hb-subset.h" +#include "hb-unicode.h" #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-layout-base-table.hh" -#include "hb-ot-layout-gdef-table.hh" -#include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-layout-gsub-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" #include "OT/Color/COLR/COLR.hh" #include "OT/Color/COLR/colrv1-closure.hh" #include "OT/Color/CPAL/CPAL.hh" #include "hb-ot-var-fvar-table.hh" -#include "hb-ot-var-avar-table.hh" #include "hb-ot-stat-table.hh" #include "hb-ot-math-table.hh" -using OT::Layout::GSUB; -using OT::Layout::GPOS; - - hb_subset_accelerator_t::~hb_subset_accelerator_t () { if (cmap_cache && destroy_cmap_cache) @@ -63,7 +57,6 @@ hb_subset_accelerator_t::~hb_subset_accelerator_t () } -typedef hb_hashmap_t> script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline bool _add_cff_seac_components (const OT::cff1::accelerator_subset_t &cff, @@ -98,414 +91,14 @@ _remap_palette_indexes (const hb_set_t *palette_indexes, } } -static void -_remap_indexes (const hb_set_t *indexes, - hb_map_t *mapping /* OUT */) +void +remap_indexes (const hb_set_t *indexes, + hb_map_t *mapping /* OUT */) { for (auto _ : + hb_enumerate (indexes->iter ())) mapping->set (_.second, _.first); - -} - -#ifndef HB_NO_SUBSET_LAYOUT - -/* - * Removes all tags from 'tags' that are not in filter. Additionally eliminates any duplicates. - * Returns true if anything was removed (not including duplicates). - */ -static bool _filter_tag_list(hb_vector_t* tags, /* IN/OUT */ - const hb_set_t* filter) -{ - hb_vector_t out; - out.alloc (tags->get_size() + 1); // +1 is to allocate room for the null terminator. - - bool removed = false; - hb_set_t visited; - - for (hb_tag_t tag : *tags) - { - if (!tag) continue; - if (visited.has (tag)) continue; - - if (!filter->has (tag)) - { - removed = true; - continue; - } - - visited.add (tag); - out.push (tag); - } - - // The collect function needs a null element to signal end of the array. - out.push (HB_TAG_NONE); - - hb_swap (out, *tags); - return removed; -} - -template -static void _collect_layout_indices (hb_subset_plan_t *plan, - const T& table, - hb_set_t *lookup_indices, /* OUT */ - hb_set_t *feature_indices, /* OUT */ - hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */ - hb_hashmap_t *feature_substitutes_map, /* OUT */ - hb_set_t& catch_all_record_feature_idxes, /* OUT */ - hb_hashmap_t>& catch_all_record_idx_feature_map /* OUT */) -{ - unsigned num_features = table.get_feature_count (); - hb_vector_t features; - if (!plan->check_success (features.resize (num_features))) return; - table.get_feature_tags (0, &num_features, features.arrayZ); - bool retain_all_features = !_filter_tag_list (&features, &plan->layout_features); - - unsigned num_scripts = table.get_script_count (); - hb_vector_t scripts; - if (!plan->check_success (scripts.resize (num_scripts))) return; - table.get_script_tags (0, &num_scripts, scripts.arrayZ); - bool retain_all_scripts = !_filter_tag_list (&scripts, &plan->layout_scripts); - - if (!plan->check_success (!features.in_error ()) || !features - || !plan->check_success (!scripts.in_error ()) || !scripts) - return; - - hb_ot_layout_collect_features (plan->source, - T::tableTag, - retain_all_scripts ? nullptr : scripts.arrayZ, - nullptr, - retain_all_features ? nullptr : features.arrayZ, - feature_indices); - -#ifndef HB_NO_VAR - // collect feature substitutes with variations - if (!plan->user_axes_location.is_empty ()) - { - hb_hashmap_t, unsigned> conditionset_map; - OT::hb_collect_feature_substitutes_with_var_context_t c = - { - &plan->axes_old_index_tag_map, - &plan->axes_location, - feature_record_cond_idx_map, - feature_substitutes_map, - catch_all_record_feature_idxes, - feature_indices, - false, - false, - false, - 0, - &conditionset_map - }; - table.collect_feature_substitutes_with_variations (&c); - } -#endif - - for (unsigned feature_index : *feature_indices) - { - const OT::Feature* f = &(table.get_feature (feature_index)); - const OT::Feature **p = nullptr; - if (feature_substitutes_map->has (feature_index, &p)) - f = *p; - - f->add_lookup_indexes_to (lookup_indices); - } - -#ifndef HB_NO_VAR - if (catch_all_record_feature_idxes) - { - for (unsigned feature_index : catch_all_record_feature_idxes) - { - const OT::Feature& f = table.get_feature (feature_index); - f.add_lookup_indexes_to (lookup_indices); - const void *tag = reinterpret_cast (&(table.get_feature_list ().get_tag (feature_index))); - catch_all_record_idx_feature_map.set (feature_index, hb_pair (&f, tag)); - } - } - - // If all axes are pinned then all feature variations will be dropped so there's no need - // to collect lookups from them. - if (!plan->all_axes_pinned) - table.feature_variation_collect_lookups (feature_indices, - plan->user_axes_location.is_empty () ? nullptr: feature_record_cond_idx_map, - lookup_indices); -#endif -} - - -static inline void -_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g, - const hb_map_t *lookup_indices, - const hb_set_t *feature_indices, - const hb_hashmap_t *feature_substitutes_map, - hb_map_t *duplicate_feature_map /* OUT */) -{ - if (feature_indices->is_empty ()) return; - hb_hashmap_t> unique_features; - //find out duplicate features after subset - for (unsigned i : feature_indices->iter ()) - { - hb_tag_t t = g.get_feature_tag (i); - if (t == HB_MAP_VALUE_INVALID) continue; - if (!unique_features.has (t)) - { - if (unlikely (!unique_features.set (t, hb::unique_ptr {hb_set_create ()}))) - return; - if (unique_features.has (t)) - unique_features.get (t)->add (i); - duplicate_feature_map->set (i, i); - continue; - } - - bool found = false; - - hb_set_t* same_tag_features = unique_features.get (t); - for (unsigned other_f_index : same_tag_features->iter ()) - { - const OT::Feature* f = &(g.get_feature (i)); - const OT::Feature **p = nullptr; - if (feature_substitutes_map->has (i, &p)) - f = *p; - - const OT::Feature* other_f = &(g.get_feature (other_f_index)); - if (feature_substitutes_map->has (other_f_index, &p)) - other_f = *p; - - auto f_iter = - + hb_iter (f->lookupIndex) - | hb_filter (lookup_indices) - ; - - auto other_f_iter = - + hb_iter (other_f->lookupIndex) - | hb_filter (lookup_indices) - ; - - bool is_equal = true; - for (; f_iter && other_f_iter; f_iter++, other_f_iter++) - { - unsigned a = *f_iter; - unsigned b = *other_f_iter; - if (a != b) { is_equal = false; break; } - } - - if (is_equal == false || f_iter || other_f_iter) continue; - - found = true; - duplicate_feature_map->set (i, other_f_index); - break; - } - - if (found == false) - { - same_tag_features->add (i); - duplicate_feature_map->set (i, i); - } - } -} - -template -static inline void -_closure_glyphs_lookups_features (hb_subset_plan_t *plan, - hb_set_t *gids_to_retain, - hb_map_t *lookups, - hb_map_t *features, - script_langsys_map *langsys_map, - hb_hashmap_t> *feature_record_cond_idx_map, - hb_hashmap_t *feature_substitutes_map, - hb_set_t &catch_all_record_feature_idxes, - hb_hashmap_t>& catch_all_record_idx_feature_map) -{ - hb_blob_ptr_t table = plan->source_table (); - hb_tag_t table_tag = table->tableTag; - hb_set_t lookup_indices, feature_indices; - _collect_layout_indices (plan, - *table, - &lookup_indices, - &feature_indices, - feature_record_cond_idx_map, - feature_substitutes_map, - catch_all_record_feature_idxes, - catch_all_record_idx_feature_map); - - if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) - hb_ot_layout_lookups_substitute_closure (plan->source, - &lookup_indices, - gids_to_retain); - table->closure_lookups (plan->source, - gids_to_retain, - &lookup_indices); - _remap_indexes (&lookup_indices, lookups); - - // prune features - table->prune_features (lookups, - plan->user_axes_location.is_empty () ? nullptr : feature_record_cond_idx_map, - feature_substitutes_map, - &feature_indices); - hb_map_t duplicate_feature_map; - _GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, feature_substitutes_map, &duplicate_feature_map); - - feature_indices.clear (); - table->prune_langsys (&duplicate_feature_map, &plan->layout_scripts, langsys_map, &feature_indices); - _remap_indexes (&feature_indices, features); - - table.destroy (); -} - -#endif - -#ifndef HB_NO_VAR -static inline void -_generate_varstore_inner_maps (const hb_set_t& varidx_set, - unsigned subtable_count, - hb_vector_t &inner_maps /* OUT */) -{ - if (varidx_set.is_empty () || subtable_count == 0) return; - - if (unlikely (!inner_maps.resize (subtable_count))) return; - for (unsigned idx : varidx_set) - { - uint16_t major = idx >> 16; - uint16_t minor = idx & 0xFFFF; - - if (major >= subtable_count) - continue; - inner_maps[major].add (minor); - } -} - -static inline hb_font_t* -_get_hb_font_with_variations (const hb_subset_plan_t *plan) -{ - hb_font_t *font = hb_font_create (plan->source); - - hb_vector_t vars; - if (!vars.alloc (plan->user_axes_location.get_population ())) { - hb_font_destroy (font); - return nullptr; - } - - for (auto _ : plan->user_axes_location) - { - hb_variation_t var; - var.tag = _.first; - var.value = _.second.middle; - vars.push (var); - } - -#ifndef HB_NO_VAR - hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ()); -#endif - return font; -} - -static inline void -_remap_variation_indices (const OT::ItemVariationStore &var_store, - const hb_set_t &variation_indices, - const hb_vector_t& normalized_coords, - bool calculate_delta, /* not pinned at default */ - bool no_variations, /* all axes pinned */ - hb_hashmap_t> &variation_idx_delta_map /* OUT */) -{ - if (&var_store == &Null (OT::ItemVariationStore)) return; - unsigned subtable_count = var_store.get_sub_table_count (); - float *store_cache = var_store.create_cache (); - - unsigned new_major = 0, new_minor = 0; - unsigned last_major = (variation_indices.get_min ()) >> 16; - for (unsigned idx : variation_indices) - { - int delta = 0; - if (calculate_delta) - delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, - normalized_coords.length, store_cache)); - - if (no_variations) - { - variation_idx_delta_map.set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); - continue; - } - - uint16_t major = idx >> 16; - if (major >= subtable_count) break; - if (major != last_major) - { - new_minor = 0; - ++new_major; - } - - unsigned new_idx = (new_major << 16) + new_minor; - variation_idx_delta_map.set (idx, hb_pair_t (new_idx, delta)); - ++new_minor; - last_major = major; - } - var_store.destroy_cache (store_cache); -} - -static inline void -_collect_layout_variation_indices (hb_subset_plan_t* plan) -{ - hb_blob_ptr_t gdef = plan->source_table (); - hb_blob_ptr_t gpos = plan->source_table (); - - if (!gdef->has_data () || !gdef->has_var_store ()) - { - gdef.destroy (); - gpos.destroy (); - return; - } - - hb_set_t varidx_set; - OT::hb_collect_variation_indices_context_t c (&varidx_set, - &plan->_glyphset_gsub, - &plan->gpos_lookups); - gdef->collect_variation_indices (&c); - - if (hb_ot_layout_has_positioning (plan->source)) - gpos->collect_variation_indices (&c); - - _remap_variation_indices (gdef->get_var_store (), - varidx_set, plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - plan->layout_variation_idx_delta_map); - - unsigned subtable_count = gdef->get_var_store ().get_sub_table_count (); - _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); - - gdef.destroy (); - gpos.destroy (); -} - -#ifndef HB_NO_BASE -static inline void -_collect_base_variation_indices (hb_subset_plan_t* plan) -{ - hb_blob_ptr_t base = plan->source_table (); - if (!base->has_var_store ()) - { - base.destroy (); - return; - } - - hb_set_t varidx_set; - base->collect_variation_indices (plan, varidx_set); - const OT::ItemVariationStore &var_store = base->get_var_store (); - unsigned subtable_count = var_store.get_sub_table_count (); - - - _remap_variation_indices (var_store, varidx_set, - plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - plan->base_variation_idx_map); - _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); - - base.destroy (); } -#endif -#endif - static inline void _cmap_closure (hb_face_t *face, const hb_set_t *unicodes, @@ -515,41 +108,6 @@ _cmap_closure (hb_face_t *face, cmap.table->closure_glyphs (unicodes, glyphset); } -#ifndef HB_NO_VAR -static void -_remap_colrv1_delta_set_index_indices (const OT::DeltaSetIndexMap &index_map, - const hb_set_t &delta_set_idxes, - hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ - hb_map_t &new_deltaset_idx_varidx_map /* OUT */) -{ - if (!index_map.get_map_count ()) - return; - - hb_hashmap_t> delta_set_idx_delta_map; - unsigned new_delta_set_idx = 0; - for (unsigned delta_set_idx : delta_set_idxes) - { - unsigned var_idx = index_map.map (delta_set_idx); - unsigned new_varidx = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; - int delta = 0; - - if (var_idx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) - { - hb_pair_t *new_varidx_delta; - if (!variation_idx_delta_map.has (var_idx, &new_varidx_delta)) continue; - - new_varidx = hb_first (*new_varidx_delta); - delta = hb_second (*new_varidx_delta); - } - - new_deltaset_idx_varidx_map.set (new_delta_set_idx, new_varidx); - delta_set_idx_delta_map.set (delta_set_idx, hb_pair_t (new_delta_set_idx, delta)); - new_delta_set_idx++; - } - variation_idx_delta_map = std::move (delta_set_idx_delta_map); -} -#endif - static void _colr_closure (hb_subset_plan_t* plan, hb_set_t *glyphs_colred) { @@ -569,7 +127,7 @@ static void _colr_closure (hb_subset_plan_t* plan, colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices, &variation_indices, &delta_set_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); - _remap_indexes (&layer_indices, &plan->colrv1_layers); + remap_indexes (&layer_indices, &plan->colrv1_layers); _remap_palette_indexes (&palette_indices, &plan->colr_palettes); #ifndef HB_NO_VAR @@ -578,7 +136,7 @@ static void _colr_closure (hb_subset_plan_t* plan, const OT::ItemVariationStore &var_store = colr.get_var_store (); // generated inner_maps is used by ItemVariationStore serialize(), which is subset only unsigned subtable_count = var_store.get_sub_table_count (); - _generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); + generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); /* colr variation indices mapping during planning phase: * generate colrv1_variation_idx_delta_map. When delta set index map is not @@ -590,7 +148,7 @@ static void _colr_closure (hb_subset_plan_t* plan, * instancing. */ if (!plan->all_axes_pinned) { - _remap_variation_indices (var_store, + remap_variation_indices (var_store, variation_indices, plan->normalized_coords, false, /* no need to calculate delta for COLR during planning */ @@ -598,7 +156,7 @@ static void _colr_closure (hb_subset_plan_t* plan, plan->colrv1_variation_idx_delta_map); if (colr.has_delta_set_index_map ()) - _remap_colrv1_delta_set_index_indices (colr.get_delta_set_index_map (), + remap_colrv1_delta_set_index_indices (colr.get_delta_set_index_map (), delta_set_indices, plan->colrv1_variation_idx_delta_map, plan->colrv1_new_deltaset_idx_varidx_map); @@ -616,25 +174,6 @@ _math_closure (hb_subset_plan_t *plan, math.destroy (); } -static inline void -_remap_used_mark_sets (hb_subset_plan_t *plan, - hb_map_t& used_mark_sets_map) -{ - hb_blob_ptr_t gdef = plan->source_table (); - - if (!gdef->has_data () || !gdef->has_mark_glyph_sets ()) - { - gdef.destroy (); - return; - } - - hb_set_t used_mark_sets; - gdef->get_mark_glyph_sets ().collect_used_mark_sets (plan->_glyphset_gsub, used_mark_sets); - gdef.destroy (); - - _remap_indexes (&used_mark_sets, &used_mark_sets_map); -} - static inline void _remove_invalid_gids (hb_set_t *glyphs, unsigned int num_glyphs) @@ -672,15 +211,46 @@ _fill_unicode_and_glyph_map(hb_subset_plan_t *plan, _fill_unicode_and_glyph_map(plan, unicode_iterator, unicode_to_gid_for_iterator, unicode_to_gid_for_iterator); } +/* + * Finds additional unicode codepoints which are reachable from the input unicode set. + * Currently this adds in mirrored variants (needed for bidi) of any input unicodes. + */ +static hb_set_t +_unicode_closure (const hb_set_t* unicodes, bool bidi_closure) { + // TODO: we may want to also consider pulling in reachable unicode composition and decompositions. + // see: https://github.com/harfbuzz/harfbuzz/issues/2283 + hb_set_t out = *unicodes; + if (!bidi_closure) return out; + + if (out.is_inverted()) { + // don't closure inverted sets, they are asking to specifically exclude certain codepoints. + // otherwise everything is already included. + return out; + } + + auto unicode_funcs = hb_unicode_funcs_get_default (); + for (hb_codepoint_t cp : *unicodes) { + hb_codepoint_t mirror = hb_unicode_mirroring(unicode_funcs, cp); + if (unlikely (mirror != cp)) { + out.add(mirror); + } + } + + return out; +} + static void -_populate_unicodes_to_retain (const hb_set_t *unicodes, +_populate_unicodes_to_retain (const hb_set_t *unicodes_in, const hb_set_t *glyphs, hb_subset_plan_t *plan) { + hb_set_t unicodes = _unicode_closure(unicodes_in, + !(plan->flags & HB_SUBSET_FLAGS_NO_BIDI_CLOSURE)); + OT::cmap::accelerator_t cmap (plan->source); unsigned size_threshold = plan->source->get_num_glyphs (); - if (glyphs->is_empty () && unicodes->get_population () < size_threshold) + if (glyphs->is_empty () && unicodes.get_population () < size_threshold) { const hb_map_t* unicode_to_gid = nullptr; @@ -690,9 +260,9 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, // This is approach to collection is faster, but can only be used if glyphs // are not being explicitly added to the subset and the input unicodes set is // not excessively large (eg. an inverted set). - plan->unicode_to_new_gid_list.alloc (unicodes->get_population ()); + plan->unicode_to_new_gid_list.alloc (unicodes.get_population ()); if (!unicode_to_gid) { - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { hb_codepoint_t gid; if (!cmap.get_nominal_glyph (cp, &gid)) { return HB_MAP_VALUE_INVALID; @@ -704,7 +274,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, // the map. This code is mostly duplicated from above to avoid doing // conditionals on the presence of the unicode_to_gid map each // iteration. - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { return unicode_to_gid->get (cp); }); } @@ -721,7 +291,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, if (!plan->accelerator) { cmap.collect_mapping (&cmap_unicodes_storage, &unicode_glyphid_map_storage); - plan->unicode_to_new_gid_list.alloc (hb_min(unicodes->get_population () + plan->unicode_to_new_gid_list.alloc (hb_min(unicodes.get_population () + glyphs->get_population (), cmap_unicodes->get_population ())); } else { @@ -730,10 +300,10 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, } if (plan->accelerator && - unicodes->get_population () < cmap_unicodes->get_population () && + unicodes.get_population () < cmap_unicodes->get_population () && glyphs->get_population () < cmap_unicodes->get_population ()) { - plan->codepoint_to_glyph->alloc (unicodes->get_population () + glyphs->get_population ()); + plan->codepoint_to_glyph->alloc (unicodes.get_population () + glyphs->get_population ()); auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes; @@ -748,7 +318,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, }); } - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { /* Don't double-add entry. */ if (plan->codepoint_to_glyph->has (cp)) return HB_MAP_VALUE_INVALID; @@ -769,7 +339,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, { _fill_unicode_and_glyph_map(plan, hb_range(first, last + 1), [&] (hb_codepoint_t cp) { hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; - if (!unicodes->has (cp) && !glyphs->has (gid)) + if (!unicodes.has (cp) && !glyphs->has (gid)) return HB_MAP_VALUE_INVALID; return gid; }, @@ -860,18 +430,7 @@ _nameid_closure (hb_subset_plan_t* plan, #endif #ifndef HB_NO_SUBSET_LAYOUT - if (!drop_tables->has (HB_OT_TAG_GPOS)) - { - hb_blob_ptr_t gpos = plan->source_table (); - gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids); - gpos.destroy (); - } - if (!drop_tables->has (HB_OT_TAG_GSUB)) - { - hb_blob_ptr_t gsub = plan->source_table (); - gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids); - gsub.destroy (); - } + layout_nameid_closure(plan, drop_tables); #endif } @@ -893,31 +452,9 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _cmap_closure (plan->source, &plan->unicodes, &plan->_glyphset_gsub); #ifndef HB_NO_SUBSET_LAYOUT - if (!drop_tables->has (HB_OT_TAG_GSUB)) - // closure all glyphs/lookups/features needed for GSUB substitutions. - _closure_glyphs_lookups_features ( - plan, - &plan->_glyphset_gsub, - &plan->gsub_lookups, - &plan->gsub_features, - &plan->gsub_langsys, - &plan->gsub_feature_record_cond_idx_map, - &plan->gsub_feature_substitutes_map, - plan->gsub_old_features, - plan->gsub_old_feature_idx_tag_map); - - if (!drop_tables->has (HB_OT_TAG_GPOS)) - _closure_glyphs_lookups_features ( - plan, - &plan->_glyphset_gsub, - &plan->gpos_lookups, - &plan->gpos_features, - &plan->gpos_langsys, - &plan->gpos_feature_record_cond_idx_map, - &plan->gpos_feature_substitutes_map, - plan->gpos_old_features, - plan->gpos_old_feature_idx_tag_map); + layout_populate_gids_to_retain(plan, drop_tables); #endif + _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ()); plan->_glyphset_mathed = plan->_glyphset_gsub; @@ -962,8 +499,10 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _remove_invalid_gids (&plan->_glyphset, plan->source->get_num_glyphs ()); #ifndef HB_NO_VAR +#ifndef HB_NO_SUBSET_LAYOUT if (!drop_tables->has (HB_OT_TAG_GDEF)) - _collect_layout_variation_indices (plan); + collect_layout_variation_indices (plan); +#endif #endif } @@ -1077,193 +616,6 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, return true; } -#ifndef HB_NO_VAR -static void -_normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) -{ - if (plan->user_axes_location.is_empty ()) - return; - - hb_array_t axes = face->table.fvar->get_axes (); - plan->normalized_coords.resize (axes.length); - - bool has_avar = face->table.avar->has_data (); - const OT::SegmentMaps *seg_maps = nullptr; - unsigned avar_axis_count = 0; - if (has_avar) - { - seg_maps = face->table.avar->get_segment_maps (); - avar_axis_count = face->table.avar->get_axis_count(); - } - - bool axis_not_pinned = false; - unsigned old_axis_idx = 0, new_axis_idx = 0; - for (const auto& axis : axes) - { - hb_tag_t axis_tag = axis.get_axis_tag (); - plan->axes_old_index_tag_map.set (old_axis_idx, axis_tag); - - if (!plan->user_axes_location.has (axis_tag) || - !plan->user_axes_location.get (axis_tag).is_point ()) - { - axis_not_pinned = true; - plan->axes_index_map.set (old_axis_idx, new_axis_idx); - plan->axis_tags.push (axis_tag); - new_axis_idx++; - } - - Triple *axis_range; - if (plan->user_axes_location.has (axis_tag, &axis_range)) - { - plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ()); - - int normalized_min = axis.normalize_axis_value (axis_range->minimum); - int normalized_default = axis.normalize_axis_value (axis_range->middle); - int normalized_max = axis.normalize_axis_value (axis_range->maximum); - - if (has_avar && old_axis_idx < avar_axis_count) - { - normalized_min = seg_maps->map (normalized_min); - normalized_default = seg_maps->map (normalized_default); - normalized_max = seg_maps->map (normalized_max); - } - plan->axes_location.set (axis_tag, Triple (static_cast (normalized_min / 16384.0), - static_cast (normalized_default / 16384.0), - static_cast (normalized_max / 16384.0))); - - if (normalized_default != 0) - plan->pinned_at_default = false; - - plan->normalized_coords[old_axis_idx] = normalized_default; - } - - old_axis_idx++; - - if (has_avar && old_axis_idx < avar_axis_count) - seg_maps = &StructAfter (*seg_maps); - } - plan->all_axes_pinned = !axis_not_pinned; -} - -static void -_update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) -{ - if (!plan->normalized_coords) return; - OT::cff2::accelerator_t cff2 (plan->source); - if (!cff2.is_valid ()) return; - - hb_font_t *font = _get_hb_font_with_variations (plan); - if (unlikely (!plan->check_success (font != nullptr))) - { - hb_font_destroy (font); - return; - } - - hb_glyph_extents_t extents = {0x7FFF, -0x7FFF}; - OT::hmtx_accelerator_t _hmtx (plan->source); - float *hvar_store_cache = nullptr; - if (_hmtx.has_data () && _hmtx.var_table.get_length ()) - hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache (); - - OT::vmtx_accelerator_t _vmtx (plan->source); - float *vvar_store_cache = nullptr; - if (_vmtx.has_data () && _vmtx.var_table.get_length ()) - vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache (); - - for (auto p : *plan->glyph_map) - { - hb_codepoint_t old_gid = p.first; - hb_codepoint_t new_gid = p.second; - if (!cff2.get_extents (font, old_gid, &extents)) continue; - bool has_bounds_info = true; - if (extents.x_bearing == 0 && extents.width == 0 && - extents.height == 0 && extents.y_bearing == 0) - has_bounds_info = false; - - if (has_bounds_info) - { - plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing); - plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width); - plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing); - plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height); - } - - if (_hmtx.has_data ()) - { - int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid); - if (_hmtx.var_table.get_length ()) - hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, - hvar_store_cache)); - int lsb = extents.x_bearing; - if (!has_bounds_info) - { - if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) - continue; - } - plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); - plan->bounds_width_vec[new_gid] = extents.width; - } - - if (_vmtx.has_data ()) - { - int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid); - if (_vmtx.var_table.get_length ()) - vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, - vvar_store_cache)); - - int tsb = extents.y_bearing; - if (!has_bounds_info) - { - if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb)) - continue; - } - plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); - plan->bounds_height_vec[new_gid] = extents.height; - } - } - hb_font_destroy (font); - if (hvar_store_cache) - _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache); - if (vvar_store_cache) - _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache); -} - -static bool -_get_instance_glyphs_contour_points (hb_subset_plan_t *plan) -{ - /* contour_points vector only needed for updating gvar table (infer delta and - * iup delta optimization) during partial instancing */ - if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) - return true; - - OT::glyf_accelerator_t glyf (plan->source); - - for (auto &_ : plan->new_to_old_gid_list) - { - hb_codepoint_t new_gid = _.first; - contour_point_vector_t all_points; - if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) - { - if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) - return false; - continue; - } - - hb_codepoint_t old_gid = _.second; - auto glyph = glyf.glyph_for_gid (old_gid); - if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) - return false; - if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) - return false; - - /* composite new gids are only needed by iup delta optimization */ - if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) - plan->composite_new_gids.add (new_gid); - } - return true; -} -#endif - hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, const hb_subset_input_t *input) { @@ -1324,7 +676,7 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; #ifndef HB_NO_VAR - _normalize_axes_location (face, this); + normalize_axes_location (face, this); #endif _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this); @@ -1365,13 +717,15 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, for (auto &v : bounds_height_vec) v = 0xFFFFFFFF; +#ifndef HB_NO_SUBSET_LAYOUT if (!drop_tables.has (HB_OT_TAG_GDEF)) - _remap_used_mark_sets (this, used_mark_sets_map); + remap_used_mark_sets (this, used_mark_sets_map); +#endif #ifndef HB_NO_VAR #ifndef HB_NO_BASE if (!drop_tables.has (HB_OT_TAG_BASE)) - _collect_base_variation_indices (this); + collect_base_variation_indices (this); #endif #endif @@ -1379,8 +733,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; #ifndef HB_NO_VAR - _update_instance_metrics_map_from_cff2 (this); - if (!check_success (_get_instance_glyphs_contour_points (this))) + update_instance_metrics_map_from_cff2 (this); + if (!check_success (get_instance_glyphs_contour_points (this))) return; #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh index a6bae23966a..8a6574365ed 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh @@ -296,5 +296,75 @@ struct hb_subset_plan_t } }; +// hb-subset-plan implementation is split into multiple files to keep +// compile times more reasonable: +// - hb-subset-plan.cc +// - hb-subset-plan-layout.cc +// +// The functions below are those needed to connect the split files +// above together. +HB_INTERNAL void +remap_indexes (const hb_set_t *indexes, + hb_map_t *mapping /* OUT */); + + +#ifndef HB_NO_VAR +template +HB_INTERNAL void +remap_variation_indices (const ItemVarStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */); + + +template +HB_INTERNAL void +remap_colrv1_delta_set_index_indices (const DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */); + + +HB_INTERNAL void +generate_varstore_inner_maps (const hb_set_t& varidx_set, + unsigned subtable_count, + hb_vector_t &inner_maps /* OUT */); + +HB_INTERNAL void +normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan); + +HB_INTERNAL void +update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan); + +HB_INTERNAL bool +get_instance_glyphs_contour_points (hb_subset_plan_t *plan); + +#ifndef HB_NO_BASE +HB_INTERNAL void +collect_base_variation_indices (hb_subset_plan_t* plan); +#endif +#endif + +#ifndef HB_NO_SUBSET_LAYOUT +typedef hb_hashmap_t> script_langsys_map; + +HB_INTERNAL void +remap_used_mark_sets (hb_subset_plan_t *plan, + hb_map_t& used_mark_sets_map); + +HB_INTERNAL void +layout_nameid_closure (hb_subset_plan_t* plan, + hb_set_t* drop_tables); + +HB_INTERNAL void +layout_populate_gids_to_retain (hb_subset_plan_t* plan, + hb_set_t* drop_tables); + +HB_INTERNAL void +collect_layout_variation_indices (hb_subset_plan_t* plan); +#endif + #endif /* HB_SUBSET_PLAN_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc index 595cafc283e..079c94eddfe 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc @@ -708,3 +708,107 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) end: return success ? hb_face_reference (plan->dest) : nullptr; } + + +#ifdef HB_EXPERIMENTAL_API + +#include "hb-ot-cff1-table.hh" + +template +static hb_blob_t* get_charstrings_data(accel_t& accel, hb_codepoint_t glyph_index) { + if (!accel.is_valid()) { + return hb_blob_get_empty (); + } + + hb_ubytes_t bytes = (*accel.charStrings)[glyph_index]; + if (!bytes) { + return hb_blob_get_empty (); + } + + hb_blob_t* cff_blob = accel.get_blob(); + uint32_t length; + const char* cff_data = hb_blob_get_data(cff_blob, &length) ; + + long int offset = (const char*) bytes.arrayZ - cff_data; + if (offset < 0 || offset > INT32_MAX) { + return hb_blob_get_empty (); + } + + return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, bytes.length); +} + +template +static hb_blob_t* get_charstrings_index(accel_t& accel) { + if (!accel.is_valid()) { + return hb_blob_get_empty (); + } + + const char* charstrings_start = (const char*) accel.charStrings; + unsigned charstrings_length = accel.charStrings->get_size(); + + hb_blob_t* cff_blob = accel.get_blob(); + uint32_t length; + const char* cff_data = hb_blob_get_data(cff_blob, &length) ; + + long int offset = charstrings_start - cff_data; + if (offset < 0 || offset > INT32_MAX) { + return hb_blob_get_empty (); + } + + return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, charstrings_length); +} + +/** + * hb_subset_cff_get_charstring_data: + * @face: A face object + * @glyph_index: Glyph index to get data for. + * + * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { + return get_charstrings_data(*face->table.cff1, glyph_index); +} + +/** + * hb_subset_cff_get_charstrings_index: + * @face: A face object + * + * Returns the raw CFF CharStrings INDEX from the CFF table. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstrings_index (hb_face_t* face) { + return get_charstrings_index (*face->table.cff1); +} + +/** + * hb_subset_cff2_get_charstring_data: + * @face: A face object + * @glyph_index: Glyph index to get data for. + * + * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { + return get_charstrings_data(*face->table.cff2, glyph_index); +} + +/** + * hb_subset_cff2_get_charstrings_index: + * @face: A face object + * + * Returns the raw CFF2 CharStrings INDEX from the CFF2 table. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstrings_index (hb_face_t* face) { + return get_charstrings_index (*face->table.cff2); +} +#endif \ No newline at end of file diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.h b/src/java.desktop/share/native/libharfbuzz/hb-subset.h index 13fcd5332e6..3eccd25738e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.h @@ -71,10 +71,12 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * in the final subset. * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in * OS/2 will not be recalculated. - * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout + * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set do not perform glyph closure on layout * substitution rules (GSUB). Since: 7.2.0. * @HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS: If set perform IUP delta optimization on the * remaining gvar table's deltas. Since: 8.5.0 + * @HB_SUBSET_FLAGS_NO_BIDI_CLOSURE: If set do not pull mirrored versions of input + * codepoints into the subset. Since: 11.1.0 * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset * to allow it to be used with incremental font transfer IFTB patches. Primarily, * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL @@ -96,8 +98,9 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS = 0x00000400u, + HB_SUBSET_FLAGS_NO_BIDI_CLOSURE = 0x00000800u, #ifdef HB_EXPERIMENTAL_API - HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00000800u, + HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00001000u, #endif } hb_subset_flags_t; @@ -224,6 +227,23 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, unsigned language_id, const char *name_str, int str_len); + + +/* +* Raw outline data access +*/ + +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstring_data (hb_face_t* face, hb_codepoint_t glyph_index); + +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstrings_index (hb_face_t* face); + +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstring_data (hb_face_t* face, hb_codepoint_t glyph_index); + +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstrings_index (hb_face_t* face); #endif HB_EXTERN hb_face_t * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh index 7e755818ddd..cd27da96648 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh @@ -90,7 +90,13 @@ struct hb_vector_t { auto iter = hb_iter (o); if (iter.is_random_access_iterator || iter.has_fast_len) - alloc (hb_len (iter), true); + { + if (unlikely (!alloc (hb_len (iter), true))) + return; + unsigned count = hb_len (iter); + for (unsigned i = 0; i < count; i++) + push_has_room (*iter++); + } while (iter) { if (unlikely (!alloc (length + 1))) @@ -436,7 +442,6 @@ struct hb_vector_t new_allocated += (new_allocated >> 1) + 8; } - /* Reallocate */ bool overflows = diff --git a/src/java.desktop/share/native/libharfbuzz/hb-version.h b/src/java.desktop/share/native/libharfbuzz/hb-version.h index 01edf174350..e41286d2d8c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-version.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-version.h @@ -41,13 +41,13 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 10 +#define HB_VERSION_MAJOR 11 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 4 +#define HB_VERSION_MINOR 2 /** * HB_VERSION_MICRO: * @@ -60,7 +60,7 @@ HB_BEGIN_DECLS * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "10.4.0" +#define HB_VERSION_STRING "11.2.0" /** * HB_VERSION_ATLEAST: diff --git a/src/java.desktop/share/native/libharfbuzz/hb.hh b/src/java.desktop/share/native/libharfbuzz/hb.hh index fee1c9cd663..8c430e5770d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb.hh @@ -89,6 +89,7 @@ #pragma GCC diagnostic error "-Wstring-conversion" #pragma GCC diagnostic error "-Wswitch-enum" #pragma GCC diagnostic error "-Wtautological-overlap-compare" +#pragma GCC diagnostic error "-Wuninitialized" #pragma GCC diagnostic error "-Wunneeded-internal-declaration" #pragma GCC diagnostic error "-Wunused" #pragma GCC diagnostic error "-Wunused-local-typedefs" @@ -230,33 +231,6 @@ #define HB_PASTE(a,b) HB_PASTE1(a,b) -/* Compile-time custom allocator support. */ - -#if !defined(HB_CUSTOM_MALLOC) \ - && defined(hb_malloc_impl) \ - && defined(hb_calloc_impl) \ - && defined(hb_realloc_impl) \ - && defined(hb_free_impl) -#define HB_CUSTOM_MALLOC -#endif - -#ifdef HB_CUSTOM_MALLOC -extern "C" void* hb_malloc_impl(size_t size); -extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); -extern "C" void* hb_realloc_impl(void *ptr, size_t size); -extern "C" void hb_free_impl(void *ptr); -#define hb_malloc hb_malloc_impl -#define hb_calloc hb_calloc_impl -#define hb_realloc hb_realloc_impl -#define hb_free hb_free_impl -#else -#define hb_malloc malloc -#define hb_calloc calloc -#define hb_realloc realloc -#define hb_free free -#endif - - /* * Compiler attributes */ @@ -282,7 +256,7 @@ extern "C" void hb_free_impl(void *ptr); #define __attribute__(x) #endif -#if defined(__MINGW32__) && (__GNUC__ >= 3) +#if defined(__MINGW32__) && (__GNUC__ >= 3) && !defined(__clang__) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (gnu_printf, format_idx, arg_idx))) #elif defined(__GNUC__) && (__GNUC__ >= 3) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) @@ -491,7 +465,7 @@ static int HB_UNUSED _hb_errno = 0; # define hb_atexit atexit # else template struct hb_atexit_t { ~hb_atexit_t () { function (); } }; -# define hb_atexit(f) static hb_atexit_t _hb_atexit_##__LINE__; +# define hb_atexit(f) static hb_atexit_t _hb_atexit_##__LINE__ # endif #endif #endif @@ -539,6 +513,29 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #define HB_PI 3.14159265358979f #define HB_2_PI (2.f * HB_PI) +/* Compile-time custom allocator support. */ + +#if !defined(HB_CUSTOM_MALLOC) \ + && defined(hb_malloc_impl) \ + && defined(hb_calloc_impl) \ + && defined(hb_realloc_impl) \ + && defined(hb_free_impl) +#define HB_CUSTOM_MALLOC +#endif + +#ifdef HB_CUSTOM_MALLOC +extern "C" void* hb_malloc_impl(size_t size); +extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); +extern "C" void* hb_realloc_impl(void *ptr, size_t size); +extern "C" void hb_free_impl(void *ptr); +#else +#define hb_malloc_impl malloc +#define hb_calloc_impl calloc +#define hb_realloc_impl realloc +#define hb_free_impl free +#endif + + /* Headers we include for everyone. Keep topologically sorted by dependency. * They express dependency amongst themselves, but no other file should include