From 37f506c33dbcde7108fa59e65ee72e72694d57ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:41:20 +0300 Subject: [PATCH] harfbuzz: Update to 11.3.2 --- thirdparty/README.md | 4 +- thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh | 57 +- .../src/OT/Layout/GPOS/AnchorFormat3.hh | 17 +- .../src/OT/Layout/GPOS/ValueFormat.hh | 6 +- .../src/OT/Layout/GSUB/LigatureSet.hh | 4 +- .../harfbuzz/src/OT/Layout/GSUB/Sequence.hh | 2 +- thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc | 56 +- thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh | 18 +- thirdparty/harfbuzz/src/OT/glyf/Glyph.hh | 38 +- thirdparty/harfbuzz/src/OT/glyf/glyf.hh | 148 +- .../harfbuzz/src/graph/classdef-graph.hh | 2 +- .../harfbuzz/src/graph/coverage-graph.hh | 24 +- thirdparty/harfbuzz/src/graph/graph.hh | 83 +- .../harfbuzz/src/graph/gsubgpos-graph.hh | 74 +- .../harfbuzz/src/graph/ligature-graph.hh | 480 +++++ .../harfbuzz/src/graph/pairpos-graph.hh | 2 +- thirdparty/harfbuzz/src/graph/serialize.hh | 16 +- thirdparty/harfbuzz/src/hb-algs.hh | 247 ++- thirdparty/harfbuzz/src/hb-cache.hh | 7 +- thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh | 2 +- thirdparty/harfbuzz/src/hb-common.cc | 7 +- thirdparty/harfbuzz/src/hb-coretext-shape.cc | 11 +- thirdparty/harfbuzz/src/hb-coretext.cc | 3 +- thirdparty/harfbuzz/src/hb-deprecated.h | 8 +- thirdparty/harfbuzz/src/hb-directwrite.cc | 55 + thirdparty/harfbuzz/src/hb-draw.cc | 22 +- thirdparty/harfbuzz/src/hb-face-builder.cc | 3 +- thirdparty/harfbuzz/src/hb-face.cc | 2 +- thirdparty/harfbuzz/src/hb-font.cc | 248 ++- thirdparty/harfbuzz/src/hb-font.h | 129 +- thirdparty/harfbuzz/src/hb-font.hh | 357 +++- thirdparty/harfbuzz/src/hb-ft-colr.hh | 30 +- thirdparty/harfbuzz/src/hb-ft.cc | 30 +- thirdparty/harfbuzz/src/hb-geometry.hh | 249 ++- thirdparty/harfbuzz/src/hb-glib.cc | 8 - thirdparty/harfbuzz/src/hb-gobject-structs.cc | 6 - thirdparty/harfbuzz/src/hb-machinery.hh | 17 +- thirdparty/harfbuzz/src/hb-open-type.hh | 102 +- thirdparty/harfbuzz/src/hb-ot-cff2-table.cc | 6 +- thirdparty/harfbuzz/src/hb-ot-cmap-table.hh | 6 +- thirdparty/harfbuzz/src/hb-ot-font.cc | 564 +++++- thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh | 79 +- .../harfbuzz/src/hb-ot-layout-common.hh | 336 ++-- .../harfbuzz/src/hb-ot-layout-gsubgpos.hh | 4 +- thirdparty/harfbuzz/src/hb-ot-layout.cc | 52 +- thirdparty/harfbuzz/src/hb-ot-shape.cc | 106 +- .../harfbuzz/src/hb-ot-shaper-arabic.cc | 2 +- thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc | 2 +- .../harfbuzz/src/hb-ot-shaper-use-table.hh | 36 +- thirdparty/harfbuzz/src/hb-ot-tag-table.hh | 4 +- .../harfbuzz/src/hb-ot-var-avar-table.hh | 141 +- thirdparty/harfbuzz/src/hb-ot-var-common.hh | 115 +- .../harfbuzz/src/hb-ot-var-fvar-table.hh | 29 +- .../harfbuzz/src/hb-ot-var-gvar-table.hh | 54 +- .../harfbuzz/src/hb-ot-var-hvar-table.hh | 31 +- thirdparty/harfbuzz/src/hb-ot-var.cc | 26 +- thirdparty/harfbuzz/src/hb-ot-vorg-table.hh | 1 + thirdparty/harfbuzz/src/hb-paint-extents.cc | 14 +- thirdparty/harfbuzz/src/hb-paint-extents.hh | 38 +- thirdparty/harfbuzz/src/hb-paint.hh | 76 +- thirdparty/harfbuzz/src/hb-repacker.hh | 11 +- thirdparty/harfbuzz/src/hb-sanitize.hh | 26 +- thirdparty/harfbuzz/src/hb-serialize.hh | 3 +- thirdparty/harfbuzz/src/hb-shaper-list.hh | 4 +- thirdparty/harfbuzz/src/hb-static.cc | 23 - thirdparty/harfbuzz/src/hb-subset-plan-var.cc | 103 +- thirdparty/harfbuzz/src/hb-subset-plan.cc | 4 +- thirdparty/harfbuzz/src/hb-ucd-table.hh | 1745 +++++++---------- .../harfbuzz/src/hb-unicode-emoji-table.hh | 20 +- thirdparty/harfbuzz/src/hb-unicode.hh | 51 + thirdparty/harfbuzz/src/hb-version.h | 6 +- thirdparty/harfbuzz/src/hb.hh | 4 + 72 files changed, 3901 insertions(+), 2395 deletions(-) create mode 100644 thirdparty/harfbuzz/src/graph/ligature-graph.hh diff --git a/thirdparty/README.md b/thirdparty/README.md index 25847cab59d..6787357619c 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -436,7 +436,7 @@ Patches: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 11.2.1 (33a3f8de60dcad7535f14f07d6710144548853ac, 2025) +- Version: 11.3.2 (4e3df1c1383481ed5717603d5dd3453a04fb16ba, 2025) - License: MIT Files extracted from upstream source: @@ -444,7 +444,7 @@ Files extracted from upstream source: - `AUTHORS`, `COPYING`, `THANKS` - From the `src` folder, recursively: - All the `.cc`, `.h`, `.hh` files - - Except `main.cc`, `harfbuzz*.cc`, `failing-alloc.c`, `test*.cc`, `hb-wasm*.*`, `wasm/*` + - Except `main.cc`, `harfbuzz*.cc`, `failing-alloc.c`, `test*.cc`, `hb-wasm*.*`, `hb-harfrust.cc`, `wasm/*`, `ms-use/*`, `rust/*` ## hidapi diff --git a/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh b/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh index 448c1e4a0bd..896b0fb1034 100644 --- a/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh +++ b/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh @@ -104,7 +104,7 @@ public: foreground (foreground_), instancer (instancer_) { - if (font->is_synthetic ()) + if (font->is_synthetic) { font = hb_font_create_sub_font (font); hb_font_set_synthetic_bold (font, 0, 0, true); @@ -1075,9 +1075,9 @@ struct PaintTranslate float ddx = dx + c->instancer (varIdxBase, 0); float ddy = dy + c->instancer (varIdxBase, 1); - bool p1 = c->funcs->push_translate (c->data, ddx, ddy); + c->funcs->push_translate (c->data, ddx, ddy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ @@ -1124,9 +1124,9 @@ struct PaintScale float sx = scaleX.to_float (c->instancer (varIdxBase, 0)); float sy = scaleY.to_float (c->instancer (varIdxBase, 1)); - bool p1 = c->funcs->push_scale (c->data, sx, sy); + c->funcs->push_scale (c->data, sx, sy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ @@ -1177,13 +1177,9 @@ struct PaintScaleAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_scale (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_scale_around_center (c->data, sx, sy, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ @@ -1228,9 +1224,9 @@ struct PaintScaleUniform TRACE_PAINT (this); float s = scale.to_float (c->instancer (varIdxBase, 0)); - bool p1 = c->funcs->push_scale (c->data, s, s); + c->funcs->push_scale (c->data, s, s); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ @@ -1278,13 +1274,9 @@ struct PaintScaleUniformAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_scale (c->data, s, s); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_scale_around_center (c->data, s, s, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ @@ -1328,9 +1320,9 @@ struct PaintRotate TRACE_PAINT (this); float a = angle.to_float (c->instancer (varIdxBase, 0)); - bool p1 = c->funcs->push_rotate (c->data, a); + c->funcs->push_rotate (c->data, a); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ @@ -1378,13 +1370,9 @@ struct PaintRotateAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_rotate (c->data, a); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_rotate_around_center (c->data, a, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ @@ -1432,9 +1420,9 @@ struct PaintSkew float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0)); float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1)); - bool p1 = c->funcs->push_skew (c->data, sx, sy); + c->funcs->push_skew (c->data, sx, sy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ @@ -1485,13 +1473,9 @@ struct PaintSkewAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_skew (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_skew_around_center (c->data, sx, sy, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ @@ -2693,7 +2677,8 @@ struct COLR { ItemVarStoreInstancer instancer (get_var_store_ptr (), get_delta_set_index_map_ptr (), - hb_array (font->coords, font->num_coords)); + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); hb_decycler_node_t node (c.glyphs_decycler); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh index b5422652c4e..c49705bea0e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh @@ -37,12 +37,12 @@ struct AnchorFormat3 *x = font->em_fscale_x (xCoordinate); *y = font->em_fscale_y (yCoordinate); - if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) + if ((font->x_ppem || font->has_nonzero_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) { hb_barrier (); *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); } - if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) + if ((font->y_ppem || font->has_nonzero_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) { hb_barrier (); *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); @@ -63,7 +63,7 @@ struct AnchorFormat3 hb_pair_t *new_varidx_delta; if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta)) return_trace (false); - + x_varidx = hb_first (*new_varidx_delta); int delta = hb_second (*new_varidx_delta); if (delta != 0) @@ -91,10 +91,13 @@ struct AnchorFormat3 } } - /* in case that all axes are pinned or no variations after instantiation, - * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ - if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX && - y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + + bool no_downgrade = (!xDeviceTable.is_null () && !(this+xDeviceTable).is_variation_device ()) || + x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX || + y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX || + (!yDeviceTable.is_null () && !(this+yDeviceTable).is_variation_device ()); + + if (!no_downgrade) return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); if (!c->serializer->embed (xDeviceTable)) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh index 9442cc1cc53..89a5493f47d 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/ValueFormat.hh @@ -56,7 +56,7 @@ struct ValueFormat : HBUINT16 * PosTable (may be NULL) */ #endif - IntType& operator = (uint16_t i) { v = i; return *this; } + NumType& operator = (uint16_t i) { v = i; return *this; } unsigned int get_len () const { return hb_popcount ((unsigned int) *this); } unsigned int get_size () const { return get_len () * Value::static_size; } @@ -111,8 +111,8 @@ struct ValueFormat : HBUINT16 if (!has_device ()) return ret; - bool use_x_device = font->x_ppem || font->num_coords; - bool use_y_device = font->y_ppem || font->num_coords; + bool use_x_device = font->x_ppem || font->has_nonzero_coords; + bool use_y_device = font->y_ppem || font->has_nonzero_coords; if (!use_x_device && !use_y_device) return ret; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh index 17ae38766ae..928c74a167c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh @@ -11,11 +11,11 @@ namespace GSUB_impl { template struct LigatureSet { - protected: + public: Array16OfOffset16To> ligature; /* Array LigatureSet tables * ordered by preference */ - public: + DEFINE_SIZE_ARRAY (2, ligature); bool sanitize (hb_sanitize_context_t *c) const diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh index a26cf8c6a65..8edb0053b52 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh @@ -115,7 +115,7 @@ struct Sequence for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) { - if (buf < p) + if (buf < p && sizeof(buf) - 1u > unsigned (p - buf)) *p++ = ','; snprintf (p, sizeof(buf) - (p - buf), "%u", i); p += strlen(p); diff --git a/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc b/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc index d121c12c296..9e4fa3c2440 100644 --- a/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc +++ b/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.cc @@ -13,7 +13,7 @@ namespace OT { struct hb_transforming_pen_context_t { - hb_transform_t transform; + hb_transform_t<> transform; hb_draw_funcs_t *dfuncs; void *data; hb_draw_state_t *st; @@ -130,9 +130,9 @@ hb_ubytes_t VarComponent::get_path_at (const hb_varc_context_t &c, hb_codepoint_t parent_gid, hb_array_t coords, - hb_transform_t total_transform, + hb_transform_t<> total_transform, hb_ubytes_t total_record, - VarRegionList::cache_t *cache) const + hb_scalar_cache_t *cache) const { const unsigned char *end = total_record.arrayZ + total_record.length; const unsigned char *record = total_record.arrayZ; @@ -216,7 +216,7 @@ VarComponent::get_path_at (const hb_varc_context_t &c, * limit on the max number of coords for now. */ if ((flags & (unsigned) flags_t::RESET_UNSPECIFIED_AXES) || coords.length > HB_VAR_COMPOSITE_MAX_AXES) - component_coords = hb_array (c.font->coords, c.font->num_coords); + component_coords = hb_array (c.font->coords, c.font->num_coords); // Transform @@ -226,28 +226,28 @@ VarComponent::get_path_at (const hb_varc_context_t &c, #define PROCESS_TRANSFORM_COMPONENTS \ HB_STMT_START { \ - PROCESS_TRANSFORM_COMPONENT (FWORD, HAVE_TRANSLATE_X, translateX); \ - PROCESS_TRANSFORM_COMPONENT (FWORD, HAVE_TRANSLATE_Y, translateY); \ - PROCESS_TRANSFORM_COMPONENT (F4DOT12, HAVE_ROTATION, rotation); \ - PROCESS_TRANSFORM_COMPONENT (F6DOT10, HAVE_SCALE_X, scaleX); \ - PROCESS_TRANSFORM_COMPONENT (F6DOT10, HAVE_SCALE_Y, scaleY); \ - PROCESS_TRANSFORM_COMPONENT (F4DOT12, HAVE_SKEW_X, skewX); \ - PROCESS_TRANSFORM_COMPONENT (F4DOT12, HAVE_SKEW_Y, skewY); \ - PROCESS_TRANSFORM_COMPONENT (FWORD, HAVE_TCENTER_X, tCenterX); \ - PROCESS_TRANSFORM_COMPONENT (FWORD, HAVE_TCENTER_Y, tCenterY); \ + PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TRANSLATE_X, translateX); \ + PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TRANSLATE_Y, translateY); \ + PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_ROTATION, rotation); \ + PROCESS_TRANSFORM_COMPONENT (F6DOT10, 1.0f, HAVE_SCALE_X, scaleX); \ + PROCESS_TRANSFORM_COMPONENT (F6DOT10, 1.0f, HAVE_SCALE_Y, scaleY); \ + PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_SKEW_X, skewX); \ + PROCESS_TRANSFORM_COMPONENT (F4DOT12, HB_PI, HAVE_SKEW_Y, skewY); \ + PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TCENTER_X, tCenterX); \ + PROCESS_TRANSFORM_COMPONENT (FWORD, 1.0f, HAVE_TCENTER_Y, tCenterY); \ } HB_STMT_END - hb_transform_decomposed_t transform; + hb_transform_decomposed_t<> transform; // Read transform components -#define PROCESS_TRANSFORM_COMPONENT(type, flag, name) \ +#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ if (flags & (unsigned) flags_t::flag) \ { \ static_assert (type::static_size == HBINT16::static_size, ""); \ if (unlikely (unsigned (end - record) < HBINT16::static_size)) \ return hb_ubytes_t (); \ hb_barrier (); \ - transform.name = * (const HBINT16 *) record; \ + transform.name = mult * * (const HBINT16 *) record; \ record += HBINT16::static_size; \ } PROCESS_TRANSFORM_COMPONENTS; @@ -279,22 +279,22 @@ VarComponent::get_path_at (const hb_varc_context_t &c, { float transformValues[9]; unsigned numTransformValues = 0; -#define PROCESS_TRANSFORM_COMPONENT(type, flag, name) \ +#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ if (flags & (unsigned) flags_t::flag) \ - transformValues[numTransformValues++] = transform.name; + transformValues[numTransformValues++] = transform.name / mult; PROCESS_TRANSFORM_COMPONENTS; #undef PROCESS_TRANSFORM_COMPONENT varStore.get_delta (transformVarIdx, coords, hb_array (transformValues, numTransformValues), cache); numTransformValues = 0; -#define PROCESS_TRANSFORM_COMPONENT(type, flag, name) \ +#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ if (flags & (unsigned) flags_t::flag) \ - transform.name = transformValues[numTransformValues++]; + transform.name = transformValues[numTransformValues++] * mult; PROCESS_TRANSFORM_COMPONENTS; #undef PROCESS_TRANSFORM_COMPONENT } // Divide them by their divisors -#define PROCESS_TRANSFORM_COMPONENT(type, flag, name) \ +#define PROCESS_TRANSFORM_COMPONENT(type, mult, flag, name) \ if (flags & (unsigned) flags_t::flag) \ { \ HBINT16 int_v; \ @@ -334,9 +334,9 @@ bool VARC::get_path_at (const hb_varc_context_t &c, hb_codepoint_t glyph, hb_array_t coords, - hb_transform_t transform, + hb_transform_t<> transform, hb_codepoint_t parent_glyph, - VarRegionList::cache_t *parent_cache) const + hb_scalar_cache_t *parent_cache) const { // Don't recurse on the same glyph. unsigned idx = glyph == parent_glyph ? @@ -372,7 +372,7 @@ VARC::get_path_at (const hb_varc_context_t &c, #endif return false; - hb_extents_t comp_extents (glyph_extents); + hb_extents_t<> comp_extents (glyph_extents); transform.transform_extents (comp_extents); c.extents->union_ (comp_extents); } @@ -392,10 +392,10 @@ VARC::get_path_at (const hb_varc_context_t &c, hb_ubytes_t record = (this+glyphRecords)[idx]; - VarRegionList::cache_t static_cache[sizeof (void *) * 16]; - VarRegionList::cache_t *cache = parent_cache ? + hb_scalar_cache_t static_cache; + hb_scalar_cache_t *cache = parent_cache ? parent_cache : - (this+varStore).create_cache (hb_array (static_cache)); + (this+varStore).create_cache (&static_cache); transform.scale (c.font->x_multf, c.font->y_multf); @@ -406,7 +406,7 @@ VARC::get_path_at (const hb_varc_context_t &c, cache); if (cache != parent_cache) - (this+varStore).destroy_cache (cache, hb_array (static_cache)); + (this+varStore).destroy_cache (cache, &static_cache); return true; } diff --git a/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh b/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh index 0ce2ee5f10a..a372701cde9 100644 --- a/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh +++ b/thirdparty/harfbuzz/src/OT/Var/VARC/VARC.hh @@ -32,7 +32,7 @@ struct hb_varc_context_t { hb_font_t *font; hb_draw_session_t *draw_session; - hb_extents_t *extents; + hb_extents_t<> *extents; mutable hb_decycler_t decycler; mutable signed edges_left; mutable signed depth_left; @@ -65,9 +65,9 @@ struct VarComponent get_path_at (const hb_varc_context_t &c, hb_codepoint_t parent_gid, hb_array_t coords, - hb_transform_t transform, + hb_transform_t<> transform, hb_ubytes_t record, - VarRegionList::cache_t *cache = nullptr) const; + hb_scalar_cache_t *cache = nullptr) const; }; struct VarCompositeGlyph @@ -76,9 +76,9 @@ struct VarCompositeGlyph get_path_at (const hb_varc_context_t &c, hb_codepoint_t gid, hb_array_t coords, - hb_transform_t transform, + hb_transform_t<> transform, hb_ubytes_t record, - VarRegionList::cache_t *cache) + hb_scalar_cache_t *cache) { while (record) { @@ -104,9 +104,9 @@ struct VARC get_path_at (const hb_varc_context_t &c, hb_codepoint_t gid, hb_array_t coords, - hb_transform_t transform = HB_TRANSFORM_IDENTITY, + hb_transform_t<> transform = HB_TRANSFORM_IDENTITY, hb_codepoint_t parent_gid = HB_CODEPOINT_INVALID, - VarRegionList::cache_t *parent_cache = nullptr) const; + hb_scalar_cache_t *parent_cache = nullptr) const; bool get_path (hb_font_t *font, @@ -129,7 +129,7 @@ struct VARC bool get_extents (hb_font_t *font, hb_codepoint_t gid, - hb_extents_t *extents, + hb_extents_t<> *extents, hb_varc_scratch_t &scratch) const { hb_varc_context_t c {font, @@ -196,7 +196,7 @@ struct VARC { if (!table->has_data ()) return false; - hb_extents_t f_extents; + hb_extents_t<> f_extents; auto *scratch = acquire_scratch (); if (unlikely (!scratch)) return true; diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh index 2c289d5110b..f8a396bf9bd 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh @@ -102,17 +102,15 @@ struct Glyph if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { + // Duplicated code. int lsb = 0; - int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? - (int) header->xMin - lsb : 0; + face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + int h_delta = (int) header->xMin - lsb; HB_UNUSED int tsb = 0; - int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL - ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) -#else - 0 + face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb); #endif - ; + int v_orig = (int) header->yMax + tsb; unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL @@ -314,6 +312,7 @@ struct Glyph bool use_my_metrics = true, bool phantom_only = false, hb_array_t coords = hb_array_t (), + hb_scalar_cache_t *gvar_cache = nullptr, unsigned int depth = 0, unsigned *edge_count = nullptr) const { @@ -328,7 +327,7 @@ struct Glyph head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); } - if (!coords) + if (!coords && font->has_nonzero_coords) coords = hb_array (font->coords, font->num_coords); contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points; @@ -357,25 +356,23 @@ struct Glyph if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { + // Duplicated code. int lsb = 0; - int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? - (int) header->xMin - lsb : 0; + glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + int h_delta = (int) header->xMin - lsb; HB_UNUSED int tsb = 0; - int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL - ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) -#else - 0 + glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb); #endif - ; + int v_orig = (int) header->yMax + tsb; unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid) + glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid) #else - - font->face->get_upem () + - font->face->get_upem () #endif - ; + ; phantoms[PHANTOM_LEFT].x = h_delta; phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta; phantoms[PHANTOM_TOP].y = v_orig; @@ -383,7 +380,7 @@ struct Glyph } #ifndef HB_NO_VAR - if (coords) + if (hb_any (coords)) { #ifndef HB_NO_BEYOND_64K if (glyf_accelerator.GVAR->has_data ()) @@ -391,6 +388,7 @@ struct Glyph coords, points.as_array ().sub_array (old_length), scratch, + gvar_cache, phantom_only && type == SIMPLE); else #endif @@ -398,6 +396,7 @@ struct Glyph coords, points.as_array ().sub_array (old_length), scratch, + gvar_cache, phantom_only && type == SIMPLE); } #endif @@ -447,6 +446,7 @@ struct Glyph use_my_metrics, phantom_only, coords, + gvar_cache, depth + 1, edge_count))) { diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh index 16bd26eae2b..b821dd32258 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh @@ -220,7 +220,8 @@ struct glyf_accelerator_t template bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer, hb_array_t coords, - hb_glyf_scratch_t &scratch) const + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { if (gid >= num_glyphs) return false; @@ -228,7 +229,7 @@ struct glyf_accelerator_t all_points.resize (0); bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords))) + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords, gvar_cache))) return false; unsigned count = all_points.length; @@ -371,28 +372,28 @@ struct glyf_accelerator_t contour_point_t *get_phantoms_sink () { return phantoms; } }; +#ifndef HB_NO_VAR unsigned - get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + get_advance_with_var_unscaled (hb_codepoint_t gid, + hb_font_t *font, + bool is_vertical, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { if (unlikely (gid >= num_glyphs)) return 0; bool success = false; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (font->num_coords) - { - hb_glyf_scratch_t scratch; - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), - hb_array (font->coords, font->num_coords), - scratch); - } - + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + scratch, gvar_cache); if (unlikely (!success)) - return -#ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_advance_without_var_unscaled (gid) : -#endif - hmtx->get_advance_without_var_unscaled (gid); + { + unsigned upem = font->face->get_upem (); + return is_vertical ? upem : upem / 2; + } float result = is_vertical ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y @@ -400,40 +401,38 @@ struct glyf_accelerator_t return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); } - bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const + float + get_v_origin_with_var_unscaled (hb_codepoint_t gid, + hb_font_t *font, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { - if (unlikely (gid >= num_glyphs)) return false; + if (unlikely (gid >= num_glyphs)) return 0; + + bool success = false; - hb_glyph_extents_t extents; - hb_glyf_scratch_t scratch; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false), - hb_array (font->coords, font->num_coords), - scratch))) - return false; + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + scratch, gvar_cache); + if (unlikely (!success)) + { + return font->face->get_upem (); + } - *lsb = is_vertical - ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing - : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x); - return true; + return phantoms[glyf_impl::PHANTOM_TOP].y; } #endif - - bool get_leading_bearing_without_var_unscaled (hb_codepoint_t gid, bool is_vertical, int *lsb) const - { - if (unlikely (gid >= num_glyphs)) return false; - if (is_vertical) return false; // TODO Humm, what to do here? - - *lsb = glyph_for_gid (gid).get_header ()->xMin; - return true; - } +#endif public: 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)); } + { return get_extents_at (font, gid, extents, hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); } bool get_extents_at (hb_font_t *font, hb_codepoint_t gid, @@ -445,12 +444,16 @@ struct glyf_accelerator_t #ifndef HB_NO_VAR if (coords) { - hb_glyf_scratch_t scratch; - return get_points (font, - gid, - points_aggregator_t (font, extents, nullptr, true), - coords, - scratch); + hb_glyf_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) + return false; + bool ret = get_points (font, + gid, + points_aggregator_t (font, extents, nullptr, true), + coords, + *scratch); + release_scratch (scratch); + return ret; } #endif return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); @@ -485,33 +488,21 @@ struct glyf_accelerator_t } bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, hb_scalar_cache_t *gvar_cache = nullptr) const { if (!has_data ()) return false; - hb_glyf_scratch_t *scratch; - - // Borrow the cached strach buffer. - { - 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; - } - } + hb_glyf_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) + return true; bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), - hb_array (font->coords, font->num_coords), - *scratch); + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + *scratch, + gvar_cache); - // Put it back. - if (!cached_scratch.cmpexch (nullptr, scratch)) - { - scratch->~hb_glyf_scratch_t (); - hb_free (scratch); - } + release_scratch (scratch); return ret; } @@ -519,12 +510,35 @@ struct glyf_accelerator_t bool get_path_at (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, hb_array_t coords, - hb_glyf_scratch_t &scratch) const + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { if (!has_data ()) return false; return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), coords, - scratch); + scratch, + gvar_cache); + } + + + hb_glyf_scratch_t *acquire_scratch () const + { + hb_glyf_scratch_t *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 nullptr; + } + return scratch; + } + void release_scratch (hb_glyf_scratch_t *scratch) const + { + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } } #ifndef HB_NO_VAR diff --git a/thirdparty/harfbuzz/src/graph/classdef-graph.hh b/thirdparty/harfbuzz/src/graph/classdef-graph.hh index da6378820bb..d6c174e8751 100644 --- a/thirdparty/harfbuzz/src/graph/classdef-graph.hh +++ b/thirdparty/harfbuzz/src/graph/classdef-graph.hh @@ -74,7 +74,7 @@ struct ClassDef : public OT::ClassDef class_def_link->width = SmallTypes::size; class_def_link->objidx = class_def_prime_id; class_def_link->position = link_position; - class_def_prime_vertex.add_parent (parent_id); + class_def_prime_vertex.add_parent (parent_id, false); return true; } diff --git a/thirdparty/harfbuzz/src/graph/coverage-graph.hh b/thirdparty/harfbuzz/src/graph/coverage-graph.hh index 61ca063e345..2314020bf7b 100644 --- a/thirdparty/harfbuzz/src/graph/coverage-graph.hh +++ b/thirdparty/harfbuzz/src/graph/coverage-graph.hh @@ -98,11 +98,33 @@ struct Coverage : public OT::Layout::Common::Coverage coverage_link->width = SmallTypes::size; coverage_link->objidx = coverage_prime_id; coverage_link->position = link_position; - coverage_prime_vertex.add_parent (parent_id); + coverage_prime_vertex.add_parent (parent_id, false); return (Coverage*) coverage_prime_vertex.obj.head; } + // Filter an existing coverage table to glyphs at indices [start, end) and replace it with the filtered version. + static bool filter_coverage (gsubgpos_graph_context_t& c, + unsigned existing_coverage, + unsigned start, unsigned end) { + unsigned coverage_size = c.graph.vertices_[existing_coverage].table_size (); + auto& coverage_v = c.graph.vertices_[existing_coverage]; + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + if (!coverage_table || !coverage_table->sanitize (coverage_v)) + return false; + + auto new_coverage = + + hb_zip (coverage_table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t p) { + return p.second >= start && p.second < end; + }) + | hb_map_retains_sorting (hb_first) + ; + + return make_coverage (c, new_coverage, existing_coverage, coverage_size * 2 + 100); + } + + // Replace the coverage table at dest obj with one covering 'glyphs'. template static bool make_coverage (gsubgpos_graph_context_t& c, It glyphs, diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh index b24507ece17..332f27169df 100644 --- a/thirdparty/harfbuzz/src/graph/graph.hh +++ b/thirdparty/harfbuzz/src/graph/graph.hh @@ -50,6 +50,7 @@ struct graph_t private: unsigned incoming_edges_ = 0; unsigned single_parent = (unsigned) -1; + bool has_incoming_virtual_edges_ = false; hb_hashmap_t parents; public: @@ -66,6 +67,11 @@ struct graph_t return parents.in_error (); } + bool has_incoming_virtual_edges () const + { + return has_incoming_virtual_edges_; + } + bool link_positions_valid (unsigned num_objects, bool removed_nil) { hb_set_t assigned_bytes; @@ -121,7 +127,9 @@ struct graph_t } } - bool equals (const vertex_t& other, + bool equals (unsigned this_index, + unsigned other_index, + const vertex_t& other, const graph_t& graph, const graph_t& other_graph, unsigned depth) const @@ -129,8 +137,10 @@ struct graph_t if (!(as_bytes () == other.as_bytes ())) { DEBUG_MSG (SUBSET_REPACK, nullptr, - "vertex [%lu] bytes != [%lu] bytes, depth = %u", + "vertex %u [%lu bytes] != %u [%lu bytes], depth = %u", + this_index, (unsigned long) table_size (), + other_index, (unsigned long) other.table_size (), depth); @@ -162,6 +172,7 @@ struct graph_t hb_swap (a.single_parent, b.single_parent); hb_swap (a.parents, b.parents); hb_swap (a.incoming_edges_, b.incoming_edges_); + hb_swap (a.has_incoming_virtual_edges_, b.has_incoming_virtual_edges_); hb_swap (a.start, b.start); hb_swap (a.end, b.end); hb_swap (a.priority, b.priority); @@ -207,13 +218,16 @@ struct graph_t void reset_parents () { incoming_edges_ = 0; + has_incoming_virtual_edges_ = false; single_parent = (unsigned) -1; parents.reset (); } - void add_parent (unsigned parent_index) + void add_parent (unsigned parent_index, bool is_virtual) { assert (parent_index != (unsigned) -1); + has_incoming_virtual_edges_ |= is_virtual; + if (incoming_edges_ == 0) { single_parent = parent_index; @@ -408,7 +422,7 @@ struct graph_t link_a.bias != link_b.bias) return false; - if (!graph.vertices_[link_a.objidx].equals ( + if (!graph.vertices_[link_a.objidx].equals (link_a.objidx, link_b.objidx, other_graph.vertices_[link_b.objidx], graph, other_graph, depth + 1)) return false; @@ -490,7 +504,7 @@ struct graph_t bool operator== (const graph_t& other) const { - return root ().equals (other.root (), *this, other, 0); + return root ().equals (root_idx(), other.root_idx(), other.root (), *this, other, 0); } void print () const { @@ -501,6 +515,9 @@ struct graph_t for (const auto &l : v.obj.real_links) { printf("%u, ", l.objidx); } + for (const auto &l : v.obj.virtual_links) { + printf("v%u, ", l.objidx); + } printf("]\n"); } } @@ -556,7 +573,7 @@ struct graph_t link->width = 2; link->objidx = child_id; link->position = (char*) offset - (char*) v.obj.head; - vertices_[child_id].add_parent (parent_id); + vertices_[child_id].add_parent (parent_id, false); } /* @@ -943,9 +960,11 @@ struct graph_t /* * Moves the child of old_parent_idx pointed to by old_offset to a new * vertex at the new_offset. + * + * Returns the id of the child node that was moved. */ template - void move_child (unsigned old_parent_idx, + unsigned move_child (unsigned old_parent_idx, const O* old_offset, unsigned new_parent_idx, const O* new_offset) @@ -965,10 +984,12 @@ struct graph_t new_link->position = (const char*) new_offset - (const char*) new_v.obj.head; auto& child = vertices_[child_id]; - child.add_parent (new_parent_idx); + child.add_parent (new_parent_idx, false); old_v.remove_real_link (child_id, old_offset); child.remove_parent (old_parent_idx); + + return child_id; } /* @@ -1015,12 +1036,12 @@ struct graph_t for (const auto& l : child.obj.real_links) { clone->obj.real_links.push (l); - vertices_[l.objidx].add_parent (clone_idx); + vertices_[l.objidx].add_parent (clone_idx, false); } for (const auto& l : child.obj.virtual_links) { clone->obj.virtual_links.push (l); - vertices_[l.objidx].add_parent (clone_idx); + vertices_[l.objidx].add_parent (clone_idx, true); } check_success (!clone->obj.real_links.in_error ()); @@ -1073,10 +1094,15 @@ struct graph_t const auto& child = vertices_[child_idx]; unsigned links_to_child = child.incoming_edges_from_parent(parent_idx); - if (child.incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child || child.has_incoming_virtual_edges()) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. + // + // We don't allow duplication of nodes with incoming virtual edges because we don't track + // the number of virtual vs real incoming edges. As a result we can't tell if a node + // with virtual edges may end up orphaned by duplication (ie. where one copy is only pointed + // to by virtual edges). DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u => %u", parent_idx, child_idx); return -1; @@ -1091,12 +1117,15 @@ struct graph_t if (parent_idx == clone_idx) parent_idx++; auto& parent = vertices_[parent_idx]; + unsigned count = 0; + unsigned num_real = parent.obj.real_links.length; for (auto& l : parent.obj.all_links_writer ()) { + count++; if (l.objidx != child_idx) continue; - reassign_link (l, parent_idx, clone_idx); + reassign_link (l, parent_idx, clone_idx, count > num_real); } return clone_idx; @@ -1129,10 +1158,15 @@ struct graph_t links_to_child += child.incoming_edges_from_parent(parent_idx); } - if (child.incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child || child.has_incoming_virtual_edges()) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. + // + // We don't allow duplication of nodes with incoming virtual edges because we don't track + // the number of virtual vs real incoming edges. As a result we can't tell if a node + // with virtual edges may end up orphaned by duplication (ie. where one copy is only pointed + // to by virtual edges). DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); return -1; } @@ -1146,12 +1180,15 @@ struct graph_t // duplicate shifts the root node idx, so if parent_idx was root update it. if (parent_idx == clone_idx) parent_idx++; auto& parent = vertices_[parent_idx]; + unsigned count = 0; + unsigned num_real = parent.obj.real_links.length; for (auto& l : parent.obj.all_links_writer ()) { + count++; if (l.objidx != child_idx) continue; - reassign_link (l, parent_idx, clone_idx); + reassign_link (l, parent_idx, clone_idx, count > num_real); } } @@ -1279,6 +1316,7 @@ struct graph_t if (!DEBUG_ENABLED(SUBSET_REPACK)) return; DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); + parents_invalid = true; update_parents(); @@ -1398,8 +1436,11 @@ struct graph_t for (unsigned p = 0; p < count; p++) { - for (auto& l : vertices_.arrayZ[p].obj.all_links ()) - vertices_[l.objidx].add_parent (p); + for (auto& l : vertices_.arrayZ[p].obj.real_links) + vertices_[l.objidx].add_parent (p, false); + + for (auto& l : vertices_.arrayZ[p].obj.virtual_links) + vertices_[l.objidx].add_parent (p, true); } for (unsigned i = 0; i < count; i++) @@ -1502,12 +1543,13 @@ struct graph_t */ void reassign_link (hb_serialize_context_t::object_t::link_t& link, unsigned parent_idx, - unsigned new_idx) + unsigned new_idx, + bool is_virtual) { unsigned old_idx = link.objidx; link.objidx = new_idx; vertices_[old_idx].remove_parent (parent_idx); - vertices_[new_idx].add_parent (parent_idx); + vertices_[new_idx].add_parent (parent_idx, is_virtual); } /* @@ -1521,13 +1563,16 @@ struct graph_t if (!id_map) return; for (unsigned i : subgraph) { + unsigned num_real = vertices_[i].obj.real_links.length; + unsigned count = 0; for (auto& link : vertices_[i].obj.all_links_writer ()) { + count++; const uint32_t *v; if (!id_map.has (link.objidx, &v)) continue; if (only_wide && !(link.width == 4 && !link.is_signed)) continue; - reassign_link (link, i, *v); + reassign_link (link, i, *v, count > num_real); } } } diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh index 0f6d5662e03..77ba4ee18c1 100644 --- a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh @@ -27,9 +27,11 @@ #include "graph.hh" #include "../hb-ot-layout-gsubgpos.hh" #include "../OT/Layout/GSUB/ExtensionSubst.hh" +#include "../OT/Layout/GSUB/SubstLookupSubTable.hh" #include "gsubgpos-context.hh" #include "pairpos-graph.hh" #include "markbasepos-graph.hh" +#include "ligature-graph.hh" #ifndef GRAPH_GSUBGPOS_GRAPH_HH #define GRAPH_GSUBGPOS_GRAPH_HH @@ -120,12 +122,10 @@ struct Lookup : public OT::Lookup unsigned type = lookupType; bool is_ext = is_extension (c.table_tag); - if (c.table_tag != HB_OT_TAG_GPOS) + if (c.table_tag != HB_OT_TAG_GPOS && c.table_tag != HB_OT_TAG_GSUB) return true; - if (!is_ext && - type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair && - type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) + if (!is_ext && !is_supported_gpos_type(type, c) && !is_supported_gsub_type(type, c)) return true; hb_vector_t>> all_new_subtables; @@ -144,21 +144,32 @@ struct Lookup : public OT::Lookup subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index); type = extension->get_lookup_type (); - if (type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair - && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) + if (!is_supported_gpos_type(type, c) && !is_supported_gsub_type(type, c)) continue; } hb_vector_t new_sub_tables; - switch (type) - { - case 2: - new_sub_tables = split_subtable (c, parent_index, subtable_index); break; - case 4: - new_sub_tables = split_subtable (c, parent_index, subtable_index); break; - default: - break; + + if (c.table_tag == HB_OT_TAG_GPOS) { + switch (type) + { + case 2: + new_sub_tables = split_subtable (c, parent_index, subtable_index); break; + case 4: + new_sub_tables = split_subtable (c, parent_index, subtable_index); break; + default: + break; + } + } else if (c.table_tag == HB_OT_TAG_GSUB) { + switch (type) + { + case 4: + new_sub_tables = split_subtable (c, parent_index, subtable_index); break; + default: + break; + } } + if (new_sub_tables.in_error ()) return false; if (!new_sub_tables) continue; hb_pair_t>* entry = all_new_subtables.push (); @@ -191,14 +202,14 @@ struct Lookup : public OT::Lookup hb_vector_t>>& subtable_ids) { bool is_ext = is_extension (c.table_tag); - auto& v = c.graph.vertices_[this_index]; + auto* v = &c.graph.vertices_[this_index]; fix_existing_subtable_links (c, this_index, subtable_ids); unsigned new_subtable_count = 0; for (const auto& p : subtable_ids) new_subtable_count += p.second.length; - size_t new_size = v.table_size () + size_t new_size = v->table_size () + new_subtable_count * OT::Offset16::static_size; char* buffer = (char*) hb_calloc (1, new_size); if (!buffer) return false; @@ -207,10 +218,10 @@ struct Lookup : public OT::Lookup hb_free (buffer); return false; } - hb_memcpy (buffer, v.obj.head, v.table_size()); + hb_memcpy (buffer, v->obj.head, v->table_size()); - v.obj.head = buffer; - v.obj.tail = buffer + new_size; + v->obj.head = buffer; + v->obj.tail = buffer + new_size; Lookup* new_lookup = (Lookup*) buffer; @@ -226,21 +237,23 @@ struct Lookup : public OT::Lookup if (is_ext) { unsigned ext_id = create_extension_subtable (c, subtable_id, type); - c.graph.vertices_[subtable_id].add_parent (ext_id); + c.graph.vertices_[subtable_id].add_parent (ext_id, false); subtable_id = ext_id; + // the reference to v may have changed on adding a node, so reassign it. + v = &c.graph.vertices_[this_index]; } - auto* link = v.obj.real_links.push (); + auto* link = v->obj.real_links.push (); link->width = 2; link->objidx = subtable_id; link->position = (char*) &new_lookup->subTable[offset_index++] - (char*) new_lookup; - c.graph.vertices_[subtable_id].add_parent (this_index); + c.graph.vertices_[subtable_id].add_parent (this_index, false); } } // Repacker sort order depends on link order, which we've messed up so resort it. - v.obj.real_links.qsort (); + v->obj.real_links.qsort (); // The head location of the lookup has changed, invalidating the lookups map entry // in the context. Update the map. @@ -326,7 +339,7 @@ struct Lookup : public OT::Lookup // Make extension point at the subtable. auto& ext_vertex = c.graph.vertices_[ext_index]; - ext_vertex.add_parent (lookup_index); + ext_vertex.add_parent (lookup_index, false); if (!existing_ext_index) subtable_vertex.remap_parent (lookup_index, ext_index); @@ -334,6 +347,19 @@ struct Lookup : public OT::Lookup } private: + bool is_supported_gsub_type(unsigned type, gsubgpos_graph_context_t& c) const { + return (c.table_tag == HB_OT_TAG_GSUB) && ( + type == OT::Layout::GSUB_impl::SubstLookupSubTable::Type::Ligature + ); + } + + bool is_supported_gpos_type(unsigned type, gsubgpos_graph_context_t& c) const { + return (c.table_tag == HB_OT_TAG_GPOS) && ( + type == OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair || + type == OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase + ); + } + unsigned extension_type (hb_tag_t table_tag) const { switch (table_tag) diff --git a/thirdparty/harfbuzz/src/graph/ligature-graph.hh b/thirdparty/harfbuzz/src/graph/ligature-graph.hh new file mode 100644 index 00000000000..611ab686e9b --- /dev/null +++ b/thirdparty/harfbuzz/src/graph/ligature-graph.hh @@ -0,0 +1,480 @@ +/* + * Copyright © 2025 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. + * + * Google Author(s): Garret Rieger + */ + +#ifndef GRAPH_LIGATURE_GRAPH_HH +#define GRAPH_LIGATURE_GRAPH_HH + +#include "graph.hh" +#include "../OT/Layout/GSUB/LigatureSubst.hh" +#include "../OT/Layout/GSUB/LigatureSubstFormat1.hh" +#include "../OT/Layout/GSUB/LigatureSet.hh" +#include "../OT/Layout/types.hh" +#include +#include + +namespace graph { + +struct LigatureSet : public OT::Layout::GSUB_impl::LigatureSet +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::Layout::GSUB_impl::LigatureSet::min_size) return false; + hb_barrier (); + + int64_t total_len = ligature.get_size() + OT::Layout::GSUB_impl::LigatureSet::min_size - ligature.len.get_size(); + if (vertex_len < total_len) { + return false; + } + return true; + } +}; + +struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1_2 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + unsigned min_size = OT::Layout::GSUB_impl::LigatureSubstFormat1_2::min_size; + if (vertex_len < min_size) return false; + hb_barrier (); + + return vertex_len >= + min_size + ligatureSet.get_size() - ligatureSet.len.get_size(); + } + + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned parent_index, + unsigned this_index) + { + auto split_points = compute_split_points(c, parent_index, this_index); + split_context_t split_context { + c, + this, + c.graph.duplicate_if_shared (parent_index, this_index), + total_number_ligas(c, this_index), + liga_counts(c, this_index), + }; + return actuate_subtable_split (split_context, split_points); + } + + private: + unsigned total_number_ligas(gsubgpos_graph_context_t& c, unsigned this_index) const { + unsigned total = 0; + for (unsigned i = 0; i < ligatureSet.len; i++) + { + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + if (!liga_set.table) { + return 0; + } + total += liga_set.table->ligature.len; + } + return total; + } + + hb_vector_t liga_counts(gsubgpos_graph_context_t& c, unsigned this_index) const { + hb_vector_t result; + for (unsigned i = 0; i < ligatureSet.len; i++) + { + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + result.push(!liga_set.table ? 0 : liga_set.table->ligature.len); + } + return result; + } + + hb_vector_t compute_split_points(gsubgpos_graph_context_t& c, + unsigned parent_index, + unsigned this_index) const + { + // For ligature subst coverage is always packed last, and as a result is where an overflow + // will happen if there is one, so we can check the estimate length of the + // LigatureSubstFormat1 -> Coverage offset length which is the sum of all data in the + // retained sub graph except for the coverage table itself. + const unsigned base_size = OT::Layout::GSUB_impl::LigatureSubstFormat1_2::min_size; + unsigned accumulated = base_size; + + unsigned ligature_index = 0; + hb_vector_t split_points; + for (unsigned i = 0; i < ligatureSet.len; i++) + { + accumulated += OT::HBUINT16::static_size; // for ligature set offset + accumulated += OT::Layout::GSUB_impl::LigatureSet::min_size; // for ligature set table + + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + if (!liga_set.table) { + return hb_vector_t {}; + } + + for (unsigned j = 0; j < liga_set.table->ligature.len; j++) + { + const unsigned liga_id = c.graph.index_for_offset (liga_set.index, &liga_set.table->ligature[j]); + const unsigned liga_size = c.graph.vertices_[liga_id].table_size (); + + accumulated += OT::HBUINT16::static_size; // for ligature offset + accumulated += liga_size; // for the ligature table + + if (accumulated >= (1 << 16)) + { + split_points.push(ligature_index); + // We're going to split such that the current ligature will be in the new sub table. + // That means we'll have one ligature subst (base_base), one ligature set, and one liga table + accumulated = base_size + // for liga subst subtable + (OT::HBUINT16::static_size * 2) + // for liga set and liga offset + OT::Layout::GSUB_impl::LigatureSet::min_size + // for liga set subtable + liga_size; // for liga sub table + } + + ligature_index++; + } + } + + return split_points; + } + + + struct split_context_t + { + gsubgpos_graph_context_t& c; + LigatureSubstFormat1* thiz; + unsigned this_index; + unsigned original_count_; + hb_vector_t liga_counts; + + unsigned original_count () + { + return original_count_; + } + + unsigned clone_range (unsigned start, unsigned end) + { + return thiz->clone_range (c, this_index, liga_counts, start, end); + } + + bool shrink (unsigned count) + { + return thiz->shrink (c, this_index, original_count(), liga_counts, count); + } + }; + + hb_pair_t new_liga_set(gsubgpos_graph_context_t& c, unsigned count) const { + unsigned prime_size = OT::Layout::GSUB_impl::LigatureSet::min_size + + count * SmallTypes::size; + + unsigned prime_id = c.create_node (prime_size); + if (prime_id == (unsigned) -1) return hb_pair(-1, nullptr); + + LigatureSet* prime = (LigatureSet*) c.graph.object (prime_id).head; + prime->ligature.len = count; + return hb_pair(prime_id, prime); + } + + void clear_virtual_links (gsubgpos_graph_context_t& c, unsigned node_index) const + { + auto& obj = c.graph.vertices_[node_index].obj; + for (const auto& l : obj.virtual_links) + { + auto& child = c.graph.vertices_[l.objidx]; + child.remove_parent(node_index); + } + obj.virtual_links.clear(); + } + + void add_virtual_link(gsubgpos_graph_context_t& c, unsigned from, unsigned to) const { + auto& from_obj = c.graph.vertices_[from].obj; + c.graph.vertices_[to].add_parent(from, true); + auto& link = *from_obj.virtual_links.push (); + link.objidx = to; + } + + hb_pair_t current_liga_set_bounds (gsubgpos_graph_context_t& c, + unsigned liga_set_index, + const hb_serialize_context_t::object_t& liga_set) const + { + // Finds the actual liga indices present in the liga set currently. Takes + // into account those that have been removed by processing. + unsigned min_index = (unsigned) -1; + unsigned max_index = 0; + for (const auto& l : liga_set.real_links) { + if (l.position < 2) continue; + + unsigned liga_index = (l.position - 2) / 2; + min_index = hb_min(min_index, liga_index); + max_index = hb_max(max_index, liga_index); + } + return hb_pair(min_index, max_index + 1); + } + + void compact_liga_set (gsubgpos_graph_context_t& c, LigatureSet* table, hb_serialize_context_t::object_t& obj) const + { + if (table->ligature.len <= obj.real_links.length) return; + + // compact the remaining linked liga offsets into a continous array and shrink the node as needed. + unsigned to_remove = table->ligature.len - obj.real_links.length; + unsigned new_position = SmallTypes::size; + obj.real_links.qsort(); // for this to work we need to process links in order of position. + for (auto& l : obj.real_links) + { + l.position = new_position; + new_position += SmallTypes::size; + } + + table->ligature.len = obj.real_links.length; + obj.tail -= to_remove * SmallTypes::size; + } + + unsigned clone_range (gsubgpos_graph_context_t& c, + unsigned this_index, + hb_vector_t liga_counts, + unsigned start, unsigned end) const + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Cloning LigatureSubstFormat1 (%u) range [%u, %u).", this_index, start, end); + + // Create an oversized new liga subst, we'll adjust the size down later. We don't know + // the final size until we process it but we also need it to exist while we're processing + // so that nodes can be moved to it as needed. + unsigned prime_size = OT::Layout::GSUB_impl::LigatureSubstFormat1_2::min_size + + ligatureSet.get_size() - ligatureSet.len.get_size(); + + unsigned liga_subst_prime_id = c.create_node (prime_size); + if (liga_subst_prime_id == (unsigned) -1) return -1; + + LigatureSubstFormat1* liga_subst_prime = (LigatureSubstFormat1*) c.graph.object (liga_subst_prime_id).head; + liga_subst_prime->format = this->format; + liga_subst_prime->ligatureSet.len = this->ligatureSet.len; + + // Create a place holder coverage prime id since we need to add virtual links to it while + // generating liga and liga sets. Afterwards it will be updated to have the correct coverage. + unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage); + unsigned coverage_prime_id = c.graph.duplicate(coverage_id); + auto& coverage_prime_vertex = c.graph.vertices_[coverage_prime_id]; + auto* coverage_prime_link = c.graph.vertices_[liga_subst_prime_id].obj.real_links.push (); + coverage_prime_link->width = SmallTypes::size; + coverage_prime_link->objidx = coverage_prime_id; + coverage_prime_link->position = 2; + coverage_prime_vertex.add_parent (liga_subst_prime_id, false); + + // Locate all liga sets with ligas between start and end. + // Clone or move them as needed. + unsigned count = 0; + unsigned liga_set_count = 0; + unsigned liga_set_start = -1; + unsigned liga_set_end = 0; // inclusive + for (unsigned i = 0; i < liga_counts.length; i++) + { + unsigned num_ligas = liga_counts[i]; + + unsigned current_start = count; + unsigned current_end = count + num_ligas; + + if (current_start >= end || start >= current_end) { + // No intersection, so just skip + count += num_ligas; + continue; + } + + auto liga_set_index = c.graph.index_for_offset(this_index, &ligatureSet[i]); + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + if (!liga_set.table) { + return -1; + } + + // Bounds may need to be adjusted if some ligas have been previously removed. + hb_pair_t liga_bounds = current_liga_set_bounds(c, liga_set_index, liga_set.vertex->obj); + current_start = hb_max(count + liga_bounds.first, current_start); + current_end = hb_min(count + liga_bounds.second, current_end); + + unsigned liga_set_prime_id; + if (current_start >= start && current_end <= end) { + // This liga set is fully contined within [start, end) + // We can move the entire ligaset to the new liga subset object. + liga_set_end = i; + if (i < liga_set_start) liga_set_start = i; + liga_set_prime_id = c.graph.move_child<> (this_index, + &ligatureSet[i], + liga_subst_prime_id, + &liga_subst_prime->ligatureSet[liga_set_count++]); + compact_liga_set(c, liga_set.table, liga_set.vertex->obj); + } + else + { + // This liga set partially overlaps [start, end). We'll need to create + // a new liga set sub table and move the intersecting ligas to it. + unsigned liga_count = hb_min(end, current_end) - hb_max(start, current_start); + auto result = new_liga_set(c, liga_count); + liga_set_prime_id = result.first; + LigatureSet* prime = result.second; + if (liga_set_prime_id == (unsigned) -1) return -1; + + unsigned new_index = 0; + for (unsigned j = hb_max(start, current_start) - count; j < hb_min(end, current_end) - count; j++) { + c.graph.move_child<> (liga_set_index, + &liga_set.table->ligature[j], + liga_set_prime_id, + &prime->ligature[new_index++]); + } + + liga_set_end = i; + if (i < liga_set_start) liga_set_start = i; + c.graph.add_link(&liga_subst_prime->ligatureSet[liga_set_count++], liga_subst_prime_id, liga_set_prime_id); + } + + // The new liga and all children set needs to have a virtual link to the new coverage table: + auto& liga_set_prime = c.graph.vertices_[liga_set_prime_id].obj; + clear_virtual_links(c, liga_set_prime_id); + add_virtual_link(c, liga_set_prime_id, coverage_prime_id); + for (const auto& l : liga_set_prime.real_links) { + clear_virtual_links(c, l.objidx); + add_virtual_link(c, l.objidx, coverage_prime_id); + } + + count += num_ligas; + } + + c.graph.vertices_[liga_subst_prime_id].obj.tail -= (liga_subst_prime->ligatureSet.len - liga_set_count) * SmallTypes::size; + liga_subst_prime->ligatureSet.len = liga_set_count; + + if (!Coverage::filter_coverage (c, + coverage_prime_id, + liga_set_start, liga_set_end + 1)) + return -1; + + return liga_subst_prime_id; + } + + bool shrink (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned old_count, + hb_vector_t liga_counts, + unsigned count) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Shrinking LigatureSubstFormat1 (%u) to [0, %u).", + this_index, + count); + if (count >= old_count) + return true; + + hb_set_t retained_indices; + unsigned new_liga_set_count = 0; + for (unsigned i = 0; i < liga_counts.length; i++) + { + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + if (!liga_set.table) { + return false; + } + + // We need the virtual links to coverage removed from all descendants on this liga subst. + // If any are left when we try to mutate the coverage table later it will be unnessecarily + // duplicated. Code later on will re-add the virtual links as needed (via retained_indices). + clear_virtual_links(c, liga_set.index); + retained_indices.add(liga_set.index); + for (const auto& liga_offset : liga_set.table->ligature) { + unsigned liga_index = c.graph.index_for_offset(liga_set.index, &liga_offset); + if (liga_index != (unsigned) -1) { + clear_virtual_links(c, liga_index); + retained_indices.add(liga_index); + } + } + + unsigned num_ligas = liga_counts[i]; + if (num_ligas >= count) { + // drop the trailing liga's from this set and all subsequent liga sets + unsigned num_ligas_to_remove = num_ligas - count; + new_liga_set_count = i + 1; + c.graph.vertices_[liga_set.index].obj.tail -= num_ligas_to_remove * SmallTypes::size; + liga_set.table->ligature.len = count; + break; + } else { + count -= num_ligas; + } + } + + // Adjust liga set array + c.graph.vertices_[this_index].obj.tail -= (ligatureSet.len - new_liga_set_count) * SmallTypes::size; + ligatureSet.len = new_liga_set_count; + + // Coverage matches the number of liga sets so rebuild as needed + auto coverage = c.graph.as_mutable_table (this_index, &this->coverage); + if (!coverage) return false; + + for (unsigned i : retained_indices.iter()) + add_virtual_link(c, i, coverage.index); + + unsigned coverage_size = coverage.vertex->table_size (); + auto new_coverage = + + hb_zip (coverage.table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t p) { + return p.second < new_liga_set_count; + }) + | hb_map_retains_sorting (hb_first) + ; + + return Coverage::make_coverage (c, new_coverage, coverage.index, coverage_size); + } +}; + +struct LigatureSubst : public OT::Layout::GSUB_impl::LigatureSubst +{ + + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned parent_index, + unsigned this_index) + { + switch (u.format) { + case 1: + return ((LigatureSubstFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); +#ifndef HB_NO_BEYOND_64K + case 2: HB_FALLTHROUGH; + // Don't split 24bit Ligature Subs +#endif + default: + return hb_vector_t (); + } + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < u.format.get_size ()) return false; + hb_barrier (); + + switch (u.format) { + case 1: + return ((LigatureSubstFormat1*)(&u.format1))->sanitize (vertex); +#ifndef HB_NO_BEYOND_64K + case 2: HB_FALLTHROUGH; +#endif + default: + // We don't handle format 2 here. + return false; + } + } +}; + +} + +#endif // GRAPH_LIGATURE_GRAPH_HH diff --git a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh index fd46861de46..46da2740615 100644 --- a/thirdparty/harfbuzz/src/graph/pairpos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/pairpos-graph.hh @@ -423,7 +423,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4width = SmallTypes::size; class_def_link->objidx = class_def_2_id; class_def_link->position = 10; - graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id); + graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id, false); graph.duplicate (pair_pos_prime_id, class_def_2_id); return pair_pos_prime_id; diff --git a/thirdparty/harfbuzz/src/graph/serialize.hh b/thirdparty/harfbuzz/src/graph/serialize.hh index 06e4bf44d8e..fb8950e6f56 100644 --- a/thirdparty/harfbuzz/src/graph/serialize.hh +++ b/thirdparty/harfbuzz/src/graph/serialize.hh @@ -172,8 +172,11 @@ void print_overflows (graph_t& graph, template inline void serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, char* head, + unsigned size, hb_serialize_context_t* c) { + assert(link.position + link.width <= size); + OT::Offset* offset = reinterpret_cast*> (head + link.position); *offset = 0; c->add_link (*offset, @@ -187,6 +190,7 @@ serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, inline void serialize_link (const hb_serialize_context_t::object_t::link_t& link, char* head, + unsigned size, hb_serialize_context_t* c) { switch (link.width) @@ -197,21 +201,21 @@ void serialize_link (const hb_serialize_context_t::object_t::link_t& link, case 4: if (link.is_signed) { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, c); } else { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, c); } return; case 2: if (link.is_signed) { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, c); } else { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, c); } return; case 3: - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, c); return; default: // Unexpected link width. @@ -251,7 +255,7 @@ inline hb_blob_t* serialize (const graph_t& graph) // Only real links needs to be serialized. for (const auto& link : vertices[i].obj.real_links) - serialize_link (link, start, &c); + serialize_link (link, start, size, &c); // All duplications are already encoded in the graph, so don't // enable sharing during packing. diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index 0252fa7dfe3..7dfa9769699 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -78,129 +78,220 @@ /* - * Big-endian integers. + * Fixed-endian integers / floats. */ + /* Endian swap, used in Windows related backends */ static inline constexpr uint16_t hb_uint16_swap (uint16_t v) { return (v >> 8) | (v << 8); } static inline constexpr uint32_t hb_uint32_swap (uint32_t v) { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } -#ifndef HB_FAST_INT_ACCESS +template +struct __attribute__((packed)) hb_packed_t { Type v; }; + +#ifndef HB_FAST_NUM_ACCESS #if defined(__OPTIMIZE__) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __BIG_ENDIAN || \ (__BYTE_ORDER == __LITTLE_ENDIAN && \ hb_has_builtin(__builtin_bswap16) && \ hb_has_builtin(__builtin_bswap32))) -#define HB_FAST_INT_ACCESS 1 +#define HB_FAST_NUM_ACCESS 1 #else -#define HB_FAST_INT_ACCESS 0 +#define HB_FAST_NUM_ACCESS 0 #endif #endif -template -struct BEInt; -template -struct BEInt +template +struct HBInt; +template +struct HBInt { public: - BEInt () = default; - constexpr BEInt (Type V) : v {uint8_t (V)} {} + HBInt () = default; + constexpr HBInt (Type V) : v {uint8_t (V)} {} constexpr operator Type () const { return v; } private: uint8_t v; }; -template -struct BEInt +template +struct HBInt { - struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; - public: - BEInt () = default; + HBInt () = default; - BEInt (Type V) -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - { ((packed_uint16_t *) v)->v = __builtin_bswap16 (V); } -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - { ((packed_uint16_t *) v)->v = V; } -#endif + HBInt (Type V) +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + ((hb_packed_t *) v)->v = V; + else + ((hb_packed_t *) v)->v = __builtin_bswap16 (V); + } #else - : v {uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} + : v {BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 8) & 0xFF)} {} #endif - constexpr operator Type () const { -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) v)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) v)->v; -#endif + constexpr operator Type () const + { +#if HB_FAST_NUM_ACCESS + return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? + ((const hb_packed_t *) v)->v + : + __builtin_bswap16 (((const hb_packed_t *) v)->v) + ; #else - return (v[0] << 8) - + (v[1] ); + return (BE ? (v[0] << 8) : (v[0] )) + + (BE ? (v[1] ) : (v[1] << 8)); #endif } private: uint8_t v[2]; }; -template -struct BEInt +template +struct HBInt { static_assert (!std::is_signed::value, ""); public: - BEInt () = default; - constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), - uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} + HBInt () = default; + constexpr HBInt (Type V) : v {BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V ) & 0xFF)} {} - constexpr operator Type () const { return (v[0] << 16) - + (v[1] << 8) - + (v[2] ); } + constexpr operator Type () const { return (BE ? (v[0] << 16) : (v[0] )) + + (BE ? (v[1] << 8) : (v[1] << 8)) + + (BE ? (v[2] ) : (v[2] << 16)); } private: uint8_t v[3]; }; -template -struct BEInt +template +struct HBInt { - struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + template + friend struct HBFloat; public: - BEInt () = default; + HBInt () = default; - BEInt (Type V) -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - { ((packed_uint32_t *) v)->v = __builtin_bswap32 (V); } -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - { ((packed_uint32_t *) v)->v = V; } -#endif + HBInt (Type V) +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + ((hb_packed_t *) v)->v = V; + else + ((hb_packed_t *) v)->v = __builtin_bswap32 (V); + } #else - : v {uint8_t ((V >> 24) & 0xFF), - uint8_t ((V >> 16) & 0xFF), - uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} + : v {BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 24) & 0xFF)} {} #endif constexpr operator Type () const { -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap32 (((packed_uint32_t *) v)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint32_t *) v)->v; -#endif +#if HB_FAST_NUM_ACCESS + return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? + ((const hb_packed_t *) v)->v + : + __builtin_bswap32 (((const hb_packed_t *) v)->v) + ; #else - return (v[0] << 24) - + (v[1] << 16) - + (v[2] << 8) - + (v[3] ); + return (BE ? (v[0] << 24) : (v[0] )) + + (BE ? (v[1] << 16) : (v[1] << 8)) + + (BE ? (v[2] << 8) : (v[2] << 16)) + + (BE ? (v[3] ) : (v[3] << 24)); #endif } private: uint8_t v[4]; }; +template +struct HBInt +{ + template + friend struct HBFloat; + + public: + HBInt () = default; + + HBInt (Type V) + : v {BE ? uint8_t ((V >> 56) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V >> 48) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V >> 40) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V >> 32) & 0xFF) : uint8_t ((V >> 24) & 0xFF), + BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V >> 32) & 0xFF), + BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 40) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 48) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 56) & 0xFF)} {} + + constexpr operator Type () const { + return (BE ? (uint64_t (v[0]) << 56) : (uint64_t (v[0]) )) + + (BE ? (uint64_t (v[1]) << 48) : (uint64_t (v[1]) << 8)) + + (BE ? (uint64_t (v[2]) << 40) : (uint64_t (v[2]) << 16)) + + (BE ? (uint64_t (v[3]) << 32) : (uint64_t (v[3]) << 24)) + + (BE ? (uint64_t (v[4]) << 24) : (uint64_t (v[4]) << 32)) + + (BE ? (uint64_t (v[5]) << 16) : (uint64_t (v[5]) << 40)) + + (BE ? (uint64_t (v[6]) << 8) : (uint64_t (v[6]) << 48)) + + (BE ? (uint64_t (v[7]) ) : (uint64_t (v[7]) << 56)); + } + private: uint8_t v[8]; +}; /* Floats. */ +template +struct HBFloat +{ + using IntType = typename std::conditional::type; + + public: + HBFloat () = default; + + HBFloat (Type V) + { +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + { + ((hb_packed_t *) v)->v = V; + return; + } + } +#endif + + union { + hb_packed_t f; + hb_packed_t i; + } u = {{V}}; + + const HBInt I = u.i.v; + for (unsigned i = 0; i < Bytes; i++) + v[i] = I.v[i]; + } + + /* c++14 constexpr */ operator Type () const + { +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + return ((const hb_packed_t *) v)->v; + } +#endif + + HBInt I; + for (unsigned i = 0; i < Bytes; i++) + I.v[i] = v[i]; + + union { + hb_packed_t i; + hb_packed_t f; + } u = {{I}}; + + return u.f.v; + } + private: uint8_t v[Bytes]; +}; + + /* We want our rounding towards +infinity. */ static inline double _hb_roundf (double x) { return floor (x + .5); } @@ -210,6 +301,27 @@ _hb_roundf (float x) { return floorf (x + .5f); } #define roundf(x) _hb_roundf(x) +static inline void +hb_sincos (float rotation, float &s, float &c) +{ +#ifdef HAVE_SINCOSF + sincosf (rotation, &s, &c); +#else + c = cosf (rotation); + s = sinf (rotation); +#endif +} +static inline void +hb_sincos (double rotation, double &s, double &c) +{ +#ifdef HAVE_SINCOS + sincos (rotation, &s, &c); +#else + c = cos (rotation); + s = sin (rotation); +#endif +} + /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, * values will be truncated / overlap, and might not decode exactly. */ @@ -1070,6 +1182,7 @@ _hb_cmp_operator (const void *pkey, const void *pval) } template +HB_HOT static inline bool hb_bsearch_impl (unsigned *pos, /* Out */ const K& key, diff --git a/thirdparty/harfbuzz/src/hb-cache.hh b/thirdparty/harfbuzz/src/hb-cache.hh index f9d1aa08b86..ac76deb725e 100644 --- a/thirdparty/harfbuzz/src/hb-cache.hh +++ b/thirdparty/harfbuzz/src/hb-cache.hh @@ -83,6 +83,7 @@ struct hb_cache_t v = -1; } + HB_HOT bool get (unsigned int key, unsigned int *value) const { unsigned int k = key & ((1u<> key_bits) || (value >> value_bits))) - return false; /* Overflows */ + return; /* Overflows */ unsigned int k = key & ((1u<>cache_bits)< coords = coords_; num_coords = num_coords_; varStore = acc.varStore; - do_blend = num_coords && coords && varStore->size; + do_blend = num_coords && varStore->size; set_ivs (acc.privateDicts[fd].ivs); } diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc index 16fd883d209..9f3b6785b97 100644 --- a/thirdparty/harfbuzz/src/hb-common.cc +++ b/thirdparty/harfbuzz/src/hb-common.cc @@ -545,8 +545,11 @@ hb_script_to_iso15924_tag (hb_script_t script) * Fetches the #hb_direction_t of a script when it is * set horizontally. All right-to-left scripts will return * #HB_DIRECTION_RTL. All left-to-right scripts will return - * #HB_DIRECTION_LTR. Scripts that can be written either - * horizontally or vertically will return #HB_DIRECTION_INVALID. + * #HB_DIRECTION_LTR. + * + * Scripts that can be written either right-to-left or + * left-to-right will return #HB_DIRECTION_INVALID. + * * Unknown scripts will return #HB_DIRECTION_LTR. * * Return value: The horizontal #hb_direction_t of @script diff --git a/thirdparty/harfbuzz/src/hb-coretext-shape.cc b/thirdparty/harfbuzz/src/hb-coretext-shape.cc index c874d49565c..ebd0bc13268 100644 --- a/thirdparty/harfbuzz/src/hb-coretext-shape.cc +++ b/thirdparty/harfbuzz/src/hb-coretext-shape.cc @@ -73,9 +73,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) return nullptr; } - unsigned num_axes = hb_ot_var_get_axis_count (face); - // https://github.com/harfbuzz/harfbuzz/issues/5163 - if (num_axes) + if (font->num_coords) { CFMutableDictionaryRef variations = CFDictionaryCreateMutable (kCFAllocatorDefault, @@ -83,15 +81,14 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - unsigned count = hb_max (num_axes, font->num_coords); + unsigned count = font->num_coords; for (unsigned i = 0; i < count; i++) { hb_ot_var_axis_info_t info; unsigned int c = 1; hb_ot_var_get_axis_infos (font->face, i, &c, &info); - float v = i < font->num_coords ? - hb_clamp (font->design_coords[i], info.min_value, info.max_value) : - info.default_value; + + float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value); CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag); CFNumberRef value_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &v); diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc index ea2d5b6e978..4eb6c0fcc77 100644 --- a/thirdparty/harfbuzz/src/hb-coretext.cc +++ b/thirdparty/harfbuzz/src/hb-coretext.cc @@ -206,8 +206,9 @@ create_cg_font (hb_blob_t *blob, unsigned int index) if (unlikely (named_instance_index != 0)) { // https://github.com/harfbuzz/harfbuzz/issues/5300 + // https://github.com/harfbuzz/harfbuzz/issues/5354 #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) || \ - (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || \ + (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) || \ (defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= 110000) || \ (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __WATCH_OS_VERSION_MIN_REQUIRED >= 40000) || \ (defined(__MACCATALYST_VERSION_MIN_REQUIRED) && __MACCATALYST_VERSION_MIN_REQUIRED >= 130100) || \ diff --git a/thirdparty/harfbuzz/src/hb-deprecated.h b/thirdparty/harfbuzz/src/hb-deprecated.h index 62911bba795..849869f39d2 100644 --- a/thirdparty/harfbuzz/src/hb-deprecated.h +++ b/thirdparty/harfbuzz/src/hb-deprecated.h @@ -287,7 +287,7 @@ typedef void (*hb_font_get_glyph_shape_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 - * XDeprecated: REPLACEME: Use hb_font_draw_glyph_func_or_fail_t instead. + * Deprecated: 11.2.0: 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, @@ -308,7 +308,7 @@ 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 - * XDeprecated: REPLACEME: Use hb_font_paint_glyph_or_fail_func_t instead. + * Deprecated: 11.2.0: 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, @@ -346,7 +346,7 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, * 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. + * Deprecated: 11.2.0: 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 @@ -364,7 +364,7 @@ hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, * 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. + * Deprecated: 11.2.0: 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 diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc index 9c4bab95df5..6e2bd914b6f 100644 --- a/thirdparty/harfbuzz/src/hb-directwrite.cc +++ b/thirdparty/harfbuzz/src/hb-directwrite.cc @@ -161,6 +161,58 @@ _hb_directwrite_table_data_release (void *data) hb_free (context); } +static hb_blob_t * +_hb_directwrite_get_file_blob (IDWriteFontFace *dw_face) +{ + UINT32 file_count; + if (FAILED (dw_face->GetFiles(&file_count, NULL))) + return nullptr; + + IDWriteFontFile **files = new IDWriteFontFile*[file_count]; + if (FAILED (dw_face->GetFiles(&file_count, files))) + { + delete [] files; + return nullptr; + } + + hb_blob_t *blob = nullptr; + for (UINT32 i = 0; i < file_count; i++) + { + LPCVOID reference_key; + UINT32 reference_key_size; + if (FAILED (files[i]->GetReferenceKey(&reference_key, &reference_key_size))) + continue; + + IDWriteFontFileLoader *loader; + if (FAILED (files[i]->GetLoader(&loader))) + continue; + + IDWriteFontFileStream *stream; + if (FAILED (loader->CreateStreamFromKey (reference_key, reference_key_size, &stream))) + { + loader->Release (); + continue; + } + + UINT64 file_size; + const void *fragment; + void *context; + if (FAILED (stream->GetFileSize(&file_size)) || + FAILED (stream->ReadFileFragment (&fragment, 0, file_size, &context))) + { + loader->Release (); + continue; + } + blob = hb_blob_create ((const char *) fragment, file_size, HB_MEMORY_MODE_DUPLICATE, NULL, NULL); + stream->ReleaseFileFragment (context); + loader->Release (); + break; + } + + delete [] files; + return blob; +} + static hb_blob_t * _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { @@ -169,6 +221,9 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * uint32_t length; void *table_context; BOOL exists; + if (tag == HB_TAG_NONE) + return _hb_directwrite_get_file_blob (dw_face); + if (FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data, &length, &table_context, &exists))) return nullptr; diff --git a/thirdparty/harfbuzz/src/hb-draw.cc b/thirdparty/harfbuzz/src/hb-draw.cc index eec3b0bb9f0..30ab86d33b0 100644 --- a/thirdparty/harfbuzz/src/hb-draw.cc +++ b/thirdparty/harfbuzz/src/hb-draw.cc @@ -63,14 +63,14 @@ hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data, float to_x, float to_y, void *user_data HB_UNUSED) { -#define HB_ONE_THIRD 0.33333333f +#define HB_TWO_THIRD 0.66666666666666666666666667f dfuncs->emit_cubic_to (draw_data, *st, - (st->current_x + 2.f * control_x) * HB_ONE_THIRD, - (st->current_y + 2.f * control_y) * HB_ONE_THIRD, - (to_x + 2.f * control_x) * HB_ONE_THIRD, - (to_y + 2.f * control_y) * HB_ONE_THIRD, + st->current_x + (control_x - st->current_x) * HB_TWO_THIRD, + st->current_y + (control_y - st->current_y) * HB_TWO_THIRD, + to_x + (control_x - to_x) * HB_TWO_THIRD, + to_y + (control_y - to_y) * HB_TWO_THIRD, to_x, to_y); -#undef HB_ONE_THIRD +#undef HB_TWO_THIRD } static void @@ -277,7 +277,7 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs) * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * - * Attaches a user-data key/data pair to the specified draw-functions structure. + * Attaches a user-data key/data pair to the specified draw-functions structure. * * Return value: `true` if success, `false` otherwise * @@ -467,7 +467,7 @@ hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_extents_t *extents = (hb_extents_t *) data; + hb_extents_t<> *extents = (hb_extents_t<> *) data; extents->add_point (to_x, to_y); } @@ -479,7 +479,7 @@ hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_extents_t *extents = (hb_extents_t *) data; + hb_extents_t<> *extents = (hb_extents_t<> *) data; extents->add_point (to_x, to_y); } @@ -492,7 +492,7 @@ hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_extents_t *extents = (hb_extents_t *) data; + hb_extents_t<> *extents = (hb_extents_t<> *) data; extents->add_point (control_x, control_y); extents->add_point (to_x, to_y); @@ -507,7 +507,7 @@ hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, float to_x, float to_y, void *user_data HB_UNUSED) { - hb_extents_t *extents = (hb_extents_t *) data; + hb_extents_t<> *extents = (hb_extents_t<> *) data; extents->add_point (control1_x, control1_y); extents->add_point (control2_x, control2_y); diff --git a/thirdparty/harfbuzz/src/hb-face-builder.cc b/thirdparty/harfbuzz/src/hb-face-builder.cc index beea89ed22f..c3ddcd856b7 100644 --- a/thirdparty/harfbuzz/src/hb-face-builder.cc +++ b/thirdparty/harfbuzz/src/hb-face-builder.cc @@ -169,8 +169,7 @@ _hb_face_builder_get_table_tags (const hb_face_t *face HB_UNUSED, if (unlikely (start_offset >= population)) { - if (table_count) - *table_count = 0; + *table_count = 0; return population; } diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc index 431cbaccb1a..3a504510921 100644 --- a/thirdparty/harfbuzz/src/hb-face.cc +++ b/thirdparty/harfbuzz/src/hb-face.cc @@ -329,7 +329,7 @@ hb_face_create_from_file_or_fail (const char *file_name, return face; } -static struct supported_face_loaders_t { +static const 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); diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc index 3a2b645b66e..fe94e2ea6c5 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -246,7 +246,6 @@ hb_font_get_glyph_v_advance_nil (hb_font_t *font, hb_codepoint_t glyph HB_UNUSED, void *user_data HB_UNUSED) { - /* TODO use font_extents.ascender+descender */ return -font->y_scale; } @@ -352,6 +351,10 @@ hb_font_get_glyph_h_origin_default (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { + if (font->has_glyph_h_origins_func_set ()) + { + return font->get_glyph_h_origins (1, &glyph, 0, x, 0, y, 0, false); + } hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); if (ret) font->parent_scale_position (x, y); @@ -366,7 +369,6 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, hb_position_t *y, void *user_data HB_UNUSED) { - *x = *y = 0; return false; } @@ -378,12 +380,100 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { + if (font->has_glyph_v_origins_func_set ()) + { + return font->get_glyph_v_origins (1, &glyph, 0, x, 0, y, 0, false); + } hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); if (ret) font->parent_scale_position (x, y); return ret; } +#define hb_font_get_glyph_h_origins_nil hb_font_get_glyph_h_origins_default + +static hb_bool_t +hb_font_get_glyph_h_origins_default (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_glyph HB_UNUSED, + unsigned glyph_stride HB_UNUSED, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data HB_UNUSED) +{ + if (font->has_glyph_h_origin_func_set ()) + { + for (unsigned int i = 0; i < count; i++) + { + font->get_glyph_h_origin (*first_glyph, first_x, first_y, false); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + return true; + } + + hb_bool_t ret = font->parent->get_glyph_h_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); + if (ret) + { + for (unsigned i = 0; i < count; i++) + { + font->parent_scale_position (first_x, first_y); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + return ret; +} + +#define hb_font_get_glyph_v_origins_nil hb_font_get_glyph_v_origins_default + +static hb_bool_t +hb_font_get_glyph_v_origins_default (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_glyph HB_UNUSED, + unsigned glyph_stride HB_UNUSED, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data HB_UNUSED) +{ + if (font->has_glyph_v_origin_func_set ()) + { + for (unsigned int i = 0; i < count; i++) + { + font->get_glyph_v_origin (*first_glyph, first_x, first_y, false); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + return true; + } + + hb_bool_t ret = font->parent->get_glyph_v_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); + if (ret) + { + for (unsigned i = 0; i < count; i++) + { + font->parent_scale_position (first_x, first_y); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + return ret; +} + static hb_position_t hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, @@ -1256,6 +1346,77 @@ hb_font_get_glyph_v_origin (hb_font_t *font, return font->get_glyph_v_origin (glyph, x, y); } +/** + * hb_font_get_glyph_h_origins: + * @font: #hb_font_t to work upon + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first X coordinate of the origin retrieved + * @x_stride: The stride between successive X coordinates + * @first_y: (out): The first Y coordinate of the origin retrieved + * @y_stride: The stride between successive Y coordinates + * + * Fetches the (X,Y) coordinates of the origin for requested glyph IDs + * in the specified font, for horizontal text segments. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +hb_bool_t +hb_font_get_glyph_h_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride) + +{ + return font->get_glyph_h_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); +} + +/** + * hb_font_get_glyph_v_origins: + * @font: #hb_font_t to work upon + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first X coordinate of the origin retrieved + * @x_stride: The stride between successive X coordinates + * @first_y: (out): The first Y coordinate of the origin retrieved + * @y_stride: The stride between successive Y coordinates + * + * Fetches the (X,Y) coordinates of the origin for requested glyph IDs + * in the specified font, for vertical text segments. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +hb_bool_t +hb_font_get_glyph_v_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride) + +{ + return font->get_glyph_v_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); +} + + /** * hb_font_get_glyph_h_kerning: * @font: #hb_font_t to work upon @@ -1443,7 +1604,7 @@ hb_font_get_glyph_shape (hb_font_t *font, * * Return value: `true` if glyph was drawn, `false` otherwise * - * XSince: REPLACEME + * Since: 11.2.0 **/ hb_bool_t hb_font_draw_glyph_or_fail (hb_font_t *font, @@ -1480,7 +1641,7 @@ hb_font_draw_glyph_or_fail (hb_font_t *font, * * Return value: `true` if glyph was painted, `false` otherwise * - * XSince: REPLACEME + * Since: 11.2.0 */ hb_bool_t hb_font_paint_glyph_or_fail (hb_font_t *font, @@ -1883,6 +2044,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 1000, /* x_scale */ 1000, /* y_scale */ + false, /* is_synthetic */ 0.f, /* x_embolden */ 0.f, /* y_embolden */ true, /* embolden_in_place */ @@ -1900,6 +2062,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 0, /* ptem */ HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */ + false, /* has_nonzero_coords */ 0, /* num_coords */ nullptr, /* coords */ nullptr, /* design_coords */ @@ -1960,8 +2123,14 @@ hb_font_create (hb_face_t *face) hb_font_set_funcs_using (font, nullptr); #ifndef HB_NO_VAR - if (face && face->index >> 16) - hb_font_set_var_named_instance (font, (face->index >> 16) - 1); + // Initialize variations. + if (likely (face)) + { + if (face->index >> 16) + hb_font_set_var_named_instance (font, (face->index >> 16) - 1); + else + hb_font_set_variations (font, nullptr, 0); + } #endif return font; @@ -1979,6 +2148,7 @@ _hb_font_adopt_var_coords (hb_font_t *font, font->coords = coords; font->design_coords = design_coords; font->num_coords = coords_length; + font->has_nonzero_coords = hb_any (hb_array (coords, coords_length)); font->changed (); font->serial_coords = font->serial; @@ -2393,7 +2563,7 @@ hb_font_set_funcs_data (hb_font_t *font, font->changed (); } -static struct supported_font_funcs_t { +static const struct supported_font_funcs_t { char name[16]; void (*func) (hb_font_t *); } supported_font_funcs[] = @@ -2450,6 +2620,9 @@ hb_bool_t hb_font_set_funcs_using (hb_font_t *font, const char *name) { + if (unlikely (hb_object_is_immutable (font))) + return false; + bool retry = false; if (!name || !*name) @@ -2704,12 +2877,12 @@ hb_font_get_ptem (hb_font_t *font) * * Return value: `true` if the font is synthetic, `false` otherwise. * - * XSince: REPLACEME + * Since: 11.2.0 */ hb_bool_t hb_font_is_synthetic (hb_font_t *font) { - return font->is_synthetic (); + return font->is_synthetic; } /** @@ -2858,12 +3031,6 @@ hb_font_set_variations (hb_font_t *font, if (hb_object_is_immutable (font)) return; - if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE) - { - hb_font_set_var_coords_normalized (font, nullptr, 0); - return; - } - const OT::fvar &fvar = *font->face->table.fvar; auto axes = fvar.get_axes (); const unsigned coords_length = axes.length; @@ -2970,7 +3137,6 @@ hb_font_set_variation (hb_font_t *font, hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); - } /** @@ -2991,11 +3157,16 @@ hb_font_set_variation (hb_font_t *font, void hb_font_set_var_coords_design (hb_font_t *font, const float *coords, - unsigned int coords_length) + unsigned int input_coords_length) { if (hb_object_is_immutable (font)) return; + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + const unsigned coords_length = axes.length; + + input_coords_length = hb_min (input_coords_length, coords_length); 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; @@ -3006,8 +3177,11 @@ hb_font_set_var_coords_design (hb_font_t *font, return; } - if (coords_length) - hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); + if (input_coords_length) + hb_memcpy (design_coords, coords, input_coords_length * sizeof (font->design_coords[0])); + // Fill in the rest with default values + for (unsigned int i = input_coords_length; i < coords_length; i++) + design_coords[i] = axes[i].get_default (); hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); @@ -3072,34 +3246,31 @@ hb_font_get_var_named_instance (hb_font_t *font) void hb_font_set_var_coords_normalized (hb_font_t *font, const int *coords, /* 2.14 normalized */ - unsigned int coords_length) + unsigned int input_coords_length) { if (hb_object_is_immutable (font)) return; + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + unsigned coords_length = axes.length; + + input_coords_length = hb_min (input_coords_length, coords_length); 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; - if (unlikely (coords_length && !(copy && unmapped && design_coords))) + if (unlikely (coords_length && !(copy && design_coords))) { hb_free (copy); - hb_free (unmapped); hb_free (design_coords); return; } - if (coords_length) - { - hb_memcpy (copy, coords, coords_length * sizeof (coords[0])); - hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0])); - } + if (input_coords_length) + hb_memcpy (copy, coords, input_coords_length * sizeof (coords[0])); - /* Best effort design coords simulation */ - font->face->table.avar->unmap_coords (unmapped, coords_length); for (unsigned int i = 0; i < coords_length; ++i) - design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]); - hb_free (unmapped); + design_coords[i] = NAN; _hb_font_adopt_var_coords (font, copy, design_coords, coords_length); } @@ -3112,8 +3283,8 @@ hb_font_set_var_coords_normalized (hb_font_t *font, * Fetches the list of normalized variation coordinates currently * set on a font. * - * Note that this returned array may only contain values for some - * (or none) of the axes; omitted axes effectively have zero values. + * Note that if no variation coordinates are set, this function may + * return %NULL. * * Return value is valid as long as variation coordinates of the font * are not modified. @@ -3140,9 +3311,12 @@ hb_font_get_var_coords_normalized (hb_font_t *font, * Fetches the list of variation coordinates (in design-space units) currently * set on a font. * - * Note that this returned array may only contain values for some - * (or none) of the axes; omitted axes effectively have their default - * values. + * Note that if no variation coordinates are set, this function may + * return %NULL. + * + * If variations have been set on the font using normalized coordinates + * (i.e. via hb_font_set_var_coords_normalized()), the design coordinates will + * have NaN (Not a Number) values. * * Return value is valid as long as variation coordinates of the font * are not modified. diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h index 77178bf8472..16b7f552e0f 100644 --- a/thirdparty/harfbuzz/src/hb-font.h +++ b/thirdparty/harfbuzz/src/hb-font.h @@ -97,7 +97,7 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); * @descender: The depth of typographic descenders. * @line_gap: The suggested line-spacing gap. * - * Font-wide extent values, measured in font units. + * Font-wide extent values, measured in scaled units. * * Note that typically @ascender is positive and @descender * negative, in coordinate systems that grow up. @@ -332,7 +332,7 @@ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t; * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph. Each coordinate must be returned in an #hb_position_t * output parameter. * @@ -349,7 +349,7 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph, for horizontal-direction text segments. Each * coordinate must be returned in an #hb_position_t output parameter. * @@ -361,13 +361,72 @@ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t; * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph, for vertical-direction text segments. Each coordinate * must be returned in an #hb_position_t output parameter. * **/ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t; +/** + * hb_font_get_glyph_origins_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @first_glyph: The first glyph ID to query + * @count: number of glyphs to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first origin X coordinate retrieved + * @x_stride: The stride between successive origin X coordinates + * @first_y: (out): The first origin Y coordinate retrieved + * @y_stride: The stride between successive origin Y coordinates + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for each requested glyph. Each coordinate value must be returned in + * an #hb_position_t in the two output parameters. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +typedef hb_bool_t (*hb_font_get_glyph_origins_func_t) (hb_font_t *font, void *font_data, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data); + +/** + * hb_font_get_glyph_h_origins_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for requested glyph, for horizontal-direction text segments. Each + * coordinate must be returned in a the x/y #hb_position_t output parameters. + * + * Since: 11.3.0 + **/ +typedef hb_font_get_glyph_origins_func_t hb_font_get_glyph_h_origins_func_t; + +/** + * hb_font_get_glyph_v_origins_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for requested glyph, for vertical-direction text segments. Each + * coordinate must be returned in a the x/y #hb_position_t output parameters. + * + * Since: 11.3.0 + **/ +typedef hb_font_get_glyph_origins_func_t hb_font_get_glyph_v_origins_func_t; + /** * hb_font_get_glyph_kerning_func_t: * @font: #hb_font_t to work upon @@ -428,7 +487,7 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) for a + * This method should retrieve the (X,Y) coordinates (in scaled units) for a * specified contour point in a glyph. Each coordinate must be returned as * an #hb_position_t output parameter. * @@ -498,7 +557,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * * Return value: `true` if glyph was drawn, `false` otherwise * - * XSince: REPLACEME + * Since: 11.2.0 **/ typedef hb_bool_t (*hb_font_draw_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -520,7 +579,7 @@ typedef hb_bool_t (*hb_font_draw_glyph_or_fail_func_t) (hb_font_t *font, void *f * * Return value: `true` if glyph was painted, `false` otherwise * - * XSince: REPLACEME + * Since: 11.2.0 */ typedef hb_bool_t (*hb_font_paint_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -707,6 +766,38 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_v_origin_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_font_funcs_set_glyph_h_origins_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_get_glyph_h_origins_func_t. + * + * Since: 11.3.0 + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_h_origins_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_h_origins_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_glyph_v_origins_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_get_glyph_v_origins_func_t. + * + * Since: 11.3.0 + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_v_origins_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_v_origins_func_t func, + void *user_data, hb_destroy_func_t destroy); + /** * hb_font_funcs_set_glyph_h_kerning_func: * @ffuncs: A font-function structure @@ -796,7 +887,7 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, * * Sets the implementation function for #hb_font_draw_glyph_or_fail_func_t. * - * XSince: REPLACEME + * Since: 11.2.0 **/ HB_EXTERN void hb_font_funcs_set_draw_glyph_or_fail_func (hb_font_funcs_t *ffuncs, @@ -812,7 +903,7 @@ hb_font_funcs_set_draw_glyph_or_fail_func (hb_font_funcs_t *ffuncs, * * Sets the implementation function for #hb_font_paint_glyph_or_fail_func_t. * - * XSince: REPLACEME + * Since: 11.2.0 */ HB_EXTERN void hb_font_funcs_set_paint_glyph_or_fail_func (hb_font_funcs_t *ffuncs, @@ -876,6 +967,26 @@ hb_font_get_glyph_v_origin (hb_font_t *font, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y); +HB_EXTERN hb_bool_t +hb_font_get_glyph_h_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride); + +HB_EXTERN hb_bool_t +hb_font_get_glyph_v_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride); + HB_EXTERN hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); diff --git a/thirdparty/harfbuzz/src/hb-font.hh b/thirdparty/harfbuzz/src/hb-font.hh index b64b19bc9fc..f7f67af3bdd 100644 --- a/thirdparty/harfbuzz/src/hb-font.hh +++ b/thirdparty/harfbuzz/src/hb-font.hh @@ -55,6 +55,8 @@ HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origins) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origins) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \ HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \ @@ -118,6 +120,8 @@ struct hb_font_t int32_t x_scale; int32_t y_scale; + bool is_synthetic; + float x_embolden; float y_embolden; bool embolden_in_place; @@ -139,6 +143,7 @@ struct hb_font_t /* Font variation coordinates. */ unsigned int instance_index; + bool has_nonzero_coords; unsigned int num_coords; int *coords; float *design_coords; @@ -430,21 +435,135 @@ struct hb_font_t } hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, - 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_h_origin (this, user_data, - glyph, x, y, - !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); + bool ret = klass->get.f.glyph_h_origin (this, user_data, + glyph, x, y, + !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); + + if (synthetic && ret) + { + /* Slant */ + if (slant_xy) + *x += roundf (*y * slant_xy); + + /* Embolden */ + if (!embolden_in_place) + { + *x += x_scale < 0 ? -x_strength : x_strength; + *y += y_scale < 0 ? -y_strength : y_strength; + } + } + + return ret; } hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, - 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_v_origin (this, user_data, - glyph, x, y, - !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); + bool ret = klass->get.f.glyph_v_origin (this, user_data, + glyph, x, y, + !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); + + if (synthetic && ret) + { + /* Slant */ + if (slant_xy) + *x += roundf (*y * slant_xy); + + /* Embolden */ + if (!embolden_in_place) + { + *x += x_scale < 0 ? -x_strength : x_strength; + *y += y_scale < 0 ? -y_strength : y_strength; + } + } + + return ret; + } + + hb_bool_t get_glyph_h_origins (unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride, + bool synthetic = true) + + { + bool ret = klass->get.f.glyph_h_origins (this, user_data, + count, + first_glyph, glyph_stride, + first_x, x_stride, first_y, y_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_h_origins); + + if (synthetic && ret) + { + hb_position_t x_shift = x_scale < 0 ? -x_strength : x_strength; + hb_position_t y_shift = y_scale < 0 ? -y_strength : y_strength; + for (unsigned i = 0; i < count; i++) + { + /* Slant */ + if (slant_xy) + *first_x += roundf (*first_y * slant_xy); + + /* Embolden */ + if (!embolden_in_place) + { + *first_x += x_shift; + *first_y += y_shift; + } + } + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + + return ret; + } + + hb_bool_t get_glyph_v_origins (unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride, + bool synthetic = true) + + { + bool ret = klass->get.f.glyph_v_origins (this, user_data, + count, + first_glyph, glyph_stride, + first_x, x_stride, first_y, y_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_v_origins); + + if (synthetic && is_synthetic && ret) + { + hb_position_t x_shift = x_scale < 0 ? -x_strength : x_strength; + hb_position_t y_shift = y_scale < 0 ? -y_strength : y_strength; + for (unsigned i = 0; i < count; i++) + { + /* Slant */ + if (slant_xy) + *first_x += roundf (*first_y * slant_xy); + + /* Embolden */ + if (!embolden_in_place) + { + *first_x += x_shift; + *first_y += y_shift; + } + } + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + + return ret; } hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, @@ -486,7 +605,7 @@ struct hb_font_t extents, !klass->user_data ? nullptr : klass->user_data->glyph_extents); } - if (!is_synthetic () && + if (!is_synthetic && klass->get.f.glyph_extents (this, user_data, glyph, extents, @@ -508,7 +627,7 @@ struct hb_font_t #endif #ifndef HB_NO_DRAW - hb_extents_t draw_extents; + hb_extents_t<> draw_extents; if (draw_glyph_or_fail (glyph, hb_draw_extents_get_funcs (), &draw_extents)) { @@ -714,6 +833,28 @@ struct hb_font_t get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); } + void apply_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy, + signed mult) + { + assert (mult == -1 || mult == +1); + + *x += dx * mult; + *y += dy * mult; + } + void add_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy) + { + *x += dx; + *y += dy; + } + void subtract_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy) + { + *x -= dx; + *y -= dy; + } + void guess_v_origin_minus_h_origin (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { @@ -724,6 +865,141 @@ struct hb_font_t *y = extents.ascender; } + void apply_glyph_h_origins_with_fallback (hb_buffer_t *buf, int mult) + { + bool has_ascender = false; + hb_position_t ascender = 0; + + struct { hb_position_t x, y; } origins[32]; + + unsigned int offset = 0; + unsigned int count = buf->len; + while (offset < count) + { + unsigned n = hb_min (count - offset, ARRAY_LENGTH (origins)); + if (!get_glyph_h_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (get_glyph_v_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (!has_ascender) + { + hb_font_extents_t extents; + get_h_extents_with_fallback (&extents); + ascender = extents.ascender; + has_ascender = true; + } + + /* We got the v_origins, adjust them to h_origins. */ + for (unsigned j = 0; j < n; j++) + { + hb_codepoint_t glyph = buf->info[offset + j].codepoint; + origins[j].x -= get_glyph_h_advance (glyph) / 2; + origins[j].y -= ascender; + } + } + else + { + for (unsigned j = 0; j < n; j++) + { + origins[j].x = 0; + origins[j].y = 0; + } + } + } + + assert (mult == -1 || mult == +1); + if (mult == +1) + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + add_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + else /* mult == -1 */ + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + subtract_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + + offset += n; + } + } + void apply_glyph_v_origins_with_fallback (hb_buffer_t *buf, int mult) + { + bool has_ascender = false; + hb_position_t ascender = 0; + + struct { hb_position_t x, y; } origins[32]; + + unsigned int offset = 0; + unsigned int count = buf->len; + while (offset < count) + { + unsigned n = hb_min (count - offset, ARRAY_LENGTH (origins)); + if (!get_glyph_v_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (get_glyph_h_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (!has_ascender) + { + hb_font_extents_t extents; + get_h_extents_with_fallback (&extents); + ascender = extents.ascender; + has_ascender = true; + } + + /* We got the h_origins, adjust them to v_origins. */ + for (unsigned j = 0; j < n; j++) + { + hb_codepoint_t glyph = buf->info[offset + j].codepoint; + origins[j].x += get_glyph_h_advance (glyph) / 2; + origins[j].y += ascender; + } + } + else + { + for (unsigned j = 0; j < n; j++) + { + origins[j].x = 0; + origins[j].y = 0; + } + } + } + + assert (mult == -1 || mult == +1); + if (mult == +1) + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + add_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + else /* mult == -1 */ + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + subtract_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + + offset += n; + } + } + void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { @@ -732,7 +1008,7 @@ struct hb_font_t { hb_position_t dx, dy; guess_v_origin_minus_h_origin (glyph, &dx, &dy); - *x -= dx; *y -= dy; + subtract_offset (x, y, dx, dy); } } void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph, @@ -743,7 +1019,7 @@ struct hb_font_t { hb_position_t dx, dy; guess_v_origin_minus_h_origin (glyph, &dx, &dy); - *x += dx; *y += dy; + add_offset (x, y, dx, dy); } } @@ -757,68 +1033,38 @@ struct hb_font_t get_glyph_v_origin_with_fallback (glyph, x, y); } - void add_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void add_glyph_h_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + apply_glyph_h_origins_with_fallback (buf, +1); } - void add_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void add_glyph_v_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + apply_glyph_v_origins_with_fallback (buf, +1); } void add_glyph_origin_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) { hb_position_t origin_x, origin_y; - get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + add_offset (x, y, origin_x, origin_y); } - void subtract_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void subtract_glyph_h_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + apply_glyph_h_origins_with_fallback (buf, -1); } - void subtract_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void subtract_glyph_v_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + apply_glyph_v_origins_with_fallback (buf, -1); } void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) { hb_position_t origin_x, origin_y; - get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + subtract_offset (x, y, origin_x, origin_y); } void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, @@ -900,11 +1146,6 @@ struct hb_font_t return false; } - bool is_synthetic () const - { - return x_embolden || y_embolden || slant; - } - void changed () { float upem = face->get_upem (); @@ -916,6 +1157,8 @@ 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; + is_synthetic = x_embolden || y_embolden || slant; + x_strength = roundf (abs (x_scale) * x_embolden); y_strength = roundf (abs (y_scale) * y_embolden); diff --git a/thirdparty/harfbuzz/src/hb-ft-colr.hh b/thirdparty/harfbuzz/src/hb-ft-colr.hh index cb9e4985442..d7a3611696c 100644 --- a/thirdparty/harfbuzz/src/hb-ft-colr.hh +++ b/thirdparty/harfbuzz/src/hb-ft-colr.hh @@ -90,7 +90,7 @@ struct hb_ft_paint_context_t funcs (paint_funcs), data (paint_data), palette (palette), palette_index (palette_index), foreground (foreground) { - if (font->is_synthetic ()) + if (font->is_synthetic) { font = hb_font_create_sub_font (font); hb_font_set_synthetic_bold (font, 0, 0, true); @@ -412,9 +412,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, float dx = paint.u.translate.dx / 65536.f; float dy = paint.u.translate.dy / 65536.f; - bool p1 = c->funcs->push_translate (c->data, dx, dy); + c->funcs->push_translate (c->data, dx, dy); c->recurse (paint.u.translate.paint); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_SCALE: @@ -424,13 +424,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, float sx = paint.u.scale.scale_x / 65536.f; float sy = paint.u.scale.scale_y / 65536.f; - bool p1 = c->funcs->push_translate (c->data, +dx, +dy); - bool p2 = c->funcs->push_scale (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -dx, -dy); + c->funcs->push_scale_around_center (c->data, sx, sy, dx, dy); c->recurse (paint.u.scale.paint); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_ROTATE: @@ -439,13 +435,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, float dy = paint.u.rotate.center_y / 65536.f; float a = paint.u.rotate.angle / 65536.f; - bool p1 = c->funcs->push_translate (c->data, +dx, +dy); - bool p2 = c->funcs->push_rotate (c->data, a); - bool p3 = c->funcs->push_translate (c->data, -dx, -dy); + c->funcs->push_rotate_around_center (c->data, a, dx, dy); c->recurse (paint.u.rotate.paint); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_SKEW: @@ -455,13 +447,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, float sx = paint.u.skew.x_skew_angle / 65536.f; float sy = paint.u.skew.y_skew_angle / 65536.f; - bool p1 = c->funcs->push_translate (c->data, +dx, +dy); - bool p2 = c->funcs->push_skew (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -dx, -dy); + c->funcs->push_skew_around_center (c->data, sx, sy, dx, dy); c->recurse (paint.u.skew.paint); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_COMPOSITE: diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index 9287118594d..971f5078ee5 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -143,6 +143,9 @@ _hb_ft_font_destroy (void *data) /* hb_font changed, update FT_Face. */ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) { + if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) + return; + hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; float x_mult = 1.f, y_mult = 1.f; @@ -184,12 +187,14 @@ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) FT_Set_Transform (ft_face, &matrix, nullptr); ft_font->transform = true; } + else + FT_Set_Transform (ft_face, nullptr, nullptr); #if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) - unsigned int num_coords; - const float *coords = hb_font_get_var_coords_design (font, &num_coords); - if (num_coords) + if (font->has_nonzero_coords) { + unsigned int num_coords; + const float *coords = hb_font_get_var_coords_design (font, &num_coords); FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); if (ft_coords) { @@ -199,6 +204,12 @@ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) hb_free (ft_coords); } } + else if (font->num_coords) + { + // Some old versions of FreeType crash if we + // call this function on non-variable fonts. + FT_Set_Var_Design_Coordinates (ft_face, 0, nullptr); + } #endif } @@ -1093,6 +1104,10 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data FT_ULong length = 0; FT_Error error; + /* In new FreeType, a tag value of 1 loads the SFNT table directory. Reject it. */ + if (tag == 1) + return nullptr; + /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */ error = FT_Load_Sfnt_Table (ft_face, tag, 0, nullptr, &length); @@ -1366,7 +1381,7 @@ hb_ft_font_changed (hb_font_t *font) for (unsigned int i = 0; i < mm_var->num_axis; ++i) { - coords[i] = ft_coords[i] >>= 2; + coords[i] = (ft_coords[i] + 2) >> 2; nonzero = nonzero || coords[i]; } @@ -1717,7 +1732,12 @@ hb_ft_font_set_funcs (hb_font_t *font) ft_face->generic.finalizer = _release_blob; // And the FT_Library to the blob - hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true); + if (unlikely (!hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true))) + { + DEBUG_MSG (FT, font, "hb_blob_set_user_data() failed"); + FT_Done_Face (ft_face); + return; + } _hb_ft_font_set_funcs (font, ft_face, true); hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); diff --git a/thirdparty/harfbuzz/src/hb-geometry.hh b/thirdparty/harfbuzz/src/hb-geometry.hh index c22a26a404a..60f4e692c0d 100644 --- a/thirdparty/harfbuzz/src/hb-geometry.hh +++ b/thirdparty/harfbuzz/src/hb-geometry.hh @@ -26,7 +26,10 @@ #include "hb.hh" +#include "hb-algs.hh" + +template struct hb_extents_t { hb_extents_t () {} @@ -35,7 +38,7 @@ struct hb_extents_t 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) : + hb_extents_t (Float xmin, Float ymin, Float xmax, Float ymax) : xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} bool is_empty () const { return xmin >= xmax || ymin >= ymax; } @@ -69,7 +72,7 @@ struct hb_extents_t } void - add_point (float x, float y) + add_point (Float x, Float y) { if (unlikely (is_void ())) { @@ -97,62 +100,69 @@ struct hb_extents_t yneg ? y1 - y0 : y0 - y1}; } - float xmin = 0.f; - float ymin = 0.f; - float xmax = -1.f; - float ymax = -1.f; + Float xmin = 0; + Float ymin = 0; + Float xmax = -1; + Float ymax = -1; }; +template struct hb_transform_t { hb_transform_t () {} - hb_transform_t (float xx, float yx, - float xy, float yy, - float x0, float y0) : + hb_transform_t (Float xx, Float yx, + Float xy, Float yy, + Float x0, Float y0) : xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {} bool is_identity () const { - return xx == 1.f && yx == 0.f && - xy == 0.f && yy == 1.f && - x0 == 0.f && y0 == 0.f; + return xx == 1 && yx == 0 && + xy == 0 && yy == 1 && + x0 == 0 && y0 == 0; + } + bool is_translation () const + { + return xx == 1 && yx == 0 && + xy == 0 && yy == 1; } - void multiply (const hb_transform_t &o) + void multiply (const hb_transform_t &o, bool before=false) { - /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */ - hb_transform_t r; - - r.xx = o.xx * xx + o.yx * xy; - r.yx = o.xx * yx + o.yx * yy; - - r.xy = o.xy * xx + o.yy * xy; - r.yy = o.xy * yx + o.yy * yy; - - r.x0 = o.x0 * xx + o.y0 * xy + x0; - r.y0 = o.x0 * yx + o.y0 * yy + y0; - - *this = r; + // Copied from cairo-matrix.c + const hb_transform_t &a = before ? o : *this; + const hb_transform_t &b = before ? *this : o; + *this = { + a.xx * b.xx + a.xy * b.yx, + a.yx * b.xx + a.yy * b.yx, + a.xx * b.xy + a.xy * b.yy, + a.yx * b.xy + a.yy * b.yy, + a.xx * b.x0 + a.xy * b.y0 + a.x0, + a.yx * b.x0 + a.yy * b.y0 + a.y0 + }; } - void transform_distance (float &dx, float &dy) const + HB_ALWAYS_INLINE + void transform_distance (Float &dx, Float &dy) const { - float new_x = xx * dx + xy * dy; - float new_y = yx * dx + yy * dy; + Float new_x = xx * dx + xy * dy; + Float new_y = yx * dx + yy * dy; dx = new_x; dy = new_y; } - void transform_point (float &x, float &y) const + HB_ALWAYS_INLINE + void transform_point (Float &x, Float &y) const { - transform_distance (x, y); - x += x0; - y += y0; + Float new_x = x0 + xx * x + xy * y; + Float new_y = y0 + yx * x + yy * y; + x = new_x; + y = new_y; } - void transform_extents (hb_extents_t &extents) const + void transform_extents (hb_extents_t &extents) const { - float quad_x[4], quad_y[4]; + Float quad_x[4], quad_y[4]; quad_x[0] = extents.xmin; quad_y[0] = extents.ymin; @@ -163,7 +173,7 @@ struct hb_transform_t quad_x[3] = extents.xmax; quad_y[3] = extents.ymax; - extents = hb_extents_t {}; + extents = hb_extents_t {}; for (unsigned i = 0; i < 4; i++) { transform_point (quad_x[i], quad_y[i]); @@ -171,20 +181,36 @@ struct hb_transform_t } } - void transform (const hb_transform_t &o) { multiply (o); } + void transform (const hb_transform_t &o, bool before=false) { multiply (o, before); } - void translate (float x, float y) + static hb_transform_t translation (Float x, Float y) { - if (x == 0.f && y == 0.f) - return; + return {1, 0, 0, 1, x, y}; + } + void translate (Float x, Float y, bool before=false) + { + if (before) + { + x0 += x; + y0 += y; + } + else + { + if (x == 0 && y == 0) + return; - x0 += xx * x + xy * y; - y0 += yx * x + yy * y; + x0 += xx * x + xy * y; + y0 += yx * x + yy * y; + } } - void scale (float scaleX, float scaleY) + static hb_transform_t scaling (Float scaleX, Float scaleY) { - if (scaleX == 1.f && scaleY == 1.f) + return {scaleX, 0, 0, scaleY, 0, 0}; + } + void scale (Float scaleX, Float scaleY) + { + if (scaleX == 1 && scaleY == 1) return; xx *= scaleX; @@ -192,52 +218,94 @@ struct hb_transform_t xy *= scaleY; yy *= scaleY; } - - void rotate (float rotation) + static hb_transform_t scaling_around_center (Float scaleX, Float scaleY, Float center_x, Float center_y) { - if (rotation == 0.f) + return {scaleX, 0, 0, scaleY, + center_x ? (1 - scaleX) * center_x : 0, + center_y ? (1 - scaleY) * center_y : 0}; + } + void scale_around_center (Float scaleX, Float scaleY, Float center_x, Float center_y) + { + if (scaleX == 1 && scaleY == 1) return; + transform (scaling_around_center (scaleX, scaleY, center_x, center_y)); + } + + static hb_transform_t rotation (Float radians) + { // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 - rotation = rotation * HB_PI; - float c; - float s; -#ifdef HAVE_SINCOSF - sincosf (rotation, &s, &c); -#else - c = cosf (rotation); - s = sinf (rotation); -#endif - auto other = hb_transform_t{c, s, -s, c, 0.f, 0.f}; - transform (other); + Float c; + Float s; + hb_sincos (radians, s, c); + return {c, s, -s, c, 0, 0}; } - - void skew (float skewX, float skewY) + void rotate (Float radians, bool before=false) { - if (skewX == 0.f && skewY == 0.f) + if (radians == 0) return; - // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 - skewX = skewX * HB_PI; - skewY = skewY * HB_PI; - auto other = hb_transform_t{1.f, - skewY ? tanf (skewY) : 0.f, - skewX ? tanf (skewX) : 0.f, - 1.f, - 0.f, 0.f}; - transform (other); + transform (rotation (radians), before); } - float xx = 1.f; - float yx = 0.f; - float xy = 0.f; - float yy = 1.f; - float x0 = 0.f; - float y0 = 0.f; + static hb_transform_t rotation_around_center (Float radians, Float center_x, Float center_y) + { + Float s, c; + hb_sincos (radians, s, c); + return { + c, s, -s, c, + (1 - c) * center_x + s * center_y, + -s * center_x + (1 - c) * center_y + }; + } + void rotate_around_center (Float radians, Float center_x, Float center_y, bool before=false) + { + if (radians == 0) + return; + + transform (rotation_around_center (radians, center_x, center_y), before); + } + + static hb_transform_t skewing (Float skewX, Float skewY) + { + return {1, skewY ? tanf (skewY) : 0, skewX ? tanf (skewX) : 0, 1, 0, 0}; + } + void skew (Float skewX, Float skewY) + { + if (skewX == 0 && skewY == 0) + return; + + transform (skewing (skewX, skewY)); + } + static hb_transform_t skewing_around_center (Float skewX, Float skewY, Float center_x, Float center_y) + { + skewX = skewX ? tanf (skewX) : 0; + skewY = skewY ? tanf (skewY) : 0; + return { + 1, skewY, skewX, 1, + center_y ? -skewX * center_y : 0, + center_x ? -skewY * center_x : 0 + }; + } + void skew_around_center (Float skewX, Float skewY, Float center_x, Float center_y) + { + if (skewX == 0 && skewY == 0) + return; + + transform (skewing_around_center (skewX, skewY, center_x, center_y)); + } + + Float xx = 1; + Float yx = 0; + Float xy = 0; + Float yy = 1; + Float x0 = 0; + Float y0 = 0; }; -#define HB_TRANSFORM_IDENTITY hb_transform_t{1.f, 0.f, 0.f, 1.f, 0.f, 0.f} +#define HB_TRANSFORM_IDENTITY {1, 0, 0, 1, 0, 0} +template struct hb_bounds_t { enum status_t { @@ -247,7 +315,7 @@ struct hb_bounds_t }; hb_bounds_t (status_t status = UNBOUNDED) : status (status) {} - hb_bounds_t (const hb_extents_t &extents) : + hb_bounds_t (const hb_extents_t &extents) : status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} void union_ (const hb_bounds_t &o) @@ -281,20 +349,21 @@ struct hb_bounds_t } status_t status; - hb_extents_t extents; + hb_extents_t extents; }; +template struct hb_transform_decomposed_t { - float translateX = 0; - float translateY = 0; - float rotation = 0; // in degrees, counter-clockwise - float scaleX = 1; - float scaleY = 1; - float skewX = 0; // in degrees, counter-clockwise - float skewY = 0; // in degrees, counter-clockwise - float tCenterX = 0; - float tCenterY = 0; + Float translateX = 0; + Float translateY = 0; + Float rotation = 0; // in radians, counter-clockwise + Float scaleX = 1; + Float scaleY = 1; + Float skewX = 0; // in radians, counter-clockwise + Float skewY = 0; // in radians, counter-clockwise + Float tCenterX = 0; + Float tCenterY = 0; operator bool () const { @@ -305,9 +374,9 @@ struct hb_transform_decomposed_t tCenterX || tCenterY; } - hb_transform_t to_transform () const + hb_transform_t to_transform () const { - hb_transform_t t; + hb_transform_t t; t.translate (translateX + tCenterX, translateY + tCenterY); t.rotate (rotation); t.scale (scaleX, scaleY); diff --git a/thirdparty/harfbuzz/src/hb-glib.cc b/thirdparty/harfbuzz/src/hb-glib.cc index 1da81696e75..a85cb365d7f 100644 --- a/thirdparty/harfbuzz/src/hb-glib.cc +++ b/thirdparty/harfbuzz/src/hb-glib.cc @@ -127,11 +127,7 @@ hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t *ab, void *user_data HB_UNUSED) { -#if GLIB_CHECK_VERSION(2,29,12) return g_unichar_compose (a, b, ab); -#else - return false; -#endif } static hb_bool_t @@ -141,11 +137,7 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t *b, void *user_data HB_UNUSED) { -#if GLIB_CHECK_VERSION(2,29,12) return g_unichar_decompose (ab, a, b); -#else - return false; -#endif } diff --git a/thirdparty/harfbuzz/src/hb-gobject-structs.cc b/thirdparty/harfbuzz/src/hb-gobject-structs.cc index d66de0b237f..60670b862b6 100644 --- a/thirdparty/harfbuzz/src/hb-gobject-structs.cc +++ b/thirdparty/harfbuzz/src/hb-gobject-structs.cc @@ -51,12 +51,6 @@ /* g++ didn't like older gtype.h gcc-only code path. */ #include -#if !GLIB_CHECK_VERSION(2,29,16) -#undef __GNUC__ -#undef __GNUC_MINOR__ -#define __GNUC__ 2 -#define __GNUC_MINOR__ 6 -#endif #include "hb-gobject.h" diff --git a/thirdparty/harfbuzz/src/hb-machinery.hh b/thirdparty/harfbuzz/src/hb-machinery.hh index 4b76f91c7aa..4916765e8fd 100644 --- a/thirdparty/harfbuzz/src/hb-machinery.hh +++ b/thirdparty/harfbuzz/src/hb-machinery.hh @@ -66,13 +66,15 @@ static inline Type& StructAtOffsetUnaligned(void *P, unsigned int offset) } /* StructAfter(X) returns the struct T& that is placed after X. - * Works with X of variable size also. X must implement get_size() */ -template -static inline const Type& StructAfter(const TObject &X) -{ return StructAtOffset(&X, X.get_size()); } -template -static inline Type& StructAfter(TObject &X) -{ return StructAtOffset(&X, X.get_size()); } + * Works with X of variable size also. X must implement get_size(). + * Any extra arguments are forwarded to get_size, so for example + * it can work with UnsizedArrayOf<> as well. */ +template +static inline const Type& StructAfter(const TObject &X, Ts... args) +{ return StructAtOffset(&X, X.get_size(args...)); } +template +static inline Type& StructAfter(TObject &X, Ts... args) +{ return StructAtOffset(&X, X.get_size(args...)); } /* @@ -132,7 +134,6 @@ static inline Type& StructAfter(TObject &X) DEFINE_SIZE_ARRAY(size, array) - /* * Lazy loaders. * diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index f2040ea5c9c..08b0fe86c72 100644 --- a/thirdparty/harfbuzz/src/hb-open-type.hh +++ b/thirdparty/harfbuzz/src/hb-open-type.hh @@ -54,35 +54,40 @@ namespace OT { */ /* Integer types in big-endian order and no alignment requirement */ -template -struct IntType +struct NumType { typedef Type type; - - IntType () = default; - explicit constexpr IntType (Type V) : v {V} {} - IntType& operator = (Type i) { v = i; return *this; } /* For reason we define cast out operator for signed/unsigned, instead of Type, see: * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */ - operator typename std::conditional::value, signed, unsigned>::type () const { return v; } + typedef typename std::conditional::value, + typename std::conditional::value, signed, unsigned>::type, + Type>::type WideType; - bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } - bool operator != (const IntType &o) const { return !(*this == o); } + NumType () = default; + explicit constexpr NumType (Type V) : v {V} {} + NumType& operator = (Type V) { v = V; return *this; } - IntType& operator += (unsigned count) { *this = *this + count; return *this; } - IntType& operator -= (unsigned count) { *this = *this - count; return *this; } - IntType& operator ++ () { *this += 1; return *this; } - IntType& operator -- () { *this -= 1; return *this; } - IntType operator ++ (int) { IntType c (*this); ++*this; return c; } - IntType operator -- (int) { IntType c (*this); --*this; return c; } + operator WideType () const { return v; } - HB_INTERNAL static int cmp (const IntType *a, const IntType *b) + bool operator == (const NumType &o) const { return (Type) v == (Type) o.v; } + bool operator != (const NumType &o) const { return !(*this == o); } + + NumType& operator += (WideType count) { *this = *this + count; return *this; } + NumType& operator -= (WideType count) { *this = *this - count; return *this; } + NumType& operator ++ () { *this += 1; return *this; } + NumType& operator -- () { *this -= 1; return *this; } + NumType operator ++ (int) { NumType c (*this); ++*this; return c; } + NumType operator -- (int) { NumType c (*this); --*this; return c; } + + HB_INTERNAL static int cmp (const NumType *a, const NumType *b) { return b->cmp (*a); } HB_INTERNAL static int cmp (const void *a, const void *b) { - IntType *pa = (IntType *) a; - IntType *pb = (IntType *) b; + NumType *pa = (NumType *) a; + NumType *pb = (NumType *) b; return pb->cmp (*pa); } @@ -99,20 +104,32 @@ struct IntType return_trace (c->check_struct (this)); } protected: - BEInt v; + typename std::conditional::value, + HBInt, + HBFloat>::type v; public: DEFINE_SIZE_STATIC (Size); }; -typedef IntType HBUINT8; /* 8-bit unsigned integer. */ -typedef IntType HBINT8; /* 8-bit signed integer. */ -typedef IntType HBUINT16; /* 16-bit unsigned integer. */ -typedef IntType HBINT16; /* 16-bit signed integer. */ -typedef IntType HBUINT32; /* 32-bit unsigned integer. */ -typedef IntType HBINT32; /* 32-bit signed integer. */ +typedef NumType HBUINT8; /* 8-bit big-endian unsigned integer. */ +typedef NumType HBINT8; /* 8-bit big-endian signed integer. */ +typedef NumType HBUINT16; /* 16-bit big-endian unsigned integer. */ +typedef NumType HBINT16; /* 16-bit big-endian signed integer. */ +typedef NumType HBUINT32; /* 32-bit big-endian unsigned integer. */ +typedef NumType HBINT32; /* 32-bit big-endian signed integer. */ /* Note: we cannot defined a signed HBINT24 because there's no corresponding C type. * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ -typedef IntType HBUINT24; /* 24-bit unsigned integer. */ +typedef NumType HBUINT24; /* 24-bit big-endian unsigned integer. */ + +typedef NumType HBUINT16LE; /* 16-bit little-endian unsigned integer. */ +typedef NumType HBINT16LE; /* 16-bit little-endian signed integer. */ +typedef NumType HBUINT32LE; /* 32-bit little-endian unsigned integer. */ +typedef NumType HBINT32LE; /* 32-bit little-endian signed integer. */ + +typedef NumType HBFLOAT32BE; /* 32-bit little-endian floating point number. */ +typedef NumType HBFLOAT64BE; /* 64-bit little-endian floating point number. */ +typedef NumType HBFLOAT32LE; /* 32-bit little-endian floating point number. */ +typedef NumType HBFLOAT64LE; /* 64-bit little-endian floating point number. */ /* 15-bit unsigned number; top bit used for extension. */ struct HBUINT15 : HBUINT16 @@ -218,7 +235,7 @@ typedef HBUINT16 UFWORD; template struct HBFixed : Type { - static constexpr float shift = (float) (1 << fraction_bits); + static constexpr float mult = 1.f / (1 << fraction_bits); static_assert (Type::static_size * 8 > fraction_bits, ""); operator signed () const = delete; @@ -226,8 +243,8 @@ struct HBFixed : Type explicit operator float () const { return to_float (); } typename Type::type to_int () const { return Type::v; } void set_int (typename Type::type i ) { Type::v = i; } - float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; } - void set_float (float f) { Type::v = roundf (f * shift); } + float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) * mult; } + void set_float (float f) { Type::v = roundf (f / mult); } public: DEFINE_SIZE_STATIC (Type::static_size); }; @@ -1707,7 +1724,8 @@ struct TupleValues static bool decompile (const HBUINT8 *&p /* IN/OUT */, hb_vector_t &values /* IN/OUT */, const HBUINT8 *end, - bool consume_all = false) + bool consume_all = false, + unsigned start = 0) { unsigned i = 0; unsigned count = consume_all ? UINT_MAX : values.length; @@ -1725,6 +1743,10 @@ struct TupleValues } unsigned stop = i + run_count; if (unlikely (stop > count)) return false; + + unsigned skip = i < start ? hb_min (start - i, run_count) : 0; + i += skip; + if ((control & VALUES_SIZE_MASK) == VALUES_ARE_ZEROS) { for (; i < stop; i++) @@ -1733,6 +1755,7 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_WORDS) { if (unlikely (p + run_count * HBINT16::static_size > end)) return false; + p += skip * HBINT16::static_size; #ifndef HB_OPTIMIZE_SIZE for (; i + 3 < stop; i += 4) { @@ -1755,6 +1778,7 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_LONGS) { if (unlikely (p + run_count * HBINT32::static_size > end)) return false; + p += skip * HBINT32::static_size; for (; i < stop; i++) { values.arrayZ[i] = * (const HBINT32 *) p; @@ -1764,6 +1788,7 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_BYTES) { if (unlikely (p + run_count > end)) return false; + p += skip * HBINT8::static_size; #ifndef HB_OPTIMIZE_SIZE for (; i + 3 < stop; i += 4) { @@ -2038,6 +2063,23 @@ struct TupleList : CFF2Index }; +// Alignment + +template +struct Align +{ + unsigned get_size (const void *base) const + { + unsigned offset = (const char *) this - (const char *) base; + return (alignment - offset) & (alignment - 1); + } + + public: + DEFINE_SIZE_MIN (0); +}; + + + } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/hb-ot-cff2-table.cc b/thirdparty/harfbuzz/src/hb-ot-cff2-table.cc index 4157bd3b569..bec1397ed56 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff2-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-cff2-table.cc @@ -202,7 +202,11 @@ struct cff2_cs_opset_path_t : cff2_cs_opset_tcoords, font->num_coords)); + return get_path_at (font, + glyph, + draw_session, + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); } bool OT::cff2::accelerator_t::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/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh index 564ef41a96b..294b2b60d2d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh @@ -501,10 +501,6 @@ struct CmapSubtableFormat4 this->length = c->length () - table_initpos; if ((long long) this->length != (long long) c->length () - table_initpos) { - // Length overflowed. Discard the current object before setting the error condition, otherwise - // discard is a noop which prevents the higher level code from reverting the serializer to the - // pre-error state in cmap4 overflow handling code. - c->pop_discard (); c->err (HB_SERIALIZE_ERROR_INT_OVERFLOW); return; } @@ -1646,7 +1642,7 @@ struct EncodingRecord CmapSubtable *cmapsubtable = c->push (); unsigned origin_length = c->length (); cmapsubtable->serialize (c, it, format, plan, &(base+subtable)); - if (c->length () - origin_length > 0) *objidx = c->pop_pack (); + if (c->length () - origin_length > 0 && !c->in_error()) *objidx = c->pop_pack (); else c->pop_discard (); } diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index 2785f626a7c..e1a0c1d2fe6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -37,6 +37,7 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-var-gvar-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-hmtx-table.hh" @@ -64,18 +65,22 @@ using hb_ot_font_advance_cache_t = hb_cache_t<24, 16>; static_assert (sizeof (hb_ot_font_advance_cache_t) == 1024, ""); +using hb_ot_font_origin_cache_t = hb_cache_t<20, 20>; +static_assert (sizeof (hb_ot_font_origin_cache_t) == 1024, ""); + struct hb_ot_font_t { const hb_ot_face_t *ot_face; - /* h_advance caching */ + mutable hb_atomic_t cached_serial; mutable hb_atomic_t cached_coords_serial; - struct advance_cache_t + + struct direction_cache_t { mutable hb_atomic_t advance_cache; - mutable hb_atomic_t varStore_cache; + mutable hb_atomic_t varStore_cache; - ~advance_cache_t () + ~direction_cache_t () { clear (); } @@ -116,7 +121,7 @@ struct hb_ot_font_t goto retry; } - OT::ItemVariationStore::cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const + OT::hb_scalar_cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const { retry: auto *cache = varStore_cache.get_acquire (); @@ -127,7 +132,7 @@ struct hb_ot_font_t else goto retry; } - void release_varStore_cache (OT::ItemVariationStore::cache_t *cache) const + void release_varStore_cache (OT::hb_scalar_cache_t *cache) const { if (!cache) return; @@ -154,17 +159,157 @@ struct hb_ot_font_t } h, v; + struct origin_cache_t + { + mutable hb_atomic_t origin_cache; + mutable hb_atomic_t varStore_cache; + + ~origin_cache_t () + { + clear (); + } + + hb_ot_font_origin_cache_t *acquire_origin_cache () const + { + retry: + auto *cache = origin_cache.get_acquire (); + if (!cache) + { + cache = (hb_ot_font_origin_cache_t *) hb_malloc (sizeof (hb_ot_font_origin_cache_t)); + if (!cache) + return nullptr; + new (cache) hb_ot_font_origin_cache_t; + return cache; + } + if (origin_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_origin_cache (hb_ot_font_origin_cache_t *cache) const + { + if (!cache) + return; + if (!origin_cache.cmpexch (nullptr, cache)) + hb_free (cache); + } + void clear_origin_cache () const + { + retry: + auto *cache = origin_cache.get_acquire (); + if (!cache) + return; + if (origin_cache.cmpexch (cache, nullptr)) + hb_free (cache); + else + goto retry; + } + + OT::hb_scalar_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::hb_scalar_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_origin_cache (); + clear_varStore_cache (); + } + } v_origin; + + struct draw_cache_t + { + mutable hb_atomic_t gvar_cache; + + ~draw_cache_t () + { + clear (); + } + + OT::hb_scalar_cache_t *acquire_gvar_cache (const OT::gvar_accelerator_t &gvar) const + { + retry: + auto *cache = gvar_cache.get_acquire (); + if (!cache) + return gvar.create_cache (); + if (gvar_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_gvar_cache (OT::hb_scalar_cache_t *cache) const + { + if (!cache) + return; + if (!gvar_cache.cmpexch (nullptr, cache)) + OT::gvar_accelerator_t::destroy_cache (cache); + } + void clear_gvar_cache () const + { + retry: + auto *cache = gvar_cache.get_acquire (); + if (!cache) + return; + if (gvar_cache.cmpexch (cache, nullptr)) + OT::gvar_accelerator_t::destroy_cache (cache); + else + goto retry; + } + + void clear () const + { + clear_gvar_cache (); + } + } draw; + void check_serial (hb_font_t *font) const { int font_serial = font->serial_coords.get_acquire (); + if (cached_serial.get_acquire () != font_serial) + { + /* These caches are dependent on scale and synthetic settings. + * Any change to the font invalidates them. */ + v_origin.clear (); - if (cached_coords_serial.get_acquire () == font_serial) - return; + cached_serial.set_release (font_serial); + } - h.clear (); - v.clear (); + int font_serial_coords = font->serial_coords.get_acquire (); + if (cached_coords_serial.get_acquire () != font_serial_coords) + { + /* These caches are independent of scale or synthetic settings. + * Just variation changes will invalidate them. */ + h.clear (); + v.clear (); + draw.clear (); - cached_coords_serial.set_release (font_serial); + cached_coords_serial.set_release (font_serial_coords); + } } }; @@ -242,37 +387,59 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { + // Duplicated in v_advances. Ugly. Keep in sync'ish. 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; - 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 = ot_font->h.acquire_varStore_cache (varStore); - - hb_ot_font_advance_cache_t *advance_cache = nullptr; - - bool use_cache = font->num_coords; - if (use_cache) - { - advance_cache = ot_font->h.acquire_advance_cache (); - if (!advance_cache) - use_cache = false; - } - - if (!use_cache) + if (unlikely (!hmtx.has_data ())) { + hb_position_t advance = font->face->get_upem () / 2; + advance = font->em_scale_x (advance); for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); + *first_advance = advance; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + return; + } + +#ifndef HB_NO_VAR + if (!font->has_nonzero_coords) + { + fallback: +#else + { +#endif + // Just plain htmx data. No need to cache. + for (unsigned int i = 0; i < count; i++) + { + *first_advance = font->em_scale_x (hmtx.get_advance_without_var_unscaled (*first_glyph)); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + return; } - else - { /* Use cache. */ + +#ifndef HB_NO_VAR + /* has_nonzero_coords. */ + + ot_font->check_serial (font); + hb_ot_font_advance_cache_t *advance_cache = ot_font->h.acquire_advance_cache (); + if (!advance_cache) + { + // malloc failure. Just use the fallback non-variable path. + goto fallback; + } + + /* If HVAR is present, use it.*/ + const OT::HVAR &HVAR = *hmtx.var_table; + if (HVAR.has_data ()) + { + const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; + OT::hb_scalar_cache_t *varStore_cache = ot_font->h.acquire_varStore_cache (varStore); + for (unsigned int i = 0; i < count; i++) { hb_position_t v; @@ -289,10 +456,44 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + ot_font->h.release_varStore_cache (varStore_cache); ot_font->h.release_advance_cache (advance_cache); + return; } - ot_font->h.release_varStore_cache (varStore_cache); + const auto &gvar = *ot_face->gvar; + if (gvar.has_data ()) + { + const auto &glyf = *ot_face->glyf; + auto *scratch = glyf.acquire_scratch (); + OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); + + for (unsigned int i = 0; i < count; i++) + { + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = glyf.get_advance_with_var_unscaled (*first_glyph, font, false, *scratch, gvar_cache); + 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); + } + + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->h.release_advance_cache (advance_cache); + return; + } + + ot_font->h.release_advance_cache (advance_cache); + // No HVAR or GVAR. Just use the fallback non-variable path. + goto fallback; +#endif } #ifndef HB_NO_VERTICAL @@ -305,99 +506,281 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { + // Duplicated from h_advances. Ugly. Keep in sync'ish. + 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::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - if (vmtx.has_data ()) + if (unlikely (!vmtx.has_data ())) + { + hb_font_extents_t font_extents; + font->get_h_extents_with_fallback (&font_extents); + hb_position_t advance = font_extents.ascender - font_extents.descender; + advance = font->em_scale_y (- (int) advance); + for (unsigned int i = 0; i < count; i++) + { + *first_advance = advance; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + return; + } + +#ifndef HB_NO_VAR + if (!font->has_nonzero_coords) + { + fallback: +#else + { +#endif + // Just plain vtmx data. No need to cache. + for (unsigned int i = 0; i < count; i++) + { + *first_advance = font->em_scale_y (- (int) vmtx.get_advance_without_var_unscaled (*first_glyph)); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + return; + } + +#ifndef HB_NO_VAR + /* has_nonzero_coords. */ + + ot_font->check_serial (font); + hb_ot_font_advance_cache_t *advance_cache = ot_font->v.acquire_advance_cache (); + if (!advance_cache) + { + // malloc failure. Just use the fallback non-variable path. + goto fallback; + } + + /* If VVAR is present, use it.*/ + const OT::VVAR &VVAR = *vmtx.var_table; + if (VVAR.has_data ()) { - 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 = ot_font->v.acquire_varStore_cache (varStore); - // TODO Use advance_cache. + OT::hb_scalar_cache_t *varStore_cache = ot_font->v.acquire_varStore_cache (varStore); for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_y (- (int) v); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } ot_font->v.release_varStore_cache (varStore_cache); + ot_font->v.release_advance_cache (advance_cache); + return; } - else + + const auto &gvar = *ot_face->gvar; + if (gvar.has_data ()) { - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - hb_position_t advance = -(font_extents.ascender - font_extents.descender); + const auto &glyf = *ot_face->glyf; + auto *scratch = glyf.acquire_scratch (); + OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); for (unsigned int i = 0; i < count; i++) { - *first_advance = advance; + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = glyf.get_advance_with_var_unscaled (*first_glyph, font, true, *scratch, gvar_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_y (- (int) v); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->v.release_advance_cache (advance_cache); + return; } + + ot_font->v.release_advance_cache (advance_cache); + // No VVAR or GVAR. Just use the fallback non-variable path. + goto fallback; +#endif } #endif #ifndef HB_NO_VERTICAL +HB_HOT static hb_bool_t -hb_ot_get_glyph_v_origin (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_ot_get_glyph_v_origins (hb_font_t *font, + void *font_data, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_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; - *x = font->get_glyph_h_advance (glyph) / 2; - - const OT::VORG &VORG = *ot_face->VORG; - if (VORG.has_data ()) + /* First, set all the x values to half the advance width. */ + font->get_glyph_h_advances (count, + first_glyph, glyph_stride, + first_x, x_stride); + for (unsigned i = 0; i < count; i++) { - float delta = 0; + *first_x /= 2; + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + } + /* The vertical origin business is messy... + * + * We allocate the cache, then have various code paths that use the cache. + * Each one is responsible to free it before returning. + */ + hb_ot_font_origin_cache_t *origin_cache = ot_font->v_origin.acquire_origin_cache (); + + /* If there is VORG, always use it. It uses VVAR for variations if necessary. */ + const OT::VORG &VORG = *ot_face->VORG; + if (origin_cache && VORG.has_data ()) + { #ifndef HB_NO_VAR - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - const OT::VVAR &VVAR = *vmtx.var_table; - if (font->num_coords) - VVAR.get_vorg_delta_unscaled (glyph, - font->coords, font->num_coords, - &delta); + if (!font->has_nonzero_coords) #endif + { + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -cv : cv; + else + { + origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } - *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta); + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } +#ifndef HB_NO_VAR + else + { + const OT::VVAR &VVAR = *ot_face->vmtx->var_table; + const auto &varStore = &VVAR + VVAR.varStore; + auto *varStore_cache = ot_font->v_origin.acquire_varStore_cache (varStore); + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -cv : cv; + else + { + origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph) + + VVAR.get_vorg_delta_unscaled (*first_glyph, + font->coords, font->num_coords, + varStore_cache)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + ot_font->v_origin.release_varStore_cache (varStore_cache); + } +#endif + ot_font->v_origin.release_origin_cache (origin_cache); return true; } - hb_glyph_extents_t extents = {0}; - - if (hb_font_get_glyph_extents (font, glyph, &extents)) + /* If and only if `vmtx` is present and it's a `glyf` font, + * we use the top phantom point, deduced from vmtx,glyf[,gvar]. */ + const auto &vmtx = *ot_face->vmtx; + const auto &glyf = *ot_face->glyf; + if (origin_cache && vmtx.has_data() && glyf.has_data ()) { - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - int tsb = 0; - if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb)) + auto *scratch = glyf.acquire_scratch (); + OT::hb_scalar_cache_t *gvar_cache = font->has_nonzero_coords ? + ot_font->draw.acquire_gvar_cache (*ot_face->gvar) : + nullptr; + + for (unsigned i = 0; i < count; i++) { - *y = extents.y_bearing + font->em_scale_y (tsb); - return true; + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -cv : cv; + else + { + origin = font->em_scalef_y (glyf.get_v_origin_with_var_unscaled (*first_glyph, font, *scratch, gvar_cache)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); } - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - hb_position_t advance = font_extents.ascender - font_extents.descender; - hb_position_t diff = advance - -extents.height; - *y = extents.y_bearing + (diff >> 1); + if (gvar_cache) + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->v_origin.release_origin_cache (origin_cache); return true; } - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - *y = font_extents.ascender; + /* Otherwise, use glyph extents to center the glyph vertically. + * If getting glyph extents failed, just use the font ascender. */ + if (origin_cache && font->has_glyph_extents_func ()) + { + hb_font_extents_t font_extents; + font->get_h_extents_with_fallback (&font_extents); + hb_position_t font_advance = font_extents.ascender - font_extents.descender; + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -cv : cv; + else + { + hb_glyph_extents_t extents = {0}; + if (likely (font->get_glyph_extents (*first_glyph, &extents))) + origin = extents.y_bearing + ((font_advance - -extents.height) >> 1); + else + origin = font_extents.ascender; + + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + + ot_font->v_origin.release_origin_cache (origin_cache); return true; } #endif @@ -498,17 +881,33 @@ hb_ot_draw_glyph_or_fail (hb_font_t *font, hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data) { + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; hb_draw_session_t draw_session {draw_funcs, draw_data}; + bool ret = false; + + OT::hb_scalar_cache_t *gvar_cache = nullptr; + if (font->num_coords) + { + ot_font->check_serial (font); + gvar_cache = ot_font->draw.acquire_gvar_cache (*ot_font->ot_face->gvar); + } + #ifndef HB_NO_VAR_COMPOSITES - if (font->face->table.VARC->get_path (font, glyph, draw_session)) return true; + if (font->face->table.VARC->get_path (font, glyph, draw_session)) { ret = true; goto done; } #endif // Keep the following in synch with VARC::get_path_at() - if (font->face->table.glyf->get_path (font, glyph, draw_session)) return true; + if (font->face->table.glyf->get_path (font, glyph, draw_session, gvar_cache)) { ret = true; goto done; } + #ifndef HB_NO_CFF - 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; + if (font->face->table.cff2->get_path (font, glyph, draw_session)) { ret = true; goto done; } + if (font->face->table.cff1->get_path (font, glyph, draw_session)) { ret = true; goto done; } #endif - return false; + +done: + + ot_font->draw.release_gvar_cache (gvar_cache); + + return ret; } #endif @@ -548,12 +947,11 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_tplan->new_to_old_gid_list) - | hb_map ([c, &_mtx, mtx_map] (hb_codepoint_pair_t _) + | hb_map ([&_mtx, mtx_map] (hb_codepoint_pair_t _) { hb_codepoint_t new_gid = _.first; hb_codepoint_t old_gid = _.second; @@ -246,8 +236,7 @@ struct hmtxvmtx if (!mtx_map->has (new_gid, &v)) { int lsb = 0; - if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) - (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb); + _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); } return *v; @@ -326,49 +315,23 @@ struct hmtxvmtx bool has_data () const { return (bool) num_bearings; } - bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, + void get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, int *lsb) const { if (glyph < num_long_metrics) { *lsb = table->longMetricZ[glyph].sb; - return true; + return; } if (unlikely (glyph >= num_bearings)) - return false; + { + *lsb = 0; + return; + } const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; *lsb = bearings[glyph - num_long_metrics]; - return true; - } - - bool get_leading_bearing_with_var_unscaled (hb_font_t *font, - hb_codepoint_t glyph, - int *lsb) const - { - if (!font->num_coords) - return get_leading_bearing_without_var_unscaled (glyph, lsb); - -#ifndef HB_NO_VAR - float delta; - if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) && - get_leading_bearing_without_var_unscaled (glyph, lsb)) - { - *lsb += roundf (delta); - return true; - } - - // If there's no vmtx data, the phantom points from glyf table are not accurate, - // so we cannot take the next path. - bool is_vertical = T::tableTag == HB_OT_TAG_vmtx; - if (is_vertical && !has_data ()) - return false; - - return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); -#else - return false; -#endif } unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const @@ -402,27 +365,17 @@ struct hmtxvmtx return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)]; } - unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, - hb_font_t *font, - ItemVariationStore::cache_t *store_cache = nullptr) const +#ifndef HB_NO_VAR + unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, + hb_font_t *font, + hb_scalar_cache_t *store_cache = nullptr) const { unsigned int advance = get_advance_without_var_unscaled (glyph); - -#ifndef HB_NO_VAR - if (unlikely (glyph >= num_bearings) || !font->num_coords) - return advance; - - if (var_table.get_length ()) - return advance + roundf (var_table->get_advance_delta_unscaled (glyph, - font->coords, font->num_coords, - store_cache)); - - unsigned glyf_advance = _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); - return glyf_advance ? glyf_advance : advance; -#else - return advance; -#endif + return advance + roundf (var_table->get_advance_delta_unscaled (glyph, + font->coords, font->num_coords, + store_cache)); } +#endif protected: // 0 <= num_long_metrics <= num_bearings <= num_advances <= num_glyphs diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 085bc3c5cfd..06c3c0ee976 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -2548,32 +2548,94 @@ struct SparseVarRegionAxis DEFINE_SIZE_STATIC (8); }; -#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 hb_scalar_cache_t +{ + private: + static constexpr unsigned STATIC_LENGTH = 16; + static constexpr int INVALID = INT_MIN; + static constexpr float MULTIPLIER = 1 << ((sizeof (int) * 8) - 2); + static constexpr float DIVISOR = 1.f / MULTIPLIER; + + public: + hb_scalar_cache_t () : length (STATIC_LENGTH) { clear (); } + + hb_scalar_cache_t (const hb_scalar_cache_t&) = delete; + hb_scalar_cache_t (hb_scalar_cache_t&&) = delete; + hb_scalar_cache_t& operator= (const hb_scalar_cache_t&) = delete; + hb_scalar_cache_t& operator= (hb_scalar_cache_t&&) = delete; + + static hb_scalar_cache_t *create (unsigned int count, + hb_scalar_cache_t *scratch_cache = nullptr) + { + if (!count) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); + + if (scratch_cache && count <= scratch_cache->length) + { + scratch_cache->clear (); + return scratch_cache; + } + + auto *cache = (hb_scalar_cache_t *) hb_malloc (sizeof (hb_scalar_cache_t) - sizeof (values) + sizeof (values[0]) * count); + if (unlikely (!cache)) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); + + cache->length = count; + cache->clear (); + + return cache; + } + + static void destroy (hb_scalar_cache_t *cache, + hb_scalar_cache_t *scratch_cache = nullptr) + { + if (cache != &Null(hb_scalar_cache_t) && cache != scratch_cache) + hb_free (cache); + } + + void clear () + { + for (unsigned i = 0; i < length; i++) + values[i] = INVALID; + } + + HB_ALWAYS_INLINE + bool get (unsigned i, float *value) const + { + if (unlikely (i >= length)) + { + *value = 0.f; + return true; + } + auto *cached_value = &values[i]; + if (*cached_value != INVALID) + { + *value = *cached_value ? *cached_value * DIVISOR : 0.f; + return true; + } + return false; + } + + HB_ALWAYS_INLINE + void set (unsigned i, float value) + { + if (unlikely (i >= length)) return; + auto *cached_value = &values[i]; + *cached_value = roundf(value * MULTIPLIER); + } + + private: + unsigned length; + mutable hb_atomic_t values[STATIC_LENGTH]; +}; struct VarRegionList { - using cache_t = hb_atomic_t; - - float evaluate (unsigned int region_index, - const int *coords, unsigned int coord_len, - cache_t *cache = nullptr) const + private: + float evaluate_impl (unsigned int region_index, + const int *coords, unsigned int coord_len) const { - if (unlikely (region_index >= regionCount)) - return 0.; - - cache_t *cached_value = nullptr; - if (cache) - { - cached_value = &(cache[region_index]); - if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) - return *cached_value * REGION_CACHE_ITEM_DIVISOR; - } - const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); + float v = 1.f; - float v = 1.; unsigned int count = axisCount; for (unsigned int i = 0; i < count; i++) { @@ -2581,15 +2643,32 @@ struct VarRegionList float factor = axes[i].evaluate (coord); if (factor == 0.f) { - if (cache) - *cached_value = 0.; - return 0.; + v = 0.f; + break; } v *= factor; } + return v; + } + + public: + HB_ALWAYS_INLINE + float evaluate (unsigned int region_index, + const int *coords, unsigned int coord_len, + hb_scalar_cache_t *cache = nullptr) const + { + if (unlikely (region_index >= regionCount)) + return 0.; + + float v; + if (cache && cache->get (region_index, &v)) + return v; + + v = evaluate_impl (region_index, coords, coord_len); + if (cache) - *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; + cache->set (region_index, v); return v; } @@ -2732,29 +2811,24 @@ struct SparseVariationRegion : Array16Of struct SparseVarRegionList { - using cache_t = hb_atomic_t; - + HB_ALWAYS_INLINE float evaluate (unsigned int region_index, const int *coords, unsigned int coord_len, - cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { if (unlikely (region_index >= regions.len)) return 0.; - cache_t *cached_value = nullptr; - if (cache) - { - cached_value = &(cache[region_index]); - if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) - return *cached_value * REGION_CACHE_ITEM_DIVISOR; - } + float v; + if (cache && cache->get (region_index, &v)) + return v; const SparseVariationRegion ®ion = this+regions[region_index]; - float v = region.evaluate (coords, coord_len); - + v = region.evaluate (coords, coord_len); if (cache) - *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; + cache->set (region_index, v); + return v; } @@ -2792,46 +2866,62 @@ struct VarData + itemCount * get_row_size (); } - float get_delta (unsigned int inner, - const int *coords, unsigned int coord_count, - const VarRegionList ®ions, - VarRegionList::cache_t *cache = nullptr) const + float _get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const VarRegionList ®ions, + hb_scalar_cache_t *cache = nullptr) const { if (unlikely (inner >= itemCount)) return 0.; + bool is_long = longWords (); + unsigned int count = regionIndices.len; + unsigned word_count = wordCount (); + unsigned int scount = is_long ? count : word_count; + unsigned int lcount = is_long ? word_count : 0; - unsigned int count = regionIndices.len; - bool is_long = longWords (); - unsigned word_count = wordCount (); - unsigned int scount = is_long ? count : word_count; - unsigned int lcount = is_long ? word_count : 0; + const HBUINT8 *bytes = get_delta_bytes (); + const HBUINT8 *row = bytes + inner * get_row_size (); - const HBUINT8 *bytes = get_delta_bytes (); - const HBUINT8 *row = bytes + inner * get_row_size (); + float delta = 0.; + unsigned int i = 0; - float delta = 0.; - unsigned int i = 0; + const HBINT32 *lcursor = reinterpret_cast (row); + for (; i < lcount; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *lcursor; + lcursor++; + } + const HBINT16 *scursor = reinterpret_cast (lcursor); + for (; i < scount; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *scursor; + scursor++; + } + const HBINT8 *bcursor = reinterpret_cast (scursor); + for (; i < count; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *bcursor; + bcursor++; + } - const HBINT32 *lcursor = reinterpret_cast (row); - for (; i < lcount; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *lcursor++; - } - const HBINT16 *scursor = reinterpret_cast (lcursor); - for (; i < scount; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *scursor++; - } - const HBINT8 *bcursor = reinterpret_cast (scursor); - for (; i < count; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *bcursor++; - } + return delta; + } - return delta; + HB_ALWAYS_INLINE + float get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const VarRegionList ®ions, + hb_scalar_cache_t *cache = nullptr) const + { + unsigned int count = regionIndices.len; + if (!count) return 0.f; // This is quite common, so optimize it. + return _get_delta (inner, coords, coord_count, regions, cache); } void get_region_scalars (const int *coords, unsigned int coord_count, @@ -2869,7 +2959,7 @@ struct VarData return false; } - if (unlikely (!c->extend_min (this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); itemCount = row_count; int min_threshold = has_long ? -65536 : -128; @@ -3150,7 +3240,7 @@ struct MultiVarData const int *coords, unsigned int coord_count, const SparseVarRegionList ®ions, hb_array_t out, - SparseVarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { auto &deltaSets = StructAfter (regionIndices); @@ -3187,31 +3277,24 @@ struct MultiVarData struct ItemVariationStore { friend struct item_variations_t; - using cache_t = VarRegionList::cache_t; - cache_t *create_cache () const + hb_scalar_cache_t *create_cache () const { #ifdef HB_NO_VAR - return nullptr; + return hb_scalar_cache_t::create (0); #endif - unsigned count = (this+regions).regionCount; - if (!count) return nullptr; - - cache_t *cache = (cache_t *) hb_malloc (sizeof (float) * count); - if (unlikely (!cache)) return nullptr; - - for (unsigned i = 0; i < count; i++) - cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; - - return cache; + return hb_scalar_cache_t::create ((this+regions).regionCount); } - static void destroy_cache (cache_t *cache) { hb_free (cache); } + static void destroy_cache (hb_scalar_cache_t *cache) + { + hb_scalar_cache_t::destroy (cache); + } private: float get_delta (unsigned int outer, unsigned int inner, const int *coords, unsigned int coord_count, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { #ifdef HB_NO_VAR return 0.f; @@ -3229,7 +3312,7 @@ struct ItemVariationStore public: float get_delta (unsigned int index, const int *coords, unsigned int coord_count, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; @@ -3237,7 +3320,7 @@ struct ItemVariationStore } float get_delta (unsigned int index, hb_array_t coords, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { return get_delta (index, coords.arrayZ, coords.length, @@ -3445,43 +3528,28 @@ struct ItemVariationStore struct MultiItemVariationStore { - using cache_t = SparseVarRegionList::cache_t; - - cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const + hb_scalar_cache_t *create_cache (hb_scalar_cache_t *static_cache = nullptr) const { #ifdef HB_NO_VAR - return nullptr; + return hb_scalar_cache_t::create (0); #endif auto &r = this+regions; unsigned count = r.regions.len; - cache_t *cache; - if (count <= static_cache.length) - cache = static_cache.arrayZ; - else - { - cache = (cache_t *) hb_malloc (sizeof (float) * count); - if (unlikely (!cache)) return nullptr; - } - - for (unsigned i = 0; i < count; i++) - cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; - - return cache; + return hb_scalar_cache_t::create (count, static_cache); } - static void destroy_cache (cache_t *cache, - hb_array_t static_cache = hb_array_t ()) + static void destroy_cache (hb_scalar_cache_t *cache, + hb_scalar_cache_t *static_cache = nullptr) { - if (cache != static_cache.arrayZ) - hb_free (cache); + hb_scalar_cache_t::destroy (cache, static_cache); } private: void get_delta (unsigned int outer, unsigned int inner, const int *coords, unsigned int coord_count, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { #ifdef HB_NO_VAR return; @@ -3501,7 +3569,7 @@ struct MultiItemVariationStore void get_delta (unsigned int index, const int *coords, unsigned int coord_count, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; @@ -3510,7 +3578,7 @@ struct MultiItemVariationStore void get_delta (unsigned int index, hb_array_t coords, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { return get_delta (index, coords.arrayZ, coords.length, @@ -3540,8 +3608,6 @@ struct MultiItemVariationStore DEFINE_SIZE_ARRAY_SIZED (8, dataSets); }; -#undef REGION_CACHE_ITEM_CACHE_INVALID - template struct DeltaSetIndexMapFormat01 { @@ -3592,13 +3658,19 @@ struct DeltaSetIndexMapFormat01 return_trace (true); } + HB_ALWAYS_INLINE uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ { /* If count is zero, pass value unchanged. This takes * care of direct mapping for advance map. */ if (!mapCount) return v; + return _map (v); + } + HB_HOT + uint32_t _map (unsigned int v) const /* Returns 16.16 outer.inner. */ + { if (v >= mapCount) v = mapCount - 1; @@ -3736,7 +3808,7 @@ struct ItemVarStoreInstancer ItemVarStoreInstancer (const ItemVariationStore *varStore_, const DeltaSetIndexMap *varIdxMap, hb_array_t coords, - VarRegionList::cache_t *cache = nullptr) : + hb_scalar_cache_t *cache = nullptr) : varStore (varStore_), varIdxMap (varIdxMap), coords (coords), cache (cache) { if (!varStore) @@ -3762,7 +3834,7 @@ struct ItemVarStoreInstancer const ItemVariationStore *varStore; const DeltaSetIndexMap *varIdxMap; hb_array_t coords; - VarRegionList::cache_t *cache; + hb_scalar_cache_t *cache; }; struct MultiItemVarStoreInstancer @@ -3770,7 +3842,7 @@ struct MultiItemVarStoreInstancer MultiItemVarStoreInstancer (const MultiItemVariationStore *varStore, const DeltaSetIndexMap *varIdxMap, hb_array_t coords, - SparseVarRegionList::cache_t *cache = nullptr) : + hb_scalar_cache_t *cache = nullptr) : varStore (varStore), varIdxMap (varIdxMap), coords (coords), cache (cache) { if (!varStore) @@ -3803,7 +3875,7 @@ struct MultiItemVarStoreInstancer const MultiItemVariationStore *varStore; const DeltaSetIndexMap *varIdxMap; hb_array_t coords; - SparseVarRegionList::cache_t *cache; + hb_scalar_cache_t *cache; }; @@ -4783,13 +4855,13 @@ struct VariationDevice hb_position_t get_x_delta (hb_font_t *font, const ItemVariationStore &store, - ItemVariationStore::cache_t *store_cache = nullptr) const - { return !font->num_coords ? 0 : font->em_scalef_x (get_delta (font, store, store_cache)); } + hb_scalar_cache_t *store_cache = nullptr) const + { return !font->has_nonzero_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->num_coords ? 0 : font->em_scalef_y (get_delta (font, store, store_cache)); } + hb_scalar_cache_t *store_cache = nullptr) const + { return !font->has_nonzero_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 @@ -4823,9 +4895,9 @@ struct VariationDevice float get_delta (hb_font_t *font, const ItemVariationStore &store, - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords, (ItemVariationStore::cache_t *) store_cache); + return store.get_delta (varIdx, font->coords, font->num_coords, store_cache); } protected: @@ -4850,7 +4922,7 @@ struct Device { hb_position_t get_x_delta (hb_font_t *font, const ItemVariationStore &store=Null (ItemVariationStore), - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4868,7 +4940,7 @@ struct Device } hb_position_t get_y_delta (hb_font_t *font, const ItemVariationStore &store=Null (ItemVariationStore), - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4954,6 +5026,18 @@ struct Device } } + bool is_variation_device () const + { + switch (u.b.format) { +#ifndef HB_NO_VAR + case 0x8000: + return true; +#endif + default: + return false; + } + } + protected: union { DeviceHeader b; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index 433be1f33f8..83325548ded 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -700,7 +700,7 @@ struct hb_ot_apply_context_t : const GDEF::accelerator_t &gdef_accel; const hb_ot_layout_lookup_accelerator_t *lookup_accel = nullptr; const ItemVariationStore &var_store; - ItemVariationStore::cache_t *var_store_cache; + hb_scalar_cache_t *var_store_cache; hb_set_digest_t digest; hb_direction_t direction; @@ -723,7 +723,7 @@ struct hb_ot_apply_context_t : hb_font_t *font_, hb_buffer_t *buffer_, hb_blob_t *table_blob_, - ItemVariationStore::cache_t *var_store_cache_ = nullptr) : + hb_scalar_cache_t *var_store_cache_ = nullptr) : table_index (table_index_), font (font_), face (font->face), buffer (buffer_), sanitizer (table_blob_), diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index 83e8a5d747f..51572ce4b03 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -343,7 +343,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, * @face: The #hb_face_t to work on * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first attachment point to retrieve - * @point_count: (inout) (optional): Input = the maximum number of attachment points to return; + * @point_count: (inout) (nullable): Input = the maximum number of attachment points to return; * Output = the actual number of attachment points returned (may be zero) * @point_array: (out) (array length=point_count): The array of attachment points found for the query * @@ -373,7 +373,7 @@ hb_ot_layout_get_attach_points (hb_face_t *face, * @direction: The #hb_direction_t text direction to use * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first caret position to retrieve - * @caret_count: (inout) (optional): Input = the maximum number of caret positions to return; + * @caret_count: (inout) (nullable): Input = the maximum number of caret positions to return; * Output = the actual number of caret positions returned (may be zero) * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query * @@ -444,7 +444,7 @@ get_gsubgpos_table (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first script tag to retrieve - * @script_count: (inout) (optional): Input = the maximum number of script tags to return; + * @script_count: (inout) (nullable): Input = the maximum number of script tags to return; * Output = the actual number of script tags returned (may be zero) * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query * @@ -541,8 +541,8 @@ hb_ot_layout_table_choose_script (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_count: Number of script tags in the array * @script_tags: Array of #hb_tag_t script tags - * @script_index: (out) (optional): The index of the requested script - * @chosen_script: (out) (optional): #hb_tag_t of the requested script + * @script_index: (out) (nullable): The index of the requested script + * @chosen_script: (out) (nullable): #hb_tag_t of the requested script * * Selects an OpenType script for @table_tag from the @script_tags array. * @@ -613,7 +613,7 @@ hb_ot_layout_table_select_script (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table * @@ -683,7 +683,7 @@ hb_ot_layout_table_find_feature (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @start_offset: offset of the first language tag to retrieve - * @language_count: (inout) (optional): Input = the maximum number of language tags to return; + * @language_count: (inout) (nullable): Input = the maximum number of language tags to return; * Output = the actual number of language tags returned (may be zero) * @language_tags: (out) (array length=language_count): Array of language tags found in the table * @@ -911,7 +911,7 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output: the actual number of feature tags returned (may be zero) * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query * @@ -947,7 +947,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query * @@ -1035,7 +1035,7 @@ hb_ot_layout_language_find_feature (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_index: The index of the requested feature * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (nullable): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query * @@ -1386,10 +1386,10 @@ hb_ot_layout_collect_lookups (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @lookup_index: The index of the feature lookup to query - * @glyphs_before: (out): Array of glyphs preceding the substitution range - * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup - * @glyphs_after: (out): Array of glyphs following the substitution range - * @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup + * @glyphs_before: (out) (nullable): Array of glyphs preceding the substitution range + * @glyphs_input: (out) (nullable): Array of input glyphs that would be substituted by the lookup + * @glyphs_after: (out) (nullable): Array of glyphs following the substitution range + * @glyphs_output: (out) (nullable): Array of glyphs that would be the substituted output of the lookup * * Fetches a list of all glyphs affected by the specified lookup in the * specified face's GSUB table or GPOS table. @@ -1473,7 +1473,7 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, * @feature_index: The index of the feature to query * @variations_index: The index of the feature variation to query * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (nullable): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query * @@ -1777,15 +1777,15 @@ hb_ot_layout_get_size_params (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. - * @label_id: (out) (optional): The ‘name’ table name ID that specifies a string - * for a user-interface label for this feature. (May be NULL.) - * @tooltip_id: (out) (optional): The ‘name’ table name ID that specifies a string + * @label_id: (out) (nullable): The ‘name’ table name ID that specifies a string + * for a user-interface label for this feature. + * @tooltip_id: (out) (nullable): The ‘name’ table name ID that specifies a string * that an application can use for tooltip text for this - * feature. (May be NULL.) - * @sample_id: (out) (optional): The ‘name’ table name ID that specifies sample text - * that illustrates the effect of this feature. (May be NULL.) - * @num_named_parameters: (out) (optional): Number of named parameters. (May be zero.) - * @first_param_id: (out) (optional): The first ‘name’ table name ID used to specify + * feature. + * @sample_id: (out) (nullable): The ‘name’ table name ID that specifies sample text + * that illustrates the effect of this feature. + * @num_named_parameters: (out) (nullable): Number of named parameters. + * @first_param_id: (out) (nullable): The first ‘name’ table name ID used to specify * strings for user-interface labels for the feature * parameters. (Must be zero if numParameters is zero.) * @@ -1852,7 +1852,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. * @start_offset: offset of the first character to retrieve - * @char_count: (inout) (optional): Input = the maximum number of characters to return; + * @char_count: (inout) (nullable): Input = the maximum number of characters to return; * Output = the actual number of characters returned (may be zero) * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. * The Unicode codepoints of the characters for which this feature provides @@ -2017,7 +2017,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, unsigned int i = 0; auto *font_data = font->data.ot.get (); - auto *var_store_cache = font_data == HB_SHAPER_DATA_SUCCEEDED ? nullptr : (OT::ItemVariationStore::cache_t *) font_data; + auto *var_store_cache = (OT::hb_scalar_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); @@ -2627,7 +2627,7 @@ struct hb_get_glyph_alternates_dispatch_t : * @lookup_index: index of the feature lookup to query. * @glyph: a glyph id. * @start_offset: starting offset. - * @alternate_count: (inout) (optional): Input = the maximum number of alternate glyphs to return; + * @alternate_count: (inout) (nullable): Input = the maximum number of alternate glyphs to return; * Output = the actual number of alternate glyphs returned (may be zero). * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer. * Alternate glyphs associated with the glyph id. diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index a2d2edee9cc..6ee0e2b7f9d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -44,6 +44,7 @@ #include "hb-ot-face.hh" #include "hb-set.hh" +#include "hb-unicode.hh" #include "hb-aat-layout.hh" #include "hb-ot-layout-gdef-table.hh" @@ -425,25 +426,20 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data) */ struct hb_ot_font_data_t { - OT::ItemVariationStore::cache_t unused; // Just for alignment + OT::hb_scalar_cache_t unused; // Just for alignment }; hb_ot_font_data_t * _hb_ot_shaper_font_data_create (hb_font_t *font) { - 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; + return (hb_ot_font_data_t *) var_store.create_cache (); } void _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); + OT::ItemVariationStore::destroy_cache ((OT::hb_scalar_cache_t *) data); } @@ -651,59 +647,6 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Substitute */ -#ifndef HB_NO_VERTICAL -static hb_codepoint_t -hb_vert_char_for (hb_codepoint_t u) -{ - switch (u >> 8) - { - case 0x20: switch (u) { - case 0x2013u: return 0xfe32u; // EN DASH - case 0x2014u: return 0xfe31u; // EM DASH - case 0x2025u: return 0xfe30u; // TWO DOT LEADER - case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS - } break; - case 0x30: switch (u) { - case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA - case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP - case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET - case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET - case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET - case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET - case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET - case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET - case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET - case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET - case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET - case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET - case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET - case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET - case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET - case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET - } break; - case 0xfe: switch (u) { - case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE - } break; - case 0xff: switch (u) { - case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK - case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS - case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS - case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA - case 0xff1au: return 0xfe13u; // FULLWIDTH COLON - case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON - case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK - case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET - case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET - case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE - case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET - case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET - } break; - } - - return u; -} -#endif - static inline void hb_ot_rotate_chars (const hb_ot_shape_context_t *c) { @@ -729,7 +672,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c) if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert) { for (unsigned int i = 0; i < count; i++) { - hb_codepoint_t codepoint = hb_vert_char_for (info[i].codepoint); + hb_codepoint_t codepoint = hb_unicode_funcs_t::vertical_char_for (info[i].codepoint); if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint))) info[i].codepoint = codepoint; } @@ -1054,23 +997,16 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) { c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]), &pos[0].x_advance, sizeof(pos[0])); - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->subtract_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->subtract_glyph_h_origins (c->buffer); } else { c->font->get_glyph_v_advances (count, &info[0].codepoint, sizeof(info[0]), &pos[0].y_advance, sizeof(pos[0])); - for (unsigned int i = 0; i < count; i++) - { - c->font->subtract_glyph_v_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); - } + // v_origin defaults to non-zero; apply even if only fallback is there. + c->font->subtract_glyph_v_origins (c->buffer); } if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); @@ -1079,10 +1015,6 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) static inline void hb_ot_position_plan (const hb_ot_shape_context_t *c) { - unsigned int count = c->buffer->len; - hb_glyph_info_t *info = c->buffer->info; - hb_glyph_position_t *pos = c->buffer->pos; - /* If the font has no GPOS and direction is forward, then when * zeroing mark widths, we shift the mark with it, such that the * mark is positioned hanging over the previous glyph. When @@ -1097,12 +1029,9 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->add_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->add_glyph_h_origins (c->buffer); hb_ot_layout_position_start (c->font, c->buffer); @@ -1139,12 +1068,9 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) hb_ot_zero_width_default_ignorables (c->buffer); hb_ot_layout_position_finish_offsets (c->font, c->buffer); - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->subtract_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->subtract_glyph_h_origins (c->buffer); if (c->plan->fallback_mark_positioning) _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer, diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc index d25a3f6f480..c5104c94890 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc @@ -654,7 +654,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, /* https://www.unicode.org/reports/tr53/ */ -static hb_codepoint_t +static const hb_codepoint_t modifier_combining_marks[] = { 0x0654u, /* ARABIC HAMZA ABOVE */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc index 6124a2114f8..6d293b5c489 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc @@ -163,7 +163,7 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) } -static enum thai_above_state_t +static const enum thai_above_state_t { /* Cluster above looks like: */ T0, /* ⣤ */ T1, /* ⣼ */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh index 9f9b5c6e5f6..eac7f5c0a09 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh @@ -101,8 +101,9 @@ #ifndef HB_OPTIMIZE_SIZE -static const uint8_t -hb_use_u8[3345] = +#include + +static const uint8_t hb_use_u8[3345]= { 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, @@ -315,8 +316,7 @@ hb_use_u8[3345] = J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; -static const uint16_t -hb_use_u16[856] = +static const uint16_t hb_use_u16[856]= { 0, 0, 1, 2, 0, 3, 0, 3, 0, 0, 4, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, @@ -374,22 +374,21 @@ hb_use_u16[856] = 163,163,163,163,163,163,163,130, }; -static inline unsigned -hb_use_b4 (const uint8_t* a, unsigned i) +static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline uint_fast8_t -hb_use_get_category (unsigned u) +static inline uint8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[2953+(((hb_use_u8[625+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + return u<921600 ? hb_use_u8[2953u+(((hb_use_u8[625u+(((hb_use_u16[((hb_use_u8[113u+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31))])<<3)+((u>>1>>3)&7)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : O; } #else -static const uint8_t -hb_use_u8[3657] = +#include + +static const uint8_t hb_use_u8[3657]= { 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, @@ -621,8 +620,7 @@ hb_use_u8[3657] = VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; -static const uint16_t -hb_use_u16[486] = +static const uint16_t hb_use_u16[486]= { 0, 0, 1, 2, 0, 3, 4, 5, 0, 6, 7, 0, 8, 0, 9, 10, 11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -657,15 +655,13 @@ hb_use_u16[486] = 130,130,163,163,163,130, }; -static inline unsigned -hb_use_b4 (const uint8_t* a, unsigned i) +static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline uint_fast8_t -hb_use_get_category (unsigned u) +static inline uint8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[3265+(((hb_use_u8[937+(((hb_use_u16[((hb_use_u8[369+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + return u<921600 ? hb_use_u8[3265u+(((hb_use_u8[937u+(((hb_use_u16[((hb_use_u8[369u+(((hb_use_u8[113u+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15))])<<3)+((u>>1>>3>>1)&7))])<<1)+((u>>1>>3)&1)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : O; } #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh index 3d4ebddd86c..f8a1c74e2b6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * - * File-Date: 2025-01-21 + * + * File-Date: 2025-03-10 */ #ifndef HB_OT_TAG_TABLE_HH diff --git a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh index 75ea338e2a8..880b081316b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh @@ -143,10 +143,13 @@ struct AxisValueMap struct SegmentMaps : Array16Of { - int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const + float map_float (float value, unsigned int from_offset = 0, unsigned int to_offset = 1) const { -#define fromCoord coords[from_offset].to_int () -#define toCoord coords[to_offset].to_int () +#define fromCoord coords[from_offset].to_float () +#define toCoord coords[to_offset].to_float () + + const auto *map = arrayZ; + /* The following special-cases are not part of OpenType, which requires * that at least -1, 0, and +1 must be mapped. But we include these as * part of a better error recovery scheme. */ @@ -155,47 +158,98 @@ struct SegmentMaps : Array16Of if (!len) return value; else /* len == 1*/ - return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; + return value - map[0].fromCoord + map[0].toCoord; } - if (value <= arrayZ[0].fromCoord) - return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; + // At least two mappings now. - unsigned int i; - unsigned int count = len - 1; - for (i = 1; i < count && value > arrayZ[i].fromCoord; i++) - ; + /* CoreText is wild... + * PingFangUI avar needs all this special-casing... + * So we implement an extended version of the spec here, + * which is more robust and more likely to be compatible with + * the wild. */ - if (value >= arrayZ[i].fromCoord) - return value - arrayZ[i].fromCoord + arrayZ[i].toCoord; + unsigned start = 0; + unsigned end = len; + if (map[start].fromCoord == -1 && map[start].toCoord == -1 && map[start+1].fromCoord == -1) + start++; + if (map[end-1].fromCoord == +1 && map[end-1].toCoord == +1 && map[end-2].fromCoord == +1) + end--; - if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord)) - return arrayZ[i-1].toCoord; + /* Look for exact match first, and do lots of special-casing. */ + unsigned i; + for (i = start; i < end; i++) + if (value == map[i].fromCoord) + break; + if (i < end) + { + // There's at least one exact match. See if there are more. + unsigned j = i; + for (; j + 1 < end; j++) + if (value != map[j + 1].fromCoord) + break; + + // [i,j] inclusive are all exact matches: + + // If there's only one, return it. This is the only spec-compliant case. + if (i == j) + return map[i].toCoord; + // If there's exactly three, return the middle one. + if (i + 2 == j) + return map[i + 1].toCoord; + + // Ignore the middle ones. Return the one mapping closer to 0. + if (value < 0) return map[j].toCoord; + if (value > 0) return map[i].toCoord; + + // Mapping 0? CoreText seems confused. It seems to prefer 0 here... + // So we'll just return the smallest one. lol + return fabsf (map[i].toCoord) < fabsf (map[j].toCoord) ? map[i].toCoord : map[j].toCoord; + + // Mapping 0? Return one not mapping to 0. + if (map[i].toCoord == 0) + return map[j].toCoord; + else + return map[i].toCoord; + } + + /* There's at least two and we're not an exact match. Prepare to lerp. */ + + // Find the segment we're in. + for (i = start; i < end; i++) + if (value < map[i].fromCoord) + break; + + if (i == 0) + { + // Value before all segments; Shift. + return value - map[0].fromCoord + map[0].toCoord; + } + if (i == end) + { + // Value after all segments; Shift. + return value - map[end - 1].fromCoord + map[end - 1].toCoord; + } + + // Actually interpolate. + auto &before = map[i-1]; + auto &after = map[i]; + float denom = after.fromCoord - before.fromCoord; // Can't be zero by now. + return before.toCoord + ((after.toCoord - before.toCoord) * (value - before.fromCoord)) / denom; - int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord; - return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) * - (value - arrayZ[i-1].fromCoord)) / denom); #undef toCoord #undef fromCoord } - int unmap (int value) const { return map (value, 1, 0); } + float unmap_float (float value) const { return map_float (value, 1, 0); } + + // TODO Kill this. Triple unmap_axis_range (const Triple& axis_range) const { - F2DOT14 val, unmapped_val; - - val.set_float (axis_range.minimum); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_min = unmapped_val.to_float (); - - val.set_float (axis_range.middle); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_middle = unmapped_val.to_float (); - - val.set_float (axis_range.maximum); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_max = unmapped_val.to_float (); + float unmapped_min = unmap_float (axis_range.minimum); + float unmapped_middle = unmap_float (axis_range.middle); + float unmapped_max = unmap_float (axis_range.maximum); return Triple{(double) unmapped_min, (double) unmapped_middle, (double) unmapped_max}; } @@ -203,6 +257,11 @@ struct SegmentMaps : Array16Of bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const { TRACE_SUBSET (this); + + /* This function cannot work on avar2 table (and currently doesn't). + * We should instead keep the design coords in the shape plan and use + * those. unmap_axis_range needs to be killed. */ + /* avar mapped normalized axis range*/ Triple *axis_range; if (!c->plan->axes_location.has (axis_tag, &axis_range)) @@ -304,14 +363,14 @@ struct avar return_trace (true); } - void map_coords (int *coords, unsigned int coords_length) const + void map_coords_16_16 (int *coords, unsigned int coords_length) const { unsigned int count = hb_min (coords_length, axisCount); const SegmentMaps *map = &firstAxisSegmentMaps; for (unsigned int i = 0; i < count; i++) { - coords[i] = map->map (coords[i]); + coords[i] = roundf (map->map_float (coords[i] / 65536.f) * 65536.f); map = &StructAfter (*map); } @@ -336,8 +395,8 @@ struct avar int v = coords[i]; uint32_t varidx = varidx_map.map (i); float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache); - v += roundf (delta); - v = hb_clamp (v, -(1<<14), +(1<<14)); + v += roundf (delta * 4); // 2.14 -> 16.16 + v = hb_clamp (v, -(1<<16), +(1<<16)); out.push (v); } for (unsigned i = 0; i < coords_length; i++) @@ -347,18 +406,6 @@ struct avar #endif } - void unmap_coords (int *coords, unsigned int coords_length) const - { - unsigned int count = hb_min (coords_length, axisCount); - - const SegmentMaps *map = &firstAxisSegmentMaps; - for (unsigned int i = 0; i < count; i++) - { - coords[i] = map->unmap (coords[i]); - map = &StructAfter (*map); - } - } - bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh index 8eec5195a34..722e8599a96 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh @@ -33,7 +33,6 @@ namespace OT { - /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ struct TupleVariationHeader { @@ -53,7 +52,7 @@ struct TupleVariationHeader { const F2DOT14 *peak_tuple = nullptr; if (has_peak ()) - peak_tuple = get_peak_tuple (axis_count).arrayZ; + peak_tuple = get_peak_tuple (axis_count); else { unsigned int index = get_index (); @@ -68,8 +67,8 @@ struct TupleVariationHeader if (has_interm) { - start_tuple = get_start_tuple (axis_count).arrayZ; - end_tuple = get_end_tuple (axis_count).arrayZ; + start_tuple = get_start_tuple (axis_count); + end_tuple = get_end_tuple (axis_count); } for (unsigned i = 0; i < axis_count; i++) @@ -98,60 +97,56 @@ struct TupleVariationHeader return true; } + HB_ALWAYS_INLINE double calculate_scalar (hb_array_t coords, unsigned int coord_count, const hb_array_t shared_tuples, - const hb_vector_t> *shared_tuple_active_idx = nullptr) const + hb_scalar_cache_t *shared_tuple_scalar_cache = nullptr) const { + unsigned tuple_index = tupleIndex; + const F2DOT14 *peak_tuple; - unsigned start_idx = 0; - unsigned end_idx = coord_count; - unsigned step = 1; + bool has_interm = tuple_index & TuppleIndex::IntermediateRegion; // Inlined for performance + if (unlikely (has_interm)) + shared_tuple_scalar_cache = nullptr; - if (has_peak ()) - peak_tuple = get_peak_tuple (coord_count).arrayZ; + if (unlikely (tuple_index & TuppleIndex::EmbeddedPeakTuple)) // Inlined for performance + { + peak_tuple = get_peak_tuple (coord_count); + shared_tuple_scalar_cache = nullptr; + } else { - unsigned int index = get_index (); + unsigned int index = tuple_index & TuppleIndex::TupleIndexMask; // Inlined for performance + + float scalar; + if (shared_tuple_scalar_cache && + shared_tuple_scalar_cache->get (index, &scalar)) + return (double) scalar; + if (unlikely ((index + 1) * coord_count > shared_tuples.length)) return 0.0; - peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ; + peak_tuple = shared_tuples.arrayZ + (coord_count * index); - if (shared_tuple_active_idx) - { - if (unlikely (index >= shared_tuple_active_idx->length)) - return 0.0; - auto _ = (*shared_tuple_active_idx).arrayZ[index]; - if (_.second != -1) - { - start_idx = _.first; - end_idx = _.second + 1; - step = _.second - _.first; - } - else if (_.first != -1) - { - start_idx = _.first; - end_idx = start_idx + 1; - } - } } const F2DOT14 *start_tuple = nullptr; const F2DOT14 *end_tuple = nullptr; - bool has_interm = has_intermediate (); + if (has_interm) { - start_tuple = get_start_tuple (coord_count).arrayZ; - end_tuple = get_end_tuple (coord_count).arrayZ; + start_tuple = get_start_tuple (coord_count); + end_tuple = get_end_tuple (coord_count); } double scalar = 1.0; - for (unsigned int i = start_idx; i < end_idx; i += step) + for (unsigned int i = 0; i < coord_count; i++) { int peak = peak_tuple[i].to_int (); if (!peak) continue; int v = coords[i]; + if (!v) { scalar = 0.0; break; } if (v == peak) continue; if (has_interm) @@ -160,16 +155,18 @@ struct TupleVariationHeader int end = end_tuple[i].to_int (); if (unlikely (start > peak || peak > end || (start < 0 && end > 0 && peak))) continue; - if (v < start || v > end) return 0.0; + if (v < start || v > end) { scalar = 0.0; break; } if (v < peak) { if (peak != start) scalar *= (double) (v - start) / (peak - start); } else { if (peak != end) scalar *= (double) (end - v) / (end - peak); } } - else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.0; + else if (v < hb_min (0, peak) || v > hb_max (0, peak)) { scalar = 0.0; break; } else scalar *= (double) v / peak; } + if (shared_tuple_scalar_cache) + shared_tuple_scalar_cache->set (get_index (), scalar); return scalar; } @@ -194,12 +191,14 @@ struct TupleVariationHeader hb_array_t get_all_tuples (unsigned axis_count) const { return StructAfter> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); } - hb_array_t get_peak_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (0, axis_count); } - hb_array_t get_start_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); } - hb_array_t get_end_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); } + const F2DOT14* get_all_tuples_base (unsigned axis_count) const + { return StructAfter> (tupleIndex).arrayZ; } + const F2DOT14* get_peak_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count); } + const F2DOT14* get_start_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count) + has_peak () * axis_count; } + const F2DOT14* get_end_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count) + has_peak () * axis_count + axis_count; } HBUINT16 varDataSize; /* The size in bytes of the serialized * data for this tuple variation table. */ @@ -1330,7 +1329,7 @@ struct TupleVariationData { var_data_bytes = var_data_bytes_; var_data = var_data_bytes_.as (); - index = 0; + tuples_left = var_data->tupleVarCount.get_count (); axis_count = axis_count_; current_tuple = &var_data->get_tuple_var_header (); data_offset = 0; @@ -1349,30 +1348,41 @@ struct TupleVariationData return true; } - bool is_valid () const + bool is_valid () { - return (index < var_data->tupleVarCount.get_count ()) && - var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) && - var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), - current_tuple->get_size (axis_count))); + if (unlikely (tuples_left <= 0)) + return false; + + current_tuple_size = TupleVariationHeader::min_size; + if (unlikely (!var_data_bytes.check_range (current_tuple, current_tuple_size))) + return false; + + current_tuple_size = current_tuple->get_size (axis_count); + if (unlikely (!var_data_bytes.check_range (current_tuple, current_tuple_size))) + return false; + + return true; } + HB_ALWAYS_INLINE bool move_to_next () { data_offset += current_tuple->get_data_size (); - current_tuple = ¤t_tuple->get_next (axis_count); - index++; + current_tuple = &StructAtOffset (current_tuple, current_tuple_size); + tuples_left--; return is_valid (); } + // TODO: Make it return (sanitized) hb_bytes_t const HBUINT8 *get_serialized_data () const { return &(table_base+var_data->data) + data_offset; } private: + signed tuples_left; const TupleVariationData *var_data; - unsigned int index; unsigned int axis_count; unsigned int data_offset; + unsigned int current_tuple_size; const void *table_base; public: @@ -1449,9 +1459,10 @@ struct TupleVariationData static bool decompile_deltas (const HBUINT8 *&p /* IN/OUT */, hb_vector_t &deltas /* IN/OUT */, const HBUINT8 *end, - bool consume_all = false) + bool consume_all = false, + unsigned start = 0) { - return TupleValues::decompile (p, deltas, end, consume_all); + return TupleValues::decompile (p, deltas, end, consume_all, start); } bool has_data () const { return tupleVarCount; } diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh index 2cd9afbb709..4b4410f9ba1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh @@ -78,7 +78,7 @@ struct InstanceRecord return false; if (!axes_location->has (*axis_tag)) continue; - + Triple axis_limit = axes_location->get (*axis_tag); if (!axis_coord_pinned_or_within_axis_range (coords, i, axis_limit)) return false; @@ -106,7 +106,7 @@ struct InstanceRecord { if (!axis_coord_pinned_or_within_axis_range (coords, i, *axis_limit)) return_trace (false); - + //skip pinned axis if (axis_limit->is_point ()) continue; @@ -179,7 +179,7 @@ struct AxisRecord hb_tag_t get_axis_tag () const { return axisTag; } - int normalize_axis_value (float v) const + float normalize_axis_value (float v) const { float min_value, default_value, max_value; get_coordinates (min_value, default_value, max_value); @@ -189,23 +189,9 @@ struct AxisRecord if (v == default_value) return 0; else if (v < default_value) - v = (v - default_value) / (default_value - min_value); + return (v - default_value) / (default_value - min_value); else - v = (v - default_value) / (max_value - default_value); - return roundf (v * 16384.f); - } - - float unnormalize_axis_value (int v) const - { - float min_value, default_value, max_value; - get_coordinates (min_value, default_value, max_value); - - if (v == 0) - return default_value; - else if (v < 0) - return v * (default_value - min_value) / 16384.f + default_value; - else - return v * (max_value - default_value) / 16384.f + default_value; + return (v - default_value) / (max_value - default_value); } hb_ot_name_id_t get_name_id () const { return axisNameID; } @@ -341,12 +327,9 @@ struct fvar return axes.lfind (tag, &i) && ((void) axes[i].get_axis_info (i, info), true); } - int normalize_axis_value (unsigned int axis_index, float v) const + float normalize_axis_value (unsigned int axis_index, float v) const { return get_axes ()[axis_index].normalize_axis_value (v); } - float unnormalize_axis_value (unsigned int axis_index, int v) const - { return get_axes ()[axis_index].unnormalize_axis_value (v); } - unsigned int get_instance_count () const { return instanceCount; } hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh index 8523683b974..f2b381b1e7b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh @@ -582,6 +582,17 @@ struct gvar_GVAR public: struct accelerator_t { + + hb_scalar_cache_t *create_cache () const + { + return hb_scalar_cache_t::create (table->sharedTupleCount); + } + + static void destroy_cache (hb_scalar_cache_t *cache) + { + hb_scalar_cache_t::destroy (cache); + } + bool has_data () const { return table->has_data (); } accelerator_t (hb_face_t *face) @@ -589,36 +600,6 @@ struct gvar_GVAR table = hb_sanitize_context_t ().reference_table (face); /* If sanitize failed, set glyphCount to 0. */ glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; - - /* 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; - unsigned axis_count = table->axisCount; - for (unsigned i = 0; i < count; i++) - { - hb_array_t tuple = shared_tuples.sub_array (axis_count * i, axis_count); - int idx1 = -1, idx2 = -1; - for (unsigned j = 0; j < axis_count; j++) - { - const F2DOT14 &peak = tuple.arrayZ[j]; - if (peak.to_int () != 0) - { - if (idx1 == -1) - idx1 = j; - else if (idx2 == -1) - idx2 = j; - else - { - idx1 = idx2 = -1; - break; - } - } - } - shared_tuple_active_idx.arrayZ[i] = {idx1, idx2}; - } } ~accelerator_t () { table.destroy (); } @@ -655,6 +636,7 @@ struct gvar_GVAR hb_array_t coords, const hb_array_t points, hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr, bool phantom_only = false) const { if (unlikely (glyph >= glyphCount)) return true; @@ -690,10 +672,12 @@ struct gvar_GVAR unsigned count = points.length; bool flush = false; + do { float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples, - &shared_tuple_active_idx); + gvar_cache); + if (scalar == 0.f) continue; const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); @@ -717,11 +701,12 @@ struct gvar_GVAR const hb_array_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); - unsigned int num_deltas = apply_to_all ? points.length : indices.length; + unsigned num_deltas = apply_to_all ? points.length : indices.length; + unsigned start_deltas = (phantom_only && num_deltas >= 4 ? num_deltas - 4 : 0); if (unlikely (!x_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end, false, start_deltas))) return false; if (unlikely (!y_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end, false, start_deltas))) return false; if (!apply_to_all) { @@ -884,7 +869,6 @@ struct gvar_GVAR private: hb_blob_ptr_t table; unsigned glyphCount; - hb_vector_t> shared_tuple_active_idx; }; protected: diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh index 33a4e1a40e6..d9437d832a8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh @@ -156,7 +156,7 @@ struct index_map_subset_plan_t unsigned outer = (*new_varidx) >> 16; unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer); outer_bit_count = hb_max (bit_count, outer_bit_count); - + unsigned inner = (*new_varidx) & 0xFFFF; bit_count = (inner == 0) ? 1 : hb_bit_storage (inner); inner_bit_count = hb_max (bit_count, inner_bit_count); @@ -284,6 +284,8 @@ struct HVARVVAR static constexpr hb_tag_t HVARTag = HB_OT_TAG_HVAR; static constexpr hb_tag_t VVARTag = HB_OT_TAG_VVAR; + bool has_data () const { return version.major != 0; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -382,9 +384,10 @@ struct HVARVVAR hvar_plan.index_map_plans.as_array ())); } + HB_ALWAYS_INLINE float get_advance_delta_unscaled (hb_codepoint_t glyph, const int *coords, unsigned int coord_count, - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, @@ -392,16 +395,6 @@ struct HVARVVAR store_cache); } - bool get_lsb_delta_unscaled (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count, - float *lsb) const - { - if (!lsbMap) return false; - uint32_t varidx = (this+lsbMap).map (glyph); - *lsb = (this+varStore).get_delta (varidx, coords, coord_count); - return true; - } - public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ @@ -454,14 +447,16 @@ struct VVAR : HVARVVAR { bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset (c); } - bool get_vorg_delta_unscaled (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count, - float *delta) const + HB_ALWAYS_INLINE + float get_vorg_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + hb_scalar_cache_t *store_cache = nullptr) const { - if (!vorgMap) return false; + if (!vorgMap) return 0.f; uint32_t varidx = (this+vorgMap).map (glyph); - *delta = (this+varStore).get_delta (varidx, coords, coord_count); - return true; + return (this+varStore).get_delta (varidx, + coords, coord_count, + store_cache); } protected: diff --git a/thirdparty/harfbuzz/src/hb-ot-var.cc b/thirdparty/harfbuzz/src/hb-ot-var.cc index 45424f79957..72ef9fbbd9d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var.cc +++ b/thirdparty/harfbuzz/src/hb-ot-var.cc @@ -70,7 +70,7 @@ hb_ot_var_has_data (hb_face_t *face) * hb_ot_var_get_axis_count: * @face: The #hb_face_t to work on * - * Fetches the number of OpenType variation axes included in the face. + * Fetches the number of OpenType variation axes included in the face. * * Return value: the number of variation axes defined * @@ -183,7 +183,7 @@ hb_ot_var_find_axis_info (hb_face_t *face, * hb_ot_var_get_named_instance_count: * @face: The #hb_face_t to work on * - * Fetches the number of named instances included in the face. + * Fetches the number of named instances included in the face. * * Return value: the number of named instances defined * @@ -263,7 +263,7 @@ hb_ot_var_named_instance_get_design_coords (hb_face_t *face, * @face: The #hb_face_t to work on * @variations: The array of variations to normalize * @variations_length: The number of variations to normalize - * @coords: (out) (array length=coords_length): The array of normalized coordinates + * @coords: (out) (array length=coords_length): The array of normalized coordinates * @coords_length: The length of the coordinate array * * Normalizes all of the coordinates in the given list of variation axes. @@ -286,10 +286,14 @@ hb_ot_var_normalize_variations (hb_face_t *face, hb_ot_var_axis_info_t info; if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) && info.axis_index < coords_length) - coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value); + coords[info.axis_index] = roundf (fvar.normalize_axis_value (info.axis_index, variations[i].value) * 65536.0f); } - face->table.avar->map_coords (coords, coords_length); + face->table.avar->map_coords_16_16 (coords, coords_length); + + // Round to 2.14 + for (unsigned i = 0; i < coords_length; i++) + coords[i] = (coords[i] + 2) >> 2; } /** @@ -309,6 +313,10 @@ hb_ot_var_normalize_variations (hb_face_t *face, * Any additional scaling defined in the face's `avar` table is also * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar * + * Note: @coords_length must be the same as the number of axes in the face, as + * for example returned by hb_ot_var_get_axis_count(). + * Otherwise, the behavior is undefined. + * * Since: 1.4.2 **/ void @@ -319,9 +327,13 @@ hb_ot_var_normalize_coords (hb_face_t *face, { const OT::fvar &fvar = *face->table.fvar; for (unsigned int i = 0; i < coords_length; i++) - normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); + normalized_coords[i] = roundf (fvar.normalize_axis_value (i, design_coords[i]) * 65536.0f); - face->table.avar->map_coords (normalized_coords, coords_length); + face->table.avar->map_coords_16_16 (normalized_coords, coords_length); + + // Round to 2.14 + for (unsigned i = 0; i < coords_length; i++) + normalized_coords[i] = (normalized_coords[i] + 2) >> 2; } diff --git a/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh b/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh index 95ae8ef5590..1ba9ca26967 100644 --- a/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh @@ -61,6 +61,7 @@ struct VORG bool has_data () const { return version.to_int (); } + HB_ALWAYS_INLINE int get_y_origin (hb_codepoint_t glyph) const { unsigned int i; diff --git a/thirdparty/harfbuzz/src/hb-paint-extents.cc b/thirdparty/harfbuzz/src/hb-paint-extents.cc index 35dcb76f2a7..11339a76a05 100644 --- a/thirdparty/harfbuzz/src/hb-paint-extents.cc +++ b/thirdparty/harfbuzz/src/hb-paint-extents.cc @@ -49,7 +49,7 @@ hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - c->push_transform (hb_transform_t {xx, yx, xy, yy, dx, dy}); + c->push_transform (hb_transform_t<> {xx, yx, xy, yy, dx, dy}); } static void @@ -71,7 +71,7 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_extents_t extents; + hb_extents_t<> extents; hb_draw_funcs_t *draw_extent_funcs = hb_draw_extents_get_funcs (); hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents); c->push_clip (extents); @@ -85,7 +85,7 @@ hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_extents_t extents = {xmin, ymin, xmax, ymax}; + hb_extents_t<> extents = {xmin, ymin, xmax, ymax}; c->push_clip (extents); } @@ -136,10 +136,10 @@ hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, 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, - (float) glyph_extents->y_bearing}; + 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, + (float) glyph_extents->y_bearing}; c->push_clip (extents); c->paint (); c->pop_clip (); diff --git a/thirdparty/harfbuzz/src/hb-paint-extents.hh b/thirdparty/harfbuzz/src/hb-paint-extents.hh index 708af4a8602..0e18e3f8aab 100644 --- a/thirdparty/harfbuzz/src/hb-paint-extents.hh +++ b/thirdparty/harfbuzz/src/hb-paint-extents.hh @@ -41,9 +41,9 @@ struct hb_paint_extents_context_t 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}); + 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 () @@ -51,19 +51,19 @@ struct hb_paint_extents_context_t clear (); } - hb_extents_t get_extents () + hb_extents_t<> get_extents () { return groups.tail().extents; } bool is_bounded () { - return groups.tail().status != hb_bounds_t::UNBOUNDED; + return groups.tail().status != hb_bounds_t<>::UNBOUNDED; } - void push_transform (const hb_transform_t &trans) + void push_transform (const hb_transform_t<> &trans) { - hb_transform_t t = transforms.tail (); + hb_transform_t<> t = transforms.tail (); t.multiply (trans); transforms.push (t); } @@ -73,13 +73,13 @@ struct hb_paint_extents_context_t transforms.pop (); } - void push_clip (hb_extents_t extents) + void push_clip (hb_extents_t<> extents) { /* Transform extents and push a new clip. */ - const hb_transform_t &t = transforms.tail (); + const hb_transform_t<> &t = transforms.tail (); t.transform_extents (extents); - auto bounds = hb_bounds_t {extents}; + auto bounds = hb_bounds_t<> {extents}; bounds.intersect (clips.tail ()); clips.push (bounds); @@ -92,19 +92,19 @@ struct hb_paint_extents_context_t void push_group () { - groups.push (hb_bounds_t {hb_bounds_t::EMPTY}); + groups.push (hb_bounds_t<> {hb_bounds_t<>::EMPTY}); } void pop_group (hb_paint_composite_mode_t mode) { - const hb_bounds_t src_bounds = groups.pop (); - hb_bounds_t &backdrop_bounds = groups.tail (); + const hb_bounds_t<> src_bounds = groups.pop (); + hb_bounds_t<> &backdrop_bounds = groups.tail (); // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite switch ((int) mode) { case HB_PAINT_COMPOSITE_MODE_CLEAR: - backdrop_bounds.status = hb_bounds_t::EMPTY; + backdrop_bounds.status = hb_bounds_t<>::EMPTY; break; case HB_PAINT_COMPOSITE_MODE_SRC: case HB_PAINT_COMPOSITE_MODE_SRC_OUT: @@ -125,16 +125,16 @@ struct hb_paint_extents_context_t void paint () { - const hb_bounds_t &clip = clips.tail (); - hb_bounds_t &group = groups.tail (); + const hb_bounds_t<> &clip = clips.tail (); + hb_bounds_t<> &group = groups.tail (); group.union_ (clip); } protected: - hb_vector_t transforms; - hb_vector_t clips; - hb_vector_t groups; + hb_vector_t> transforms; + hb_vector_t> clips; + hb_vector_t> groups; }; HB_INTERNAL hb_paint_funcs_t * diff --git a/thirdparty/harfbuzz/src/hb-paint.hh b/thirdparty/harfbuzz/src/hb-paint.hh index 6ad365a79fd..bbeeb0319d4 100644 --- a/thirdparty/harfbuzz/src/hb-paint.hh +++ b/thirdparty/harfbuzz/src/hb-paint.hh @@ -28,6 +28,7 @@ #include "hb.hh" #include "hb-face.hh" #include "hb-font.hh" +#include "hb-geometry.hh" #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ @@ -72,7 +73,11 @@ struct hb_paint_funcs_t float xx, float yx, float xy, float yy, float dx, float dy) - { func.push_transform (this, paint_data, + { + // Handle -0.f to avoid -0.f == 0.f in the transform matrix. + if (dx == -0.f) dx = 0.f; + if (dy == -0.f) dy = 0.f; + func.push_transform (this, paint_data, xx, yx, xy, yy, dx, dy, !user_data ? nullptr : user_data->push_transform); } void pop_transform (void *paint_data) @@ -182,54 +187,59 @@ struct hb_paint_funcs_t 0, 0); } - HB_NODISCARD - bool push_translate (void *paint_data, + void push_transform (void *paint_data, hb_transform_t t) + { + push_transform (paint_data, t.xx, t.yx, t.xy, t.yy, t.x0, t.y0); + } + + void push_translate (void *paint_data, float dx, float dy) { - if (!dx && !dy) - return false; - push_transform (paint_data, - 1.f, 0.f, 0.f, 1.f, dx, dy); - return true; + hb_transform_t::translation (dx, dy)); } - HB_NODISCARD - bool push_scale (void *paint_data, + void push_scale (void *paint_data, float sx, float sy) { - if (sx == 1.f && sy == 1.f) - return false; - push_transform (paint_data, - sx, 0.f, 0.f, sy, 0.f, 0.f); - return true; + hb_transform_t::scaling (sx, sy)); + } + void push_scale_around_center (void *paint_data, + float sx, float sy, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::scaling_around_center (sx, sy, cx, cy)); } - HB_NODISCARD - bool push_rotate (void *paint_data, + void push_rotate (void *paint_data, float a) { - if (!a) - return false; - - float cc = cosf (a * HB_PI); - float ss = sinf (a * HB_PI); - push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f); - return true; + push_transform (paint_data, + hb_transform_t::rotation (a * HB_PI)); } - HB_NODISCARD - bool push_skew (void *paint_data, + void push_rotate_around_center (void *paint_data, + float a, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::rotation_around_center (a * HB_PI, cx, cy)); + } + + void push_skew (void *paint_data, float sx, float sy) { - if (!sx && !sy) - return false; - - float x = tanf (-sx * HB_PI); - float y = tanf (+sy * HB_PI); - push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f); - return true; + push_transform (paint_data, + hb_transform_t::skewing (-sx * HB_PI, sy * HB_PI)); + } + void push_skew_around_center (void *paint_data, + float sx, float sy, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::skewing_around_center (-sx * HB_PI, sy * HB_PI, cx, cy)); } }; DECLARE_NULL_INSTANCE (hb_paint_funcs_t); diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index cb4fdeead2e..11d47c9dca3 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -266,7 +266,7 @@ bool _resolve_shared_overflow(const hb_vector_t& overf result = sorted_graph.duplicate(&parents, r.child); } - if (result == (unsigned) -1) return result; + if (result == (unsigned) -1) return false; if (parents.get_population() > 1) { // If the duplicated node has more than one parent pre-emptively raise it's priority to the maximum. @@ -283,7 +283,7 @@ bool _resolve_shared_overflow(const hb_vector_t& overf sorted_graph.vertices_[result].give_max_priority(); } - return result; + return true; } static inline @@ -302,8 +302,11 @@ bool _process_overflows (const hb_vector_t& overflows, { // The child object is shared, we may be able to eliminate the overflow // by duplicating it. - if (!_resolve_shared_overflow(overflows, i, sorted_graph)) continue; - return true; + if (_resolve_shared_overflow(overflows, i, sorted_graph)) + return true; + + // Sometimes we can't duplicate a node which looks shared because it's not actually shared + // (eg. all links from the same parent) in this case continue on to other resolution options. } if (child.is_leaf () && !priority_bumped_parents.has (r.parent)) diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh index 199165a1e4c..88a956b2731 100644 --- a/thirdparty/harfbuzz/src/hb-sanitize.hh +++ b/thirdparty/harfbuzz/src/hb-sanitize.hh @@ -120,8 +120,8 @@ struct hb_sanitize_context_t : hb_dispatch_context_t { - hb_sanitize_context_t () : - start (nullptr), end (nullptr), + hb_sanitize_context_t (const char *start_ = nullptr, const char *end_ = nullptr) : + start (start_), end (end_), length (0), max_ops (0), max_subtables (0), recursion_depth (0), @@ -212,14 +212,22 @@ struct hb_sanitize_context_t : void reset_object () { - this->start = this->blob->data; - this->end = this->start + this->blob->length; + if (this->blob) + { + this->start = this->blob->data; + this->end = this->start + this->blob->length; + } this->length = this->end - this->start; assert (this->start <= this->end); /* Must not overflow. */ } - void start_processing () + void start_processing (const char *start_ = nullptr, const char *end_ = nullptr) { + if (start_) + { + this->start = start_; + this->end = end_; + } reset_object (); unsigned m; if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m))) @@ -463,9 +471,11 @@ struct hb_sanitize_context_t : } else { - if (edit_count && !writable) { - start = hb_blob_get_data_writable (blob, nullptr); - end = start + blob->length; + if (edit_count && !writable) + { + unsigned length; + start = hb_blob_get_data_writable (blob, &length); + end = start + length; if (start) { diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh index 63ab185863c..c6dbf8db91c 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -794,7 +794,8 @@ struct hb_serialize_context_t template void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset) { - auto &off = * ((BEInt *) (parent->head + link.position)); + // XXX We should stop assuming big-endian! + auto &off = * ((HBInt *) (parent->head + link.position)); assert (0 == off); check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW); } diff --git a/thirdparty/harfbuzz/src/hb-shaper-list.hh b/thirdparty/harfbuzz/src/hb-shaper-list.hh index dc494d236af..41673a38441 100644 --- a/thirdparty/harfbuzz/src/hb-shaper-list.hh +++ b/thirdparty/harfbuzz/src/hb-shaper-list.hh @@ -57,8 +57,8 @@ HB_SHAPER_IMPLEMENT (directwrite) HB_SHAPER_IMPLEMENT (coretext) #endif -#ifdef HAVE_HARFRUZZ -HB_SHAPER_IMPLEMENT (harfruzz) +#ifdef HAVE_HARFRUST +HB_SHAPER_IMPLEMENT (harfrust) #endif #ifndef HB_NO_FALLBACK_SHAPE diff --git a/thirdparty/harfbuzz/src/hb-static.cc b/thirdparty/harfbuzz/src/hb-static.cc index e328bc48a49..06cc80b5f38 100644 --- a/thirdparty/harfbuzz/src/hb-static.cc +++ b/thirdparty/harfbuzz/src/hb-static.cc @@ -113,27 +113,4 @@ hb_face_t::load_upem () const return ret; } - -#ifndef HB_NO_VAR -bool -_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, - int *lsb) -{ - return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); -} - -unsigned -_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) -{ - return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); -} -#endif - -bool -_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb) -{ - return face->table.glyf->get_leading_bearing_without_var_unscaled (gid, is_vertical, lsb); -} - - #endif diff --git a/thirdparty/harfbuzz/src/hb-subset-plan-var.cc b/thirdparty/harfbuzz/src/hb-subset-plan-var.cc index 0515b42b2e0..3fe3d633d5c 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan-var.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan-var.cc @@ -42,30 +42,30 @@ 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; @@ -73,11 +73,11 @@ var.value = _.second.middle; vars.push (var); } - + hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ()); return font; } - + template void remap_variation_indices (const ItemVarStore &var_store, @@ -90,7 +90,7 @@ if (&var_store == &Null (OT::ItemVariationStore)) return; unsigned subtable_count = var_store.get_sub_table_count (); auto *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) @@ -99,13 +99,13 @@ 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) @@ -113,7 +113,7 @@ 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; @@ -121,7 +121,7 @@ } var_store.destroy_cache (store_cache); } - + template void remap_variation_indices (const OT::ItemVariationStore &var_store, @@ -130,7 +130,7 @@ bool calculate_delta, /* not pinned at default */ bool no_variations, /* all axes pinned */ hb_hashmap_t> &variation_idx_delta_map /* OUT */); - + #ifndef HB_NO_BASE void collect_base_variation_indices (hb_subset_plan_t* plan) @@ -141,23 +141,23 @@ 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 void @@ -199,24 +199,44 @@ normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) { 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); + float normalized_min = axis.normalize_axis_value (axis_range->minimum); + float normalized_default = axis.normalize_axis_value (axis_range->middle); + float normalized_max = axis.normalize_axis_value (axis_range->maximum); + + // TODO(behdad): Spec says axis normalization should be done in 16.16; + // We used to do it in 2.14, but that's not correct. I fixed this in + // the fvar/avar code, but keeping 2.14 here for now to keep tests + // happy. We might need to adjust fonttools as well. + // I'm only fairly confident in the above statement. Anyway, + // we should look deeper into this, and also update fonttools if + // needed. + + // Round to 2.14 + normalized_min = roundf (normalized_min * 16384.f) / 16384.f; + normalized_default = roundf (normalized_default * 16384.f) / 16384.f; + normalized_max = roundf (normalized_max * 16384.f) / 16384.f; 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))); + normalized_min = seg_maps->map_float (normalized_min); + normalized_default = seg_maps->map_float (normalized_default); + normalized_max = seg_maps->map_float (normalized_max); - if (normalized_default != 0) + // Round to 2.14 + normalized_min = roundf (normalized_min * 16384.f) / 16384.f; + normalized_default = roundf (normalized_default * 16384.f) / 16384.f; + normalized_max = roundf (normalized_max * 16384.f) / 16384.f; + } + plan->axes_location.set (axis_tag, Triple ((double) normalized_min, + (double) normalized_default, + (double) normalized_max)); + + if (normalized_default == -0.f) + normalized_default = 0.f; // Normalize -0 to 0 + if (normalized_default != 0.f) plan->pinned_at_default = false; - plan->normalized_coords[old_axis_idx] = normalized_default; + plan->normalized_coords[old_axis_idx] = roundf (normalized_default * 16384.f); } old_axis_idx++; @@ -243,12 +263,12 @@ update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) hb_glyph_extents_t extents = {0x7FFF, -0x7FFF}; OT::hmtx_accelerator_t _hmtx (plan->source); - OT::ItemVariationStore::cache_t *hvar_store_cache = nullptr; + OT::hb_scalar_cache_t *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); - OT::ItemVariationStore::cache_t *vvar_store_cache = nullptr; + OT::hb_scalar_cache_t *vvar_store_cache = nullptr; if (_vmtx.has_data () && _vmtx.var_table.get_length ()) vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache (); @@ -279,8 +299,7 @@ update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) int lsb = extents.x_bearing; if (!has_bounds_info) { - if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) - continue; + _hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); } plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); plan->bounds_width_vec[new_gid] = extents.width; @@ -292,13 +311,17 @@ update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) 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) + hb_position_t vorg_x = 0; + hb_position_t vorg_y = 0; + int tsb = 0; + if (has_bounds_info && + hb_font_get_glyph_v_origin (font, old_gid, &vorg_x, &vorg_y)) { - if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb)) - continue; + tsb = vorg_y - extents.y_bearing; + } else { + _vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb); } + plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); plan->bounds_height_vec[new_gid] = extents.height; } @@ -385,4 +408,4 @@ remap_colrv1_delta_set_index_indices (const OT::DeltaSetIn hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ hb_map_t &new_deltaset_idx_varidx_map /* OUT */); - #endif \ No newline at end of file + #endif diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index a56965246ce..25073d23fda 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -248,7 +248,7 @@ _populate_unicodes_to_retain (const hb_set_t *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 (); + unsigned size_threshold = plan->source->get_num_glyphs (); if (glyphs->is_empty () && unicodes.get_population () < size_threshold) { @@ -376,7 +376,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes_in, // so record those first. plan->os2_info.min_cmap_codepoint = plan->unicodes.get_min(); plan->os2_info.max_cmap_codepoint = plan->unicodes.get_max(); - + hb_set_t variation_selectors_to_retain; cmap.collect_variation_selectors(&variation_selectors_to_retain); + variation_selectors_to_retain.iter() diff --git a/thirdparty/harfbuzz/src/hb-ucd-table.hh b/thirdparty/harfbuzz/src/hb-ucd-table.hh index 8731a0bcf8d..9c0bfe56b27 100644 --- a/thirdparty/harfbuzz/src/hb-ucd-table.hh +++ b/thirdparty/harfbuzz/src/hb-ucd-table.hh @@ -2,7 +2,7 @@ /* * The following table is generated by running: * - * ./gen-ucd-table.py ucd.nounihan.grouped.xml + * ./gen-ucd-table.py ucd.nounihan.grouped.xml hb-script-list.h * * on file with this description: Unicode 16.0.0 */ @@ -12,8 +12,9 @@ #include "hb.hh" -static const hb_script_t -_hb_ucd_sc_map[172] = +#include + +static const hb_script_t _hb_ucd_sc_map[172]= { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -102,987 +103,665 @@ _hb_ucd_sc_map[172] = HB_SCRIPT_OL_ONAL, HB_SCRIPT_SUNUWAR, HB_SCRIPT_TODHRI, HB_SCRIPT_TULU_TIGALARI, }; -static const uint16_t -_hb_ucd_dm1_p0_map[825] = +static const uint16_t _hb_ucd_dm1_p0_map[825]= { - 0x003Bu, 0x004Bu, 0x0060u, 0x00B4u, 0x00B7u, 0x00C5u, 0x02B9u, 0x0300u, - 0x0301u, 0x0313u, 0x0385u, 0x0386u, 0x0388u, 0x0389u, 0x038Au, 0x038Cu, - 0x038Eu, 0x038Fu, 0x0390u, 0x03A9u, 0x03ACu, 0x03ADu, 0x03AEu, 0x03AFu, - 0x03B0u, 0x03B9u, 0x03CCu, 0x03CDu, 0x03CEu, 0x2002u, 0x2003u, 0x3008u, - 0x3009u, 0x349Eu, 0x34B9u, 0x34BBu, 0x34DFu, 0x3515u, 0x36EEu, 0x36FCu, - 0x3781u, 0x382Fu, 0x3862u, 0x387Cu, 0x38C7u, 0x38E3u, 0x391Cu, 0x393Au, - 0x3A2Eu, 0x3A6Cu, 0x3AE4u, 0x3B08u, 0x3B19u, 0x3B49u, 0x3B9Du, 0x3C18u, - 0x3C4Eu, 0x3D33u, 0x3D96u, 0x3EACu, 0x3EB8u, 0x3F1Bu, 0x3FFCu, 0x4008u, - 0x4018u, 0x4039u, 0x4046u, 0x4096u, 0x40E3u, 0x412Fu, 0x4202u, 0x4227u, - 0x42A0u, 0x4301u, 0x4334u, 0x4359u, 0x43D5u, 0x43D9u, 0x440Bu, 0x446Bu, - 0x452Bu, 0x455Du, 0x4561u, 0x456Bu, 0x45D7u, 0x45F9u, 0x4635u, 0x46BEu, - 0x46C7u, 0x4995u, 0x49E6u, 0x4A6Eu, 0x4A76u, 0x4AB2u, 0x4B33u, 0x4BCEu, - 0x4CCEu, 0x4CEDu, 0x4CF8u, 0x4D56u, 0x4E0Du, 0x4E26u, 0x4E32u, 0x4E38u, - 0x4E39u, 0x4E3Du, 0x4E41u, 0x4E82u, 0x4E86u, 0x4EAEu, 0x4EC0u, 0x4ECCu, - 0x4EE4u, 0x4F60u, 0x4F80u, 0x4F86u, 0x4F8Bu, 0x4FAEu, 0x4FBBu, 0x4FBFu, - 0x5002u, 0x502Bu, 0x507Au, 0x5099u, 0x50CFu, 0x50DAu, 0x50E7u, 0x5140u, - 0x5145u, 0x514Du, 0x5154u, 0x5164u, 0x5167u, 0x5168u, 0x5169u, 0x516Du, - 0x5177u, 0x5180u, 0x518Du, 0x5192u, 0x5195u, 0x5197u, 0x51A4u, 0x51ACu, - 0x51B5u, 0x51B7u, 0x51C9u, 0x51CCu, 0x51DCu, 0x51DEu, 0x51F5u, 0x5203u, - 0x5207u, 0x5217u, 0x5229u, 0x523Au, 0x523Bu, 0x5246u, 0x5272u, 0x5277u, - 0x5289u, 0x529Bu, 0x52A3u, 0x52B3u, 0x52C7u, 0x52C9u, 0x52D2u, 0x52DEu, - 0x52E4u, 0x52F5u, 0x52FAu, 0x5305u, 0x5306u, 0x5317u, 0x533Fu, 0x5349u, - 0x5351u, 0x535Au, 0x5373u, 0x5375u, 0x537Du, 0x537Fu, 0x53C3u, 0x53CAu, - 0x53DFu, 0x53E5u, 0x53EBu, 0x53F1u, 0x5406u, 0x540Fu, 0x541Du, 0x5438u, - 0x5442u, 0x5448u, 0x5468u, 0x549Eu, 0x54A2u, 0x54BDu, 0x54F6u, 0x5510u, - 0x5553u, 0x5555u, 0x5563u, 0x5584u, 0x5587u, 0x5599u, 0x559Du, 0x55ABu, - 0x55B3u, 0x55C0u, 0x55C2u, 0x55E2u, 0x5606u, 0x5651u, 0x5668u, 0x5674u, - 0x56F9u, 0x5716u, 0x5717u, 0x578Bu, 0x57CEu, 0x57F4u, 0x580Du, 0x5831u, - 0x5832u, 0x5840u, 0x585Au, 0x585Eu, 0x58A8u, 0x58ACu, 0x58B3u, 0x58D8u, - 0x58DFu, 0x58EEu, 0x58F2u, 0x58F7u, 0x5906u, 0x591Au, 0x5922u, 0x5944u, - 0x5948u, 0x5951u, 0x5954u, 0x5962u, 0x5973u, 0x59D8u, 0x59ECu, 0x5A1Bu, - 0x5A27u, 0x5A62u, 0x5A66u, 0x5AB5u, 0x5B08u, 0x5B28u, 0x5B3Eu, 0x5B85u, - 0x5BC3u, 0x5BD8u, 0x5BE7u, 0x5BEEu, 0x5BF3u, 0x5BFFu, 0x5C06u, 0x5C22u, - 0x5C3Fu, 0x5C60u, 0x5C62u, 0x5C64u, 0x5C65u, 0x5C6Eu, 0x5C8Du, 0x5CC0u, - 0x5D19u, 0x5D43u, 0x5D50u, 0x5D6Bu, 0x5D6Eu, 0x5D7Cu, 0x5DB2u, 0x5DBAu, - 0x5DE1u, 0x5DE2u, 0x5DFDu, 0x5E28u, 0x5E3Du, 0x5E69u, 0x5E74u, 0x5EA6u, - 0x5EB0u, 0x5EB3u, 0x5EB6u, 0x5EC9u, 0x5ECAu, 0x5ED2u, 0x5ED3u, 0x5ED9u, - 0x5EECu, 0x5EFEu, 0x5F04u, 0x5F22u, 0x5F53u, 0x5F62u, 0x5F69u, 0x5F6Bu, - 0x5F8Bu, 0x5F9Au, 0x5FA9u, 0x5FADu, 0x5FCDu, 0x5FD7u, 0x5FF5u, 0x5FF9u, - 0x6012u, 0x601Cu, 0x6075u, 0x6081u, 0x6094u, 0x60C7u, 0x60D8u, 0x60E1u, - 0x6108u, 0x6144u, 0x6148u, 0x614Cu, 0x614Eu, 0x6160u, 0x6168u, 0x617Au, - 0x618Eu, 0x6190u, 0x61A4u, 0x61AFu, 0x61B2u, 0x61DEu, 0x61F2u, 0x61F6u, - 0x6200u, 0x6210u, 0x621Bu, 0x622Eu, 0x6234u, 0x625Du, 0x62B1u, 0x62C9u, - 0x62CFu, 0x62D3u, 0x62D4u, 0x62FCu, 0x62FEu, 0x633Du, 0x6350u, 0x6368u, - 0x637Bu, 0x6383u, 0x63A0u, 0x63A9u, 0x63C4u, 0x63C5u, 0x63E4u, 0x641Cu, - 0x6422u, 0x6452u, 0x6469u, 0x6477u, 0x647Eu, 0x649Au, 0x649Du, 0x64C4u, - 0x654Fu, 0x6556u, 0x656Cu, 0x6578u, 0x6599u, 0x65C5u, 0x65E2u, 0x65E3u, - 0x6613u, 0x6649u, 0x6674u, 0x6688u, 0x6691u, 0x669Cu, 0x66B4u, 0x66C6u, - 0x66F4u, 0x66F8u, 0x6700u, 0x6717u, 0x671Bu, 0x6721u, 0x674Eu, 0x6753u, - 0x6756u, 0x675Eu, 0x677Bu, 0x6785u, 0x6797u, 0x67F3u, 0x67FAu, 0x6817u, - 0x681Fu, 0x6852u, 0x6881u, 0x6885u, 0x688Eu, 0x68A8u, 0x6914u, 0x6942u, - 0x69A3u, 0x69EAu, 0x6A02u, 0x6A13u, 0x6AA8u, 0x6AD3u, 0x6ADBu, 0x6B04u, - 0x6B21u, 0x6B54u, 0x6B72u, 0x6B77u, 0x6B79u, 0x6B9Fu, 0x6BAEu, 0x6BBAu, - 0x6BBBu, 0x6C4Eu, 0x6C67u, 0x6C88u, 0x6CBFu, 0x6CCCu, 0x6CCDu, 0x6CE5u, - 0x6D16u, 0x6D1Bu, 0x6D1Eu, 0x6D34u, 0x6D3Eu, 0x6D41u, 0x6D69u, 0x6D6Au, - 0x6D77u, 0x6D78u, 0x6D85u, 0x6DCBu, 0x6DDAu, 0x6DEAu, 0x6DF9u, 0x6E1Au, - 0x6E2Fu, 0x6E6Eu, 0x6E9Cu, 0x6EBAu, 0x6EC7u, 0x6ECBu, 0x6ED1u, 0x6EDBu, - 0x6F0Fu, 0x6F22u, 0x6F23u, 0x6F6Eu, 0x6FC6u, 0x6FEBu, 0x6FFEu, 0x701Bu, - 0x701Eu, 0x7039u, 0x704Au, 0x7070u, 0x7077u, 0x707Du, 0x7099u, 0x70ADu, - 0x70C8u, 0x70D9u, 0x7145u, 0x7149u, 0x716Eu, 0x719Cu, 0x71CEu, 0x71D0u, - 0x7210u, 0x721Bu, 0x7228u, 0x722Bu, 0x7235u, 0x7250u, 0x7262u, 0x7280u, - 0x7295u, 0x72AFu, 0x72C0u, 0x72FCu, 0x732Au, 0x7375u, 0x737Au, 0x7387u, - 0x738Bu, 0x73A5u, 0x73B2u, 0x73DEu, 0x7406u, 0x7409u, 0x7422u, 0x7447u, - 0x745Cu, 0x7469u, 0x7471u, 0x7485u, 0x7489u, 0x7498u, 0x74CAu, 0x7506u, - 0x7524u, 0x753Bu, 0x753Eu, 0x7559u, 0x7565u, 0x7570u, 0x75E2u, 0x7610u, - 0x761Du, 0x761Fu, 0x7642u, 0x7669u, 0x76CAu, 0x76DBu, 0x76E7u, 0x76F4u, - 0x7701u, 0x771Eu, 0x771Fu, 0x7740u, 0x774Au, 0x778Bu, 0x77A7u, 0x784Eu, - 0x786Bu, 0x788Cu, 0x7891u, 0x78CAu, 0x78CCu, 0x78FBu, 0x792Au, 0x793Cu, - 0x793Eu, 0x7948u, 0x7949u, 0x7950u, 0x7956u, 0x795Du, 0x795Eu, 0x7965u, - 0x797Fu, 0x798Du, 0x798Eu, 0x798Fu, 0x79AEu, 0x79CAu, 0x79EBu, 0x7A1Cu, - 0x7A40u, 0x7A4Au, 0x7A4Fu, 0x7A81u, 0x7AB1u, 0x7ACBu, 0x7AEEu, 0x7B20u, - 0x7BC0u, 0x7BC6u, 0x7BC9u, 0x7C3Eu, 0x7C60u, 0x7C7Bu, 0x7C92u, 0x7CBEu, - 0x7CD2u, 0x7CD6u, 0x7CE3u, 0x7CE7u, 0x7CE8u, 0x7D00u, 0x7D10u, 0x7D22u, - 0x7D2Fu, 0x7D5Bu, 0x7D63u, 0x7DA0u, 0x7DBEu, 0x7DC7u, 0x7DF4u, 0x7E02u, - 0x7E09u, 0x7E37u, 0x7E41u, 0x7E45u, 0x7F3Eu, 0x7F72u, 0x7F79u, 0x7F7Au, - 0x7F85u, 0x7F95u, 0x7F9Au, 0x7FBDu, 0x7FFAu, 0x8001u, 0x8005u, 0x8046u, - 0x8060u, 0x806Fu, 0x8070u, 0x807Eu, 0x808Bu, 0x80ADu, 0x80B2u, 0x8103u, - 0x813Eu, 0x81D8u, 0x81E8u, 0x81EDu, 0x8201u, 0x8204u, 0x8218u, 0x826Fu, - 0x8279u, 0x828Bu, 0x8291u, 0x829Du, 0x82B1u, 0x82B3u, 0x82BDu, 0x82E5u, - 0x82E6u, 0x831Du, 0x8323u, 0x8336u, 0x8352u, 0x8353u, 0x8363u, 0x83ADu, - 0x83BDu, 0x83C9u, 0x83CAu, 0x83CCu, 0x83DCu, 0x83E7u, 0x83EFu, 0x83F1u, - 0x843Du, 0x8449u, 0x8457u, 0x84EEu, 0x84F1u, 0x84F3u, 0x84FCu, 0x8516u, - 0x8564u, 0x85CDu, 0x85FAu, 0x8606u, 0x8612u, 0x862Du, 0x863Fu, 0x8650u, - 0x865Cu, 0x8667u, 0x8669u, 0x8688u, 0x86A9u, 0x86E2u, 0x870Eu, 0x8728u, - 0x876Bu, 0x8779u, 0x8786u, 0x87BAu, 0x87E1u, 0x8801u, 0x881Fu, 0x884Cu, - 0x8860u, 0x8863u, 0x88C2u, 0x88CFu, 0x88D7u, 0x88DEu, 0x88E1u, 0x88F8u, - 0x88FAu, 0x8910u, 0x8941u, 0x8964u, 0x8986u, 0x898Bu, 0x8996u, 0x8AA0u, - 0x8AAAu, 0x8ABFu, 0x8ACBu, 0x8AD2u, 0x8AD6u, 0x8AEDu, 0x8AF8u, 0x8AFEu, - 0x8B01u, 0x8B39u, 0x8B58u, 0x8B80u, 0x8B8Au, 0x8C48u, 0x8C55u, 0x8CABu, - 0x8CC1u, 0x8CC2u, 0x8CC8u, 0x8CD3u, 0x8D08u, 0x8D1Bu, 0x8D77u, 0x8DBCu, - 0x8DCBu, 0x8DEFu, 0x8DF0u, 0x8ECAu, 0x8ED4u, 0x8F26u, 0x8F2Au, 0x8F38u, - 0x8F3Bu, 0x8F62u, 0x8F9Eu, 0x8FB0u, 0x8FB6u, 0x9023u, 0x9038u, 0x9072u, - 0x907Cu, 0x908Fu, 0x9094u, 0x90CEu, 0x90DEu, 0x90F1u, 0x90FDu, 0x9111u, - 0x911Bu, 0x916Au, 0x9199u, 0x91B4u, 0x91CCu, 0x91CFu, 0x91D1u, 0x9234u, - 0x9238u, 0x9276u, 0x927Cu, 0x92D7u, 0x92D8u, 0x9304u, 0x934Au, 0x93F9u, - 0x9415u, 0x958Bu, 0x95ADu, 0x95B7u, 0x962Eu, 0x964Bu, 0x964Du, 0x9675u, - 0x9678u, 0x967Cu, 0x9686u, 0x96A3u, 0x96B7u, 0x96B8u, 0x96C3u, 0x96E2u, - 0x96E3u, 0x96F6u, 0x96F7u, 0x9723u, 0x9732u, 0x9748u, 0x9756u, 0x97DBu, - 0x97E0u, 0x97FFu, 0x980Bu, 0x9818u, 0x9829u, 0x983Bu, 0x985Eu, 0x98E2u, - 0x98EFu, 0x98FCu, 0x9928u, 0x9929u, 0x99A7u, 0x99C2u, 0x99F1u, 0x99FEu, - 0x9A6Au, 0x9B12u, 0x9B6Fu, 0x9C40u, 0x9C57u, 0x9CFDu, 0x9D67u, 0x9DB4u, - 0x9DFAu, 0x9E1Eu, 0x9E7Fu, 0x9E97u, 0x9E9Fu, 0x9EBBu, 0x9ECEu, 0x9EF9u, - 0x9EFEu, 0x9F05u, 0x9F0Fu, 0x9F16u, 0x9F3Bu, 0x9F43u, 0x9F8Du, 0x9F8Eu, - 0x9F9Cu, + 0x003B, 0x004B, 0x0060, 0x00B4, 0x00B7, 0x00C5, 0x02B9, 0x0300, + 0x0301, 0x0313, 0x0385, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, + 0x038E, 0x038F, 0x0390, 0x03A9, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B9, 0x03CC, 0x03CD, 0x03CE, 0x2002, 0x2003, 0x3008, + 0x3009, 0x349E, 0x34B9, 0x34BB, 0x34DF, 0x3515, 0x36EE, 0x36FC, + 0x3781, 0x382F, 0x3862, 0x387C, 0x38C7, 0x38E3, 0x391C, 0x393A, + 0x3A2E, 0x3A6C, 0x3AE4, 0x3B08, 0x3B19, 0x3B49, 0x3B9D, 0x3C18, + 0x3C4E, 0x3D33, 0x3D96, 0x3EAC, 0x3EB8, 0x3F1B, 0x3FFC, 0x4008, + 0x4018, 0x4039, 0x4046, 0x4096, 0x40E3, 0x412F, 0x4202, 0x4227, + 0x42A0, 0x4301, 0x4334, 0x4359, 0x43D5, 0x43D9, 0x440B, 0x446B, + 0x452B, 0x455D, 0x4561, 0x456B, 0x45D7, 0x45F9, 0x4635, 0x46BE, + 0x46C7, 0x4995, 0x49E6, 0x4A6E, 0x4A76, 0x4AB2, 0x4B33, 0x4BCE, + 0x4CCE, 0x4CED, 0x4CF8, 0x4D56, 0x4E0D, 0x4E26, 0x4E32, 0x4E38, + 0x4E39, 0x4E3D, 0x4E41, 0x4E82, 0x4E86, 0x4EAE, 0x4EC0, 0x4ECC, + 0x4EE4, 0x4F60, 0x4F80, 0x4F86, 0x4F8B, 0x4FAE, 0x4FBB, 0x4FBF, + 0x5002, 0x502B, 0x507A, 0x5099, 0x50CF, 0x50DA, 0x50E7, 0x5140, + 0x5145, 0x514D, 0x5154, 0x5164, 0x5167, 0x5168, 0x5169, 0x516D, + 0x5177, 0x5180, 0x518D, 0x5192, 0x5195, 0x5197, 0x51A4, 0x51AC, + 0x51B5, 0x51B7, 0x51C9, 0x51CC, 0x51DC, 0x51DE, 0x51F5, 0x5203, + 0x5207, 0x5217, 0x5229, 0x523A, 0x523B, 0x5246, 0x5272, 0x5277, + 0x5289, 0x529B, 0x52A3, 0x52B3, 0x52C7, 0x52C9, 0x52D2, 0x52DE, + 0x52E4, 0x52F5, 0x52FA, 0x5305, 0x5306, 0x5317, 0x533F, 0x5349, + 0x5351, 0x535A, 0x5373, 0x5375, 0x537D, 0x537F, 0x53C3, 0x53CA, + 0x53DF, 0x53E5, 0x53EB, 0x53F1, 0x5406, 0x540F, 0x541D, 0x5438, + 0x5442, 0x5448, 0x5468, 0x549E, 0x54A2, 0x54BD, 0x54F6, 0x5510, + 0x5553, 0x5555, 0x5563, 0x5584, 0x5587, 0x5599, 0x559D, 0x55AB, + 0x55B3, 0x55C0, 0x55C2, 0x55E2, 0x5606, 0x5651, 0x5668, 0x5674, + 0x56F9, 0x5716, 0x5717, 0x578B, 0x57CE, 0x57F4, 0x580D, 0x5831, + 0x5832, 0x5840, 0x585A, 0x585E, 0x58A8, 0x58AC, 0x58B3, 0x58D8, + 0x58DF, 0x58EE, 0x58F2, 0x58F7, 0x5906, 0x591A, 0x5922, 0x5944, + 0x5948, 0x5951, 0x5954, 0x5962, 0x5973, 0x59D8, 0x59EC, 0x5A1B, + 0x5A27, 0x5A62, 0x5A66, 0x5AB5, 0x5B08, 0x5B28, 0x5B3E, 0x5B85, + 0x5BC3, 0x5BD8, 0x5BE7, 0x5BEE, 0x5BF3, 0x5BFF, 0x5C06, 0x5C22, + 0x5C3F, 0x5C60, 0x5C62, 0x5C64, 0x5C65, 0x5C6E, 0x5C8D, 0x5CC0, + 0x5D19, 0x5D43, 0x5D50, 0x5D6B, 0x5D6E, 0x5D7C, 0x5DB2, 0x5DBA, + 0x5DE1, 0x5DE2, 0x5DFD, 0x5E28, 0x5E3D, 0x5E69, 0x5E74, 0x5EA6, + 0x5EB0, 0x5EB3, 0x5EB6, 0x5EC9, 0x5ECA, 0x5ED2, 0x5ED3, 0x5ED9, + 0x5EEC, 0x5EFE, 0x5F04, 0x5F22, 0x5F53, 0x5F62, 0x5F69, 0x5F6B, + 0x5F8B, 0x5F9A, 0x5FA9, 0x5FAD, 0x5FCD, 0x5FD7, 0x5FF5, 0x5FF9, + 0x6012, 0x601C, 0x6075, 0x6081, 0x6094, 0x60C7, 0x60D8, 0x60E1, + 0x6108, 0x6144, 0x6148, 0x614C, 0x614E, 0x6160, 0x6168, 0x617A, + 0x618E, 0x6190, 0x61A4, 0x61AF, 0x61B2, 0x61DE, 0x61F2, 0x61F6, + 0x6200, 0x6210, 0x621B, 0x622E, 0x6234, 0x625D, 0x62B1, 0x62C9, + 0x62CF, 0x62D3, 0x62D4, 0x62FC, 0x62FE, 0x633D, 0x6350, 0x6368, + 0x637B, 0x6383, 0x63A0, 0x63A9, 0x63C4, 0x63C5, 0x63E4, 0x641C, + 0x6422, 0x6452, 0x6469, 0x6477, 0x647E, 0x649A, 0x649D, 0x64C4, + 0x654F, 0x6556, 0x656C, 0x6578, 0x6599, 0x65C5, 0x65E2, 0x65E3, + 0x6613, 0x6649, 0x6674, 0x6688, 0x6691, 0x669C, 0x66B4, 0x66C6, + 0x66F4, 0x66F8, 0x6700, 0x6717, 0x671B, 0x6721, 0x674E, 0x6753, + 0x6756, 0x675E, 0x677B, 0x6785, 0x6797, 0x67F3, 0x67FA, 0x6817, + 0x681F, 0x6852, 0x6881, 0x6885, 0x688E, 0x68A8, 0x6914, 0x6942, + 0x69A3, 0x69EA, 0x6A02, 0x6A13, 0x6AA8, 0x6AD3, 0x6ADB, 0x6B04, + 0x6B21, 0x6B54, 0x6B72, 0x6B77, 0x6B79, 0x6B9F, 0x6BAE, 0x6BBA, + 0x6BBB, 0x6C4E, 0x6C67, 0x6C88, 0x6CBF, 0x6CCC, 0x6CCD, 0x6CE5, + 0x6D16, 0x6D1B, 0x6D1E, 0x6D34, 0x6D3E, 0x6D41, 0x6D69, 0x6D6A, + 0x6D77, 0x6D78, 0x6D85, 0x6DCB, 0x6DDA, 0x6DEA, 0x6DF9, 0x6E1A, + 0x6E2F, 0x6E6E, 0x6E9C, 0x6EBA, 0x6EC7, 0x6ECB, 0x6ED1, 0x6EDB, + 0x6F0F, 0x6F22, 0x6F23, 0x6F6E, 0x6FC6, 0x6FEB, 0x6FFE, 0x701B, + 0x701E, 0x7039, 0x704A, 0x7070, 0x7077, 0x707D, 0x7099, 0x70AD, + 0x70C8, 0x70D9, 0x7145, 0x7149, 0x716E, 0x719C, 0x71CE, 0x71D0, + 0x7210, 0x721B, 0x7228, 0x722B, 0x7235, 0x7250, 0x7262, 0x7280, + 0x7295, 0x72AF, 0x72C0, 0x72FC, 0x732A, 0x7375, 0x737A, 0x7387, + 0x738B, 0x73A5, 0x73B2, 0x73DE, 0x7406, 0x7409, 0x7422, 0x7447, + 0x745C, 0x7469, 0x7471, 0x7485, 0x7489, 0x7498, 0x74CA, 0x7506, + 0x7524, 0x753B, 0x753E, 0x7559, 0x7565, 0x7570, 0x75E2, 0x7610, + 0x761D, 0x761F, 0x7642, 0x7669, 0x76CA, 0x76DB, 0x76E7, 0x76F4, + 0x7701, 0x771E, 0x771F, 0x7740, 0x774A, 0x778B, 0x77A7, 0x784E, + 0x786B, 0x788C, 0x7891, 0x78CA, 0x78CC, 0x78FB, 0x792A, 0x793C, + 0x793E, 0x7948, 0x7949, 0x7950, 0x7956, 0x795D, 0x795E, 0x7965, + 0x797F, 0x798D, 0x798E, 0x798F, 0x79AE, 0x79CA, 0x79EB, 0x7A1C, + 0x7A40, 0x7A4A, 0x7A4F, 0x7A81, 0x7AB1, 0x7ACB, 0x7AEE, 0x7B20, + 0x7BC0, 0x7BC6, 0x7BC9, 0x7C3E, 0x7C60, 0x7C7B, 0x7C92, 0x7CBE, + 0x7CD2, 0x7CD6, 0x7CE3, 0x7CE7, 0x7CE8, 0x7D00, 0x7D10, 0x7D22, + 0x7D2F, 0x7D5B, 0x7D63, 0x7DA0, 0x7DBE, 0x7DC7, 0x7DF4, 0x7E02, + 0x7E09, 0x7E37, 0x7E41, 0x7E45, 0x7F3E, 0x7F72, 0x7F79, 0x7F7A, + 0x7F85, 0x7F95, 0x7F9A, 0x7FBD, 0x7FFA, 0x8001, 0x8005, 0x8046, + 0x8060, 0x806F, 0x8070, 0x807E, 0x808B, 0x80AD, 0x80B2, 0x8103, + 0x813E, 0x81D8, 0x81E8, 0x81ED, 0x8201, 0x8204, 0x8218, 0x826F, + 0x8279, 0x828B, 0x8291, 0x829D, 0x82B1, 0x82B3, 0x82BD, 0x82E5, + 0x82E6, 0x831D, 0x8323, 0x8336, 0x8352, 0x8353, 0x8363, 0x83AD, + 0x83BD, 0x83C9, 0x83CA, 0x83CC, 0x83DC, 0x83E7, 0x83EF, 0x83F1, + 0x843D, 0x8449, 0x8457, 0x84EE, 0x84F1, 0x84F3, 0x84FC, 0x8516, + 0x8564, 0x85CD, 0x85FA, 0x8606, 0x8612, 0x862D, 0x863F, 0x8650, + 0x865C, 0x8667, 0x8669, 0x8688, 0x86A9, 0x86E2, 0x870E, 0x8728, + 0x876B, 0x8779, 0x8786, 0x87BA, 0x87E1, 0x8801, 0x881F, 0x884C, + 0x8860, 0x8863, 0x88C2, 0x88CF, 0x88D7, 0x88DE, 0x88E1, 0x88F8, + 0x88FA, 0x8910, 0x8941, 0x8964, 0x8986, 0x898B, 0x8996, 0x8AA0, + 0x8AAA, 0x8ABF, 0x8ACB, 0x8AD2, 0x8AD6, 0x8AED, 0x8AF8, 0x8AFE, + 0x8B01, 0x8B39, 0x8B58, 0x8B80, 0x8B8A, 0x8C48, 0x8C55, 0x8CAB, + 0x8CC1, 0x8CC2, 0x8CC8, 0x8CD3, 0x8D08, 0x8D1B, 0x8D77, 0x8DBC, + 0x8DCB, 0x8DEF, 0x8DF0, 0x8ECA, 0x8ED4, 0x8F26, 0x8F2A, 0x8F38, + 0x8F3B, 0x8F62, 0x8F9E, 0x8FB0, 0x8FB6, 0x9023, 0x9038, 0x9072, + 0x907C, 0x908F, 0x9094, 0x90CE, 0x90DE, 0x90F1, 0x90FD, 0x9111, + 0x911B, 0x916A, 0x9199, 0x91B4, 0x91CC, 0x91CF, 0x91D1, 0x9234, + 0x9238, 0x9276, 0x927C, 0x92D7, 0x92D8, 0x9304, 0x934A, 0x93F9, + 0x9415, 0x958B, 0x95AD, 0x95B7, 0x962E, 0x964B, 0x964D, 0x9675, + 0x9678, 0x967C, 0x9686, 0x96A3, 0x96B7, 0x96B8, 0x96C3, 0x96E2, + 0x96E3, 0x96F6, 0x96F7, 0x9723, 0x9732, 0x9748, 0x9756, 0x97DB, + 0x97E0, 0x97FF, 0x980B, 0x9818, 0x9829, 0x983B, 0x985E, 0x98E2, + 0x98EF, 0x98FC, 0x9928, 0x9929, 0x99A7, 0x99C2, 0x99F1, 0x99FE, + 0x9A6A, 0x9B12, 0x9B6F, 0x9C40, 0x9C57, 0x9CFD, 0x9D67, 0x9DB4, + 0x9DFA, 0x9E1E, 0x9E7F, 0x9E97, 0x9E9F, 0x9EBB, 0x9ECE, 0x9EF9, + 0x9EFE, 0x9F05, 0x9F0F, 0x9F16, 0x9F3B, 0x9F43, 0x9F8D, 0x9F8E, + 0x9F9C, }; -static const uint16_t -_hb_ucd_dm1_p2_map[110] = +static const uint16_t _hb_ucd_dm1_p2_map[110]= { - 0x0122u, 0x051Cu, 0x0525u, 0x054Bu, 0x063Au, 0x0804u, 0x08DEu, 0x0A2Cu, - 0x0B63u, 0x14E4u, 0x16A8u, 0x16EAu, 0x19C8u, 0x1B18u, 0x1D0Bu, 0x1DE4u, - 0x1DE6u, 0x2183u, 0x219Fu, 0x2331u, 0x26D4u, 0x2844u, 0x284Au, 0x2B0Cu, - 0x2BF1u, 0x300Au, 0x32B8u, 0x335Fu, 0x3393u, 0x339Cu, 0x33C3u, 0x33D5u, - 0x346Du, 0x36A3u, 0x38A7u, 0x3A8Du, 0x3AFAu, 0x3CBCu, 0x3D1Eu, 0x3ED1u, - 0x3F5Eu, 0x3F8Eu, 0x4263u, 0x42EEu, 0x43ABu, 0x4608u, 0x4735u, 0x4814u, - 0x4C36u, 0x4C92u, 0x4FA1u, 0x4FB8u, 0x5044u, 0x50F2u, 0x50F3u, 0x5119u, - 0x5133u, 0x5249u, 0x541Du, 0x5626u, 0x569Au, 0x56C5u, 0x597Cu, 0x5AA7u, - 0x5BABu, 0x5C80u, 0x5CD0u, 0x5F86u, 0x61DAu, 0x6228u, 0x6247u, 0x62D9u, - 0x633Eu, 0x64DAu, 0x6523u, 0x65A8u, 0x67A7u, 0x67B5u, 0x6B3Cu, 0x6C36u, - 0x6CD5u, 0x6D6Bu, 0x6F2Cu, 0x6FB1u, 0x70D2u, 0x73CAu, 0x7667u, 0x78AEu, - 0x7966u, 0x7CA8u, 0x7ED3u, 0x7F2Fu, 0x85D2u, 0x85EDu, 0x872Eu, 0x8BFAu, - 0x8D77u, 0x9145u, 0x91DFu, 0x921Au, 0x940Au, 0x9496u, 0x95B6u, 0x9B30u, - 0xA0CEu, 0xA105u, 0xA20Eu, 0xA291u, 0xA392u, 0xA600u, + 0x0122, 0x051C, 0x0525, 0x054B, 0x063A, 0x0804, 0x08DE, 0x0A2C, + 0x0B63, 0x14E4, 0x16A8, 0x16EA, 0x19C8, 0x1B18, 0x1D0B, 0x1DE4, + 0x1DE6, 0x2183, 0x219F, 0x2331, 0x26D4, 0x2844, 0x284A, 0x2B0C, + 0x2BF1, 0x300A, 0x32B8, 0x335F, 0x3393, 0x339C, 0x33C3, 0x33D5, + 0x346D, 0x36A3, 0x38A7, 0x3A8D, 0x3AFA, 0x3CBC, 0x3D1E, 0x3ED1, + 0x3F5E, 0x3F8E, 0x4263, 0x42EE, 0x43AB, 0x4608, 0x4735, 0x4814, + 0x4C36, 0x4C92, 0x4FA1, 0x4FB8, 0x5044, 0x50F2, 0x50F3, 0x5119, + 0x5133, 0x5249, 0x541D, 0x5626, 0x569A, 0x56C5, 0x597C, 0x5AA7, + 0x5BAB, 0x5C80, 0x5CD0, 0x5F86, 0x61DA, 0x6228, 0x6247, 0x62D9, + 0x633E, 0x64DA, 0x6523, 0x65A8, 0x67A7, 0x67B5, 0x6B3C, 0x6C36, + 0x6CD5, 0x6D6B, 0x6F2C, 0x6FB1, 0x70D2, 0x73CA, 0x7667, 0x78AE, + 0x7966, 0x7CA8, 0x7ED3, 0x7F2F, 0x85D2, 0x85ED, 0x872E, 0x8BFA, + 0x8D77, 0x9145, 0x91DF, 0x921A, 0x940A, 0x9496, 0x95B6, 0x9B30, + 0xA0CE, 0xA105, 0xA20E, 0xA291, 0xA392, 0xA600, }; -static const uint32_t -_hb_ucd_dm2_u32_map[638] = +static const uint32_t _hb_ucd_dm2_u32_map[638]= { - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Cu, 0x0338u, 0x226Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Du, 0x0338u, 0x2260u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Eu, 0x0338u, 0x226Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0300u, 0x00C0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0301u, 0x00C1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0302u, 0x00C2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0303u, 0x00C3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0304u, 0x0100u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0306u, 0x0102u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0307u, 0x0226u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0308u, 0x00C4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0309u, 0x1EA2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Au, 0x00C5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Cu, 0x01CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Fu, 0x0200u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0311u, 0x0202u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0323u, 0x1EA0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0325u, 0x1E00u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0328u, 0x0104u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0307u, 0x1E02u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0323u, 0x1E04u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0331u, 0x1E06u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0301u, 0x0106u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0302u, 0x0108u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0307u, 0x010Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x030Cu, 0x010Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0327u, 0x00C7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0307u, 0x1E0Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x030Cu, 0x010Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0323u, 0x1E0Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0327u, 0x1E10u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x032Du, 0x1E12u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0331u, 0x1E0Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0300u, 0x00C8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0301u, 0x00C9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0302u, 0x00CAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0303u, 0x1EBCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0304u, 0x0112u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0306u, 0x0114u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0307u, 0x0116u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0308u, 0x00CBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0309u, 0x1EBAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Cu, 0x011Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Fu, 0x0204u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0311u, 0x0206u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0323u, 0x1EB8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0327u, 0x0228u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0328u, 0x0118u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x032Du, 0x1E18u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0330u, 0x1E1Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0046u, 0x0307u, 0x1E1Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0301u, 0x01F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0302u, 0x011Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0304u, 0x1E20u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0306u, 0x011Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0307u, 0x0120u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x030Cu, 0x01E6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0327u, 0x0122u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0302u, 0x0124u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0307u, 0x1E22u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0308u, 0x1E26u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x030Cu, 0x021Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0323u, 0x1E24u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0327u, 0x1E28u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x032Eu, 0x1E2Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0300u, 0x00CCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0301u, 0x00CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0302u, 0x00CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0303u, 0x0128u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0304u, 0x012Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0306u, 0x012Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0307u, 0x0130u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0308u, 0x00CFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0309u, 0x1EC8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Cu, 0x01CFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Fu, 0x0208u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0311u, 0x020Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0323u, 0x1ECAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0328u, 0x012Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0330u, 0x1E2Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Au, 0x0302u, 0x0134u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0301u, 0x1E30u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x030Cu, 0x01E8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0323u, 0x1E32u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0327u, 0x0136u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0331u, 0x1E34u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0301u, 0x0139u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x030Cu, 0x013Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0323u, 0x1E36u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0327u, 0x013Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x032Du, 0x1E3Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0331u, 0x1E3Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0301u, 0x1E3Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0307u, 0x1E40u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0323u, 0x1E42u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0300u, 0x01F8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0301u, 0x0143u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0303u, 0x00D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0307u, 0x1E44u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x030Cu, 0x0147u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0323u, 0x1E46u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0327u, 0x0145u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x032Du, 0x1E4Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0331u, 0x1E48u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0300u, 0x00D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0301u, 0x00D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0302u, 0x00D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0303u, 0x00D5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0304u, 0x014Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0306u, 0x014Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0307u, 0x022Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0308u, 0x00D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0309u, 0x1ECEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Bu, 0x0150u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Cu, 0x01D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Fu, 0x020Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0311u, 0x020Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x031Bu, 0x01A0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0323u, 0x1ECCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0328u, 0x01EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0301u, 0x1E54u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0307u, 0x1E56u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0301u, 0x0154u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0307u, 0x1E58u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Cu, 0x0158u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Fu, 0x0210u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0311u, 0x0212u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0323u, 0x1E5Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0327u, 0x0156u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0331u, 0x1E5Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0301u, 0x015Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0302u, 0x015Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0307u, 0x1E60u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x030Cu, 0x0160u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0323u, 0x1E62u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0326u, 0x0218u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0327u, 0x015Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0307u, 0x1E6Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x030Cu, 0x0164u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0323u, 0x1E6Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0326u, 0x021Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0327u, 0x0162u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x032Du, 0x1E70u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0331u, 0x1E6Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0300u, 0x00D9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0301u, 0x00DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0302u, 0x00DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0303u, 0x0168u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0304u, 0x016Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0306u, 0x016Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0308u, 0x00DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0309u, 0x1EE6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Au, 0x016Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Bu, 0x0170u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Cu, 0x01D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Fu, 0x0214u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0311u, 0x0216u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x031Bu, 0x01AFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0323u, 0x1EE4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0324u, 0x1E72u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0328u, 0x0172u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x032Du, 0x1E76u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0330u, 0x1E74u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0303u, 0x1E7Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0323u, 0x1E7Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0300u, 0x1E80u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0301u, 0x1E82u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0302u, 0x0174u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0307u, 0x1E86u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0308u, 0x1E84u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0323u, 0x1E88u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0307u, 0x1E8Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0308u, 0x1E8Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0300u, 0x1EF2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0301u, 0x00DDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0302u, 0x0176u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0303u, 0x1EF8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0304u, 0x0232u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0307u, 0x1E8Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0308u, 0x0178u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0309u, 0x1EF6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0323u, 0x1EF4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0301u, 0x0179u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0302u, 0x1E90u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0307u, 0x017Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x030Cu, 0x017Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0323u, 0x1E92u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0331u, 0x1E94u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0300u, 0x00E0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0301u, 0x00E1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0302u, 0x00E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0303u, 0x00E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0304u, 0x0101u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0306u, 0x0103u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0307u, 0x0227u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0308u, 0x00E4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0309u, 0x1EA3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Au, 0x00E5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Cu, 0x01CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Fu, 0x0201u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0311u, 0x0203u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0323u, 0x1EA1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0325u, 0x1E01u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0328u, 0x0105u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0307u, 0x1E03u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0323u, 0x1E05u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0331u, 0x1E07u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0301u, 0x0107u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0302u, 0x0109u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0307u, 0x010Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x030Cu, 0x010Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0327u, 0x00E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0307u, 0x1E0Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x030Cu, 0x010Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0323u, 0x1E0Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0327u, 0x1E11u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x032Du, 0x1E13u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0331u, 0x1E0Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0300u, 0x00E8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0301u, 0x00E9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0302u, 0x00EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0303u, 0x1EBDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0304u, 0x0113u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0306u, 0x0115u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0307u, 0x0117u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0308u, 0x00EBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0309u, 0x1EBBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Cu, 0x011Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Fu, 0x0205u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0311u, 0x0207u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0323u, 0x1EB9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0327u, 0x0229u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0328u, 0x0119u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x032Du, 0x1E19u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0330u, 0x1E1Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0066u, 0x0307u, 0x1E1Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0301u, 0x01F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0302u, 0x011Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0304u, 0x1E21u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0306u, 0x011Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0307u, 0x0121u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x030Cu, 0x01E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0327u, 0x0123u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0302u, 0x0125u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0307u, 0x1E23u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0308u, 0x1E27u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x030Cu, 0x021Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0323u, 0x1E25u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0327u, 0x1E29u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x032Eu, 0x1E2Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0331u, 0x1E96u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0300u, 0x00ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0301u, 0x00EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0302u, 0x00EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0303u, 0x0129u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0304u, 0x012Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0306u, 0x012Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0308u, 0x00EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0309u, 0x1EC9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Cu, 0x01D0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Fu, 0x0209u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0311u, 0x020Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0323u, 0x1ECBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0328u, 0x012Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0330u, 0x1E2Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x0302u, 0x0135u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x030Cu, 0x01F0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0301u, 0x1E31u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x030Cu, 0x01E9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0323u, 0x1E33u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0327u, 0x0137u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0331u, 0x1E35u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0301u, 0x013Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x030Cu, 0x013Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0323u, 0x1E37u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0327u, 0x013Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x032Du, 0x1E3Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0331u, 0x1E3Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0301u, 0x1E3Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0307u, 0x1E41u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0323u, 0x1E43u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0300u, 0x01F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0301u, 0x0144u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0303u, 0x00F1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0307u, 0x1E45u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x030Cu, 0x0148u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0323u, 0x1E47u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0327u, 0x0146u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x032Du, 0x1E4Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0331u, 0x1E49u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0300u, 0x00F2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0301u, 0x00F3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0302u, 0x00F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0303u, 0x00F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0304u, 0x014Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0306u, 0x014Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0307u, 0x022Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0308u, 0x00F6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0309u, 0x1ECFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Bu, 0x0151u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Cu, 0x01D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Fu, 0x020Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0311u, 0x020Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x031Bu, 0x01A1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0323u, 0x1ECDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0328u, 0x01EBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0301u, 0x1E55u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0307u, 0x1E57u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0301u, 0x0155u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0307u, 0x1E59u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Cu, 0x0159u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Fu, 0x0211u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0311u, 0x0213u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0323u, 0x1E5Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0327u, 0x0157u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0331u, 0x1E5Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0301u, 0x015Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0302u, 0x015Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0307u, 0x1E61u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x030Cu, 0x0161u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0323u, 0x1E63u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0326u, 0x0219u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0327u, 0x015Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0307u, 0x1E6Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0308u, 0x1E97u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x030Cu, 0x0165u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0323u, 0x1E6Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0326u, 0x021Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0327u, 0x0163u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x032Du, 0x1E71u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0331u, 0x1E6Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0300u, 0x00F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0301u, 0x00FAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0302u, 0x00FBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0303u, 0x0169u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0304u, 0x016Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0306u, 0x016Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0308u, 0x00FCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0309u, 0x1EE7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Au, 0x016Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Bu, 0x0171u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Cu, 0x01D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Fu, 0x0215u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0311u, 0x0217u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x031Bu, 0x01B0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0323u, 0x1EE5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0324u, 0x1E73u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0328u, 0x0173u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x032Du, 0x1E77u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0330u, 0x1E75u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0303u, 0x1E7Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0323u, 0x1E7Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0300u, 0x1E81u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0301u, 0x1E83u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0302u, 0x0175u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0307u, 0x1E87u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0308u, 0x1E85u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x030Au, 0x1E98u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0323u, 0x1E89u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0307u, 0x1E8Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0308u, 0x1E8Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0300u, 0x1EF3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0301u, 0x00FDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0302u, 0x0177u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0303u, 0x1EF9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0304u, 0x0233u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0307u, 0x1E8Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0308u, 0x00FFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0309u, 0x1EF7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x030Au, 0x1E99u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0323u, 0x1EF5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0301u, 0x017Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0302u, 0x1E91u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0307u, 0x017Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x030Cu, 0x017Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0323u, 0x1E93u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0331u, 0x1E95u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0300u, 0x1FEDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0301u, 0x0385u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0342u, 0x1FC1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0300u, 0x1EA6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0301u, 0x1EA4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0303u, 0x1EAAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0309u, 0x1EA8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4u, 0x0304u, 0x01DEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5u, 0x0301u, 0x01FAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0301u, 0x01FCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0304u, 0x01E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7u, 0x0301u, 0x1E08u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0300u, 0x1EC0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0301u, 0x1EBEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0303u, 0x1EC4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0309u, 0x1EC2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CFu, 0x0301u, 0x1E2Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0300u, 0x1ED2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0301u, 0x1ED0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0303u, 0x1ED6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0309u, 0x1ED4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0301u, 0x1E4Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0304u, 0x022Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0308u, 0x1E4Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6u, 0x0304u, 0x022Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8u, 0x0301u, 0x01FEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0300u, 0x01DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0301u, 0x01D7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0304u, 0x01D5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x030Cu, 0x01D9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0300u, 0x1EA7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0301u, 0x1EA5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0303u, 0x1EABu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0309u, 0x1EA9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4u, 0x0304u, 0x01DFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5u, 0x0301u, 0x01FBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0301u, 0x01FDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0304u, 0x01E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7u, 0x0301u, 0x1E09u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0300u, 0x1EC1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0301u, 0x1EBFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0303u, 0x1EC5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0309u, 0x1EC3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EFu, 0x0301u, 0x1E2Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0300u, 0x1ED3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0301u, 0x1ED1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0303u, 0x1ED7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0309u, 0x1ED5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0301u, 0x1E4Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0304u, 0x022Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0308u, 0x1E4Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6u, 0x0304u, 0x022Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8u, 0x0301u, 0x01FFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0300u, 0x01DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0301u, 0x01D8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0304u, 0x01D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x030Cu, 0x01DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0300u, 0x1EB0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0301u, 0x1EAEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0303u, 0x1EB4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0309u, 0x1EB2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0300u, 0x1EB1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0301u, 0x1EAFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0303u, 0x1EB5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0309u, 0x1EB3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0300u, 0x1E14u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0301u, 0x1E16u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0300u, 0x1E15u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0301u, 0x1E17u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0300u, 0x1E50u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0301u, 0x1E52u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0300u, 0x1E51u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0301u, 0x1E53u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x015Au, 0x0307u, 0x1E64u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x015Bu, 0x0307u, 0x1E65u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0160u, 0x0307u, 0x1E66u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0161u, 0x0307u, 0x1E67u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0168u, 0x0301u, 0x1E78u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0169u, 0x0301u, 0x1E79u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x016Au, 0x0308u, 0x1E7Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x016Bu, 0x0308u, 0x1E7Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x017Fu, 0x0307u, 0x1E9Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0300u, 0x1EDCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0301u, 0x1EDAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0303u, 0x1EE0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0309u, 0x1EDEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0323u, 0x1EE2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0300u, 0x1EDDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0301u, 0x1EDBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0303u, 0x1EE1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0309u, 0x1EDFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0323u, 0x1EE3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0300u, 0x1EEAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0301u, 0x1EE8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0303u, 0x1EEEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0309u, 0x1EECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0323u, 0x1EF0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0300u, 0x1EEBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0301u, 0x1EE9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0303u, 0x1EEFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0309u, 0x1EEDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0323u, 0x1EF1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7u, 0x030Cu, 0x01EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01EAu, 0x0304u, 0x01ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01EBu, 0x0304u, 0x01EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0226u, 0x0304u, 0x01E0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0227u, 0x0304u, 0x01E1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0228u, 0x0306u, 0x1E1Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0229u, 0x0306u, 0x1E1Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x022Eu, 0x0304u, 0x0230u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x022Fu, 0x0304u, 0x0231u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0292u, 0x030Cu, 0x01EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0308u, 0x0301u, 0x0000u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0300u, 0x1FBAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0301u, 0x0386u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0304u, 0x1FB9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0306u, 0x1FB8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0313u, 0x1F08u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0314u, 0x1F09u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0345u, 0x1FBCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0300u, 0x1FC8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0301u, 0x0388u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0313u, 0x1F18u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0314u, 0x1F19u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0300u, 0x1FCAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0301u, 0x0389u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0313u, 0x1F28u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0314u, 0x1F29u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0345u, 0x1FCCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0300u, 0x1FDAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0301u, 0x038Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0304u, 0x1FD9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0306u, 0x1FD8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0308u, 0x03AAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0313u, 0x1F38u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0314u, 0x1F39u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0300u, 0x1FF8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0301u, 0x038Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0313u, 0x1F48u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0314u, 0x1F49u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1u, 0x0314u, 0x1FECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0300u, 0x1FEAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0301u, 0x038Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0304u, 0x1FE9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0306u, 0x1FE8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0308u, 0x03ABu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0314u, 0x1F59u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0300u, 0x1FFAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0301u, 0x038Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0313u, 0x1F68u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0314u, 0x1F69u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0345u, 0x1FFCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03ACu, 0x0345u, 0x1FB4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03AEu, 0x0345u, 0x1FC4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0300u, 0x1F70u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0301u, 0x03ACu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0304u, 0x1FB1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0306u, 0x1FB0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0313u, 0x1F00u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0314u, 0x1F01u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0342u, 0x1FB6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0345u, 0x1FB3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0300u, 0x1F72u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0301u, 0x03ADu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0313u, 0x1F10u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0314u, 0x1F11u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0300u, 0x1F74u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0301u, 0x03AEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0313u, 0x1F20u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0314u, 0x1F21u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0342u, 0x1FC6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0345u, 0x1FC3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0300u, 0x1F76u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0301u, 0x03AFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0304u, 0x1FD1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0306u, 0x1FD0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0308u, 0x03CAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0313u, 0x1F30u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0314u, 0x1F31u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0342u, 0x1FD6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0300u, 0x1F78u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0301u, 0x03CCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0313u, 0x1F40u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0314u, 0x1F41u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0313u, 0x1FE4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0314u, 0x1FE5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0300u, 0x1F7Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0301u, 0x03CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0304u, 0x1FE1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0306u, 0x1FE0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0308u, 0x03CBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0313u, 0x1F50u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0314u, 0x1F51u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0342u, 0x1FE6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0300u, 0x1F7Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0301u, 0x03CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0313u, 0x1F60u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0314u, 0x1F61u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0342u, 0x1FF6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0345u, 0x1FF3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0300u, 0x1FD2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0301u, 0x0390u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0342u, 0x1FD7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0300u, 0x1FE2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0301u, 0x03B0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0342u, 0x1FE7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CEu, 0x0345u, 0x1FF4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0301u, 0x03D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0308u, 0x03D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0406u, 0x0308u, 0x0407u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0306u, 0x04D0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0308u, 0x04D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0413u, 0x0301u, 0x0403u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0300u, 0x0400u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0306u, 0x04D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0308u, 0x0401u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0306u, 0x04C1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0308u, 0x04DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0417u, 0x0308u, 0x04DEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0300u, 0x040Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0304u, 0x04E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0306u, 0x0419u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0308u, 0x04E4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x041Au, 0x0301u, 0x040Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x041Eu, 0x0308u, 0x04E6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0304u, 0x04EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0306u, 0x040Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0308u, 0x04F0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x030Bu, 0x04F2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0427u, 0x0308u, 0x04F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x042Bu, 0x0308u, 0x04F8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x042Du, 0x0308u, 0x04ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0306u, 0x04D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0308u, 0x04D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0433u, 0x0301u, 0x0453u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0300u, 0x0450u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0306u, 0x04D7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0308u, 0x0451u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0306u, 0x04C2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0308u, 0x04DDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0437u, 0x0308u, 0x04DFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0300u, 0x045Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0304u, 0x04E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0306u, 0x0439u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0308u, 0x04E5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x043Au, 0x0301u, 0x045Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x043Eu, 0x0308u, 0x04E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0304u, 0x04EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0306u, 0x045Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0308u, 0x04F1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x030Bu, 0x04F3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0447u, 0x0308u, 0x04F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x044Bu, 0x0308u, 0x04F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x044Du, 0x0308u, 0x04EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0456u, 0x0308u, 0x0457u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0474u, 0x030Fu, 0x0476u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0475u, 0x030Fu, 0x0477u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8u, 0x0308u, 0x04DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9u, 0x0308u, 0x04DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8u, 0x0308u, 0x04EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu), + HB_CODEPOINT_ENCODE3_11_7_14 (0x003C, 0x0338, 0x226E),HB_CODEPOINT_ENCODE3_11_7_14 (0x003D, 0x0338, 0x2260), + HB_CODEPOINT_ENCODE3_11_7_14 (0x003E, 0x0338, 0x226F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0300, 0x00C0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0301, 0x00C1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0302, 0x00C2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0303, 0x00C3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0304, 0x0100), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0306, 0x0102),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0307, 0x0226), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0308, 0x00C4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0309, 0x1EA2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030A, 0x00C5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030C, 0x01CD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030F, 0x0200),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0311, 0x0202), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0323, 0x1EA0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0325, 0x1E00), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0328, 0x0104),HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0307, 0x1E02), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0323, 0x1E04),HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0331, 0x1E06), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0301, 0x0106),HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0302, 0x0108), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0307, 0x010A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x030C, 0x010C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0327, 0x00C7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0307, 0x1E0A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x030C, 0x010E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0323, 0x1E0C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0327, 0x1E10),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x032D, 0x1E12), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0331, 0x1E0E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0300, 0x00C8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0301, 0x00C9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0302, 0x00CA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0303, 0x1EBC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0304, 0x0112), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0306, 0x0114),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0307, 0x0116), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0308, 0x00CB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0309, 0x1EBA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x030C, 0x011A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x030F, 0x0204), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0311, 0x0206),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0323, 0x1EB8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0327, 0x0228),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0328, 0x0118), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x032D, 0x1E18),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0330, 0x1E1A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0046, 0x0307, 0x1E1E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0301, 0x01F4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0302, 0x011C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0304, 0x1E20), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0306, 0x011E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0307, 0x0120), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x030C, 0x01E6),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0327, 0x0122), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0302, 0x0124),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0307, 0x1E22), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0308, 0x1E26),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x030C, 0x021E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0323, 0x1E24),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0327, 0x1E28), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x032E, 0x1E2A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0300, 0x00CC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0301, 0x00CD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0302, 0x00CE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0303, 0x0128),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0304, 0x012A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0306, 0x012C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0307, 0x0130), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0308, 0x00CF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0309, 0x1EC8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x030C, 0x01CF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x030F, 0x0208), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0311, 0x020A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0323, 0x1ECA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0328, 0x012E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0330, 0x1E2C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004A, 0x0302, 0x0134),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0301, 0x1E30), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x030C, 0x01E8),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0323, 0x1E32), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0327, 0x0136),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0331, 0x1E34), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0301, 0x0139),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x030C, 0x013D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0323, 0x1E36),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0327, 0x013B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x032D, 0x1E3C),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0331, 0x1E3A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0301, 0x1E3E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0307, 0x1E40), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0323, 0x1E42),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0300, 0x01F8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0301, 0x0143),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0303, 0x00D1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0307, 0x1E44),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x030C, 0x0147), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0323, 0x1E46),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0327, 0x0145), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x032D, 0x1E4A),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0331, 0x1E48), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0300, 0x00D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0301, 0x00D3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0302, 0x00D4),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0303, 0x00D5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0304, 0x014C),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0306, 0x014E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0307, 0x022E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0308, 0x00D6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0309, 0x1ECE),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030B, 0x0150), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030C, 0x01D1),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030F, 0x020C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0311, 0x020E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x031B, 0x01A0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0323, 0x1ECC),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0328, 0x01EA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0050, 0x0301, 0x1E54),HB_CODEPOINT_ENCODE3_11_7_14 (0x0050, 0x0307, 0x1E56), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0301, 0x0154),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0307, 0x1E58), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x030C, 0x0158),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x030F, 0x0210), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0311, 0x0212),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0323, 0x1E5A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0327, 0x0156),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0331, 0x1E5E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0301, 0x015A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0302, 0x015C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0307, 0x1E60),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x030C, 0x0160), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0323, 0x1E62),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0326, 0x0218), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0327, 0x015E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0307, 0x1E6A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x030C, 0x0164),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0323, 0x1E6C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0326, 0x021A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0327, 0x0162), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x032D, 0x1E70),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0331, 0x1E6E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0300, 0x00D9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0301, 0x00DA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0302, 0x00DB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0303, 0x0168), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0304, 0x016A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0306, 0x016C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0308, 0x00DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0309, 0x1EE6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030A, 0x016E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030B, 0x0170), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030C, 0x01D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030F, 0x0214), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0311, 0x0216),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x031B, 0x01AF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0323, 0x1EE4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0324, 0x1E72), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0328, 0x0172),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x032D, 0x1E76), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0330, 0x1E74),HB_CODEPOINT_ENCODE3_11_7_14 (0x0056, 0x0303, 0x1E7C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0056, 0x0323, 0x1E7E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0300, 0x1E80), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0301, 0x1E82),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0302, 0x0174), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0307, 0x1E86),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0308, 0x1E84), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0323, 0x1E88),HB_CODEPOINT_ENCODE3_11_7_14 (0x0058, 0x0307, 0x1E8A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0058, 0x0308, 0x1E8C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0300, 0x1EF2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0301, 0x00DD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0302, 0x0176), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0303, 0x1EF8),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0304, 0x0232), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0307, 0x1E8E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0308, 0x0178), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0309, 0x1EF6),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0323, 0x1EF4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0301, 0x0179),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0302, 0x1E90), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0307, 0x017B),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x030C, 0x017D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0323, 0x1E92),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0331, 0x1E94), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0300, 0x00E0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0301, 0x00E1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0302, 0x00E2),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0303, 0x00E3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0304, 0x0101),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0306, 0x0103), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0307, 0x0227),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0308, 0x00E4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0309, 0x1EA3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030A, 0x00E5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030C, 0x01CE),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030F, 0x0201), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0311, 0x0203),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0323, 0x1EA1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0325, 0x1E01),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0328, 0x0105), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0307, 0x1E03),HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0323, 0x1E05), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0331, 0x1E07),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0301, 0x0107), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0302, 0x0109),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0307, 0x010B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x030C, 0x010D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0327, 0x00E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0307, 0x1E0B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x030C, 0x010F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0323, 0x1E0D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0327, 0x1E11), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x032D, 0x1E13),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0331, 0x1E0F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0300, 0x00E8),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0301, 0x00E9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0302, 0x00EA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0303, 0x1EBD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0304, 0x0113),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0306, 0x0115), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0307, 0x0117),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0308, 0x00EB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0309, 0x1EBB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x030C, 0x011B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x030F, 0x0205),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0311, 0x0207), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0323, 0x1EB9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0327, 0x0229), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0328, 0x0119),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x032D, 0x1E19), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0330, 0x1E1B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0066, 0x0307, 0x1E1F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0301, 0x01F5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0302, 0x011D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0304, 0x1E21),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0306, 0x011F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0307, 0x0121),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x030C, 0x01E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0327, 0x0123),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0302, 0x0125), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0307, 0x1E23),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0308, 0x1E27), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x030C, 0x021F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0323, 0x1E25), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0327, 0x1E29),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x032E, 0x1E2B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0331, 0x1E96),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0300, 0x00EC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0301, 0x00ED),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0302, 0x00EE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0303, 0x0129),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0304, 0x012B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0306, 0x012D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0308, 0x00EF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0309, 0x1EC9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x030C, 0x01D0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x030F, 0x0209),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0311, 0x020B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0323, 0x1ECB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0328, 0x012F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0330, 0x1E2D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006A, 0x0302, 0x0135), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006A, 0x030C, 0x01F0),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0301, 0x1E31), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x030C, 0x01E9),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0323, 0x1E33), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0327, 0x0137),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0331, 0x1E35), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0301, 0x013A),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x030C, 0x013E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0323, 0x1E37),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0327, 0x013C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x032D, 0x1E3D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0331, 0x1E3B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0301, 0x1E3F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0307, 0x1E41), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0323, 0x1E43),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0300, 0x01F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0301, 0x0144),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0303, 0x00F1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0307, 0x1E45),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x030C, 0x0148), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0323, 0x1E47),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0327, 0x0146), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x032D, 0x1E4B),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0331, 0x1E49), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0300, 0x00F2),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0301, 0x00F3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0302, 0x00F4),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0303, 0x00F5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0304, 0x014D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0306, 0x014F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0307, 0x022F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0308, 0x00F6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0309, 0x1ECF),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030B, 0x0151), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030C, 0x01D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030F, 0x020D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0311, 0x020F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x031B, 0x01A1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0323, 0x1ECD),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0328, 0x01EB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0070, 0x0301, 0x1E55),HB_CODEPOINT_ENCODE3_11_7_14 (0x0070, 0x0307, 0x1E57), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0301, 0x0155),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0307, 0x1E59), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x030C, 0x0159),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x030F, 0x0211), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0311, 0x0213),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0323, 0x1E5B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0327, 0x0157),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0331, 0x1E5F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0301, 0x015B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0302, 0x015D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0307, 0x1E61),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x030C, 0x0161), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0323, 0x1E63),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0326, 0x0219), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0327, 0x015F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0307, 0x1E6B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0308, 0x1E97),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x030C, 0x0165), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0323, 0x1E6D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0326, 0x021B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0327, 0x0163),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x032D, 0x1E71), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0331, 0x1E6F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0300, 0x00F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0301, 0x00FA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0302, 0x00FB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0303, 0x0169),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0304, 0x016B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0306, 0x016D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0308, 0x00FC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0309, 0x1EE7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030A, 0x016F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030B, 0x0171),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030C, 0x01D4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030F, 0x0215),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0311, 0x0217), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x031B, 0x01B0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0323, 0x1EE5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0324, 0x1E73),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0328, 0x0173), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x032D, 0x1E77),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0330, 0x1E75), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0076, 0x0303, 0x1E7D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0076, 0x0323, 0x1E7F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0300, 0x1E81),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0301, 0x1E83), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0302, 0x0175),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0307, 0x1E87), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0308, 0x1E85),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x030A, 0x1E98), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0323, 0x1E89),HB_CODEPOINT_ENCODE3_11_7_14 (0x0078, 0x0307, 0x1E8B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0078, 0x0308, 0x1E8D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0300, 0x1EF3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0301, 0x00FD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0302, 0x0177), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0303, 0x1EF9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0304, 0x0233), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0307, 0x1E8F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0308, 0x00FF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0309, 0x1EF7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x030A, 0x1E99), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0323, 0x1EF5),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0301, 0x017A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0302, 0x1E91),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0307, 0x017C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x030C, 0x017E),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0323, 0x1E93), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0331, 0x1E95),HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0300, 0x1FED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0301, 0x0385),HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0342, 0x1FC1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0300, 0x1EA6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0301, 0x1EA4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0303, 0x1EAA),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0309, 0x1EA8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4, 0x0304, 0x01DE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5, 0x0301, 0x01FA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6, 0x0301, 0x01FC),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6, 0x0304, 0x01E2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7, 0x0301, 0x1E08),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0300, 0x1EC0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0301, 0x1EBE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0303, 0x1EC4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0309, 0x1EC2),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CF, 0x0301, 0x1E2E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0300, 0x1ED2),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0301, 0x1ED0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0303, 0x1ED6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0309, 0x1ED4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0301, 0x1E4C),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0304, 0x022C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0308, 0x1E4E),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6, 0x0304, 0x022A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8, 0x0301, 0x01FE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0300, 0x01DB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0301, 0x01D7),HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0304, 0x01D5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x030C, 0x01D9),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0300, 0x1EA7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0301, 0x1EA5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0303, 0x1EAB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0309, 0x1EA9),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4, 0x0304, 0x01DF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5, 0x0301, 0x01FB),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6, 0x0301, 0x01FD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6, 0x0304, 0x01E3),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7, 0x0301, 0x1E09), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0300, 0x1EC1),HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0301, 0x1EBF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0303, 0x1EC5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0309, 0x1EC3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EF, 0x0301, 0x1E2F),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0300, 0x1ED3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0301, 0x1ED1),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0303, 0x1ED7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0309, 0x1ED5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0301, 0x1E4D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0304, 0x022D),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0308, 0x1E4F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6, 0x0304, 0x022B),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8, 0x0301, 0x01FF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0300, 0x01DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0301, 0x01D8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0304, 0x01D6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x030C, 0x01DA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0300, 0x1EB0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0301, 0x1EAE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0303, 0x1EB4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0309, 0x1EB2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0300, 0x1EB1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0301, 0x1EAF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0303, 0x1EB5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0309, 0x1EB3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0112, 0x0300, 0x1E14),HB_CODEPOINT_ENCODE3_11_7_14 (0x0112, 0x0301, 0x1E16), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0113, 0x0300, 0x1E15),HB_CODEPOINT_ENCODE3_11_7_14 (0x0113, 0x0301, 0x1E17), + HB_CODEPOINT_ENCODE3_11_7_14 (0x014C, 0x0300, 0x1E50),HB_CODEPOINT_ENCODE3_11_7_14 (0x014C, 0x0301, 0x1E52), + HB_CODEPOINT_ENCODE3_11_7_14 (0x014D, 0x0300, 0x1E51),HB_CODEPOINT_ENCODE3_11_7_14 (0x014D, 0x0301, 0x1E53), + HB_CODEPOINT_ENCODE3_11_7_14 (0x015A, 0x0307, 0x1E64),HB_CODEPOINT_ENCODE3_11_7_14 (0x015B, 0x0307, 0x1E65), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0160, 0x0307, 0x1E66),HB_CODEPOINT_ENCODE3_11_7_14 (0x0161, 0x0307, 0x1E67), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0168, 0x0301, 0x1E78),HB_CODEPOINT_ENCODE3_11_7_14 (0x0169, 0x0301, 0x1E79), + HB_CODEPOINT_ENCODE3_11_7_14 (0x016A, 0x0308, 0x1E7A),HB_CODEPOINT_ENCODE3_11_7_14 (0x016B, 0x0308, 0x1E7B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x017F, 0x0307, 0x1E9B),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0300, 0x1EDC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0301, 0x1EDA),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0303, 0x1EE0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0309, 0x1EDE),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0323, 0x1EE2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0300, 0x1EDD),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0301, 0x1EDB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0303, 0x1EE1),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0309, 0x1EDF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0323, 0x1EE3),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0300, 0x1EEA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0301, 0x1EE8),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0303, 0x1EEE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0309, 0x1EEC),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0323, 0x1EF0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0300, 0x1EEB),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0301, 0x1EE9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0303, 0x1EEF),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0309, 0x1EED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0323, 0x1EF1),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7, 0x030C, 0x01EE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01EA, 0x0304, 0x01EC),HB_CODEPOINT_ENCODE3_11_7_14 (0x01EB, 0x0304, 0x01ED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0226, 0x0304, 0x01E0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0227, 0x0304, 0x01E1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0228, 0x0306, 0x1E1C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0229, 0x0306, 0x1E1D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x022E, 0x0304, 0x0230),HB_CODEPOINT_ENCODE3_11_7_14 (0x022F, 0x0304, 0x0231), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0292, 0x030C, 0x01EF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0308, 0x0301, 0x0000), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0300, 0x1FBA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0301, 0x0386), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0304, 0x1FB9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0306, 0x1FB8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0313, 0x1F08),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0314, 0x1F09), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0345, 0x1FBC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0300, 0x1FC8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0301, 0x0388),HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0313, 0x1F18), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0314, 0x1F19),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0300, 0x1FCA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0301, 0x0389),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0313, 0x1F28), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0314, 0x1F29),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0345, 0x1FCC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0300, 0x1FDA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0301, 0x038A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0304, 0x1FD9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0306, 0x1FD8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0308, 0x03AA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0313, 0x1F38), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0314, 0x1F39),HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0300, 0x1FF8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0301, 0x038C),HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0313, 0x1F48), + HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0314, 0x1F49),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1, 0x0314, 0x1FEC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0300, 0x1FEA),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0301, 0x038E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0304, 0x1FE9),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0306, 0x1FE8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0308, 0x03AB),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0314, 0x1F59), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0300, 0x1FFA),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0301, 0x038F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0313, 0x1F68),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0314, 0x1F69), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0345, 0x1FFC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03AC, 0x0345, 0x1FB4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03AE, 0x0345, 0x1FC4),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0300, 0x1F70), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0301, 0x03AC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0304, 0x1FB1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0306, 0x1FB0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0313, 0x1F00), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0314, 0x1F01),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0342, 0x1FB6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0345, 0x1FB3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0300, 0x1F72), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0301, 0x03AD),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0313, 0x1F10), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0314, 0x1F11),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0300, 0x1F74), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0301, 0x03AE),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0313, 0x1F20), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0314, 0x1F21),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0342, 0x1FC6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0345, 0x1FC3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0300, 0x1F76), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0301, 0x03AF),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0304, 0x1FD1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0306, 0x1FD0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0308, 0x03CA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0313, 0x1F30),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0314, 0x1F31), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0342, 0x1FD6),HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0300, 0x1F78), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0301, 0x03CC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0313, 0x1F40), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0314, 0x1F41),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1, 0x0313, 0x1FE4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1, 0x0314, 0x1FE5),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0300, 0x1F7A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0301, 0x03CD),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0304, 0x1FE1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0306, 0x1FE0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0308, 0x03CB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0313, 0x1F50),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0314, 0x1F51), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0342, 0x1FE6),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0300, 0x1F7C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0301, 0x03CE),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0313, 0x1F60), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0314, 0x1F61),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0342, 0x1FF6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0345, 0x1FF3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0300, 0x1FD2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0301, 0x0390),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0342, 0x1FD7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0300, 0x1FE2),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0301, 0x03B0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0342, 0x1FE7),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CE, 0x0345, 0x1FF4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2, 0x0301, 0x03D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2, 0x0308, 0x03D4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0406, 0x0308, 0x0407),HB_CODEPOINT_ENCODE3_11_7_14 (0x0410, 0x0306, 0x04D0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0410, 0x0308, 0x04D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x0413, 0x0301, 0x0403), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0300, 0x0400),HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0306, 0x04D6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0308, 0x0401),HB_CODEPOINT_ENCODE3_11_7_14 (0x0416, 0x0306, 0x04C1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0416, 0x0308, 0x04DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0417, 0x0308, 0x04DE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0300, 0x040D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0304, 0x04E2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0306, 0x0419),HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0308, 0x04E4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x041A, 0x0301, 0x040C),HB_CODEPOINT_ENCODE3_11_7_14 (0x041E, 0x0308, 0x04E6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0304, 0x04EE),HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0306, 0x040E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0308, 0x04F0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x030B, 0x04F2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0427, 0x0308, 0x04F4),HB_CODEPOINT_ENCODE3_11_7_14 (0x042B, 0x0308, 0x04F8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x042D, 0x0308, 0x04EC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0430, 0x0306, 0x04D1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0430, 0x0308, 0x04D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0433, 0x0301, 0x0453), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0300, 0x0450),HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0306, 0x04D7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0308, 0x0451),HB_CODEPOINT_ENCODE3_11_7_14 (0x0436, 0x0306, 0x04C2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0436, 0x0308, 0x04DD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0437, 0x0308, 0x04DF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0300, 0x045D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0304, 0x04E3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0306, 0x0439),HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0308, 0x04E5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x043A, 0x0301, 0x045C),HB_CODEPOINT_ENCODE3_11_7_14 (0x043E, 0x0308, 0x04E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0304, 0x04EF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0306, 0x045E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0308, 0x04F1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x030B, 0x04F3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0447, 0x0308, 0x04F5),HB_CODEPOINT_ENCODE3_11_7_14 (0x044B, 0x0308, 0x04F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x044D, 0x0308, 0x04ED),HB_CODEPOINT_ENCODE3_11_7_14 (0x0456, 0x0308, 0x0457), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0474, 0x030F, 0x0476),HB_CODEPOINT_ENCODE3_11_7_14 (0x0475, 0x030F, 0x0477), + HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8, 0x0308, 0x04DA),HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9, 0x0308, 0x04DB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8, 0x0308, 0x04EA),HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9, 0x0308, 0x04EB), }; -static const uint64_t -_hb_ucd_dm2_u64_map[408] = +static const uint64_t _hb_ucd_dm2_u64_map[408]= { - HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B8u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D2u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D3u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D4u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05B9u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D8u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05B4u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DCu, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DEu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E0u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E1u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E3u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BFu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E7u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E8u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C2u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05EAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05F2u, 0x05B7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0627u, 0x0653u, 0x0622u), HB_CODEPOINT_ENCODE3 (0x0627u, 0x0654u, 0x0623u), - HB_CODEPOINT_ENCODE3 (0x0627u, 0x0655u, 0x0625u), HB_CODEPOINT_ENCODE3 (0x0648u, 0x0654u, 0x0624u), - HB_CODEPOINT_ENCODE3 (0x064Au, 0x0654u, 0x0626u), HB_CODEPOINT_ENCODE3 (0x06C1u, 0x0654u, 0x06C2u), - HB_CODEPOINT_ENCODE3 (0x06D2u, 0x0654u, 0x06D3u), HB_CODEPOINT_ENCODE3 (0x06D5u, 0x0654u, 0x06C0u), - HB_CODEPOINT_ENCODE3 (0x0915u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0916u, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0917u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x091Cu, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0921u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0922u, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0928u, 0x093Cu, 0x0929u), HB_CODEPOINT_ENCODE3 (0x092Bu, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x092Fu, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0930u, 0x093Cu, 0x0931u), - HB_CODEPOINT_ENCODE3 (0x0933u, 0x093Cu, 0x0934u), HB_CODEPOINT_ENCODE3 (0x09A1u, 0x09BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x09A2u, 0x09BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x09AFu, 0x09BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09BEu, 0x09CBu), HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09D7u, 0x09CCu), - HB_CODEPOINT_ENCODE3 (0x0A16u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A17u, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0A1Cu, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A2Bu, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0A32u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A38u, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0B21u, 0x0B3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0B22u, 0x0B3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B3Eu, 0x0B4Bu), HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B56u, 0x0B48u), - HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B57u, 0x0B4Cu), HB_CODEPOINT_ENCODE3 (0x0B92u, 0x0BD7u, 0x0B94u), - HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BBEu, 0x0BCAu), HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BD7u, 0x0BCCu), - HB_CODEPOINT_ENCODE3 (0x0BC7u, 0x0BBEu, 0x0BCBu), HB_CODEPOINT_ENCODE3 (0x0C46u, 0x0C56u, 0x0C48u), - HB_CODEPOINT_ENCODE3 (0x0CBFu, 0x0CD5u, 0x0CC0u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CC2u, 0x0CCAu), - HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD5u, 0x0CC7u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD6u, 0x0CC8u), - HB_CODEPOINT_ENCODE3 (0x0CCAu, 0x0CD5u, 0x0CCBu), HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D3Eu, 0x0D4Au), - HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D57u, 0x0D4Cu), HB_CODEPOINT_ENCODE3 (0x0D47u, 0x0D3Eu, 0x0D4Bu), - HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCAu, 0x0DDAu), HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCFu, 0x0DDCu), - HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DDFu, 0x0DDEu), HB_CODEPOINT_ENCODE3 (0x0DDCu, 0x0DCAu, 0x0DDDu), - HB_CODEPOINT_ENCODE3 (0x0F40u, 0x0FB5u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F42u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F4Cu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F51u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F56u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F5Bu, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F72u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F74u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F90u, 0x0FB5u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F92u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F9Cu, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FA1u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FA6u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FABu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FB2u, 0x0F80u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FB3u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1025u, 0x102Eu, 0x1026u), - HB_CODEPOINT_ENCODE3 (0x1B05u, 0x1B35u, 0x1B06u), HB_CODEPOINT_ENCODE3 (0x1B07u, 0x1B35u, 0x1B08u), - HB_CODEPOINT_ENCODE3 (0x1B09u, 0x1B35u, 0x1B0Au), HB_CODEPOINT_ENCODE3 (0x1B0Bu, 0x1B35u, 0x1B0Cu), - HB_CODEPOINT_ENCODE3 (0x1B0Du, 0x1B35u, 0x1B0Eu), HB_CODEPOINT_ENCODE3 (0x1B11u, 0x1B35u, 0x1B12u), - HB_CODEPOINT_ENCODE3 (0x1B3Au, 0x1B35u, 0x1B3Bu), HB_CODEPOINT_ENCODE3 (0x1B3Cu, 0x1B35u, 0x1B3Du), - HB_CODEPOINT_ENCODE3 (0x1B3Eu, 0x1B35u, 0x1B40u), HB_CODEPOINT_ENCODE3 (0x1B3Fu, 0x1B35u, 0x1B41u), - HB_CODEPOINT_ENCODE3 (0x1B42u, 0x1B35u, 0x1B43u), HB_CODEPOINT_ENCODE3 (0x1E36u, 0x0304u, 0x1E38u), - HB_CODEPOINT_ENCODE3 (0x1E37u, 0x0304u, 0x1E39u), HB_CODEPOINT_ENCODE3 (0x1E5Au, 0x0304u, 0x1E5Cu), - HB_CODEPOINT_ENCODE3 (0x1E5Bu, 0x0304u, 0x1E5Du), HB_CODEPOINT_ENCODE3 (0x1E62u, 0x0307u, 0x1E68u), - HB_CODEPOINT_ENCODE3 (0x1E63u, 0x0307u, 0x1E69u), HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0302u, 0x1EACu), - HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0306u, 0x1EB6u), HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0302u, 0x1EADu), - HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0306u, 0x1EB7u), HB_CODEPOINT_ENCODE3 (0x1EB8u, 0x0302u, 0x1EC6u), - HB_CODEPOINT_ENCODE3 (0x1EB9u, 0x0302u, 0x1EC7u), HB_CODEPOINT_ENCODE3 (0x1ECCu, 0x0302u, 0x1ED8u), - HB_CODEPOINT_ENCODE3 (0x1ECDu, 0x0302u, 0x1ED9u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0300u, 0x1F02u), - HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0301u, 0x1F04u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0342u, 0x1F06u), - HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0345u, 0x1F80u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0300u, 0x1F03u), - HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0301u, 0x1F05u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0342u, 0x1F07u), - HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0345u, 0x1F81u), HB_CODEPOINT_ENCODE3 (0x1F02u, 0x0345u, 0x1F82u), - HB_CODEPOINT_ENCODE3 (0x1F03u, 0x0345u, 0x1F83u), HB_CODEPOINT_ENCODE3 (0x1F04u, 0x0345u, 0x1F84u), - HB_CODEPOINT_ENCODE3 (0x1F05u, 0x0345u, 0x1F85u), HB_CODEPOINT_ENCODE3 (0x1F06u, 0x0345u, 0x1F86u), - HB_CODEPOINT_ENCODE3 (0x1F07u, 0x0345u, 0x1F87u), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0300u, 0x1F0Au), - HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0301u, 0x1F0Cu), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0342u, 0x1F0Eu), - HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0345u, 0x1F88u), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0300u, 0x1F0Bu), - HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0301u, 0x1F0Du), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0342u, 0x1F0Fu), - HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0345u, 0x1F89u), HB_CODEPOINT_ENCODE3 (0x1F0Au, 0x0345u, 0x1F8Au), - HB_CODEPOINT_ENCODE3 (0x1F0Bu, 0x0345u, 0x1F8Bu), HB_CODEPOINT_ENCODE3 (0x1F0Cu, 0x0345u, 0x1F8Cu), - HB_CODEPOINT_ENCODE3 (0x1F0Du, 0x0345u, 0x1F8Du), HB_CODEPOINT_ENCODE3 (0x1F0Eu, 0x0345u, 0x1F8Eu), - HB_CODEPOINT_ENCODE3 (0x1F0Fu, 0x0345u, 0x1F8Fu), HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0300u, 0x1F12u), - HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0301u, 0x1F14u), HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0300u, 0x1F13u), - HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0301u, 0x1F15u), HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0300u, 0x1F1Au), - HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0301u, 0x1F1Cu), HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0300u, 0x1F1Bu), - HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0301u, 0x1F1Du), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0300u, 0x1F22u), - HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0301u, 0x1F24u), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0342u, 0x1F26u), - HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0345u, 0x1F90u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0300u, 0x1F23u), - HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0301u, 0x1F25u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0342u, 0x1F27u), - HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0345u, 0x1F91u), HB_CODEPOINT_ENCODE3 (0x1F22u, 0x0345u, 0x1F92u), - HB_CODEPOINT_ENCODE3 (0x1F23u, 0x0345u, 0x1F93u), HB_CODEPOINT_ENCODE3 (0x1F24u, 0x0345u, 0x1F94u), - HB_CODEPOINT_ENCODE3 (0x1F25u, 0x0345u, 0x1F95u), HB_CODEPOINT_ENCODE3 (0x1F26u, 0x0345u, 0x1F96u), - HB_CODEPOINT_ENCODE3 (0x1F27u, 0x0345u, 0x1F97u), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0300u, 0x1F2Au), - HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0301u, 0x1F2Cu), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0342u, 0x1F2Eu), - HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0345u, 0x1F98u), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0300u, 0x1F2Bu), - HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0301u, 0x1F2Du), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0342u, 0x1F2Fu), - HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0345u, 0x1F99u), HB_CODEPOINT_ENCODE3 (0x1F2Au, 0x0345u, 0x1F9Au), - HB_CODEPOINT_ENCODE3 (0x1F2Bu, 0x0345u, 0x1F9Bu), HB_CODEPOINT_ENCODE3 (0x1F2Cu, 0x0345u, 0x1F9Cu), - HB_CODEPOINT_ENCODE3 (0x1F2Du, 0x0345u, 0x1F9Du), HB_CODEPOINT_ENCODE3 (0x1F2Eu, 0x0345u, 0x1F9Eu), - HB_CODEPOINT_ENCODE3 (0x1F2Fu, 0x0345u, 0x1F9Fu), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0300u, 0x1F32u), - HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0301u, 0x1F34u), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0342u, 0x1F36u), - HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0300u, 0x1F33u), HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0301u, 0x1F35u), - HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0342u, 0x1F37u), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0300u, 0x1F3Au), - HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0301u, 0x1F3Cu), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0342u, 0x1F3Eu), - HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0300u, 0x1F3Bu), HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0301u, 0x1F3Du), - HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0342u, 0x1F3Fu), HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0300u, 0x1F42u), - HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0301u, 0x1F44u), HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0300u, 0x1F43u), - HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0301u, 0x1F45u), HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0300u, 0x1F4Au), - HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0301u, 0x1F4Cu), HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0300u, 0x1F4Bu), - HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0301u, 0x1F4Du), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0300u, 0x1F52u), - HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0301u, 0x1F54u), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0342u, 0x1F56u), - HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0300u, 0x1F53u), HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0301u, 0x1F55u), - HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0342u, 0x1F57u), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0300u, 0x1F5Bu), - HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0301u, 0x1F5Du), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0342u, 0x1F5Fu), - HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0300u, 0x1F62u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0301u, 0x1F64u), - HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0342u, 0x1F66u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0345u, 0x1FA0u), - HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0300u, 0x1F63u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0301u, 0x1F65u), - HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0342u, 0x1F67u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0345u, 0x1FA1u), - HB_CODEPOINT_ENCODE3 (0x1F62u, 0x0345u, 0x1FA2u), HB_CODEPOINT_ENCODE3 (0x1F63u, 0x0345u, 0x1FA3u), - HB_CODEPOINT_ENCODE3 (0x1F64u, 0x0345u, 0x1FA4u), HB_CODEPOINT_ENCODE3 (0x1F65u, 0x0345u, 0x1FA5u), - HB_CODEPOINT_ENCODE3 (0x1F66u, 0x0345u, 0x1FA6u), HB_CODEPOINT_ENCODE3 (0x1F67u, 0x0345u, 0x1FA7u), - HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0300u, 0x1F6Au), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0301u, 0x1F6Cu), - HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0342u, 0x1F6Eu), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0345u, 0x1FA8u), - HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0300u, 0x1F6Bu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0301u, 0x1F6Du), - HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0342u, 0x1F6Fu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0345u, 0x1FA9u), - HB_CODEPOINT_ENCODE3 (0x1F6Au, 0x0345u, 0x1FAAu), HB_CODEPOINT_ENCODE3 (0x1F6Bu, 0x0345u, 0x1FABu), - HB_CODEPOINT_ENCODE3 (0x1F6Cu, 0x0345u, 0x1FACu), HB_CODEPOINT_ENCODE3 (0x1F6Du, 0x0345u, 0x1FADu), - HB_CODEPOINT_ENCODE3 (0x1F6Eu, 0x0345u, 0x1FAEu), HB_CODEPOINT_ENCODE3 (0x1F6Fu, 0x0345u, 0x1FAFu), - HB_CODEPOINT_ENCODE3 (0x1F70u, 0x0345u, 0x1FB2u), HB_CODEPOINT_ENCODE3 (0x1F74u, 0x0345u, 0x1FC2u), - HB_CODEPOINT_ENCODE3 (0x1F7Cu, 0x0345u, 0x1FF2u), HB_CODEPOINT_ENCODE3 (0x1FB6u, 0x0345u, 0x1FB7u), - HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0300u, 0x1FCDu), HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0301u, 0x1FCEu), - HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0342u, 0x1FCFu), HB_CODEPOINT_ENCODE3 (0x1FC6u, 0x0345u, 0x1FC7u), - HB_CODEPOINT_ENCODE3 (0x1FF6u, 0x0345u, 0x1FF7u), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0300u, 0x1FDDu), - HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0301u, 0x1FDEu), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0342u, 0x1FDFu), - HB_CODEPOINT_ENCODE3 (0x2190u, 0x0338u, 0x219Au), HB_CODEPOINT_ENCODE3 (0x2192u, 0x0338u, 0x219Bu), - HB_CODEPOINT_ENCODE3 (0x2194u, 0x0338u, 0x21AEu), HB_CODEPOINT_ENCODE3 (0x21D0u, 0x0338u, 0x21CDu), - HB_CODEPOINT_ENCODE3 (0x21D2u, 0x0338u, 0x21CFu), HB_CODEPOINT_ENCODE3 (0x21D4u, 0x0338u, 0x21CEu), - HB_CODEPOINT_ENCODE3 (0x2203u, 0x0338u, 0x2204u), HB_CODEPOINT_ENCODE3 (0x2208u, 0x0338u, 0x2209u), - HB_CODEPOINT_ENCODE3 (0x220Bu, 0x0338u, 0x220Cu), HB_CODEPOINT_ENCODE3 (0x2223u, 0x0338u, 0x2224u), - HB_CODEPOINT_ENCODE3 (0x2225u, 0x0338u, 0x2226u), HB_CODEPOINT_ENCODE3 (0x223Cu, 0x0338u, 0x2241u), - HB_CODEPOINT_ENCODE3 (0x2243u, 0x0338u, 0x2244u), HB_CODEPOINT_ENCODE3 (0x2245u, 0x0338u, 0x2247u), - HB_CODEPOINT_ENCODE3 (0x2248u, 0x0338u, 0x2249u), HB_CODEPOINT_ENCODE3 (0x224Du, 0x0338u, 0x226Du), - HB_CODEPOINT_ENCODE3 (0x2261u, 0x0338u, 0x2262u), HB_CODEPOINT_ENCODE3 (0x2264u, 0x0338u, 0x2270u), - HB_CODEPOINT_ENCODE3 (0x2265u, 0x0338u, 0x2271u), HB_CODEPOINT_ENCODE3 (0x2272u, 0x0338u, 0x2274u), - HB_CODEPOINT_ENCODE3 (0x2273u, 0x0338u, 0x2275u), HB_CODEPOINT_ENCODE3 (0x2276u, 0x0338u, 0x2278u), - HB_CODEPOINT_ENCODE3 (0x2277u, 0x0338u, 0x2279u), HB_CODEPOINT_ENCODE3 (0x227Au, 0x0338u, 0x2280u), - HB_CODEPOINT_ENCODE3 (0x227Bu, 0x0338u, 0x2281u), HB_CODEPOINT_ENCODE3 (0x227Cu, 0x0338u, 0x22E0u), - HB_CODEPOINT_ENCODE3 (0x227Du, 0x0338u, 0x22E1u), HB_CODEPOINT_ENCODE3 (0x2282u, 0x0338u, 0x2284u), - HB_CODEPOINT_ENCODE3 (0x2283u, 0x0338u, 0x2285u), HB_CODEPOINT_ENCODE3 (0x2286u, 0x0338u, 0x2288u), - HB_CODEPOINT_ENCODE3 (0x2287u, 0x0338u, 0x2289u), HB_CODEPOINT_ENCODE3 (0x2291u, 0x0338u, 0x22E2u), - HB_CODEPOINT_ENCODE3 (0x2292u, 0x0338u, 0x22E3u), HB_CODEPOINT_ENCODE3 (0x22A2u, 0x0338u, 0x22ACu), - HB_CODEPOINT_ENCODE3 (0x22A8u, 0x0338u, 0x22ADu), HB_CODEPOINT_ENCODE3 (0x22A9u, 0x0338u, 0x22AEu), - HB_CODEPOINT_ENCODE3 (0x22ABu, 0x0338u, 0x22AFu), HB_CODEPOINT_ENCODE3 (0x22B2u, 0x0338u, 0x22EAu), - HB_CODEPOINT_ENCODE3 (0x22B3u, 0x0338u, 0x22EBu), HB_CODEPOINT_ENCODE3 (0x22B4u, 0x0338u, 0x22ECu), - HB_CODEPOINT_ENCODE3 (0x22B5u, 0x0338u, 0x22EDu), HB_CODEPOINT_ENCODE3 (0x2ADDu, 0x0338u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x3046u, 0x3099u, 0x3094u), HB_CODEPOINT_ENCODE3 (0x304Bu, 0x3099u, 0x304Cu), - HB_CODEPOINT_ENCODE3 (0x304Du, 0x3099u, 0x304Eu), HB_CODEPOINT_ENCODE3 (0x304Fu, 0x3099u, 0x3050u), - HB_CODEPOINT_ENCODE3 (0x3051u, 0x3099u, 0x3052u), HB_CODEPOINT_ENCODE3 (0x3053u, 0x3099u, 0x3054u), - HB_CODEPOINT_ENCODE3 (0x3055u, 0x3099u, 0x3056u), HB_CODEPOINT_ENCODE3 (0x3057u, 0x3099u, 0x3058u), - HB_CODEPOINT_ENCODE3 (0x3059u, 0x3099u, 0x305Au), HB_CODEPOINT_ENCODE3 (0x305Bu, 0x3099u, 0x305Cu), - HB_CODEPOINT_ENCODE3 (0x305Du, 0x3099u, 0x305Eu), HB_CODEPOINT_ENCODE3 (0x305Fu, 0x3099u, 0x3060u), - HB_CODEPOINT_ENCODE3 (0x3061u, 0x3099u, 0x3062u), HB_CODEPOINT_ENCODE3 (0x3064u, 0x3099u, 0x3065u), - HB_CODEPOINT_ENCODE3 (0x3066u, 0x3099u, 0x3067u), HB_CODEPOINT_ENCODE3 (0x3068u, 0x3099u, 0x3069u), - HB_CODEPOINT_ENCODE3 (0x306Fu, 0x3099u, 0x3070u), HB_CODEPOINT_ENCODE3 (0x306Fu, 0x309Au, 0x3071u), - HB_CODEPOINT_ENCODE3 (0x3072u, 0x3099u, 0x3073u), HB_CODEPOINT_ENCODE3 (0x3072u, 0x309Au, 0x3074u), - HB_CODEPOINT_ENCODE3 (0x3075u, 0x3099u, 0x3076u), HB_CODEPOINT_ENCODE3 (0x3075u, 0x309Au, 0x3077u), - HB_CODEPOINT_ENCODE3 (0x3078u, 0x3099u, 0x3079u), HB_CODEPOINT_ENCODE3 (0x3078u, 0x309Au, 0x307Au), - HB_CODEPOINT_ENCODE3 (0x307Bu, 0x3099u, 0x307Cu), HB_CODEPOINT_ENCODE3 (0x307Bu, 0x309Au, 0x307Du), - HB_CODEPOINT_ENCODE3 (0x309Du, 0x3099u, 0x309Eu), HB_CODEPOINT_ENCODE3 (0x30A6u, 0x3099u, 0x30F4u), - HB_CODEPOINT_ENCODE3 (0x30ABu, 0x3099u, 0x30ACu), HB_CODEPOINT_ENCODE3 (0x30ADu, 0x3099u, 0x30AEu), - HB_CODEPOINT_ENCODE3 (0x30AFu, 0x3099u, 0x30B0u), HB_CODEPOINT_ENCODE3 (0x30B1u, 0x3099u, 0x30B2u), - HB_CODEPOINT_ENCODE3 (0x30B3u, 0x3099u, 0x30B4u), HB_CODEPOINT_ENCODE3 (0x30B5u, 0x3099u, 0x30B6u), - HB_CODEPOINT_ENCODE3 (0x30B7u, 0x3099u, 0x30B8u), HB_CODEPOINT_ENCODE3 (0x30B9u, 0x3099u, 0x30BAu), - HB_CODEPOINT_ENCODE3 (0x30BBu, 0x3099u, 0x30BCu), HB_CODEPOINT_ENCODE3 (0x30BDu, 0x3099u, 0x30BEu), - HB_CODEPOINT_ENCODE3 (0x30BFu, 0x3099u, 0x30C0u), HB_CODEPOINT_ENCODE3 (0x30C1u, 0x3099u, 0x30C2u), - HB_CODEPOINT_ENCODE3 (0x30C4u, 0x3099u, 0x30C5u), HB_CODEPOINT_ENCODE3 (0x30C6u, 0x3099u, 0x30C7u), - HB_CODEPOINT_ENCODE3 (0x30C8u, 0x3099u, 0x30C9u), HB_CODEPOINT_ENCODE3 (0x30CFu, 0x3099u, 0x30D0u), - HB_CODEPOINT_ENCODE3 (0x30CFu, 0x309Au, 0x30D1u), HB_CODEPOINT_ENCODE3 (0x30D2u, 0x3099u, 0x30D3u), - HB_CODEPOINT_ENCODE3 (0x30D2u, 0x309Au, 0x30D4u), HB_CODEPOINT_ENCODE3 (0x30D5u, 0x3099u, 0x30D6u), - HB_CODEPOINT_ENCODE3 (0x30D5u, 0x309Au, 0x30D7u), HB_CODEPOINT_ENCODE3 (0x30D8u, 0x3099u, 0x30D9u), - HB_CODEPOINT_ENCODE3 (0x30D8u, 0x309Au, 0x30DAu), HB_CODEPOINT_ENCODE3 (0x30DBu, 0x3099u, 0x30DCu), - HB_CODEPOINT_ENCODE3 (0x30DBu, 0x309Au, 0x30DDu), HB_CODEPOINT_ENCODE3 (0x30EFu, 0x3099u, 0x30F7u), - HB_CODEPOINT_ENCODE3 (0x30F0u, 0x3099u, 0x30F8u), HB_CODEPOINT_ENCODE3 (0x30F1u, 0x3099u, 0x30F9u), - HB_CODEPOINT_ENCODE3 (0x30F2u, 0x3099u, 0x30FAu), HB_CODEPOINT_ENCODE3 (0x30FDu, 0x3099u, 0x30FEu), - HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C2u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x105D2u, 0x0307u, 0x105C9u), HB_CODEPOINT_ENCODE3 (0x105DAu, 0x0307u, 0x105E4u), - HB_CODEPOINT_ENCODE3 (0x11099u, 0x110BAu, 0x1109Au),HB_CODEPOINT_ENCODE3 (0x1109Bu, 0x110BAu, 0x1109Cu), - HB_CODEPOINT_ENCODE3 (0x110A5u, 0x110BAu, 0x110ABu),HB_CODEPOINT_ENCODE3 (0x11131u, 0x11127u, 0x1112Eu), - HB_CODEPOINT_ENCODE3 (0x11132u, 0x11127u, 0x1112Fu),HB_CODEPOINT_ENCODE3 (0x11347u, 0x1133Eu, 0x1134Bu), - HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x11382u, 0x113C9u, 0x11383u), - HB_CODEPOINT_ENCODE3 (0x11384u, 0x113BBu, 0x11385u),HB_CODEPOINT_ENCODE3 (0x1138Bu, 0x113C2u, 0x1138Eu), - HB_CODEPOINT_ENCODE3 (0x11390u, 0x113C9u, 0x11391u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113B8u, 0x113C7u), - HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C2u, 0x113C5u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C9u, 0x113C8u), - HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu), - HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu),HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu), - HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu),HB_CODEPOINT_ENCODE3 (0x11935u, 0x11930u, 0x11938u), - HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Eu, 0x16121u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Fu, 0x16123u), - HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16120u, 0x16125u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16129u, 0x16122u), - HB_CODEPOINT_ENCODE3 (0x16121u, 0x1611Fu, 0x16126u),HB_CODEPOINT_ENCODE3 (0x16121u, 0x16120u, 0x16128u), - HB_CODEPOINT_ENCODE3 (0x16122u, 0x1611Fu, 0x16127u),HB_CODEPOINT_ENCODE3 (0x16129u, 0x1611Fu, 0x16124u), - HB_CODEPOINT_ENCODE3 (0x16D63u, 0x16D67u, 0x16D69u),HB_CODEPOINT_ENCODE3 (0x16D67u, 0x16D67u, 0x16D68u), - HB_CODEPOINT_ENCODE3 (0x16D69u, 0x16D67u, 0x16D6Au), HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1B9u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BAu, 0x1D165u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Fu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Fu, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x05D0, 0x05B7, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D0, 0x05B8, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D0, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D1, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D1, 0x05BF, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D2, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D3, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D4, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D5, 0x05B9, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D5, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D6, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D8, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D9, 0x05B4, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D9, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DA, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05DB, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DB, 0x05BF, 0x0000), HB_CODEPOINT_ENCODE3 (0x05DC, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DE, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E0, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E1, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E3, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E4, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E4, 0x05BF, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E6, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E7, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E8, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E9, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E9, 0x05C1, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E9, 0x05C2, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05EA, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05F2, 0x05B7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0627, 0x0653, 0x0622), HB_CODEPOINT_ENCODE3 (0x0627, 0x0654, 0x0623), + HB_CODEPOINT_ENCODE3 (0x0627, 0x0655, 0x0625), HB_CODEPOINT_ENCODE3 (0x0648, 0x0654, 0x0624), + HB_CODEPOINT_ENCODE3 (0x064A, 0x0654, 0x0626), HB_CODEPOINT_ENCODE3 (0x06C1, 0x0654, 0x06C2), + HB_CODEPOINT_ENCODE3 (0x06D2, 0x0654, 0x06D3), HB_CODEPOINT_ENCODE3 (0x06D5, 0x0654, 0x06C0), + HB_CODEPOINT_ENCODE3 (0x0915, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0916, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0917, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x091C, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0921, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0922, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0928, 0x093C, 0x0929), HB_CODEPOINT_ENCODE3 (0x092B, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x092F, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0930, 0x093C, 0x0931), + HB_CODEPOINT_ENCODE3 (0x0933, 0x093C, 0x0934), HB_CODEPOINT_ENCODE3 (0x09A1, 0x09BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x09A2, 0x09BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x09AF, 0x09BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x09C7, 0x09BE, 0x09CB), HB_CODEPOINT_ENCODE3 (0x09C7, 0x09D7, 0x09CC), + HB_CODEPOINT_ENCODE3 (0x0A16, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A17, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0A1C, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A2B, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0A32, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A38, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0B21, 0x0B3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0B22, 0x0B3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B3E, 0x0B4B), HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B56, 0x0B48), + HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B57, 0x0B4C), HB_CODEPOINT_ENCODE3 (0x0B92, 0x0BD7, 0x0B94), + HB_CODEPOINT_ENCODE3 (0x0BC6, 0x0BBE, 0x0BCA), HB_CODEPOINT_ENCODE3 (0x0BC6, 0x0BD7, 0x0BCC), + HB_CODEPOINT_ENCODE3 (0x0BC7, 0x0BBE, 0x0BCB), HB_CODEPOINT_ENCODE3 (0x0C46, 0x0C56, 0x0C48), + HB_CODEPOINT_ENCODE3 (0x0CBF, 0x0CD5, 0x0CC0), HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CC2, 0x0CCA), + HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CD5, 0x0CC7), HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CD6, 0x0CC8), + HB_CODEPOINT_ENCODE3 (0x0CCA, 0x0CD5, 0x0CCB), HB_CODEPOINT_ENCODE3 (0x0D46, 0x0D3E, 0x0D4A), + HB_CODEPOINT_ENCODE3 (0x0D46, 0x0D57, 0x0D4C), HB_CODEPOINT_ENCODE3 (0x0D47, 0x0D3E, 0x0D4B), + HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DCA, 0x0DDA), HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DCF, 0x0DDC), + HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DDF, 0x0DDE), HB_CODEPOINT_ENCODE3 (0x0DDC, 0x0DCA, 0x0DDD), + HB_CODEPOINT_ENCODE3 (0x0F40, 0x0FB5, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F42, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F4C, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F51, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F56, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F5B, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F72, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F74, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F80, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F90, 0x0FB5, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F92, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F9C, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FA1, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0FA6, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FAB, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0FB2, 0x0F80, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FB3, 0x0F80, 0x0000), HB_CODEPOINT_ENCODE3 (0x1025, 0x102E, 0x1026), + HB_CODEPOINT_ENCODE3 (0x1B05, 0x1B35, 0x1B06), HB_CODEPOINT_ENCODE3 (0x1B07, 0x1B35, 0x1B08), + HB_CODEPOINT_ENCODE3 (0x1B09, 0x1B35, 0x1B0A), HB_CODEPOINT_ENCODE3 (0x1B0B, 0x1B35, 0x1B0C), + HB_CODEPOINT_ENCODE3 (0x1B0D, 0x1B35, 0x1B0E), HB_CODEPOINT_ENCODE3 (0x1B11, 0x1B35, 0x1B12), + HB_CODEPOINT_ENCODE3 (0x1B3A, 0x1B35, 0x1B3B), HB_CODEPOINT_ENCODE3 (0x1B3C, 0x1B35, 0x1B3D), + HB_CODEPOINT_ENCODE3 (0x1B3E, 0x1B35, 0x1B40), HB_CODEPOINT_ENCODE3 (0x1B3F, 0x1B35, 0x1B41), + HB_CODEPOINT_ENCODE3 (0x1B42, 0x1B35, 0x1B43), HB_CODEPOINT_ENCODE3 (0x1E36, 0x0304, 0x1E38), + HB_CODEPOINT_ENCODE3 (0x1E37, 0x0304, 0x1E39), HB_CODEPOINT_ENCODE3 (0x1E5A, 0x0304, 0x1E5C), + HB_CODEPOINT_ENCODE3 (0x1E5B, 0x0304, 0x1E5D), HB_CODEPOINT_ENCODE3 (0x1E62, 0x0307, 0x1E68), + HB_CODEPOINT_ENCODE3 (0x1E63, 0x0307, 0x1E69), HB_CODEPOINT_ENCODE3 (0x1EA0, 0x0302, 0x1EAC), + HB_CODEPOINT_ENCODE3 (0x1EA0, 0x0306, 0x1EB6), HB_CODEPOINT_ENCODE3 (0x1EA1, 0x0302, 0x1EAD), + HB_CODEPOINT_ENCODE3 (0x1EA1, 0x0306, 0x1EB7), HB_CODEPOINT_ENCODE3 (0x1EB8, 0x0302, 0x1EC6), + HB_CODEPOINT_ENCODE3 (0x1EB9, 0x0302, 0x1EC7), HB_CODEPOINT_ENCODE3 (0x1ECC, 0x0302, 0x1ED8), + HB_CODEPOINT_ENCODE3 (0x1ECD, 0x0302, 0x1ED9), HB_CODEPOINT_ENCODE3 (0x1F00, 0x0300, 0x1F02), + HB_CODEPOINT_ENCODE3 (0x1F00, 0x0301, 0x1F04), HB_CODEPOINT_ENCODE3 (0x1F00, 0x0342, 0x1F06), + HB_CODEPOINT_ENCODE3 (0x1F00, 0x0345, 0x1F80), HB_CODEPOINT_ENCODE3 (0x1F01, 0x0300, 0x1F03), + HB_CODEPOINT_ENCODE3 (0x1F01, 0x0301, 0x1F05), HB_CODEPOINT_ENCODE3 (0x1F01, 0x0342, 0x1F07), + HB_CODEPOINT_ENCODE3 (0x1F01, 0x0345, 0x1F81), HB_CODEPOINT_ENCODE3 (0x1F02, 0x0345, 0x1F82), + HB_CODEPOINT_ENCODE3 (0x1F03, 0x0345, 0x1F83), HB_CODEPOINT_ENCODE3 (0x1F04, 0x0345, 0x1F84), + HB_CODEPOINT_ENCODE3 (0x1F05, 0x0345, 0x1F85), HB_CODEPOINT_ENCODE3 (0x1F06, 0x0345, 0x1F86), + HB_CODEPOINT_ENCODE3 (0x1F07, 0x0345, 0x1F87), HB_CODEPOINT_ENCODE3 (0x1F08, 0x0300, 0x1F0A), + HB_CODEPOINT_ENCODE3 (0x1F08, 0x0301, 0x1F0C), HB_CODEPOINT_ENCODE3 (0x1F08, 0x0342, 0x1F0E), + HB_CODEPOINT_ENCODE3 (0x1F08, 0x0345, 0x1F88), HB_CODEPOINT_ENCODE3 (0x1F09, 0x0300, 0x1F0B), + HB_CODEPOINT_ENCODE3 (0x1F09, 0x0301, 0x1F0D), HB_CODEPOINT_ENCODE3 (0x1F09, 0x0342, 0x1F0F), + HB_CODEPOINT_ENCODE3 (0x1F09, 0x0345, 0x1F89), HB_CODEPOINT_ENCODE3 (0x1F0A, 0x0345, 0x1F8A), + HB_CODEPOINT_ENCODE3 (0x1F0B, 0x0345, 0x1F8B), HB_CODEPOINT_ENCODE3 (0x1F0C, 0x0345, 0x1F8C), + HB_CODEPOINT_ENCODE3 (0x1F0D, 0x0345, 0x1F8D), HB_CODEPOINT_ENCODE3 (0x1F0E, 0x0345, 0x1F8E), + HB_CODEPOINT_ENCODE3 (0x1F0F, 0x0345, 0x1F8F), HB_CODEPOINT_ENCODE3 (0x1F10, 0x0300, 0x1F12), + HB_CODEPOINT_ENCODE3 (0x1F10, 0x0301, 0x1F14), HB_CODEPOINT_ENCODE3 (0x1F11, 0x0300, 0x1F13), + HB_CODEPOINT_ENCODE3 (0x1F11, 0x0301, 0x1F15), HB_CODEPOINT_ENCODE3 (0x1F18, 0x0300, 0x1F1A), + HB_CODEPOINT_ENCODE3 (0x1F18, 0x0301, 0x1F1C), HB_CODEPOINT_ENCODE3 (0x1F19, 0x0300, 0x1F1B), + HB_CODEPOINT_ENCODE3 (0x1F19, 0x0301, 0x1F1D), HB_CODEPOINT_ENCODE3 (0x1F20, 0x0300, 0x1F22), + HB_CODEPOINT_ENCODE3 (0x1F20, 0x0301, 0x1F24), HB_CODEPOINT_ENCODE3 (0x1F20, 0x0342, 0x1F26), + HB_CODEPOINT_ENCODE3 (0x1F20, 0x0345, 0x1F90), HB_CODEPOINT_ENCODE3 (0x1F21, 0x0300, 0x1F23), + HB_CODEPOINT_ENCODE3 (0x1F21, 0x0301, 0x1F25), HB_CODEPOINT_ENCODE3 (0x1F21, 0x0342, 0x1F27), + HB_CODEPOINT_ENCODE3 (0x1F21, 0x0345, 0x1F91), HB_CODEPOINT_ENCODE3 (0x1F22, 0x0345, 0x1F92), + HB_CODEPOINT_ENCODE3 (0x1F23, 0x0345, 0x1F93), HB_CODEPOINT_ENCODE3 (0x1F24, 0x0345, 0x1F94), + HB_CODEPOINT_ENCODE3 (0x1F25, 0x0345, 0x1F95), HB_CODEPOINT_ENCODE3 (0x1F26, 0x0345, 0x1F96), + HB_CODEPOINT_ENCODE3 (0x1F27, 0x0345, 0x1F97), HB_CODEPOINT_ENCODE3 (0x1F28, 0x0300, 0x1F2A), + HB_CODEPOINT_ENCODE3 (0x1F28, 0x0301, 0x1F2C), HB_CODEPOINT_ENCODE3 (0x1F28, 0x0342, 0x1F2E), + HB_CODEPOINT_ENCODE3 (0x1F28, 0x0345, 0x1F98), HB_CODEPOINT_ENCODE3 (0x1F29, 0x0300, 0x1F2B), + HB_CODEPOINT_ENCODE3 (0x1F29, 0x0301, 0x1F2D), HB_CODEPOINT_ENCODE3 (0x1F29, 0x0342, 0x1F2F), + HB_CODEPOINT_ENCODE3 (0x1F29, 0x0345, 0x1F99), HB_CODEPOINT_ENCODE3 (0x1F2A, 0x0345, 0x1F9A), + HB_CODEPOINT_ENCODE3 (0x1F2B, 0x0345, 0x1F9B), HB_CODEPOINT_ENCODE3 (0x1F2C, 0x0345, 0x1F9C), + HB_CODEPOINT_ENCODE3 (0x1F2D, 0x0345, 0x1F9D), HB_CODEPOINT_ENCODE3 (0x1F2E, 0x0345, 0x1F9E), + HB_CODEPOINT_ENCODE3 (0x1F2F, 0x0345, 0x1F9F), HB_CODEPOINT_ENCODE3 (0x1F30, 0x0300, 0x1F32), + HB_CODEPOINT_ENCODE3 (0x1F30, 0x0301, 0x1F34), HB_CODEPOINT_ENCODE3 (0x1F30, 0x0342, 0x1F36), + HB_CODEPOINT_ENCODE3 (0x1F31, 0x0300, 0x1F33), HB_CODEPOINT_ENCODE3 (0x1F31, 0x0301, 0x1F35), + HB_CODEPOINT_ENCODE3 (0x1F31, 0x0342, 0x1F37), HB_CODEPOINT_ENCODE3 (0x1F38, 0x0300, 0x1F3A), + HB_CODEPOINT_ENCODE3 (0x1F38, 0x0301, 0x1F3C), HB_CODEPOINT_ENCODE3 (0x1F38, 0x0342, 0x1F3E), + HB_CODEPOINT_ENCODE3 (0x1F39, 0x0300, 0x1F3B), HB_CODEPOINT_ENCODE3 (0x1F39, 0x0301, 0x1F3D), + HB_CODEPOINT_ENCODE3 (0x1F39, 0x0342, 0x1F3F), HB_CODEPOINT_ENCODE3 (0x1F40, 0x0300, 0x1F42), + HB_CODEPOINT_ENCODE3 (0x1F40, 0x0301, 0x1F44), HB_CODEPOINT_ENCODE3 (0x1F41, 0x0300, 0x1F43), + HB_CODEPOINT_ENCODE3 (0x1F41, 0x0301, 0x1F45), HB_CODEPOINT_ENCODE3 (0x1F48, 0x0300, 0x1F4A), + HB_CODEPOINT_ENCODE3 (0x1F48, 0x0301, 0x1F4C), HB_CODEPOINT_ENCODE3 (0x1F49, 0x0300, 0x1F4B), + HB_CODEPOINT_ENCODE3 (0x1F49, 0x0301, 0x1F4D), HB_CODEPOINT_ENCODE3 (0x1F50, 0x0300, 0x1F52), + HB_CODEPOINT_ENCODE3 (0x1F50, 0x0301, 0x1F54), HB_CODEPOINT_ENCODE3 (0x1F50, 0x0342, 0x1F56), + HB_CODEPOINT_ENCODE3 (0x1F51, 0x0300, 0x1F53), HB_CODEPOINT_ENCODE3 (0x1F51, 0x0301, 0x1F55), + HB_CODEPOINT_ENCODE3 (0x1F51, 0x0342, 0x1F57), HB_CODEPOINT_ENCODE3 (0x1F59, 0x0300, 0x1F5B), + HB_CODEPOINT_ENCODE3 (0x1F59, 0x0301, 0x1F5D), HB_CODEPOINT_ENCODE3 (0x1F59, 0x0342, 0x1F5F), + HB_CODEPOINT_ENCODE3 (0x1F60, 0x0300, 0x1F62), HB_CODEPOINT_ENCODE3 (0x1F60, 0x0301, 0x1F64), + HB_CODEPOINT_ENCODE3 (0x1F60, 0x0342, 0x1F66), HB_CODEPOINT_ENCODE3 (0x1F60, 0x0345, 0x1FA0), + HB_CODEPOINT_ENCODE3 (0x1F61, 0x0300, 0x1F63), HB_CODEPOINT_ENCODE3 (0x1F61, 0x0301, 0x1F65), + HB_CODEPOINT_ENCODE3 (0x1F61, 0x0342, 0x1F67), HB_CODEPOINT_ENCODE3 (0x1F61, 0x0345, 0x1FA1), + HB_CODEPOINT_ENCODE3 (0x1F62, 0x0345, 0x1FA2), HB_CODEPOINT_ENCODE3 (0x1F63, 0x0345, 0x1FA3), + HB_CODEPOINT_ENCODE3 (0x1F64, 0x0345, 0x1FA4), HB_CODEPOINT_ENCODE3 (0x1F65, 0x0345, 0x1FA5), + HB_CODEPOINT_ENCODE3 (0x1F66, 0x0345, 0x1FA6), HB_CODEPOINT_ENCODE3 (0x1F67, 0x0345, 0x1FA7), + HB_CODEPOINT_ENCODE3 (0x1F68, 0x0300, 0x1F6A), HB_CODEPOINT_ENCODE3 (0x1F68, 0x0301, 0x1F6C), + HB_CODEPOINT_ENCODE3 (0x1F68, 0x0342, 0x1F6E), HB_CODEPOINT_ENCODE3 (0x1F68, 0x0345, 0x1FA8), + HB_CODEPOINT_ENCODE3 (0x1F69, 0x0300, 0x1F6B), HB_CODEPOINT_ENCODE3 (0x1F69, 0x0301, 0x1F6D), + HB_CODEPOINT_ENCODE3 (0x1F69, 0x0342, 0x1F6F), HB_CODEPOINT_ENCODE3 (0x1F69, 0x0345, 0x1FA9), + HB_CODEPOINT_ENCODE3 (0x1F6A, 0x0345, 0x1FAA), HB_CODEPOINT_ENCODE3 (0x1F6B, 0x0345, 0x1FAB), + HB_CODEPOINT_ENCODE3 (0x1F6C, 0x0345, 0x1FAC), HB_CODEPOINT_ENCODE3 (0x1F6D, 0x0345, 0x1FAD), + HB_CODEPOINT_ENCODE3 (0x1F6E, 0x0345, 0x1FAE), HB_CODEPOINT_ENCODE3 (0x1F6F, 0x0345, 0x1FAF), + HB_CODEPOINT_ENCODE3 (0x1F70, 0x0345, 0x1FB2), HB_CODEPOINT_ENCODE3 (0x1F74, 0x0345, 0x1FC2), + HB_CODEPOINT_ENCODE3 (0x1F7C, 0x0345, 0x1FF2), HB_CODEPOINT_ENCODE3 (0x1FB6, 0x0345, 0x1FB7), + HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0300, 0x1FCD), HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0301, 0x1FCE), + HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0342, 0x1FCF), HB_CODEPOINT_ENCODE3 (0x1FC6, 0x0345, 0x1FC7), + HB_CODEPOINT_ENCODE3 (0x1FF6, 0x0345, 0x1FF7), HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0300, 0x1FDD), + HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0301, 0x1FDE), HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0342, 0x1FDF), + HB_CODEPOINT_ENCODE3 (0x2190, 0x0338, 0x219A), HB_CODEPOINT_ENCODE3 (0x2192, 0x0338, 0x219B), + HB_CODEPOINT_ENCODE3 (0x2194, 0x0338, 0x21AE), HB_CODEPOINT_ENCODE3 (0x21D0, 0x0338, 0x21CD), + HB_CODEPOINT_ENCODE3 (0x21D2, 0x0338, 0x21CF), HB_CODEPOINT_ENCODE3 (0x21D4, 0x0338, 0x21CE), + HB_CODEPOINT_ENCODE3 (0x2203, 0x0338, 0x2204), HB_CODEPOINT_ENCODE3 (0x2208, 0x0338, 0x2209), + HB_CODEPOINT_ENCODE3 (0x220B, 0x0338, 0x220C), HB_CODEPOINT_ENCODE3 (0x2223, 0x0338, 0x2224), + HB_CODEPOINT_ENCODE3 (0x2225, 0x0338, 0x2226), HB_CODEPOINT_ENCODE3 (0x223C, 0x0338, 0x2241), + HB_CODEPOINT_ENCODE3 (0x2243, 0x0338, 0x2244), HB_CODEPOINT_ENCODE3 (0x2245, 0x0338, 0x2247), + HB_CODEPOINT_ENCODE3 (0x2248, 0x0338, 0x2249), HB_CODEPOINT_ENCODE3 (0x224D, 0x0338, 0x226D), + HB_CODEPOINT_ENCODE3 (0x2261, 0x0338, 0x2262), HB_CODEPOINT_ENCODE3 (0x2264, 0x0338, 0x2270), + HB_CODEPOINT_ENCODE3 (0x2265, 0x0338, 0x2271), HB_CODEPOINT_ENCODE3 (0x2272, 0x0338, 0x2274), + HB_CODEPOINT_ENCODE3 (0x2273, 0x0338, 0x2275), HB_CODEPOINT_ENCODE3 (0x2276, 0x0338, 0x2278), + HB_CODEPOINT_ENCODE3 (0x2277, 0x0338, 0x2279), HB_CODEPOINT_ENCODE3 (0x227A, 0x0338, 0x2280), + HB_CODEPOINT_ENCODE3 (0x227B, 0x0338, 0x2281), HB_CODEPOINT_ENCODE3 (0x227C, 0x0338, 0x22E0), + HB_CODEPOINT_ENCODE3 (0x227D, 0x0338, 0x22E1), HB_CODEPOINT_ENCODE3 (0x2282, 0x0338, 0x2284), + HB_CODEPOINT_ENCODE3 (0x2283, 0x0338, 0x2285), HB_CODEPOINT_ENCODE3 (0x2286, 0x0338, 0x2288), + HB_CODEPOINT_ENCODE3 (0x2287, 0x0338, 0x2289), HB_CODEPOINT_ENCODE3 (0x2291, 0x0338, 0x22E2), + HB_CODEPOINT_ENCODE3 (0x2292, 0x0338, 0x22E3), HB_CODEPOINT_ENCODE3 (0x22A2, 0x0338, 0x22AC), + HB_CODEPOINT_ENCODE3 (0x22A8, 0x0338, 0x22AD), HB_CODEPOINT_ENCODE3 (0x22A9, 0x0338, 0x22AE), + HB_CODEPOINT_ENCODE3 (0x22AB, 0x0338, 0x22AF), HB_CODEPOINT_ENCODE3 (0x22B2, 0x0338, 0x22EA), + HB_CODEPOINT_ENCODE3 (0x22B3, 0x0338, 0x22EB), HB_CODEPOINT_ENCODE3 (0x22B4, 0x0338, 0x22EC), + HB_CODEPOINT_ENCODE3 (0x22B5, 0x0338, 0x22ED), HB_CODEPOINT_ENCODE3 (0x2ADD, 0x0338, 0x0000), + HB_CODEPOINT_ENCODE3 (0x3046, 0x3099, 0x3094), HB_CODEPOINT_ENCODE3 (0x304B, 0x3099, 0x304C), + HB_CODEPOINT_ENCODE3 (0x304D, 0x3099, 0x304E), HB_CODEPOINT_ENCODE3 (0x304F, 0x3099, 0x3050), + HB_CODEPOINT_ENCODE3 (0x3051, 0x3099, 0x3052), HB_CODEPOINT_ENCODE3 (0x3053, 0x3099, 0x3054), + HB_CODEPOINT_ENCODE3 (0x3055, 0x3099, 0x3056), HB_CODEPOINT_ENCODE3 (0x3057, 0x3099, 0x3058), + HB_CODEPOINT_ENCODE3 (0x3059, 0x3099, 0x305A), HB_CODEPOINT_ENCODE3 (0x305B, 0x3099, 0x305C), + HB_CODEPOINT_ENCODE3 (0x305D, 0x3099, 0x305E), HB_CODEPOINT_ENCODE3 (0x305F, 0x3099, 0x3060), + HB_CODEPOINT_ENCODE3 (0x3061, 0x3099, 0x3062), HB_CODEPOINT_ENCODE3 (0x3064, 0x3099, 0x3065), + HB_CODEPOINT_ENCODE3 (0x3066, 0x3099, 0x3067), HB_CODEPOINT_ENCODE3 (0x3068, 0x3099, 0x3069), + HB_CODEPOINT_ENCODE3 (0x306F, 0x3099, 0x3070), HB_CODEPOINT_ENCODE3 (0x306F, 0x309A, 0x3071), + HB_CODEPOINT_ENCODE3 (0x3072, 0x3099, 0x3073), HB_CODEPOINT_ENCODE3 (0x3072, 0x309A, 0x3074), + HB_CODEPOINT_ENCODE3 (0x3075, 0x3099, 0x3076), HB_CODEPOINT_ENCODE3 (0x3075, 0x309A, 0x3077), + HB_CODEPOINT_ENCODE3 (0x3078, 0x3099, 0x3079), HB_CODEPOINT_ENCODE3 (0x3078, 0x309A, 0x307A), + HB_CODEPOINT_ENCODE3 (0x307B, 0x3099, 0x307C), HB_CODEPOINT_ENCODE3 (0x307B, 0x309A, 0x307D), + HB_CODEPOINT_ENCODE3 (0x309D, 0x3099, 0x309E), HB_CODEPOINT_ENCODE3 (0x30A6, 0x3099, 0x30F4), + HB_CODEPOINT_ENCODE3 (0x30AB, 0x3099, 0x30AC), HB_CODEPOINT_ENCODE3 (0x30AD, 0x3099, 0x30AE), + HB_CODEPOINT_ENCODE3 (0x30AF, 0x3099, 0x30B0), HB_CODEPOINT_ENCODE3 (0x30B1, 0x3099, 0x30B2), + HB_CODEPOINT_ENCODE3 (0x30B3, 0x3099, 0x30B4), HB_CODEPOINT_ENCODE3 (0x30B5, 0x3099, 0x30B6), + HB_CODEPOINT_ENCODE3 (0x30B7, 0x3099, 0x30B8), HB_CODEPOINT_ENCODE3 (0x30B9, 0x3099, 0x30BA), + HB_CODEPOINT_ENCODE3 (0x30BB, 0x3099, 0x30BC), HB_CODEPOINT_ENCODE3 (0x30BD, 0x3099, 0x30BE), + HB_CODEPOINT_ENCODE3 (0x30BF, 0x3099, 0x30C0), HB_CODEPOINT_ENCODE3 (0x30C1, 0x3099, 0x30C2), + HB_CODEPOINT_ENCODE3 (0x30C4, 0x3099, 0x30C5), HB_CODEPOINT_ENCODE3 (0x30C6, 0x3099, 0x30C7), + HB_CODEPOINT_ENCODE3 (0x30C8, 0x3099, 0x30C9), HB_CODEPOINT_ENCODE3 (0x30CF, 0x3099, 0x30D0), + HB_CODEPOINT_ENCODE3 (0x30CF, 0x309A, 0x30D1), HB_CODEPOINT_ENCODE3 (0x30D2, 0x3099, 0x30D3), + HB_CODEPOINT_ENCODE3 (0x30D2, 0x309A, 0x30D4), HB_CODEPOINT_ENCODE3 (0x30D5, 0x3099, 0x30D6), + HB_CODEPOINT_ENCODE3 (0x30D5, 0x309A, 0x30D7), HB_CODEPOINT_ENCODE3 (0x30D8, 0x3099, 0x30D9), + HB_CODEPOINT_ENCODE3 (0x30D8, 0x309A, 0x30DA), HB_CODEPOINT_ENCODE3 (0x30DB, 0x3099, 0x30DC), + HB_CODEPOINT_ENCODE3 (0x30DB, 0x309A, 0x30DD), HB_CODEPOINT_ENCODE3 (0x30EF, 0x3099, 0x30F7), + HB_CODEPOINT_ENCODE3 (0x30F0, 0x3099, 0x30F8), HB_CODEPOINT_ENCODE3 (0x30F1, 0x3099, 0x30F9), + HB_CODEPOINT_ENCODE3 (0x30F2, 0x3099, 0x30FA), HB_CODEPOINT_ENCODE3 (0x30FD, 0x3099, 0x30FE), + HB_CODEPOINT_ENCODE3 (0xFB49, 0x05C1, 0x0000), HB_CODEPOINT_ENCODE3 (0xFB49, 0x05C2, 0x0000), + HB_CODEPOINT_ENCODE3 (0x105D2, 0x0307, 0x105C9), HB_CODEPOINT_ENCODE3 (0x105DA, 0x0307, 0x105E4), + HB_CODEPOINT_ENCODE3 (0x11099, 0x110BA, 0x1109A),HB_CODEPOINT_ENCODE3 (0x1109B, 0x110BA, 0x1109C), + HB_CODEPOINT_ENCODE3 (0x110A5, 0x110BA, 0x110AB),HB_CODEPOINT_ENCODE3 (0x11131, 0x11127, 0x1112E), + HB_CODEPOINT_ENCODE3 (0x11132, 0x11127, 0x1112F),HB_CODEPOINT_ENCODE3 (0x11347, 0x1133E, 0x1134B), + HB_CODEPOINT_ENCODE3 (0x11347, 0x11357, 0x1134C),HB_CODEPOINT_ENCODE3 (0x11382, 0x113C9, 0x11383), + HB_CODEPOINT_ENCODE3 (0x11384, 0x113BB, 0x11385),HB_CODEPOINT_ENCODE3 (0x1138B, 0x113C2, 0x1138E), + HB_CODEPOINT_ENCODE3 (0x11390, 0x113C9, 0x11391),HB_CODEPOINT_ENCODE3 (0x113C2, 0x113B8, 0x113C7), + HB_CODEPOINT_ENCODE3 (0x113C2, 0x113C2, 0x113C5),HB_CODEPOINT_ENCODE3 (0x113C2, 0x113C9, 0x113C8), + HB_CODEPOINT_ENCODE3 (0x114B9, 0x114B0, 0x114BC),HB_CODEPOINT_ENCODE3 (0x114B9, 0x114BA, 0x114BB), + HB_CODEPOINT_ENCODE3 (0x114B9, 0x114BD, 0x114BE),HB_CODEPOINT_ENCODE3 (0x115B8, 0x115AF, 0x115BA), + HB_CODEPOINT_ENCODE3 (0x115B9, 0x115AF, 0x115BB),HB_CODEPOINT_ENCODE3 (0x11935, 0x11930, 0x11938), + HB_CODEPOINT_ENCODE3 (0x1611E, 0x1611E, 0x16121),HB_CODEPOINT_ENCODE3 (0x1611E, 0x1611F, 0x16123), + HB_CODEPOINT_ENCODE3 (0x1611E, 0x16120, 0x16125),HB_CODEPOINT_ENCODE3 (0x1611E, 0x16129, 0x16122), + HB_CODEPOINT_ENCODE3 (0x16121, 0x1611F, 0x16126),HB_CODEPOINT_ENCODE3 (0x16121, 0x16120, 0x16128), + HB_CODEPOINT_ENCODE3 (0x16122, 0x1611F, 0x16127),HB_CODEPOINT_ENCODE3 (0x16129, 0x1611F, 0x16124), + HB_CODEPOINT_ENCODE3 (0x16D63, 0x16D67, 0x16D69),HB_CODEPOINT_ENCODE3 (0x16D67, 0x16D67, 0x16D68), + HB_CODEPOINT_ENCODE3 (0x16D69, 0x16D67, 0x16D6A), HB_CODEPOINT_ENCODE3 (0x1D157, 0x1D165, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D158, 0x1D165, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D16E, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D16F, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D170, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D171, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D172, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1B9, 0x1D165, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BA, 0x1D165, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1BB, 0x1D16E, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BB, 0x1D16F, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1BC, 0x1D16E, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BC, 0x1D16F, 0x0000), }; #ifndef HB_OPTIMIZE_SIZE -static const uint8_t -_hb_ucd_u8[17612] = +#include + +static const uint8_t _hb_ucd_u8[17612]= { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, @@ -2186,8 +1865,7 @@ _hb_ucd_u8[17612] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; -static const uint16_t -_hb_ucd_u16[10400] = +static const uint16_t _hb_ucd_u16[10400]= { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -2840,8 +2518,7 @@ _hb_ucd_u16[10400] = 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; -static const int16_t -_hb_ucd_i16[196] = +static const int16_t _hb_ucd_i16[196]= { 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, @@ -2858,42 +2535,37 @@ _hb_ucd_i16[196] = -1, 0, 1, -1, }; -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) +static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110 ? _hb_ucd_u8[6472u+(((_hb_ucd_u8[816u+(((_hb_ucd_u16[((_hb_ucd_u8[272u+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15))])<<4)+((u>>1>>3)&15)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2; } -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) +static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259 ? _hb_ucd_u8[8504u+(((_hb_ucd_u8[7936u+(((_hb_ucd_u8[7460u+(((_hb_ucd_u8[7100u+(((_hb_ucd_u8[6854u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0; } -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) +static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9252+(((_hb_ucd_u8[9132+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9252u+(((_hb_ucd_u8[9132u+(((_hb_ucd_b4(_hb_ucd_u8+9004u,u>>2>>3>>3))<<3)+((u>>2>>3)&7))])<<3)+((u>>2)&7))])<<2)+((u)&3)] : 0; } -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) +static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[10486+(((_hb_ucd_u16[3744+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9588+(u>>3>>3>>4)])<<4)+((u>>3>>3)&15u))])<<3)+((u>>3)&7u))])<<3)+((u)&7u))]:2; + return u<918000 ? _hb_ucd_u8[10486u+(((_hb_ucd_u16[3744u+(((_hb_ucd_u16[2624u+(((_hb_ucd_u8[9588u+(u>>3>>3>>4)])<<4)+((u>>3>>3)&15))])<<3)+((u>>3)&7))])<<3)+((u)&7))] : 2; } -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) +static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6976+(((_hb_ucd_u8[16716+(((_hb_ucd_u8[16334+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102 ? _hb_ucd_u16[6976u+(((_hb_ucd_u8[16716u+(((_hb_ucd_u8[16334u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0; } #elif !defined(HB_NO_UCD_UNASSIGNED) -static const uint8_t -_hb_ucd_u8[17524] = +#include + +static const uint8_t _hb_ucd_u8[17524]= { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, @@ -3992,8 +3664,7 @@ _hb_ucd_u8[17524] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; -static const uint16_t -_hb_ucd_u16[9668] = +static const uint16_t _hb_ucd_u16[9668]= { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -4601,8 +4272,7 @@ _hb_ucd_u16[9668] = 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; -static const int16_t -_hb_ucd_i16[92] = +static const int16_t _hb_ucd_i16[92]= { 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, @@ -4612,42 +4282,37 @@ _hb_ucd_i16[92] = 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, }; -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) +static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110 ? _hb_ucd_u8[6472u+(((_hb_ucd_u8[816u+(((_hb_ucd_u16[((_hb_ucd_u8[272u+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15))])<<4)+((u>>1>>3)&15)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2; } -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) +static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259 ? _hb_ucd_u8[8504u+(((_hb_ucd_u8[7936u+(((_hb_ucd_u8[7460u+(((_hb_ucd_u8[7100u+(((_hb_ucd_u8[6854u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0; } -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) +static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9396+(((_hb_ucd_u8[9164+(((_hb_ucd_u8[9068+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[9396u+(((_hb_ucd_u8[9164u+(((_hb_ucd_u8[9068u+(((_hb_ucd_b4(_hb_ucd_u8+9004u,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7))])<<3)+((u>>1>>2)&7))])<<2)+((u>>1)&3))])<<1)+((u)&1)] : 0; } -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) +static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[10398+(((_hb_ucd_u16[3952+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9870+(((_hb_ucd_u8[9644+(u>>3>>2>>3>>4)])<<4)+((u>>3>>2>>3)&15u))])<<3)+((u>>3>>2)&7u))])<<2)+((u>>3)&3u))])<<3)+((u)&7u))]:2; + return u<918000 ? _hb_ucd_u8[10398u+(((_hb_ucd_u16[3952u+(((_hb_ucd_u16[2624u+(((_hb_ucd_u8[9870u+(((_hb_ucd_u8[9644u+(u>>3>>2>>3>>4)])<<4)+((u>>3>>2>>3)&15))])<<3)+((u>>3>>2)&7))])<<2)+((u>>3)&3))])<<3)+((u)&7))] : 2; } -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) +static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6244+(((_hb_ucd_u8[16628+(((_hb_ucd_u8[16246+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102 ? _hb_ucd_u16[6244u+(((_hb_ucd_u8[16628u+(((_hb_ucd_u8[16246u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0; } #else -static const uint8_t -_hb_ucd_u8[13730] = +#include + +static const uint8_t _hb_ucd_u8[13730]= { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, @@ -5509,8 +5174,7 @@ _hb_ucd_u8[13730] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; -static const uint16_t -_hb_ucd_u16[5080] = +static const uint16_t _hb_ucd_u16[5080]= { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -5831,8 +5495,7 @@ _hb_ucd_u16[5080] = 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; -static const int16_t -_hb_ucd_i16[92] = +static const int16_t _hb_ucd_i16[92]= { 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, @@ -5842,40 +5505,34 @@ _hb_ucd_i16[92] = 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, }; -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) +static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114112u?_hb_ucd_u8[5208+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114112 ? _hb_ucd_u8[5208u+(((_hb_ucd_u8[1168u+(((_hb_ucd_u16[((_hb_ucd_u8[544u+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15))])<<3)+((u>>1>>3)&7)])<<3)+((u>>1)&7))])<<1)+((u)&1))] : 2; } -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) +static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[7206+(((_hb_ucd_u8[6638+(((_hb_ucd_u8[6162+(((_hb_ucd_u8[5802+(((_hb_ucd_u8[5556+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259 ? _hb_ucd_u8[7206u+(((_hb_ucd_u8[6638u+(((_hb_ucd_u8[6162u+(((_hb_ucd_u8[5802u+(((_hb_ucd_u8[5556u+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 0; } -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) +static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[8098+(((_hb_ucd_u8[7866+(((_hb_ucd_u8[7770+(((_hb_ucd_b4(7706+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380 ? _hb_ucd_i16[((_hb_ucd_u8[8098u+(((_hb_ucd_u8[7866u+(((_hb_ucd_u8[7770u+(((_hb_ucd_b4(_hb_ucd_u8+7706u,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7))])<<3)+((u>>1>>2)&7))])<<2)+((u>>1)&3))])<<1)+((u)&1)] : 0; } -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) +static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11464+(((_hb_ucd_u8[10472+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[8764+(((_hb_ucd_u8[8460+(((_hb_ucd_u8[8346+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918016 ? _hb_ucd_u8[11464u+(((_hb_ucd_u8[10472u+(((_hb_ucd_u8[9452u+(((_hb_ucd_u8[8764u+(((_hb_ucd_u8[8460u+(((_hb_ucd_u8[8346u+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15))])<<3)+((u>>2>>2>>2)&7))])<<2)+((u>>2>>2)&3))])<<2)+((u>>2)&3))])<<2)+((u)&3))] : 2; } -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) +static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1656+(((_hb_ucd_u8[12834+(((_hb_ucd_u8[12452+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102 ? _hb_ucd_u16[1656u+(((_hb_ucd_u8[12834u+(((_hb_ucd_u8[12452u+(u>>4>>5)])<<5)+((u>>4)&31))])<<4)+((u)&15))] : 0; } + #endif - #endif /* HB_UCD_TABLE_HH */ /* == End of generated table == */ diff --git a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh index 4bc8d64c28f..724917668da 100644 --- a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh +++ b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh @@ -23,8 +23,9 @@ #include "hb-unicode.hh" -static const uint8_t -_hb_emoji_u8[464] = +#include + +static const uint8_t _hb_emoji_u8[464]= { 16, 17, 17, 17, 50, 20, 21, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -57,20 +58,17 @@ _hb_emoji_u8[464] = 0,192,255,255, 0,240,255,255,255,255,255,247,191,255,255,255, }; -static inline unsigned -_hb_emoji_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_emoji_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline unsigned -_hb_emoji_b1 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_emoji_b1 (const uint8_t* a, unsigned i) { - return (a[i>>3]>>((i&7u)<<0))&1u; + return (a[i>>3]>>((i&7)<<0))&1; } -static inline uint_fast8_t -_hb_emoji_is_Extended_Pictographic (unsigned u) +static inline uint8_t _hb_emoji_is_Extended_Pictographic (unsigned u) { - return u<131070u?_hb_emoji_b1(264+_hb_emoji_u8,((_hb_emoji_u8[144+(((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>5>>2>>3))<<3)+((u>>5>>2)&7u))])<<2)+((u>>5)&3u))])<<5)+((u)&31u)):0; + return u<131070 ? _hb_emoji_b1(_hb_emoji_u8+264u,((_hb_emoji_u8[144u+(((_hb_emoji_u8[64u+(((_hb_emoji_b4(_hb_emoji_u8,u>>5>>2>>3))<<3)+((u>>5>>2)&7))])<<2)+((u>>5)&3))])<<5)+((u)&31)) : 0; } diff --git a/thirdparty/harfbuzz/src/hb-unicode.hh b/thirdparty/harfbuzz/src/hb-unicode.hh index 39aaee5baa7..485f3f52738 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.hh +++ b/thirdparty/harfbuzz/src/hb-unicode.hh @@ -241,6 +241,57 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE } } + static hb_codepoint_t + vertical_char_for (hb_codepoint_t u) + { + switch (u >> 8) + { + case 0x20: switch (u) { + case 0x2013u: return 0xfe32u; // EN DASH + case 0x2014u: return 0xfe31u; // EM DASH + case 0x2025u: return 0xfe30u; // TWO DOT LEADER + case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS + } break; + case 0x30: switch (u) { + case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA + case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP + case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET + case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET + case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET + case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET + case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET + case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET + case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET + case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET + case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET + case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET + case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET + case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET + case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET + case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET + } break; + case 0xfe: switch (u) { + case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE + } break; + case 0xff: switch (u) { + case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK + case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS + case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS + case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA + case 0xff1au: return 0xfe13u; // FULLWIDTH COLON + case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON + case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK + case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET + case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET + case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE + case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET + case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET + } break; + } + + return u; + } + struct { #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name; HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index 85d760b5f85..ce9ce4a6483 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -47,20 +47,20 @@ HB_BEGIN_DECLS * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 2 +#define HB_VERSION_MINOR 3 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 1 +#define HB_VERSION_MICRO 2 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "11.2.1" +#define HB_VERSION_STRING "11.3.2" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/harfbuzz/src/hb.hh b/thirdparty/harfbuzz/src/hb.hh index ce8d075cd4d..47b710e6740 100644 --- a/thirdparty/harfbuzz/src/hb.hh +++ b/thirdparty/harfbuzz/src/hb.hh @@ -314,6 +314,10 @@ #endif #endif +#ifndef HB_HOT +#define HB_HOT __attribute__((hot)) +#endif + /* * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch