diff --git a/make/lib/Awt2dLibraries.gmk b/make/lib/Awt2dLibraries.gmk index d50e5fa4cf0..03f03f567af 100644 --- a/make/lib/Awt2dLibraries.gmk +++ b/make/lib/Awt2dLibraries.gmk @@ -556,7 +556,10 @@ else HARFBUZZ_CFLAGS += -DHAVE_SOLARIS_ATOMIC_OPS endif # hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later. - LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc + # hb-subset and hb-style APIs are not needed, excluded to cut on compilation time. + LIBFONTMANAGER_EXCLUDE_FILES += hb-ft.cc hb-subset-cff-common.cc \ + hb-subset-cff1.cc hb-subset-cff2.cc hb-subset-input.cc hb-subset-plan.cc \ + hb-subset.cc hb-subset-instancer-solver.cc gsubgpos-context.cc hb-style.cc # list of disabled warnings and the compilers for which it was specifically added. # array-bounds -> GCC 12 on Alpine Linux @@ -564,11 +567,14 @@ else # range-loop-analysis -> clang on Xcode12 HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing \ - array-bounds + array-bounds dangling-pointer # noexcept-type required for GCC 7 builds. Not required for GCC 8+. # expansion-to-defined required for GCC 9 builds. Not required for GCC 10+. + # maybe-uninitialized required for GCC 8 builds. Not required for GCC 9+. + # calloc-transposed-args required for GCC 14 builds. (fixed upstream in Harfbuzz 032c931e1c0cfb20f18e5acb8ba005775242bd92) HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \ - maybe-uninitialized class-memaccess unused-result extra noexcept-type expansion-to-defined + maybe-uninitialized class-memaccess unused-result extra noexcept-type expansion-to-defined \ + dangling-reference maybe-uninitialized calloc-transposed-args attributes HARFBUZZ_DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \ tautological-constant-out-of-range-compare int-to-pointer-cast \ undef missing-field-initializers deprecated-declarations c++11-narrowing range-loop-analysis diff --git a/src/java.desktop/share/legal/harfbuzz.md b/src/java.desktop/share/legal/harfbuzz.md index 3ae73d215b0..2d0a28ed310 100644 --- a/src/java.desktop/share/legal/harfbuzz.md +++ b/src/java.desktop/share/legal/harfbuzz.md @@ -1,4 +1,4 @@ -## Harfbuzz v8.2.2 +## Harfbuzz v10.4.0 ### Harfbuzz License @@ -8,14 +8,14 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow. For parts of HarfBuzz that are licensed under different licenses see individual files names COPYING in subdirectories where applicable. -Copyright © 2010-2023 Google, Inc. +Copyright © 2010-2024 Google, Inc. Copyright © 2018-2020 Ebrahim Byagowi Copyright © 2004-2013 Red Hat, Inc. Copyright © 2019 Facebook, Inc. Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) Copyright © 2007 Chris Wilson Copyright © 2018-2019 Adobe Inc. -Copyright © 2006-2023 Behdad Esfahbod +Copyright © 2006-2025 Behdad Esfahbod Copyright © 1998-2004 David Turner and Werner Lemberg Copyright © 2009 Keith Stribley Copyright © 2018 Khaled Hosny @@ -54,7 +54,7 @@ exception is licensed with a slightly different MIT variant: The contents of this directory are licensed under the following terms: --------------------------------- -The below license applies to the following files: +The below applies to the following file(s): libharfbuzz/hb-ucd.cc Copyright (C) 2012 Grigori Goronzy @@ -72,13 +72,14 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --------------------------------- -The below license applies to the following files: +The below applies to the following file(s): libharfbuzz/hb-unicode-emoji-table.hh -© 2023 Unicode®, Inc. +© 2024 Unicode®, Inc. + Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -For terms of use, see https://www.unicode.org/terms_of_use.html +For terms of use and license, see https://www.unicode.org/terms_of_use.html diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh index d7b2b13e4d3..43a611a0058 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh @@ -204,6 +204,7 @@ struct IndexSubtable { TRACE_SANITIZE (this); if (!u.header.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.header.indexFormat) { case 1: return_trace (u.format1.sanitize (c, glyph_count)); @@ -378,6 +379,7 @@ struct IndexSubtableRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && firstGlyphIndex <= lastGlyphIndex && offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1)); } @@ -635,6 +637,7 @@ struct BitmapSizeTable { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && horizontal.sanitize (c) && vertical.sanitize (c)); @@ -738,7 +741,9 @@ struct CBLC { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2 || version.major == 3) && + hb_barrier () && sizeTables.sanitize (c, this)); } @@ -936,10 +941,12 @@ struct CBDT } } - bool has_data () const { return cbdt.get_length (); } + bool has_data () const { return cbdt->version.major; } bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + if (!has_data ()) return false; + hb_glyph_extents_t extents; hb_glyph_extents_t pixel_extents; hb_blob_t *blob = reference_png (font, glyph); @@ -975,6 +982,7 @@ struct CBDT { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2 || version.major == 3)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh index fb2c42a88f0..4d6272d05cb 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh @@ -29,11 +29,14 @@ #define OT_COLOR_COLR_COLR_HH #include "../../../hb.hh" +#include "../../../hb-decycler.hh" #include "../../../hb-open-type.hh" #include "../../../hb-ot-var-common.hh" #include "../../../hb-paint.hh" #include "../../../hb-paint-extents.hh" +#include "../CPAL/CPAL.hh" + /* * COLR -- Color * https://docs.microsoft.com/en-us/typography/opentype/spec/colr @@ -66,13 +69,13 @@ public: hb_paint_funcs_t *funcs; void *data; hb_font_t *font; - unsigned int palette_index; + hb_array_t palette; hb_color_t foreground; - VarStoreInstancer &instancer; - hb_map_t current_glyphs; - hb_map_t current_layers; + ItemVarStoreInstancer &instancer; + hb_decycler_t glyphs_decycler; + hb_decycler_t layers_decycler; int depth_left = HB_MAX_NESTING_LEVEL; - int edge_count = HB_COLRV1_MAX_EDGE_COUNT; + int edge_count = HB_MAX_GRAPH_EDGE_COUNT; hb_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, @@ -80,12 +83,16 @@ public: hb_font_t *font_, unsigned int palette_, hb_color_t foreground_, - VarStoreInstancer &instancer_) : + ItemVarStoreInstancer &instancer_) : base (base_), funcs (funcs_), data (data_), font (font_), - palette_index (palette_), + palette ( +#ifndef HB_NO_COLOR + font->face->table.CPAL->get_palette_colors (palette_) +#endif + ), foreground (foreground_), instancer (instancer_) { } @@ -99,12 +106,7 @@ public: if (color_index != 0xffff) { if (!funcs->custom_palette_color (data, color_index, &color)) - { - unsigned int clen = 1; - hb_face_t *face = hb_font_get_face (font); - - hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color); - } + color = palette[color_index]; *is_foreground = false; } @@ -159,23 +161,35 @@ struct hb_colrv1_closure_context_t : void add_palette_index (unsigned palette_index) { palette_indices->add (palette_index); } + void add_var_idxes (unsigned first_var_idx, unsigned num_idxes) + { + if (!num_idxes || first_var_idx == VarIdx::NO_VARIATION) return; + variation_indices->add_range (first_var_idx, first_var_idx + num_idxes - 1); + } + public: const void *base; hb_set_t visited_paint; hb_set_t *glyphs; hb_set_t *layer_indices; hb_set_t *palette_indices; + hb_set_t *variation_indices; + unsigned num_var_idxes; unsigned nesting_level_left; hb_colrv1_closure_context_t (const void *base_, hb_set_t *glyphs_, hb_set_t *layer_indices_, hb_set_t *palette_indices_, + hb_set_t *variation_indices_, + unsigned num_var_idxes_ = 1, unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) : base (base_), glyphs (glyphs_), layer_indices (layer_indices_), palette_indices (palette_indices_), + variation_indices (variation_indices_), + num_var_idxes (num_var_idxes_), nesting_level_left (nesting_level_left_) {} }; @@ -242,18 +256,33 @@ struct Variable } void closurev1 (hb_colrv1_closure_context_t* c) const - { value.closurev1 (c); } + { + c->num_var_idxes = 0; + // update c->num_var_idxes during value closure + value.closurev1 (c); + c->add_var_idxes (varIdxBase, c->num_var_idxes); + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); if (!value.subset (c, instancer, varIdxBase)) return_trace (false); if (c->plan->all_axes_pinned) return_trace (true); - //TODO: update varIdxBase for partial-instancing - return_trace (c->serializer->embed (varIdxBase)); + VarIdx new_varidx; + new_varidx = varIdxBase; + if (varIdxBase != VarIdx::NO_VARIATION) + { + hb_pair_t *new_varidx_delta; + if (!c->plan->colrv1_variation_idx_delta_map.has (varIdxBase, &new_varidx_delta)) + return_trace (false); + + new_varidx = hb_first (*new_varidx_delta); + } + + return_trace (c->serializer->embed (new_varidx)); } bool sanitize (hb_sanitize_context_t *c) const @@ -270,7 +299,7 @@ struct Variable void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *stop, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { value.get_color_stop (c, stop, varIdxBase, instancer); } @@ -305,7 +334,7 @@ struct NoVariable { value.closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); return_trace (value.subset (c, instancer, varIdxBase)); @@ -325,7 +354,7 @@ struct NoVariable void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *stop, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer); } @@ -345,10 +374,13 @@ struct NoVariable struct ColorStop { void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (paletteIndex); } + { + c->add_palette_index (paletteIndex); + c->num_var_idxes = 2; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -374,7 +406,7 @@ struct ColorStop void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *out, uint32_t varIdx, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { out->offset = stopOffset.to_float(instancer (varIdx, 0)); out->color = c->get_color (paletteIndex, @@ -410,7 +442,7 @@ struct ColorLine } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -439,7 +471,7 @@ struct ColorLine unsigned int start, unsigned int *count, hb_color_stop_t *color_stops, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { unsigned int len = stops.len; @@ -542,8 +574,11 @@ struct Affine2x3 return_trace (c->check_struct (this)); } + void closurev1 (hb_colrv1_closure_context_t* c) const + { c->num_var_idxes = 6; } + bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -588,7 +623,7 @@ struct PaintColrLayers void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer HB_UNUSED) const + const ItemVarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -617,10 +652,13 @@ struct PaintColrLayers struct PaintSolid { void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (paletteIndex); } + { + c->add_palette_index (paletteIndex); + c->num_var_idxes = 1; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -666,10 +704,13 @@ template class Var> struct PaintLinearGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 6; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -733,10 +774,13 @@ template class Var> struct PaintRadialGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 6; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -800,10 +844,13 @@ template class Var> struct PaintSweepGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { (this+colorLine).closurev1 (c); } + { + (this+colorLine).closurev1 (c); + c->num_var_idxes = 4; + } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -863,7 +910,7 @@ struct PaintGlyph void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -906,7 +953,7 @@ struct PaintColrGlyph void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer HB_UNUSED) const + const ItemVarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -936,7 +983,7 @@ struct PaintTransform HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -958,7 +1005,7 @@ struct PaintTransform void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - (this+transform).paint_glyph (c); + (this+transform).paint_glyph (c); // This does a push_transform() c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -975,7 +1022,7 @@ struct PaintTranslate HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1024,7 +1071,7 @@ struct PaintScale HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1073,7 +1120,7 @@ struct PaintScaleAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1132,7 +1179,7 @@ struct PaintScaleUniform HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1176,7 +1223,7 @@ struct PaintScaleUniformAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1232,7 +1279,7 @@ struct PaintRotate HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1276,7 +1323,7 @@ struct PaintRotateAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1332,7 +1379,7 @@ struct PaintSkew HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1381,7 +1428,7 @@ struct PaintSkewAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1440,7 +1487,7 @@ struct PaintComposite void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -1491,7 +1538,7 @@ struct ClipBoxFormat1 return_trace (c->check_struct (this)); } - void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const + void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer HB_UNUSED) const { clip_box.xMin = xMin; clip_box.yMin = yMin; @@ -1500,7 +1547,7 @@ struct ClipBoxFormat1 } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1533,7 +1580,7 @@ struct ClipBoxFormat1 struct ClipBoxFormat2 : Variable { - void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const + void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer) const { value.get_clip_box(clip_box, instancer); if (instancer) @@ -1544,12 +1591,15 @@ struct ClipBoxFormat2 : Variable clip_box.yMax += roundf (instancer (varIdxBase, 3)); } } + + void closurev1 (hb_colrv1_closure_context_t* c) const + { c->variation_indices->add_range (varIdxBase, varIdxBase + 3); } }; struct ClipBox { bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); switch (u.format) { @@ -1559,6 +1609,14 @@ struct ClipBox } } + void closurev1 (hb_colrv1_closure_context_t* c) const + { + switch (u.format) { + case 2: u.format2.closurev1 (c); + default:return; + } + } + template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { @@ -1572,7 +1630,7 @@ struct ClipBox } bool get_extents (hb_glyph_extents_t *extents, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { ClipBoxData clip_box; switch (u.format) { @@ -1606,9 +1664,15 @@ struct ClipRecord int cmp (hb_codepoint_t g) const { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; } + void closurev1 (hb_colrv1_closure_context_t* c, const void *base) const + { + if (!c->glyphs->intersects (startGlyphID, endGlyphID)) return; + (base+clipBox).closurev1 (c); + } + bool subset (hb_subset_context_t *c, const void *base, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (*this); @@ -1625,7 +1689,7 @@ struct ClipRecord bool get_extents (hb_glyph_extents_t *extents, const void *base, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { return (base+clipBox).get_extents (extents, instancer); } @@ -1642,7 +1706,7 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord); struct ClipList { unsigned serialize_clip_records (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, const hb_set_t& gids, const hb_map_t& gid_offset_map) const { @@ -1695,7 +1759,7 @@ struct ClipList } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); @@ -1735,7 +1799,7 @@ struct ClipList bool get_extents (hb_codepoint_t gid, hb_glyph_extents_t *extents, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { auto *rec = clips.as_array ().bsearch (gid); if (rec) @@ -1855,7 +1919,7 @@ struct BaseGlyphPaintRecord bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map, const void* src_base, hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SERIALIZE (this); auto *out = s->embed (this); @@ -1884,7 +1948,7 @@ struct BaseGlyphPaintRecord struct BaseGlyphList : SortedArray32Of { bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -1916,7 +1980,7 @@ struct LayerList : Array32OfOffset32To { return this+(*this)[i]; } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -1941,6 +2005,76 @@ struct LayerList : Array32OfOffset32To } }; +struct delta_set_index_map_subset_plan_t +{ + unsigned get_inner_bit_count () const { return inner_bit_count; } + unsigned get_width () const { return ((outer_bit_count + inner_bit_count + 7) / 8); } + hb_array_t get_output_map () const { return output_map.as_array (); } + + delta_set_index_map_subset_plan_t (const hb_map_t &new_deltaset_idx_varidx_map) + { + map_count = 0; + outer_bit_count = 0; + inner_bit_count = 1; + output_map.init (); + + /* search backwards */ + unsigned count = new_deltaset_idx_varidx_map.get_population (); + if (!count) return; + + unsigned last_idx = (unsigned)-1; + unsigned last_varidx = (unsigned)-1; + + for (unsigned i = count; i; i--) + { + unsigned delta_set_idx = i - 1; + unsigned var_idx = new_deltaset_idx_varidx_map.get (delta_set_idx); + if (i == count) + { + last_idx = delta_set_idx; + last_varidx = var_idx; + continue; + } + if (var_idx != last_varidx) + break; + last_idx = delta_set_idx; + } + + map_count = last_idx + 1; + } + + bool remap (const hb_map_t &new_deltaset_idx_varidx_map) + { + /* recalculate bit_count */ + outer_bit_count = 1; + inner_bit_count = 1; + + if (unlikely (!output_map.resize (map_count, false))) return false; + + for (unsigned idx = 0; idx < map_count; idx++) + { + uint32_t *var_idx; + if (!new_deltaset_idx_varidx_map.has (idx, &var_idx)) return false; + output_map.arrayZ[idx] = *var_idx; + + unsigned outer = (*var_idx) >> 16; + unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer); + outer_bit_count = hb_max (bit_count, outer_bit_count); + + unsigned inner = (*var_idx) & 0xFFFF; + bit_count = (inner == 0) ? 1 : hb_bit_storage (inner); + inner_bit_count = hb_max (bit_count, inner_bit_count); + } + return true; + } + + private: + unsigned map_count; + unsigned outer_bit_count; + unsigned inner_bit_count; + hb_vector_t output_map; +}; + struct COLR { static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR; @@ -1948,10 +2082,11 @@ struct COLR bool has_v0_data () const { return numBaseGlyphs; } bool has_v1_data () const { - if (version == 1) - return (this+baseGlyphList).len > 0; + if (version < 1) + return false; + hb_barrier (); - return false; + return (this+baseGlyphList).len > 0; } unsigned int get_glyph_layers (hb_codepoint_t glyph, @@ -1991,8 +2126,26 @@ struct COLR void closure_forV1 (hb_set_t *glyphset, hb_set_t *layer_indices, - hb_set_t *palette_indices) const - { colr->closure_forV1 (glyphset, layer_indices, palette_indices); } + hb_set_t *palette_indices, + hb_set_t *variation_indices, + hb_set_t *delta_set_indices) const + { colr->closure_forV1 (glyphset, layer_indices, palette_indices, variation_indices, delta_set_indices); } + + bool has_var_store () const + { return colr->has_var_store (); } + + const ItemVariationStore &get_var_store () const + { return colr->get_var_store (); } + const ItemVariationStore *get_var_store_ptr () const + { return colr->get_var_store_ptr (); } + + bool has_delta_set_index_map () const + { return colr->has_delta_set_index_map (); } + + const DeltaSetIndexMap &get_delta_set_index_map () const + { return colr->get_delta_set_index_map (); } + const DeltaSetIndexMap *get_delta_set_index_map_ptr () const + { return colr->get_delta_set_index_map_ptr (); } private: hb_blob_ptr_t colr; @@ -2029,12 +2182,16 @@ struct COLR void closure_forV1 (hb_set_t *glyphset, hb_set_t *layer_indices, - hb_set_t *palette_indices) const + hb_set_t *palette_indices, + hb_set_t *variation_indices, + hb_set_t *delta_set_indices) const { - if (version != 1) return; + if (version < 1) return; + hb_barrier (); + hb_set_t visited_glyphs; - hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices); + hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices, variation_indices); const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ()) @@ -2046,6 +2203,22 @@ struct COLR paint.dispatch (&c); } hb_set_union (glyphset, &visited_glyphs); + + const ClipList &cliplist = this+clipList; + c.glyphs = glyphset; + for (const ClipRecord &clip_record : cliplist.clips.iter()) + clip_record.closurev1 (&c, &cliplist); + + // if a DeltaSetIndexMap is included, collected variation indices are + // actually delta set indices, we need to map them into variation indices + if (has_delta_set_index_map ()) + { + const DeltaSetIndexMap &var_idx_map = this+varIdxMap; + delta_set_indices->set (*variation_indices); + variation_indices->clear (); + for (unsigned delta_set_idx : *delta_set_indices) + variation_indices->add (var_idx_map.map (delta_set_idx)); + } } const LayerList& get_layerList () const @@ -2054,14 +2227,37 @@ struct COLR const BaseGlyphList& get_baseglyphList () const { return (this+baseGlyphList); } + bool has_var_store () const + { return version >= 1 && hb_barrier () && varStore != 0; } + + bool has_delta_set_index_map () const + { return version >= 1 && hb_barrier () && varIdxMap != 0; } + + bool has_clip_list () const + { return version >= 1 && hb_barrier () && clipList != 0; } + + const DeltaSetIndexMap &get_delta_set_index_map () const + { return has_delta_set_index_map () && hb_barrier () ? this+varIdxMap : Null (DeltaSetIndexMap); } + const DeltaSetIndexMap *get_delta_set_index_map_ptr () const + { return has_delta_set_index_map () && hb_barrier () ? &(this+varIdxMap) : nullptr; } + + const ItemVariationStore &get_var_store () const + { return has_var_store () && hb_barrier () ? this+varStore : Null (ItemVariationStore); } + const ItemVariationStore *get_var_store_ptr () const + { return has_var_store () && hb_barrier () ? &(this+varStore) : nullptr; } + + const ClipList &get_clip_list () const + { return has_clip_list () && hb_barrier () ? this+clipList : Null (ClipList); } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && (this+layersZ).sanitize (c, numLayers) && (version == 0 || - (version == 1 && + (hb_barrier () && baseGlyphList.sanitize (c, this) && layerList.sanitize (c, this) && clipList.sanitize (c, this) && @@ -2127,6 +2323,94 @@ struct COLR return record; } + bool downgrade_to_V0 (const hb_set_t &glyphset) const + { + //no more COLRv1 glyphs, downgrade to version 0 + for (const BaseGlyphPaintRecord& _ : get_baseglyphList ()) + if (glyphset.has (_.glyphId)) + return false; + + return true; + } + + bool subset_varstore (hb_subset_context_t *c, + COLR* out /* OUT */) const + { + TRACE_SUBSET (this); + if (!varStore || c->plan->all_axes_pinned || + !c->plan->colrv1_variation_idx_delta_map) + return_trace (true); + + const ItemVariationStore& var_store = this+varStore; + if (c->plan->normalized_coords) + { + item_variations_t item_vars; + /* turn off varstore optimization when varIdxMap is null, so we maintain + * original var_idx sequence */ + bool optimize = (varIdxMap != 0) ? true : false; + if (!item_vars.instantiate (var_store, c->plan, + optimize, /* optimization */ + optimize, /* use_no_variation_idx = false */ + c->plan->colrv1_varstore_inner_maps.as_array ())) + return_trace (false); + + /* do not serialize varStore if there's no variation data after + * instancing: region_list or var_data is empty */ + if (item_vars.get_region_list () && + item_vars.get_vardata_encodings () && + !out->varStore.serialize_serialize (c->serializer, + item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ())) + return_trace (false); + + /* if varstore is optimized, update colrv1_new_deltaset_idx_varidx_map in + * subset plan. + * If varstore is empty after instancing, varidx_map would be empty and + * all var_idxes will be updated to VarIdx::NO_VARIATION */ + if (optimize) + { + const hb_map_t &varidx_map = item_vars.get_varidx_map (); + for (auto _ : c->plan->colrv1_new_deltaset_idx_varidx_map.iter_ref ()) + { + uint32_t varidx = _.second; + uint32_t *new_varidx; + if (varidx_map.has (varidx, &new_varidx)) + _.second = *new_varidx; + else + _.second = VarIdx::NO_VARIATION; + } + } + } + else + { + if (unlikely (!out->varStore.serialize_serialize (c->serializer, + &var_store, + c->plan->colrv1_varstore_inner_maps.as_array ()))) + return_trace (false); + } + + return_trace (true); + } + + bool subset_delta_set_index_map (hb_subset_context_t *c, + COLR* out /* OUT */) const + { + TRACE_SUBSET (this); + if (!varIdxMap || c->plan->all_axes_pinned || + !c->plan->colrv1_new_deltaset_idx_varidx_map) + return_trace (true); + + const hb_map_t &deltaset_idx_varidx_map = c->plan->colrv1_new_deltaset_idx_varidx_map; + delta_set_index_map_subset_plan_t index_map_plan (deltaset_idx_varidx_map); + + if (unlikely (!index_map_plan.remap (deltaset_idx_varidx_map))) + return_trace (false); + + return_trace (out->varIdxMap.serialize_serialize (c->serializer, index_map_plan)); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -2195,34 +2479,30 @@ struct COLR auto *colr_prime = c->serializer->start_embed (); if (unlikely (!c->serializer->extend_min (colr_prime))) return_trace (false); - if (version == 0) - return_trace (colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)); + if (version == 0 || downgrade_to_V0 (glyphset)) + return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it)); + + hb_barrier (); - auto snap = c->serializer->snapshot (); + //start version 1 if (!c->serializer->allocate_size (5 * HBUINT32::static_size)) return_trace (false); + if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false); - VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr, - varIdxMap ? &(this+varIdxMap) : nullptr, - c->plan->normalized_coords.as_array ()); + /* subset ItemVariationStore first, cause varidx_map needs to be updated + * after instancing */ + if (!subset_varstore (c, colr_prime)) return_trace (false); - if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer)) - { - if (c->serializer->in_error ()) return_trace (false); - //no more COLRv1 glyphs: downgrade to version 0 - c->serializer->revert (snap); - return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it)); - } + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + c->plan->normalized_coords.as_array ()); - if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false); + if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer)) + return_trace (false); colr_prime->layerList.serialize_subset (c, layerList, this, instancer); colr_prime->clipList.serialize_subset (c, clipList, this, instancer); - if (!varStore || c->plan->all_axes_pinned) - return_trace (true); - colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this); - colr_prime->varStore.serialize_copy (c->serializer, varStore, this); - return_trace (true); + return_trace (subset_delta_set_index_map (c, colr_prime)); } const Paint *get_base_glyph_paint (hb_codepoint_t glyph) const @@ -2242,12 +2522,10 @@ struct COLR bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { - if (version != 1) - return false; - VarStoreInstancer instancer (&(this+varStore), - &(this+varIdxMap), - hb_array (font->coords, font->num_coords)); + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + hb_array (font->coords, font->num_coords)); if (get_clip (glyph, extents, instancer)) { @@ -2282,8 +2560,10 @@ struct COLR bool has_paint_for_glyph (hb_codepoint_t glyph) const { - if (version == 1) + if (version >= 1) { + hb_barrier (); + const Paint *paint = get_base_glyph_paint (glyph); return paint != nullptr; @@ -2294,9 +2574,9 @@ struct COLR bool get_clip (hb_codepoint_t glyph, hb_glyph_extents_t *extents, - const VarStoreInstancer instancer) const + const ItemVarStoreInstancer instancer) const { - return (this+clipList).get_extents (glyph, + return get_clip_list ().get_extents (glyph, extents, instancer); } @@ -2305,23 +2585,23 @@ struct COLR bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const { - VarStoreInstancer instancer (&(this+varStore), - &(this+varIdxMap), - hb_array (font->coords, font->num_coords)); + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); - c.current_glyphs.add (glyph); - if (version == 1) + hb_decycler_node_t node (c.glyphs_decycler); + node.visit (glyph); + + if (version >= 1) { + hb_barrier (); + const Paint *paint = get_base_glyph_paint (glyph); if (paint) { // COLRv1 glyph - VarStoreInstancer instancer (&(this+varStore), - &(this+varIdxMap), - hb_array (font->coords, font->num_coords)); - bool is_bounded = true; if (clip) { @@ -2404,7 +2684,7 @@ struct COLR Offset32To layerList; Offset32To clipList; // Offset to ClipList table (may be NULL) Offset32To varIdxMap; // Offset to DeltaSetIndexMap table (may be NULL) - Offset32To varStore; + Offset32To varStore; public: DEFINE_SIZE_MIN (14); }; @@ -2427,19 +2707,16 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); + hb_decycler_node_t node (c->layers_decycler); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { - if (unlikely (c->current_layers.has (i))) - continue; - - c->current_layers.add (i); + if (unlikely (!node.visit (i))) + return; const Paint &paint = paint_offset_lists.get_paint (i); c->funcs->push_group (c->data); c->recurse (paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); - - c->current_layers.del (i); } } @@ -2447,16 +2724,14 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - if (unlikely (c->current_glyphs.has (gid))) + hb_decycler_node_t node (c->glyphs_decycler); + if (unlikely (!node.visit (gid))) return; - c->current_glyphs.add (gid); - c->funcs->push_inverse_root_transform (c->data, c->font); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->funcs->pop_transform (c->data); - c->current_glyphs.del (gid); return; } c->funcs->pop_transform (c->data); @@ -2479,8 +2754,6 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (has_clip_box) c->funcs->pop_clip (c->data); - - c->current_glyphs.del (gid); } } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh index 705863d4ade..9ed0aa5632a 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh @@ -66,34 +66,64 @@ HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) cons template class Var> HB_INTERNAL void PaintTransform::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + (this+transform).closurev1 (c); +} HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 4; +} HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 1; +} HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 3; +} HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 1; +} HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 3; +} HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 2; +} HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const -{ (this+src).dispatch (c); } +{ + (this+src).dispatch (c); + c->num_var_idxes = 4; +} HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh index ed8f5957e96..51fc1b52af4 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh @@ -187,6 +187,14 @@ struct CPAL hb_ot_name_id_t get_color_name_id (unsigned int color_index) const { return v1 ().get_color_name_id (this, color_index, numColors); } + hb_array_t get_palette_colors (unsigned int palette_index) const + { + if (unlikely (palette_index >= numPalettes)) + return hb_array_t (); + unsigned int start_index = colorRecordIndicesZ[palette_index]; + hb_array_t all_colors ((this+colorRecordsZ).arrayZ, numColorRecords); + return all_colors.sub_array (start_index, numColors); + } unsigned int get_palette_colors (unsigned int palette_index, unsigned int start_offset, unsigned int *color_count, /* IN/OUT. May be NULL. */ @@ -214,13 +222,17 @@ struct CPAL hb_set_t *nameids_to_retain /* OUT */) const { if (version == 1) + { + hb_barrier (); v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain); + } } private: const CPALV1Tail& v1 () const { if (version == 0) return Null (CPALV1Tail); + hb_barrier (); return StructAfter (*this); } @@ -312,7 +324,10 @@ struct CPAL return_trace (false); if (version == 1) + { + hb_barrier (); return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map)); + } return_trace (true); } @@ -321,6 +336,7 @@ struct CPAL { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (this+colorRecordsZ).sanitize (c, numColorRecords) && colorRecordIndicesZ.sanitize (c, numPalettes) && (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors))); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh index 20b06ab13e3..e95d8c13a44 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh @@ -368,6 +368,7 @@ struct sbix { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version >= 1 && strikes.sanitize (c, this))); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh index c8ff6ab743e..9f676f9689e 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh @@ -56,6 +56,7 @@ struct SVGDocumentIndexEntry { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && svgDoc.sanitize (c, base, svgDocLength)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh index 257b2a3361a..35d73c7b858 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh @@ -64,6 +64,7 @@ struct Coverage { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); @@ -95,6 +96,15 @@ struct Coverage default:return NOT_COVERED; } } + unsigned int get_coverage (hb_codepoint_t glyph_id, + hb_ot_lookup_cache_t *cache) const + { + unsigned coverage; + if (cache && cache->get (glyph_id, &coverage)) return coverage; + coverage = get_coverage (glyph_id); + if (cache) cache->set (glyph_id, coverage); + return coverage; + } unsigned get_population () const { @@ -200,6 +210,19 @@ struct Coverage } } + unsigned cost () const + { + switch (u.format) { + case 1: hb_barrier (); return u.format1.cost (); + case 2: hb_barrier (); return u.format2.cost (); +#ifndef HB_NO_BEYOND_64K + case 3: hb_barrier (); return u.format3.cost (); + case 4: hb_barrier (); return u.format4.cost (); +#endif + default:return 0u; + } + } + /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh index 995f1ebdbda..4a925763bd7 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh @@ -103,6 +103,8 @@ struct CoverageFormat1_3 intersect_glyphs << glyphArray[i]; } + unsigned cost () const { return hb_bit_storage ((unsigned) glyphArray.len); /* bsearch cost */ } + template bool collect_coverage (set_t *glyphs) const { return glyphs->add_sorted_array (glyphArray.as_array ()); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh index d47c7eea992..247b7274b14 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh @@ -157,6 +157,8 @@ struct CoverageFormat2_4 } } + unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ } + template bool collect_coverage (set_t *glyphs) const { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh index 98543f56c3b..542480d2dd0 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh @@ -189,7 +189,7 @@ struct CaretValueFormat3 friend struct CaretValue; hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, - const VariationStore &var_store) const + const ItemVariationStore &var_store) const { return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) : @@ -251,7 +251,7 @@ struct CaretValue hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store) const + const ItemVariationStore &var_store) const { switch (u.format) { case 1: return u.format1.get_caret_value (font, direction); @@ -291,6 +291,7 @@ struct CaretValue { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -315,7 +316,7 @@ struct LigGlyph unsigned get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store, + const ItemVariationStore &var_store, unsigned start_offset, unsigned *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -371,7 +372,7 @@ struct LigCaretList unsigned int get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store, + const ItemVariationStore &var_store, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -441,6 +442,20 @@ struct MarkGlyphSetsFormat1 bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } + void collect_used_mark_sets (const hb_set_t& glyph_set, + hb_set_t& used_mark_sets /* OUT */) const + { + unsigned i = 0; + for (const auto &offset : coverage) + { + const auto &cov = this+offset; + if (cov.intersects (&glyph_set)) + used_mark_sets.add (i); + + i++; + } + } + template void collect_coverage (hb_vector_t &sets) const { @@ -461,6 +476,7 @@ struct MarkGlyphSetsFormat1 bool ret = true; for (const Offset32To& offset : coverage.iter ()) { + auto snap = c->serializer->snapshot (); auto *o = out->coverage.serialize_append (c->serializer); if (unlikely (!o)) { @@ -468,11 +484,17 @@ struct MarkGlyphSetsFormat1 break; } - //not using o->serialize_subset (c, offset, this, out) here because - //OTS doesn't allow null offset. - //See issue: https://github.com/khaledhosny/ots/issues/172 + //skip empty coverage c->serializer->push (); - c->dispatch (this+offset); + bool res = false; + if (offset) res = c->dispatch (this+offset); + if (!res) + { + c->serializer->pop_discard (); + c->serializer->revert (snap); + (out->coverage.len)--; + continue; + } c->serializer->add_link (*o, c->serializer->pop_pack ()); } @@ -513,6 +535,15 @@ struct MarkGlyphSets } } + void collect_used_mark_sets (const hb_set_t& glyph_set, + hb_set_t& used_mark_sets /* OUT */) const + { + switch (u.format) { + case 1: u.format1.collect_used_mark_sets (glyph_set, used_mark_sets); return; + default:return; + } + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -526,6 +557,7 @@ struct MarkGlyphSets { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); default:return_trace (true); @@ -577,7 +609,7 @@ struct GDEFVersion1_2 * definitions--from beginning of GDEF * header (may be NULL). Introduced * in version 0x00010002. */ - Offset32To + Offset32To varStore; /* Offset to the table of Item Variation * Store--from beginning of GDEF * header (may be NULL). Introduced @@ -600,8 +632,9 @@ struct GDEFVersion1_2 attachList.sanitize (c, this) && ligCaretList.sanitize (c, this) && markAttachClassDef.sanitize (c, this) && - (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && - (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); + hb_barrier () && + ((version.to_int () < 0x00010002u && hb_barrier ()) || markGlyphSetsDef.sanitize (c, this)) && + ((version.to_int () < 0x00010003u && hb_barrier ()) || varStore.sanitize (c, this))); } static void remap_varidx_after_instantiation (const hb_map_t& varidx_map, @@ -627,23 +660,23 @@ struct GDEFVersion1_2 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - - bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); - bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); - bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); - bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - bool subset_markglyphsetsdef = false; - if (version.to_int () >= 0x00010002u) - { - subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); - } + // Push var store first (if it's needed) so that it's last in the + // serialization order. Some font consumers assume that varstore runs to + // the end of the GDEF table. + // See: https://github.com/harfbuzz/harfbuzz/issues/4636 + auto snapshot_version0 = c->serializer->snapshot (); + if (unlikely (version.to_int () >= 0x00010002u && hb_barrier () && !c->serializer->embed (markGlyphSetsDef))) + return_trace (false); bool subset_varstore = false; - if (version.to_int () >= 0x00010003u) + unsigned varstore_index = (unsigned) -1; + auto snapshot_version2 = c->serializer->snapshot (); + if (version.to_int () >= 0x00010003u && hb_barrier ()) { + if (unlikely (!c->serializer->embed (varStore))) return_trace (false); if (c->plan->all_axes_pinned) out->varStore = 0; else if (c->plan->normalized_coords) @@ -652,27 +685,56 @@ struct GDEFVersion1_2 { item_variations_t item_vars; if (item_vars.instantiate (this+varStore, c->plan, true, true, - c->plan->gdef_varstore_inner_maps.as_array ())) + c->plan->gdef_varstore_inner_maps.as_array ())) { subset_varstore = out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (), c->plan->axis_tags, item_vars.get_region_list (), item_vars.get_vardata_encodings ()); + varstore_index = c->serializer->last_added_child_index(); + } remap_varidx_after_instantiation (item_vars.get_varidx_map (), c->plan->layout_variation_idx_delta_map); } } else + { subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ()); + varstore_index = c->serializer->last_added_child_index(); + } + } + + out->version.major = version.major; + out->version.minor = version.minor; + + if (!subset_varstore && version.to_int () >= 0x00010002u) { + c->serializer->revert (snapshot_version2); + } + + bool subset_markglyphsetsdef = false; + if (version.to_int () >= 0x00010002u && hb_barrier ()) + { + subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); } if (subset_varstore) { out->version.minor = 3; + c->plan->has_gdef_varstore = true; } else if (subset_markglyphsetsdef) { out->version.minor = 2; } else { out->version.minor = 0; + c->serializer->revert (snapshot_version0); + } + + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); + bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); + bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); + + if (subset_varstore && varstore_index != (unsigned) -1) { + c->serializer->repack_last(varstore_index); } return_trace (subset_glyphclassdef || subset_attachlist || @@ -709,6 +771,7 @@ struct GDEF { TRACE_SANITIZE (this); if (unlikely (!u.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.version.major) { case 1: return_trace (u.version1.sanitize (c)); #ifndef HB_NO_BEYOND_64K @@ -812,7 +875,7 @@ struct GDEF bool has_mark_glyph_sets () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0; + case 1: return u.version.to_int () >= 0x00010002u && hb_barrier () && u.version1.markGlyphSetsDef != 0; #ifndef HB_NO_BEYOND_64K case 2: return u.version2.markGlyphSetsDef != 0; #endif @@ -822,7 +885,7 @@ struct GDEF const MarkGlyphSets &get_mark_glyph_sets () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets); + case 1: return u.version.to_int () >= 0x00010002u && hb_barrier () ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets); #ifndef HB_NO_BEYOND_64K case 2: return this+u.version2.markGlyphSetsDef; #endif @@ -832,21 +895,21 @@ struct GDEF bool has_var_store () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0; + case 1: return u.version.to_int () >= 0x00010003u && hb_barrier () && u.version1.varStore != 0; #ifndef HB_NO_BEYOND_64K case 2: return u.version2.varStore != 0; #endif default: return false; } } - const VariationStore &get_var_store () const + const ItemVariationStore &get_var_store () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore); + case 1: return u.version.to_int () >= 0x00010003u && hb_barrier () ? this+u.version1.varStore : Null(ItemVariationStore); #ifndef HB_NO_BEYOND_64K case 2: return this+u.version2.varStore; #endif - default: return Null(VariationStore); + default: return Null(ItemVariationStore); } } @@ -959,47 +1022,6 @@ struct GDEF void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { get_lig_caret_list ().collect_variation_indices (c); } - void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, - const hb_vector_t& normalized_coords, - bool calculate_delta, /* not pinned at default */ - bool no_variations, /* all axes pinned */ - hb_hashmap_t> *layout_variation_idx_delta_map /* OUT */) const - { - if (!has_var_store ()) return; - const VariationStore &var_store = get_var_store (); - float *store_cache = var_store.create_cache (); - - unsigned new_major = 0, new_minor = 0; - unsigned last_major = (layout_variation_indices->get_min ()) >> 16; - for (unsigned idx : layout_variation_indices->iter ()) - { - int delta = 0; - if (calculate_delta) - delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, - normalized_coords.length, store_cache)); - - if (no_variations) - { - layout_variation_idx_delta_map->set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); - continue; - } - - uint16_t major = idx >> 16; - if (major >= var_store.get_sub_table_count ()) break; - if (major != last_major) - { - new_minor = 0; - ++new_major; - } - - unsigned new_idx = (new_major << 16) + new_minor; - layout_variation_idx_delta_map->set (idx, hb_pair_t (new_idx, delta)); - ++new_minor; - last_major = major; - } - var_store.destroy_cache (store_cache); - } - protected: union { FixedVersion<> version; /* Version identifier */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh index 49e76e77509..7802e397f4c 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Anchor.hh @@ -25,6 +25,7 @@ struct Anchor { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh index 23821a49c77..61bd90310a5 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh @@ -38,9 +38,15 @@ struct AnchorFormat3 *y = font->em_fscale_y (yCoordinate); if ((font->x_ppem || font->num_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)) + { + hb_barrier (); *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); + } } bool subset (hb_subset_context_t *c) const diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh index b61f1413ea5..9da9fff50ba 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh @@ -8,7 +8,7 @@ namespace GPOS_impl { struct AnchorMatrix { HBUINT16 rows; /* Number of rows */ - UnsizedArrayOf> + UnsizedArrayOf> matrixZ; /* Matrix of offsets to Anchor tables-- * from beginning of AnchorMatrix table */ public: @@ -18,6 +18,7 @@ struct AnchorMatrix { TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); + hb_barrier (); if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false); unsigned int count = rows * cols; if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false); @@ -25,6 +26,7 @@ struct AnchorMatrix if (c->lazy_some_gpos) return_trace (true); + hb_barrier (); for (unsigned int i = 0; i < count; i++) if (!matrixZ[i].sanitize (c, this)) return_trace (false); return_trace (true); @@ -38,6 +40,7 @@ struct AnchorMatrix if (unlikely (row >= rows || col >= cols)) return Null (Anchor); auto &offset = matrixZ[row * cols + col]; if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor); + hb_barrier (); *found = !offset.is_null (); return this+offset; } @@ -65,15 +68,14 @@ struct AnchorMatrix if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->rows = num_rows; - bool ret = false; for (const unsigned i : index_iter) { auto *offset = c->serializer->embed (matrixZ[i]); if (!offset) return_trace (false); - ret |= offset->serialize_subset (c, matrixZ[i], this); + offset->serialize_subset (c, matrixZ[i], this); } - return_trace (ret); + return_trace (true); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh index 408197454f1..696d25d75c8 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/Common.hh @@ -23,7 +23,7 @@ static void SinglePos_serialize (hb_serialize_context_t *c, const SrcLookup *src, Iterator it, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned); + unsigned new_format); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh index 3a2957af1a5..361aaed658a 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh @@ -11,21 +11,21 @@ struct EntryExitRecord { friend struct CursivePosFormat1; - bool sanitize (hb_sanitize_context_t *c, const void *base) const + bool sanitize (hb_sanitize_context_t *c, const struct CursivePosFormat1 *base) const { TRACE_SANITIZE (this); return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); } void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const void *src_base) const + const struct CursivePosFormat1 *src_base) const { (src_base+entryAnchor).collect_variation_indices (c); (src_base+exitAnchor).collect_variation_indices (c); } bool subset (hb_subset_context_t *c, - const void *src_base) const + const struct CursivePosFormat1 *src_base) const { TRACE_SERIALIZE (this); auto *out = c->serializer->embed (this); @@ -38,11 +38,11 @@ struct EntryExitRecord } protected: - Offset16To + Offset16To entryAnchor; /* Offset to EntryAnchor table--from * beginning of CursivePos * subtable--may be NULL */ - Offset16To + Offset16To exitAnchor; /* Offset to ExitAnchor table--from * beginning of CursivePos * subtable--may be NULL */ @@ -128,6 +128,7 @@ struct CursivePosFormat1 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.entryAnchor || unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); + hb_barrier (); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -145,6 +146,7 @@ struct CursivePosFormat1 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); return_trace (false); } + hb_barrier (); unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; @@ -262,7 +264,7 @@ struct CursivePosFormat1 hb_requires (hb_is_iterator (Iterator))> void serialize (hb_subset_context_t *c, Iterator it, - const void *src_base) + const struct CursivePosFormat1 *src_base) { if (unlikely (!c->serializer->extend_min ((*this)))) return; this->format = 1; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh index ea196581aff..6519e79b443 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -42,6 +42,7 @@ struct MarkMarkPosFormat1_2 mark1Coverage.sanitize (c, this) && mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) && + hb_barrier () && mark2Array.sanitize (c, this, (unsigned int) classCount)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh index 478c72df750..597ff4c088a 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh @@ -36,6 +36,7 @@ struct PairPosFormat1_3 TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); + hb_barrier (); unsigned int len1 = valueFormat[0].get_len (); unsigned int len2 = valueFormat[1].get_len (); @@ -102,12 +103,50 @@ struct PairPosFormat1_3 const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + unsigned cache_cost () const + { + return (this+coverage).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); + if (likely (cache)) + cache->clear (); + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } + + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); +#else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -131,21 +170,34 @@ struct PairPosFormat1_3 auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->format = format; - out->valueFormat[0] = valueFormat[0]; - out->valueFormat[1] = valueFormat[1]; - if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + + hb_pair_t newFormats = hb_pair (valueFormat[0], valueFormat[1]); + + if (c->plan->normalized_coords) { - hb_pair_t newFormats = compute_effective_value_formats (glyphset); - out->valueFormat[0] = newFormats.first; - out->valueFormat[1] = newFormats.second; + /* all device flags will be dropped when full instancing, no need to strip + * hints, also do not strip emtpy cause we don't compute the new default + * value during stripping */ + newFormats = compute_effective_value_formats (glyphset, false, false, &c->plan->layout_variation_idx_delta_map); } - - if (c->plan->all_axes_pinned) + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) { - out->valueFormat[0] = out->valueFormat[0].drop_device_table_flags (); - out->valueFormat[1] = out->valueFormat[1].drop_device_table_flags (); + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + newFormats = compute_effective_value_formats (glyphset, strip, true); } + out->valueFormat[0] = newFormats.first; + out->valueFormat[1] = newFormats.second; + hb_sorted_vector_t new_coverage; + hb_zip (this+coverage, pairSet) @@ -175,7 +227,9 @@ struct PairPosFormat1_3 } - hb_pair_t compute_effective_value_formats (const hb_set_t& glyphset) const + hb_pair_t compute_effective_value_formats (const hb_set_t& glyphset, + bool strip_hints, bool strip_empty, + const hb_hashmap_t> *varidx_delta_map = nullptr) const { unsigned record_size = PairSet::get_size (valueFormat); @@ -195,8 +249,8 @@ struct PairPosFormat1_3 { if (record->intersects (glyphset)) { - format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 ()); - format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0])); + format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 (), strip_hints, strip_empty, &set, varidx_delta_map); + format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0]), strip_hints, strip_empty, &set, varidx_delta_map); } record = &StructAtOffset (record, record_size); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh index ce6eec4f206..d85b1ac2c17 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh @@ -8,7 +8,7 @@ namespace Layout { namespace GPOS_impl { template -struct PairPosFormat2_4 +struct PairPosFormat2_4 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 2 */ @@ -123,12 +123,61 @@ struct PairPosFormat2_4 const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + struct pair_pos_cache_t + { + hb_ot_lookup_cache_t coverage; + hb_ot_lookup_cache_t first; + hb_ot_lookup_cache_t second; + }; + + unsigned cache_cost () const + { + return (this+coverage).cost () + (this+classDef1).cost () + (this+classDef2).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + pair_pos_cache_t *cache = (pair_pos_cache_t *) hb_malloc (sizeof (pair_pos_cache_t)); + if (likely (cache)) + { + cache->coverage.clear (); + cache->first.clear (); + cache->second.clear (); + } + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + pair_pos_cache_t *cache = (pair_pos_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } + + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + pair_pos_cache_t *cache = cached ? (pair_pos_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -139,14 +188,13 @@ struct PairPosFormat2_4 return_trace (false); } - unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); - if (!klass2) - { - buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1); - return_trace (false); - } - +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint, cache ? &cache->first : nullptr); + unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint, cache ? &cache->second : nullptr); +#else unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); + unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); +#endif if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) { buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1); @@ -287,18 +335,31 @@ struct PairPosFormat2_4 unsigned len2 = valueFormat2.get_len (); hb_pair_t newFormats = hb_pair (valueFormat1, valueFormat2); - if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) - newFormats = compute_effective_value_formats (klass1_map, klass2_map); - - out->valueFormat1 = newFormats.first; - out->valueFormat2 = newFormats.second; - if (c->plan->all_axes_pinned) + if (c->plan->normalized_coords) { - out->valueFormat1 = out->valueFormat1.drop_device_table_flags (); - out->valueFormat2 = out->valueFormat2.drop_device_table_flags (); + /* in case of full instancing, all var device flags will be dropped so no + * need to strip hints here */ + newFormats = compute_effective_value_formats (klass1_map, klass2_map, false, false, &c->plan->layout_variation_idx_delta_map); + } + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + newFormats = compute_effective_value_formats (klass1_map, klass2_map, strip, true); } + out->valueFormat1 = newFormats.first; + out->valueFormat2 = newFormats.second; + unsigned total_len = len1 + len2; hb_vector_t class2_idxs (+ hb_range ((unsigned) class2Count) | hb_filter (klass2_map)); for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map)) @@ -311,22 +372,15 @@ struct PairPosFormat2_4 } } - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; - - auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) - | hb_map_retains_sorting (glyph_map) - ; - - out->coverage.serialize_serialize (c->serializer, it); - return_trace (out->class1Count && out->class2Count && bool (it)); + bool ret = out->coverage.serialize_subset(c, coverage, this); + return_trace (out->class1Count && out->class2Count && ret); } hb_pair_t compute_effective_value_formats (const hb_map_t& klass1_map, - const hb_map_t& klass2_map) const + const hb_map_t& klass2_map, + bool strip_hints, bool strip_empty, + const hb_hashmap_t> *varidx_delta_map = nullptr) const { unsigned len1 = valueFormat1.get_len (); unsigned len2 = valueFormat2.get_len (); @@ -340,8 +394,8 @@ struct PairPosFormat2_4 for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) { unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size; - format1 = format1 | valueFormat1.get_effective_format (&values[idx]); - format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]); + format1 = format1 | valueFormat1.get_effective_format (&values[idx], strip_hints, strip_empty, this, varidx_delta_map); + format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1], strip_hints, strip_empty, this, varidx_delta_map); } if (format1 == valueFormat1 && format2 == valueFormat2) diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh index 7ccec1df841..e610fcd7517 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh @@ -9,7 +9,7 @@ namespace GPOS_impl { template -struct PairSet +struct PairSet : ValueBase { template friend struct PairPosFormat1_3; @@ -45,10 +45,12 @@ struct PairSet bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const { TRACE_SANITIZE (this); - if (!(c->check_struct (this) - && c->check_range (&firstPairValueRecord, + if (!(c->check_struct (this) && + hb_barrier () && + c->check_range (&firstPairValueRecord, len, closure->stride))) return_trace (false); + hb_barrier (); unsigned int count = len; const PairValueRecord *record = &firstPairValueRecord; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh index b32abe46d21..fe9595f1266 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh @@ -29,7 +29,7 @@ struct PairValueRecord struct context_t { - const void *base; + const ValueBase *base; const ValueFormat *valueFormats; const ValueFormat *newFormats; unsigned len1; /* valueFormats[0].get_len() */ @@ -62,7 +62,7 @@ struct PairValueRecord void collect_variation_indices (hb_collect_variation_indices_context_t *c, const ValueFormat *valueFormats, - const void *base) const + const ValueBase *base) const { unsigned record1_len = valueFormats[0].get_len (); unsigned record2_len = valueFormats[1].get_len (); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh index 3af6c499659..a0243a218c5 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePos.hh @@ -39,14 +39,12 @@ struct SinglePos const SrcLookup* src, Iterator glyph_val_iter_pairs, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned) + unsigned newFormat) { if (unlikely (!c->extend_min (u.format))) return; unsigned format = 2; - ValueFormat new_format = src->get_value_format (); - - if (all_axes_pinned) - new_format = new_format.drop_device_table_flags (); + ValueFormat new_format; + new_format = newFormat; if (glyph_val_iter_pairs) format = get_format (glyph_val_iter_pairs); @@ -89,8 +87,8 @@ SinglePos_serialize (hb_serialize_context_t *c, const SrcLookup *src, Iterator it, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned) -{ c->start_embed ()->serialize (c, src, it, layout_variation_idx_delta_map, all_axes_pinned); } + unsigned new_format) +{ c->start_embed ()->serialize (c, src, it, layout_variation_idx_delta_map, new_format); } } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh index 8e21c5f8e71..1a14be020f9 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh @@ -8,7 +8,7 @@ namespace OT { namespace Layout { namespace GPOS_impl { -struct SinglePosFormat1 +struct SinglePosFormat1 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 1 */ @@ -28,6 +28,7 @@ struct SinglePosFormat1 TRACE_SANITIZE (this); return_trace (c->check_struct (this) && coverage.sanitize (c, this) && + hb_barrier () && /* The coverage table may use a range to represent a set * of glyphs, which means a small number of bytes can * generate a large glyph set. Manually modify the @@ -66,7 +67,7 @@ struct SinglePosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { @@ -146,6 +147,30 @@ struct SinglePosFormat1 hb_set_t intersection; (this+coverage).intersect_set (glyphset, intersection); + unsigned new_format = valueFormat; + + if (c->plan->normalized_coords) + { + new_format = valueFormat.get_effective_format (values.arrayZ, false, false, this, &c->plan->layout_variation_idx_delta_map); + } + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + new_format = valueFormat.get_effective_format (values.arrayZ, + strip, /* strip hints */ + true, /* strip empty */ + this, nullptr); + } + auto it = + hb_iter (intersection) | hb_map_retains_sorting (glyph_map) @@ -153,7 +178,7 @@ struct SinglePosFormat1 ; bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned); + SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, new_format); return_trace (ret); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh index ddc4c18ec1c..455796b4b27 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { namespace GPOS_impl { -struct SinglePosFormat2 +struct SinglePosFormat2 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 2 */ @@ -66,7 +66,7 @@ struct SinglePosFormat2 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (index >= valueCount)) return_trace (false); @@ -143,6 +143,37 @@ struct SinglePosFormat2 coverage.serialize_serialize (c, glyphs); } + template + unsigned compute_effective_format (const hb_face_t *face, + Iterator it, + bool is_instancing, bool strip_hints, + bool has_gdef_varstore, + const hb_hashmap_t> *varidx_delta_map) const + { + hb_blob_t* blob = hb_face_reference_table (face, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + unsigned new_format = 0; + if (is_instancing) + { + new_format = new_format | valueFormat.get_effective_format (+ it | hb_map (hb_second), false, false, this, varidx_delta_map); + } + /* do not strip hints for VF */ + else if (strip_hints) + { + bool strip = !has_fvar; + if (has_fvar && !has_gdef_varstore) + strip = true; + new_format = new_format | valueFormat.get_effective_format (+ it | hb_map (hb_second), strip, true, this, nullptr); + } + else + new_format = valueFormat; + + return new_format; + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -163,8 +194,13 @@ struct SinglePosFormat2 }) ; + unsigned new_format = compute_effective_format (c->plan->source, it, + bool (c->plan->normalized_coords), + bool (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING), + c->plan->has_gdef_varstore, + &c->plan->layout_variation_idx_delta_map); bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned); + SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, new_format); return_trace (ret); } }; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh index 8618cddad1c..731d1ffca1a 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh @@ -9,6 +9,8 @@ namespace GPOS_impl { typedef HBUINT16 Value; +struct ValueBase {}; // Dummy base class tag for OffsetTo bases. + typedef UnsizedArrayOf ValueRecord; struct ValueFormat : HBUINT16 @@ -78,7 +80,7 @@ struct ValueFormat : HBUINT16 } bool apply_value (hb_ot_apply_context_t *c, - const void *base, + const ValueBase *base, const Value *values, hb_glyph_position_t &glyph_pos) const { @@ -114,7 +116,7 @@ struct ValueFormat : HBUINT16 if (!use_x_device && !use_y_device) return ret; - const VariationStore &store = c->var_store; + const ItemVariationStore &store = c->var_store; auto *cache = c->var_store_cache; /* pixel -> fractional pixel */ @@ -142,11 +144,29 @@ struct ValueFormat : HBUINT16 return ret; } - unsigned int get_effective_format (const Value *values) const + unsigned int get_effective_format (const Value *values, bool strip_hints, bool strip_empty, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const { unsigned int format = *this; for (unsigned flag = xPlacement; flag <= yAdvDevice; flag = flag << 1) { - if (format & flag) should_drop (*values++, (Flags) flag, &format); + if (format & flag) + { + if (strip_hints && flag >= xPlaDevice) + { + format = format & ~flag; + values++; + continue; + } + if (varidx_delta_map && flag >= xPlaDevice) + { + update_var_flag (values++, (Flags) flag, &format, base, varidx_delta_map); + continue; + } + /* do not strip empty when instancing, cause we don't know whether the new + * default value is 0 or not */ + if (strip_empty) should_drop (*values, (Flags) flag, &format); + values++; + } } return format; @@ -154,18 +174,19 @@ struct ValueFormat : HBUINT16 template - unsigned int get_effective_format (Iterator it) const { + unsigned int get_effective_format (Iterator it, bool strip_hints, bool strip_empty, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const { unsigned int new_format = 0; for (const hb_array_t& values : it) - new_format = new_format | get_effective_format (&values); + new_format = new_format | get_effective_format (&values, strip_hints, strip_empty, base, varidx_delta_map); return new_format; } void copy_values (hb_serialize_context_t *c, unsigned int new_format, - const void *base, + const ValueBase *base, const Value *values, const hb_hashmap_t> *layout_variation_idx_delta_map) const { @@ -217,7 +238,7 @@ struct ValueFormat : HBUINT16 } void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const void *base, + const ValueBase *base, const hb_array_t& values) const { unsigned format = *this; @@ -251,17 +272,8 @@ struct ValueFormat : HBUINT16 } } - unsigned drop_device_table_flags () const - { - unsigned format = *this; - for (unsigned flag = xPlaDevice; flag <= yAdvDevice; flag = flag << 1) - format = format & ~flag; - - return format; - } - private: - bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const + bool sanitize_value_devices (hb_sanitize_context_t *c, const ValueBase *base, const Value *values) const { unsigned int format = *this; @@ -278,17 +290,17 @@ struct ValueFormat : HBUINT16 return true; } - static inline Offset16To& get_device (Value* value) + static inline Offset16To& get_device (Value* value) { - return *static_cast *> (value); + return *static_cast *> (value); } - static inline const Offset16To& get_device (const Value* value) + static inline const Offset16To& get_device (const Value* value) { - return *static_cast *> (value); + return *static_cast *> (value); } static inline const Device& get_device (const Value* value, bool *worked, - const void *base, + const ValueBase *base, hb_sanitize_context_t &c) { if (worked) *worked |= bool (*value); @@ -296,12 +308,13 @@ struct ValueFormat : HBUINT16 if (unlikely (!offset.sanitize (&c, base))) return Null(Device); + hb_barrier (); return base + offset; } void add_delta_to_value (HBINT16 *value, - const void *base, + const ValueBase *base, const Value *src_value, const hb_hashmap_t> *layout_variation_idx_delta_map) const { @@ -313,7 +326,8 @@ struct ValueFormat : HBUINT16 *value += hb_second (*varidx_delta); } - bool copy_device (hb_serialize_context_t *c, const void *base, + bool copy_device (hb_serialize_context_t *c, + const ValueBase *base, const Value *src_value, const hb_hashmap_t> *layout_variation_idx_delta_map, unsigned int new_format, Flags flag) const @@ -354,7 +368,7 @@ struct ValueFormat : HBUINT16 return (format & devices) != 0; } - bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const + bool sanitize_value (hb_sanitize_context_t *c, const ValueBase *base, const Value *values) const { TRACE_SANITIZE (this); @@ -366,7 +380,7 @@ struct ValueFormat : HBUINT16 return_trace (!has_device () || sanitize_value_devices (c, base, values)); } - bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const + bool sanitize_values (hb_sanitize_context_t *c, const ValueBase *base, const Value *values, unsigned int count) const { TRACE_SANITIZE (this); unsigned size = get_size (); @@ -376,11 +390,12 @@ struct ValueFormat : HBUINT16 if (c->lazy_some_gpos) return_trace (true); + hb_barrier (); return_trace (sanitize_values_stride_unsafe (c, base, values, count, size)); } /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ - bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const + bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const ValueBase *base, const Value *values, unsigned int count, unsigned int stride) const { TRACE_SANITIZE (this); @@ -403,6 +418,20 @@ struct ValueFormat : HBUINT16 *format = *format & ~flag; } + void update_var_flag (const Value* value, Flags flag, + unsigned int* format, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const + { + if (*value) + { + unsigned varidx = (base + get_device (value)).get_variation_index (); + hb_pair_t *varidx_delta; + if (varidx_delta_map->has (varidx, &varidx_delta) && + varidx_delta->first != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + return; + } + *format = *format & ~flag; + } }; } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh index adec65d5864..421a6e06627 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/AlternateSubstFormat1.hh @@ -74,7 +74,7 @@ struct AlternateSubstFormat1_2 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); return_trace ((this+alternateSet[index]).apply (c)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh index de4a111b46c..726da458fac 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh @@ -90,8 +90,17 @@ struct Ligature unsigned int total_component_count = 0; + if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return false; + unsigned match_positions_stack[4]; + unsigned *match_positions = match_positions_stack; + if (unlikely (count > ARRAY_LENGTH (match_positions_stack))) + { + match_positions = (unsigned *) hb_malloc (hb_max (count, 1u) * sizeof (unsigned)); + if (unlikely (!match_positions)) + return_trace (false); + } + unsigned int match_end = 0; - unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; if (likely (!match_input (c, count, &component[1], @@ -102,6 +111,8 @@ struct Ligature &total_component_count))) { c->buffer->unsafe_to_concat (c->buffer->idx, match_end); + if (match_positions != match_positions_stack) + hb_free (match_positions); return_trace (false); } @@ -145,6 +156,8 @@ struct Ligature pos); } + if (match_positions != match_positions_stack) + hb_free (match_positions); return_trace (true); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh index 5c7df97d13a..6ae24b33754 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -78,12 +78,49 @@ struct LigatureSubstFormat1_2 return lig_set.would_apply (c); } - bool apply (hb_ot_apply_context_t *c) const + unsigned cache_cost () const { - TRACE_APPLY (this); + return (this+coverage).cost (); + } + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) + { + switch (op) + { + case hb_ot_lookup_cache_op_t::CREATE: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t)); + if (likely (cache)) + cache->clear (); + return cache; + } + case hb_ot_lookup_cache_op_t::ENTER: + return (void *) true; + case hb_ot_lookup_cache_op_t::LEAVE: + return nullptr; + case hb_ot_lookup_cache_op_t::DESTROY: + { + hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p; + hb_free (cache); + return nullptr; + } + } + return nullptr; + } - unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } + bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } + bool _apply (hb_ot_apply_context_t *c, bool cached) const + { + TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache); +#else + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); +#endif + if (index == NOT_COVERED) return_trace (false); const auto &lig_set = this+ligatureSet[index]; return_trace (lig_set.apply (c)); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh index 4a9972c29cc..aec8d0f2c07 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/MultipleSubstFormat1.hh @@ -66,7 +66,7 @@ struct MultipleSubstFormat1_2 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); return_trace ((this+sequence[index]).apply (c)); } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index ec6dfa47647..400a9e73791 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -33,9 +33,11 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &lookahead = StructAfter (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); + hb_barrier (); const auto &substitute = StructAfter (lookahead); return_trace (substitute.sanitize (c)); } @@ -109,12 +111,12 @@ struct ReverseChainSingleSubstFormat1 bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); + unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); + if (index == NOT_COVERED) return_trace (false); + if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) return_trace (false); /* No chaining to this type */ - unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); - const auto &lookahead = StructAfter (backtrack); const auto &substitute = StructAfter (lookahead); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh index 268487c5ae7..be6cd820d28 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -128,7 +128,7 @@ struct SingleSubstFormat1_3 TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; unsigned int index = (this+coverage).get_coverage (glyph_id); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); hb_codepoint_t d = deltaGlyphID; hb_codepoint_t mask = get_mask (); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh index 51890011671..e9096460451 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -104,7 +104,7 @@ struct SingleSubstFormat2_4 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (index >= substitute.len)) return_trace (false); diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh index 6a43403e94b..527f64114b4 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/types.hh @@ -29,6 +29,9 @@ #ifndef OT_LAYOUT_TYPES_HH #define OT_LAYOUT_TYPES_HH +using hb_ot_lookup_cache_t = hb_cache_t<15, 8, 7>; +static_assert (sizeof (hb_ot_lookup_cache_t) == 256, ""); + namespace OT { namespace Layout { @@ -38,8 +41,8 @@ struct SmallTypes { using HBUINT = HBUINT16; using HBGlyphID = HBGlyphID16; using Offset = Offset16; - template - using OffsetTo = OT::Offset16To; + template + using OffsetTo = OT::Offset16To; template using ArrayOf = OT::Array16Of; template @@ -52,8 +55,8 @@ struct MediumTypes { using HBUINT = HBUINT24; using HBGlyphID = HBGlyphID24; using Offset = Offset24; - template - using OffsetTo = OT::Offset24To; + template + using OffsetTo = OT::Offset24To; template using ArrayOf = OT::Array24Of; template diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh new file mode 100644 index 00000000000..dbbbec9eee0 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/VARC.hh @@ -0,0 +1,218 @@ +#ifndef OT_VAR_VARC_VARC_HH +#define OT_VAR_VARC_VARC_HH + +#include "../../../hb-decycler.hh" +#include "../../../hb-geometry.hh" +#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-glyf-table.hh" +#include "../../../hb-ot-cff2-table.hh" +#include "../../../hb-ot-cff1-table.hh" + +#include "coord-setter.hh" + +namespace OT { + +//namespace Var { + +/* + * VARC -- Variable Composites + * https://github.com/harfbuzz/boring-expansion-spec/blob/main/VARC.md + */ + +#ifndef HB_NO_VAR_COMPOSITES + +struct VarComponent +{ + enum class flags_t : uint32_t + { + RESET_UNSPECIFIED_AXES = 1u << 0, + HAVE_AXES = 1u << 1, + AXIS_VALUES_HAVE_VARIATION = 1u << 2, + TRANSFORM_HAS_VARIATION = 1u << 3, + HAVE_TRANSLATE_X = 1u << 4, + HAVE_TRANSLATE_Y = 1u << 5, + HAVE_ROTATION = 1u << 6, + HAVE_CONDITION = 1u << 7, + HAVE_SCALE_X = 1u << 8, + HAVE_SCALE_Y = 1u << 9, + HAVE_TCENTER_X = 1u << 10, + HAVE_TCENTER_Y = 1u << 11, + GID_IS_24BIT = 1u << 12, + HAVE_SKEW_X = 1u << 13, + HAVE_SKEW_Y = 1u << 14, + RESERVED_MASK = ~((1u << 15) - 1), + }; + + HB_INTERNAL hb_ubytes_t + get_path_at (hb_font_t *font, + hb_codepoint_t parent_gid, + hb_draw_session_t &draw_session, + hb_array_t coords, + hb_transform_t transform, + hb_ubytes_t record, + hb_decycler_t *decycler, + signed *edges_left, + signed depth_left, + hb_glyf_scratch_t &scratch, + VarRegionList::cache_t *cache = nullptr) const; +}; + +struct VarCompositeGlyph +{ + static void + get_path_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_session_t &draw_session, + hb_array_t coords, + hb_transform_t transform, + hb_ubytes_t record, + hb_decycler_t *decycler, + signed *edges_left, + signed depth_left, + hb_glyf_scratch_t &scratch, + VarRegionList::cache_t *cache = nullptr) + { + while (record) + { + const VarComponent &comp = * (const VarComponent *) (record.arrayZ); + record = comp.get_path_at (font, glyph, + draw_session, coords, transform, + record, + decycler, edges_left, depth_left, scratch, cache); + } + } +}; + +HB_MARK_AS_FLAG_T (VarComponent::flags_t); + +struct VARC +{ + friend struct VarComponent; + + static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C'); + + HB_INTERNAL bool + get_path_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_session_t &draw_session, + hb_array_t coords, + hb_transform_t transform, + hb_codepoint_t parent_glyph, + hb_decycler_t *decycler, + signed *edges_left, + signed depth_left, + hb_glyf_scratch_t &scratch) const; + + bool + get_path (hb_font_t *font, + hb_codepoint_t gid, + hb_draw_session_t &draw_session, + hb_glyf_scratch_t &scratch) const + { + hb_decycler_t decycler; + signed edges = HB_MAX_GRAPH_EDGE_COUNT; + + return get_path_at (font, + gid, + draw_session, + hb_array (font->coords, font->num_coords), + HB_TRANSFORM_IDENTITY, + HB_CODEPOINT_INVALID, + &decycler, + &edges, + HB_MAX_NESTING_LEVEL, + scratch); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + hb_barrier () && + version.major == 1 && + coverage.sanitize (c, this) && + varStore.sanitize (c, this) && + conditionList.sanitize (c, this) && + axisIndicesList.sanitize (c, this) && + glyphRecords.sanitize (c, this)); + } + + struct accelerator_t + { + friend struct VarComponent; + + accelerator_t (hb_face_t *face) + { + table = hb_sanitize_context_t ().reference_table (face); + } + ~accelerator_t () + { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + table.destroy (); + } + + bool + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + { + if (!table->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; + } + } + + bool ret = table->get_path (font, gid, draw_session, *scratch); + + // Put it back. + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + return ret; + } + + private: + hb_blob_ptr_t table; + hb_atomic_ptr_t cached_scratch; + }; + + bool has_data () const { return version.major != 0; } + + protected: + FixedVersion<> version; /* Version identifier */ + Offset32To coverage; + Offset32To varStore; + Offset32To conditionList; + Offset32To axisIndicesList; + Offset32To*/> glyphRecords; + public: + DEFINE_SIZE_STATIC (24); +}; + +struct VARC_accelerator_t : VARC::accelerator_t { + VARC_accelerator_t (hb_face_t *face) : VARC::accelerator_t (face) {} +}; + +#endif + +//} + +} + +#endif /* OT_VAR_VARC_VARC_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/coord-setter.hh b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/coord-setter.hh new file mode 100644 index 00000000000..70c0968e1e4 --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/OT/Var/VARC/coord-setter.hh @@ -0,0 +1,63 @@ +#ifndef OT_VAR_VARC_COORD_SETTER_HH +#define OT_VAR_VARC_COORD_SETTER_HH + + +#include "../../../hb.hh" + + +namespace OT { +//namespace Var { + + +struct coord_setter_t +{ + coord_setter_t (hb_array_t coords_) + { + length = coords_.length; + if (length <= ARRAY_LENGTH (static_coords)) + hb_memcpy (static_coords, coords_.arrayZ, length * sizeof (int)); + else + dynamic_coords.extend (coords_); + } + + int& operator [] (unsigned idx) + { + if (unlikely (idx >= HB_VAR_COMPOSITE_MAX_AXES)) + return Crap(int); + + if (length <= ARRAY_LENGTH (static_coords)) + { + if (idx < ARRAY_LENGTH (static_coords)) + { + while (length <= idx) + static_coords[length++] = 0; + return static_coords[idx]; + } + else + dynamic_coords.extend (hb_array (static_coords, length)); + } + + if (dynamic_coords.length <= idx) + { + if (unlikely (!dynamic_coords.resize (idx + 1))) + return Crap(int); + length = idx + 1; + } + return dynamic_coords.arrayZ[idx]; + } + + hb_array_t get_coords () + { return length <= ARRAY_LENGTH (static_coords) ? hb_array (static_coords, length) : dynamic_coords.as_array (); } + + private: + hb_vector_t dynamic_coords; + unsigned length; + int static_coords[sizeof (void *) * 8]; +}; + + +//} // namespace Var + +} // namespace OT + +#endif /* OT_VAR_VARC_COORD_SETTER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh index 151c1ac48cb..fb347770e6f 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh @@ -143,7 +143,7 @@ struct CompositeGlyphRecord float matrix[4]; contour_point_t trans; get_transformation (matrix, trans); - if (unlikely (!points.alloc (points.length + 4))) return false; // For phantom points + if (unlikely (!points.alloc (points.length + 1 + 4))) return false; // For phantom points points.push (trans); return true; } @@ -240,7 +240,8 @@ struct CompositeGlyphRecord } if (is_anchored ()) tx = ty = 0; - trans.init ((float) tx, (float) ty); + /* set is_end_point flag to true, used by IUP delta optimization */ + trans.init ((float) tx, (float) ty, true); { const F2DOT14 *points = (const F2DOT14 *) p; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh index b295e41510f..1805df262aa 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh @@ -7,8 +7,6 @@ #include "GlyphHeader.hh" #include "SimpleGlyph.hh" #include "CompositeGlyph.hh" -#include "VarCompositeGlyph.hh" -#include "coord-setter.hh" namespace OT { @@ -33,9 +31,6 @@ struct Glyph EMPTY, SIMPLE, COMPOSITE, -#ifndef HB_NO_VAR_COMPOSITES - VAR_COMPOSITE, -#endif }; public: @@ -44,22 +39,10 @@ struct Glyph if (type != COMPOSITE) return composite_iter_t (); return CompositeGlyph (*header, bytes).iter (); } - var_composite_iter_t get_var_composite_iterator () const - { -#ifndef HB_NO_VAR_COMPOSITES - if (type != VAR_COMPOSITE) return var_composite_iter_t (); - return VarCompositeGlyph (*header, bytes).iter (); -#else - return var_composite_iter_t (); -#endif - } const hb_bytes_t trim_padding () const { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: return VarCompositeGlyph (*header, bytes).trim_padding (); -#endif case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding (); case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding (); case EMPTY: return bytes; @@ -70,9 +53,6 @@ struct Glyph void drop_hints () { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: return; // No hinting -#endif case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return; case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return; case EMPTY: return; @@ -82,9 +62,6 @@ struct Glyph void set_overlaps_flag () { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: return; // No overlaps flag -#endif case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return; case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return; case EMPTY: return; @@ -94,15 +71,15 @@ struct Glyph void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: return; // No hinting -#endif case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return; case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return; case EMPTY: return; } } + bool is_composite () const + { return type == COMPOSITE; } + bool get_all_points_without_var (const hb_face_t *face, contour_point_vector_t &points /* OUT */) const { @@ -117,14 +94,6 @@ struct Glyph if (unlikely (!item.get_points (points))) return false; break; } -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: - { - for (auto &item : get_var_composite_iterator ()) - if (unlikely (!item.get_points (points))) return false; - break; - } -#endif case EMPTY: break; } @@ -282,7 +251,8 @@ struct Glyph composite_contours_p = nullptr; } - if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) + hb_glyf_scratch_t scratch; + if (!get_points (font, glyf, all_points, scratch, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) return false; // .notdef, set type to empty so we only update metrics and don't compile bytes for @@ -300,13 +270,6 @@ struct Glyph { switch (type) { -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: - // TODO - dest_end = hb_bytes_t (); - break; -#endif - case COMPOSITE: if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start, points_with_deltas, @@ -343,27 +306,23 @@ struct Glyph template bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, contour_point_vector_t &all_points /* OUT */, + hb_glyf_scratch_t &scratch, contour_point_vector_t *points_with_deltas = nullptr, /* OUT */ head_maxp_info_t * head_maxp_info = nullptr, /* OUT */ unsigned *composite_contours = nullptr, /* OUT */ bool shift_points_hori = true, bool use_my_metrics = true, bool phantom_only = false, - hb_array_t coords = hb_array_t (), - hb_map_t *current_glyphs = nullptr, + hb_array_t coords = hb_array_t (), unsigned int depth = 0, unsigned *edge_count = nullptr) const { if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false; unsigned stack_edge_count = 0; if (!edge_count) edge_count = &stack_edge_count; - if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false; + if (unlikely (*edge_count > HB_MAX_GRAPH_EDGE_COUNT)) return false; (*edge_count)++; - hb_map_t current_glyphs_stack; - if (current_glyphs == nullptr) - current_glyphs = ¤t_glyphs_stack; - if (head_maxp_info) { head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); @@ -372,8 +331,7 @@ struct Glyph if (!coords) coords = hb_array (font->coords, font->num_coords); - contour_point_vector_t stack_points; - contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points; + contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points; unsigned old_length = points.length; switch (type) { @@ -391,14 +349,6 @@ struct Glyph if (unlikely (!item.get_points (points))) return false; break; } -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: - { - for (auto &item : get_var_composite_iterator ()) - if (unlikely (!item.get_points (points))) return false; - break; - } -#endif case EMPTY: break; } @@ -434,36 +384,53 @@ struct Glyph #ifndef HB_NO_VAR if (coords) - glyf_accelerator.gvar->apply_deltas_to_points (gid, - coords, - points.as_array ().sub_array (old_length), - phantom_only && type == SIMPLE); + { +#ifndef HB_NO_BEYOND_64K + if (glyf_accelerator.GVAR->has_data ()) + glyf_accelerator.GVAR->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + scratch, + phantom_only && type == SIMPLE); + else +#endif + glyf_accelerator.gvar->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + scratch, + phantom_only && type == SIMPLE); + } #endif // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it // with child glyphs' points if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE) { - if (unlikely (!points_with_deltas->resize (points.length))) return false; + assert (old_length == 0); *points_with_deltas = points; } + float shift = 0; switch (type) { case SIMPLE: if (depth == 0 && head_maxp_info) head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4); + shift = phantoms[PHANTOM_LEFT].x; break; case COMPOSITE: { + hb_decycler_node_t decycler_node (scratch.decycler); + unsigned int comp_index = 0; for (auto &item : get_composite_iterator ()) { hb_codepoint_t item_gid = item.get_gid (); - if (unlikely (current_glyphs->has (item_gid))) + if (unlikely (!decycler_node.visit (item_gid))) + { + comp_index++; continue; - - current_glyphs->add (item_gid); + } unsigned old_count = all_points.length; @@ -472,6 +439,7 @@ struct Glyph .get_points (font, glyf_accelerator, all_points, + scratch, points_with_deltas, head_maxp_info, composite_contours, @@ -479,14 +447,16 @@ struct Glyph use_my_metrics, phantom_only, coords, - current_glyphs, depth + 1, edge_count))) { - current_glyphs->del (item_gid); + points.resize (old_length); return false; } + // points might have been reallocated. Relocate phantoms. + phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + auto comp_points = all_points.as_array ().sub_array (old_count); /* Copy phantom points from component if USE_MY_METRICS flag set */ @@ -501,7 +471,7 @@ struct Glyph item.get_transformation (matrix, default_trans); /* Apply component transformation & translation (with deltas applied) */ - item.transform_points (comp_points, matrix, points[comp_index]); + item.transform_points (comp_points, matrix, points[old_length + comp_index]); } if (item.is_anchored () && !phantom_only) @@ -522,12 +492,11 @@ struct Glyph if (all_points.length > HB_GLYF_MAX_POINTS) { - current_glyphs->del (item_gid); + points.resize (old_length); return false; } comp_index++; - current_glyphs->del (item_gid); } if (head_maxp_info && depth == 0) @@ -538,84 +507,13 @@ struct Glyph head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index); } all_points.extend (phantoms); + shift = phantoms[PHANTOM_LEFT].x; + points.resize (old_length); } break; -#ifndef HB_NO_VAR_COMPOSITES - case VAR_COMPOSITE: - { - hb_array_t points_left = points.as_array (); - for (auto &item : get_var_composite_iterator ()) - { - hb_codepoint_t item_gid = item.get_gid (); - - if (unlikely (current_glyphs->has (item_gid))) - continue; - - current_glyphs->add (item_gid); - - unsigned item_num_points = item.get_num_points (); - hb_array_t record_points = points_left.sub_array (0, item_num_points); - assert (record_points.length == item_num_points); - - auto component_coords = coords; - /* Copying coords is expensive; so we have put an arbitrary - * limit on the max number of coords for now. */ - if (item.is_reset_unspecified_axes () || - coords.length > HB_GLYF_VAR_COMPOSITE_MAX_AXES) - component_coords = hb_array (); - - coord_setter_t coord_setter (component_coords); - item.set_variations (coord_setter, record_points); - - unsigned old_count = all_points.length; - - if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) && - !glyf_accelerator.glyph_for_gid (item_gid) - .get_points (font, - glyf_accelerator, - all_points, - points_with_deltas, - head_maxp_info, - nullptr, - shift_points_hori, - use_my_metrics, - phantom_only, - coord_setter.get_coords (), - current_glyphs, - depth + 1, - edge_count))) - { - current_glyphs->del (item_gid); - return false; - } - - auto comp_points = all_points.as_array ().sub_array (old_count); - - /* Apply component transformation */ - if (comp_points) // Empty in case of phantom_only - item.transform_points (record_points, comp_points); - - /* Copy phantom points from component if USE_MY_METRICS flag set */ - if (use_my_metrics && item.is_use_my_metrics ()) - for (unsigned int i = 0; i < PHANTOM_COUNT; i++) - phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; - - all_points.resize (all_points.length - PHANTOM_COUNT); - - if (all_points.length > HB_GLYF_MAX_POINTS) - { - current_glyphs->del (item_gid); - return false; - } - - points_left += item_num_points; - - current_glyphs->del (item_gid); - } - all_points.extend (phantoms); - } break; -#endif case EMPTY: all_points.extend (phantoms); + shift = phantoms[PHANTOM_LEFT].x; + points.resize (old_length); break; } @@ -624,10 +522,9 @@ struct Glyph /* Undocumented rasterizer behavior: * Shift points horizontally by the updated left side bearing */ - int v = -phantoms[PHANTOM_LEFT].x; - if (v) + if (shift) for (auto &point : all_points) - point.x += v; + point.x -= shift; } return !all_points.in_error (); @@ -658,10 +555,7 @@ struct Glyph int num_contours = header->numberOfContours; if (unlikely (num_contours == 0)) type = EMPTY; else if (num_contours > 0) type = SIMPLE; - else if (num_contours == -1) type = COMPOSITE; -#ifndef HB_NO_VAR_COMPOSITES - else if (num_contours == -2) type = VAR_COMPOSITE; -#endif + else if (num_contours <= -1) type = COMPOSITE; else type = EMPTY; // Spec deviation; Spec says COMPOSITE, but not seen in the wild. } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh index 5088397266d..601e1303792 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh @@ -127,19 +127,20 @@ struct SimpleGlyph hb_array_t points_ /* IN/OUT */, const HBUINT8 *end) { + auto *points = points_.arrayZ; unsigned count = points_.length; for (unsigned int i = 0; i < count;) { if (unlikely (p + 1 > end)) return false; uint8_t flag = *p++; - points_.arrayZ[i++].flag = flag; + points[i++].flag = flag; if (flag & FLAG_REPEAT) { if (unlikely (p + 1 > end)) return false; unsigned int repeat_count = *p++; unsigned stop = hb_min (i + repeat_count, count); for (; i < stop; i++) - points_.arrayZ[i].flag = flag; + points[i].flag = flag; } } return true; @@ -160,10 +161,7 @@ struct SimpleGlyph if (flag & short_flag) { if (unlikely (p + 1 > end)) return false; - if (flag & same_flag) - v += *p++; - else - v -= *p++; + v += (bool(flag & same_flag) * 2 - 1) * *p++; } else { @@ -190,7 +188,7 @@ struct SimpleGlyph unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; unsigned old_length = points.length; - points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy + points.alloc (points.length + num_points + 4); // Allocate for phantom points, to avoid a possible copy if (unlikely (!points.resize (points.length + num_points, false))) return false; auto points_ = points.as_array ().sub_array (old_length); if (!phantom_only) @@ -281,9 +279,9 @@ struct SimpleGlyph unsigned num_points = all_points.length - 4; hb_vector_t flags, x_coords, y_coords; - if (unlikely (!flags.alloc (num_points, true))) return false; - if (unlikely (!x_coords.alloc (2*num_points, true))) return false; - if (unlikely (!y_coords.alloc (2*num_points, true))) return false; + if (unlikely (!flags.alloc_exact (num_points))) return false; + if (unlikely (!x_coords.alloc_exact (2*num_points))) return false; + if (unlikely (!y_coords.alloc_exact (2*num_points))) return false; unsigned lastflag = 255, repeat = 0; int prev_x = 0, prev_y = 0; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh index 9c04d890d1a..643b0226492 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh @@ -53,23 +53,12 @@ struct SubsetGlyph if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) const_cast (_).set_gid (new_gid); } -#ifndef HB_NO_VAR_COMPOSITES - for (auto &_ : Glyph (dest_glyph).get_var_composite_iterator ()) - { - hb_codepoint_t new_gid; - if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) - const_cast (_).set_gid (new_gid); - } -#endif #ifndef HB_NO_BEYOND_64K auto it = Glyph (dest_glyph).get_composite_iterator (); if (it) { - /* lower GID24 to GID16 in components if possible. - * - * TODO: VarComposite. Not as critical, since VarComposite supports - * gid24 from the first version. */ + /* lower GID24 to GID16 in components if possible. */ char *p = it ? (char *) &*it : nullptr; char *q = p; const char *end = dest_glyph.arrayZ + dest_glyph.length; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh deleted file mode 100644 index 4f29f0aab37..00000000000 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh +++ /dev/null @@ -1,401 +0,0 @@ -#ifndef OT_GLYF_VARCOMPOSITEGLYPH_HH -#define OT_GLYF_VARCOMPOSITEGLYPH_HH - - -#include "../../hb-open-type.hh" -#include "coord-setter.hh" - - -namespace OT { -namespace glyf_impl { - - -struct VarCompositeGlyphRecord -{ - protected: - enum var_composite_glyph_flag_t - { - USE_MY_METRICS = 0x0001, - AXIS_INDICES_ARE_SHORT = 0x0002, - UNIFORM_SCALE = 0x0004, - HAVE_TRANSLATE_X = 0x0008, - HAVE_TRANSLATE_Y = 0x0010, - HAVE_ROTATION = 0x0020, - HAVE_SCALE_X = 0x0040, - HAVE_SCALE_Y = 0x0080, - HAVE_SKEW_X = 0x0100, - HAVE_SKEW_Y = 0x0200, - HAVE_TCENTER_X = 0x0400, - HAVE_TCENTER_Y = 0x0800, - GID_IS_24BIT = 0x1000, - AXES_HAVE_VARIATION = 0x2000, - RESET_UNSPECIFIED_AXES = 0x4000, - }; - - public: - - unsigned int get_size () const - { - unsigned fl = flags; - unsigned int size = min_size; - - unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 4 : 3; - size += numAxes * axis_width; - - if (fl & GID_IS_24BIT) size += 1; - - // 2 bytes each for the following flags - fl = fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y | - HAVE_ROTATION | - HAVE_SCALE_X | HAVE_SCALE_Y | - HAVE_SKEW_X | HAVE_SKEW_Y | - HAVE_TCENTER_X | HAVE_TCENTER_Y); - size += hb_popcount (fl) * 2; - - return size; - } - - bool has_more () const { return true; } - - bool is_use_my_metrics () const { return flags & USE_MY_METRICS; } - bool is_reset_unspecified_axes () const { return flags & RESET_UNSPECIFIED_AXES; } - - hb_codepoint_t get_gid () const - { - if (flags & GID_IS_24BIT) - return * (const HBGlyphID24 *) &pad; - else - return * (const HBGlyphID16 *) &pad; - } - - void set_gid (hb_codepoint_t gid) - { - if (flags & GID_IS_24BIT) - * (HBGlyphID24 *) &pad = gid; - else - * (HBGlyphID16 *) &pad = gid; - } - - unsigned get_numAxes () const - { - return numAxes; - } - - unsigned get_num_points () const - { - unsigned fl = flags; - unsigned num = 0; - if (fl & AXES_HAVE_VARIATION) num += numAxes; - - /* Hopefully faster code, relying on the value of the flags. */ - fl = (((fl & (HAVE_TRANSLATE_Y | HAVE_SCALE_Y | HAVE_SKEW_Y | HAVE_TCENTER_Y)) >> 1) | fl) & - (HAVE_TRANSLATE_X | HAVE_ROTATION | HAVE_SCALE_X | HAVE_SKEW_X | HAVE_TCENTER_X); - num += hb_popcount (fl); - return num; - - /* Slower but more readable code. */ - if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) num++; - if (fl & HAVE_ROTATION) num++; - if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y)) num++; - if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y)) num++; - if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) num++; - return num; - } - - void transform_points (hb_array_t record_points, - hb_array_t points) const - { - float matrix[4]; - contour_point_t trans; - - get_transformation_from_points (record_points.arrayZ, matrix, trans); - - auto arrayZ = points.arrayZ; - unsigned count = points.length; - - if (matrix[0] != 1.f || matrix[1] != 0.f || - matrix[2] != 0.f || matrix[3] != 1.f) - for (unsigned i = 0; i < count; i++) - arrayZ[i].transform (matrix); - - if (trans.x != 0.f || trans.y != 0.f) - for (unsigned i = 0; i < count; i++) - arrayZ[i].translate (trans); - } - - static inline void transform (float (&matrix)[4], contour_point_t &trans, - float (other)[6]) - { - // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268 - float xx1 = other[0]; - float xy1 = other[1]; - float yx1 = other[2]; - float yy1 = other[3]; - float dx1 = other[4]; - float dy1 = other[5]; - float xx2 = matrix[0]; - float xy2 = matrix[1]; - float yx2 = matrix[2]; - float yy2 = matrix[3]; - float dx2 = trans.x; - float dy2 = trans.y; - - matrix[0] = xx1*xx2 + xy1*yx2; - matrix[1] = xx1*xy2 + xy1*yy2; - matrix[2] = yx1*xx2 + yy1*yx2; - matrix[3] = yx1*xy2 + yy1*yy2; - trans.x = xx2*dx1 + yx2*dy1 + dx2; - trans.y = xy2*dx1 + yy2*dy1 + dy2; - } - - static void translate (float (&matrix)[4], contour_point_t &trans, - float translateX, float translateY) - { - if (!translateX && !translateY) - return; - - trans.x += matrix[0] * translateX + matrix[2] * translateY; - trans.y += matrix[1] * translateX + matrix[3] * translateY; - } - - static void scale (float (&matrix)[4], contour_point_t &trans, - float scaleX, float scaleY) - { - if (scaleX == 1.f && scaleY == 1.f) - return; - - matrix[0] *= scaleX; - matrix[1] *= scaleX; - matrix[2] *= scaleY; - matrix[3] *= scaleY; - } - - static void rotate (float (&matrix)[4], contour_point_t &trans, - float rotation) - { - if (!rotation) - return; - - // 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 - float other[6] = {c, s, -s, c, 0.f, 0.f}; - transform (matrix, trans, other); - } - - static void skew (float (&matrix)[4], contour_point_t &trans, - float skewX, float skewY) - { - if (!skewX && !skewY) - return; - - // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 - skewX = skewX * HB_PI; - skewY = skewY * HB_PI; - float other[6] = {1.f, - skewY ? tanf (skewY) : 0.f, - skewX ? tanf (skewX) : 0.f, - 1.f, - 0.f, 0.f}; - transform (matrix, trans, other); - } - - bool get_points (contour_point_vector_t &points) const - { - unsigned num_points = get_num_points (); - - points.alloc (points.length + num_points + 4); // For phantom points - if (unlikely (!points.resize (points.length + num_points, false))) return false; - contour_point_t *rec_points = points.arrayZ + (points.length - num_points); - hb_memset (rec_points, 0, num_points * sizeof (rec_points[0])); - - unsigned fl = flags; - - unsigned num_axes = numAxes; - unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 2 : 1; - unsigned axes_size = num_axes * axis_width; - - const F2DOT14 *q = (const F2DOT14 *) (axes_size + - (fl & GID_IS_24BIT ? 3 : 2) + - (const HBUINT8 *) &pad); - - unsigned count = num_axes; - if (fl & AXES_HAVE_VARIATION) - { - for (unsigned i = 0; i < count; i++) - rec_points++->x = q++->to_int (); - } - else - q += count; - - const HBUINT16 *p = (const HBUINT16 *) q; - - if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) - { - int translateX = (fl & HAVE_TRANSLATE_X) ? * (const FWORD *) p++ : 0; - int translateY = (fl & HAVE_TRANSLATE_Y) ? * (const FWORD *) p++ : 0; - rec_points->x = translateX; - rec_points->y = translateY; - rec_points++; - } - if (fl & HAVE_ROTATION) - { - int rotation = (fl & HAVE_ROTATION) ? ((const F4DOT12 *) p++)->to_int () : 0; - rec_points->x = rotation; - rec_points++; - } - if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y)) - { - int scaleX = (fl & HAVE_SCALE_X) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10; - int scaleY = (fl & HAVE_SCALE_Y) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10; - if ((fl & UNIFORM_SCALE) && !(fl & HAVE_SCALE_Y)) - scaleY = scaleX; - rec_points->x = scaleX; - rec_points->y = scaleY; - rec_points++; - } - if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y)) - { - int skewX = (fl & HAVE_SKEW_X) ? ((const F4DOT12 *) p++)->to_int () : 0; - int skewY = (fl & HAVE_SKEW_Y) ? ((const F4DOT12 *) p++)->to_int () : 0; - rec_points->x = skewX; - rec_points->y = skewY; - rec_points++; - } - if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) - { - int tCenterX = (fl & HAVE_TCENTER_X) ? * (const FWORD *) p++ : 0; - int tCenterY = (fl & HAVE_TCENTER_Y) ? * (const FWORD *) p++ : 0; - rec_points->x = tCenterX; - rec_points->y = tCenterY; - rec_points++; - } - - return true; - } - - void get_transformation_from_points (const contour_point_t *rec_points, - float (&matrix)[4], contour_point_t &trans) const - { - unsigned fl = flags; - - if (fl & AXES_HAVE_VARIATION) - rec_points += numAxes; - - matrix[0] = matrix[3] = 1.f; - matrix[1] = matrix[2] = 0.f; - trans.init (0.f, 0.f); - - float translateX = 0.f; - float translateY = 0.f; - float rotation = 0.f; - float scaleX = 1.f; - float scaleY = 1.f; - float skewX = 0.f; - float skewY = 0.f; - float tCenterX = 0.f; - float tCenterY = 0.f; - - if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) - { - translateX = rec_points->x; - translateY = rec_points->y; - rec_points++; - } - if (fl & HAVE_ROTATION) - { - rotation = rec_points->x / (1 << 12); - rec_points++; - } - if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y)) - { - scaleX = rec_points->x / (1 << 10); - scaleY = rec_points->y / (1 << 10); - rec_points++; - } - if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y)) - { - skewX = rec_points->x / (1 << 12); - skewY = rec_points->y / (1 << 12); - rec_points++; - } - if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) - { - tCenterX = rec_points->x; - tCenterY = rec_points->y; - rec_points++; - } - - translate (matrix, trans, translateX + tCenterX, translateY + tCenterY); - rotate (matrix, trans, rotation); - scale (matrix, trans, scaleX, scaleY); - skew (matrix, trans, -skewX, skewY); - translate (matrix, trans, -tCenterX, -tCenterY); - } - - void set_variations (coord_setter_t &setter, - hb_array_t rec_points) const - { - bool have_variations = flags & AXES_HAVE_VARIATION; - unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; - unsigned num_axes = numAxes; - - const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2)); - const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2)); - - const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + num_axes) : (HBUINT8 *) (q + num_axes))); - - unsigned count = num_axes; - for (unsigned i = 0; i < count; i++) - { - unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++; - - signed v = have_variations ? rec_points.arrayZ[i].x : a++->to_int (); - - v = hb_clamp (v, -(1<<14), (1<<14)); - setter[axis_index] = v; - } - } - - protected: - HBUINT16 flags; - HBUINT8 numAxes; - HBUINT16 pad; - public: - DEFINE_SIZE_MIN (5); -}; - -using var_composite_iter_t = composite_iter_tmpl; - -struct VarCompositeGlyph -{ - const GlyphHeader &header; - hb_bytes_t bytes; - VarCompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : - header (header_), bytes (bytes_) {} - - var_composite_iter_t iter () const - { return var_composite_iter_t (bytes, &StructAfter (header)); } - - const hb_bytes_t trim_padding () const - { - unsigned length = GlyphHeader::static_size; - for (auto &comp : iter ()) - length += comp.get_size (); - return bytes.sub_array (0, length); - } -}; - - -} /* namespace glyf_impl */ -} /* namespace OT */ - - -#endif /* OT_GLYF_VARCOMPOSITEGLYPH_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh deleted file mode 100644 index cf05929362f..00000000000 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef OT_GLYF_COORD_SETTER_HH -#define OT_GLYF_COORD_SETTER_HH - - -#include "../../hb.hh" - - -namespace OT { -namespace glyf_impl { - - -struct coord_setter_t -{ - coord_setter_t (hb_array_t coords) : - coords (coords) {} - - int& operator [] (unsigned idx) - { - if (unlikely (idx >= HB_GLYF_VAR_COMPOSITE_MAX_AXES)) - return Crap(int); - if (coords.length < idx + 1) - coords.resize (idx + 1); - return coords[idx]; - } - - hb_array_t get_coords () - { return coords.as_array (); } - - hb_vector_t coords; -}; - - -} /* namespace glyf_impl */ -} /* namespace OT */ - -#endif /* OT_GLYF_COORD_SETTER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh index 3462e4d1ea5..bd07e941393 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh @@ -38,7 +38,7 @@ _write_loca (IteratorIn&& it, unsigned padded_size = *it++; offset += padded_size; - DEBUG_MSG (SUBSET, nullptr, "loca entry gid %u offset %u padded-size %u", gid, offset, padded_size); + DEBUG_MSG (SUBSET, nullptr, "loca entry gid %" PRIu32 " offset %u padded-size %u", gid, offset, padded_size); value = offset >> right_shift; *dest++ = value; diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh index 175e1de308c..681c3b9a007 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh @@ -94,7 +94,7 @@ struct glyf } hb_vector_t padded_offsets; - if (unlikely (!padded_offsets.alloc (c->plan->new_to_old_gid_list.length, true))) + if (unlikely (!padded_offsets.alloc_exact (c->plan->new_to_old_gid_list.length))) return_trace (false); hb_vector_t glyphs; @@ -172,6 +172,9 @@ struct glyf_accelerator_t glyf_table = nullptr; #ifndef HB_NO_VAR gvar = nullptr; +#ifndef HB_NO_BEYOND_64K + GVAR = nullptr; +#endif #endif hmtx = nullptr; #ifndef HB_NO_VERTICAL @@ -187,6 +190,9 @@ struct glyf_accelerator_t glyf_table = hb_sanitize_context_t ().reference_table (face); #ifndef HB_NO_VAR gvar = face->table.gvar; +#ifndef HB_NO_BEYOND_64K + GVAR = face->table.GVAR; +#endif #endif hmtx = face->table.hmtx; #ifndef HB_NO_VERTICAL @@ -198,6 +204,13 @@ struct glyf_accelerator_t } ~glyf_accelerator_t () { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + glyf_table.destroy (); } @@ -205,18 +218,17 @@ struct glyf_accelerator_t protected: template - bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const + bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer, + hb_array_t coords, + hb_glyf_scratch_t &scratch) const { if (gid >= num_glyphs) return false; - /* Making this allocfree is not that easy - https://github.com/harfbuzz/harfbuzz/issues/2095 - mostly because of gvar handling in VF fonts, - perhaps a separate path for non-VF fonts can be considered */ - contour_point_vector_t all_points; + auto &all_points = scratch.all_points; + all_points.resize (0); bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only))) + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords))) return false; unsigned count = all_points.length; @@ -225,8 +237,61 @@ struct glyf_accelerator_t if (consumer.is_consuming_contour_points ()) { - for (auto &point : all_points.as_array ().sub_array (0, count)) - consumer.consume_point (point); + auto *points = all_points.arrayZ; + + if (false) + { + /* Our path-builder was designed to work with this simple loop. + * But FreeType and CoreText do it differently, so we match those + * with the other, more complicated, code branch below. */ + for (unsigned i = 0; i < count; i++) + { + consumer.consume_point (points[i]); + if (points[i].is_end_point) + consumer.contour_end (); + } + } + else + { + for (unsigned i = 0; i < count; i++) + { + // Start of a contour. + if (points[i].flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE) + { + // First point is on-curve. Draw the contour. + for (; i < count; i++) + { + consumer.consume_point (points[i]); + if (points[i].is_end_point) + { + consumer.contour_end (); + break; + } + } + } + else + { + unsigned start = i; + + // Find end of the contour. + for (; i < count; i++) + if (points[i].is_end_point) + break; + + unsigned end = i; + + // Enough to start from the end. Our path-builder takes care of the rest. + if (likely (end < count)) // Can only fail in case of alloc failure *maybe*. + consumer.consume_point (points[end]); + + for (i = start; i < end; i++) + consumer.consume_point (points[i]); + + consumer.contour_end (); + } + } + } + consumer.points_end (); } @@ -299,6 +364,7 @@ struct glyf_accelerator_t HB_ALWAYS_INLINE void consume_point (const contour_point_t &point) { bounds.add (point); } + void contour_end () {} void points_end () { bounds.get_extents (font, extents, scaled); } bool is_consuming_contour_points () { return extents; } @@ -314,7 +380,12 @@ struct glyf_accelerator_t contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; if (font->num_coords) - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false)); + { + 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); + } if (unlikely (!success)) return @@ -334,9 +405,11 @@ struct glyf_accelerator_t if (unlikely (gid >= num_glyphs)) return 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)))) + if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false), + hb_array (font->coords, font->num_coords), + scratch))) return false; *lsb = is_vertical @@ -362,20 +435,16 @@ struct glyf_accelerator_t #ifndef HB_NO_VAR if (font->num_coords) - return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true)); + { + hb_glyf_scratch_t scratch; + return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true), + hb_array (font->coords, font->num_coords), + scratch); + } #endif return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); } - bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const - { - funcs->push_clip_glyph (data, gid, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; - } - const glyf_impl::Glyph glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const { @@ -406,10 +475,52 @@ struct glyf_accelerator_t bool get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const - { return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session)); } + { + 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; + } + } + + bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + hb_array (font->coords, font->num_coords), + *scratch); + + // Put it back. + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + return ret; + } + + 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 + { + if (!has_data ()) return false; + return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + coords, + scratch); + } #ifndef HB_NO_VAR const gvar_accelerator_t *gvar; +#ifndef HB_NO_BEYOND_64K + const GVAR_accelerator_t *GVAR; +#endif #endif const hmtx_accelerator_t *hmtx; #ifndef HB_NO_VERTICAL @@ -421,6 +532,7 @@ struct glyf_accelerator_t unsigned int num_glyphs; hb_blob_ptr_t loca_table; hb_blob_ptr_t glyf_table; + hb_atomic_ptr_t cached_scratch; }; @@ -430,7 +542,7 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, hb_vector_t& glyphs /* OUT */) const { OT::glyf_accelerator_t glyf (plan->source); - if (!glyphs.alloc (plan->new_to_old_gid_list.length, true)) return false; + if (!glyphs.alloc_exact (plan->new_to_old_gid_list.length)) return false; for (const auto &pair : plan->new_to_old_gid_list) { diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh index d56ea3e45ff..f5495f92332 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh @@ -42,7 +42,7 @@ struct path_builder_t { bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE; #ifdef HB_NO_CUBIC_GLYF - bool is_cubic = false; + constexpr bool is_cubic = false; #else bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC); #endif @@ -124,58 +124,60 @@ struct path_builder_t } } - if (unlikely (point.is_end_point)) - { - if (first_offcurve && last_offcurve) - { - optional_point_t mid = last_offcurve.mid (first_offcurve2 ? - first_offcurve2 : - first_offcurve); - if (last_offcurve2) - draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, - last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - else - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - last_offcurve = optional_point_t (); - } - /* now check the rest */ + } - if (first_offcurve && first_oncurve) - { - if (first_offcurve2) - draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y, - first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y); - else - draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y); - } - else if (last_offcurve && first_oncurve) - { - if (last_offcurve2) - draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, - last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); - else - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); - } - else if (first_oncurve) - draw_session->line_to (first_oncurve.x, first_oncurve.y); - else if (first_offcurve) - { - float x = first_offcurve.x, y = first_offcurve.y; - draw_session->move_to (x, y); - draw_session->quadratic_to (x, y, x, y); - } + void contour_end () + { + if (first_offcurve && last_offcurve) + { + optional_point_t mid = last_offcurve.mid (first_offcurve2 ? + first_offcurve2 : + first_offcurve); + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + last_offcurve = optional_point_t (); + } + /* now check the rest */ - /* Getting ready for the next contour */ - first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); - draw_session->close_path (); + if (first_offcurve && first_oncurve) + { + if (first_offcurve2) + draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y, + first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); } + else if (last_offcurve && first_oncurve) + { + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + } + else if (first_oncurve) + draw_session->line_to (first_oncurve.x, first_oncurve.y); + else if (first_offcurve) + { + float x = first_offcurve.x, y = first_offcurve.y; + draw_session->move_to (x, y); + draw_session->quadratic_to (x, y, x, y); + } + + /* Getting ready for the next contour */ + first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); + draw_session->close_path (); } + void points_end () {} bool is_consuming_contour_points () { return true; } diff --git a/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh b/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh index f14c2da2de6..b440379afbe 100644 --- a/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh +++ b/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh @@ -242,7 +242,9 @@ struct NameRecord bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && offset.sanitize (c, base, length)); + return_trace (c->check_struct (this) && + hb_barrier () && + offset.sanitize (c, base, length)); } HBUINT16 platformID; /* Platform ID. */ @@ -465,6 +467,7 @@ struct name { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (format == 0 || format == 1) && c->check_array (nameRecordZ.arrayZ, count) && c->check_range (this, stringOffset) && @@ -482,7 +485,7 @@ struct name const hb_array_t all_names (this->table->nameRecordZ.arrayZ, this->table->count); - this->names.alloc (all_names.length, true); + this->names.alloc_exact (all_names.length); for (unsigned int i = 0; i < all_names.length; i++) { diff --git a/src/java.desktop/share/native/libharfbuzz/UPDATING.txt b/src/java.desktop/share/native/libharfbuzz/UPDATING.txt index 3f72983a455..d536fad05ac 100644 --- a/src/java.desktop/share/native/libharfbuzz/UPDATING.txt +++ b/src/java.desktop/share/native/libharfbuzz/UPDATING.txt @@ -53,9 +53,9 @@ STEP 2: BUILD CHANGES INCREMENTALLY STEP 3: COMPILER WARNINGS AND SETTING FLAGS ------------------------------------------- -- Update make parameters in Awt2DLibraries.gmk +- Update make parameters in make/modules/java.desktop/lib/ClientLibraries.gmk Since we don't use configure we need to manually specify the options - we need in the Harfbuzz section of Awt2DLibraries.gmk. + we need in the Harfbuzz section of ClientLibraries.gmk. As well as adding new options, we may need to clean up obsolete options. Note there may be platform variations in the flags. diff --git a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh index c1432883ffa..da6378820bb 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh @@ -39,6 +39,7 @@ struct ClassDefFormat1 : public OT::ClassDefFormat1_3 int64_t vertex_len = vertex.obj.tail - vertex.obj.head; constexpr unsigned min_size = OT::ClassDefFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + classValue.get_size () - classValue.len.get_size (); } }; @@ -50,6 +51,7 @@ struct ClassDefFormat2 : public OT::ClassDefFormat2_4 int64_t vertex_len = vertex.obj.tail - vertex.obj.head; constexpr unsigned min_size = OT::ClassDefFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); } }; @@ -114,6 +116,7 @@ struct ClassDef : public OT::ClassDef { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::ClassDef::min_size) return false; + hb_barrier (); switch (u.format) { case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); @@ -131,20 +134,23 @@ struct ClassDef : public OT::ClassDef struct class_def_size_estimator_t { + // TODO(garretrieger): update to support beyond64k coverage/classdef tables. + constexpr static unsigned class_def_format1_base_size = 6; + constexpr static unsigned class_def_format2_base_size = 4; + constexpr static unsigned coverage_base_size = 4; + constexpr static unsigned bytes_per_range = 6; + constexpr static unsigned bytes_per_glyph = 2; + template class_def_size_estimator_t (It glyph_and_class) - : gids_consecutive (true), num_ranges_per_class (), glyphs_per_class () + : num_ranges_per_class (), glyphs_per_class () { - unsigned last_gid = (unsigned) -1; + reset(); for (auto p : + glyph_and_class) { unsigned gid = p.first; unsigned klass = p.second; - if (last_gid != (unsigned) -1 && gid != last_gid + 1) - gids_consecutive = false; - last_gid = gid; - hb_set_t* glyphs; if (glyphs_per_class.has (klass, &glyphs) && glyphs) { glyphs->add (gid); @@ -174,28 +180,54 @@ struct class_def_size_estimator_t } } - // Incremental increase in the Coverage and ClassDef table size - // (worst case) if all glyphs associated with 'klass' were added. - unsigned incremental_coverage_size (unsigned klass) const + void reset() { + class_def_1_size = class_def_format1_base_size; + class_def_2_size = class_def_format2_base_size; + included_glyphs.clear(); + included_classes.clear(); + } + + // Compute the size of coverage for all glyphs added via 'add_class_def_size'. + unsigned coverage_size () const { - // Coverage takes 2 bytes per glyph worst case, - return 2 * glyphs_per_class.get (klass).get_population (); + unsigned format1_size = coverage_base_size + bytes_per_glyph * included_glyphs.get_population(); + unsigned format2_size = coverage_base_size + bytes_per_range * num_glyph_ranges(); + return hb_min(format1_size, format2_size); } - // Incremental increase in the Coverage and ClassDef table size - // (worst case) if all glyphs associated with 'klass' were added. - unsigned incremental_class_def_size (unsigned klass) const + // Compute the new size of the ClassDef table if all glyphs associated with 'klass' were added. + unsigned add_class_def_size (unsigned klass) { - // ClassDef takes 6 bytes per range - unsigned class_def_2_size = 6 * num_ranges_per_class.get (klass); - if (gids_consecutive) - { - // ClassDef1 takes 2 bytes per glyph, but only can be used - // when gids are consecutive. - return hb_min (2 * glyphs_per_class.get (klass).get_population (), class_def_2_size); + if (!included_classes.has(klass)) { + hb_set_t* glyphs = nullptr; + if (glyphs_per_class.has(klass, &glyphs)) { + included_glyphs.union_(*glyphs); + } + + class_def_1_size = class_def_format1_base_size; + if (!included_glyphs.is_empty()) { + unsigned min_glyph = included_glyphs.get_min(); + unsigned max_glyph = included_glyphs.get_max(); + class_def_1_size += bytes_per_glyph * (max_glyph - min_glyph + 1); + } + + class_def_2_size += bytes_per_range * num_ranges_per_class.get (klass); + + included_classes.add(klass); } - return class_def_2_size; + return hb_min (class_def_1_size, class_def_2_size); + } + + unsigned num_glyph_ranges() const { + hb_codepoint_t start = HB_SET_VALUE_INVALID; + hb_codepoint_t end = HB_SET_VALUE_INVALID; + + unsigned count = 0; + while (included_glyphs.next_range (&start, &end)) { + count++; + } + return count; } bool in_error () @@ -211,9 +243,12 @@ struct class_def_size_estimator_t } private: - bool gids_consecutive; hb_hashmap_t num_ranges_per_class; hb_hashmap_t glyphs_per_class; + hb_set_t included_classes; + hb_set_t included_glyphs; + unsigned class_def_1_size; + unsigned class_def_2_size; }; diff --git a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh index 4f44e076d1f..61ca063e345 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh @@ -39,6 +39,7 @@ struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); } }; @@ -50,6 +51,7 @@ struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); } }; @@ -138,6 +140,7 @@ struct Coverage : public OT::Layout::Common::Coverage { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; + hb_barrier (); switch (u.format) { case 1: return ((CoverageFormat1*)this)->sanitize (vertex); diff --git a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh index 4a1f7ebf5a5..ed1026f5866 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh @@ -195,6 +195,15 @@ struct graph_t return incoming_edges_; } + unsigned incoming_edges_from_parent (unsigned parent_index) const { + if (single_parent != (unsigned) -1) { + return single_parent == parent_index ? 1 : 0; + } + + unsigned* count; + return parents.has(parent_index, &count) ? *count : 0; + } + void reset_parents () { incoming_edges_ = 0; @@ -334,6 +343,16 @@ struct graph_t return true; } + bool give_max_priority () + { + bool result = false; + while (!has_max_priority()) { + result = true; + priority++; + } + return result; + } + bool has_max_priority () const { return priority >= 3; } @@ -349,7 +368,7 @@ struct graph_t // it's parent where possible. int64_t modified_distance = - hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF); + hb_clamp (distance + distance_modifier (), (int64_t) 0, 0x7FFFFFFFFFF); if (has_max_priority ()) { modified_distance = 0; } @@ -567,6 +586,7 @@ struct graph_t update_distances (); hb_priority_queue_t queue; + queue.alloc (vertices_.length); hb_vector_t &sorted_graph = vertices_scratch_; if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; hb_vector_t id_map; @@ -1022,6 +1042,11 @@ struct graph_t * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parent_idx, this + * will do nothing and return the original child_idx. */ unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx) { @@ -1035,18 +1060,20 @@ struct graph_t * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parent_idx, + * duplication isn't possible and this will return -1. */ unsigned duplicate (unsigned parent_idx, unsigned child_idx) { update_parents (); - unsigned links_to_child = 0; - for (const auto& l : vertices_[parent_idx].obj.all_links ()) - { - if (l.objidx == child_idx) links_to_child++; - } + const auto& child = vertices_[child_idx]; + unsigned links_to_child = child.incoming_edges_from_parent(parent_idx); - if (vertices_[child_idx].incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. @@ -1059,7 +1086,7 @@ struct graph_t parent_idx, child_idx); unsigned clone_idx = duplicate (child_idx); - if (clone_idx == (unsigned) -1) return false; + if (clone_idx == (unsigned) -1) return -1; // duplicate shifts the root node idx, so if parent_idx was root update it. if (parent_idx == clone_idx) parent_idx++; @@ -1075,6 +1102,62 @@ struct graph_t return clone_idx; } + /* + * Creates a copy of child and re-assigns the links from + * parents to the clone. The copy is a shallow copy, objects + * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parents, + * duplication isn't possible or duplication fails and this will + * return -1. + */ + unsigned duplicate (const hb_set_t* parents, unsigned child_idx) + { + if (parents->is_empty()) { + return -1; + } + + update_parents (); + + const auto& child = vertices_[child_idx]; + unsigned links_to_child = 0; + unsigned last_parent = parents->get_max(); + unsigned first_parent = parents->get_min(); + for (unsigned parent_idx : *parents) { + links_to_child += child.incoming_edges_from_parent(parent_idx); + } + + if (child.incoming_edges () <= links_to_child) + { + // Can't duplicate this node, doing so would orphan the original one as all remaining links + // to child are from parent. + DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + return -1; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + + unsigned clone_idx = duplicate (child_idx); + if (clone_idx == (unsigned) -1) return false; + + for (unsigned parent_idx : *parents) { + // 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]; + for (auto& l : parent.obj.all_links_writer ()) + { + if (l.objidx != child_idx) + continue; + + reassign_link (l, parent_idx, clone_idx); + } + } + + return clone_idx; + } + /* * Adds a new node to the graph, not connected to anything. @@ -1370,6 +1453,7 @@ struct graph_t vertices_.tail ().distance = 0; hb_priority_queue_t queue; + queue.alloc (count); queue.insert (0, vertices_.length - 1); hb_vector_t visited; diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh index a5f9223e605..7ad2ba430b7 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh @@ -76,6 +76,7 @@ struct Lookup : public OT::Lookup { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Lookup::min_size) return false; + hb_barrier (); return vertex_len >= this->get_size (); } @@ -351,6 +352,7 @@ struct LookupList : public OT::LookupList { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::LookupList::min_size) return false; + hb_barrier (); return vertex_len >= OT::LookupList::item_size * this->len; } }; @@ -364,6 +366,7 @@ struct GSTAR : public OT::GSUBGPOS GSTAR* gstar = (GSTAR*) r.obj.head; if (!gstar || !gstar->sanitize (r)) return nullptr; + hb_barrier (); return gstar; } @@ -383,6 +386,7 @@ struct GSTAR : public OT::GSUBGPOS { int64_t len = vertex.obj.tail - vertex.obj.head; if (len < OT::GSUBGPOS::min_size) return false; + hb_barrier (); return len >= get_size (); } diff --git a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh index ae5ebd0d167..fb4166128a9 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh @@ -40,6 +40,7 @@ struct AnchorMatrix : public OT::Layout::GPOS_impl::AnchorMatrix { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < AnchorMatrix::min_size) return false; + hb_barrier (); return vertex_len >= AnchorMatrix::min_size + OT::Offset16::static_size * class_count * this->rows; @@ -128,6 +129,7 @@ struct MarkArray : public OT::Layout::GPOS_impl::MarkArray int64_t vertex_len = vertex.obj.tail - vertex.obj.head; unsigned min_size = MarkArray::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= get_size (); } @@ -495,6 +497,7 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos { 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: diff --git a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh index ad158cc9e8f..fd46861de46 100644 --- a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh +++ b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh @@ -42,6 +42,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + pairSet.get_size () - pairSet.len.get_size(); @@ -198,6 +199,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); const unsigned class1_count = class1Count; return vertex_len >= @@ -245,8 +247,8 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4check_struct (this) && + hb_barrier () && version == 0 && c->check_range (this, anchorData) && lookupTable.sanitize (c, this, &(this+anchorData)))); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh index 24d53e224c7..b14540f3a71 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-bsln-table.hh @@ -123,6 +123,7 @@ struct bsln TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && defaultBaseline < 32))) return_trace (false); + hb_barrier (); switch (format) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh index b2d1b7b67e0..673c7fbe945 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh @@ -30,6 +30,10 @@ #include "hb-aat-layout.hh" #include "hb-aat-map.hh" #include "hb-open-type.hh" +#include "hb-cache.hh" +#include "hb-bit-set.hh" +#include "hb-bit-page.hh" + namespace OT { struct GDEF; @@ -39,15 +43,18 @@ namespace AAT { using namespace OT; - struct ankr; +using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; +static_assert (sizeof (hb_aat_class_cache_t) == 256, ""); + struct hb_aat_apply_context_t : hb_dispatch_context_t { const char *get_name () { return "APPLY"; } - template - return_t dispatch (const T &obj) { return obj.apply (this); } + template + return_t dispatch (const T &obj, Ts&&... ds) + { return obj.apply (this, std::forward (ds)...); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } @@ -59,6 +66,12 @@ struct hb_aat_apply_context_t : const ankr *ankr_table; const OT::GDEF *gdef_table; const hb_sorted_vector_t *range_flags = nullptr; + bool using_buffer_glyph_set = false; + hb_bit_set_t buffer_glyph_set; + const hb_bit_set_t *left_set = nullptr; + const hb_bit_set_t *right_set = nullptr; + const hb_bit_set_t *machine_glyph_set = nullptr; + hb_aat_class_cache_t *machine_class_cache = nullptr; hb_mask_t subtable_flags = 0; /* Unused. For debug tracing only. */ @@ -74,6 +87,25 @@ struct hb_aat_apply_context_t : HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_); void set_lookup_index (unsigned int i) { lookup_index = i; } + + void setup_buffer_glyph_set () + { + using_buffer_glyph_set = buffer->len >= 4; + + if (using_buffer_glyph_set) + buffer->collect_codepoints (buffer_glyph_set); + } + bool buffer_intersects_machine () const + { + if (using_buffer_glyph_set) + return buffer_glyph_set.intersects (*machine_glyph_set); + + // Faster for shorter buffers. + for (unsigned i = 0; i < buffer->len; i++) + if (machine_glyph_set->has (buffer->info[i].codepoint)) + return true; + return false; + } }; @@ -81,6 +113,8 @@ struct hb_aat_apply_context_t : * Lookup Table */ +enum { DELETED_GLYPH = 0xFFFF }; + template struct Lookup; template @@ -95,6 +129,19 @@ struct LookupFormat0 return &arrayZ[glyph_id]; } + template + void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + glyphs.add_range (0, num_glyphs - 1); + } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + for (unsigned i = 0; i < num_glyphs; i++) + if (filter (arrayZ[i])) + glyphs.add (i); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -123,6 +170,19 @@ struct LookupSegmentSingle int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1 ; } + template + void collect_glyphs (set_t &glyphs) const + { + if (first == DELETED_GLYPH) return; + glyphs.add_range (first, last); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (!filter (value)) return; + glyphs.add_range (first, last); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -153,6 +213,21 @@ struct LookupFormat2 return v ? &v->value : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = segments.get_length (); + for (unsigned int i = 0; i < count; i++) + segments[i].collect_glyphs (glyphs); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = segments.get_length (); + for (unsigned int i = 0; i < count; i++) + segments[i].collect_glyphs_filtered (glyphs, filter); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -184,6 +259,21 @@ struct LookupSegmentArray return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + if (first == DELETED_GLYPH) return; + glyphs.add_range (first, last); + } + template + void collect_glyphs_filtered (set_t &glyphs, const void *base, const filter_t &filter) const + { + const auto &values = base+valuesZ; + for (hb_codepoint_t i = first; i <= last; i++) + if (filter (values[i - first])) + glyphs.add (i); + } + int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1; } @@ -191,6 +281,7 @@ struct LookupSegmentArray { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && first <= last && valuesZ.sanitize (c, base, last - first + 1)); } @@ -199,6 +290,7 @@ struct LookupSegmentArray { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && first <= last && valuesZ.sanitize (c, base, last - first + 1, std::forward (ds)...)); } @@ -224,6 +316,21 @@ struct LookupFormat4 return v ? v->get_value (glyph_id, this) : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = segments.get_length (); + for (unsigned i = 0; i < count; i++) + segments[i].collect_glyphs (glyphs); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = segments.get_length (); + for (unsigned i = 0; i < count; i++) + segments[i].collect_glyphs_filtered (glyphs, this, filter); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -252,6 +359,19 @@ struct LookupSingle int cmp (hb_codepoint_t g) const { return glyph.cmp (g); } + template + void collect_glyphs (set_t &glyphs) const + { + if (glyph == DELETED_GLYPH) return; + glyphs.add (glyph); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (!filter (value)) return; + glyphs.add (glyph); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -281,6 +401,21 @@ struct LookupFormat6 return v ? &v->value : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = entries.get_length (); + for (unsigned i = 0; i < count; i++) + entries[i].collect_glyphs (glyphs); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = entries.get_length (); + for (unsigned i = 0; i < count; i++) + entries[i].collect_glyphs_filtered (glyphs, filter); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -312,6 +447,24 @@ struct LookupFormat8 &valueArrayZ[glyph_id - firstGlyph] : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + const T *p = valueArrayZ.arrayZ; + for (unsigned i = 0; i < glyphCount; i++) + if (filter (p[i])) + glyphs.add (firstGlyph + i); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -356,10 +509,19 @@ struct LookupFormat10 return v; } + template + void collect_glyphs (set_t &glyphs) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && valueSize <= 4 && valueArrayZ.sanitize (c, glyphCount * valueSize)); } @@ -383,11 +545,11 @@ struct Lookup const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { switch (u.format) { - case 0: return u.format0.get_value (glyph_id, num_glyphs); - case 2: return u.format2.get_value (glyph_id); - case 4: return u.format4.get_value (glyph_id); - case 6: return u.format6.get_value (glyph_id); - case 8: return u.format8.get_value (glyph_id); + case 0: hb_barrier (); return u.format0.get_value (glyph_id, num_glyphs); + case 2: hb_barrier (); return u.format2.get_value (glyph_id); + case 4: hb_barrier (); return u.format4.get_value (glyph_id); + case 6: hb_barrier (); return u.format6.get_value (glyph_id); + case 8: hb_barrier (); return u.format8.get_value (glyph_id); default:return nullptr; } } @@ -396,13 +558,39 @@ struct Lookup { switch (u.format) { /* Format 10 cannot return a pointer. */ - case 10: return u.format10.get_value_or_null (glyph_id); + case 10: hb_barrier (); return u.format10.get_value_or_null (glyph_id); default: const T *v = get_value (glyph_id, num_glyphs); return v ? *v : Null (T); } } + template + void collect_glyphs (set_t &glyphs, unsigned int num_glyphs) const + { + switch (u.format) { + case 0: hb_barrier (); u.format0.collect_glyphs (glyphs, num_glyphs); return; + case 2: hb_barrier (); u.format2.collect_glyphs (glyphs); return; + case 4: hb_barrier (); u.format4.collect_glyphs (glyphs); return; + case 6: hb_barrier (); u.format6.collect_glyphs (glyphs); return; + case 8: hb_barrier (); u.format8.collect_glyphs (glyphs); return; + case 10: hb_barrier (); u.format10.collect_glyphs (glyphs); return; + default:return; + } + } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + switch (u.format) { + case 0: hb_barrier (); u.format0.collect_glyphs_filtered (glyphs, num_glyphs, filter); return; + case 2: hb_barrier (); u.format2.collect_glyphs_filtered (glyphs, filter); return; + case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return; + case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return; + case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return; + default:return; + } + } + typename T::type get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs, unsigned int outOfRange) const @@ -415,13 +603,14 @@ struct Lookup { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 0: return_trace (u.format0.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 4: return_trace (u.format4.sanitize (c)); - case 6: return_trace (u.format6.sanitize (c)); - case 8: return_trace (u.format8.sanitize (c)); - case 10: return_trace (u.format10.sanitize (c)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); + case 6: hb_barrier (); return_trace (u.format6.sanitize (c)); + case 8: hb_barrier (); return_trace (u.format8.sanitize (c)); + case 10: hb_barrier (); return_trace (u.format10.sanitize (c)); default:return_trace (true); } } @@ -429,12 +618,13 @@ struct Lookup { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 0: return_trace (u.format0.sanitize (c, base)); - case 2: return_trace (u.format2.sanitize (c, base)); - case 4: return_trace (u.format4.sanitize (c, base)); - case 6: return_trace (u.format6.sanitize (c, base)); - case 8: return_trace (u.format8.sanitize (c, base)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, base)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c, base)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c, base)); + case 6: hb_barrier (); return_trace (u.format6.sanitize (c, base)); + case 8: hb_barrier (); return_trace (u.format8.sanitize (c, base)); case 10: return_trace (false); /* We don't support format10 here currently. */ default:return_trace (true); } @@ -455,8 +645,6 @@ struct Lookup }; DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); -enum { DELETED_GLYPH = 0xFFFF }; - /* * (Extended) State Table */ @@ -464,7 +652,7 @@ enum { DELETED_GLYPH = 0xFFFF }; template struct Entry { - // This does seem like it's ever called. + // This doesn't seem like it's ever called. bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -507,6 +695,14 @@ struct Entry DEFINE_SIZE_STATIC (4); }; +enum Class +{ + CLASS_END_OF_TEXT = 0, + CLASS_OUT_OF_BOUNDS = 1, + CLASS_DELETED_GLYPH = 2, + CLASS_END_OF_LINE = 3, +}; + template struct StateTable { @@ -519,21 +715,53 @@ struct StateTable STATE_START_OF_TEXT = 0, STATE_START_OF_LINE = 1, }; - enum Class + + template + void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const { - CLASS_END_OF_TEXT = 0, - CLASS_OUT_OF_BOUNDS = 1, - CLASS_DELETED_GLYPH = 2, - CLASS_END_OF_LINE = 3, - }; + (this+classTable).collect_glyphs (glyphs, num_glyphs); + } + template + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const + { + unsigned num_classes = nClasses; + + if (unlikely (num_classes > hb_bit_page_t::BITS)) + { + (this+classTable).collect_glyphs (glyphs, num_glyphs); + return; + } + + // Collect all classes going out from the start state. + hb_bit_page_t filter; + + for (unsigned i = 0; i < num_classes; i++) + { + const auto &entry = get_entry (STATE_START_OF_TEXT, i); + if (new_state (entry.newState) == STATE_START_OF_TEXT && + !table.is_action_initiable (entry) && !table.is_actionable (entry)) + continue; + + filter.add (i); + } + + // And glyphs in those classes. + (this+classTable).collect_glyphs_filtered (glyphs, num_glyphs, filter); + } int new_state (unsigned int newState) const { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; } - unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + unsigned int get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs, + hb_aat_class_cache_t *cache = nullptr) const { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; - return (this+classTable).get_class (glyph_id, num_glyphs, 1); + klass = (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS); + if (cache) cache->set (glyph_id, klass); + return klass; } const Entry *get_entries () const @@ -541,13 +769,14 @@ struct StateTable const Entry &get_entry (int state, unsigned int klass) const { - if (unlikely (klass >= nClasses)) - klass = StateTable::CLASS_OUT_OF_BOUNDS; + unsigned n_classes = nClasses; + if (unlikely (klass >= n_classes)) + klass = CLASS_OUT_OF_BOUNDS; const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry *entries = (this+entryTable).arrayZ; - unsigned int entry = states[state * nClasses + klass]; + unsigned int entry = states[state * n_classes + klass]; DEBUG_MSG (APPLY, nullptr, "e%u", entry); return entries[entry]; @@ -558,6 +787,7 @@ struct StateTable { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && + hb_barrier () && nClasses >= 4 /* Ensure pre-defined classes fit. */ && classTable.sanitize (c, this)))) return_trace (false); @@ -684,6 +914,22 @@ struct ClassTable { return get_class (glyph_id, outOfRange); } + + template + void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + for (unsigned i = 0; i < classArray.len; i++) + if (classArray.arrayZ[i] != CLASS_OUT_OF_BOUNDS) + glyphs.add (firstGlyph + i); + } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + for (unsigned i = 0; i < classArray.len; i++) + if (filter (classArray.arrayZ[i])) + glyphs.add (firstGlyph + i); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -697,6 +943,38 @@ struct ClassTable DEFINE_SIZE_ARRAY (4, classArray); }; +struct SubtableGlyphCoverage +{ + bool sanitize (hb_sanitize_context_t *c, unsigned subtable_count) const + { + TRACE_SANITIZE (this); + + if (unlikely (!c->check_array (&subtableOffsets, subtable_count))) + return_trace (false); + + unsigned bytes = (c->get_num_glyphs () + CHAR_BIT - 1) / CHAR_BIT; + for (unsigned i = 0; i < subtable_count; i++) + { + uint32_t offset = (uint32_t) subtableOffsets[i]; + if (offset == 0 || offset == 0xFFFFFFFF) + continue; + if (unlikely (!subtableOffsets[i].sanitize (c, this, bytes))) + return_trace (false); + } + + return_trace (true); + } + protected: + UnsizedArrayOf>> subtableOffsets; + /* Array of offsets from the beginning of the + * subtable glyph coverage table to the glyph + * coverage bitfield for a given subtable; there + * is one offset for each subtable in the chain */ + /* UnsizedArrayOf coverageBitfields; *//* The individual coverage bitfields. */ + public: + DEFINE_SIZE_ARRAY (0, subtableOffsets); +}; + struct ObsoleteTypes { static constexpr bool extended = false; @@ -766,22 +1044,22 @@ struct ExtendedTypes } }; -template +template struct StateTableDriver { using StateTableT = StateTable; using EntryT = Entry; StateTableDriver (const StateTableT &machine_, - hb_buffer_t *buffer_, hb_face_t *face_) : machine (machine_), - buffer (buffer_), num_glyphs (face_->get_num_glyphs ()) {} template void drive (context_t *c, hb_aat_apply_context_t *ac) { + hb_buffer_t *buffer = ac->buffer; + if (!c->in_place) buffer->clear_output (); @@ -816,9 +1094,9 @@ struct StateTableDriver } } - unsigned int klass = buffer->idx < buffer->len ? - machine.get_class (buffer->cur().codepoint, num_glyphs) : - (unsigned) StateTableT::CLASS_END_OF_TEXT; + unsigned int klass = likely (buffer->idx < buffer->len) ? + machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : + (unsigned) CLASS_END_OF_TEXT; DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); const EntryT &entry = machine.get_entry (state, klass); const int next_state = machine.new_state (entry.newState); @@ -851,44 +1129,39 @@ struct StateTableDriver * * https://github.com/harfbuzz/harfbuzz/issues/2860 */ - - const auto is_safe_to_break_extra = [&]() - { - /* 2c. */ - const auto wouldbe_entry = machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass); - - /* 2c'. */ - if (c->is_actionable (this, wouldbe_entry)) - return false; - - /* 2c". */ - return next_state == machine.new_state(wouldbe_entry.newState) - && (entry.flags & context_t::DontAdvance) == (wouldbe_entry.flags & context_t::DontAdvance); - }; - - const auto is_safe_to_break = [&]() - { + const EntryT *wouldbe_entry; + bool is_safe_to_break = + ( /* 1. */ - if (c->is_actionable (this, entry)) - return false; + !c->table->is_actionable (entry) && /* 2. */ // This one is meh, I know... - const auto ok = + ( state == StateTableT::STATE_START_OF_TEXT - || ((entry.flags & context_t::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) - || is_safe_to_break_extra(); - if (!ok) - return false; + || ((entry.flags & Flags::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) + || ( + /* 2c. */ + wouldbe_entry = &machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass) + , + /* 2c'. */ + !c->table->is_actionable (*wouldbe_entry) && + /* 2c". */ + ( + next_state == machine.new_state(wouldbe_entry->newState) && + (entry.flags & Flags::DontAdvance) == (wouldbe_entry->flags & Flags::DontAdvance) + ) + ) + ) && /* 3. */ - return !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT)); - }; + !c->table->is_actionable (machine.get_entry (state, CLASS_END_OF_TEXT)) + ); - if (!is_safe_to_break () && buffer->backtrack_len () && buffer->idx < buffer->len) + if (!is_safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len) buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); - c->transition (this, entry); + c->transition (buffer, this, entry); state = next_state; DEBUG_MSG (APPLY, nullptr, "s%d", state); @@ -896,7 +1169,7 @@ struct StateTableDriver if (buffer->idx == buffer->len || unlikely (!buffer->successful)) break; - if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0) + if (!(entry.flags & Flags::DontAdvance) || buffer->max_ops-- <= 0) (void) buffer->next_glyph (); } @@ -906,7 +1179,6 @@ struct StateTableDriver public: const StateTableT &machine; - hb_buffer_t *buffer; unsigned int num_glyphs; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh index 04260a94616..7b68a932c3f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-feat-table.hh @@ -138,6 +138,7 @@ struct FeatureName { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (base+settingTableZ).sanitize (c, nSettings))); } @@ -200,6 +201,7 @@ struct feat { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && namesZ.sanitize (c, featureNameCount, this))); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh index 0588310b53b..193d14d94d0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-just-table.hh @@ -185,15 +185,16 @@ struct ActionSubrecord TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (u.header.actionType) { - case 0: return_trace (u.decompositionAction.sanitize (c)); - case 1: return_trace (u.unconditionalAddGlyphAction.sanitize (c)); - case 2: return_trace (u.conditionalAddGlyphAction.sanitize (c)); - // case 3: return_trace (u.stretchGlyphAction.sanitize (c)); - case 4: return_trace (u.decompositionAction.sanitize (c)); - case 5: return_trace (u.decompositionAction.sanitize (c)); + case 0: hb_barrier (); return_trace (u.decompositionAction.sanitize (c)); + case 1: hb_barrier (); return_trace (u.unconditionalAddGlyphAction.sanitize (c)); + case 2: hb_barrier (); return_trace (u.conditionalAddGlyphAction.sanitize (c)); + // case 3: hb_barrier (); return_trace (u.stretchGlyphAction.sanitize (c)); + case 4: hb_barrier (); return_trace (u.decompositionAction.sanitize (c)); + case 5: hb_barrier (); return_trace (u.decompositionAction.sanitize (c)); default: return_trace (true); } } @@ -220,6 +221,7 @@ struct PostcompensationActionChain TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); unsigned int offset = min_size; for (unsigned int i = 0; i < count; i++) @@ -389,6 +391,7 @@ struct just TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && horizData.sanitize (c, this, this) && vertData.sanitize (c, this, this))); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh index 2bc7b03ce89..a091b05660c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-kerx-table.hh @@ -30,6 +30,7 @@ #include "hb-kern.hh" #include "hb-aat-layout-ankr-table.hh" +#include "hb-set-digest.hh" /* * kerx -- Extended Kerning @@ -54,6 +55,7 @@ kerxTupleKern (int value, unsigned int offset = value; const FWORD *pv = &StructAtOffset (base, offset); if (unlikely (!c->sanitizer.check_array (pv, tupleCount))) return 0; + hb_barrier (); return *pv; } @@ -81,7 +83,7 @@ struct KernPair return_trace (c->check_struct (this)); } - protected: + public: HBGlyphID16 left; HBGlyphID16 right; FWORD value; @@ -105,10 +107,10 @@ struct KerxSubTableFormat0 TRACE_APPLY (this); if (!c->plan->requested_kerning) - return false; + return_trace (false); if (header.coverage & header.Backwards) - return false; + return_trace (false); accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); @@ -117,6 +119,16 @@ struct KerxSubTableFormat0 return_trace (true); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + for (const KernPair& pair : pairs) + { + left_set.add (pair.left); + right_set.add (pair.right); + } + } + struct accelerator_t { const KerxSubTableFormat0 &table; @@ -127,7 +139,10 @@ struct KerxSubTableFormat0 table (table_), c (c_) {} int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table.get_kerning (left, right, c); } + { + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + return table.get_kerning (left, right, c); + } }; @@ -192,6 +207,9 @@ struct Format1Entry typedef void EntryData; + static bool initiateAction (const Entry &entry) + { return entry.flags & Push; } + static bool performAction (const Entry &entry) { return entry.flags & Offset; } @@ -208,13 +226,23 @@ struct KerxSubTableFormat1 typedef Format1Entry Format1EntryT; typedef typename Format1EntryT::EntryData EntryData; + enum Flags + { + DontAdvance = Format1EntryT::DontAdvance, + }; + + bool is_action_initiable (const Entry &entry) const + { + return Format1EntryT::initiateAction (entry); + } + bool is_actionable (const Entry &entry) const + { + return Format1EntryT::performAction (entry); + } + struct driver_context_t { static constexpr bool in_place = true; - enum - { - DontAdvance = Format1EntryT::DontAdvance, - }; driver_context_t (const KerxSubTableFormat1 *table_, hb_aat_apply_context_t *c_) : @@ -227,13 +255,10 @@ struct KerxSubTableFormat1 depth (0), crossStream (table->header.coverage & table->header.CrossStream) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { return Format1EntryT::performAction (entry); } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry.flags; if (flags & Format1EntryT::Reset) @@ -259,6 +284,7 @@ struct KerxSubTableFormat1 depth = 0; return; } + hb_barrier (); hb_mask_t kern_mask = c->plan->kern_mask; @@ -330,9 +356,10 @@ struct KerxSubTableFormat1 } } - private: + public: hb_aat_apply_context_t *c; const KerxSubTableFormat1 *table; + private: const UnsizedArrayOf &kernAction; unsigned int stack[8]; unsigned int depth; @@ -349,7 +376,8 @@ struct KerxSubTableFormat1 driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->font->face); + StateTableDriver driver (machine, c->font->face); + driver.drive (&dc, c); return_trace (true); @@ -363,12 +391,21 @@ struct KerxSubTableFormat1 machine.sanitize (c))); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + set_t set; + machine.collect_glyphs (set, num_glyphs); + left_set.union_ (set); + right_set.union_ (set); + } + protected: KernSubTableHeader header; StateTable machine; NNOffsetTo, HBUINT> kernAction; public: - DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 5 * sizeof (HBUINT)); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + (StateTable::static_size + HBUINT::static_size)); }; template @@ -389,6 +426,7 @@ struct KerxSubTableFormat2 kern_idx = Types::offsetToIndex (kern_idx, this, arrayZ.arrayZ); const FWORD *v = &arrayZ[kern_idx]; if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), this, c); } @@ -398,10 +436,10 @@ struct KerxSubTableFormat2 TRACE_APPLY (this); if (!c->plan->requested_kerning) - return false; + return_trace (false); if (header.coverage & header.Backwards) - return false; + return_trace (false); accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); @@ -410,6 +448,13 @@ struct KerxSubTableFormat2 return_trace (true); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + (this+leftClassTable).collect_glyphs (left_set, num_glyphs); + (this+rightClassTable).collect_glyphs (right_set, num_glyphs); + } + struct accelerator_t { const KerxSubTableFormat2 &table; @@ -420,7 +465,10 @@ struct KerxSubTableFormat2 table (table_), c (c_) {} int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table.get_kerning (left, right, c); } + { + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + return table.get_kerning (left, right, c); + } }; bool sanitize (hb_sanitize_context_t *c) const @@ -429,6 +477,7 @@ struct KerxSubTableFormat2 return_trace (likely (c->check_struct (this) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && + hb_barrier () && c->check_range (this, array))); } @@ -461,17 +510,26 @@ struct KerxSubTableFormat4 DEFINE_SIZE_STATIC (2); }; - struct driver_context_t + enum Flags { - static constexpr bool in_place = true; - enum Flags - { - Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before * going to the new state. */ - Reserved = 0x3FFF, /* Not used; set to 0. */ - }; + Reserved = 0x3FFF, /* Not used; set to 0. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & Mark); + } + bool is_actionable (const Entry &entry) const + { + return entry.data.ankrActionIndex != 0xFFFF; + } + struct driver_context_t + { + static constexpr bool in_place = true; enum SubTableFlags { ActionType = 0xC0000000, /* A two-bit field containing the action type. */ @@ -481,22 +539,19 @@ struct KerxSubTableFormat4 * point table. */ }; - driver_context_t (const KerxSubTableFormat4 *table, + driver_context_t (const KerxSubTableFormat4 *table_, hb_aat_apply_context_t *c_) : c (c_), + table (table_), action_type ((table->flags & ActionType) >> 30), ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))), mark_set (false), mark (0) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { return entry.data.ankrActionIndex != 0xFFFF; } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; - if (mark_set && entry.data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len) { hb_glyph_position_t &o = buffer->cur_pos(); @@ -509,6 +564,7 @@ struct KerxSubTableFormat4 double the ankrActionIndex to get the correct offset here. */ const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; + hb_barrier (); unsigned int markControlPoint = *data++; unsigned int currControlPoint = *data++; hb_position_t markX = 0; @@ -537,6 +593,7 @@ struct KerxSubTableFormat4 double the ankrActionIndex to get the correct offset here. */ const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; + hb_barrier (); unsigned int markAnchorPoint = *data++; unsigned int currAnchorPoint = *data++; const Anchor &markAnchor = c->ankr_table->get_anchor (c->buffer->info[mark].codepoint, @@ -557,6 +614,7 @@ struct KerxSubTableFormat4 by 4 to get the correct offset for the given action. */ const FWORD *data = (const FWORD *) &ankrData[entry.data.ankrActionIndex * 4]; if (!c->sanitizer.check_array (data, 4)) return; + hb_barrier (); int markX = *data++; int markY = *data++; int currX = *data++; @@ -579,8 +637,10 @@ struct KerxSubTableFormat4 } } - private: + public: hb_aat_apply_context_t *c; + const KerxSubTableFormat4 *table; + private: unsigned int action_type; const HBUINT16 *ankrData; bool mark_set; @@ -593,7 +653,8 @@ struct KerxSubTableFormat4 driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->font->face); + StateTableDriver driver (machine, c->font->face); + driver.drive (&dc, c); return_trace (true); @@ -607,12 +668,21 @@ struct KerxSubTableFormat4 machine.sanitize (c))); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + set_t set; + machine.collect_glyphs (set, num_glyphs); + left_set.union_ (set); + right_set.union_ (set); + } + protected: KernSubTableHeader header; StateTable machine; HBUINT32 flags; public: - DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 20); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + (StateTable::static_size + HBUINT32::static_size)); }; template @@ -631,7 +701,7 @@ struct KerxSubTableFormat6 unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); if (is_long ()) { - const typename U::Long &t = u.l; + const auto &t = u.l; unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; @@ -639,16 +709,18 @@ struct KerxSubTableFormat6 if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } else { - const typename U::Short &t = u.s; + const auto &t = u.s; unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } } @@ -658,10 +730,10 @@ struct KerxSubTableFormat6 TRACE_APPLY (this); if (!c->plan->requested_kerning) - return false; + return_trace (false); if (header.coverage & header.Backwards) - return false; + return_trace (false); accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); @@ -674,6 +746,7 @@ struct KerxSubTableFormat6 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (is_long () ? ( u.l.rowIndexTable.sanitize (c, this) && @@ -688,6 +761,23 @@ struct KerxSubTableFormat6 c->check_range (this, vector)))); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + if (is_long ()) + { + const auto &t = u.l; + (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + } + else + { + const auto &t = u.s; + (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + } + } + struct accelerator_t { const KerxSubTableFormat6 &table; @@ -698,7 +788,10 @@ struct KerxSubTableFormat6 table (table_), c (c_) {} int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table.get_kerning (left, right, c); } + { + if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0; + return table.get_kerning (left, right, c); + } }; protected: @@ -784,12 +877,27 @@ struct KerxSubTable } } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + unsigned int subtable_type = get_type (); + switch (subtable_type) { + case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; + case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; + case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; + case 4: u.format4.collect_glyphs (left_set, right_set, num_glyphs); return; + case 6: u.format6.collect_glyphs (left_set, right_set, num_glyphs); return; + default: return; + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.header.sanitize (c) || - u.header.length <= u.header.static_size || - !c->check_range (this, u.header.length)) + if (!(u.header.sanitize (c) && + hb_barrier () && + u.header.length >= u.header.static_size && + c->check_range (this, u.header.length))) return_trace (false); return_trace (dispatch (c)); @@ -813,6 +921,8 @@ struct KerxSubTable * The 'kerx' Table */ +using kern_accelerator_data_t = hb_vector_t>; + template struct KerxTable { @@ -829,6 +939,9 @@ struct KerxTable { if (st->get_type () == 1) return true; + + // TODO: What about format 4? What's this API used for anyway? + st = &StructAfter (*st); } return false; @@ -867,7 +980,8 @@ struct KerxTable return v; } - bool apply (AAT::hb_aat_apply_context_t *c) const + bool apply (AAT::hb_aat_apply_context_t *c, + const kern_accelerator_data_t &accel_data) const { c->buffer->unsafe_to_concat (); @@ -914,6 +1028,9 @@ struct KerxTable if (reverse) c->buffer->reverse (); + c->left_set = &accel_data[i].first; + c->right_set = &accel_data[i].second; + { /* See comment in sanitize() for conditional here. */ hb_sanitize_with_object_t with (&c->sanitizer, i < count - 1 ? st : (const SubTable *) nullptr); @@ -936,9 +1053,10 @@ struct KerxTable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!thiz()->version.sanitize (c) || - (unsigned) thiz()->version < (unsigned) T::minVersion || - !thiz()->tableCount.sanitize (c))) + if (unlikely (!(thiz()->version.sanitize (c) && + hb_barrier () && + (unsigned) thiz()->version >= (unsigned) T::minVersion && + thiz()->tableCount.sanitize (c)))) return_trace (false); typedef typename T::SubTable SubTable; @@ -949,6 +1067,7 @@ struct KerxTable { if (unlikely (!st->u.header.sanitize (c))) return_trace (false); + hb_barrier (); /* OpenType kern table has 2-byte subtable lengths. That's limiting. * MS implementation also only supports one subtable, of format 0, * anyway. Certain versions of some fonts, like Calibry, contain @@ -964,8 +1083,61 @@ struct KerxTable st = &StructAfter (*st); } + unsigned majorVersion = thiz()->version; + if (sizeof (thiz()->version) == 4) + majorVersion = majorVersion >> 16; + if (majorVersion >= 3) + { + const SubtableGlyphCoverage *coverage = (const SubtableGlyphCoverage *) st; + if (!coverage->sanitize (c, count)) + return_trace (false); + } + return_trace (true); } + + kern_accelerator_data_t create_accelerator_data (unsigned num_glyphs) const + { + kern_accelerator_data_t accel_data; + + typedef typename T::SubTable SubTable; + + const SubTable *st = &thiz()->firstSubTable; + unsigned int count = thiz()->tableCount; + for (unsigned int i = 0; i < count; i++) + { + hb_bit_set_t left_set, right_set; + st->collect_glyphs (left_set, right_set, num_glyphs); + accel_data.push (hb_pair (left_set, right_set)); + st = &StructAfter (*st); + } + + return accel_data; + } + + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + hb_sanitize_context_t sc; + this->table = sc.reference_table (face); + this->accel_data = this->table->create_accelerator_data (face->get_num_glyphs ()); + } + ~accelerator_t () + { + this->table.destroy (); + } + + hb_blob_t *get_blob () const { return table.get_blob (); } + + bool apply (AAT::hb_aat_apply_context_t *c) const + { + return table->apply (c, accel_data); + } + + hb_blob_ptr_t table; + kern_accelerator_data_t accel_data; + }; }; struct kerx : KerxTable @@ -994,8 +1166,10 @@ struct kerx : KerxTable DEFINE_SIZE_MIN (8); }; +struct kerx_accelerator_t : kerx::accelerator_t { + kerx_accelerator_t (hb_face_t *face) : kerx::accelerator_t (face) {} +}; } /* namespace AAT */ - #endif /* HB_AAT_LAYOUT_KERX_TABLE_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh index 81e126d5eb1..cabdc0eb555 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-morx-table.hh @@ -29,6 +29,7 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" +#include "hb-ot-layout.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-aat-map.hh" @@ -53,36 +54,42 @@ struct RearrangementSubtable typedef void EntryData; - struct driver_context_t + enum Flags { - static constexpr bool in_place = true; - enum Flags - { - MarkFirst = 0x8000, /* If set, make the current glyph the first + MarkFirst = 0x8000, /* If set, make the current glyph the first * glyph to be rearranged. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph + DontAdvance = 0x4000, /* If set, don't advance to the next glyph * before going to the new state. This means * that the glyph index doesn't change, even * if the glyph at that index has changed. */ - MarkLast = 0x2000, /* If set, make the current glyph the last + MarkLast = 0x2000, /* If set, make the current glyph the last * glyph to be rearranged. */ - Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ - Verb = 0x000F, /* The type of rearrangement specified. */ - }; + Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ + Verb = 0x000F, /* The type of rearrangement specified. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & MarkFirst); + } + bool is_actionable (const Entry &entry) const + { + return (entry.flags & Verb); + } + + struct driver_context_t + { + static constexpr bool in_place = true; - driver_context_t (const RearrangementSubtable *table HB_UNUSED) : + driver_context_t (const RearrangementSubtable *table_) : ret (false), + table (table_), start (0), end (0) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { - return (entry.flags & Verb) && start < end; - } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry.flags; if (flags & MarkFirst) @@ -157,6 +164,7 @@ struct RearrangementSubtable public: bool ret; + const RearrangementSubtable *table; private: unsigned int start; unsigned int end; @@ -168,7 +176,14 @@ struct RearrangementSubtable driver_context_t dc (this); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->face); + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + driver.drive (&dc, c); return_trace (dc.ret); @@ -180,10 +195,10 @@ struct RearrangementSubtable return_trace (machine.sanitize (c)); } - protected: + public: StateTable machine; public: - DEFINE_SIZE_STATIC (16); + DEFINE_SIZE_STATIC ((StateTable::static_size)); }; template @@ -201,43 +216,42 @@ struct ContextualSubtable DEFINE_SIZE_STATIC (4); }; + enum Flags + { + SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. */ + Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & SetMark); + } + bool is_actionable (const Entry &entry) const + { + return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF; + } + struct driver_context_t { static constexpr bool in_place = true; - enum Flags - { - SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. */ - Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ - }; driver_context_t (const ContextualSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), + table (table_), gdef (*c->gdef_table), mark_set (false), has_glyph_classes (gdef.has_glyph_classes ()), mark (0), - table (table_), subs (table+table->substitutionTables) {} - bool is_actionable (StateTableDriver *driver, - const Entry &entry) - { - hb_buffer_t *buffer = driver->buffer; - - if (buffer->idx == buffer->len && !mark_set) - return false; - - return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF; - } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; - /* Looks like CoreText applies neither mark nor current substitution for * end-of-text if mark was not explicitly set. */ if (buffer->idx == buffer->len && !mark_set) @@ -259,13 +273,17 @@ struct ContextualSubtable unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; - if (!replacement->sanitize (&c->sanitizer) || !*replacement) + if (!(replacement->sanitize (&c->sanitizer) && + hb_barrier () && + *replacement)) replacement = nullptr; } if (replacement) { buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); - buffer->info[mark].codepoint = *replacement; + hb_codepoint_t glyph = *replacement; + buffer->info[mark].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&buffer->info[mark], gdef.get_glyph_props (*replacement)); @@ -287,12 +305,16 @@ struct ContextualSubtable unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; - if (!replacement->sanitize (&c->sanitizer) || !*replacement) + if (!(replacement->sanitize (&c->sanitizer) && + hb_barrier () && + *replacement)) replacement = nullptr; } if (replacement) { - buffer->info[idx].codepoint = *replacement; + hb_codepoint_t glyph = *replacement; + buffer->info[idx].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&buffer->info[idx], gdef.get_glyph_props (*replacement)); @@ -308,14 +330,14 @@ struct ContextualSubtable public: bool ret; - private: hb_aat_apply_context_t *c; + const ContextualSubtable *table; + private: const OT::GDEF &gdef; bool mark_set; bool has_glyph_classes; unsigned int mark; - const ContextualSubtable *table; - const UnsizedListOfOffset16To, HBUINT, false> &subs; + const UnsizedListOfOffset16To, HBUINT, void, false> &subs; }; bool apply (hb_aat_apply_context_t *c) const @@ -324,7 +346,14 @@ struct ContextualSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->face); + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + driver.drive (&dc, c); return_trace (dc.ret); @@ -336,6 +365,7 @@ struct ContextualSubtable unsigned int num_entries = 0; if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false); + hb_barrier (); if (!Types::extended) return_trace (substitutionTables.sanitize (c, this, 0)); @@ -356,13 +386,14 @@ struct ContextualSubtable return_trace (substitutionTables.sanitize (c, this, num_lookups)); } - protected: + public: StateTable machine; - NNOffsetTo, HBUINT, false>, HBUINT> + protected: + NNOffsetTo, HBUINT, void, false>, HBUINT> substitutionTables; public: - DEFINE_SIZE_STATIC (20); + DEFINE_SIZE_STATIC ((StateTable::static_size + HBUINT::static_size)); }; @@ -372,6 +403,16 @@ struct LigatureEntry; template <> struct LigatureEntry { + + struct EntryData + { + HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry + * for processing this group, if indicated + * by the flags. */ + public: + DEFINE_SIZE_STATIC (2); + }; + enum Flags { SetComponent = 0x8000, /* Push this glyph onto the component stack for @@ -383,14 +424,8 @@ struct LigatureEntry Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ }; - struct EntryData - { - HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry - * for processing this group, if indicated - * by the flags. */ - public: - DEFINE_SIZE_STATIC (2); - }; + static bool initiateAction (const Entry &entry) + { return entry.flags & SetComponent; } static bool performAction (const Entry &entry) { return entry.flags & PerformAction; } @@ -401,6 +436,8 @@ struct LigatureEntry template <> struct LigatureEntry { + typedef void EntryData; + enum Flags { SetComponent = 0x8000, /* Push this glyph onto the component stack for @@ -412,7 +449,8 @@ struct LigatureEntry * multiple of 4. */ }; - typedef void EntryData; + static bool initiateAction (const Entry &entry) + { return entry.flags & SetComponent; } static bool performAction (const Entry &entry) { return entry.flags & Offset; } @@ -430,13 +468,23 @@ struct LigatureSubtable typedef LigatureEntry LigatureEntryT; typedef typename LigatureEntryT::EntryData EntryData; + enum Flags + { + DontAdvance = LigatureEntryT::DontAdvance, + }; + + bool is_action_initiable (const Entry &entry) const + { + return LigatureEntryT::initiateAction (entry); + } + bool is_actionable (const Entry &entry) const + { + return LigatureEntryT::performAction (entry); + } + struct driver_context_t { static constexpr bool in_place = false; - enum - { - DontAdvance = LigatureEntryT::DontAdvance, - }; enum LigActionFlags { LigActionLast = 0x80000000, /* This is the last action in the list. This also @@ -459,16 +507,10 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { - return LigatureEntryT::performAction (entry); - } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; - DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx); if (entry.flags & LigatureEntryT::SetComponent) { @@ -513,6 +555,7 @@ struct LigatureSubtable if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return; if (unlikely (!actionData->sanitize (&c->sanitizer))) break; + hb_barrier (); action = *actionData; uint32_t uoffset = action & LigActionOffset; @@ -523,6 +566,7 @@ struct LigatureSubtable component_idx = Types::wordOffsetToIndex (component_idx, table, component.arrayZ); const HBUINT16 &componentData = component[component_idx]; if (unlikely (!componentData.sanitize (&c->sanitizer))) break; + hb_barrier (); ligature_idx += componentData; DEBUG_MSG (APPLY, nullptr, "Action store %d last %d", @@ -533,6 +577,7 @@ struct LigatureSubtable ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ); const HBGlyphID16 &ligatureData = ligature[ligature_idx]; if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break; + hb_barrier (); hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); @@ -544,6 +589,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; + _hb_glyph_info_set_default_ignorable (&buffer->cur()); if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; } @@ -560,9 +606,9 @@ struct LigatureSubtable public: bool ret; - private: hb_aat_apply_context_t *c; const LigatureSubtable *table; + private: const UnsizedArrayOf &ligAction; const UnsizedArrayOf &component; const UnsizedArrayOf &ligature; @@ -576,7 +622,14 @@ struct LigatureSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->face); + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + driver.drive (&dc, c); return_trace (dc.ret); @@ -587,12 +640,14 @@ struct LigatureSubtable TRACE_SANITIZE (this); /* The rest of array sanitizations are done at run-time. */ return_trace (c->check_struct (this) && machine.sanitize (c) && + hb_barrier () && ligAction && component && ligature); } - protected: + public: StateTable machine; + protected: NNOffsetTo, HBUINT> ligAction; /* Offset to the ligature action table. */ NNOffsetTo, HBUINT> @@ -600,7 +655,7 @@ struct LigatureSubtable NNOffsetTo, HBUINT> ligature; /* Offset to the actual ligature lists. */ public: - DEFINE_SIZE_STATIC (28); + DEFINE_SIZE_STATIC ((StateTable::static_size + 3 * HBUINT::static_size)); }; template @@ -610,6 +665,12 @@ struct NoncontextualSubtable { TRACE_APPLY (this); + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + const OT::GDEF &gdef (*c->gdef_table); bool has_glyph_classes = gdef.has_glyph_classes (); @@ -642,7 +703,9 @@ struct NoncontextualSubtable const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs); if (replacement) { - info[i].codepoint = *replacement; + hb_codepoint_t glyph = *replacement; + info[i].codepoint = glyph; + c->buffer_glyph_set.add (glyph); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&info[i], gdef.get_glyph_props (*replacement)); @@ -653,6 +716,12 @@ struct NoncontextualSubtable return_trace (ret); } + template + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + substitute.collect_glyphs (glyphs, num_glyphs); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -686,74 +755,80 @@ struct InsertionSubtable DEFINE_SIZE_STATIC (4); }; + enum Flags + { + SetMark = 0x8000, /* If set, mark the current glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. This does not mean + * that the glyph pointed to is the same one as + * before. If you've made insertions immediately + * downstream of the current glyph, the next glyph + * processed would in fact be the first one + * inserted. */ + CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). If clear, and + * the currentInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). */ + MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). If clear, and + * the markedInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). */ + CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made + * to the left of the current glyph. If clear, + * they're made to the right of the current glyph. */ + MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be + * made to the left of the marked glyph. If clear, + * they're made to the right of the marked glyph. */ + CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the current + * position. Since zero means no insertions, the + * largest number of insertions at any given + * current location is 31 glyphs. */ + MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the marked + * position. Since zero means no insertions, the + * largest number of insertions at any given + * marked location is 31 glyphs. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & SetMark); + } + bool is_actionable (const Entry &entry) const + { + return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) && + (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF); + } + struct driver_context_t { static constexpr bool in_place = false; - enum Flags - { - SetMark = 0x8000, /* If set, mark the current glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. This does not mean - * that the glyph pointed to is the same one as - * before. If you've made insertions immediately - * downstream of the current glyph, the next glyph - * processed would in fact be the first one - * inserted. */ - CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, - * then the specified glyph list will be inserted - * as a kashida-like insertion, either before or - * after the current glyph (depending on the state - * of the currentInsertBefore flag). If clear, and - * the currentInsertList is nonzero, then the - * specified glyph list will be inserted as a - * split-vowel-like insertion, either before or - * after the current glyph (depending on the state - * of the currentInsertBefore flag). */ - MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, - * then the specified glyph list will be inserted - * as a kashida-like insertion, either before or - * after the marked glyph (depending on the state - * of the markedInsertBefore flag). If clear, and - * the markedInsertList is nonzero, then the - * specified glyph list will be inserted as a - * split-vowel-like insertion, either before or - * after the marked glyph (depending on the state - * of the markedInsertBefore flag). */ - CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made - * to the left of the current glyph. If clear, - * they're made to the right of the current glyph. */ - MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be - * made to the left of the marked glyph. If clear, - * they're made to the right of the marked glyph. */ - CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the - * number of glyphs to insert at the current - * position. Since zero means no insertions, the - * largest number of insertions at any given - * current location is 31 glyphs. */ - MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the - * number of glyphs to insert at the marked - * position. Since zero means no insertions, the - * largest number of insertions at any given - * marked location is 31 glyphs. */ - }; - driver_context_t (const InsertionSubtable *table, + driver_context_t (const InsertionSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), + table (table_), mark (0), insertionAction (table+table->insertionAction) {} - bool is_actionable (StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { - return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) && - (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF); - } - void transition (StateTableDriver *driver, + void transition (hb_buffer_t *buffer, + StateTableDriver *driver, const Entry &entry) { - hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry.flags; unsigned mark_loc = buffer->out_len; @@ -765,6 +840,7 @@ struct InsertionSubtable unsigned int start = entry.data.markedInsertIndex; const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; + hb_barrier (); bool before = flags & MarkedInsertBefore; @@ -775,6 +851,9 @@ struct InsertionSubtable if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; + for (unsigned int i = 0; i < count; i++) + c->buffer_glyph_set.add (glyphs[i]); + ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -793,6 +872,7 @@ struct InsertionSubtable unsigned int start = entry.data.currentInsertIndex; const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; + hb_barrier (); bool before = flags & CurrentInsertBefore; @@ -826,8 +906,9 @@ struct InsertionSubtable public: bool ret; - private: hb_aat_apply_context_t *c; + const InsertionSubtable *table; + private: unsigned int mark; const UnsizedArrayOf &insertionAction; }; @@ -838,7 +919,14 @@ struct InsertionSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->buffer, c->face); + StateTableDriver driver (machine, c->face); + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); + return_trace (false); + } + driver.drive (&dc, c); return_trace (dc.ret); @@ -849,17 +937,19 @@ struct InsertionSubtable TRACE_SANITIZE (this); /* The rest of array sanitizations are done at run-time. */ return_trace (c->check_struct (this) && machine.sanitize (c) && + hb_barrier () && insertionAction); } - protected: + public: StateTable machine; + protected: NNOffsetTo, HBUINT> insertionAction; /* Byte offset from stateHeader to the start of * the insertion glyph table. */ public: - DEFINE_SIZE_STATIC (20); + DEFINE_SIZE_STATIC ((StateTable::static_size + HBUINT::static_size)); }; @@ -883,6 +973,107 @@ struct Feature DEFINE_SIZE_STATIC (12); }; + +struct hb_accelerate_subtables_context_t : + hb_dispatch_context_t +{ + struct hb_applicable_t + { + friend struct hb_accelerate_subtables_context_t; + friend struct hb_aat_layout_lookup_accelerator_t; + + public: + hb_bit_set_t glyph_set; + mutable hb_aat_class_cache_t class_cache; + + template + auto init_ (const T &obj_, unsigned num_glyphs, hb_priority<1>) HB_AUTO_RETURN + ( + obj_.machine.collect_initial_glyphs (glyph_set, num_glyphs, obj_) + ) + + template + void init_ (const T &obj_, unsigned num_glyphs, hb_priority<0>) + { + obj_.collect_initial_glyphs (glyph_set, num_glyphs); + } + + template + void init (const T &obj_, unsigned num_glyphs) + { + glyph_set.init (); + init_ (obj_, num_glyphs, hb_prioritize); + class_cache.clear (); + } + + void + fini () + { + glyph_set.fini (); + } + }; + + /* Dispatch interface. */ + template + return_t dispatch (const T &obj) + { + hb_applicable_t *entry = &array[i++]; + + entry->init (obj, num_glyphs); + + return hb_empty_t (); + } + static return_t default_return_value () { return hb_empty_t (); } + + bool stop_sublookup_iteration (return_t r) const { return false; } + + hb_accelerate_subtables_context_t (hb_applicable_t *array_, unsigned num_glyphs_) : + hb_dispatch_context_t (), + array (array_), num_glyphs (num_glyphs_) {} + + hb_applicable_t *array; + unsigned num_glyphs; + unsigned i = 0; +}; + +struct hb_aat_layout_chain_accelerator_t +{ + template + static hb_aat_layout_chain_accelerator_t *create (const TChain &chain, unsigned num_glyphs) + { + unsigned count = chain.get_subtable_count (); + + unsigned size = sizeof (hb_aat_layout_chain_accelerator_t) - + HB_VAR_ARRAY * sizeof (hb_accelerate_subtables_context_t::hb_applicable_t) + + count * sizeof (hb_accelerate_subtables_context_t::hb_applicable_t); + + /* The following is a calloc because when we are collecting subtables, + * some of them might be invalid and hence not collect; as a result, + * we might not fill in all the count entries of the subtables array. + * Zeroing it allows the set digest to gatekeep it without having to + * initialize it further. */ + auto *thiz = (hb_aat_layout_chain_accelerator_t *) hb_calloc (1, size); + if (unlikely (!thiz)) + return nullptr; + + thiz->count = count; + + hb_accelerate_subtables_context_t c_accelerate_subtables (thiz->subtables, num_glyphs); + chain.dispatch (&c_accelerate_subtables); + + return thiz; + } + + void destroy () + { + for (unsigned i = 0; i < count; i++) + subtables[i].fini (); + } + + unsigned count; + hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; +}; + template struct ChainSubtable { @@ -937,19 +1128,22 @@ struct ChainSubtable bool apply (hb_aat_apply_context_t *c) const { TRACE_APPLY (this); - hb_sanitize_with_object_t with (&c->sanitizer, this); + // Disabled for https://github.com/harfbuzz/harfbuzz/issues/4873 + //hb_sanitize_with_object_t with (&c->sanitizer, this); return_trace (dispatch (c)); } bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!length.sanitize (c) || - length <= min_size || - !c->check_range (this, length)) + if (!(length.sanitize (c) && + hb_barrier () && + length >= min_size && + c->check_range (this, length))) return_trace (false); - hb_sanitize_with_object_t with (c, this); + // Disabled for https://github.com/harfbuzz/harfbuzz/issues/4873 + //hb_sanitize_with_object_t with (c, this); return_trace (dispatch (c)); } @@ -973,6 +1167,8 @@ struct Chain { typedef typename Types::HBUINT HBUINT; + unsigned get_subtable_count () const { return subtableCount; } + hb_mask_t compile_flags (const hb_aat_map_builder_t *map) const { hb_mask_t flags = defaultFlags; @@ -1013,7 +1209,8 @@ struct Chain return flags; } - void apply (hb_aat_apply_context_t *c) const + void apply (hb_aat_apply_context_t *c, + const hb_aat_layout_chain_accelerator_t *accel) const { const ChainSubtable *subtable = &StructAfter> (featureZ.as_array (featureCount)); unsigned int count = subtableCount; @@ -1021,14 +1218,19 @@ struct Chain { bool reverse; + auto coverage = subtable->get_coverage (); + + hb_mask_t subtable_flags = subtable->subFeatureFlags; if (hb_none (hb_iter (c->range_flags) | - hb_map ([&subtable] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable->subFeatureFlags & (_.flags); }))) + hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; - c->subtable_flags = subtable->subFeatureFlags; + c->subtable_flags = subtable_flags; + c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); + c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; - if (!(subtable->get_coverage() & ChainSubtable::AllDirections) && + if (!(coverage & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != - bool (subtable->get_coverage() & ChainSubtable::Vertical)) + bool (coverage & ChainSubtable::Vertical)) goto skip; /* Buffer contents is always in logical direction. Determine if @@ -1058,9 +1260,9 @@ struct Chain (the order opposite that of the characters, which may be right-to-left or left-to-right). */ - reverse = subtable->get_coverage () & ChainSubtable::Logical ? - bool (subtable->get_coverage () & ChainSubtable::Backwards) : - bool (subtable->get_coverage () & ChainSubtable::Backwards) != + reverse = coverage & ChainSubtable::Logical ? + bool (coverage & ChainSubtable::Backwards) : + bool (coverage & ChainSubtable::Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index)) @@ -1086,12 +1288,28 @@ struct Chain unsigned int get_size () const { return length; } - bool sanitize (hb_sanitize_context_t *c, unsigned int version HB_UNUSED) const + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + const ChainSubtable *subtable = &StructAfter> (featureZ.as_array (featureCount)); + unsigned int count = subtableCount; + for (unsigned int i = 0; i < count; i++) + { + typename context_t::return_t ret = subtable->dispatch (c, std::forward (ds)...); + if (c->stop_sublookup_iteration (ret)) + return ret; + subtable = &StructAfter> (*subtable); + } + return c->default_return_value (); + } + + bool sanitize (hb_sanitize_context_t *c, unsigned int version) const { TRACE_SANITIZE (this); - if (!length.sanitize (c) || - length < min_size || - !c->check_range (this, length)) + if (!(length.sanitize (c) && + hb_barrier () && + length >= min_size && + c->check_range (this, length))) return_trace (false); if (!c->check_array (featureZ.arrayZ, featureCount)) @@ -1103,9 +1321,17 @@ struct Chain { if (!subtable->sanitize (c)) return_trace (false); + hb_barrier (); subtable = &StructAfter> (*subtable); } + if (version >= 3) + { + const SubtableGlyphCoverage *coverage = (const SubtableGlyphCoverage *) subtable; + if (!coverage->sanitize (c, count)) + return_trace (false); + } + return_trace (true); } @@ -1117,7 +1343,7 @@ struct Chain UnsizedArrayOf featureZ; /* Features. */ /*ChainSubtable firstSubtable;*//* Subtables. */ -/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ +/*SubtableGlyphCoverage coverages*//* Only if version >= 3. */ public: DEFINE_SIZE_MIN (8 + 2 * sizeof (HBUINT)); @@ -1128,13 +1354,79 @@ struct Chain * The 'mort'/'morx' Table */ -template +template struct mortmorx { static constexpr hb_tag_t tableTag = TAG; bool has_data () const { return version != 0; } + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + hb_sanitize_context_t sc; + this->table = sc.reference_table (face); + + if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face))) + { + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); + } + + this->chain_count = table->get_chain_count (); + + this->accels = (hb_atomic_ptr_t *) hb_calloc (this->chain_count, sizeof (*accels)); + if (unlikely (!this->accels)) + { + this->chain_count = 0; + this->table.destroy (); + this->table = hb_blob_get_empty (); + } + } + ~accelerator_t () + { + for (unsigned int i = 0; i < this->chain_count; i++) + { + if (this->accels[i]) + this->accels[i]->destroy (); + hb_free (this->accels[i]); + } + hb_free (this->accels); + this->table.destroy (); + } + + hb_blob_t *get_blob () const { return table.get_blob (); } + + template + hb_aat_layout_chain_accelerator_t *get_accel (unsigned chain_index, const Chain &chain, unsigned num_glyphs) const + { + if (unlikely (chain_index >= chain_count)) return nullptr; + + retry: + auto *accel = accels[chain_index].get_acquire (); + if (unlikely (!accel)) + { + accel = hb_aat_layout_chain_accelerator_t::create (chain, num_glyphs); + if (unlikely (!accel)) + return nullptr; + + if (unlikely (!accels[chain_index].cmpexch (nullptr, accel))) + { + hb_free (accel); + goto retry; + } + } + + return accel; + } + + hb_blob_ptr_t table; + unsigned int chain_count; + hb_atomic_ptr_t *accels; + }; + + void compile_flags (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) const { @@ -1151,20 +1443,28 @@ struct mortmorx } } + unsigned get_chain_count () const + { + return chainCount; + } void apply (hb_aat_apply_context_t *c, - const hb_aat_map_t &map) const + const hb_aat_map_t &map, + const accelerator_t &accel) const { if (unlikely (!c->buffer->successful)) return; c->buffer->unsafe_to_concat (); + c->setup_buffer_glyph_set (); + c->set_lookup_index (0); const Chain *chain = &firstChain; unsigned int count = chainCount; for (unsigned int i = 0; i < count; i++) { + auto *chain_accel = accel.get_accel (i, *chain, c->face->get_num_glyphs ()); c->range_flags = &map.chain_flags[i]; - chain->apply (c); + chain->apply (c, chain_accel); if (unlikely (!c->buffer->successful)) return; chain = &StructAfter> (*chain); } @@ -1173,7 +1473,10 @@ struct mortmorx bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!version.sanitize (c) || !version || !chainCount.sanitize (c)) + if (!(version.sanitize (c) && + hb_barrier () && + version && + chainCount.sanitize (c))) return_trace (false); const Chain *chain = &firstChain; @@ -1182,6 +1485,7 @@ struct mortmorx { if (!chain->sanitize (c, version)) return_trace (false); + hb_barrier (); chain = &StructAfter> (*chain); } @@ -1200,8 +1504,24 @@ struct mortmorx DEFINE_SIZE_MIN (8); }; -struct morx : mortmorx {}; -struct mort : mortmorx {}; +struct morx : mortmorx +{ + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; +}; + +struct mort : mortmorx +{ + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; +}; + +struct morx_accelerator_t : morx::accelerator_t { + morx_accelerator_t (hb_face_t *face) : morx::accelerator_t (face) {} +}; +struct mort_accelerator_t : mort::accelerator_t { + mort_accelerator_t (hb_face_t *face) : mort::accelerator_t (face) {} +}; } /* namespace AAT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh index 959382f356f..f28ec326b45 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-opbd-table.hh @@ -133,8 +133,8 @@ struct opbd { switch (format) { - case 0: return u.format0.get_bounds (font, glyph_id, extents, this); - case 1: return u.format1.get_bounds (font, glyph_id, extents, this); + case 0: hb_barrier (); return u.format0.get_bounds (font, glyph_id, extents, this); + case 1: hb_barrier (); return u.format1.get_bounds (font, glyph_id, extents, this); default:return false; } } @@ -144,11 +144,12 @@ struct opbd TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this) || version.major != 1)) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, this)); - case 1: return_trace (u.format1.sanitize (c, this)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, this)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c, this)); default:return_trace (true); } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh index 5c49d1f0562..0db4035fd8c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh @@ -48,17 +48,69 @@ struct TrackTableEntry float get_track_value () const { return track.to_float (); } - int get_value (const void *base, unsigned int index, - unsigned int table_size) const - { return (base+valuesZ).as_array (table_size)[index]; } + float interpolate_at (unsigned int idx, + float ptem, + const void *base, + hb_array_t size_table) const + { + const FWORD *values = (base+valuesZ).arrayZ; + + float s0 = size_table[idx].to_float (); + float s1 = size_table[idx + 1].to_float (); + int v0 = values[idx]; + int v1 = values[idx + 1]; + + // Deal with font bugs. + if (unlikely (s1 < s0)) + { hb_swap (s0, s1); hb_swap (v0, v1); } + if (unlikely (ptem < s0)) return v0; + if (unlikely (ptem > s1)) return v1; + if (unlikely (s0 == s1)) return (v0 + v1) * 0.5f; + + float t = (ptem - s0) / (s1 - s0); + return v0 + t * (v1 - v0); + } + + float get_value (float ptem, + const void *base, + hb_array_t size_table) const + { + const FWORD *values = (base+valuesZ).arrayZ; + + unsigned int n_sizes = size_table.length; + + /* + * Choose size. + */ + if (!n_sizes) return 0.f; + if (n_sizes == 1) return values[0]; + + // At least two entries. + + unsigned i; + for (i = 0; i < n_sizes; i++) + if (size_table[i].to_float () >= ptem) + break; + + // Boundary conditions. + if (i == 0) return values[0]; + if (i == n_sizes) return values[n_sizes - 1]; + + // Exact match. + if (size_table[i].to_float () == ptem) return values[i]; + + // Interpolate. + return interpolate_at (i - 1, ptem, base, size_table); + } public: - bool sanitize (hb_sanitize_context_t *c, const void *base, - unsigned int table_size) const + bool sanitize (hb_sanitize_context_t *c, + const void *base, + unsigned int n_sizes) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - (valuesZ.sanitize (c, base, table_size)))); + (valuesZ.sanitize (c, base, n_sizes)))); } protected: @@ -76,64 +128,45 @@ struct TrackTableEntry struct TrackData { - float interpolate_at (unsigned int idx, - float target_size, - const TrackTableEntry &trackTableEntry, - const void *base) const + float get_tracking (const void *base, float ptem, float track = 0.f) const { - unsigned int sizes = nSizes; - hb_array_t size_table ((base+sizeTable).arrayZ, sizes); + unsigned count = nTracks; + hb_array_t size_table = (base+sizeTable).as_array (nSizes); - float s0 = size_table[idx].to_float (); - float s1 = size_table[idx + 1].to_float (); - float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0); - return t * trackTableEntry.get_value (base, idx + 1, sizes) + - (1.f - t) * trackTableEntry.get_value (base, idx, sizes); - } + if (!count) return 0.f; + if (count == 1) return trackTable[0].get_value (ptem, base, size_table); - int get_tracking (const void *base, float ptem) const - { - /* - * Choose track. - */ - const TrackTableEntry *trackTableEntry = nullptr; - unsigned int count = nTracks; - for (unsigned int i = 0; i < count; i++) - { - /* Note: Seems like the track entries are sorted by values. But the - * spec doesn't explicitly say that. It just mentions it in the example. */ - - /* For now we only seek for track entries with zero tracking value */ - - if (trackTable[i].get_track_value () == 0.f) - { - trackTableEntry = &trackTable[i]; - break; - } - } - if (!trackTableEntry) return 0; + // At least two entries. - /* - * Choose size. - */ - unsigned int sizes = nSizes; - if (!sizes) return 0; - if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes); - - hb_array_t size_table ((base+sizeTable).arrayZ, sizes); - unsigned int size_index; - for (size_index = 0; size_index < sizes - 1; size_index++) - if (size_table[size_index].to_float () >= ptem) - break; + unsigned i = 0; + unsigned j = count - 1; + + // Find the two entries that track is between. + while (i + 1 < count && trackTable[i + 1].get_track_value () < track) + i++; + while (j > 0 && trackTable[j - 1].get_track_value () > track) + j--; + + // Exact match. + if (i == j) return trackTable[i].get_value (ptem, base, size_table); + + // Interpolate. - return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem, - *trackTableEntry, base)); + float t0 = trackTable[i].get_track_value (); + float t1 = trackTable[j].get_track_value (); + + float t = (track - t0) / (t1 - t0); + + float a = trackTable[i].get_value (ptem, base, size_table); + float b = trackTable[j].get_value (ptem, base, size_table); + return a + t * (b - a); } bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && sizeTable.sanitize (c, base, nSizes) && trackTable.sanitize (c, nTracks, base, nSizes))); } @@ -157,45 +190,15 @@ struct trak bool has_data () const { return version.to_int (); } - bool apply (hb_aat_apply_context_t *c) const + hb_position_t get_h_tracking (hb_font_t *font, float track = 0.f) const + { + float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; + return font->em_scalef_x ((this+horizData).get_tracking (this, ptem, track)); + } + hb_position_t get_v_tracking (hb_font_t *font, float track = 0.f) const { - TRACE_APPLY (this); - - hb_mask_t trak_mask = c->plan->trak_mask; - - const float ptem = c->font->ptem; - if (unlikely (ptem <= 0.f)) - return_trace (false); - - hb_buffer_t *buffer = c->buffer; - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - { - const TrackData &trackData = this+horizData; - int tracking = trackData.get_tracking (this, ptem); - hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2); - hb_position_t advance_to_add = c->font->em_scalef_x (tracking); - foreach_grapheme (buffer, start, end) - { - if (!(buffer->info[start].mask & trak_mask)) continue; - buffer->pos[start].x_advance += advance_to_add; - buffer->pos[start].x_offset += offset_to_add; - } - } - else - { - const TrackData &trackData = this+vertData; - int tracking = trackData.get_tracking (this, ptem); - hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2); - hb_position_t advance_to_add = c->font->em_scalef_y (tracking); - foreach_grapheme (buffer, start, end) - { - if (!(buffer->info[start].mask & trak_mask)) continue; - buffer->pos[start].y_advance += advance_to_add; - buffer->pos[start].y_offset += offset_to_add; - } - } - - return_trace (true); + float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; + return font->em_scalef_y ((this+vertData).get_tracking (this, ptem, track)); } bool sanitize (hb_sanitize_context_t *c) const @@ -203,6 +206,7 @@ struct trak TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && horizData.sanitize (c, this, this) && vertData.sanitize (c, this, this))); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc index fc5834c7ca1..2cc94257aa7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc @@ -34,9 +34,12 @@ #include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" -#include "hb-aat-layout-trak-table.hh" +#include "hb-aat-layout-trak-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-ltag-table.hh" +#include "hb-ot-layout-gsub-table.hh" +#include "hb-ot-layout-gdef-table.hh" + /* * hb_aat_apply_context_t @@ -207,18 +210,48 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) */ +bool +AAT::morx::is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const +{ +#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST + return false; +#endif + + switch HB_CODEPOINT_ENCODE3 (blob->length, + face->table.GSUB->table.get_length (), + face->table.GDEF->table.get_length ()) + { + /* https://github.com/harfbuzz/harfbuzz/issues/4108 + sha1sum:a71ca6813b7e56a772cffff7c24a5166b087197c AALMAGHRIBI.ttf */ + case HB_CODEPOINT_ENCODE3 (19892, 2794, 340): + return true; + } + return false; +} + +bool +AAT::mort::is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const +{ +#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST + return false; +#endif + return false; +} + void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) { - const AAT::morx& morx = *mapper->face->table.morx; + const AAT::morx& morx = *mapper->face->table.morx->table; if (morx.has_data ()) { morx.compile_flags (mapper, map); return; } - const AAT::mort& mort = *mapper->face->table.mort; + const AAT::mort& mort = *mapper->face->table.mort->table; if (mort.has_data ()) { mort.compile_flags (mapper, map); @@ -243,8 +276,8 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face) { - return face->table.morx->has_data () || - face->table.mort->has_data (); + return face->table.morx->table->has_data () || + face->table.mort->table->has_data (); } void @@ -260,26 +293,30 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, hb_aat_map_t map; builder.compile (map); - hb_blob_t *morx_blob = font->face->table.morx.get_blob (); - const AAT::morx& morx = *morx_blob->as (); - if (morx.has_data ()) { - AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob); - if (!buffer->message (font, "start table morx")) return; - morx.apply (&c, map); - (void) buffer->message (font, "end table morx"); - return; + auto &accel = *font->face->table.morx; + const AAT::morx& morx = *accel.table; + if (morx.has_data ()) + { + AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); + if (!buffer->message (font, "start table morx")) return; + morx.apply (&c, map, accel); + (void) buffer->message (font, "end table morx"); + return; + } } - hb_blob_t *mort_blob = font->face->table.mort.get_blob (); - const AAT::mort& mort = *mort_blob->as (); - if (mort.has_data ()) { - AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob); - if (!buffer->message (font, "start table mort")) return; - mort.apply (&c, map); - (void) buffer->message (font, "end table mort"); - return; + auto &accel = *font->face->table.mort; + const AAT::mort& mort = *accel.table; + if (mort.has_data ()) + { + AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); + if (!buffer->message (font, "start table mort")) return; + mort.apply (&c, map, accel); + (void) buffer->message (font, "end table mort"); + return; + } } } @@ -322,7 +359,7 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) hb_bool_t hb_aat_layout_has_positioning (hb_face_t *face) { - return face->table.kerx->has_data (); + return face->table.kerx->table->has_data (); } void @@ -330,13 +367,12 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *kerx_blob = font->face->table.kerx.get_blob (); - const AAT::kerx& kerx = *kerx_blob->as (); + auto &accel = *font->face->table.kerx; - AAT::hb_aat_apply_context_t c (plan, font, buffer, kerx_blob); + AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table kerx")) return; c.set_ankr_table (font->face->table.ankr.get ()); - kerx.apply (&c); + accel.apply (&c); (void) buffer->message (font, "end table kerx"); } @@ -358,17 +394,6 @@ hb_aat_layout_has_tracking (hb_face_t *face) return face->table.trak->has_data (); } -void -hb_aat_layout_track (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) -{ - const AAT::trak& trak = *font->face->table.trak; - - AAT::hb_aat_apply_context_t c (plan, font, buffer); - trak.apply (&c); -} - /** * hb_aat_layout_get_feature_types: * @face: #hb_face_t to work upon diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.h b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.h index c833ea8f623..88e040d7e2b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.h @@ -40,7 +40,7 @@ HB_BEGIN_DECLS * @HB_AAT_LAYOUT_FEATURE_TYPE_INVALID: Initial, unset feature type * @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC: [All Typographic Features](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type0) * @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES: [Ligatures](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type1) - * @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2) * @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE: [Letter Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type3) * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION: [Vertical Substitution](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type4) * @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: [Linguistic Rearrangement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type5) @@ -88,7 +88,7 @@ typedef enum HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, - HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, + HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION = 2, HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh index 36bb0ef07dd..ee33223651a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.hh @@ -32,6 +32,9 @@ #include "hb-ot-shape.hh" #include "hb-aat-ltag-table.hh" +/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ +#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f + struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; @@ -68,10 +71,5 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL void -hb_aat_layout_track (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); - #endif /* HB_AAT_LAYOUT_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-ltag-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-ltag-table.hh index 17b341ef277..da4dcb1212f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-ltag-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-ltag-table.hh @@ -46,7 +46,9 @@ struct FTStringRange bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (base+tag).sanitize (c, length)); + return_trace (c->check_struct (this) && + hb_barrier () && + (base+tag).sanitize (c, length)); } protected: @@ -73,6 +75,7 @@ struct ltag { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version >= 1 && tagRanges.sanitize (c, this))); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc b/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc index 122f29dc681..e0e9d14d9b8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-map.cc @@ -88,22 +88,23 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) /* Sort features by start/end events. */ hb_vector_t feature_events; + feature_events.alloc_exact (features.length * 2 + 1); for (unsigned int i = 0; i < features.length; i++) { - auto &feature = features[i]; + auto &feature = features.arrayZ[i]; - if (features[i].start == features[i].end) + if (feature.start == feature.end) continue; feature_event_t *event; event = feature_events.push (); - event->index = features[i].start; + event->index = feature.start; event->start = true; event->feature = feature.info; event = feature_events.push (); - event->index = features[i].end; + event->index = feature.end; event->start = false; event->feature = feature.info; } @@ -139,12 +140,12 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) current_features.qsort (); unsigned int j = 0; for (unsigned int i = 1; i < current_features.length; i++) - if (current_features[i].type != current_features[j].type || + if (current_features.arrayZ[i].type != current_features.arrayZ[j].type || /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off * respectively, so we mask out the low-order bit when checking for "duplicates" * (selectors referring to the same feature setting) here. */ - (!current_features[i].is_exclusive && ((current_features[i].setting & ~1) != (current_features[j].setting & ~1)))) - current_features[++j] = current_features[i]; + (!current_features.arrayZ[i].is_exclusive && ((current_features.arrayZ[i].setting & ~1) != (current_features.arrayZ[j].setting & ~1)))) + current_features.arrayZ[++j] = current_features.arrayZ[i]; current_features.shrink (j + 1); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh index b2b7c256739..6e250bfdef0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh @@ -202,8 +202,12 @@ struct BEInt /* Floats. */ /* We want our rounding towards +infinity. */ +static inline double +_hb_roundf (double x) { return floor (x + .5); } + static inline float _hb_roundf (float x) { return floorf (x + .5f); } + #define roundf(x) _hb_roundf(x) @@ -282,7 +286,7 @@ HB_FUNCOBJ (hb_bool); // Compression function for Merkle-Damgard construction. // This function is generated using the framework provided. -#define mix(h) ( \ +#define fasthash_mix(h) ( \ (void) ((h) ^= (h) >> 23), \ (void) ((h) *= 0x2127599bf4325c37ULL), \ (h) ^= (h) >> 47) @@ -306,7 +310,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) #pragma GCC diagnostic ignored "-Wcast-align" v = * (const uint64_t *) (pos++); #pragma GCC diagnostic pop - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } } @@ -316,7 +320,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) while (pos != end) { v = pos++->v; - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } } @@ -332,11 +336,11 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH; case 2: v ^= (uint64_t)pos2[1] << 8; HB_FALLTHROUGH; case 1: v ^= (uint64_t)pos2[0]; - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } - return mix(h); + return fasthash_mix(h); } static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed) @@ -671,7 +675,7 @@ struct hb_pair_t return 0; } - friend void swap (hb_pair_t& a, hb_pair_t& b) + friend void swap (hb_pair_t& a, hb_pair_t& b) noexcept { hb_swap (a.first, b.first); hb_swap (a.second, b.second); @@ -1053,6 +1057,18 @@ _hb_cmp_method (const void *pkey, const void *pval, Ts... ds) return val.cmp (key, ds...); } +template +static int +_hb_cmp_operator (const void *pkey, const void *pval) +{ + const K& key = * (const K*) pkey; + const V& val = * (const V*) pval; + + if (key < val) return -1; + if (key > val) return 1; + return 0; +} + template static inline bool hb_bsearch_impl (unsigned *pos, /* Out */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-array.hh b/src/java.desktop/share/native/libharfbuzz/hb-array.hh index 439f18259cf..d65bbc5c711 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-array.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-array.hh @@ -47,6 +47,8 @@ enum hb_not_found_t template struct hb_array_t : hb_iter_with_fallback_t, Type&> { + static constexpr bool realloc_move = true; + /* * Constructors. */ @@ -249,7 +251,8 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> if (end < start + 2) return; - for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) + unsigned stop = start + (end - start) / 2; + for (unsigned lhs = start, rhs = end - 1; lhs < stop; lhs++, rhs--) hb_swap (arrayZ[rhs], arrayZ[lhs]); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh index 459d82e0f2e..d2de5f693f0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh @@ -118,12 +118,12 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) */ #ifndef _hb_compiler_memory_r_barrier #if defined(__ATOMIC_ACQUIRE) // gcc-like -#define _hb_compiler_memory_r_barrier() asm volatile("": : :"memory") +static inline void _hb_compiler_memory_r_barrier () { asm volatile("": : :"memory"); } #elif !defined(_MSC_VER) #include #define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire) #else -#define _hb_compiler_memory_r_barrier() do {} while (0) +static inline void _hb_compiler_memory_r_barrier () {} #endif #endif @@ -212,11 +212,18 @@ struct hb_atomic_ptr_t T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + operator bool () const { return get_acquire () != nullptr; } T * operator -> () const { return get_acquire (); } template operator C * () const { return get_acquire (); } T *v = nullptr; }; +static inline bool hb_barrier () +{ + _hb_compiler_memory_r_barrier (); + return true; +} + #endif /* HB_ATOMIC_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh index 404a19ce557..9562a9674a5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh @@ -78,6 +78,28 @@ struct hb_vector_size_t hb_vector_size_t operator ~ () const { return process (hb_bitwise_neg); } + operator bool () const + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + if (v[i]) + return true; + return false; + } + operator unsigned int () const + { + unsigned int r = 0; + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + r += hb_popcount (v[i]); + return r; + } + bool operator == (const hb_vector_size_t &o) const + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + if (v[i] != o.v[i]) + return false; + return true; + } + hb_array_t iter () const { return hb_array (v); } @@ -89,6 +111,8 @@ struct hb_vector_size_t struct hb_bit_page_t { + hb_bit_page_t () { init0 (); } + void init0 () { v.init0 (); population = 0; } void init1 () { v.init1 (); population = PAGE_BITS; } @@ -101,10 +125,9 @@ struct hb_bit_page_t bool is_empty () const { if (has_population ()) return !population; - return - + hb_iter (v) - | hb_none - ; + bool empty = !v; + if (empty) population = 0; + return empty; } uint32_t hash () const { @@ -115,6 +138,10 @@ struct hb_bit_page_t void del (hb_codepoint_t g) { elt (g) &= ~mask (g); dirty (); } void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); } bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } + + bool operator [] (hb_codepoint_t g) const { return get (g); } + bool operator () (hb_codepoint_t g) const { return get (g); } void add_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -220,13 +247,17 @@ struct hb_bit_page_t } bool operator == (const hb_bit_page_t &other) const { return is_equal (other); } - bool is_equal (const hb_bit_page_t &other) const + bool is_equal (const hb_bit_page_t &other) const { return v == other.v; } + bool intersects (const hb_bit_page_t &other) const { for (unsigned i = 0; i < len (); i++) - if (v[i] != other.v[i]) - return false; - return true; + if (v[i] & other.v[i]) + return true; + return false; } + bool may_intersect (const hb_bit_page_t &other) const + { return intersects (other); } + bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); } bool is_subset (const hb_bit_page_t &larger_page) const { @@ -241,14 +272,10 @@ struct hb_bit_page_t } bool has_population () const { return population != UINT_MAX; } - unsigned int get_population () const + unsigned get_population () const { if (has_population ()) return population; - population = - + hb_iter (v) - | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u) - ; - return population; + return population = v; } bool next (hb_codepoint_t *codepoint) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh index 2e335549e26..740a2437671 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh @@ -39,10 +39,10 @@ struct hb_bit_set_invertible_t hb_bit_set_invertible_t () = default; hb_bit_set_invertible_t (const hb_bit_set_invertible_t& o) = default; - hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) : hb_bit_set_invertible_t () { hb_swap (*this, other); } + hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) noexcept : hb_bit_set_invertible_t () { hb_swap (*this, other); } hb_bit_set_invertible_t& operator= (const hb_bit_set_invertible_t& o) = default; - hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) { hb_swap (*this, other); return *this; } - friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) + hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) noexcept { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) noexcept { if (likely (!a.s.successful || !b.s.successful)) return; @@ -126,6 +126,7 @@ struct hb_bit_set_invertible_t { unlikely (inverted) ? (void) s.add_range (a, b) : s.del_range (a, b); } bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -139,6 +140,9 @@ struct hb_bit_set_invertible_t hb_bit_set_invertible_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool may_intersect (const hb_bit_set_invertible_t &other) const + { return inverted || other.inverted || s.intersects (other.s); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { hb_codepoint_t c = first - 1; @@ -359,8 +363,8 @@ struct hb_bit_set_invertible_t typedef hb_codepoint_t __item_t__; hb_codepoint_t __item__ () const { return v; } bool __more__ () const { return v != INVALID; } - void __next__ () { s->next (&v); if (l) l--; } - void __prev__ () { s->previous (&v); } + void __next__ () { s->next (&v); if (likely (l)) l--; } + void __prev__ () { s->previous (&v); l++; } unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh index b900711a33a..c42e617f67a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh @@ -38,10 +38,10 @@ struct hb_bit_set_t ~hb_bit_set_t () = default; hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other, true); } - hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); } + hb_bit_set_t ( hb_bit_set_t&& other) noexcept : hb_bit_set_t () { hb_swap (*this, other); } hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; } - hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; } - friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) + hb_bit_set_t& operator= (hb_bit_set_t&& other) noexcept { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) noexcept { if (likely (!a.successful || !b.successful)) return; @@ -88,10 +88,11 @@ struct hb_bit_set_t { if (unlikely (!successful)) return false; - if (pages.length == 0 && count == 1) + if (pages.length < count && count <= 2) exact_size = true; // Most sets are small and local - if (unlikely (!pages.resize (count, clear, exact_size) || !page_map.resize (count, clear, exact_size))) + if (unlikely (!pages.resize (count, clear, exact_size) || + !page_map.resize (count, clear))) { pages.resize (page_map.length, clear, exact_size); successful = false; @@ -297,9 +298,9 @@ struct hb_bit_set_t unsigned int write_index = 0; for (unsigned int i = 0; i < page_map.length; i++) { - int m = (int) page_map[i].major; + int m = (int) page_map.arrayZ[i].major; if (m < ds || de < m) - page_map[write_index++] = page_map[i]; + page_map.arrayZ[write_index++] = page_map.arrayZ[i]; } compact (compact_workspace, write_index); resize (write_index); @@ -345,6 +346,7 @@ struct hb_bit_set_t return false; return page->get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -358,6 +360,31 @@ struct hb_bit_set_t hb_bit_set_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool intersects (const hb_bit_set_t &other) const + { + unsigned int na = pages.length; + unsigned int nb = other.pages.length; + + unsigned int a = 0, b = 0; + for (; a < na && b < nb; ) + { + if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major) + { + if (page_at (a).intersects (other.page_at (b))) + return true; + a++; + b++; + } + else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major) + a++; + else + b++; + } + return false; + } + bool may_intersect (const hb_bit_set_t &other) const + { return intersects (other); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { hb_codepoint_t c = first - 1; @@ -389,7 +416,7 @@ struct hb_bit_set_t { if (page_at (a).is_empty ()) { a++; continue; } if (other.page_at (b).is_empty ()) { b++; continue; } - if (page_map[a].major != other.page_map[b].major || + if (page_map.arrayZ[a].major != other.page_map.arrayZ[b].major || !page_at (a).is_equal (other.page_at (b))) return false; a++; @@ -412,8 +439,8 @@ struct hb_bit_set_t uint32_t spi = 0; for (uint32_t lpi = 0; spi < page_map.length && lpi < larger_set.page_map.length; lpi++) { - uint32_t spm = page_map[spi].major; - uint32_t lpm = larger_set.page_map[lpi].major; + uint32_t spm = page_map.arrayZ[spi].major; + uint32_t lpm = larger_set.page_map.arrayZ[lpi].major; auto sp = page_at (spi); if (spm < lpm && !sp.is_empty ()) @@ -503,7 +530,7 @@ struct hb_bit_set_t for (; a < na && b < nb; ) { - if (page_map[a].major == other.page_map[b].major) + if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major) { if (!passthru_left) { @@ -512,7 +539,7 @@ struct hb_bit_set_t // passthru_left is set since no left side pages will be removed // in that case. if (write_index < a) - page_map[write_index] = page_map[a]; + page_map.arrayZ[write_index] = page_map.arrayZ[a]; write_index++; } @@ -520,7 +547,7 @@ struct hb_bit_set_t a++; b++; } - else if (page_map[a].major < other.page_map[b].major) + else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major) { if (passthru_left) count++; @@ -765,8 +792,8 @@ struct hb_bit_set_t unsigned int initial_size = size; for (unsigned int i = start_page; i < page_map.length && size; i++) { - uint32_t base = major_start (page_map[i].major); - unsigned int n = pages[page_map[i].index].write (base, start_page_value, out, size); + uint32_t base = major_start (page_map.arrayZ[i].major); + unsigned int n = pages[page_map.arrayZ[i].index].write (base, start_page_value, out, size); out += n; size -= n; start_page_value = 0; @@ -814,8 +841,8 @@ struct hb_bit_set_t hb_codepoint_t next_value = codepoint + 1; for (unsigned int i=start_page; i= 0; i--) { - const auto& map = page_map[(unsigned) i]; - const auto& page = pages[map.index]; + const auto& map = page_map.arrayZ[(unsigned) i]; + const auto& page = pages.arrayZ[map.index]; if (!page.is_empty ()) return map.major * page_t::PAGE_BITS + page.get_max (); @@ -961,7 +988,7 @@ struct hb_bit_set_t return nullptr; last_page_lookup = i; - return &pages.arrayZ[page_map[i].index]; + return &pages.arrayZ[page_map.arrayZ[i].index]; } page_t &page_at (unsigned int i) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-blob.cc b/src/java.desktop/share/native/libharfbuzz/hb-blob.cc index 2a43afa1a43..a19599fac09 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-blob.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-blob.cc @@ -598,6 +598,11 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file) * Creates a new blob containing the data from the * specified binary font file. * + * The filename is passed directly to the system on all platforms, + * except on Windows, where the filename is interpreted as UTF-8. + * Only if the filename is not valid UTF-8, it will be interpreted + * according to the system codepage. + * * Returns: An #hb_blob_t pointer with the content of the file, * or hb_blob_get_empty() if failed. * @@ -612,10 +617,14 @@ hb_blob_create_from_file (const char *file_name) /** * hb_blob_create_from_file_or_fail: - * @file_name: A font filename + * @file_name: A filename * - * Creates a new blob containing the data from the - * specified binary font file. + * Creates a new blob containing the data from the specified file. + * + * The filename is passed directly to the system on all platforms, + * except on Windows, where the filename is interpreted as UTF-8. + * Only if the filename is not valid UTF-8, it will be interpreted + * according to the system codepage. * * Returns: An #hb_blob_t pointer with the content of the file, * or `NULL` if failed. @@ -672,10 +681,19 @@ hb_blob_create_from_file_or_fail (const char *file_name) if (unlikely (!file)) return nullptr; HANDLE fd; + int conversion; unsigned int size = strlen (file_name) + 1; wchar_t * wchar_file_name = (wchar_t *) hb_malloc (sizeof (wchar_t) * size); if (unlikely (!wchar_file_name)) goto fail_without_close; - mbstowcs (wchar_file_name, file_name, size); + + /* Assume file name is given in UTF-8 encoding */ + conversion = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, file_name, -1, wchar_file_name, size); + if (conversion <= 0) + { + /* Conversion failed due to invalid UTF-8 characters, + Repeat conversion based on system code page */ + mbstowcs(wchar_file_name, file_name, size); + } #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) { CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh index 2a90cbfe3ea..69cc1640230 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh @@ -34,36 +34,36 @@ #line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 0u, 0u, 9u, 123u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, + 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 123u, 0u, 0u, 0 + 9u, 93u, 9u, 123u, 0u, 0u, 0 }; static const char _deserialize_json_key_spans[] = { - 0, 115, 26, 21, 2, 1, 50, 49, - 10, 117, 117, 85, 117, 1, 50, 49, + 0, 115, 115, 26, 21, 2, 1, 50, + 49, 10, 117, 117, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 2, 1, 50, 49, 10, 117, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 1, 50, 49, 59, 117, 59, 117, 117, 1, 50, 49, 117, - 115, 0 + 85, 115, 0 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 143, 165, 168, 170, 221, - 271, 282, 400, 518, 604, 722, 724, 775, - 825, 836, 954, 1072, 1074, 1076, 1127, 1177, - 1295, 1413, 1416, 1418, 1469, 1519, 1530, 1648, - 1766, 1768, 1819, 1869, 1880, 1998, 2116, 2118, - 2120, 2171, 2221, 2339, 2457, 2459, 2510, 2560, - 2620, 2738, 2798, 2916, 3034, 3036, 3087, 3137, - 3255, 3371 + 0, 0, 116, 232, 259, 281, 284, 286, + 337, 387, 398, 516, 634, 752, 754, 805, + 855, 866, 984, 1102, 1104, 1106, 1157, 1207, + 1325, 1443, 1446, 1448, 1499, 1549, 1560, 1678, + 1796, 1798, 1849, 1899, 1910, 2028, 2146, 2148, + 2150, 2201, 2251, 2369, 2487, 2489, 2540, 2590, + 2650, 2768, 2828, 2946, 3064, 3066, 3117, 3167, + 3285, 3371, 3487 }; static const char _deserialize_json_indicies[] = { @@ -77,51 +77,51 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 10, 1, 11, 12, - 1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 14, 1, 14, 14, - 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 15, 1, 1, 16, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 1, - 18, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 1, 20, 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 20, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 21, 1, + 1, 1, 1, 1, 1, 1, 1, 3, + 1, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 5, 1, 6, 1, 7, 8, + 1, 9, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 1, 12, 13, 1, 14, 1, 14, + 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 15, 1, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 22, - 1, 23, 23, 23, 23, 23, 1, 1, + 1, 15, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 16, 1, + 1, 17, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 1, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 1, 21, + 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 23, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -131,94 +131,99 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 24, 1, 25, - 25, 25, 25, 25, 1, 1, 1, 1, + 1, 1, 1, 23, 1, 24, 24, 24, + 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 25, 1, + 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 26, 1, 1, 1, 1, 1, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 27, 1, 20, 20, 20, - 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 21, 1, 1, 1, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 25, 1, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 21, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 22, 1, + 1, 1, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 22, 1, 28, 1, 28, 28, 28, - 28, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 29, 1, - 29, 29, 29, 29, 29, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 23, + 1, 26, 1, 26, 26, 26, 26, 26, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 30, 1, 1, 31, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 1, 33, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 1, 35, 35, 35, - 35, 35, 1, 1, 1, 1, 1, 1, + 1, 1, 26, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 35, 1, 1, 1, + 1, 1, 1, 1, 27, 1, 27, 27, + 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 36, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 28, 1, 1, 29, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 1, + 31, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 37, 1, 35, 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 35, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 36, 1, - 1, 1, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 35, + 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 33, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 34, 1, 1, 1, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 37, - 1, 38, 1, 39, 1, 39, 39, 39, - 39, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 40, 1, - 40, 40, 40, 40, 40, 1, 1, 1, + 1, 1, 1, 1, 1, 35, 1, 36, + 1, 37, 1, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 40, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 37, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 38, 1, 38, 38, + 38, 38, 38, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 38, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 39, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 1, + 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 41, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 1, 43, 43, 43, 43, 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 43, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -227,15 +232,14 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 43, 1, 41, 41, + 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 45, 1, - 43, 43, 43, 43, 43, 1, 1, 1, + 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 43, + 1, 42, 1, 1, 1, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 44, 1, 1, 1, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -243,26 +247,26 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 45, 1, 47, 48, - 1, 49, 1, 49, 49, 49, 49, 49, + 1, 1, 43, 1, 45, 46, 1, 47, + 1, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 49, 1, 1, 1, 1, 1, + 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 50, 50, - 50, 50, 50, 1, 1, 1, 1, 1, + 1, 1, 48, 1, 48, 48, 48, 48, + 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 50, 1, 1, + 1, 1, 1, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 51, 1, 1, 52, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 1, - 54, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 56, 56, 56, 56, 56, + 49, 1, 1, 50, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 1, 52, 53, + 53, 53, 53, 53, 53, 53, 53, 53, + 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 56, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, + 54, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -272,14 +276,13 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 58, - 1, 56, 56, 56, 56, 56, 1, 1, + 1, 1, 1, 1, 1, 56, 1, 54, + 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 56, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 57, 1, 1, 1, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 1, 1, 1, 1, 1, + 1, 1, 55, 1, 1, 1, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -287,119 +290,120 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 58, 1, 59, - 1, 59, 59, 59, 59, 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 56, 1, 57, 1, 57, + 57, 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 59, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 57, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 58, 1, 58, 58, 58, 58, 58, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 58, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 59, 1, + 1, 60, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 1, 62, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 1, 64, + 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 60, 1, 60, 60, 60, 60, - 60, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 61, 1, 1, 62, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 1, 64, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 1, 66, 66, 66, 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 66, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 66, 1, 64, 64, 64, + 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 65, 1, 1, 1, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 68, 1, 66, - 66, 66, 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 67, 1, 1, 1, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 66, 1, 67, 1, 68, 1, 68, + 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 68, 1, 69, 1, 70, - 1, 70, 70, 70, 70, 70, 1, 1, + 69, 1, 69, 69, 69, 69, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 70, 1, 1, 1, 1, 1, 1, 1, + 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 70, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 1, 72, 72, 72, 72, + 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 71, 1, 71, 71, 71, 71, - 71, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 72, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 72, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 1, 74, 74, - 74, 74, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 74, 1, 72, 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 72, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 73, 1, 1, + 1, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 76, 1, 74, 74, 74, 74, - 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 74, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 75, - 1, 1, 1, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 74, 1, + 76, 1, 76, 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 76, 1, 78, 1, 78, 78, 78, 78, - 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 78, 1, 1, 1, 1, + 1, 1, 1, 77, 1, 77, 77, 77, + 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 77, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 79, 1, 79, - 79, 79, 79, 79, 1, 1, 1, 1, + 1, 1, 1, 1, 79, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 1, 82, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 83, 81, 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 79, 1, - 80, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 81, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 1, 84, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 85, 83, 86, 86, 86, - 86, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 86, 1, 1, 1, + 1, 1, 84, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -408,20 +412,21 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 86, + 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 88, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 81, 1, 87, 87, 87, + 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 83, 1, 89, - 89, 89, 89, 89, 1, 1, 1, 1, + 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 89, 1, + 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -430,97 +435,107 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 89, 1, 87, 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 91, 1, 89, 89, 89, - 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 89, 1, 1, 1, + 1, 1, 87, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 88, 1, + 1, 1, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 90, 1, 1, 1, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 89, + 1, 91, 1, 91, 91, 91, 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 91, 1, 93, 1, 93, 93, 93, - 93, 93, 1, 1, 1, 1, 1, 1, + 1, 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 93, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 92, 1, 92, 92, + 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 94, 1, - 94, 94, 94, 94, 94, 1, 1, 1, + 1, 1, 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 94, + 1, 1, 1, 1, 1, 93, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 1, + 87, 87, 87, 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 95, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 1, 89, 89, 89, 89, 89, 1, + 1, 1, 1, 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 88, 1, 1, 1, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 89, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 90, 1, 1, - 1, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 89, 1, 96, 96, + 96, 96, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 91, 1, - 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, + 1, 97, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 98, 1, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 1, 1, 0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 1, + 1, 0 }; static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 2, 3, 4, 19, 25, - 38, 44, 52, 5, 13, 6, 7, 8, - 9, 12, 9, 12, 10, 2, 11, 10, - 11, 11, 56, 57, 14, 15, 16, 17, - 18, 17, 18, 10, 2, 11, 20, 21, - 22, 23, 24, 10, 2, 11, 24, 26, - 32, 27, 28, 29, 30, 31, 30, 31, - 10, 2, 11, 33, 34, 35, 36, 37, - 36, 37, 10, 2, 11, 39, 40, 41, - 42, 43, 10, 2, 11, 43, 45, 46, - 47, 50, 51, 47, 48, 49, 10, 2, - 11, 10, 2, 11, 51, 53, 54, 50, - 55, 55 + 1, 0, 2, 3, 3, 4, 5, 19, + 25, 38, 44, 52, 6, 13, 7, 8, + 9, 10, 12, 10, 12, 11, 3, 56, + 11, 56, 14, 15, 16, 17, 18, 17, + 18, 11, 3, 56, 20, 21, 22, 23, + 24, 11, 3, 56, 24, 26, 32, 27, + 28, 29, 30, 31, 30, 31, 11, 3, + 56, 33, 34, 35, 36, 37, 36, 37, + 11, 3, 56, 39, 40, 41, 42, 43, + 11, 3, 56, 43, 45, 46, 47, 50, + 51, 47, 48, 49, 11, 3, 56, 11, + 3, 56, 51, 53, 54, 50, 55, 55, + 56, 57, 58 }; static const char _deserialize_json_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 2, 2, 0, 0, 3, 3, 4, 0, - 5, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 6, 6, 7, 0, 0, - 0, 2, 2, 8, 8, 9, 0, 0, - 0, 0, 0, 2, 2, 2, 0, 0, - 10, 10, 11, 0, 0, 2, 2, 2, - 0, 0, 12, 12, 13, 0, 0, 0, - 2, 2, 14, 14, 15, 0, 0, 0, - 2, 16, 16, 0, 17, 0, 18, 18, - 19, 20, 20, 21, 17, 0, 0, 22, - 22, 23 + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 0, 0, 3, 3, 4, + 0, 5, 0, 0, 2, 2, 2, 0, + 0, 6, 6, 7, 0, 0, 0, 2, + 2, 8, 8, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 10, 10, + 11, 0, 0, 2, 2, 2, 0, 0, + 12, 12, 13, 0, 0, 0, 2, 2, + 14, 14, 15, 0, 0, 0, 2, 16, + 16, 0, 17, 0, 18, 18, 19, 20, + 20, 21, 17, 0, 0, 22, 22, 23, + 0, 0, 0 }; static const int deserialize_json_start = 1; @@ -545,22 +560,17 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - *end_ptr = ++p; - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 559 "hb-buffer-deserialize-json.hh" +#line 569 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 564 "hb-buffer-deserialize-json.hh" +#line 574 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -772,7 +782,7 @@ _resume: *end_ptr = p; } break; -#line 776 "hb-buffer-deserialize-json.hh" +#line 786 "hb-buffer-deserialize-json.hh" } _again: @@ -784,7 +794,7 @@ _again: _out: {} } -#line 137 "hb-buffer-deserialize-json.rl" +#line 132 "hb-buffer-deserialize-json.rl" *end_ptr = p; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc index 3bdea30ed36..3a4c9c9f317 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc @@ -149,7 +149,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, } assert (text_start < text_end); - if (0) + if (false) printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); hb_buffer_clear_contents (fragment); @@ -288,7 +288,7 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, } assert (text_start < text_end); - if (0) + if (false) printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); #if 0 @@ -412,7 +412,7 @@ hb_buffer_t::verify (hb_buffer_t *text_buffer, &len, HB_BUFFER_SERIALIZE_FORMAT_TEXT, HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS); - buffer_verify_error (this, font, BUFFER_VERIFY_ERROR "text was: %s.", bytes.arrayZ); + buffer_verify_error (this, font, BUFFER_VERIFY_ERROR "text was: %s.", bytes.arrayZ ? bytes.arrayZ : ""); } #endif } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc index 5f9329e07ed..72970c9c2f7 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc @@ -271,6 +271,7 @@ hb_buffer_t::similar (const hb_buffer_t &src) replacement = src.replacement; invisible = src.invisible; not_found = src.not_found; + not_found_variation_selector = src.not_found_variation_selector; } void @@ -283,6 +284,7 @@ hb_buffer_t::reset () replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; invisible = 0; not_found = 0; + not_found_variation_selector = HB_CODEPOINT_INVALID; clear (); } @@ -309,6 +311,7 @@ hb_buffer_t::clear () deallocate_var_all (); serial = 0; + random_state = 1; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; } @@ -704,6 +707,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, 0, /* invisible */ 0, /* not_found */ + HB_CODEPOINT_INVALID, /* not_found_variation_selector */ HB_BUFFER_CONTENT_TYPE_INVALID, @@ -1359,6 +1363,89 @@ hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer) return buffer->not_found; } +/** + * hb_buffer_set_not_found_variation_selector_glyph: + * @buffer: An #hb_buffer_t + * @not_found_variation_selector: the not-found-variation-selector #hb_codepoint_t + * + * Sets the #hb_codepoint_t that replaces variation-selector characters not resolved + * in the font during shaping. + * + * The not-found-variation-selector glyph defaults to #HB_CODEPOINT_INVALID, + * in which case an unresolved variation-selector will be removed from the glyph + * string during shaping. This API allows for changing that and retaining a glyph, + * such that the situation can be detected by the client and handled accordingly + * (e.g. by using a different font). + * + * Since: 10.0.0 + **/ +void +hb_buffer_set_not_found_variation_selector_glyph (hb_buffer_t *buffer, + hb_codepoint_t not_found_variation_selector) +{ + buffer->not_found_variation_selector = not_found_variation_selector; +} + +/** + * hb_buffer_get_not_found_variation_selector_glyph: + * @buffer: An #hb_buffer_t + * + * See hb_buffer_set_not_found_variation_selector_glyph(). + * + * Return value: + * The @buffer not-found-variation-selector #hb_codepoint_t + * + * Since: 10.0.0 + **/ +hb_codepoint_t +hb_buffer_get_not_found_variation_selector_glyph (const hb_buffer_t *buffer) +{ + return buffer->not_found_variation_selector; +} + +/** + * hb_buffer_set_random_state: + * @buffer: An #hb_buffer_t + * @state: the new random state + * + * Sets the random state of the buffer. The state changes + * every time a glyph uses randomness (eg. the `rand` + * OpenType feature). This function together with + * hb_buffer_get_random_state() allow for transferring + * the current random state to a subsequent buffer, to + * get better randomness distribution. + * + * Defaults to 1 and when buffer contents are cleared. + * A value of 0 disables randomness during shaping. + * + * Since: 8.4.0 + **/ +void +hb_buffer_set_random_state (hb_buffer_t *buffer, + unsigned state) +{ + if (unlikely (hb_object_is_immutable (buffer))) + return; + + buffer->random_state = state; +} + +/** + * hb_buffer_get_random_state: + * @buffer: An #hb_buffer_t + * + * See hb_buffer_set_random_state(). + * + * Return value: + * The @buffer random state + * + * Since: 8.4.0 + **/ +unsigned +hb_buffer_get_random_state (const hb_buffer_t *buffer) +{ + return buffer->random_state; +} /** * hb_buffer_clear_contents: @@ -1896,7 +1983,7 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * @source: source #hb_buffer_t * @start: start index into source buffer to copy. Use 0 to copy from start of buffer. - * @end: end index into source buffer to copy. Use @HB_FEATURE_GLOBAL_END to copy to end of buffer. + * @end: end index into source buffer to copy. Use @UINT_MAX (or ((unsigned int) -1)) to copy to end of buffer. * * Append (part of) contents of another buffer to this buffer. * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.h b/src/java.desktop/share/native/libharfbuzz/hb-buffer.h index 6fc215d1627..d2258634ff4 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.h @@ -487,6 +487,19 @@ hb_buffer_set_not_found_glyph (hb_buffer_t *buffer, HB_EXTERN hb_codepoint_t hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer); +HB_EXTERN void +hb_buffer_set_not_found_variation_selector_glyph (hb_buffer_t *buffer, + hb_codepoint_t not_found_variation_selector); + +HB_EXTERN hb_codepoint_t +hb_buffer_get_not_found_variation_selector_glyph (const hb_buffer_t *buffer); + +HB_EXTERN void +hb_buffer_set_random_state (hb_buffer_t *buffer, + unsigned state); + +HB_EXTERN unsigned +hb_buffer_get_random_state (const hb_buffer_t *buffer); /* * Content API. diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh index 7f8ce14e90d..c92e7df320e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh @@ -32,7 +32,6 @@ #include "hb.hh" #include "hb-unicode.hh" -#include "hb-set-digest.hh" static_assert ((sizeof (hb_glyph_info_t) == 20), ""); @@ -52,6 +51,7 @@ enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u, HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u, HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u, + HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000080u, /* Reserved for shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u, @@ -80,6 +80,7 @@ struct hb_buffer_t hb_codepoint_t replacement; /* U+FFFD or something else. */ hb_codepoint_t invisible; /* 0 or something else. */ hb_codepoint_t not_found; /* 0 or something else. */ + hb_codepoint_t not_found_variation_selector; /* HB_CODEPOINT_INVALID or something else. */ /* * Buffer contents @@ -116,6 +117,7 @@ struct hb_buffer_t uint8_t allocated_var_bits; uint8_t serial; + uint32_t random_state; hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ int max_ops; /* Maximum allowed operations. */ @@ -179,22 +181,24 @@ struct hb_buffer_t allocated_var_bits = 0; } + HB_ALWAYS_INLINE hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } + HB_ALWAYS_INLINE hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } - hb_set_digest_t digest () const - { - hb_set_digest_t d; - d.init (); - d.add_array (&info[0].codepoint, len, sizeof (info[0])); - return d; - } + template + void collect_codepoints (set_t &d) const + { d.clear (); d.add_array (&info[0].codepoint, len, sizeof (info[0])); } HB_INTERNAL void similar (const hb_buffer_t &src); HB_INTERNAL void reset (); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh index 8d9ff5faf6d..79d7c4c7133 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh @@ -522,7 +522,7 @@ struct parsed_values_t void alloc (unsigned n) { - values.alloc (n, true); + values.alloc_exact (n); } void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t (), const VAL &v = VAL ()) @@ -624,7 +624,6 @@ struct opset_t } else { /* invalid unknown operator */ env.clear_args (); - env.set_error (); } break; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh index 0c0cec9986a..6a227e5e81e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-dict-common.hh @@ -54,8 +54,8 @@ struct top_dict_values_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int charStringsOffset; - unsigned int FDArrayOffset; + int charStringsOffset; + int FDArrayOffset; }; struct dict_opset_t : opset_t @@ -84,7 +84,7 @@ struct dict_opset_t : opset_t enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END }; - char buf[32]; + char buf[32] = {0}; unsigned char byte = 0; for (unsigned i = 0, count = 0; count < ARRAY_LENGTH (buf); ++i, ++count) { @@ -157,11 +157,11 @@ struct top_dict_opset_t : dict_opset_t { switch (op) { case OpCode_CharStrings: - dictval.charStringsOffset = env.argStack.pop_uint (); + dictval.charStringsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDArray: - dictval.FDArrayOffset = env.argStack.pop_uint (); + dictval.FDArrayOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FontMatrix: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh index c970633e064..ab17d68318b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cff2-interp-cs.hh @@ -76,16 +76,12 @@ struct cff2_cs_interp_env_t : cs_interp_env_t coords = coords_; num_coords = num_coords_; varStore = acc.varStore; - seen_blend = false; - seen_vsindex_ = false; - scalars.init (); do_blend = num_coords && coords && varStore->size; set_ivs (acc.privateDicts[fd].ivs); } void fini () { - scalars.fini (); SUPER::fini (); } @@ -168,13 +164,13 @@ struct cff2_cs_interp_env_t : cs_interp_env_t protected: const int *coords; unsigned int num_coords; - const CFF2VariationStore *varStore; + const CFF2ItemVariationStore *varStore; unsigned int region_count; unsigned int ivs; hb_vector_t scalars; bool do_blend; - bool seen_vsindex_; - bool seen_blend; + bool seen_vsindex_ = false; + bool seen_blend = false; typedef cs_interp_env_t SUPER; }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.cc b/src/java.desktop/share/native/libharfbuzz/hb-common.cc index 3afab4284e6..bce0d09d20a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-common.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-common.cc @@ -625,6 +625,9 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-14.0 additions */ case HB_SCRIPT_OLD_UYGHUR: + /* Unicode-16.0 additions */ + case HB_SCRIPT_GARAY: + return HB_DIRECTION_RTL; @@ -996,7 +999,7 @@ hb_feature_to_string (hb_feature_t *feature, if (feature->value > 1) { s[len++] = '='; - len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%" PRIu32, feature->value)); } assert (len < ARRAY_LENGTH (s)); len = hb_min (len, size - 1); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.h b/src/java.desktop/share/native/libharfbuzz/hb-common.h index 0d7956764cf..a8bae366f7e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-common.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-common.h @@ -47,14 +47,10 @@ # endif /* !__cplusplus */ #endif -#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \ - defined (_sgi) || defined (__sun) || defined (sun) || \ - defined (__digital__) || defined (__HP_cc) -# include -#elif defined (_AIX) +#if defined (_AIX) # include #elif defined (_MSC_VER) && _MSC_VER < 1600 -/* VS 2010 (_MSC_VER 1600) has stdint.h */ +/* VS 2010 (_MSC_VER 1600) has stdint.h */ typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; @@ -63,10 +59,11 @@ typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; -#elif defined (__KERNEL__) -# include -#else +#elif defined (_MSC_VER) && _MSC_VER < 1800 +/* VS 2013 (_MSC_VER 1800) has inttypes.h */ # include +#else +# include #endif #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) @@ -507,6 +504,13 @@ hb_language_matches (hb_language_t language, * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0 * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0 * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0 + * @HB_SCRIPT_GARAY: `Gara`, Since: 10.0.0 + * @HB_SCRIPT_GURUNG_KHEMA: `Gukh`, Since: 10.0.0 + * @HB_SCRIPT_KIRAT_RAI: `Krai`, Since: 10.0.0 + * @HB_SCRIPT_OL_ONAL: `Onao`, Since: 10.0.0 + * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 + * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 + * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 * @HB_SCRIPT_INVALID: No script set * * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding @@ -734,6 +738,17 @@ typedef enum HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/ HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.0*/ + /* + * Since 10.0.0 + */ + HB_SCRIPT_GARAY = HB_TAG ('G','a','r','a'), /*16.0*/ + HB_SCRIPT_GURUNG_KHEMA = HB_TAG ('G','u','k','h'), /*16.0*/ + HB_SCRIPT_KIRAT_RAI = HB_TAG ('K','r','a','i'), /*16.0*/ + HB_SCRIPT_OL_ONAL = HB_TAG ('O','n','a','o'), /*16.0*/ + HB_SCRIPT_SUNUWAR = HB_TAG ('S','u','n','u'), /*16.0*/ + HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ + HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-config.hh b/src/java.desktop/share/native/libharfbuzz/hb-config.hh index 816c55c7d36..40cc2403c18 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-config.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-config.hh @@ -56,7 +56,6 @@ #ifdef HB_LEAN #define HB_DISABLE_DEPRECATED -#define HB_NDEBUG #define HB_NO_ATEXIT #define HB_NO_BUFFER_MESSAGE #define HB_NO_BUFFER_SERIALIZE @@ -69,8 +68,6 @@ #define HB_NO_FACE_COLLECT_UNICODES #define HB_NO_GETENV #define HB_NO_HINTING -#define HB_NO_LANGUAGE_LONG -#define HB_NO_LANGUAGE_PRIVATE_SUBTAG #define HB_NO_LAYOUT_FEATURE_PARAMS #define HB_NO_LAYOUT_COLLECT_GLYPHS #define HB_NO_LAYOUT_RARELY_USED @@ -118,6 +115,10 @@ #define HB_NO_VAR_COMPOSITES #endif +#ifdef HB_NO_VAR +#define HB_NO_VAR_COMPOSITES +#endif + #ifdef HB_DISABLE_DEPRECATED #define HB_IF_NOT_DEPRECATED(x) #else @@ -156,6 +157,7 @@ #define HB_NO_FALLBACK_SHAPE #define HB_NO_OT_KERN #define HB_NO_OT_LAYOUT_BLOCKLIST +#define HB_NO_AAT_LAYOUT_BLOCKLIST #define HB_NO_OT_SHAPE_FALLBACK #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh b/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh index eac4ff03ed5..82d39741527 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-cplusplus.hh @@ -27,9 +27,6 @@ #include "hb.h" -HB_BEGIN_DECLS -HB_END_DECLS - #ifdef __cplusplus #include @@ -56,15 +53,15 @@ struct shared_ptr explicit shared_ptr (T *p = nullptr) : p (p) {} shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {} - shared_ptr (shared_ptr &&o) : p (o.p) { o.p = nullptr; } + shared_ptr (shared_ptr &&o) noexcept : p (o.p) { o.p = nullptr; } shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; } - shared_ptr& operator = (shared_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; } + shared_ptr& operator = (shared_ptr &&o) noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; } ~shared_ptr () { v::destroy (p); p = nullptr; } T* get() const { return p; } - void swap (shared_ptr &o) { std::swap (p, o.p); } - friend void swap (shared_ptr &a, shared_ptr &b) { std::swap (a.p, b.p); } + void swap (shared_ptr &o) noexcept { std::swap (p, o.p); } + friend void swap (shared_ptr &a, shared_ptr &b) noexcept { std::swap (a.p, b.p); } operator T * () const { return p; } T& operator * () const { return *get (); } @@ -98,16 +95,16 @@ struct unique_ptr explicit unique_ptr (T *p = nullptr) : p (p) {} unique_ptr (const unique_ptr &o) = delete; - unique_ptr (unique_ptr &&o) : p (o.p) { o.p = nullptr; } + unique_ptr (unique_ptr &&o) noexcept : p (o.p) { o.p = nullptr; } unique_ptr& operator = (const unique_ptr &o) = delete; - unique_ptr& operator = (unique_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; } + unique_ptr& operator = (unique_ptr &&o) noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; } ~unique_ptr () { v::destroy (p); p = nullptr; } T* get() const { return p; } T* release () { T* v = p; p = nullptr; return v; } - void swap (unique_ptr &o) { std::swap (p, o.p); } - friend void swap (unique_ptr &a, unique_ptr &b) { std::swap (a.p, b.p); } + void swap (unique_ptr &o) noexcept { std::swap (p, o.p); } + friend void swap (unique_ptr &a, unique_ptr &b) noexcept { std::swap (a.p, b.p); } operator T * () const { return p; } T& operator * () const { return *get (); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-decycler.hh b/src/java.desktop/share/native/libharfbuzz/hb-decycler.hh new file mode 100644 index 00000000000..95b961027bf --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-decycler.hh @@ -0,0 +1,164 @@ +/* + * Copyright © 2025 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_DECYCLER_HH +#define HB_DECYCLER_HH + +#include "hb.hh" + +/* + * hb_decycler_t is an efficient cycle detector for graph traversal. + * It's a simple tortoise-and-hare algorithm with a twist: it's + * designed to detect cycles while traversing a graph in a DFS manner, + * instead of just a linked list. + * + * For Floyd's tortoise and hare algorithm, see: + * https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare + * + * hb_decycler_t is O(n) in the number of nodes in the DFS traversal + * if there are no cycles. Unlike Floyd's algorithm, hb_decycler_t + * can be used in a DFS traversal, where the graph is not a simple + * linked list, but a tree with possible cycles. Like Floyd's algorithm, + * it is constant-memory (~three pointers). + * + * The decycler works by creating an implicit linked-list on the stack, + * of the path from the root to the current node, and apply Floyd's + * algorithm on that list as it goes. + * + * The decycler is malloc-free, and as such, much faster to use than a + * hb_set_t or hb_map_t equivalent. + * + * The decycler detects cycles in the graph *eventually*, not *immediately*. + * That is, it may not detect a cycle until the cycle is fully traversed, + * even multiple times. See Floyd's algorithm analysis for details. + * + * The implementation saves a pointer storage on the stack by combining + * this->u.decycler and this->u.next into a union. This is possible because + * at any point we only need one of those values. The invariant is that + * after construction, and before destruction, of a node, the u.decycler + * field is always valid. The u.next field is only valid when the node is + * in the traversal path, parent to another node. + * + * There are three method's: + * + * - hb_decycler_node_t() constructor: Creates a new node in the traversal. + * The constructor takes a reference to the decycler object and inserts + * itself as the latest node in the traversal path, by advancing the hare + * pointer, and for every other descent, advancing the tortoise pointer. + * + * - ~hb_decycler_node_t() destructor: Restores the decycler object to its + * previous state by removing the node from the traversal path. + * + * - bool visit(uintptr_t value): Called on every node in the graph. Returns + * true if the node is not part of a cycle, and false if it is. The value + * parameter is used to detect cycles. It's the caller's responsibility + * to ensure that the value is unique for each node in the graph. + * The cycle detection is as simple as comparing the value to the value + * held by the tortoise pointer, which is the Floyd's algorithm. + * + * For usage examples see test-decycler.cc. + */ + +struct hb_decycler_node_t; + +struct hb_decycler_t +{ + friend struct hb_decycler_node_t; + + private: + bool tortoise_awake = false; + hb_decycler_node_t *tortoise = nullptr; + hb_decycler_node_t *hare = nullptr; +}; + +struct hb_decycler_node_t +{ + hb_decycler_node_t (hb_decycler_t &decycler) + { + u.decycler = &decycler; + + decycler.tortoise_awake = !decycler.tortoise_awake; + + if (!decycler.tortoise) + { + // First node. + assert (decycler.tortoise_awake); + assert (!decycler.hare); + decycler.tortoise = decycler.hare = this; + return; + } + + if (decycler.tortoise_awake) + decycler.tortoise = decycler.tortoise->u.next; // Time to move. + + this->prev = decycler.hare; + decycler.hare->u.next = this; + decycler.hare = this; + } + + ~hb_decycler_node_t () + { + hb_decycler_t &decycler = *u.decycler; + + // Inverse of the constructor. + + assert (decycler.hare == this); + decycler.hare = prev; + if (prev) + prev->u.decycler = &decycler; + + assert (decycler.tortoise); + if (decycler.tortoise_awake) + decycler.tortoise = decycler.tortoise->prev; + + decycler.tortoise_awake = !decycler.tortoise_awake; + } + + bool visit (uintptr_t value_) + { + value = value_; + + hb_decycler_t &decycler = *u.decycler; + + if (decycler.tortoise == this) + return true; // First node; not a cycle. + + if (decycler.tortoise->value == value) + return false; // Cycle detected. + + return true; + } + + private: + union { + hb_decycler_t *decycler; + hb_decycler_node_t *next; + } u = {nullptr}; + hb_decycler_node_t *prev = nullptr; + uintptr_t value = 0; +}; + +#endif /* HB_DECYCLER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h index 200e8ff4928..d854a2b16f5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h @@ -56,7 +56,7 @@ HB_BEGIN_DECLS /** * HB_SCRIPT_CANADIAN_ABORIGINAL: * - * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead: + * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead. * * Deprecated: 0.9.20 */ @@ -301,6 +301,15 @@ hb_font_get_glyph_shape (hb_font_t *font, hb_draw_funcs_t *dfuncs, void *draw_data); +/** + * HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: + * + * Use #HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION instead. + * + * Deprecated: 8.3.0 + */ +#define HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION + #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-draw.h b/src/java.desktop/share/native/libharfbuzz/hb-draw.h index eba791d10c0..4556b082d60 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-draw.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.h @@ -70,7 +70,7 @@ typedef struct hb_draw_state_t { * * The default #hb_draw_state_t at the start of glyph drawing. */ -#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}} +#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}} /** diff --git a/src/java.desktop/share/native/libharfbuzz/hb-draw.hh b/src/java.desktop/share/native/libharfbuzz/hb-draw.hh index e1adf9ddc9f..2c30843de64 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-draw.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.hh @@ -232,7 +232,7 @@ struct hb_draw_session_t funcs->close_path (draw_data, st); } - protected: + public: float slant; bool not_slanted; hb_draw_funcs_t *funcs; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc b/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc index ff723ac7000..6b7e1913024 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-face-builder.cc @@ -42,7 +42,7 @@ struct face_table_info_t { hb_blob_t* data; - signed order; + unsigned order; }; struct hb_face_builder_data_t @@ -153,6 +153,50 @@ _hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void return hb_blob_reference (data->tables[tag].data); } +static unsigned +_hb_face_builder_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data; + + unsigned population = data->tables.get_population (); + + if (!table_count) + return population; + + if (unlikely (start_offset >= population)) + { + if (table_count) + *table_count = 0; + return population; + } + + // Sort the tags. + hb_vector_t sorted_tags; + data->tables.keys () | hb_sink (sorted_tags); + if (unlikely (sorted_tags.in_error ())) + { + // Not much to do... + } + sorted_tags.qsort ([] (const void* a, const void* b) { + return * (hb_tag_t *) a < * (hb_tag_t *) b ? -1 : + * (hb_tag_t *) a == * (hb_tag_t *) b ? 0 : + +1; + }); + + auto array = sorted_tags.as_array ().sub_array (start_offset, table_count); + auto out = hb_array (table_tags, *table_count); + + + array.iter () + | hb_sink (out) + ; + + return population; +} + /** * hb_face_builder_create: @@ -171,9 +215,16 @@ hb_face_builder_create () hb_face_builder_data_t *data = _hb_face_builder_data_create (); if (unlikely (!data)) return hb_face_get_empty (); - return hb_face_create_for_tables (_hb_face_builder_reference_table, - data, - _hb_face_builder_data_destroy); + hb_face_t *face = hb_face_create_for_tables (_hb_face_builder_reference_table, + data, + _hb_face_builder_data_destroy); + + hb_face_set_get_table_tags_func (face, + _hb_face_builder_get_table_tags, + data, + nullptr); + + return face; } /** @@ -199,7 +250,7 @@ hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; hb_blob_t* previous = data->tables.get (tag).data; - if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1})) + if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), (unsigned) -1})) { hb_blob_destroy (blob); return false; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.cc b/src/java.desktop/share/native/libharfbuzz/hb-face.cc index bc19bb9d5c9..7967ae3241b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.cc @@ -90,10 +90,6 @@ DEFINE_NULL_INSTANCE (hb_face_t) = { HB_OBJECT_HEADER_STATIC, - nullptr, /* reference_table_func */ - nullptr, /* user_data */ - nullptr, /* destroy */ - 0, /* index */ 1000, /* upem */ 0, /* num_glyphs */ @@ -110,8 +106,9 @@ DEFINE_NULL_INSTANCE (hb_face_t) = * * Variant of hb_face_create(), built for those cases where it is more * convenient to provide data for individual tables instead of the whole font - * data. With the caveat that hb_face_get_table_tags() does not currently work - * with faces created this way. + * data. With the caveat that hb_face_get_table_tags() would not work + * with faces created this way. You can address that by calling the + * hb_face_set_get_table_tags_func() function and setting the appropriate callback. * * Creates a new face object from the specified @user_data and @reference_table_func, * with the @destroy callback. @@ -194,6 +191,22 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void return blob; } +static unsigned +_hb_face_for_data_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; + + const OT::OpenTypeFontFile &ot_file = *data->blob->as (); + const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); + + return ot_face.get_table_tags (start_offset, table_count, table_tags); +} + + /** * hb_face_create: * @blob: #hb_blob_t to work upon @@ -240,12 +253,73 @@ hb_face_create (hb_blob_t *blob, face = hb_face_create_for_tables (_hb_face_for_data_reference_table, closure, _hb_face_for_data_closure_destroy); + hb_face_set_get_table_tags_func (face, + _hb_face_for_data_get_table_tags, + closure, + nullptr); face->index = index; return face; } +/** + * hb_face_create_or_fail: + * @blob: #hb_blob_t to work upon + * @index: The index of the face within @blob + * + * Like hb_face_create(), but returns `NULL` if the blob data + * contains no usable font face at the specified index. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index. + * + * Since: 10.1.0 + **/ +hb_face_t * +hb_face_create_or_fail (hb_blob_t *blob, + unsigned int index) +{ + unsigned num_faces = hb_face_count (blob); + if (index >= num_faces) + return nullptr; + + hb_face_t *face = hb_face_create (blob, index); + if (hb_object_is_immutable (face)) + return nullptr; + + return face; +} + +#ifndef HB_NO_OPEN +/** + * hb_face_create_from_file_or_fail: + * @file_name: A font filename + * @index: The index of the face within the file + * + * A thin wrapper around hb_blob_create_from_file_or_fail() + * followed by hb_face_create_or_fail(). + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the file cannot be read. + * + * Since: 10.1.0 + **/ +HB_EXTERN hb_face_t * +hb_face_create_from_file_or_fail (const char *file_name, + unsigned int index) +{ + hb_blob_t *blob = hb_blob_create_from_file_or_fail (file_name); + if (unlikely (!blob)) + return nullptr; + + hb_face_t *face = hb_face_create_or_fail (blob, index); + hb_blob_destroy (blob); + + return face; +} +#endif + /** * hb_face_get_empty: * @@ -306,6 +380,9 @@ hb_face_destroy (hb_face_t *face) face->data.fini (); face->table.fini (); + if (face->get_table_tags_destroy) + face->get_table_tags_destroy (face->get_table_tags_user_data); + if (face->destroy) face->destroy (face->user_data); @@ -395,7 +472,8 @@ hb_face_is_immutable (const hb_face_t *face) * @tag: The #hb_tag_t of the table to query * * Fetches a reference to the specified table within - * the specified face. + * the specified face. Returns an empty blob if referencing table data is not + * possible. * * Return value: (transfer full): A pointer to the @tag table within @face * @@ -415,9 +493,10 @@ hb_face_reference_table (const hb_face_t *face, * hb_face_reference_blob: * @face: A face object * - * Fetches a pointer to the binary blob that contains the - * specified face. Returns an empty blob if referencing face data is not - * possible. + * Fetches a pointer to the binary blob that contains the specified face. + * If referencing the face data is not possible, this function creates a blob + * out of individual table blobs if hb_face_get_table_tags() works with this + * face, otherwise it returns an empty blob. * * Return value: (transfer full): A pointer to the blob for @face * @@ -426,7 +505,41 @@ hb_face_reference_table (const hb_face_t *face, hb_blob_t * hb_face_reference_blob (hb_face_t *face) { - return face->reference_table (HB_TAG_NONE); + hb_blob_t *blob = face->reference_table (HB_TAG_NONE); + + if (blob == hb_blob_get_empty ()) + { + // If referencing the face blob is not possible (e.g. not implemented by the + // font functions), use face builder to create a blob out of individual + // table blobs. + unsigned total_count = hb_face_get_table_tags (face, 0, nullptr, nullptr); + if (total_count) + { + hb_tag_t tags[64]; + unsigned count = ARRAY_LENGTH (tags); + hb_face_t* builder = hb_face_builder_create (); + + for (unsigned offset = 0; offset < total_count; offset += count) + { + hb_face_get_table_tags (face, offset, &count, tags); + if (unlikely (!count)) + break; // Allocation error + for (unsigned i = 0; i < count; i++) + { + if (unlikely (!tags[i])) + continue; + hb_blob_t *table = hb_face_reference_table (face, tags[i]); + hb_face_builder_add_table (builder, tags[i], table); + hb_blob_destroy (table); + } + } + + blob = hb_face_reference_blob (builder); + hb_face_destroy (builder); + } + } + + return blob; } /** @@ -547,6 +660,38 @@ hb_face_get_glyph_count (const hb_face_t *face) return face->get_num_glyphs (); } +/** + * hb_face_set_get_table_tags_func: + * @face: A face object + * @func: (closure user_data) (destroy destroy) (scope notified): The table-tag-fetching function + * @user_data: A pointer to the user data, to be destroyed by @destroy when not needed anymore + * @destroy: (nullable): A callback to call when @func is not needed anymore + * + * Sets the table-tag-fetching function for the specified face object. + * + * Since: 10.0.0 + */ +HB_EXTERN void +hb_face_set_get_table_tags_func (hb_face_t *face, + hb_get_table_tags_func_t func, + void *user_data, + hb_destroy_func_t destroy) +{ + if (hb_object_is_immutable (face)) + { + if (destroy) + destroy (user_data); + return; + } + + if (face->get_table_tags_destroy) + face->get_table_tags_destroy (face->get_table_tags_user_data); + + face->get_table_tags_func = func; + face->get_table_tags_user_data = user_data; + face->get_table_tags_destroy = destroy; +} + /** * hb_face_get_table_tags: * @face: A face object @@ -568,19 +713,14 @@ hb_face_get_table_tags (const hb_face_t *face, unsigned int *table_count, /* IN/OUT */ hb_tag_t *table_tags /* OUT */) { - if (face->destroy != (hb_destroy_func_t) _hb_face_for_data_closure_destroy) + if (!face->get_table_tags_func) { if (table_count) *table_count = 0; return 0; } - hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data; - - const OT::OpenTypeFontFile &ot_file = *data->blob->as (); - const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); - - return ot_face.get_table_tags (start_offset, table_count, table_tags); + return face->get_table_tags_func (face, start_offset, table_count, table_tags, face->get_table_tags_user_data); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.h b/src/java.desktop/share/native/libharfbuzz/hb-face.h index 2e5fb150927..953298fa50b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.h @@ -59,15 +59,28 @@ HB_EXTERN hb_face_t * hb_face_create (hb_blob_t *blob, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_or_fail (hb_blob_t *blob, + unsigned int index); + +HB_EXTERN hb_face_t * +hb_face_create_from_file_or_fail (const char *file_name, + unsigned int index); + /** * hb_reference_table_func_t: * @face: an #hb_face_t to reference table for * @tag: the tag of the table to reference * @user_data: User data pointer passed by the caller * - * Callback function for hb_face_create_for_tables(). + * Callback function for hb_face_create_for_tables(). The @tag is the tag of the + * table to reference, and the special tag #HB_TAG_NONE is used to reference the + * blob of the face itself. If referencing the face blob is not possible, it is + * recommended to set hb_get_table_tags_func_t on the @face to allow + * hb_face_reference_blob() to create a face blob out of individual table blobs. * - * Return value: (transfer full): A pointer to the @tag table within @face + * Return value: (transfer full): A pointer to the @tag table within @face or + * `NULL` if the table is not found or cannot be referenced. * * Since: 0.9.2 */ @@ -135,6 +148,34 @@ hb_face_set_glyph_count (hb_face_t *face, HB_EXTERN unsigned int hb_face_get_glyph_count (const hb_face_t *face); + +/** + * hb_get_table_tags_func_t: + * @face: A face object + * @start_offset: The index of first table tag to retrieve + * @table_count: (inout): Input = the maximum number of table tags to return; + * Output = the actual number of table tags returned (may be zero) + * @table_tags: (out) (array length=table_count): The array of table tags found + * @user_data: User data pointer passed by the caller + * + * Callback function for hb_face_get_table_tags(). + * + * Return value: Total number of tables, or zero if it is not possible to list + * + * Since: 10.0.0 + */ +typedef unsigned int (*hb_get_table_tags_func_t) (const hb_face_t *face, + unsigned int start_offset, + unsigned int *table_count, /* IN/OUT */ + hb_tag_t *table_tags /* OUT */, + void *user_data); + +HB_EXTERN void +hb_face_set_get_table_tags_func (hb_face_t *face, + hb_get_table_tags_func_t func, + void *user_data, + hb_destroy_func_t destroy); + HB_EXTERN unsigned int hb_face_get_table_tags (const hb_face_t *face, unsigned int start_offset, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-face.hh b/src/java.desktop/share/native/libharfbuzz/hb-face.hh index 4c6b252e88e..4d12030f187 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-face.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-face.hh @@ -48,13 +48,17 @@ struct hb_face_t { hb_object_header_t header; + unsigned int index; /* Face index in a collection, zero-based. */ + mutable hb_atomic_int_t upem; /* Units-per-EM. */ + mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + hb_reference_table_func_t reference_table_func; void *user_data; hb_destroy_func_t destroy; - unsigned int index; /* Face index in a collection, zero-based. */ - mutable hb_atomic_int_t upem; /* Units-per-EM. */ - mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + hb_get_table_tags_func_t get_table_tags_func; + void *get_table_tags_user_data; + hb_destroy_func_t get_table_tags_destroy; hb_shaper_object_dataset_t data;/* Various shaper data. */ hb_ot_face_t table; /* All the face's tables. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-font.cc index 9ce55bbeb89..0c9084c574f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.cc @@ -231,7 +231,7 @@ hb_font_get_glyph_v_advance_nil (hb_font_t *font, void *user_data HB_UNUSED) { /* TODO use font_extents.ascender+descender */ - return font->y_scale; + return -font->y_scale; } static hb_position_t diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.hh b/src/java.desktop/share/native/libharfbuzz/hb-font.hh index c3198830cd3..8273f347562 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-font.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-font.hh @@ -651,7 +651,7 @@ struct hb_font_t { if (get_glyph_name (glyph, s, size)) return; - if (size && snprintf (s, size, "gid%u", glyph) < 0) + if (size && snprintf (s, size, "gid%" PRIu32, glyph) < 0) *s = '\0'; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc index 32f5d3012da..b126d2022d1 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc @@ -37,10 +37,15 @@ #include "hb-draw.hh" #include "hb-font.hh" #include "hb-machinery.hh" +#ifndef HB_NO_AAT +#include "hb-aat-layout-trak-table.hh" +#endif #include "hb-ot-os2-table.hh" +#include "hb-ot-stat-table.hh" #include "hb-ot-shaper-arabic-pua.hh" #include "hb-paint.hh" +#include FT_MODULE_H #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H #include FT_OUTLINE_H @@ -225,7 +230,7 @@ _hb_ft_hb_font_check_changed (hb_font_t *font, * Sets the FT_Load_Glyph load flags for the specified #hb_font_t. * * For more information, see - * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx + * * * This function works with #hb_font_t objects created by * hb_ft_font_create() or hb_ft_font_create_referenced(). @@ -253,7 +258,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t. * * For more information, see - * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx + * * * This function works with #hb_font_t objects created by * hb_ft_font_create() or hb_ft_font_create_referenced(). @@ -274,7 +279,7 @@ hb_ft_font_get_load_flags (hb_font_t *font) } /** - * hb_ft_font_get_face: (skip) + * hb_ft_font_get_ft_face: (skip) * @font: #hb_font_t to work upon * * Fetches the FT_Face associated with the specified #hb_font_t @@ -285,10 +290,10 @@ hb_ft_font_get_load_flags (hb_font_t *font) * * Return value: (nullable): the FT_Face found or `NULL` * - * Since: 0.9.2 + * Since: 10.4.0 **/ FT_Face -hb_ft_font_get_face (hb_font_t *font) +hb_ft_font_get_ft_face (hb_font_t *font) { if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) return nullptr; @@ -298,6 +303,31 @@ hb_ft_font_get_face (hb_font_t *font) return ft_font->ft_face; } +#ifndef HB_DISABLE_DEPRECATED + +/** + * hb_ft_font_get_face: (skip) + * @font: #hb_font_t to work upon + * + * Fetches the FT_Face associated with the specified #hb_font_t + * font object. + * + * This function works with #hb_font_t objects created by + * hb_ft_font_create() or hb_ft_font_create_referenced(). + * + * Return value: (nullable): the FT_Face found or `NULL` + * + * Since: 0.9.2 + * Deprecated: 10.4.0: Use hb_ft_font_get_ft_face() instead. + **/ +FT_Face +hb_ft_font_get_face (hb_font_t *font) +{ + return hb_ft_font_get_ft_face (font); +} + +#endif + /** * hb_ft_font_lock_face: (skip) * @font: #hb_font_t to work upon @@ -501,6 +531,26 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + bool apply_trak = false; +#endif + if (apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_h_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } +#endif } #ifndef HB_NO_VERTICAL @@ -537,7 +587,20 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, * have a Y growing upward. Hence the extra negation. */ hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - return ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); + v = ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); + +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + bool apply_trak = false; +#endif + if (apply_trak) + v += font->face->table.trak->get_v_tracking (font); +#endif + + return v; } #endif @@ -930,11 +993,15 @@ hb_ft_paint_glyph (hb_font_t *font, hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; + FT_Long load_flags = ft_font->load_flags | FT_LOAD_NO_BITMAP | FT_LOAD_COLOR; +#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21301 + load_flags |= FT_LOAD_NO_SVG; +#endif + /* We release the lock before calling into glyph callbacks, such that * eg. draw API can call back into the face.*/ - if (unlikely (FT_Load_Glyph (ft_face, gid, - ft_font->load_flags | FT_LOAD_COLOR))) + if (unlikely (FT_Load_Glyph (ft_face, gid, load_flags))) return; if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) @@ -1104,6 +1171,45 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data buffer, hb_free); } +static unsigned +_hb_ft_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + FT_Face ft_face = (FT_Face) user_data; + + FT_ULong population = 0; + FT_Sfnt_Table_Info (ft_face, + 0, // table_index; ignored + nullptr, + &population); + + if (!table_count) + return population; + else + *table_count = 0; + + if (unlikely (start_offset >= population)) + return population; + + unsigned end_offset = hb_min (start_offset + *table_count, (unsigned) population); + if (unlikely (end_offset < start_offset)) + return population; + + *table_count = end_offset - start_offset; + for (unsigned i = start_offset; i < end_offset; i++) + { + FT_ULong tag = 0, length; + FT_Sfnt_Table_Info (ft_face, i, &tag, &length); + table_tags[i - start_offset] = tag; + } + + return population; +} + + /** * hb_ft_face_create: * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon @@ -1145,6 +1251,7 @@ hb_ft_face_create (FT_Face ft_face, hb_blob_destroy (blob); } else { face = hb_face_create_for_tables (_hb_ft_reference_table, ft_face, destroy); + hb_face_set_get_table_tags_func (face, _hb_ft_get_table_tags, ft_face, nullptr); } hb_face_set_index (face, ft_face->face_index); @@ -1215,7 +1322,7 @@ hb_ft_face_finalize (void *arg) hb_face_t * hb_ft_face_create_cached (FT_Face ft_face) { - if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize)) + if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != hb_ft_face_finalize)) { if (ft_face->generic.finalizer) ft_face->generic.finalizer (ft_face); @@ -1245,7 +1352,7 @@ hb_ft_face_create_cached (FT_Face ft_face) * * If you know you have valid reasons not to use hb_ft_font_create_referenced(), * then it is the client program's responsibility to destroy @ft_face - * after the #hb_font_t font object has been destroyed. + * only after the #hb_font_t font object has been destroyed. * * HarfBuzz will use the @destroy callback on the #hb_font_t font object * if it is supplied when you use this function. However, even if @destroy @@ -1392,6 +1499,24 @@ hb_ft_font_create_referenced (FT_Face ft_face) return hb_ft_font_create (ft_face, _hb_ft_face_destroy); } + +static void * _hb_ft_alloc (FT_Memory memory, long size) +{ return hb_malloc (size); } + +static void _hb_ft_free (FT_Memory memory, void *block) +{ hb_free (block); } + +static void * _hb_ft_realloc (FT_Memory memory, long cur_size, long new_size, void *block) +{ return hb_realloc (block, new_size); } + +static FT_MemoryRec_ m = +{ + nullptr, + _hb_ft_alloc, + _hb_ft_free, + _hb_ft_realloc +}; + static inline void free_static_ft_library (); static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t, @@ -1400,16 +1525,19 @@ static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_tgeneric.data); +} + +static void +destroy_ft_library (void *arg) +{ + FT_Done_Library ((FT_Library) arg); +} + +/** + * hb_ft_face_create_from_file_or_fail: + * @file_name: A font filename + * @index: The index of the face within the file + * + * Creates an #hb_face_t face object from the specified + * font file and face index. + * + * This is similar in functionality to hb_face_create_from_file_or_fail(), + * but uses the FreeType library for loading the font file. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the file cannot be read. + * + * Since: 10.1.0 + */ +hb_face_t * +hb_ft_face_create_from_file_or_fail (const char *file_name, + unsigned int index) { - return static_ft_library.get_unconst (); + FT_Library ft_library = reference_ft_library (); + if (unlikely (!ft_library)) + { + DEBUG_MSG (FT, ft_library, "reference_ft_library failed"); + return nullptr; + } + + FT_Face ft_face; + if (unlikely (FT_New_Face (ft_library, + file_name, + index, + &ft_face))) + return nullptr; + + hb_face_t *face = hb_ft_face_create_referenced (ft_face); + FT_Done_Face (ft_face); + + ft_face->generic.data = ft_library; + ft_face->generic.finalizer = finalize_ft_library; + + if (hb_face_is_immutable (face)) + return nullptr; + + return face; } static void @@ -1465,32 +1660,47 @@ _release_blob (void *arg) void hb_ft_font_set_funcs (hb_font_t *font) { + // In case of failure... + hb_font_set_funcs (font, + hb_font_funcs_get_empty (), + nullptr, nullptr); + hb_blob_t *blob = hb_face_reference_blob (font->face); unsigned int blob_length; const char *blob_data = hb_blob_get_data (blob, &blob_length); if (unlikely (!blob_length)) DEBUG_MSG (FT, font, "Font face has empty blob"); - FT_Face ft_face = nullptr; - FT_Error err = FT_New_Memory_Face (get_ft_library (), - (const FT_Byte *) blob_data, - blob_length, - hb_face_get_index (font->face), - &ft_face); + FT_Library ft_library = reference_ft_library (); + if (unlikely (!ft_library)) + { + hb_blob_destroy (blob); + DEBUG_MSG (FT, font, "reference_ft_library failed"); + return; + } - if (unlikely (err)) { + FT_Face ft_face = nullptr; + if (unlikely (FT_New_Memory_Face (ft_library, + (const FT_Byte *) blob_data, + blob_length, + hb_face_get_index (font->face), + &ft_face))) + { hb_blob_destroy (blob); - DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed"); + DEBUG_MSG (FT, font, "FT_New_Memory_Face() failed"); return; } if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL)) FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE); - + // Hook the blob to the FT_Face ft_face->generic.data = blob; 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); + _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/src/java.desktop/share/native/libharfbuzz/hb-ft.h b/src/java.desktop/share/native/libharfbuzz/hb-ft.h index b2d148014c0..94952f48a05 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ft.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.h @@ -84,6 +84,9 @@ hb_ft_face_create_cached (FT_Face ft_face); HB_EXTERN hb_face_t * hb_ft_face_create_referenced (FT_Face ft_face); +HB_EXTERN hb_face_t * +hb_ft_face_create_from_file_or_fail (const char *file_name, + unsigned int index); /* * hb-font from ft-face. @@ -108,7 +111,7 @@ HB_EXTERN hb_font_t * hb_ft_font_create_referenced (FT_Face ft_face); HB_EXTERN FT_Face -hb_ft_font_get_face (hb_font_t *font); +hb_ft_font_get_ft_face (hb_font_t *font); HB_EXTERN FT_Face hb_ft_font_lock_face (hb_font_t *font); @@ -139,6 +142,13 @@ hb_ft_hb_font_changed (hb_font_t *font); HB_EXTERN void hb_ft_font_set_funcs (hb_font_t *font); +#ifndef HB_DISABLE_DEPRECATED + +HB_DEPRECATED_FOR (hb_ft_font_get_ft_face) +HB_EXTERN FT_Face +hb_ft_font_get_face (hb_font_t *font); + +#endif HB_END_DECLS diff --git a/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh new file mode 100644 index 00000000000..e91e371dc0c --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-geometry.hh @@ -0,0 +1,293 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ +#ifndef HB_GEOMETRY_HH +#define HB_GEOMETRY_HH + +#include "hb.hh" + + +struct hb_extents_t +{ + hb_extents_t () {} + 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; } + bool is_void () const { return xmin > xmax; } + + void union_ (const hb_extents_t &o) + { + xmin = hb_min (xmin, o.xmin); + ymin = hb_min (ymin, o.ymin); + xmax = hb_max (xmax, o.xmax); + ymax = hb_max (ymax, o.ymax); + } + + void intersect (const hb_extents_t &o) + { + xmin = hb_max (xmin, o.xmin); + ymin = hb_max (ymin, o.ymin); + xmax = hb_min (xmax, o.xmax); + ymax = hb_min (ymax, o.ymax); + } + + void + add_point (float x, float y) + { + if (unlikely (is_void ())) + { + xmin = xmax = x; + ymin = ymax = y; + } + else + { + xmin = hb_min (xmin, x); + ymin = hb_min (ymin, y); + xmax = hb_max (xmax, x); + ymax = hb_max (ymax, y); + } + } + + float xmin = 0.f; + float ymin = 0.f; + float xmax = -1.f; + float ymax = -1.f; +}; + +struct hb_transform_t +{ + hb_transform_t () {} + 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; + } + + void multiply (const hb_transform_t &o) + { + /* 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; + } + + void transform_distance (float &dx, float &dy) const + { + 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 + { + transform_distance (x, y); + x += x0; + y += y0; + } + + void transform_extents (hb_extents_t &extents) const + { + float quad_x[4], quad_y[4]; + + quad_x[0] = extents.xmin; + quad_y[0] = extents.ymin; + quad_x[1] = extents.xmin; + quad_y[1] = extents.ymax; + quad_x[2] = extents.xmax; + quad_y[2] = extents.ymin; + quad_x[3] = extents.xmax; + quad_y[3] = extents.ymax; + + extents = hb_extents_t {}; + for (unsigned i = 0; i < 4; i++) + { + transform_point (quad_x[i], quad_y[i]); + extents.add_point (quad_x[i], quad_y[i]); + } + } + + void transform (const hb_transform_t &o) { multiply (o); } + + void translate (float x, float y) + { + if (x == 0.f && y == 0.f) + return; + + x0 += xx * x + xy * y; + y0 += yx * x + yy * y; + } + + void scale (float scaleX, float scaleY) + { + if (scaleX == 1.f && scaleY == 1.f) + return; + + xx *= scaleX; + yx *= scaleX; + xy *= scaleY; + yy *= scaleY; + } + + void rotate (float rotation) + { + if (rotation == 0.f) + return; + + // 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); + } + + void skew (float skewX, float skewY) + { + if (skewX == 0.f && skewY == 0.f) + 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); + } + + float xx = 1.f; + float yx = 0.f; + float xy = 0.f; + float yy = 1.f; + float x0 = 0.f; + float y0 = 0.f; +}; + +#define HB_TRANSFORM_IDENTITY hb_transform_t{1.f, 0.f, 0.f, 1.f, 0.f, 0.f} + +struct hb_bounds_t +{ + enum status_t { + UNBOUNDED, + BOUNDED, + EMPTY, + }; + + hb_bounds_t (status_t status) : status (status) {} + hb_bounds_t (const hb_extents_t &extents) : + status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} + + void union_ (const hb_bounds_t &o) + { + if (o.status == UNBOUNDED) + status = UNBOUNDED; + else if (o.status == BOUNDED) + { + if (status == EMPTY) + *this = o; + else if (status == BOUNDED) + extents.union_ (o.extents); + } + } + + void intersect (const hb_bounds_t &o) + { + if (o.status == EMPTY) + status = EMPTY; + else if (o.status == BOUNDED) + { + if (status == UNBOUNDED) + *this = o; + else if (status == BOUNDED) + { + extents.intersect (o.extents); + if (extents.is_empty ()) + status = EMPTY; + } + } + } + + status_t status; + hb_extents_t extents; +}; + +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; + + operator bool () const + { + return translateX || translateY || + rotation || + scaleX != 1 || scaleY != 1 || + skewX || skewY || + tCenterX || tCenterY; + } + + hb_transform_t to_transform () const + { + hb_transform_t t; + t.translate (translateX + tCenterX, translateY + tCenterY); + t.rotate (rotation); + t.scale (scaleX, scaleY); + t.skew (-skewX, skewY); + t.translate (-tCenterX, -tCenterY); + return t; + } +}; + + +#endif /* HB_GEOMETRY_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh index ad45dcf2c1d..21d9544a74b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh @@ -324,6 +324,16 @@ struct hb_is_sink_of (hb_is_source_of(Iter, Item) && Iter::is_sorted_iterator) +struct +{ + template + unsigned operator () (const Iterable &_) const { return hb_len (hb_iter (_)); } + + unsigned operator () (unsigned _) const { return _; } +} +HB_FUNCOBJ (hb_len_of); + /* Range-based 'for' for iterables. */ template struct hb_hashmap_t { + static constexpr bool realloc_move = true; + hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { alloc (o.population); hb_copy (o, *this); } - hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); } + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () + { + if (unlikely (!o.mask)) return; + + if (item_t::is_trivial) + { + items = (item_t *) hb_malloc (sizeof (item_t) * (o.mask + 1)); + if (unlikely (!items)) + { + successful = false; + return; + } + population = o.population; + occupancy = o.occupancy; + mask = o.mask; + prime = o.prime; + max_chain_length = o.max_chain_length; + memcpy (items, o.items, sizeof (item_t) * (mask + 1)); + return; + } + + alloc (o.population); hb_copy (o, *this); + } + hb_hashmap_t (hb_hashmap_t&& o) noexcept : hb_hashmap_t () { hb_swap (*this, o); } hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } - hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; } + hb_hashmap_t& operator= (hb_hashmap_t&& o) noexcept { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list> lst) : hb_hashmap_t () { @@ -113,26 +137,23 @@ struct hb_hashmap_t }; hb_object_header_t header; - unsigned int successful : 1; /* Allocations successful */ - unsigned int population : 31; /* Not including tombstones. */ + bool successful; /* Allocations successful */ + unsigned short max_chain_length; + unsigned int population; /* Not including tombstones. */ unsigned int occupancy; /* Including tombstones. */ unsigned int mask; unsigned int prime; - unsigned int max_chain_length; item_t *items; - friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) + friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) noexcept { if (unlikely (!a.successful || !b.successful)) return; - unsigned tmp = a.population; - a.population = b.population; - b.population = tmp; - //hb_swap (a.population, b.population); + hb_swap (a.max_chain_length, b.max_chain_length); + hb_swap (a.population, b.population); hb_swap (a.occupancy, b.occupancy); hb_swap (a.mask, b.mask); hb_swap (a.prime, b.prime); - hb_swap (a.max_chain_length, b.max_chain_length); hb_swap (a.items, b.items); } void init () @@ -140,10 +161,10 @@ struct hb_hashmap_t hb_object_init (this); successful = true; + max_chain_length = 0; population = occupancy = 0; mask = 0; prime = 0; - max_chain_length = 0; items = nullptr; } void fini () @@ -209,9 +230,10 @@ struct hb_hashmap_t old_items[i].hash, std::move (old_items[i].value)); } - if (!item_t::is_trivial) - old_items[i].~item_t (); } + if (!item_t::is_trivial) + for (unsigned int i = 0; i < old_size; i++) + old_items[i].~item_t (); hb_free (old_items); @@ -285,7 +307,7 @@ struct hb_hashmap_t const V& get_with_hash (const K &key, uint32_t hash) const { if (!items) return item_t::default_value (); - auto *item = fetch_item (key, hb_hash (key)); + auto *item = fetch_item (key, hash); if (item) return item->value; return item_t::default_value (); @@ -533,7 +555,7 @@ struct hb_map_t : hb_hashmap_t lst) : hashmap (lst) {} diff --git a/src/java.desktop/share/native/libharfbuzz/hb-null.hh b/src/java.desktop/share/native/libharfbuzz/hb-null.hh index 4a5270e3400..63ec9a7c64d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-null.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-null.hh @@ -176,7 +176,7 @@ template static inline Type& Crap () { static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast (_hb_CrapPool); - memcpy (obj, std::addressof (Null (Type)), sizeof (*obj)); + memcpy (reinterpret_cast(obj), std::addressof (Null (Type)), sizeof (*obj)); return *obj; } template diff --git a/src/java.desktop/share/native/libharfbuzz/hb-object.hh b/src/java.desktop/share/native/libharfbuzz/hb-object.hh index ef675f835f1..c02ec8bfacf 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-object.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-object.hh @@ -325,7 +325,7 @@ retry: hb_user_data_array_t *user_data = obj->header.user_data.get_acquire (); if (unlikely (!user_data)) { - user_data = (hb_user_data_array_t *) hb_calloc (sizeof (hb_user_data_array_t), 1); + user_data = (hb_user_data_array_t *) hb_calloc (1, sizeof (hb_user_data_array_t)); if (unlikely (!user_data)) return false; user_data->init (); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh index 387b1430ac1..382ee2ddaf2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh @@ -250,7 +250,7 @@ struct TTCHeader { switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ - case 1: return u.version1.get_face_count (); + case 1: hb_barrier (); return u.version1.get_face_count (); default:return 0; } } @@ -258,7 +258,7 @@ struct TTCHeader { switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ - case 1: return u.version1.get_face (i); + case 1: hb_barrier (); return u.version1.get_face (i); default:return Null (OpenTypeFontFace); } } @@ -267,9 +267,10 @@ struct TTCHeader { TRACE_SANITIZE (this); if (unlikely (!u.header.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ - case 1: return_trace (u.version1.sanitize (c)); + case 1: hb_barrier (); return_trace (u.version1.sanitize (c)); default:return_trace (true); } } @@ -302,6 +303,7 @@ struct ResourceRecord TRACE_SANITIZE (this); return_trace (c->check_struct (this) && offset.sanitize (c, data_base) && + hb_barrier () && get_face (data_base).sanitize (c)); } @@ -337,6 +339,7 @@ struct ResourceTypeRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && resourcesZ.sanitize (c, type_base, get_resource_count (), data_base)); @@ -385,6 +388,7 @@ struct ResourceMap { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && typeList.sanitize (c, this, &(this+typeList), data_base)); @@ -428,6 +432,7 @@ struct ResourceForkHeader { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && data.sanitize (c, this, dataLen) && map.sanitize (c, this, &(this+data))); } @@ -508,6 +513,7 @@ struct OpenTypeFontFile { TRACE_SANITIZE (this); if (unlikely (!u.tag.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.tag) { case CFFTag: /* All the non-collection tags */ case TrueTag: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh index 25142da44a6..89da9c7bc95 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh @@ -86,21 +86,12 @@ struct IntType return pb->cmp (*pa); } - template ::value && - sizeof (Type2) < sizeof (int) && - sizeof (Type) < sizeof (int))> - int cmp (Type2 a) const - { - Type b = v; - return (int) a - (int) b; - } template int cmp (Type2 a) const { Type b = v; - return a < b ? -1 : a == b ? 0 : +1; + return (a > b) - (a < b); } bool sanitize (hb_sanitize_context_t *c) const { @@ -132,6 +123,89 @@ struct HBUINT15 : HBUINT16 DEFINE_SIZE_STATIC (2); }; +/* 32-bit unsigned integer with variable encoding. */ +struct HBUINT32VAR +{ + unsigned get_size () const + { + unsigned b0 = v[0]; + if (b0 < 0x80) + return 1; + else if (b0 < 0xC0) + return 2; + else if (b0 < 0xE0) + return 3; + else if (b0 < 0xF0) + return 4; + else + return 5; + } + + static unsigned get_size (uint32_t v) + { + if (v < 0x80) + return 1; + else if (v < 0x4000) + return 2; + else if (v < 0x200000) + return 3; + else if (v < 0x10000000) + return 4; + else + return 5; + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_range (v, 1) && + hb_barrier () && + c->check_range (v, get_size ())); + } + + operator uint32_t () const + { + unsigned b0 = v[0]; + if (b0 < 0x80) + return b0; + else if (b0 < 0xC0) + return ((b0 & 0x3F) << 8) | v[1]; + else if (b0 < 0xE0) + return ((b0 & 0x1F) << 16) | (v[1] << 8) | v[2]; + else if (b0 < 0xF0) + return ((b0 & 0x0F) << 24) | (v[1] << 16) | (v[2] << 8) | v[3]; + else + return (v[1] << 24) | (v[2] << 16) | (v[3] << 8) | v[4]; + } + + static bool serialize (hb_serialize_context_t *c, uint32_t v) + { + unsigned len = get_size (v); + + unsigned char *buf = c->allocate_size (len, false); + if (unlikely (!buf)) + return false; + + unsigned char *p = buf + len; + for (unsigned i = 0; i < len; i++) + { + *--p = v & 0xFF; + v >>= 8; + } + + if (len > 1) + buf[0] |= ((1 << (len - 1)) - 1) << (9 - len); + + return true; + } + + protected: + unsigned char v[5]; + + public: + DEFINE_SIZE_MIN (1); +}; + /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */ typedef HBINT16 FWORD; @@ -149,6 +223,7 @@ struct HBFixed : Type operator signed () const = delete; operator unsigned () const = delete; + 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; } @@ -215,11 +290,6 @@ typedef Index NameID; struct VarIdx : HBUINT32 { static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu; static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, ""); - static uint32_t add (uint32_t i, unsigned short v) - { - if (i == NO_VARIATION) return i; - return i + v; - } VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; } }; DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx); @@ -309,7 +379,7 @@ struct _hb_has_null static Type *get_crap () { return &Crap (Type); } }; -template +template struct OffsetTo : Offset { using target_t = Type; @@ -335,22 +405,22 @@ struct OffsetTo : Offset } template + hb_enable_if (hb_is_convertible (const Base, const BaseType *))> friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); } template + hb_enable_if (hb_is_convertible (const Base, const BaseType *))> friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); } template + hb_enable_if (hb_is_convertible (Base, BaseType *))> friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); } template + hb_enable_if (hb_is_convertible (Base, BaseType *))> friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); } - template + template bool serialize_subset (hb_subset_context_t *c, const OffsetTo& src, - const void *src_base, Ts&&... ds) + const Base *src_base, Ts&&... ds) { *this = 0; if (src.is_null ()) @@ -414,10 +484,11 @@ struct OffsetTo : Offset const void *src_base, unsigned dst_bias = 0) { return serialize_copy (c, src, src_base, dst_bias, hb_serialize_context_t::Head); } - bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const + bool sanitize_shallow (hb_sanitize_context_t *c, const BaseType *base) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); //if (unlikely (this->is_null ())) return_trace (true); if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false); return_trace (true); @@ -427,10 +498,11 @@ struct OffsetTo : Offset #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const + bool sanitize (hb_sanitize_context_t *c, const BaseType *base, Ts&&... ds) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && + hb_barrier () && (this->is_null () || c->dispatch (StructAtOffset (base, *this), std::forward (ds)...) || neuter (c))); @@ -445,14 +517,14 @@ struct OffsetTo : Offset DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; /* Partial specializations. */ -template using Offset16To = OffsetTo; -template using Offset24To = OffsetTo; -template using Offset32To = OffsetTo; +template using Offset16To = OffsetTo; +template using Offset24To = OffsetTo; +template using Offset32To = OffsetTo; -template using NNOffsetTo = OffsetTo; -template using NNOffset16To = Offset16To; -template using NNOffset24To = Offset24To; -template using NNOffset32To = Offset32To; +template using NNOffsetTo = OffsetTo; +template using NNOffset16To = Offset16To; +template using NNOffset24To = Offset24To; +template using NNOffset32To = Offset32To; /* @@ -536,6 +608,7 @@ struct UnsizedArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) return_trace (false); @@ -555,27 +628,27 @@ struct UnsizedArrayOf }; /* Unsized array of offset's */ -template -using UnsizedArray16OfOffsetTo = UnsizedArrayOf>; +template +using UnsizedArray16OfOffsetTo = UnsizedArrayOf>; /* Unsized array of offsets relative to the beginning of the array itself. */ -template -struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo +template +struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo { const Type& operator [] (int i_) const { unsigned int i = (unsigned int) i_; - const OffsetTo *p = &this->arrayZ[i]; + const OffsetTo *p = &this->arrayZ[i]; if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Null (Type); /* Overflowed. */ - _hb_compiler_memory_r_barrier (); + hb_barrier (); return this+*p; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; - const OffsetTo *p = &this->arrayZ[i]; + const OffsetTo *p = &this->arrayZ[i]; if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Crap (Type); /* Overflowed. */ - _hb_compiler_memory_r_barrier (); + hb_barrier (); return this+*p; } @@ -583,7 +656,7 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo + return_trace ((UnsizedArray16OfOffsetTo ::sanitize (c, count, this, std::forward (ds)...))); } }; @@ -626,14 +699,14 @@ struct ArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i]; } @@ -725,6 +798,7 @@ struct ArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -735,7 +809,9 @@ struct ArrayOf bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && c->check_array_sized (arrayZ, len, sizeof (LenType))); + return_trace (len.sanitize (c) && + hb_barrier () && + c->check_array_sized (arrayZ, len, sizeof (LenType))); } public: @@ -750,6 +826,7 @@ template using Array32Of = ArrayOf; using PString = ArrayOf; /* Array of Offset's */ +template using Array8OfOffset24To = ArrayOf, HBUINT8>; template using Array16OfOffset16To = ArrayOf, HBUINT16>; template using Array16OfOffset32To = ArrayOf, HBUINT16>; template using Array32OfOffset32To = ArrayOf, HBUINT32>; @@ -762,14 +839,14 @@ struct List16OfOffsetTo : ArrayOf, HBUINT16> { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return this+this->arrayZ[i]; } const Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return this+this->arrayZ[i]; } @@ -807,14 +884,14 @@ struct HeadlessArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i-1]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i-1]; } unsigned int get_size () const @@ -866,6 +943,7 @@ struct HeadlessArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -878,6 +956,7 @@ struct HeadlessArrayOf { TRACE_SANITIZE (this); return_trace (lenP1.sanitize (c) && + hb_barrier () && (!lenP1 || c->check_array_sized (arrayZ, lenP1 - 1, sizeof (LenType)))); } @@ -899,14 +978,14 @@ struct ArrayOfM1 { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return arrayZ[i]; } unsigned int get_size () const @@ -919,6 +998,7 @@ struct ArrayOfM1 TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -931,6 +1011,7 @@ struct ArrayOfM1 { TRACE_SANITIZE (this); return_trace (lenM1.sanitize (c) && + hb_barrier () && (c->check_array_sized (arrayZ, lenM1 + 1, sizeof (LenType)))); } @@ -975,6 +1056,13 @@ struct SortedArrayOf : ArrayOf return_trace (ret); } + SortedArrayOf* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + SortedArrayOf* out = reinterpret_cast (ArrayOf::copy (c)); + return_trace (out); + } + template Type &bsearch (const T &x, Type ¬_found = Crap (Type)) { return *as_array ().bsearch (x, ¬_found); } @@ -1082,14 +1170,14 @@ struct VarSizedBinSearchArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Null (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return StructAtOffset (&bytesZ, i * header.unitSize); } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Crap (Type); - _hb_compiler_memory_r_barrier (); + hb_barrier (); return StructAtOffset (&bytesZ, i * header.unitSize); } unsigned int get_length () const @@ -1104,6 +1192,7 @@ struct VarSizedBinSearchArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, std::forward (ds)...))) @@ -1130,6 +1219,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); return_trace (header.sanitize (c) && + hb_barrier () && Type::static_size <= header.unitSize && c->check_range (bytesZ.arrayZ, header.nUnits, @@ -1144,6 +1234,800 @@ struct VarSizedBinSearchArrayOf }; +/* CFF INDEX */ + +template +struct CFFIndex +{ + unsigned int offset_array_size () const + { return offSize * (count + 1); } + + template + bool serialize (hb_serialize_context_t *c, + const Iterable &iterable, + const unsigned *p_data_size = nullptr, + unsigned min_off_size = 0) + { + TRACE_SERIALIZE (this); + unsigned data_size; + if (p_data_size) + data_size = *p_data_size; + else + total_size (iterable, &data_size); + + auto it = hb_iter (iterable); + if (unlikely (!serialize_header (c, +it, data_size, min_off_size))) return_trace (false); + unsigned char *ret = c->allocate_size (data_size, false); + if (unlikely (!ret)) return_trace (false); + for (const auto &_ : +it) + { + unsigned len = _.length; + if (!len) + continue; + if (len <= 1) + { + *ret++ = *_.arrayZ; + continue; + } + hb_memcpy (ret, _.arrayZ, len); + ret += len; + } + return_trace (true); + } + + template + bool serialize_header (hb_serialize_context_t *c, + Iterator it, + unsigned data_size, + unsigned min_off_size = 0) + { + TRACE_SERIALIZE (this); + + unsigned off_size = (hb_bit_storage (data_size + 1) + 7) / 8; + off_size = hb_max(min_off_size, off_size); + + /* serialize CFFIndex header */ + if (unlikely (!c->extend_min (this))) return_trace (false); + this->count = hb_len (it); + if (!this->count) return_trace (true); + if (unlikely (!c->extend (this->offSize))) return_trace (false); + this->offSize = off_size; + if (unlikely (!c->allocate_size (off_size * (this->count + 1), false))) + return_trace (false); + + /* serialize indices */ + unsigned int offset = 1; + if (HB_OPTIMIZE_SIZE_VAL) + { + unsigned int i = 0; + for (const auto &_ : +it) + { + set_offset_at (i++, offset); + offset += hb_len_of (_); + } + set_offset_at (i, offset); + } + else + switch (off_size) + { + case 1: + { + HBUINT8 *p = (HBUINT8 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += hb_len_of (_); + } + *p = offset; + } + break; + case 2: + { + HBUINT16 *p = (HBUINT16 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += hb_len_of (_); + } + *p = offset; + } + break; + case 3: + { + HBUINT24 *p = (HBUINT24 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += hb_len_of (_); + } + *p = offset; + } + break; + case 4: + { + HBUINT32 *p = (HBUINT32 *) offsets; + for (const auto &_ : +it) + { + *p++ = offset; + offset += hb_len_of (_); + } + *p = offset; + } + break; + default: + break; + } + + assert (offset == data_size + 1); + return_trace (true); + } + + template + static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr, unsigned min_off_size = 0) + { + auto it = + hb_iter (iterable); + if (!it) + { + if (data_size) *data_size = 0; + return min_size; + } + + unsigned total = 0; + for (const auto &_ : +it) + total += hb_len_of (_); + + if (data_size) *data_size = total; + + unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8; + off_size = hb_max(min_off_size, off_size); + + return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total; + } + + void set_offset_at (unsigned int index, unsigned int offset) + { + assert (index <= count); + + unsigned int size = offSize; + const HBUINT8 *p = offsets; + switch (size) + { + case 1: ((HBUINT8 *) p)[index] = offset; break; + case 2: ((HBUINT16 *) p)[index] = offset; break; + case 3: ((HBUINT24 *) p)[index] = offset; break; + case 4: ((HBUINT32 *) p)[index] = offset; break; + default: return; + } + } + + private: + unsigned int offset_at (unsigned int index) const + { + assert (index <= count); + + unsigned int size = offSize; + const HBUINT8 *p = offsets; + switch (size) + { + case 1: return ((HBUINT8 *) p)[index]; + case 2: return ((HBUINT16 *) p)[index]; + case 3: return ((HBUINT24 *) p)[index]; + case 4: return ((HBUINT32 *) p)[index]; + default: return 0; + } + } + + const unsigned char *data_base () const + { return (const unsigned char *) this + min_size + offSize.static_size - 1 + offset_array_size (); } + public: + + hb_ubytes_t operator [] (unsigned int index) const + { + if (unlikely (index >= count)) return hb_ubytes_t (); + hb_barrier (); + unsigned offset0 = offset_at (index); + unsigned offset1 = offset_at (index + 1); + if (unlikely (offset1 < offset0 || offset1 > offset_at (count))) + return hb_ubytes_t (); + return hb_ubytes_t (data_base () + offset0, offset1 - offset0); + } + + unsigned int get_size () const + { + if (count) + return min_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1); + return min_size; /* empty CFFIndex contains count only */ + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + hb_barrier () && + (count == 0 || /* empty INDEX */ + (count < count + 1u && + c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 && + c->check_array (offsets, offSize, count + 1u) && + c->check_range (data_base (), offset_at (count)))))); + } + + public: + COUNT count; /* Number of object data. Note there are (count+1) offsets */ + private: + HBUINT8 offSize; /* The byte size of each offset in the offsets array. */ + HBUINT8 offsets[HB_VAR_ARRAY]; + /* The array of (count + 1) offsets into objects array (1-base). */ + /* HBUINT8 data[HB_VAR_ARRAY]; Object data */ + public: + DEFINE_SIZE_MIN (COUNT::static_size); +}; +typedef CFFIndex CFF1Index; +typedef CFFIndex CFF2Index; + + +/* TupleValues */ +struct TupleValues +{ + enum packed_value_flag_t + { + VALUES_ARE_ZEROS = 0x80, + VALUES_ARE_BYTES = 0x00, + VALUES_ARE_WORDS = 0x40, + VALUES_ARE_LONGS = 0xC0, + VALUES_SIZE_MASK = 0xC0, + VALUE_RUN_COUNT_MASK = 0x3F + }; + + static unsigned compile (hb_array_t values, /* IN */ + hb_array_t encoded_bytes /* OUT */) + { + unsigned num_values = values.length; + unsigned encoded_len = 0; + unsigned i = 0; + while (i < num_values) + { + int val = values.arrayZ[i]; + if (val == 0) + encoded_len += encode_value_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), values); + else if (val >= -128 && val <= 127) + encoded_len += encode_value_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), values); + else if (val >= -32768 && val <= 32767) + encoded_len += encode_value_run_as_words (i, encoded_bytes.sub_array (encoded_len), values); + else + encoded_len += encode_value_run_as_longs (i, encoded_bytes.sub_array (encoded_len), values); + } + return encoded_len; + } + + static unsigned encode_value_run_as_zeroes (unsigned& i, + hb_array_t encoded_bytes, + hb_array_t values) + { + unsigned num_values = values.length; + unsigned run_length = 0; + auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (i < num_values && values.arrayZ[i] == 0) + { + i++; + run_length++; + } + + while (run_length >= 64) + { + *it++ = char (VALUES_ARE_ZEROS | 63); + run_length -= 64; + encoded_len++; + } + + if (run_length) + { + *it++ = char (VALUES_ARE_ZEROS | (run_length - 1)); + encoded_len++; + } + return encoded_len; + } + + static unsigned encode_value_run_as_bytes (unsigned &i, + hb_array_t encoded_bytes, + hb_array_t values) + { + unsigned start = i; + unsigned num_values = values.length; + while (i < num_values) + { + int val = values.arrayZ[i]; + if (val > 127 || val < -128) + break; + + /* from fonttools: if there're 2 or more zeros in a sequence, + * it is better to start a new run to save bytes. */ + if (val == 0 && i + 1 < num_values && values.arrayZ[i+1] == 0) + break; + + i++; + } + unsigned run_length = i - start; + + unsigned encoded_len = 0; + auto it = encoded_bytes.iter (); + + while (run_length >= 64) + { + *it++ = (VALUES_ARE_BYTES | 63); + encoded_len++; + + for (unsigned j = 0; j < 64; j++) + { + *it++ = static_cast (values.arrayZ[start + j]); + encoded_len++; + } + + start += 64; + run_length -= 64; + } + + if (run_length) + { + *it++ = (VALUES_ARE_BYTES | (run_length - 1)); + encoded_len++; + + while (start < i) + { + *it++ = static_cast (values.arrayZ[start++]); + encoded_len++; + } + } + + return encoded_len; + } + + static unsigned encode_value_run_as_words (unsigned &i, + hb_array_t encoded_bytes, + hb_array_t values) + { + unsigned start = i; + unsigned num_values = values.length; + while (i < num_values) + { + int val = values.arrayZ[i]; + + /* start a new run for a single zero value*/ + if (val == 0) break; + + /* from fonttools: continue word-encoded run if there's only one + * single value in the range [-128, 127] because it is more compact. + * Only start a new run when there're 2 continuous such values. */ + if (val >= -128 && val <= 127 && + i + 1 < num_values && + values.arrayZ[i+1] >= -128 && values.arrayZ[i+1] <= 127) + break; + + i++; + } + + unsigned run_length = i - start; + auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (run_length >= 64) + { + *it++ = (VALUES_ARE_WORDS | 63); + encoded_len++; + + for (unsigned j = 0; j < 64; j++) + { + int16_t value_val = values.arrayZ[start + j]; + *it++ = static_cast (value_val >> 8); + *it++ = static_cast (value_val & 0xFF); + + encoded_len += 2; + } + + start += 64; + run_length -= 64; + } + + if (run_length) + { + *it++ = (VALUES_ARE_WORDS | (run_length - 1)); + encoded_len++; + while (start < i) + { + int16_t value_val = values.arrayZ[start++]; + *it++ = static_cast (value_val >> 8); + *it++ = static_cast (value_val & 0xFF); + + encoded_len += 2; + } + } + return encoded_len; + } + + static unsigned encode_value_run_as_longs (unsigned &i, + hb_array_t encoded_bytes, + hb_array_t values) + { + unsigned start = i; + unsigned num_values = values.length; + while (i < num_values) + { + int val = values.arrayZ[i]; + + if (val >= -32768 && val <= 32767) + break; + + i++; + } + + unsigned run_length = i - start; + auto it = encoded_bytes.iter (); + unsigned encoded_len = 0; + while (run_length >= 64) + { + *it++ = (VALUES_ARE_LONGS | 63); + encoded_len++; + + for (unsigned j = 0; j < 64; j++) + { + int32_t value_val = values.arrayZ[start + j]; + *it++ = static_cast (value_val >> 24); + *it++ = static_cast (value_val >> 16); + *it++ = static_cast (value_val >> 8); + *it++ = static_cast (value_val & 0xFF); + + encoded_len += 4; + } + + start += 64; + run_length -= 64; + } + + if (run_length) + { + *it++ = (VALUES_ARE_LONGS | (run_length - 1)); + encoded_len++; + while (start < i) + { + int32_t value_val = values.arrayZ[start++]; + *it++ = static_cast (value_val >> 24); + *it++ = static_cast (value_val >> 16); + *it++ = static_cast (value_val >> 8); + *it++ = static_cast (value_val & 0xFF); + + encoded_len += 4; + } + } + return encoded_len; + } + + template + static bool decompile (const HBUINT8 *&p /* IN/OUT */, + hb_vector_t &values /* IN/OUT */, + const HBUINT8 *end, + bool consume_all = false) + { + unsigned i = 0; + unsigned count = consume_all ? UINT_MAX : values.length; + if (consume_all) + values.alloc ((end - p) / 2); + while (i < count) + { + if (unlikely (p + 1 > end)) return consume_all; + unsigned control = *p++; + unsigned run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + if (consume_all) + { + if (unlikely (!values.resize (values.length + run_count, false))) + return false; + } + unsigned stop = i + run_count; + if (unlikely (stop > count)) return false; + if ((control & VALUES_SIZE_MASK) == VALUES_ARE_ZEROS) + { + for (; i < stop; i++) + values.arrayZ[i] = 0; + } + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_WORDS) + { + if (unlikely (p + run_count * HBINT16::static_size > end)) return false; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { + values.arrayZ[i] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 1] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 2] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 3] = * (const HBINT16 *) p; + p += HBINT16::static_size; + } +#endif + for (; i < stop; i++) + { + values.arrayZ[i] = * (const HBINT16 *) p; + p += HBINT16::static_size; + } + } + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_LONGS) + { + if (unlikely (p + run_count * HBINT32::static_size > end)) return false; + for (; i < stop; i++) + { + values.arrayZ[i] = * (const HBINT32 *) p; + p += HBINT32::static_size; + } + } + else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_BYTES) + { + if (unlikely (p + run_count > end)) return false; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { + values.arrayZ[i] = * (const HBINT8 *) p++; + values.arrayZ[i + 1] = * (const HBINT8 *) p++; + values.arrayZ[i + 2] = * (const HBINT8 *) p++; + values.arrayZ[i + 3] = * (const HBINT8 *) p++; + } +#endif + for (; i < stop; i++) + values.arrayZ[i] = * (const HBINT8 *) p++; + } + } + return true; + } + + struct iter_t : hb_iter_with_fallback_t + { + iter_t (const unsigned char *p_, unsigned len_) + : p (p_), endp (p_ + len_) + { if (ensure_run ()) read_value (); } + + private: + const unsigned char *p; + const unsigned char * const endp; + int current_value = 0; + signed run_count = 0; + unsigned width = 0; + + bool ensure_run () + { + if (likely (run_count > 0)) return true; + + if (unlikely (p >= endp)) + { + run_count = 0; + current_value = 0; + return false; + } + + unsigned control = *p++; + run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + width = control & VALUES_SIZE_MASK; + switch (width) + { + case VALUES_ARE_ZEROS: width = 0; break; + case VALUES_ARE_BYTES: width = HBINT8::static_size; break; + case VALUES_ARE_WORDS: width = HBINT16::static_size; break; + case VALUES_ARE_LONGS: width = HBINT32::static_size; break; + default: assert (false); + } + + if (unlikely (p + run_count * width > endp)) + { + run_count = 0; + current_value = 0; + return false; + } + + return true; + } + void read_value () + { + switch (width) + { + case 0: current_value = 0; break; + case 1: current_value = * (const HBINT8 *) p; break; + case 2: current_value = * (const HBINT16 *) p; break; + case 4: current_value = * (const HBINT32 *) p; break; + } + p += width; + } + + public: + + typedef int __item_t__; + __item_t__ __item__ () const + { return current_value; } + + bool __more__ () const { return run_count || p < endp; } + void __next__ () + { + run_count--; + if (unlikely (!ensure_run ())) + return; + read_value (); + } + void __forward__ (unsigned n) + { + if (unlikely (!ensure_run ())) + return; + while (n) + { + unsigned i = hb_min (n, (unsigned) run_count); + run_count -= i; + n -= i; + p += (i - 1) * width; + if (unlikely (!ensure_run ())) + return; + read_value (); + } + } + bool operator != (const iter_t& o) const + { return p != o.p || run_count != o.run_count; } + iter_t __end__ () const + { + iter_t it (endp, 0); + return it; + } + }; + + struct fetcher_t + { + fetcher_t (const unsigned char *p_, unsigned len_) + : p (p_), end (p_ + len_) {} + + private: + const unsigned char *p; + const unsigned char * const end; + signed run_count = 0; + unsigned width = 0; + + bool ensure_run () + { + if (likely (run_count > 0)) return true; + + if (unlikely (p >= end)) + { + run_count = 0; + return false; + } + + unsigned control = *p++; + run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + width = control & VALUES_SIZE_MASK; + switch (width) + { + case VALUES_ARE_ZEROS: width = 0; break; + case VALUES_ARE_BYTES: width = HBINT8::static_size; break; + case VALUES_ARE_WORDS: width = HBINT16::static_size; break; + case VALUES_ARE_LONGS: width = HBINT32::static_size; break; + default: assert (false); + } + + if (unlikely (p + run_count * width > end)) + { + run_count = 0; + return false; + } + + return true; + } + + void skip (unsigned n) + { + while (n) + { + if (unlikely (!ensure_run ())) + return; + unsigned i = hb_min (n, (unsigned) run_count); + run_count -= i; + n -= i; + p += i * width; + } + } + + template + void _add_to (hb_array_t out, float scale = 1.0f) + { + unsigned n = out.length; + float *arrayZ = out.arrayZ; + + for (unsigned i = 0; i < n;) + { + if (unlikely (!ensure_run ())) + break; + unsigned count = hb_min (n - i, (unsigned) run_count); + switch (width) + { + case 1: + { + const auto *pp = (const HBINT8 *) p; + unsigned j = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; j + 3 < count; j += 4) + { + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } +#endif + for (; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + case 2: + { + const auto *pp = (const HBINT16 *) p; + unsigned j = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; j + 3 < count; j += 4) + { + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } +#endif + for (; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + case 4: + { + const auto *pp = (const HBINT32 *) p; + for (unsigned j = 0; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } + break; + } + p += count * width; + run_count -= count; + i += count; + } + } + + public: + void add_to (hb_array_t out, float scale = 1.0f) + { + unsigned n = out.length; + + if (scale == 0.0f) + { + skip (n); + return; + } + +#ifndef HB_OPTIMIZE_SIZE + if (scale == 1.0f) + _add_to (out); + else +#endif + _add_to (out, scale); + } + }; +}; + +struct TupleList : CFF2Index +{ + TupleValues::iter_t operator [] (unsigned i) const + { + auto bytes = CFF2Index::operator [] (i); + return TupleValues::iter_t (bytes.arrayZ, bytes.length); + } + + TupleValues::fetcher_t fetcher (unsigned i) const + { + auto bytes = CFF2Index::operator [] (i); + return TupleValues::fetcher_t (bytes.arrayZ, bytes.length); + } +}; + + } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh index 081c333f50f..1e3e0be5106 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh @@ -41,10 +41,21 @@ using namespace OT; using objidx_t = hb_serialize_context_t::objidx_t; using whence_t = hb_serialize_context_t::whence_t; -/* utility macro */ -template -static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset) -{ return offset ? StructAtOffset (P, offset) : Null (Type); } +/* CFF offsets can technically be negative */ +template +static inline const Type& StructAtOffsetOrNull (const void *P, int offset, hb_sanitize_context_t &sc, Ts&&... ds) +{ + if (!offset) return Null (Type); + + const char *p = (const char *) P + offset; + if (!sc.check_point (p)) return Null (Type); + + const Type &obj = *reinterpret_cast (p); + if (!obj.sanitize (&sc, std::forward (ds)...)) return Null (Type); + + return obj; +} + struct code_pair_t { @@ -57,241 +68,6 @@ using str_buff_t = hb_vector_t; using str_buff_vec_t = hb_vector_t; using glyph_to_sid_map_t = hb_vector_t; -struct length_f_t -{ - template - unsigned operator () (const Iterable &_) const { return hb_len (hb_iter (_)); } - - unsigned operator () (unsigned _) const { return _; } -} -HB_FUNCOBJ (length_f); - -/* CFF INDEX */ -template -struct CFFIndex -{ - unsigned int offset_array_size () const - { return offSize * (count + 1); } - - template - bool serialize (hb_serialize_context_t *c, - const Iterable &iterable, - const unsigned *p_data_size = nullptr) - { - TRACE_SERIALIZE (this); - unsigned data_size; - if (p_data_size) - data_size = *p_data_size; - else - total_size (iterable, &data_size); - - auto it = hb_iter (iterable); - if (unlikely (!serialize_header (c, +it, data_size))) return_trace (false); - unsigned char *ret = c->allocate_size (data_size, false); - if (unlikely (!ret)) return_trace (false); - for (const auto &_ : +it) - { - unsigned len = _.length; - if (!len) - continue; - if (len <= 1) - { - *ret++ = *_.arrayZ; - continue; - } - hb_memcpy (ret, _.arrayZ, len); - ret += len; - } - return_trace (true); - } - - template - bool serialize_header (hb_serialize_context_t *c, - Iterator it, - unsigned data_size) - { - TRACE_SERIALIZE (this); - - unsigned off_size = (hb_bit_storage (data_size + 1) + 7) / 8; - - /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (this))) return_trace (false); - this->count = hb_len (it); - if (!this->count) return_trace (true); - if (unlikely (!c->extend (this->offSize))) return_trace (false); - this->offSize = off_size; - if (unlikely (!c->allocate_size (off_size * (this->count + 1), false))) - return_trace (false); - - /* serialize indices */ - unsigned int offset = 1; - if (HB_OPTIMIZE_SIZE_VAL) - { - unsigned int i = 0; - for (const auto &_ : +it) - { - set_offset_at (i++, offset); - offset += length_f (_); - } - set_offset_at (i, offset); - } - else - switch (off_size) - { - case 1: - { - HBUINT8 *p = (HBUINT8 *) offsets; - for (const auto &_ : +it) - { - *p++ = offset; - offset += length_f (_); - } - *p = offset; - } - break; - case 2: - { - HBUINT16 *p = (HBUINT16 *) offsets; - for (const auto &_ : +it) - { - *p++ = offset; - offset += length_f (_); - } - *p = offset; - } - break; - case 3: - { - HBUINT24 *p = (HBUINT24 *) offsets; - for (const auto &_ : +it) - { - *p++ = offset; - offset += length_f (_); - } - *p = offset; - } - break; - case 4: - { - HBUINT32 *p = (HBUINT32 *) offsets; - for (const auto &_ : +it) - { - *p++ = offset; - offset += length_f (_); - } - *p = offset; - } - break; - default: - break; - } - - assert (offset == data_size + 1); - return_trace (true); - } - - template - static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr) - { - auto it = + hb_iter (iterable); - if (!it) - { - if (data_size) *data_size = 0; - return min_size; - } - - unsigned total = 0; - for (const auto &_ : +it) - total += length_f (_); - - if (data_size) *data_size = total; - - unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8; - - return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total; - } - - void set_offset_at (unsigned int index, unsigned int offset) - { - assert (index <= count); - - unsigned int size = offSize; - const HBUINT8 *p = offsets; - switch (size) - { - case 1: ((HBUINT8 *) p)[index] = offset; break; - case 2: ((HBUINT16 *) p)[index] = offset; break; - case 3: ((HBUINT24 *) p)[index] = offset; break; - case 4: ((HBUINT32 *) p)[index] = offset; break; - default: return; - } - } - - private: - unsigned int offset_at (unsigned int index) const - { - assert (index <= count); - - unsigned int size = offSize; - const HBUINT8 *p = offsets; - switch (size) - { - case 1: return ((HBUINT8 *) p)[index]; - case 2: return ((HBUINT16 *) p)[index]; - case 3: return ((HBUINT24 *) p)[index]; - case 4: return ((HBUINT32 *) p)[index]; - default: return 0; - } - } - - const unsigned char *data_base () const - { return (const unsigned char *) this + min_size + offSize.static_size - 1 + offset_array_size (); } - public: - - hb_ubytes_t operator [] (unsigned int index) const - { - if (unlikely (index >= count)) return hb_ubytes_t (); - _hb_compiler_memory_r_barrier (); - unsigned offset0 = offset_at (index); - unsigned offset1 = offset_at (index + 1); - if (unlikely (offset1 < offset0 || offset1 > offset_at (count))) - return hb_ubytes_t (); - return hb_ubytes_t (data_base () + offset0, offset1 - offset0); - } - - unsigned int get_size () const - { - if (count) - return min_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1); - return min_size; /* empty CFFIndex contains count only */ - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (count == 0 || /* empty INDEX */ - (count < count + 1u && - c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 && - c->check_array (offsets, offSize, count + 1u) && - c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count)))))); - } - - public: - COUNT count; /* Number of object data. Note there are (count+1) offsets */ - private: - HBUINT8 offSize; /* The byte size of each offset in the offsets array. */ - HBUINT8 offsets[HB_VAR_ARRAY]; - /* The array of (count + 1) offsets into objects array (1-base). */ - /* HBUINT8 data[HB_VAR_ARRAY]; Object data */ - public: - DEFINE_SIZE_MIN (COUNT::static_size); -}; - /* Top Dict, Font Dict, Private Dict */ struct Dict : UnsizedByteStr { @@ -412,6 +188,7 @@ struct FDSelect0 { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this)))) return_trace (false); + hb_barrier (); if (unlikely (!c->check_array (fds, c->get_num_glyphs ()))) return_trace (false); @@ -438,7 +215,9 @@ struct FDSelect3_4_Range bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const { TRACE_SANITIZE (this); - return_trace (first < c->get_num_glyphs () && (fd < fdcount)); + return_trace (c->check_struct (this) && + hb_barrier () && + first < c->get_num_glyphs () && (fd < fdcount)); } GID_TYPE first; @@ -456,15 +235,20 @@ struct FDSelect3_4 bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) || - (nRanges () == 0) || ranges[0].first != 0)) + if (unlikely (!(c->check_struct (this) && + ranges.sanitize (c, nullptr, fdcount) && + hb_barrier () && + (nRanges () != 0) && + ranges[0].first == 0))) return_trace (false); for (unsigned int i = 1; i < nRanges (); i++) if (unlikely (ranges[i - 1].first >= ranges[i].first)) return_trace (false); - if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ()))) + if (unlikely (!(sentinel().sanitize (c) && + hb_barrier () && + (sentinel() == c->get_num_glyphs ())))) return_trace (false); return_trace (true); @@ -524,8 +308,8 @@ struct FDSelect { switch (format) { - case 0: return format.static_size + u.format0.get_size (num_glyphs); - case 3: return format.static_size + u.format3.get_size (); + case 0: hb_barrier (); return format.static_size + u.format0.get_size (num_glyphs); + case 3: hb_barrier (); return format.static_size + u.format3.get_size (); default:return 0; } } @@ -536,8 +320,8 @@ struct FDSelect switch (format) { - case 0: return u.format0.get_fd (glyph); - case 3: return u.format3.get_fd (glyph); + case 0: hb_barrier (); return u.format0.get_fd (glyph); + case 3: hb_barrier (); return u.format3.get_fd (glyph); default:return 0; } } @@ -548,8 +332,8 @@ struct FDSelect switch (format) { - case 0: return u.format0.get_fd_range (glyph); - case 3: return u.format3.get_fd_range (glyph); + case 0: hb_barrier (); return u.format0.get_fd_range (glyph); + case 3: hb_barrier (); return u.format3.get_fd_range (glyph); default:return {0, 1}; } } @@ -559,11 +343,12 @@ struct FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, fdcount)); - case 3: return_trace (u.format3.sanitize (c, fdcount)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, fdcount)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c, fdcount)); default:return_trace (false); } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc index 6fcc8c46587..b06936f94c8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc @@ -553,15 +553,6 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin return true; } -bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const -{ - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; -} - bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const { #ifdef HB_NO_OT_FONT_CFF diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh index d1310c66fde..0116a0c9192 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh @@ -51,9 +51,6 @@ namespace CFF { enum EncodingID { StandardEncoding = 0, ExpertEncoding = 1 }; enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 }; -typedef CFFIndex CFF1Index; - -typedef CFFIndex CFF1Index; typedef CFF1Index CFF1CharStrings; typedef Subrs CFF1Subrs; @@ -242,8 +239,8 @@ struct Encoding unsigned int size = min_size; switch (table_format ()) { - case 0: size += u.format0.get_size (); break; - case 1: size += u.format1.get_size (); break; + case 0: hb_barrier (); size += u.format0.get_size (); break; + case 1: hb_barrier (); size += u.format1.get_size (); break; } if (has_supplement ()) size += suppEncData ().get_size (); @@ -254,8 +251,8 @@ struct Encoding { switch (table_format ()) { - case 0: return u.format0.get_code (glyph); - case 1: return u.format1.get_code (glyph); + case 0: hb_barrier (); return u.format0.get_code (glyph); + case 1: hb_barrier (); return u.format1.get_code (glyph); default:return 0; } } @@ -275,11 +272,12 @@ struct Encoding TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (table_format ()) { - case 0: if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break; - case 1: if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break; + case 0: hb_barrier (); if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break; + case 1: hb_barrier (); if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break; default:return_trace (false); } return_trace (likely (!has_supplement () || suppEncData ().sanitize (c))); @@ -290,8 +288,8 @@ struct Encoding { switch (table_format ()) { - case 0: return StructAfter (u.format0.codes[u.format0.nCodes ()-1]); - case 1: return StructAfter (u.format1.ranges[u.format1.nRanges ()-1]); + case 0: hb_barrier (); return StructAfter (u.format0.codes[u.format0.nCodes ()-1]); + case 1: hb_barrier (); return StructAfter (u.format1.ranges[u.format1.nRanges ()-1]); default:return Null (CFF1SuppEncData); } } @@ -376,13 +374,13 @@ struct Charset1_2 { bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); num_glyphs--; unsigned i; for (i = 0; num_glyphs > 0; i++) { - if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1))) + if (unlikely (!(ranges[i].sanitize (c) && + hb_barrier () && + (num_glyphs >= ranges[i].nLeft + 1)))) return_trace (false); num_glyphs -= (ranges[i].nLeft + 1); } @@ -569,9 +567,9 @@ struct Charset { switch (format) { - case 0: return min_size + u.format0.get_size (num_glyphs); - case 1: return min_size + u.format1.get_size (num_glyphs); - case 2: return min_size + u.format2.get_size (num_glyphs); + case 0: hb_barrier (); return min_size + u.format0.get_size (num_glyphs); + case 1: hb_barrier (); return min_size + u.format1.get_size (num_glyphs); + case 2: hb_barrier (); return min_size + u.format2.get_size (num_glyphs); default:return 0; } } @@ -581,9 +579,9 @@ struct Charset { switch (format) { - case 0: return u.format0.get_sid (glyph, num_glyphs); - case 1: return u.format1.get_sid (glyph, num_glyphs, cache); - case 2: return u.format2.get_sid (glyph, num_glyphs, cache); + case 0: hb_barrier (); return u.format0.get_sid (glyph, num_glyphs); + case 1: hb_barrier (); return u.format1.get_sid (glyph, num_glyphs, cache); + case 2: hb_barrier (); return u.format2.get_sid (glyph, num_glyphs, cache); default:return 0; } } @@ -592,9 +590,9 @@ struct Charset { switch (format) { - case 0: u.format0.collect_glyph_to_sid_map (mapping, num_glyphs); return; - case 1: u.format1.collect_glyph_to_sid_map (mapping, num_glyphs); return; - case 2: u.format2.collect_glyph_to_sid_map (mapping, num_glyphs); return; + case 0: hb_barrier (); u.format0.collect_glyph_to_sid_map (mapping, num_glyphs); return; + case 1: hb_barrier (); u.format1.collect_glyph_to_sid_map (mapping, num_glyphs); return; + case 2: hb_barrier (); u.format2.collect_glyph_to_sid_map (mapping, num_glyphs); return; default:return; } } @@ -603,9 +601,9 @@ struct Charset { switch (format) { - case 0: return u.format0.get_glyph (sid, num_glyphs); - case 1: return u.format1.get_glyph (sid, num_glyphs); - case 2: return u.format2.get_glyph (sid, num_glyphs); + case 0: hb_barrier (); return u.format0.get_glyph (sid, num_glyphs); + case 1: hb_barrier (); return u.format1.get_glyph (sid, num_glyphs); + case 2: hb_barrier (); return u.format2.get_glyph (sid, num_glyphs); default:return 0; } } @@ -615,12 +613,13 @@ struct Charset TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs (), num_charset_entries)); - case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs (), num_charset_entries)); - case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c, c->get_num_glyphs (), num_charset_entries)); default:return_trace (false); } } @@ -761,9 +760,9 @@ struct cff1_top_dict_values_t : top_dict_values_t unsigned int ros_supplement; unsigned int cidCount; - unsigned int EncodingOffset; - unsigned int CharsetOffset; - unsigned int FDSelectOffset; + int EncodingOffset; + int CharsetOffset; + int FDSelectOffset; table_info_t privateDictInfo; }; @@ -819,24 +818,24 @@ struct cff1_top_dict_opset_t : top_dict_opset_t break; case OpCode_Encoding: - dictval.EncodingOffset = env.argStack.pop_uint (); + dictval.EncodingOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.EncodingOffset == 0)) return; break; case OpCode_charset: - dictval.CharsetOffset = env.argStack.pop_uint (); + dictval.CharsetOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.CharsetOffset == 0)) return; break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_Private: - dictval.privateDictInfo.offset = env.argStack.pop_uint (); + dictval.privateDictInfo.offset = env.argStack.pop_int (); dictval.privateDictInfo.size = env.argStack.pop_uint (); env.clear_args (); break; @@ -911,7 +910,7 @@ struct cff1_private_dict_values_base_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF1Subrs *localSubrs; }; @@ -946,7 +945,7 @@ struct cff1_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -988,7 +987,7 @@ struct cff1_private_dict_opset_subset_t : dict_opset_t break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -1055,6 +1054,7 @@ struct cff1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 1)); } @@ -1085,14 +1085,17 @@ struct cff1 nameIndex = &cff->nameIndex (cff); if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc)) goto fail; + hb_barrier (); - topDictIndex = &StructAtOffset (nameIndex, nameIndex->get_size ()); - if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) + topDictIndex = &StructAtOffsetOrNull (nameIndex, nameIndex->get_size (), sc); + if (topDictIndex == &Null (CFF1TopDictIndex) || (topDictIndex->count == 0)) goto fail; + hb_barrier (); { /* parse top dict */ const hb_ubytes_t topDictStr = (*topDictIndex)[0]; if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff1_top_dict_interp_env_t env (topDictStr); cff1_top_dict_interpreter_t top_interp (env); if (unlikely (!top_interp.interpret (topDict))) goto fail; @@ -1102,17 +1105,17 @@ struct cff1 charset = &Null (Charset); else { - charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset); - if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries))) goto fail; + charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset, sc, &num_charset_entries); + if (unlikely (charset == &Null (Charset))) goto fail; } fdCount = 1; if (is_CID ()) { - fdArray = &StructAtOffsetOrNull (cff, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull (cff, topDict.FDSelectOffset); - if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) || - (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) + fdArray = &StructAtOffsetOrNull (cff, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull (cff, topDict.FDSelectOffset, sc, fdArray->count); + if (unlikely (fdArray == &Null (CFF1FDArray) || + fdSelect == &Null (CFF1FDSelect))) goto fail; fdCount = fdArray->count; @@ -1132,22 +1135,18 @@ struct cff1 { if (!is_predef_encoding ()) { - encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset); - if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) goto fail; + encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset, sc); + if (unlikely (encoding == &Null (Encoding))) goto fail; } } - stringIndex = &StructAtOffset (topDictIndex, topDictIndex->get_size ()); - if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) + stringIndex = &StructAtOffsetOrNull (topDictIndex, topDictIndex->get_size (), sc); + if (stringIndex == &Null (CFF1StringIndex)) goto fail; - globalSubrs = &StructAtOffset (stringIndex, stringIndex->get_size ()); - if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) - goto fail; - - charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset); - - if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) + globalSubrs = &StructAtOffsetOrNull (stringIndex, stringIndex->get_size (), sc); + charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset, sc); + if (charStrings == &Null (CFF1CharStrings)) goto fail; num_glyphs = charStrings->count; @@ -1166,6 +1165,7 @@ struct cff1 { hb_ubytes_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff1_font_dict_values_t *font; cff1_top_dict_interp_env_t env (fontDictStr); cff1_font_dict_interpreter_t font_interp (env); @@ -1175,17 +1175,14 @@ struct cff1 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; - const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); priv->init (); if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null (CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - goto fail; + priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset, sc); } } else /* non-CID */ @@ -1193,17 +1190,15 @@ struct cff1 cff1_top_dict_values_t *font = &topDict; PRIVDICTVAL *priv = &privateDicts[0]; - const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env (privDictStr); dict_interpreter_t priv_interp (env); priv->init (); if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null (CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - goto fail; + priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset, sc); + hb_barrier (); } return; @@ -1420,7 +1415,7 @@ struct cff1 hb_sorted_vector_t *names = glyph_names.get_acquire (); if (unlikely (!names)) { - names = (hb_sorted_vector_t *) hb_calloc (sizeof (hb_sorted_vector_t), 1); + names = (hb_sorted_vector_t *) hb_calloc (1, sizeof (hb_sorted_vector_t)); if (likely (names)) { names->init (); @@ -1467,7 +1462,6 @@ struct cff1 } HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; private: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc index ed430ee59d5..fce39da21ce 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.cc @@ -143,15 +143,6 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, return true; } -bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const -{ - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; -} - struct cff2_path_param_t { cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_) @@ -202,6 +193,11 @@ struct cff2_path_procs_path_t : path_procs_t {}; bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const +{ + return get_path_at (font, glyph, draw_session, hb_array (font->coords, font->num_coords)); +} + +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 { #ifdef HB_NO_OT_FONT_CFF /* XXX Remove check when this code moves to .hh file. */ @@ -212,7 +208,7 @@ bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, h unsigned int fd = fdSelect->get_fd (glyph); const hb_ubytes_t str = (*charStrings)[glyph]; - cff2_cs_interp_env_t env (str, *this, fd, font->coords, font->num_coords); + cff2_cs_interp_env_t env (str, *this, fd, coords.arrayZ, coords.length); cff2_cs_interpreter_t interp (env); cff2_path_param_t param (font, draw_session); if (unlikely (!interp.interpret (param))) return false; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh index db10f22ec52..81d30f57a28 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh @@ -40,8 +40,6 @@ namespace CFF { */ #define HB_OT_TAG_CFF2 HB_TAG('C','F','F','2') -typedef CFFIndex CFF2Index; - typedef CFF2Index CFF2CharStrings; typedef Subrs CFF2Subrs; @@ -64,9 +62,9 @@ struct CFF2FDSelect { switch (format) { - case 0: return format.static_size + u.format0.get_size (num_glyphs); - case 3: return format.static_size + u.format3.get_size (); - case 4: return format.static_size + u.format4.get_size (); + case 0: hb_barrier (); return format.static_size + u.format0.get_size (num_glyphs); + case 3: hb_barrier (); return format.static_size + u.format3.get_size (); + case 4: hb_barrier (); return format.static_size + u.format4.get_size (); default:return 0; } } @@ -78,9 +76,9 @@ struct CFF2FDSelect switch (format) { - case 0: return u.format0.get_fd (glyph); - case 3: return u.format3.get_fd (glyph); - case 4: return u.format4.get_fd (glyph); + case 0: hb_barrier (); return u.format0.get_fd (glyph); + case 3: hb_barrier (); return u.format3.get_fd (glyph); + case 4: hb_barrier (); return u.format4.get_fd (glyph); default:return 0; } } @@ -90,12 +88,13 @@ struct CFF2FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, fdcount)); - case 3: return_trace (u.format3.sanitize (c, fdcount)); - case 4: return_trace (u.format4.sanitize (c, fdcount)); + case 0: hb_barrier (); return_trace (u.format0.sanitize (c, fdcount)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c, fdcount)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c, fdcount)); default:return_trace (false); } } @@ -110,19 +109,22 @@ struct CFF2FDSelect DEFINE_SIZE_MIN (2); }; -struct CFF2VariationStore +struct CFF2ItemVariationStore { bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this)) && c->check_range (&varStore, size) && varStore.sanitize (c)); + return_trace (c->check_struct (this) && + hb_barrier () && + c->check_range (&varStore, size) && + varStore.sanitize (c)); } - bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore) + bool serialize (hb_serialize_context_t *c, const CFF2ItemVariationStore *varStore) { TRACE_SERIALIZE (this); unsigned int size_ = varStore->get_size (); - CFF2VariationStore *dest = c->allocate_size (size_); + CFF2ItemVariationStore *dest = c->allocate_size (size_); if (unlikely (!dest)) return_trace (false); hb_memcpy (dest, varStore, size_); return_trace (true); @@ -131,9 +133,9 @@ struct CFF2VariationStore unsigned int get_size () const { return HBUINT16::static_size + size; } HBUINT16 size; - VariationStore varStore; + ItemVariationStore varStore; - DEFINE_SIZE_MIN (2 + VariationStore::min_size); + DEFINE_SIZE_MIN (2 + ItemVariationStore::min_size); }; struct cff2_top_dict_values_t : top_dict_values_t<> @@ -146,8 +148,8 @@ struct cff2_top_dict_values_t : top_dict_values_t<> } void fini () { top_dict_values_t<>::fini (); } - unsigned int vstoreOffset; - unsigned int FDSelectOffset; + int vstoreOffset; + int FDSelectOffset; }; struct cff2_top_dict_opset_t : top_dict_opset_t<> @@ -165,11 +167,11 @@ struct cff2_top_dict_opset_t : top_dict_opset_t<> break; case OpCode_vstore: - dictval.vstoreOffset = env.argStack.pop_uint (); + dictval.vstoreOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -237,7 +239,7 @@ struct cff2_private_dict_values_base_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF2Subrs *localSubrs; unsigned int ivs; }; @@ -291,7 +293,7 @@ struct cff2_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_vsindexdict: @@ -340,7 +342,7 @@ struct cff2_private_dict_opset_subset_t : dict_opset_t return; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -384,6 +386,7 @@ struct cff2 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2)); } @@ -414,23 +417,22 @@ struct cff2 { /* parse top dict */ hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize); if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); num_interp_env_t env (topDictStr); cff2_top_dict_interpreter_t top_interp (env); topDict.init (); if (unlikely (!top_interp.interpret (topDict))) goto fail; } - globalSubrs = &StructAtOffset (cff2, cff2->topDict + cff2->topDictSize); - varStore = &StructAtOffsetOrNull (cff2, topDict.vstoreOffset); - charStrings = &StructAtOffsetOrNull (cff2, topDict.charStringsOffset); - fdArray = &StructAtOffsetOrNull (cff2, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull (cff2, topDict.FDSelectOffset); - - if (((varStore != &Null (CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) || - (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) || - (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) || - (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) || - (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) + globalSubrs = &StructAtOffsetOrNull (cff2, cff2->topDict + cff2->topDictSize, sc); + varStore = &StructAtOffsetOrNull (cff2, topDict.vstoreOffset, sc); + charStrings = &StructAtOffsetOrNull (cff2, topDict.charStringsOffset, sc); + fdArray = &StructAtOffsetOrNull (cff2, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull (cff2, topDict.FDSelectOffset, sc, fdArray->count); + + if (charStrings == &Null (CFF2CharStrings) || + globalSubrs == &Null (CFF2Subrs) || + fdArray == &Null (CFF2FDArray)) goto fail; num_glyphs = charStrings->count; @@ -446,6 +448,7 @@ struct cff2 { const hb_ubytes_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff2_font_dict_values_t *font; num_interp_env_t env (fontDictStr); cff2_font_dict_interpreter_t font_interp (env); @@ -454,17 +457,14 @@ struct cff2 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; - const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); privateDicts[i].init (); if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail; - privateDicts[i].localSubrs = &StructAtOffsetOrNull (&privDictStr[0], privateDicts[i].subrsOffset); - if (privateDicts[i].localSubrs != &Null (CFF2Subrs) && - unlikely (!privateDicts[i].localSubrs->sanitize (&sc))) - goto fail; + privateDicts[i].localSubrs = &StructAtOffsetOrNull (&privDictStr[0], privateDicts[i].subrsOffset, sc); } return; @@ -499,7 +499,7 @@ struct cff2 hb_blob_t *blob = nullptr; cff2_top_dict_values_t topDict; const CFF2Subrs *globalSubrs = nullptr; - const CFF2VariationStore *varStore = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; const CFF2CharStrings *charStrings = nullptr; const CFF2FDArray *fdArray = nullptr; const CFF2FDSelect *fdSelect = nullptr; @@ -518,8 +518,8 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; + HB_INTERNAL bool get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t coords) const; }; struct accelerator_subset_t : accelerator_templ_t diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh index 7e6ced3df4c..249d4cac5db 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh @@ -41,6 +41,148 @@ namespace OT { +static inline uint8_t unicode_to_macroman (hb_codepoint_t u) +{ + static const struct unicode_to_macroman_t + { + uint16_t unicode; + uint8_t macroman; + } + mapping[] = + { + { 0x00A0, 0xCA }, + { 0x00A1, 0xC1 }, + { 0x00A2, 0xA2 }, + { 0x00A3, 0xA3 }, + { 0x00A5, 0xB4 }, + { 0x00A7, 0xA4 }, + { 0x00A8, 0xAC }, + { 0x00A9, 0xA9 }, + { 0x00AA, 0xBB }, + { 0x00AB, 0xC7 }, + { 0x00AC, 0xC2 }, + { 0x00AE, 0xA8 }, + { 0x00AF, 0xF8 }, + { 0x00B0, 0xA1 }, + { 0x00B1, 0xB1 }, + { 0x00B4, 0xAB }, + { 0x00B5, 0xB5 }, + { 0x00B6, 0xA6 }, + { 0x00B7, 0xE1 }, + { 0x00B8, 0xFC }, + { 0x00BA, 0xBC }, + { 0x00BB, 0xC8 }, + { 0x00BF, 0xC0 }, + { 0x00C0, 0xCB }, + { 0x00C1, 0xE7 }, + { 0x00C2, 0xE5 }, + { 0x00C3, 0xCC }, + { 0x00C4, 0x80 }, + { 0x00C5, 0x81 }, + { 0x00C6, 0xAE }, + { 0x00C7, 0x82 }, + { 0x00C8, 0xE9 }, + { 0x00C9, 0x83 }, + { 0x00CA, 0xE6 }, + { 0x00CB, 0xE8 }, + { 0x00CC, 0xED }, + { 0x00CD, 0xEA }, + { 0x00CE, 0xEB }, + { 0x00CF, 0xEC }, + { 0x00D1, 0x84 }, + { 0x00D2, 0xF1 }, + { 0x00D3, 0xEE }, + { 0x00D4, 0xEF }, + { 0x00D5, 0xCD }, + { 0x00D6, 0x85 }, + { 0x00D8, 0xAF }, + { 0x00D9, 0xF4 }, + { 0x00DA, 0xF2 }, + { 0x00DB, 0xF3 }, + { 0x00DC, 0x86 }, + { 0x00DF, 0xA7 }, + { 0x00E0, 0x88 }, + { 0x00E1, 0x87 }, + { 0x00E2, 0x89 }, + { 0x00E3, 0x8B }, + { 0x00E4, 0x8A }, + { 0x00E5, 0x8C }, + { 0x00E6, 0xBE }, + { 0x00E7, 0x8D }, + { 0x00E8, 0x8F }, + { 0x00E9, 0x8E }, + { 0x00EA, 0x90 }, + { 0x00EB, 0x91 }, + { 0x00EC, 0x93 }, + { 0x00ED, 0x92 }, + { 0x00EE, 0x94 }, + { 0x00EF, 0x95 }, + { 0x00F1, 0x96 }, + { 0x00F2, 0x98 }, + { 0x00F3, 0x97 }, + { 0x00F4, 0x99 }, + { 0x00F5, 0x9B }, + { 0x00F6, 0x9A }, + { 0x00F7, 0xD6 }, + { 0x00F8, 0xBF }, + { 0x00F9, 0x9D }, + { 0x00FA, 0x9C }, + { 0x00FB, 0x9E }, + { 0x00FC, 0x9F }, + { 0x00FF, 0xD8 }, + { 0x0131, 0xF5 }, + { 0x0152, 0xCE }, + { 0x0153, 0xCF }, + { 0x0178, 0xD9 }, + { 0x0192, 0xC4 }, + { 0x02C6, 0xF6 }, + { 0x02C7, 0xFF }, + { 0x02D8, 0xF9 }, + { 0x02D9, 0xFA }, + { 0x02DA, 0xFB }, + { 0x02DB, 0xFE }, + { 0x02DC, 0xF7 }, + { 0x02DD, 0xFD }, + { 0x03A9, 0xBD }, + { 0x03C0, 0xB9 }, + { 0x2013, 0xD0 }, + { 0x2014, 0xD1 }, + { 0x2018, 0xD4 }, + { 0x2019, 0xD5 }, + { 0x201A, 0xE2 }, + { 0x201C, 0xD2 }, + { 0x201D, 0xD3 }, + { 0x201E, 0xE3 }, + { 0x2020, 0xA0 }, + { 0x2021, 0xE0 }, + { 0x2022, 0xA5 }, + { 0x2026, 0xC9 }, + { 0x2030, 0xE4 }, + { 0x2039, 0xDC }, + { 0x203A, 0xDD }, + { 0x2044, 0xDA }, + { 0x20AC, 0xDB }, + { 0x2122, 0xAA }, + { 0x2202, 0xB6 }, + { 0x2206, 0xC6 }, + { 0x220F, 0xB8 }, + { 0x2211, 0xB7 }, + { 0x221A, 0xC3 }, + { 0x221E, 0xB0 }, + { 0x222B, 0xBA }, + { 0x2248, 0xC5 }, + { 0x2260, 0xAD }, + { 0x2264, 0xB2 }, + { 0x2265, 0xB3 }, + { 0x25CA, 0xD7 }, + { 0xF8FF, 0xF0 }, + { 0xFB01, 0xDE }, + { 0xFB02, 0xDF }, + }; + auto *c = hb_bsearch (u, mapping, ARRAY_LENGTH (mapping), sizeof (mapping[0]), + _hb_cmp_operator); + return c ? c->macroman : 0; +} struct CmapSubtableFormat0 { @@ -556,6 +698,7 @@ struct CmapSubtableFormat4 TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); if (unlikely (!c->check_range (this, length))) { @@ -742,10 +885,11 @@ struct CmapSubtableLongSegmented unsigned num_glyphs) const { hb_codepoint_t last_end = 0; - for (unsigned i = 0; i < this->groups.len; i++) + unsigned count = this->groups.len; + for (unsigned i = 0; i < count; i++) { - hb_codepoint_t start = this->groups[i].startCharCode; - hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode, + hb_codepoint_t start = this->groups.arrayZ[i].startCharCode; + hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups.arrayZ[i].endCharCode, (hb_codepoint_t) HB_UNICODE_MAX); if (unlikely (start > end || start < last_end)) { // Range is not in order and is invalid, skip it. @@ -754,7 +898,7 @@ struct CmapSubtableLongSegmented last_end = end; - hb_codepoint_t gid = this->groups[i].glyphID; + hb_codepoint_t gid = this->groups.arrayZ[i].glyphID; if (!gid) { if (T::formatNumber == 13) continue; @@ -767,9 +911,9 @@ struct CmapSubtableLongSegmented mapping->alloc (mapping->get_population () + end - start + 1); + unicodes->add_range (start, end); for (unsigned cp = start; cp <= end; cp++) { - unicodes->add (cp); mapping->set (cp, gid); gid += T::increment; } @@ -1253,6 +1397,9 @@ struct CmapSubtableFormat14 hb_vector_t> obj_indices; for (int i = src_tbl->record.len - 1; i >= 0; i--) { + if (!unicodes->has(src_tbl->record[i].varSelector)) + continue; + hb_pair_t result = src_tbl->record[i].copy (c, unicodes, glyphs_requested, glyph_map, base); if (result.first || result.second) obj_indices.push (result); @@ -1309,6 +1456,7 @@ struct CmapSubtableFormat14 { + hb_iter (record) | hb_filter (hb_bool, &VariationSelectorRecord::nonDefaultUVS) + | hb_filter (unicodes, &VariationSelectorRecord::varSelector) | hb_map (&VariationSelectorRecord::nonDefaultUVS) | hb_map (hb_add (this)) | hb_apply ([=] (const NonDefaultUVS& _) { _.closure_glyphs (unicodes, glyphset); }) @@ -1353,12 +1501,12 @@ struct CmapSubtable hb_codepoint_t *glyph) const { switch (u.format) { - case 0: return u.format0 .get_glyph (codepoint, glyph); - case 4: return u.format4 .get_glyph (codepoint, glyph); - case 6: return u.format6 .get_glyph (codepoint, glyph); - case 10: return u.format10.get_glyph (codepoint, glyph); - case 12: return u.format12.get_glyph (codepoint, glyph); - case 13: return u.format13.get_glyph (codepoint, glyph); + case 0: hb_barrier (); return u.format0 .get_glyph (codepoint, glyph); + case 4: hb_barrier (); return u.format4 .get_glyph (codepoint, glyph); + case 6: hb_barrier (); return u.format6 .get_glyph (codepoint, glyph); + case 10: hb_barrier (); return u.format10.get_glyph (codepoint, glyph); + case 12: hb_barrier (); return u.format12.get_glyph (codepoint, glyph); + case 13: hb_barrier (); return u.format13.get_glyph (codepoint, glyph); case 14: default: return false; } @@ -1366,12 +1514,12 @@ struct CmapSubtable void collect_unicodes (hb_set_t *out, unsigned int num_glyphs = UINT_MAX) const { switch (u.format) { - case 0: u.format0 .collect_unicodes (out); return; - case 4: u.format4 .collect_unicodes (out); return; - case 6: u.format6 .collect_unicodes (out); return; - case 10: u.format10.collect_unicodes (out); return; - case 12: u.format12.collect_unicodes (out, num_glyphs); return; - case 13: u.format13.collect_unicodes (out, num_glyphs); return; + case 0: hb_barrier (); u.format0 .collect_unicodes (out); return; + case 4: hb_barrier (); u.format4 .collect_unicodes (out); return; + case 6: hb_barrier (); u.format6 .collect_unicodes (out); return; + case 10: hb_barrier (); u.format10.collect_unicodes (out); return; + case 12: hb_barrier (); u.format12.collect_unicodes (out, num_glyphs); return; + case 13: hb_barrier (); u.format13.collect_unicodes (out, num_glyphs); return; case 14: default: return; } @@ -1382,12 +1530,12 @@ struct CmapSubtable unsigned num_glyphs = UINT_MAX) const { switch (u.format) { - case 0: u.format0 .collect_mapping (unicodes, mapping); return; - case 4: u.format4 .collect_mapping (unicodes, mapping); return; - case 6: u.format6 .collect_mapping (unicodes, mapping); return; - case 10: u.format10.collect_mapping (unicodes, mapping); return; - case 12: u.format12.collect_mapping (unicodes, mapping, num_glyphs); return; - case 13: u.format13.collect_mapping (unicodes, mapping, num_glyphs); return; + case 0: hb_barrier (); u.format0 .collect_mapping (unicodes, mapping); return; + case 4: hb_barrier (); u.format4 .collect_mapping (unicodes, mapping); return; + case 6: hb_barrier (); u.format6 .collect_mapping (unicodes, mapping); return; + case 10: hb_barrier (); u.format10.collect_mapping (unicodes, mapping); return; + case 12: hb_barrier (); u.format12.collect_mapping (unicodes, mapping, num_glyphs); return; + case 13: hb_barrier (); u.format13.collect_mapping (unicodes, mapping, num_glyphs); return; case 14: default: return; } @@ -1396,12 +1544,12 @@ struct CmapSubtable unsigned get_language () const { switch (u.format) { - case 0: return u.format0 .get_language (); - case 4: return u.format4 .get_language (); - case 6: return u.format6 .get_language (); - case 10: return u.format10.get_language (); - case 12: return u.format12.get_language (); - case 13: return u.format13.get_language (); + case 0: hb_barrier (); return u.format0 .get_language (); + case 4: hb_barrier (); return u.format4 .get_language (); + case 6: hb_barrier (); return u.format6 .get_language (); + case 10: hb_barrier (); return u.format10.get_language (); + case 12: hb_barrier (); return u.format12.get_language (); + case 13: hb_barrier (); return u.format13.get_language (); case 14: default: return 0; } @@ -1416,9 +1564,9 @@ struct CmapSubtable const void *base) { switch (format) { - case 4: return u.format4.serialize (c, it); - case 12: return u.format12.serialize (c, it); - case 14: return u.format14.serialize (c, &plan->unicodes, &plan->glyphs_requested, plan->glyph_map, base); + case 4: hb_barrier (); return u.format4.serialize (c, it); + case 12: hb_barrier (); return u.format12.serialize (c, it); + case 14: hb_barrier (); return u.format14.serialize (c, &plan->unicodes, &plan->glyphs_requested, plan->glyph_map, base); default: return; } } @@ -1427,14 +1575,15 @@ struct CmapSubtable { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 0: return_trace (u.format0 .sanitize (c)); - case 4: return_trace (u.format4 .sanitize (c)); - case 6: return_trace (u.format6 .sanitize (c)); - case 10: return_trace (u.format10.sanitize (c)); - case 12: return_trace (u.format12.sanitize (c)); - case 13: return_trace (u.format13.sanitize (c)); - case 14: return_trace (u.format14.sanitize (c)); + case 0: hb_barrier (); return_trace (u.format0 .sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4 .sanitize (c)); + case 6: hb_barrier (); return_trace (u.format6 .sanitize (c)); + case 10: hb_barrier (); return_trace (u.format10.sanitize (c)); + case 12: hb_barrier (); return_trace (u.format12.sanitize (c)); + case 13: hb_barrier (); return_trace (u.format13.sanitize (c)); + case 14: hb_barrier (); return_trace (u.format14.sanitize (c)); default:return_trace (true); } } @@ -1462,8 +1611,11 @@ struct EncodingRecord int ret; ret = platformID.cmp (other.platformID); if (ret) return ret; - ret = encodingID.cmp (other.encodingID); - if (ret) return ret; + if (other.encodingID != 0xFFFF) + { + ret = encodingID.cmp (other.encodingID); + if (ret) return ret; + } return 0; } @@ -1811,9 +1963,13 @@ struct cmap c->plan)); } - const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const + const CmapSubtable *find_best_subtable (bool *symbol = nullptr, + bool *mac = nullptr, + bool *macroman = nullptr) const { if (symbol) *symbol = false; + if (mac) *mac = false; + if (macroman) *macroman = false; const CmapSubtable *subtable; @@ -1838,6 +1994,20 @@ struct cmap if ((subtable = this->find_subtable (0, 1))) return subtable; if ((subtable = this->find_subtable (0, 0))) return subtable; + /* MacRoman subtable. */ + if ((subtable = this->find_subtable (1, 0))) + { + if (mac) *mac = true; + if (macroman) *macroman = true; + return subtable; + } + /* Any other Mac subtable; we just map ASCII for these. */ + if ((subtable = this->find_subtable (1, 0xFFFF))) + { + if (mac) *mac = true; + return subtable; + } + /* Meh. */ return &Null (CmapSubtable); } @@ -1849,8 +2019,8 @@ struct cmap accelerator_t (hb_face_t *face) { this->table = hb_sanitize_context_t ().reference_table (face); - bool symbol; - this->subtable = table->find_best_subtable (&symbol); + bool symbol, mac, macroman; + this->subtable = table->find_best_subtable (&symbol, &mac, ¯oman); this->subtable_uvs = &Null (CmapSubtableFormat14); { const CmapSubtable *st = table->find_subtable (0, 5); @@ -1859,6 +2029,7 @@ struct cmap } this->get_glyph_data = subtable; +#ifndef HB_NO_CMAP_LEGACY_SUBTABLES if (unlikely (symbol)) { switch ((unsigned) face->table.OS2->get_font_page ()) { @@ -1878,7 +2049,16 @@ struct cmap break; } } + else if (unlikely (macroman)) + { + this->get_glyph_funcZ = get_glyph_from_macroman; + } + else if (unlikely (mac)) + { + this->get_glyph_funcZ = get_glyph_from_ascii; + } else +#endif { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ @@ -1921,7 +2101,7 @@ struct cmap hb_codepoint_t *glyph, cache_t *cache = nullptr) const { - if (unlikely (!this->get_glyph_funcZ)) return 0; + if (unlikely (!this->get_glyph_funcZ)) return false; return _cached_get (unicode, glyph, cache); } @@ -2003,6 +2183,28 @@ struct cmap return false; } + template + HB_INTERNAL static bool get_glyph_from_ascii (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + const Type *typed_obj = (const Type *) obj; + return codepoint < 0x80 && typed_obj->get_glyph (codepoint, glyph); + } + + template + HB_INTERNAL static bool get_glyph_from_macroman (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + if (get_glyph_from_ascii (obj, codepoint, glyph)) + return true; + + const Type *typed_obj = (const Type *) obj; + unsigned c = unicode_to_macroman (codepoint); + return c && typed_obj->get_glyph (c, glyph); + } + private: hb_nonnull_ptr_t subtable; hb_nonnull_ptr_t subtable_uvs; @@ -2032,34 +2234,13 @@ struct cmap return &(this+result.subtable); } - const EncodingRecord *find_encodingrec (unsigned int platform_id, - unsigned int encoding_id) const - { - EncodingRecord key; - key.platformID = platform_id; - key.encodingID = encoding_id; - - return encodingRecord.as_array ().bsearch (key); - } - - bool find_subtable (unsigned format) const - { - auto it = - + hb_iter (encodingRecord) - | hb_map (&EncodingRecord::subtable) - | hb_map (hb_add (this)) - | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == format; }) - ; - - return it.len (); - } - public: bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version == 0) && encodingRecord.sanitize (c, this)); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh index b552dfdd9da..97825f4d19c 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh @@ -95,12 +95,18 @@ HB_OT_CORE_TABLE (OT, fvar) HB_OT_CORE_TABLE (OT, avar) HB_OT_CORE_TABLE (OT, cvar) HB_OT_ACCELERATOR (OT, gvar) +#ifndef HB_NO_BEYOND_64K +HB_OT_ACCELERATOR (OT, GVAR) +#endif HB_OT_CORE_TABLE (OT, MVAR) +#ifndef HB_NO_VAR_COMPOSITES +HB_OT_ACCELERATOR (OT, VARC) +#endif #endif /* Legacy kern. */ #ifndef HB_NO_OT_KERN -HB_OT_CORE_TABLE (OT, kern) +HB_OT_ACCELERATOR (OT, kern) #endif /* OpenType shaping. */ @@ -118,9 +124,9 @@ HB_OT_CORE_TABLE (OT, BASE) /* AAT shaping. */ #ifndef HB_NO_AAT -HB_OT_TABLE (AAT, morx) -HB_OT_TABLE (AAT, mort) -HB_OT_TABLE (AAT, kerx) +HB_OT_ACCELERATOR (AAT, morx) +HB_OT_ACCELERATOR (AAT, mort) +HB_OT_ACCELERATOR (AAT, kerx) HB_OT_TABLE (AAT, ankr) HB_OT_TABLE (AAT, trak) HB_OT_TABLE (AAT, ltag) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc index 2243ee02874..1cf14f3ebc6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-face.cc @@ -41,6 +41,9 @@ #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-var-varc-table.hh" +#include "hb-aat-layout-kerx-table.hh" +#include "hb-aat-layout-morx-table.hh" void hb_ot_face_t::init0 (hb_face_t *face) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc index deec909b22e..2a633c77816 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc @@ -36,13 +36,17 @@ #include "hb-ot-face.hh" #include "hb-outline.hh" +#ifndef HB_NO_AAT +#include "hb-aat-layout-trak-table.hh" +#endif #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-post-table.hh" -#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. +#include "hb-ot-stat-table.hh" +#include "hb-ot-var-varc-table.hh" #include "hb-ot-vorg-table.hh" #include "OT/Color/CBDT/CBDT.hh" #include "OT/Color/COLR/COLR.hh" @@ -72,6 +76,10 @@ struct hb_ot_font_t { const hb_ot_face_t *ot_face; +#ifndef HB_NO_AAT + bool apply_trak; +#endif + #ifndef HB_NO_OT_FONT_CMAP_CACHE hb_ot_font_cmap_cache_t *cmap_cache; #endif @@ -90,6 +98,15 @@ _hb_ot_font_create (hb_font_t *font) ot_font->ot_face = &font->face->table; +#ifndef HB_NO_AAT + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + ot_font->apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); +#else + ot_font->apply_trak = false; +#endif +#endif + #ifndef HB_NO_OT_FONT_CMAP_CACHE // retry: auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face, @@ -199,7 +216,6 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; @@ -208,12 +224,12 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) const OT::HVAR &HVAR = *hmtx.var_table; - const OT::VariationStore &varStore = &HVAR + HVAR.varStore; - OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; + const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; + OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; bool use_cache = font->num_coords; #else - OT::VariationStore::cache_t *varStore_cache = nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = nullptr; bool use_cache = false; #endif @@ -277,7 +293,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, } #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::VariationStore::destroy_cache (varStore_cache); + OT::ItemVariationStore::destroy_cache (varStore_cache); #endif if (font->x_strength && !font->embolden_in_place) @@ -291,6 +307,20 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + if (ot_font->apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_h_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } +#endif } #ifndef HB_NO_VERTICAL @@ -313,10 +343,10 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, { #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) const OT::VVAR &VVAR = *vmtx.var_table; - const OT::VariationStore &varStore = &VVAR + VVAR.varStore; - OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; + const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; + OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; #else - OT::VariationStore::cache_t *varStore_cache = nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = nullptr; #endif for (unsigned int i = 0; i < count; i++) @@ -327,7 +357,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, } #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::VariationStore::destroy_cache (varStore_cache); + OT::ItemVariationStore::destroy_cache (varStore_cache); #endif } else @@ -355,6 +385,20 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } + +#ifndef HB_NO_AAT + if (ot_font->apply_trak) + { + hb_position_t tracking = font->face->table.trak->get_v_tracking (font); + first_advance = orig_first_advance; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += tracking; + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } +#endif } #endif @@ -523,6 +567,10 @@ hb_ot_draw_glyph (hb_font_t *font, { // Need draw_session to be destructed before emboldening. hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs, embolden ? &outline : draw_data, font->slant_xy); +#ifndef HB_NO_VAR_COMPOSITES + if (!font->face->table.VARC->get_path (font, glyph, draw_session)) +#endif + // Keep the following in synch with VARC::get_path_at() if (!font->face->table.glyf->get_path (font, glyph, draw_session)) #ifndef HB_NO_CFF if (!font->face->table.cff2->get_path (font, glyph, draw_session)) @@ -563,11 +611,11 @@ hb_ot_paint_glyph (hb_font_t *font, if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return; #endif #endif - if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; -#ifndef HB_NO_CFF - if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; - if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; -#endif + + // Outline glyph + paint_funcs->push_clip_glyph (paint_data, glyph, font); + paint_funcs->color (paint_data, true, foreground); + paint_funcs->pop_clip (paint_data); } #endif @@ -634,7 +682,9 @@ _hb_ot_get_font_funcs () * hb_ot_font_set_funcs: * @font: #hb_font_t to work upon * - * Sets the font functions to use when working with @font. + * Sets the font functions to use when working with @font to + * the HarfBuzz's native implementation. This is the default + * for fonts newly created. * * Since: 0.9.28 **/ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh index 77e68dbca42..918cf32dcb5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh @@ -71,6 +71,7 @@ struct DeviceRecord { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && c->check_range (this, sizeDeviceRecord))); } @@ -94,7 +95,7 @@ struct hdmx bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it, - const hb_vector_t &new_to_old_gid_list, + hb_array_t new_to_old_gid_list, unsigned num_glyphs) { TRACE_SERIALIZE (this); @@ -152,6 +153,7 @@ struct hdmx { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) && min_size + numRecords * sizeDeviceRecord > numRecords * sizeDeviceRecord && sizeDeviceRecord >= DeviceRecord::min_size && diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh index ab057fcfe4f..34535e2286d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh @@ -103,6 +103,7 @@ struct head { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && version.major == 1 && magicNumber == 0x5F0F3CF5u); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-hhea-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-hhea-table.hh index 37ef8744572..5e3be5be525 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-hhea-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-hhea-table.hh @@ -50,7 +50,9 @@ struct _hea bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && + hb_barrier () && + likely (version.major == 1)); } public: diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh index 39e1f4830a5..f7b4ca72198 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh @@ -30,6 +30,7 @@ #include "hb-open-type.hh" #include "hb-ot-maxp-table.hh" #include "hb-ot-hhea-table.hh" +#include "hb-ot-os2-table.hh" #include "hb-ot-var-hvar-table.hh" #include "hb-ot-var-mvar-table.hh" #include "hb-ot-metrics.hh" @@ -145,6 +146,29 @@ struct hmtxvmtx table->minTrailingBearing = min_rsb; table->maxExtent = max_extent; } + + if (T::is_horizontal) + { + const auto &OS2 = *c->plan->source->table.OS2; + if (OS2.has_data () && + table->ascender == OS2.sTypoAscender && + table->descender == OS2.sTypoDescender && + table->lineGap == OS2.sTypoLineGap) + { + table->ascender = static_cast (roundf (OS2.sTypoAscender + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + table->descender = static_cast (roundf (OS2.sTypoDescender + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + table->lineGap = static_cast (roundf (OS2.sTypoLineGap + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + } + } } #endif @@ -158,7 +182,7 @@ struct hmtxvmtx hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, Iterator it, - const hb_vector_t new_to_old_gid_list, + hb_array_t new_to_old_gid_list, unsigned num_long_metrics, unsigned total_num_metrics) { @@ -374,7 +398,7 @@ struct hmtxvmtx unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + ItemVariationStore::cache_t *store_cache = nullptr) const { unsigned int advance = get_advance_without_var_unscaled (glyph); @@ -387,7 +411,8 @@ struct hmtxvmtx font->coords, font->num_coords, store_cache)); - return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + 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 diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh index 291683369aa..bc90c345d05 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-kern-table.hh @@ -79,12 +79,23 @@ struct KernSubTableFormat3 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (kernValueZ, kernValueCount * sizeof (FWORD) + glyphCount * 2 + leftClassCount * rightClassCount)); } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + set_t set; + if (likely (glyphCount)) + set.add_range (0, glyphCount - 1); + left_set.union_ (set); + right_set.union_ (set); + } + protected: KernSubTableHeader header; @@ -121,7 +132,7 @@ struct KernSubTable { switch (get_type ()) { /* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */ - case 0: return u.format0.get_kerning (left, right); + case 0: hb_barrier (); return u.format0.get_kerning (left, right); default:return 0; } } @@ -134,22 +145,36 @@ struct KernSubTable switch (subtable_type) { case 0: return_trace (c->dispatch (u.format0)); #ifndef HB_NO_AAT_SHAPE - case 1: return_trace (u.header.apple ? c->dispatch (u.format1, std::forward (ds)...) : c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #endif case 2: return_trace (c->dispatch (u.format2)); #ifndef HB_NO_AAT_SHAPE - case 3: return_trace (u.header.apple ? c->dispatch (u.format3, std::forward (ds)...) : c->default_return_value ()); + case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); #endif default: return_trace (c->default_return_value ()); } } + template + void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + { + unsigned int subtable_type = get_type (); + switch (subtable_type) { + case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; + case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; + case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; + case 3: u.format3.collect_glyphs (left_set, right_set, num_glyphs); return; + default: return; + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.header.sanitize (c) || - u.header.length < u.header.min_size || - !c->check_range (this, u.header.length))) return_trace (false); + if (unlikely (!(u.header.sanitize (c) && + hb_barrier () && + u.header.length >= u.header.min_size && + c->check_range (this, u.header.length)))) return_trace (false); return_trace (dispatch (c)); } @@ -286,9 +311,9 @@ struct kern bool has_state_machine () const { switch (get_type ()) { - case 0: return u.ot.has_state_machine (); + case 0: hb_barrier (); return u.ot.has_state_machine (); #ifndef HB_NO_AAT_SHAPE - case 1: return u.aat.has_state_machine (); + case 1: hb_barrier (); return u.aat.has_state_machine (); #endif default:return false; } @@ -297,9 +322,9 @@ struct kern bool has_cross_stream () const { switch (get_type ()) { - case 0: return u.ot.has_cross_stream (); + case 0: hb_barrier (); return u.ot.has_cross_stream (); #ifndef HB_NO_AAT_SHAPE - case 1: return u.aat.has_cross_stream (); + case 1: hb_barrier (); return u.aat.has_cross_stream (); #endif default:return false; } @@ -308,16 +333,17 @@ struct kern int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { switch (get_type ()) { - case 0: return u.ot.get_h_kerning (left, right); + case 0: hb_barrier (); return u.ot.get_h_kerning (left, right); #ifndef HB_NO_AAT_SHAPE - case 1: return u.aat.get_h_kerning (left, right); + case 1: hb_barrier (); return u.aat.get_h_kerning (left, right); #endif default:return 0; } } - bool apply (AAT::hb_aat_apply_context_t *c) const - { return dispatch (c); } + bool apply (AAT::hb_aat_apply_context_t *c, + const AAT::kern_accelerator_data_t &accel_data) const + { return dispatch (c, accel_data); } template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const @@ -337,9 +363,45 @@ struct kern { TRACE_SANITIZE (this); if (!u.version32.sanitize (c)) return_trace (false); + hb_barrier (); return_trace (dispatch (c)); } + AAT::kern_accelerator_data_t create_accelerator_data (unsigned num_glyphs) const + { + switch (get_type ()) { + case 0: hb_barrier (); return u.ot.create_accelerator_data (num_glyphs); +#ifndef HB_NO_AAT_SHAPE + case 1: hb_barrier (); return u.aat.create_accelerator_data (num_glyphs); +#endif + default:return AAT::kern_accelerator_data_t (); + } + } + + struct accelerator_t + { + accelerator_t (hb_face_t *face) + { + hb_sanitize_context_t sc; + this->table = sc.reference_table (face); + this->accel_data = this->table->create_accelerator_data (face->get_num_glyphs ()); + } + ~accelerator_t () + { + this->table.destroy (); + } + + hb_blob_t *get_blob () const { return table.get_blob (); } + + bool apply (AAT::hb_aat_apply_context_t *c) const + { + return table->apply (c, accel_data); + } + + hb_blob_ptr_t table; + AAT::kern_accelerator_data_t accel_data; + }; + protected: union { HBUINT32 version32; @@ -353,6 +415,10 @@ struct kern DEFINE_SIZE_UNION (4, version32); }; +struct kern_accelerator_t : kern::accelerator_t { + kern_accelerator_t (hb_face_t *face) : kern::accelerator_t (face) {} +}; + } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh index 0e57a6c7909..5a3679e4bfa 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh @@ -46,6 +46,12 @@ struct BaseCoordFormat1 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + return_trace ((bool) c->serializer->embed (*this)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -67,6 +73,17 @@ struct BaseCoordFormat2 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (c->serializer->check_assign (out->referenceGlyph, + c->plan->glyph_map->get (referenceGlyph), + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -86,7 +103,7 @@ struct BaseCoordFormat2 struct BaseCoordFormat3 { hb_position_t get_coord (hb_font_t *font, - const VariationStore &var_store, + const ItemVariationStore &var_store, hb_direction_t direction) const { const Device &device = this+deviceTable; @@ -96,6 +113,37 @@ struct BaseCoordFormat3 : font->em_scale_x (coordinate) + device.get_x_delta (font, var_store); } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + unsigned varidx = (this+deviceTable).get_variation_index (); + varidx_set.add (varidx); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + if (!c->plan->pinned_at_default) + { + unsigned var_idx = (this+deviceTable).get_variation_index (); + if (var_idx != VarIdx::NO_VARIATION) + { + hb_pair_t *v; + if (!c->plan->base_variation_idx_map.has (var_idx, &v)) + return_trace (false); + + if (unlikely (!c->serializer->check_assign (out->coordinate, coordinate + hb_second (*v), + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); + } + } + return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, + this, 0, + hb_serialize_context_t::Head, + &c->plan->base_variation_idx_map)); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -120,25 +168,47 @@ struct BaseCoord bool has_data () const { return u.format; } hb_position_t get_coord (hb_font_t *font, - const VariationStore &var_store, + const ItemVariationStore &var_store, hb_direction_t direction) const { switch (u.format) { - case 1: return u.format1.get_coord (font, direction); - case 2: return u.format2.get_coord (font, direction); - case 3: return u.format3.get_coord (font, var_store, direction); + case 1: hb_barrier (); return u.format1.get_coord (font, direction); + case 2: hb_barrier (); return u.format2.get_coord (font, direction); + case 3: hb_barrier (); return u.format3.get_coord (font, var_store, direction); default:return 0; } } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + switch (u.format) { + case 3: hb_barrier (); u.format3.collect_variation_indices (varidx_set); + default:return; + } + } + + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format); + switch (u.format) { + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (unlikely (!u.format.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 3: return_trace (u.format3.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); default:return_trace (false); } } @@ -160,12 +230,37 @@ struct FeatMinMaxRecord bool has_data () const { return tag; } + hb_tag_t get_feature_tag () const { return tag; } + void get_min_max (const BaseCoord **min, const BaseCoord **max) const { if (likely (min)) *min = &(this+minCoord); if (likely (max)) *max = &(this+maxCoord); } + void collect_variation_indices (const hb_subset_plan_t* plan, + const void *base, + hb_set_t& varidx_set /* OUT */) const + { + if (!plan->layout_features.has (tag)) + return; + + (base+minCoord).collect_variation_indices (varidx_set); + (base+maxCoord).collect_variation_indices (varidx_set); + } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + if (!(out->minCoord.serialize_subset (c, minCoord, base))) + return_trace (false); + + return_trace (out->maxCoord.serialize_subset (c, maxCoord, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -205,6 +300,39 @@ struct MinMax } } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+minCoord).collect_variation_indices (varidx_set); + (this+maxCoord).collect_variation_indices (varidx_set); + for (const FeatMinMaxRecord& record : featMinMaxRecords) + record.collect_variation_indices (plan, this, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + if (!(out->minCoord.serialize_subset (c, minCoord, this)) || + !(out->maxCoord.serialize_subset (c, maxCoord, this))) + return_trace (false); + + unsigned len = 0; + for (const FeatMinMaxRecord& _ : featMinMaxRecords) + { + hb_tag_t feature_tag = _.get_feature_tag (); + if (!c->plan->layout_features.has (feature_tag)) + continue; + + if (!_.subset (c, this)) return false; + len++; + } + return_trace (c->serializer->check_assign (out->featMinMaxRecords.len, len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -239,6 +367,26 @@ struct BaseValues return this+baseCoords[baseline_tag_index]; } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + for (const auto& _ : baseCoords) + (this+_).collect_variation_indices (varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + out->defaultIndex = defaultIndex; + + for (const auto& _ : baseCoords) + if (!subset_offset_array (c, out->baseCoords, this) (_)) + return_trace (false); + + return_trace (bool (out->baseCoords)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -267,7 +415,22 @@ struct BaseLangSysRecord bool has_data () const { return baseLangSysTag; } - const MinMax &get_min_max () const { return this+minMax; } + const MinMax &get_min_max (const void* base) const { return base+minMax; } + + void collect_variation_indices (const void* base, + const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { (base+minMax).collect_variation_indices (plan, varidx_set); } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->minMax.serialize_subset (c, minMax, base)); + } bool sanitize (hb_sanitize_context_t *c, const void *base) const { @@ -290,14 +453,43 @@ struct BaseScript const MinMax &get_min_max (hb_tag_t language_tag) const { const BaseLangSysRecord& record = baseLangSysRecords.bsearch (language_tag); - return record.has_data () ? record.get_min_max () : this+defaultMinMax; + return record.has_data () ? record.get_min_max (this) : this+defaultMinMax; } const BaseCoord &get_base_coord (int baseline_tag_index) const { return (this+baseValues).get_base_coord (baseline_tag_index); } bool has_values () const { return baseValues; } - bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ } + bool has_min_max () const { return defaultMinMax || baseLangSysRecords; } + + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+baseValues).collect_variation_indices (varidx_set); + (this+defaultMinMax).collect_variation_indices (plan, varidx_set); + + for (const BaseLangSysRecord& _ : baseLangSysRecords) + _.collect_variation_indices (this, plan, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + if (baseValues && !out->baseValues.serialize_subset (c, baseValues, this)) + return_trace (false); + + if (defaultMinMax && !out->defaultMinMax.serialize_subset (c, defaultMinMax, this)) + return_trace (false); + + for (const auto& _ : baseLangSysRecords) + if (!_.subset (c, this)) return_trace (false); + + return_trace (c->serializer->check_assign (out->baseLangSysRecords.len, baseLangSysRecords.len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -331,9 +523,31 @@ struct BaseScriptRecord bool has_data () const { return baseScriptTag; } + hb_tag_t get_script_tag () const { return baseScriptTag; } + const BaseScript &get_base_script (const BaseScriptList *list) const { return list+baseScript; } + void collect_variation_indices (const hb_subset_plan_t* plan, + const void* list, + hb_set_t& varidx_set /* OUT */) const + { + if (!plan->layout_scripts.has (baseScriptTag)) + return; + + (list+baseScript).collect_variation_indices (plan, varidx_set); + } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->baseScript.serialize_subset (c, baseScript, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -360,6 +574,33 @@ struct BaseScriptList return record->has_data () ? record->get_base_script (this) : Null (BaseScript); } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + for (const BaseScriptRecord& _ : baseScriptRecords) + _.collect_variation_indices (plan, this, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned len = 0; + for (const BaseScriptRecord& _ : baseScriptRecords) + { + hb_tag_t script_tag = _.get_script_tag (); + if (!c->plan->layout_scripts.has (script_tag)) + continue; + + if (!_.subset (c, this)) return false; + len++; + } + return_trace (c->serializer->check_assign (out->baseScriptRecords.len, len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -421,6 +662,20 @@ struct Axis return true; } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { (this+baseScriptList).collect_variation_indices (plan, varidx_set); } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + out->baseTagList.serialize_copy (c->serializer, baseTagList, this); + return_trace (out->baseScriptList.serialize_subset (c, baseScriptList, this)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -452,8 +707,77 @@ struct BASE const Axis &get_axis (hb_direction_t direction) const { return HB_DIRECTION_IS_VERTICAL (direction) ? this+vAxis : this+hAxis; } - const VariationStore &get_var_store () const - { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; } + bool has_var_store () const + { return version.to_int () >= 0x00010001u && varStore != 0; } + + const ItemVariationStore &get_var_store () const + { return version.to_int () < 0x00010001u ? Null (ItemVariationStore) : this+varStore; } + + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+hAxis).collect_variation_indices (plan, varidx_set); + (this+vAxis).collect_variation_indices (plan, varidx_set); + } + + bool subset_varstore (hb_subset_context_t *c, + BASE *out /* OUT */) const + { + TRACE_SUBSET (this); + if (!c->serializer->allocate_size> (Offset32To::static_size)) + return_trace (false); + if (!c->plan->normalized_coords) + return_trace (out->varStore.serialize_subset (c, varStore, this, c->plan->base_varstore_inner_maps.as_array ())); + + if (c->plan->all_axes_pinned) + return_trace (true); + + item_variations_t item_vars; + if (!item_vars.instantiate (this+varStore, c->plan, true, true, + c->plan->base_varstore_inner_maps.as_array ())) + return_trace (false); + + if (!out->varStore.serialize_serialize (c->serializer, + item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ())) + return_trace (false); + + const hb_map_t &varidx_map = item_vars.get_varidx_map (); + /* base_variation_idx_map in the plan is old_varidx->(varidx, delta) + * mapping, new varidx is generated for subsetting, we need to remap this + * after instancing */ + for (auto _ : c->plan->base_variation_idx_map.iter_ref ()) + { + uint32_t varidx = _.second.first; + uint32_t *new_varidx; + if (varidx_map.has (varidx, &new_varidx)) + _.second.first = *new_varidx; + else + _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + } + return_trace (true); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + out->version = version; + if (has_var_store () && !subset_varstore (c, out)) + return_trace (false); + + if (hAxis && !out->hAxis.serialize_subset (c, hAxis, this)) + return_trace (false); + + if (vAxis && !out->vAxis.serialize_subset (c, vAxis, this)) + return_trace (false); + + return_trace (true); + } bool get_baseline (hb_font_t *font, hb_tag_t baseline_tag, @@ -486,7 +810,7 @@ struct BASE &min_coord, &max_coord)) return false; - const VariationStore &var_store = get_var_store (); + const ItemVariationStore &var_store = get_var_store (); if (likely (min && min_coord)) *min = min_coord->get_coord (font, var_store, direction); if (likely (max && max_coord)) *max = max_coord->get_coord (font, var_store, direction); return true; @@ -496,6 +820,7 @@ struct BASE { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && likely (version.major == 1) && hAxis.sanitize (c, this) && vAxis.sanitize (c, this) && @@ -508,7 +833,7 @@ struct BASE * of BASE table (may be NULL) */ Offset16TovAxis; /* Offset to vertical Axis table, from beginning * of BASE table (may be NULL) */ - Offset32To + Offset32To varStore; /* Offset to the table of Item Variation * Store--from beginning of BASE * header (may be NULL). Introduced diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh index 9216a9a0fe7..f14675295f6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh @@ -34,6 +34,7 @@ #include "hb-open-type.hh" #include "hb-set.hh" #include "hb-bimap.hh" +#include "hb-cache.hh" #include "OT/Layout/Common/Coverage.hh" #include "OT/Layout/types.hh" @@ -64,7 +65,7 @@ struct hb_collect_feature_substitutes_with_var_context_t const hb_hashmap_t *axes_location; hb_hashmap_t> *record_cond_idx_map; hb_hashmap_t *feature_substitutes_map; - bool& insert_catch_all_feature_variation_record; + hb_set_t& catch_all_record_feature_idxes; // not stored in subset_plan hb_set_t *feature_indices; @@ -142,6 +143,8 @@ struct hb_subset_layout_context_t : const hb_map_t *feature_index_map; const hb_hashmap_t *feature_substitutes_map; hb_hashmap_t> *feature_record_cond_idx_map; + const hb_set_t *catch_all_record_feature_idxes; + const hb_hashmap_t> *feature_idx_tag_map; unsigned cur_script_index; unsigned cur_feature_var_record_idx; @@ -164,6 +167,8 @@ struct hb_subset_layout_context_t : feature_index_map = &c_->plan->gsub_features; feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map; + catch_all_record_feature_idxes = &c_->plan->gsub_old_features; + feature_idx_tag_map = &c_->plan->gsub_old_feature_idx_tag_map; } else { @@ -172,6 +177,8 @@ struct hb_subset_layout_context_t : feature_index_map = &c_->plan->gpos_features; feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map; + catch_all_record_feature_idxes = &c_->plan->gpos_old_features; + feature_idx_tag_map = &c_->plan->gpos_old_feature_idx_tag_map; } } @@ -182,7 +189,7 @@ struct hb_subset_layout_context_t : unsigned lookup_index_count; }; -struct VariationStore; +struct ItemVariationStore; struct hb_collect_variation_indices_context_t : hb_dispatch_context_t { @@ -454,6 +461,7 @@ struct FeatureParamsSize { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); /* This subtable has some "history", if you will. Some earlier versions of * Adobe tools calculated the offset of the FeatureParams subtable from the @@ -639,8 +647,7 @@ struct FeatureParamsCharacterVariants return; unsigned last_name_id = (unsigned) firstParamUILabelNameID + (unsigned) numNamedParameters - 1; - if (last_name_id >= 256 && last_name_id <= 32767) - nameids_to_retain->add_range (firstParamUILabelNameID, last_name_id); + nameids_to_retain->add_range (firstParamUILabelNameID, last_name_id); } bool subset (hb_subset_context_t *c) const @@ -820,6 +827,7 @@ struct Feature TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) return_trace (false); + hb_barrier (); /* Some earlier versions of Adobe tools calculated the offset of the * FeatureParams subtable from the beginning of the FeatureList table! @@ -838,6 +846,7 @@ struct Feature unsigned int orig_offset = featureParams; if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) return_trace (false); + hb_barrier (); if (featureParams == 0 && closure && closure->tag == HB_TAG ('s','i','z','e') && @@ -900,7 +909,8 @@ struct Record { TRACE_SANITIZE (this); const Record_sanitize_closure_t closure = {tag, base}; - return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); + return_trace (c->check_struct (this) && + offset.sanitize (c, base, &closure)); } Tag tag; /* 4-byte Tag identifier */ @@ -1371,10 +1381,20 @@ struct Lookup if (lookupFlag & LookupFlag::UseMarkFilteringSet) { - if (unlikely (!c->serializer->extend (out))) return_trace (false); const HBUINT16 &markFilteringSet = StructAfter (subTable); - HBUINT16 &outMarkFilteringSet = StructAfter (out->subTable); - outMarkFilteringSet = markFilteringSet; + hb_codepoint_t *idx; + if (!c->plan->used_mark_sets_map.has (markFilteringSet, &idx)) + { + unsigned new_flag = lookupFlag; + new_flag &= ~LookupFlag::UseMarkFilteringSet; + out->lookupFlag = new_flag; + } + else + { + if (unlikely (!c->serializer->extend (out))) return_trace (false); + HBUINT16 &outMarkFilteringSet = StructAfter (out->subTable); + outMarkFilteringSet = *idx; + } } // Always keep the lookup even if it's empty. The rest of layout subsetting depends on lookup @@ -1391,6 +1411,7 @@ struct Lookup { TRACE_SANITIZE (this); if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); + hb_barrier (); unsigned subtables = get_subtable_count (); if (unlikely (!c->visit_subtables (subtables))) return_trace (false); @@ -1406,6 +1427,8 @@ struct Lookup if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) { + hb_barrier (); + /* The spec says all subtables of an Extension lookup should * have the same type, which shall not be the Extension type * itself (but we already checked for that). @@ -2045,24 +2068,33 @@ struct ClassDef unsigned int get_class (hb_codepoint_t glyph_id) const { switch (u.format) { - case 1: return u.format1.get_class (glyph_id); - case 2: return u.format2.get_class (glyph_id); + case 1: hb_barrier (); return u.format1.get_class (glyph_id); + case 2: hb_barrier (); return u.format2.get_class (glyph_id); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.get_class (glyph_id); - case 4: return u.format4.get_class (glyph_id); + case 3: hb_barrier (); return u.format3.get_class (glyph_id); + case 4: hb_barrier (); return u.format4.get_class (glyph_id); #endif default:return 0; } } + unsigned int get_class (hb_codepoint_t glyph_id, + hb_ot_lookup_cache_t *cache) const + { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; + klass = get_class (glyph_id); + if (cache) cache->set (glyph_id, klass); + return klass; + } unsigned get_population () const { switch (u.format) { - case 1: return u.format1.get_population (); - case 2: return u.format2.get_population (); + case 1: hb_barrier (); return u.format1.get_population (); + case 2: hb_barrier (); return u.format2.get_population (); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.get_population (); - case 4: return u.format4.get_population (); + case 3: hb_barrier (); return u.format3.get_population (); + case 4: hb_barrier (); return u.format4.get_population (); #endif default:return NOT_COVERED; } @@ -2124,11 +2156,11 @@ struct ClassDef switch (u.format) { - case 1: return_trace (u.format1.serialize (c, it)); - case 2: return_trace (u.format2.serialize (c, it)); + case 1: hb_barrier (); return_trace (u.format1.serialize (c, it)); + case 2: hb_barrier (); return_trace (u.format2.serialize (c, it)); #ifndef HB_NO_BEYOND_64K - case 3: return_trace (u.format3.serialize (c, it)); - case 4: return_trace (u.format4.serialize (c, it)); + case 3: hb_barrier (); return_trace (u.format3.serialize (c, it)); + case 4: hb_barrier (); return_trace (u.format4.serialize (c, it)); #endif default:return_trace (false); } @@ -2142,11 +2174,11 @@ struct ClassDef { TRACE_SUBSET (this); switch (u.format) { - case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); - case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 1: hb_barrier (); return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 2: hb_barrier (); return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); #ifndef HB_NO_BEYOND_64K - case 3: return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); - case 4: return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 3: hb_barrier (); return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 4: hb_barrier (); return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); #endif default:return_trace (false); } @@ -2156,12 +2188,13 @@ struct ClassDef { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); #ifndef HB_NO_BEYOND_64K - case 3: return_trace (u.format3.sanitize (c)); - case 4: return_trace (u.format4.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); #endif default:return_trace (true); } @@ -2170,11 +2203,11 @@ struct ClassDef unsigned cost () const { switch (u.format) { - case 1: return u.format1.cost (); - case 2: return u.format2.cost (); + case 1: hb_barrier (); return u.format1.cost (); + case 2: hb_barrier (); return u.format2.cost (); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.cost (); - case 4: return u.format4.cost (); + case 3: hb_barrier (); return u.format3.cost (); + case 4: hb_barrier (); return u.format4.cost (); #endif default:return 0u; } @@ -2186,11 +2219,11 @@ struct ClassDef bool collect_coverage (set_t *glyphs) const { switch (u.format) { - case 1: return u.format1.collect_coverage (glyphs); - case 2: return u.format2.collect_coverage (glyphs); + case 1: hb_barrier (); return u.format1.collect_coverage (glyphs); + case 2: hb_barrier (); return u.format2.collect_coverage (glyphs); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.collect_coverage (glyphs); - case 4: return u.format4.collect_coverage (glyphs); + case 3: hb_barrier (); return u.format3.collect_coverage (glyphs); + case 4: hb_barrier (); return u.format4.collect_coverage (glyphs); #endif default:return false; } @@ -2202,11 +2235,11 @@ struct ClassDef bool collect_class (set_t *glyphs, unsigned int klass) const { switch (u.format) { - case 1: return u.format1.collect_class (glyphs, klass); - case 2: return u.format2.collect_class (glyphs, klass); + case 1: hb_barrier (); return u.format1.collect_class (glyphs, klass); + case 2: hb_barrier (); return u.format2.collect_class (glyphs, klass); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.collect_class (glyphs, klass); - case 4: return u.format4.collect_class (glyphs, klass); + case 3: hb_barrier (); return u.format3.collect_class (glyphs, klass); + case 4: hb_barrier (); return u.format4.collect_class (glyphs, klass); #endif default:return false; } @@ -2215,11 +2248,11 @@ struct ClassDef bool intersects (const hb_set_t *glyphs) const { switch (u.format) { - case 1: return u.format1.intersects (glyphs); - case 2: return u.format2.intersects (glyphs); + case 1: hb_barrier (); return u.format1.intersects (glyphs); + case 2: hb_barrier (); return u.format2.intersects (glyphs); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.intersects (glyphs); - case 4: return u.format4.intersects (glyphs); + case 3: hb_barrier (); return u.format3.intersects (glyphs); + case 4: hb_barrier (); return u.format4.intersects (glyphs); #endif default:return false; } @@ -2227,11 +2260,11 @@ struct ClassDef bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { switch (u.format) { - case 1: return u.format1.intersects_class (glyphs, klass); - case 2: return u.format2.intersects_class (glyphs, klass); + case 1: hb_barrier (); return u.format1.intersects_class (glyphs, klass); + case 2: hb_barrier (); return u.format2.intersects_class (glyphs, klass); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.intersects_class (glyphs, klass); - case 4: return u.format4.intersects_class (glyphs, klass); + case 3: hb_barrier (); return u.format3.intersects_class (glyphs, klass); + case 4: hb_barrier (); return u.format4.intersects_class (glyphs, klass); #endif default:return false; } @@ -2240,11 +2273,11 @@ struct ClassDef void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const { switch (u.format) { - case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); - case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 1: hb_barrier (); return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 2: hb_barrier (); return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs); - case 4: return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 3: hb_barrier (); return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 4: hb_barrier (); return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs); #endif default:return; } @@ -2253,11 +2286,11 @@ struct ClassDef void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const { switch (u.format) { - case 1: return u.format1.intersected_classes (glyphs, intersect_classes); - case 2: return u.format2.intersected_classes (glyphs, intersect_classes); + case 1: hb_barrier (); return u.format1.intersected_classes (glyphs, intersect_classes); + case 2: hb_barrier (); return u.format2.intersected_classes (glyphs, intersect_classes); #ifndef HB_NO_BEYOND_64K - case 3: return u.format3.intersected_classes (glyphs, intersect_classes); - case 4: return u.format4.intersected_classes (glyphs, intersect_classes); + case 3: hb_barrier (); return u.format3.intersected_classes (glyphs, intersect_classes); + case 4: hb_barrier (); return u.format4.intersected_classes (glyphs, intersect_classes); #endif default:return; } @@ -2447,6 +2480,8 @@ struct VarRegionAxis int peak = peakCoord.to_int (); if (peak == 0 || coord == peak) return 1.f; + else if (coord == 0) // Faster + return 0.f; int start = startCoord.to_int (), end = endCoord.to_int (); @@ -2470,8 +2505,6 @@ struct VarRegionAxis { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); - /* TODO Handle invalid start/peak/end configs, so we don't - * have to do that at runtime. */ } bool serialize (hb_serialize_context_t *c) const @@ -2487,6 +2520,33 @@ struct VarRegionAxis public: DEFINE_SIZE_STATIC (6); }; +struct SparseVarRegionAxis +{ + float evaluate (const int *coords, unsigned int coord_len) const + { + unsigned i = axisIndex; + int coord = i < coord_len ? coords[i] : 0; + return axis.evaluate (coord); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + bool serialize (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace (c->embed (this)); + } + + public: + HBUINT16 axisIndex; + VarRegionAxis axis; + public: + DEFINE_SIZE_STATIC (8); +}; #define REGION_CACHE_ITEM_CACHE_INVALID 2.f @@ -2534,7 +2594,9 @@ struct VarRegionList bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount)); + return_trace (c->check_struct (this) && + hb_barrier () && + axesZ.sanitize (c, axisCount * regionCount)); } bool serialize (hb_serialize_context_t *c, @@ -2615,7 +2677,7 @@ struct VarRegionList float max_val = axis_region->endCoord.to_float (); if (def_val != 0.f) - axis_tuples.set (*axis_tag, Triple (min_val, def_val, max_val)); + axis_tuples.set (*axis_tag, Triple ((double) min_val, (double) def_val, (double) max_val)); axis_region++; } return !axis_tuples.in_error (); @@ -2649,6 +2711,65 @@ struct VarRegionList DEFINE_SIZE_ARRAY (4, axesZ); }; +struct SparseVariationRegion : Array16Of +{ + float evaluate (const int *coords, unsigned int coord_len) const + { + float v = 1.f; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + { + float factor = arrayZ[i].evaluate (coords, coord_len); + if (factor == 0.f) + return 0.; + v *= factor; + } + return v; + } +}; + +struct SparseVarRegionList +{ + using cache_t = float; + + float evaluate (unsigned int region_index, + const int *coords, unsigned int coord_len, + cache_t *cache = nullptr) const + { + if (unlikely (region_index >= regions.len)) + return 0.; + + float *cached_value = nullptr; + if (cache) + { + cached_value = &(cache[region_index]); + if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID)) + return *cached_value; + } + + const SparseVariationRegion ®ion = this+regions[region_index]; + + float v = region.evaluate (coords, coord_len); + + if (cache) + *cached_value = v; + return v; + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (regions.sanitize (c, this)); + } + + public: + Array16Of> + regions; + public: + DEFINE_SIZE_ARRAY (2, regions); +}; + + struct VarData { unsigned int get_item_count () const @@ -2728,6 +2849,7 @@ struct VarData TRACE_SANITIZE (this); return_trace (c->check_struct (this) && regionIndices.sanitize (c) && + hb_barrier () && wordCount () <= regionIndices.len && c->check_range (get_delta_bytes (), itemCount, @@ -3009,7 +3131,53 @@ struct VarData DEFINE_SIZE_ARRAY (6, regionIndices); }; -struct VariationStore +struct MultiVarData +{ + unsigned int get_size () const + { return min_size + - regionIndices.min_size + regionIndices.get_size () + + StructAfter (regionIndices).get_size (); + } + + void get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const SparseVarRegionList ®ions, + hb_array_t out, + SparseVarRegionList::cache_t *cache = nullptr) const + { + auto &deltaSets = StructAfter (regionIndices); + + auto values_iter = deltaSets.fetcher (inner); + unsigned regionCount = regionIndices.len; + for (unsigned regionIndex = 0; regionIndex < regionCount; regionIndex++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[regionIndex], + coords, coord_count, + cache); + values_iter.add_to (out, scalar); + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (format.sanitize (c) && + hb_barrier () && + format == 1 && + regionIndices.sanitize (c) && + hb_barrier () && + StructAfter (regionIndices).sanitize (c)); + } + + protected: + HBUINT8 format; // 1 + Array16Of regionIndices; + TupleList deltaSetsX; + public: + DEFINE_SIZE_MIN (8); +}; + +struct ItemVariationStore { friend struct item_variations_t; using cache_t = VarRegionList::cache_t; @@ -3061,7 +3229,7 @@ struct VariationStore return get_delta (outer, inner, coords, coord_count, cache); } float get_delta (unsigned int index, - hb_array_t coords, + hb_array_t coords, VarRegionList::cache_t *cache = nullptr) const { return get_delta (index, @@ -3077,6 +3245,7 @@ struct VariationStore TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && format == 1 && regions.sanitize (c, this) && dataSets.sanitize (c, this)); @@ -3113,7 +3282,7 @@ struct VariationStore } bool serialize (hb_serialize_context_t *c, - const VariationStore *src, + const ItemVariationStore *src, const hb_array_t &inner_maps) { TRACE_SERIALIZE (this); @@ -3169,7 +3338,7 @@ struct VariationStore return_trace (true); } - VariationStore *copy (hb_serialize_context_t *c) const + ItemVariationStore *copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); @@ -3180,6 +3349,8 @@ struct VariationStore for (unsigned i = 0; i < count; i++) { hb_inc_bimap_t *map = inner_maps.push (); + if (!c->propagate_error(inner_maps)) + return_trace(nullptr); auto &data = this+dataSets[i]; unsigned itemCount = data.get_item_count (); @@ -3199,7 +3370,7 @@ struct VariationStore return_trace (false); #endif - VariationStore *varstore_prime = c->serializer->start_embed (); + ItemVariationStore *varstore_prime = c->serializer->start_embed (); if (unlikely (!varstore_prime)) return_trace (false); varstore_prime->serialize (c->serializer, this, inner_maps); @@ -3265,8 +3436,370 @@ struct VariationStore DEFINE_SIZE_ARRAY_SIZED (8, dataSets); }; +struct MultiItemVariationStore +{ + using cache_t = SparseVarRegionList::cache_t; + + cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const + { +#ifdef HB_NO_VAR + return nullptr; +#endif + auto &r = this+regions; + unsigned count = r.regions.len; + + float *cache; + if (count <= static_cache.length) + cache = static_cache.arrayZ; + else + { + cache = (float *) 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; + } + + static void destroy_cache (cache_t *cache, + hb_array_t static_cache = hb_array_t ()) + { + if (cache != static_cache.arrayZ) + hb_free (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 + { +#ifdef HB_NO_VAR + return; +#endif + + if (unlikely (outer >= dataSets.len)) + return; + + return (this+dataSets[outer]).get_delta (inner, + coords, coord_count, + this+regions, + out, + cache); + } + + public: + void get_delta (unsigned int index, + const int *coords, unsigned int coord_count, + hb_array_t out, + VarRegionList::cache_t *cache = nullptr) const + { + unsigned int outer = index >> 16; + unsigned int inner = index & 0xFFFF; + get_delta (outer, inner, coords, coord_count, out, cache); + } + void get_delta (unsigned int index, + hb_array_t coords, + hb_array_t out, + VarRegionList::cache_t *cache = nullptr) const + { + return get_delta (index, + coords.arrayZ, coords.length, + out, + cache); + } + + bool sanitize (hb_sanitize_context_t *c) const + { +#ifdef HB_NO_VAR + return true; +#endif + + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + hb_barrier () && + format == 1 && + regions.sanitize (c, this) && + dataSets.sanitize (c, this)); + } + + protected: + HBUINT16 format; // 1 + Offset32To regions; + Array16OfOffset32To dataSets; + public: + DEFINE_SIZE_ARRAY_SIZED (8, dataSets); +}; + #undef REGION_CACHE_ITEM_CACHE_INVALID +template +struct DeltaSetIndexMapFormat01 +{ + friend struct DeltaSetIndexMap; + + unsigned get_size () const + { return min_size + mapCount * get_width (); } + + private: + DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace (c->embed (this)); + } + + template + bool serialize (hb_serialize_context_t *c, const T &plan) + { + unsigned int width = plan.get_width (); + unsigned int inner_bit_count = plan.get_inner_bit_count (); + const hb_array_t output_map = plan.get_output_map (); + + TRACE_SERIALIZE (this); + if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) + return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); + + entryFormat = ((width-1)<<4)|(inner_bit_count-1); + mapCount = output_map.length; + HBUINT8 *p = c->allocate_size (width * output_map.length); + if (unlikely (!p)) return_trace (false); + for (unsigned int i = 0; i < output_map.length; i++) + { + unsigned int v = output_map.arrayZ[i]; + if (v) + { + unsigned int outer = v >> 16; + unsigned int inner = v & 0xFFFF; + unsigned int u = (outer << inner_bit_count) | inner; + for (unsigned int w = width; w > 0;) + { + p[--w] = u; + u >>= 8; + } + } + p += width; + } + return_trace (true); + } + + 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; + + if (v >= mapCount) + v = mapCount - 1; + + unsigned int u = 0; + { /* Fetch it. */ + unsigned int w = get_width (); + const HBUINT8 *p = mapDataZ.arrayZ + w * v; + for (; w; w--) + u = (u << 8) + *p++; + } + + { /* Repack it. */ + unsigned int n = get_inner_bit_count (); + unsigned int outer = u >> n; + unsigned int inner = u & ((1 << n) - 1); + u = (outer<<16) | inner; + } + + return u; + } + + unsigned get_map_count () const { return mapCount; } + unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } + unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } + + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + hb_barrier () && + c->check_range (mapDataZ.arrayZ, + mapCount, + get_width ())); + } + + protected: + HBUINT8 format; /* Format identifier--format = 0 */ + HBUINT8 entryFormat; /* A packed field that describes the compressed + * representation of delta-set indices. */ + MapCountT mapCount; /* The number of mapping entries. */ + UnsizedArrayOf + mapDataZ; /* The delta-set index mapping data. */ + + public: + DEFINE_SIZE_ARRAY (2+MapCountT::static_size, mapDataZ); +}; + +struct DeltaSetIndexMap +{ + template + bool serialize (hb_serialize_context_t *c, const T &plan) + { + TRACE_SERIALIZE (this); + unsigned length = plan.get_output_map ().length; + u.format = length <= 0xFFFF ? 0 : 1; + switch (u.format) { + case 0: hb_barrier (); return_trace (u.format0.serialize (c, plan)); + case 1: hb_barrier (); return_trace (u.format1.serialize (c, plan)); + default:return_trace (false); + } + } + + uint32_t map (unsigned v) const + { + switch (u.format) { + case 0: hb_barrier (); return (u.format0.map (v)); + case 1: hb_barrier (); return (u.format1.map (v)); + default:return v; + } + } + + unsigned get_map_count () const + { + switch (u.format) { + case 0: hb_barrier (); return u.format0.get_map_count (); + case 1: hb_barrier (); return u.format1.get_map_count (); + default:return 0; + } + } + + unsigned get_width () const + { + switch (u.format) { + case 0: hb_barrier (); return u.format0.get_width (); + case 1: hb_barrier (); return u.format1.get_width (); + default:return 0; + } + } + + unsigned get_inner_bit_count () const + { + switch (u.format) { + case 0: hb_barrier (); return u.format0.get_inner_bit_count (); + case 1: hb_barrier (); return u.format1.get_inner_bit_count (); + default:return 0; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); + switch (u.format) { + case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + default:return_trace (true); + } + } + + DeltaSetIndexMap* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + switch (u.format) { + case 0: hb_barrier (); return_trace (reinterpret_cast (u.format0.copy (c))); + case 1: hb_barrier (); return_trace (reinterpret_cast (u.format1.copy (c))); + default:return_trace (nullptr); + } + } + + protected: + union { + HBUINT8 format; /* Format identifier */ + DeltaSetIndexMapFormat01 format0; + DeltaSetIndexMapFormat01 format1; + } u; + public: + DEFINE_SIZE_UNION (1, format); +}; + + +struct ItemVarStoreInstancer +{ + ItemVarStoreInstancer (const ItemVariationStore *varStore_, + const DeltaSetIndexMap *varIdxMap, + hb_array_t coords, + VarRegionList::cache_t *cache = nullptr) : + varStore (varStore_), varIdxMap (varIdxMap), coords (coords), cache (cache) + { + if (!varStore) + varStore = &Null(ItemVariationStore); + } + + operator bool () const { return varStore && bool (coords); } + + float operator[] (uint32_t varIdx) const + { return (*this) (varIdx); } + + float operator() (uint32_t varIdx, unsigned short offset = 0) const + { + if (!coords || varIdx == VarIdx::NO_VARIATION) + return 0.f; + + varIdx += offset; + if (varIdxMap) + varIdx = varIdxMap->map (varIdx); + return varStore->get_delta (varIdx, coords, cache); + } + + const ItemVariationStore *varStore; + const DeltaSetIndexMap *varIdxMap; + hb_array_t coords; + VarRegionList::cache_t *cache; +}; + +struct MultiItemVarStoreInstancer +{ + MultiItemVarStoreInstancer (const MultiItemVariationStore *varStore, + const DeltaSetIndexMap *varIdxMap, + hb_array_t coords, + SparseVarRegionList::cache_t *cache = nullptr) : + varStore (varStore), varIdxMap (varIdxMap), coords (coords), cache (cache) + { + if (!varStore) + varStore = &Null(MultiItemVariationStore); + } + + operator bool () const { return varStore && bool (coords); } + + float operator[] (uint32_t varIdx) const + { + float v = 0; + (*this) (hb_array (&v, 1), varIdx); + return v; + } + + void operator() (hb_array_t out, uint32_t varIdx, unsigned short offset = 0) const + { + if (coords && varIdx != VarIdx::NO_VARIATION) + { + varIdx += offset; + if (varIdxMap) + varIdx = varIdxMap->map (varIdx); + varStore->get_delta (varIdx, coords, out, cache); + } + else + for (unsigned i = 0; i < out.length; i++) + out.arrayZ[i] = 0.f; + } + + const MultiItemVariationStore *varStore; + const DeltaSetIndexMap *varIdxMap; + hb_array_t coords; + SparseVarRegionList::cache_t *cache; +}; + + /* * Feature Variations */ @@ -3278,7 +3811,16 @@ enum Cond_with_Var_flag_t DROP_RECORD_WITH_VAR = 3, }; -struct ConditionFormat1 +struct Condition; + +template +static bool +_hb_recurse_condition_evaluate (const struct Condition &condition, + const int *coords, + unsigned int coord_len, + Instancer *instancer); + +struct ConditionAxisRange { friend struct Condition; @@ -3298,19 +3840,19 @@ struct ConditionFormat1 return_trace (false); const hb_hashmap_t& normalized_axes_location = c->plan->axes_location; - Triple axis_limit{-1.f, 0.f, 1.f}; + Triple axis_limit{-1.0, 0.0, 1.0}; Triple *normalized_limit; if (normalized_axes_location.has (*axis_tag, &normalized_limit)) axis_limit = *normalized_limit; const hb_hashmap_t& axes_triple_distances = c->plan->axes_triple_distances; - TripleDistances axis_triple_distances{1.f, 1.f}; + TripleDistances axis_triple_distances{1.0, 1.0}; TripleDistances *triple_dists; if (axes_triple_distances.has (*axis_tag, &triple_dists)) axis_triple_distances = *triple_dists; - float normalized_min = renormalizeValue (filterRangeMinValue.to_float (), axis_limit, axis_triple_distances, false); - float normalized_max = renormalizeValue (filterRangeMaxValue.to_float (), axis_limit, axis_triple_distances, false); + float normalized_min = renormalizeValue ((double) filterRangeMinValue.to_float (), axis_limit, axis_triple_distances, false); + float normalized_max = renormalizeValue ((double) filterRangeMaxValue.to_float (), axis_limit, axis_triple_distances, false); out->filterRangeMinValue.set_float (normalized_min); out->filterRangeMaxValue.set_float (normalized_max); @@ -3328,10 +3870,14 @@ struct ConditionFormat1 hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex); - Triple axis_range (-1.f, 0.f, 1.f); + Triple axis_range (-1.0, 0.0, 1.0); Triple *axis_limit; + bool axis_set_by_user = false; if (c->axes_location->has (axis_tag, &axis_limit)) + { axis_range = *axis_limit; + axis_set_by_user = true; + } float axis_min_val = axis_range.minimum; float axis_default_val = axis_range.middle; @@ -3350,26 +3896,26 @@ struct ConditionFormat1 return DROP_RECORD_WITH_VAR; //condition met and axis pinned, drop the condition - if (c->axes_location->has (axis_tag) && - c->axes_location->get (axis_tag).is_point ()) + if (axis_set_by_user && axis_range.is_point ()) return DROP_COND_WITH_VAR; if (filter_max_val != axis_max_val || filter_min_val != axis_min_val) { // add axisIndex->value into the hashmap so we can check if the record is // unique with variations - int16_t int_filter_max_val = filterRangeMaxValue.to_int (); - int16_t int_filter_min_val = filterRangeMinValue.to_int (); + uint16_t int_filter_max_val = (uint16_t) filterRangeMaxValue.to_int (); + uint16_t int_filter_min_val = (uint16_t) filterRangeMinValue.to_int (); hb_codepoint_t val = (int_filter_max_val << 16) + int_filter_min_val; condition_map->set (axisIndex, val); return KEEP_COND_WITH_VAR; } - return KEEP_RECORD_WITH_VAR; } - bool evaluate (const int *coords, unsigned int coord_len) const + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer HB_UNUSED) const { int coord = axisIndex < coord_len ? coords[axisIndex] : 0; return filterRangeMinValue.to_int () <= coord && coord <= filterRangeMaxValue.to_int (); @@ -3390,12 +3936,199 @@ struct ConditionFormat1 DEFINE_SIZE_STATIC (8); }; +struct ConditionValue +{ + friend struct Condition; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + private: + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { + signed value = defaultValue; + value += (*instancer)[varIdx]; + return value > 0; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + bool insert_catch_all) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 2 */ + HBINT16 defaultValue; /* Value at default instance. */ + VarIdx varIdx; /* Variation index */ + public: + DEFINE_SIZE_STATIC (8); +}; + +struct ConditionAnd +{ + friend struct Condition; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + private: + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { + unsigned int count = conditions.len; + for (unsigned int i = 0; i < count; i++) + if (!_hb_recurse_condition_evaluate (this+conditions.arrayZ[i], + coords, coord_len, + instancer)) + return false; + return true; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + bool insert_catch_all) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (conditions.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 3 */ + Array8OfOffset24To conditions; + public: + DEFINE_SIZE_ARRAY (3, conditions); +}; + +struct ConditionOr +{ + friend struct Condition; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + private: + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { + unsigned int count = conditions.len; + for (unsigned int i = 0; i < count; i++) + if (_hb_recurse_condition_evaluate (this+conditions.arrayZ[i], + coords, coord_len, + instancer)) + return true; + return false; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + bool insert_catch_all) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (conditions.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 4 */ + Array8OfOffset24To conditions; + public: + DEFINE_SIZE_ARRAY (3, conditions); +}; + +struct ConditionNegate +{ + friend struct Condition; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + private: + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const + { + return !_hb_recurse_condition_evaluate (this+condition, + coords, coord_len, + instancer); + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + bool insert_catch_all) const + { + TRACE_SUBSET (this); + // TODO(subset) + return_trace (false); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (condition.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 5 */ + Offset24To condition; + public: + DEFINE_SIZE_STATIC (5); +}; + struct Condition { - bool evaluate (const int *coords, unsigned int coord_len) const + template + bool evaluate (const int *coords, unsigned int coord_len, + Instancer *instancer) const { switch (u.format) { - case 1: return u.format1.evaluate (coords, coord_len); + case 1: hb_barrier (); return u.format1.evaluate (coords, coord_len, instancer); + case 2: hb_barrier (); return u.format2.evaluate (coords, coord_len, instancer); + case 3: hb_barrier (); return u.format3.evaluate (coords, coord_len, instancer); + case 4: hb_barrier (); return u.format4.evaluate (coords, coord_len, instancer); + case 5: hb_barrier (); return u.format5.evaluate (coords, coord_len, instancer); default:return false; } } @@ -3404,7 +4137,8 @@ struct Condition hb_map_t *condition_map /* OUT */) const { switch (u.format) { - case 1: return u.format1.keep_with_variations (c, condition_map); + case 1: hb_barrier (); return u.format1.keep_with_variations (c, condition_map); + // TODO(subset) default: c->apply = false; return KEEP_COND_WITH_VAR; } } @@ -3415,7 +4149,11 @@ struct Condition if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward (ds)...)); + case 5: hb_barrier (); return_trace (c->dispatch (u.format5, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -3424,8 +4162,13 @@ struct Condition { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); + case 5: hb_barrier (); return_trace (u.format5.sanitize (c)); default:return_trace (true); } } @@ -3433,19 +4176,51 @@ struct Condition protected: union { HBUINT16 format; /* Format identifier */ - ConditionFormat1 format1; + ConditionAxisRange format1; + ConditionValue format2; + ConditionAnd format3; + ConditionOr format4; + ConditionNegate format5; } u; public: DEFINE_SIZE_UNION (2, format); }; +template +bool +_hb_recurse_condition_evaluate (const struct Condition &condition, + const int *coords, + unsigned int coord_len, + Instancer *instancer) +{ + return condition.evaluate (coords, coord_len, instancer); +} + +struct ConditionList +{ + const Condition& operator[] (unsigned i) const + { return this+conditions[i]; } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (conditions.sanitize (c, this)); + } + + protected: + Array32OfOffset32To conditions; + public: + DEFINE_SIZE_ARRAY (4, conditions); +}; + struct ConditionSet { - bool evaluate (const int *coords, unsigned int coord_len) const + bool evaluate (const int *coords, unsigned int coord_len, + ItemVarStoreInstancer *instancer) const { unsigned int count = conditions.len; for (unsigned int i = 0; i < count; i++) - if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len)) + if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len, instancer)) return false; return true; } @@ -3497,12 +4272,15 @@ struct ConditionSet } bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const + hb_subset_layout_context_t *l, + bool insert_catch_all) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (insert_catch_all) return_trace (true); + hb_set_t *retained_cond_set = nullptr; if (l->feature_record_cond_idx_map != nullptr) retained_cond_set = l->feature_record_cond_idx_map->get (l->cur_feature_var_record_idx); @@ -3548,27 +4326,51 @@ struct FeatureTableSubstitutionRecord } void collect_feature_substitutes_with_variations (hb_hashmap_t *feature_substitutes_map, + hb_set_t& catch_all_record_feature_idxes, const hb_set_t *feature_indices, const void *base) const { if (feature_indices->has (featureIndex)) + { feature_substitutes_map->set (featureIndex, &(base+feature)); + catch_all_record_feature_idxes.add (featureIndex); + } + } + + bool serialize (hb_subset_layout_context_t *c, + unsigned feature_index, + const Feature *f, const Tag *tag) + { + TRACE_SERIALIZE (this); + hb_serialize_context_t *s = c->subset_context->serializer; + if (unlikely (!s->extend_min (this))) return_trace (false); + + uint32_t *new_feature_idx; + if (!c->feature_index_map->has (feature_index, &new_feature_idx)) + return_trace (false); + + if (!s->check_assign (featureIndex, *new_feature_idx, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + + s->push (); + bool ret = f->subset (c->subset_context, c, tag); + if (ret) s->add_link (feature, s->pop_pack ()); + else s->pop_discard (); + + return_trace (ret); } bool subset (hb_subset_layout_context_t *c, const void *base) const { TRACE_SUBSET (this); - if (!c->feature_index_map->has (featureIndex) || - c->feature_substitutes_map->has (featureIndex)) { - // Feature that is being substituted is not being retained, so we don't - // need this. + uint32_t *new_feature_index; + if (!c->feature_index_map->has (featureIndex, &new_feature_index)) return_trace (false); - } auto *out = c->subset_context->serializer->embed (this); if (unlikely (!out)) return_trace (false); - out->featureIndex = c->feature_index_map->get (featureIndex); + out->featureIndex = *new_feature_index; return_trace (out->feature.serialize_subset (c->subset_context, feature, base, c)); } @@ -3600,16 +4402,10 @@ struct FeatureTableSubstitution } void collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, hb_set_t *lookup_indexes /* OUT */) const { + hb_iter (substitutions) | hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex) - | hb_filter ([feature_substitutes_map] (const FeatureTableSubstitutionRecord& record) - { - if (feature_substitutes_map == nullptr) return true; - return !feature_substitutes_map->has (record.featureIndex); - }) | hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r) { r.collect_lookups (this, lookup_indexes); }) ; @@ -3634,11 +4430,14 @@ struct FeatureTableSubstitution void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const { for (const FeatureTableSubstitutionRecord& record : substitutions) - record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, c->feature_indices, this); + record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, + c->catch_all_record_feature_idxes, + c->feature_indices, this); } bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const + hb_subset_layout_context_t *l, + bool insert_catch_all) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); @@ -3647,6 +4446,22 @@ struct FeatureTableSubstitution out->version.major = version.major; out->version.minor = version.minor; + if (insert_catch_all) + { + for (unsigned feature_index : *(l->catch_all_record_feature_idxes)) + { + hb_pair_t *p; + if (!l->feature_idx_tag_map->has (feature_index, &p)) + return_trace (false); + auto *o = out->substitutions.serialize_append (c->serializer); + if (!o->serialize (l, feature_index, + reinterpret_cast (p->first), + reinterpret_cast (p->second))) + return_trace (false); + } + return_trace (true); + } + + substitutions.iter () | hb_apply (subset_record_array (l, &(out->substitutions), this)) ; @@ -3658,6 +4473,7 @@ struct FeatureTableSubstitution { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && substitutions.sanitize (c, this)); } @@ -3676,10 +4492,9 @@ struct FeatureVariationRecord void collect_lookups (const void *base, const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, hb_set_t *lookup_indexes /* OUT */) const { - return (base+substitutions).collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes); + return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes); } void closure_features (const void *base, @@ -3705,14 +4520,15 @@ struct FeatureVariationRecord } } - bool subset (hb_subset_layout_context_t *c, const void *base) const + bool subset (hb_subset_layout_context_t *c, const void *base, + bool insert_catch_all = false) const { TRACE_SUBSET (this); auto *out = c->subset_context->serializer->embed (this); if (unlikely (!out)) return_trace (false); - out->conditions.serialize_subset (c->subset_context, conditions, base, c); - out->substitutions.serialize_subset (c->subset_context, substitutions, base, c); + out->conditions.serialize_subset (c->subset_context, conditions, base, c, insert_catch_all); + out->substitutions.serialize_subset (c->subset_context, substitutions, base, c, insert_catch_all); return_trace (true); } @@ -3738,13 +4554,14 @@ struct FeatureVariations static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFFFFFu; bool find_index (const int *coords, unsigned int coord_len, - unsigned int *index) const + unsigned int *index, + ItemVarStoreInstancer *instancer) const { unsigned int count = varRecords.len; for (unsigned int i = 0; i < count; i++) { const FeatureVariationRecord &record = varRecords.arrayZ[i]; - if ((this+record.conditions).evaluate (coords, coord_len)) + if ((this+record.conditions).evaluate (coords, coord_len, instancer)) { *index = i; return true; @@ -3771,9 +4588,8 @@ struct FeatureVariations if (c->universal) break; } - if (c->variation_applied && !c->universal && - !c->record_cond_idx_map->is_empty ()) - c->insert_catch_all_feature_variation_record = true; + if (c->universal || c->record_cond_idx_map->is_empty ()) + c->catch_all_record_feature_idxes.reset (); } FeatureVariations* copy (hb_serialize_context_t *c) const @@ -3783,11 +4599,17 @@ struct FeatureVariations } void collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, + const hb_hashmap_t> *feature_record_cond_idx_map, hb_set_t *lookup_indexes /* OUT */) const { - for (const FeatureVariationRecord& r : varRecords) - r.collect_lookups (this, feature_indexes, feature_substitutes_map, lookup_indexes); + unsigned count = varRecords.len; + for (unsigned int i = 0; i < count; i++) + { + if (feature_record_cond_idx_map && + !feature_record_cond_idx_map->has (i)) + continue; + varRecords[i].collect_lookups (this, feature_indexes, lookup_indexes); + } } void closure_features (const hb_map_t *lookup_indexes, @@ -3832,6 +4654,13 @@ struct FeatureVariations l->cur_feature_var_record_idx = i; subset_record_array (l, &(out->varRecords), this) (varRecords[i]); } + + if (out->varRecords.len && !l->catch_all_record_feature_idxes->is_empty ()) + { + bool insert_catch_all_record = true; + subset_record_array (l, &(out->varRecords), this, insert_catch_all_record) (varRecords[0]); + } + return_trace (bool (out->varRecords)); } @@ -3839,6 +4668,7 @@ struct FeatureVariations { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && varRecords.sanitize (c, this)); } @@ -3945,13 +4775,13 @@ struct VariationDevice private: hb_position_t get_x_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { return font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { return font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, @@ -3985,14 +4815,14 @@ struct VariationDevice private: float get_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache); + return store.get_delta (varIdx, font->coords, font->num_coords, (ItemVariationStore::cache_t *) store_cache); } protected: - VarIdx varIdx; + VarIdx varIdx; /* Variation index */ HBUINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */ public: DEFINE_SIZE_STATIC (6); @@ -4012,8 +4842,8 @@ struct DeviceHeader struct Device { hb_position_t get_x_delta (hb_font_t *font, - const VariationStore &store=Null (VariationStore), - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store=Null (ItemVariationStore), + ItemVariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4030,8 +4860,8 @@ struct Device } } hb_position_t get_y_delta (hb_font_t *font, - const VariationStore &store=Null (VariationStore), - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store=Null (ItemVariationStore), + ItemVariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh index d5b5a488a26..1a719391b8e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh @@ -406,6 +406,7 @@ struct hb_ot_apply_context_t : void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } + void set_ignore_hidden (bool ignore_hidden_) { ignore_hidden = ignore_hidden_; } void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } void set_mask (hb_mask_t mask_) { mask = mask_; } void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; } @@ -451,9 +452,10 @@ struct hb_ot_apply_context_t : if (!c->check_glyph_property (&info, lookup_props)) return SKIP_YES; - if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_hidden (&info) && + if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && - (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) + (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && + (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) return SKIP_MAYBE; return SKIP_NO; @@ -464,6 +466,7 @@ struct hb_ot_apply_context_t : hb_mask_t mask = -1; bool ignore_zwnj = false; bool ignore_zwj = false; + bool ignore_hidden = false; bool per_syllable = false; uint8_t syllable = 0; match_func_t match_func = nullptr; @@ -486,6 +489,8 @@ struct hb_ot_apply_context_t : matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); /* Ignore ZWJ if we are matching context, or asked to. */ matcher.set_ignore_zwj (context_match || c->auto_zwj); + /* Ignore hidden glyphs (like CGJ) during GPOS. */ + matcher.set_ignore_hidden (c->table_index == 1); matcher.set_mask (context_match ? -1 : c->lookup_mask); /* Per syllable matching is only for GSUB. */ matcher.set_per_syllable (c->table_index == 0 && c->per_syllable); @@ -708,8 +713,9 @@ struct hb_ot_apply_context_t : recurse_func_t recurse_func = nullptr; const GDEF &gdef; const GDEF::accelerator_t &gdef_accel; - const VariationStore &var_store; - VariationStore::cache_t *var_store_cache; + const hb_ot_layout_lookup_accelerator_t *lookup_accel = nullptr; + const ItemVariationStore &var_store; + ItemVariationStore::cache_t *var_store_cache; hb_set_digest_t digest; hb_direction_t direction; @@ -723,7 +729,6 @@ struct hb_ot_apply_context_t : bool auto_zwj = true; bool per_syllable = false; bool random = false; - uint32_t random_state = 1; unsigned new_syllables = (unsigned) -1; signed last_base = -1; // GPOS uses @@ -758,15 +763,17 @@ struct hb_ot_apply_context_t : nullptr #endif ), - digest (buffer_->digest ()), direction (buffer_->props.direction), has_glyph_classes (gdef.has_glyph_classes ()) - { init_iters (); } + { + init_iters (); + buffer->collect_codepoints (digest); + } ~hb_ot_apply_context_t () { #ifndef HB_NO_VAR - VariationStore::destroy_cache (var_store_cache); + ItemVariationStore::destroy_cache (var_store_cache); #endif } @@ -788,8 +795,8 @@ struct hb_ot_apply_context_t : uint32_t random_number () { /* http://www.cplusplus.com/reference/random/minstd_rand/ */ - random_state = random_state * 48271 % 2147483647; - return random_state; + buffer->random_state = buffer->random_state * 48271 % 2147483647; + return buffer->random_state; } bool match_properties_mark (hb_codepoint_t glyph, @@ -895,6 +902,13 @@ struct hb_ot_apply_context_t : } }; +enum class hb_ot_lookup_cache_op_t +{ + CREATE, + ENTER, + LEAVE, + DESTROY, +}; struct hb_accelerate_subtables_context_t : hb_dispatch_context_t @@ -919,19 +933,23 @@ struct hb_accelerate_subtables_context_t : } template - static inline auto cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) ) - template - static inline bool cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; } + static inline auto cache_func_ (void *p, + hb_ot_lookup_cache_op_t op, + hb_priority<1>) HB_RETURN (void *, T::cache_func (p, op) ) + template + static inline void * cache_func_ (void *p, + hb_ot_lookup_cache_op_t op HB_UNUSED, + hb_priority<0>) { return (void *) false; } template - static inline bool cache_func_to (const void *obj, hb_ot_apply_context_t *c, bool enter) + static inline void * cache_func_to (void *p, + hb_ot_lookup_cache_op_t op) { - const Type *typed_obj = (const Type *) obj; - return cache_func_ (typed_obj, c, enter, hb_prioritize); + return cache_func_ (p, op, hb_prioritize); } #endif typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c); - typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter); + typedef void * (*hb_cache_func_t) (void *p, hb_ot_lookup_cache_op_t op); struct hb_applicable_t { @@ -968,11 +986,11 @@ struct hb_accelerate_subtables_context_t : } bool cache_enter (hb_ot_apply_context_t *c) const { - return cache_func (obj, c, true); + return (bool) cache_func (c, hb_ot_lookup_cache_op_t::ENTER); } void cache_leave (hb_ot_apply_context_t *c) const { - cache_func (obj, c, false); + cache_func (c, hb_ot_lookup_cache_op_t::LEAVE); } #endif @@ -1255,7 +1273,7 @@ static bool match_input (hb_ot_apply_context_t *c, match_func_t match_func, const void *match_data, unsigned int *end_position, - unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], + unsigned int *match_positions, unsigned int *p_total_component_count = nullptr) { TRACE_APPLY (nullptr); @@ -1379,7 +1397,7 @@ static bool match_input (hb_ot_apply_context_t *c, } static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ + const unsigned int *match_positions, /* Including the first glyph */ unsigned int match_end, hb_codepoint_t lig_glyph, unsigned int total_component_count) @@ -1458,6 +1476,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); if (this_comp == 0) this_comp = last_num_components; + assert (components_so_far >= last_num_components); unsigned int new_lig_comp = components_so_far - last_num_components + hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); @@ -1483,6 +1502,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); if (!this_comp) break; + assert (components_so_far >= last_num_components); unsigned new_lig_comp = components_so_far - last_num_components + hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); @@ -1538,6 +1558,7 @@ static bool match_lookahead (hb_ot_apply_context_t *c, TRACE_APPLY (nullptr); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + assert (start_index >= 1); skippy_iter.reset (start_index - 1); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (lookahead); @@ -1687,7 +1708,7 @@ static inline void recurse_lookups (context_t *c, static inline void apply_lookup (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ + unsigned int *match_positions, /* Including the first glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ unsigned int match_end) @@ -1695,6 +1716,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; int end; + unsigned int *match_positions_input = match_positions; + unsigned int match_positions_count = count; + /* All positions are distance from beginning of *output* buffer. * Adjust. */ { @@ -1798,6 +1822,27 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, { if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) break; + if (unlikely (delta + count > match_positions_count)) + { + unsigned new_match_positions_count = hb_max (delta + count, hb_max(match_positions_count, 4u) * 1.5); + if (match_positions == match_positions_input) + { + match_positions = (unsigned int *) hb_malloc (new_match_positions_count * sizeof (match_positions[0])); + if (unlikely (!match_positions)) + break; + memcpy (match_positions, match_positions_input, count * sizeof (match_positions[0])); + match_positions_count = new_match_positions_count; + } + else + { + unsigned int *new_match_positions = (unsigned int *) hb_realloc (match_positions, new_match_positions_count * sizeof (match_positions[0])); + if (unlikely (!new_match_positions)) + break; + match_positions = new_match_positions; + match_positions_count = new_match_positions_count; + } + } + } else { @@ -1821,6 +1866,10 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, match_positions[next] += delta; } + if (match_positions != match_positions_input) + hb_free (match_positions); + + assert (end >= 0); (void) buffer->move_to (end); } @@ -1921,8 +1970,18 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, const LookupRecord lookupRecord[], const ContextApplyLookupContext &lookup_context) { + if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; + unsigned match_positions_stack[4]; + unsigned *match_positions = match_positions_stack; + if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) + { + match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); + if (unlikely (!match_positions)) + return false; + } + unsigned match_end = 0; - unsigned match_positions[HB_MAX_CONTEXT_LENGTH]; + bool ret = false; if (match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, @@ -1933,13 +1992,18 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, inputCount, match_positions, lookupCount, lookupRecord, match_end); - return true; + ret = true; } else { c->buffer->unsafe_to_concat (c->buffer->idx, match_end); - return false; + ret = false; } + + if (unlikely (match_positions != match_positions_stack)) + hb_free (match_positions); + + return ret; } template @@ -2051,6 +2115,7 @@ struct Rule { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (inputZ.arrayZ, inputZ.item_size * (inputCount ? inputCount - 1 : 0) + LookupRecord::static_size * lookupCount)); @@ -2572,25 +2637,35 @@ struct ContextFormat2_5 unsigned c = (this+classDef).cost () * ruleSet.len; return c >= 4 ? c : 0; } - bool cache_func (hb_ot_apply_context_t *c, bool enter) const + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) { - if (enter) - { - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return true; - } - else + switch (op) { - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return true; + case hb_ot_lookup_cache_op_t::CREATE: + return (void *) true; + case hb_ot_lookup_cache_op_t::ENTER: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return (void *) false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return (void *) true; + } + case hb_ot_lookup_cache_op_t::LEAVE: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + return nullptr; + } + case hb_ot_lookup_cache_op_t::DESTROY: + return nullptr; } + return nullptr; } bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } @@ -2599,7 +2674,7 @@ struct ContextFormat2_5 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ClassDef &class_def = this+classDef; @@ -2785,7 +2860,7 @@ struct ContextFormat3 { TRACE_APPLY (this); unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); struct ContextApplyLookupContext lookup_context = { @@ -2826,6 +2901,7 @@ struct ContextFormat3 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); unsigned int count = glyphCount; if (unlikely (!count)) return_trace (false); /* We want to access coverageZ[0] freely. */ if (unlikely (!c->check_array (coverageZ.arrayZ, count))) return_trace (false); @@ -2858,12 +2934,12 @@ struct Context if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); - case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); - case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K - case 4: return_trace (c->dispatch (u.format4, std::forward (ds)...)); - case 5: return_trace (c->dispatch (u.format5, std::forward (ds)...)); + case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward (ds)...)); + case 5: hb_barrier (); return_trace (c->dispatch (u.format5, std::forward (ds)...)); #endif default:return_trace (c->default_return_value ()); } @@ -3017,9 +3093,20 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, const LookupRecord lookupRecord[], const ChainContextApplyLookupContext &lookup_context) { + if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; + unsigned match_positions_stack[4]; + unsigned *match_positions = match_positions_stack; + if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) + { + match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); + if (unlikely (!match_positions)) + return false; + } + + unsigned start_index = c->buffer->out_len; unsigned end_index = c->buffer->idx; unsigned match_end = 0; - unsigned match_positions[HB_MAX_CONTEXT_LENGTH]; + bool ret = true; if (!(match_input (c, inputCount, input, lookup_context.funcs.match[1], lookup_context.match_data[1], @@ -3030,17 +3117,18 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, match_end, &end_index))) { c->buffer->unsafe_to_concat (c->buffer->idx, end_index); - return false; + ret = false; + goto done; } - unsigned start_index = c->buffer->out_len; if (!match_backtrack (c, backtrackCount, backtrack, lookup_context.funcs.match[0], lookup_context.match_data[0], &start_index)) { c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index); - return false; + ret = false; + goto done; } c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); @@ -3048,7 +3136,12 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, inputCount, match_positions, lookupCount, lookupRecord, match_end); - return true; + done: + + if (unlikely (match_positions != match_positions_stack)) + hb_free (match_positions); + + return ret; } template @@ -3219,10 +3312,13 @@ struct ChainRule TRACE_SANITIZE (this); /* Hyper-optimized sanitized because this is really hot. */ if (unlikely (!backtrack.len.sanitize (c))) return_trace (false); + hb_barrier (); const auto &input = StructAfter (backtrack); if (unlikely (!input.lenP1.sanitize (c))) return_trace (false); + hb_barrier (); const auto &lookahead = StructAfter (input); if (unlikely (!lookahead.len.sanitize (c))) return_trace (false); + hb_barrier (); const auto &lookup = StructAfter (lookahead); return_trace (likely (lookup.sanitize (c))); } @@ -3327,6 +3423,15 @@ struct ChainRuleSet * * Replicated from LigatureSet::apply(). */ + /* If the input skippy has non-auto joiners behavior (as in Indic shapers), + * skip this fast path, as we don't distinguish between input & lookahead + * matching in the fast path. + * + * https://github.com/harfbuzz/harfbuzz/issues/4813 + */ + if (!c->auto_zwnj || !c->auto_zwj) + goto slow; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); @@ -3366,10 +3471,10 @@ struct ChainRuleSet } matched = skippy_iter.next (); if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) - { + { second = &c->buffer->info[skippy_iter.idx]; unsafe_to2 = skippy_iter.idx + 1; - } + } auto match_input = lookup_context.funcs.match[1]; auto match_lookahead = lookup_context.funcs.match[2]; @@ -3569,7 +3674,7 @@ struct ChainContextFormat1_4 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ChainRuleSet &rule_set = this+ruleSet[index]; struct ChainContextApplyLookupContext lookup_context = { @@ -3780,28 +3885,37 @@ struct ChainContextFormat2_5 unsigned cache_cost () const { - unsigned c = (this+lookaheadClassDef).cost () * ruleSet.len; - return c >= 4 ? c : 0; + return (this+lookaheadClassDef).cost () * ruleSet.len; } - bool cache_func (hb_ot_apply_context_t *c, bool enter) const + static void * cache_func (void *p, hb_ot_lookup_cache_op_t op) { - if (enter) + switch (op) { - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return true; - } - else - { - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return true; + case hb_ot_lookup_cache_op_t::CREATE: + return (void *) true; + case hb_ot_lookup_cache_op_t::ENTER: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return (void *) false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return (void *) true; + } + case hb_ot_lookup_cache_op_t::LEAVE: + { + hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p; + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + return nullptr; + } + case hb_ot_lookup_cache_op_t::DESTROY: + return nullptr; } + return nullptr; } bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } @@ -3810,7 +3924,7 @@ struct ChainContextFormat2_5 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; @@ -4056,7 +4170,7 @@ struct ChainContextFormat3 const auto &input = StructAfter (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const auto &lookahead = StructAfter (input); const auto &lookup = StructAfter (lookahead); @@ -4121,11 +4235,14 @@ struct ChainContextFormat3 { TRACE_SANITIZE (this); if (unlikely (!backtrack.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &input = StructAfter (backtrack); if (unlikely (!input.sanitize (c, this))) return_trace (false); + hb_barrier (); if (unlikely (!input.len)) return_trace (false); /* To be consistent with Context. */ const auto &lookahead = StructAfter (input); if (unlikely (!lookahead.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &lookup = StructAfter (lookahead); return_trace (likely (lookup.sanitize (c))); } @@ -4159,12 +4276,12 @@ struct ChainContext if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); - case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); - case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K - case 4: return_trace (c->dispatch (u.format4, std::forward (ds)...)); - case 5: return_trace (c->dispatch (u.format5, std::forward (ds)...)); + case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward (ds)...)); + case 5: hb_barrier (); return_trace (c->dispatch (u.format5, std::forward (ds)...)); #endif default:return_trace (c->default_return_value ()); } @@ -4209,6 +4326,7 @@ struct ExtensionFormat1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && extensionLookupType != T::SubTable::Extension); } @@ -4247,7 +4365,7 @@ struct Extension unsigned int get_type () const { switch (u.format) { - case 1: return u.format1.get_type (); + case 1: hb_barrier (); return u.format1.get_type (); default:return 0; } } @@ -4255,7 +4373,7 @@ struct Extension const X& get_subtable () const { switch (u.format) { - case 1: return u.format1.template get_subtable (); + case 1: hb_barrier (); return u.format1.template get_subtable (); default:return Null (typename T::SubTable); } } @@ -4267,7 +4385,7 @@ struct Extension typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const { switch (u.format) { - case 1: return u.format1.subset (c); + case 1: hb_barrier (); return u.format1.subset (c); default: return c->default_return_value (); } } @@ -4278,7 +4396,7 @@ struct Extension if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (u.format1.dispatch (c, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (u.format1.dispatch (c, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -4320,10 +4438,21 @@ struct hb_ot_layout_lookup_accelerator_t thiz->digest.init (); for (auto& subtable : hb_iter (thiz->subtables, count)) - thiz->digest.add (subtable.digest); + thiz->digest.union_ (subtable.digest); #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + if (c_accelerate_subtables.cache_user_cost < 4) + c_accelerate_subtables.cache_user_idx = (unsigned) -1; + thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx; + + if (thiz->cache_user_idx != (unsigned) -1) + { + thiz->cache = thiz->subtables[thiz->cache_user_idx].cache_func (nullptr, hb_ot_lookup_cache_op_t::CREATE); + if (!thiz->cache) + thiz->cache_user_idx = (unsigned) -1; + } + for (unsigned i = 0; i < count; i++) if (i != thiz->cache_user_idx) thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; @@ -4332,6 +4461,17 @@ struct hb_ot_layout_lookup_accelerator_t return thiz; } + void fini () + { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + if (cache) + { + assert (cache_user_idx != (unsigned) -1); + subtables[cache_user_idx].cache_func (cache, hb_ot_lookup_cache_op_t::DESTROY); + } +#endif + } + bool may_have (hb_codepoint_t g) const { return digest.may_have (g); } @@ -4340,6 +4480,7 @@ struct hb_ot_layout_lookup_accelerator_t #endif bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const { + c->lookup_accel = this; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE if (use_cache) { @@ -4379,10 +4520,13 @@ struct hb_ot_layout_lookup_accelerator_t hb_set_digest_t digest; - private: #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + public: + void *cache = nullptr; + private: unsigned cache_user_idx = (unsigned) -1; #endif + private: hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; }; @@ -4472,13 +4616,6 @@ struct GSUBGPOSVersion1_2 if (!c->subset_context->serializer->extend_min (&out->featureVars)) return_trace (false); - // TODO(qxliu76): the current implementation doesn't correctly handle feature variations - // that are dropped by instancing when the associated conditions don't trigger. - // Since partial instancing isn't yet supported this isn't an issue yet but will - // need to be fixed for partial instancing. - - - // if all axes are pinned all feature vars are dropped. bool ret = !c->subset_context->plan->all_axes_pinned && out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); @@ -4500,9 +4637,9 @@ struct GSUBGPOS unsigned int get_size () const { switch (u.version.major) { - case 1: return u.version1.get_size (); + case 1: hb_barrier (); return u.version1.get_size (); #ifndef HB_NO_BEYOND_64K - case 2: return u.version2.get_size (); + case 2: hb_barrier (); return u.version2.get_size (); #endif default: return u.version.static_size; } @@ -4513,10 +4650,11 @@ struct GSUBGPOS { TRACE_SANITIZE (this); if (unlikely (!u.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.version.major) { - case 1: return_trace (u.version1.sanitize (c)); + case 1: hb_barrier (); return_trace (u.version1.sanitize (c)); #ifndef HB_NO_BEYOND_64K - case 2: return_trace (u.version2.sanitize (c)); + case 2: hb_barrier (); return_trace (u.version2.sanitize (c)); #endif default: return_trace (true); } @@ -4526,9 +4664,9 @@ struct GSUBGPOS bool subset (hb_subset_layout_context_t *c) const { switch (u.version.major) { - case 1: return u.version1.subset (c); + case 1: hb_barrier (); return u.version1.subset (c); #ifndef HB_NO_BEYOND_64K - case 2: return u.version2.subset (c); + case 2: hb_barrier (); return u.version2.subset (c); #endif default: return false; } @@ -4537,9 +4675,9 @@ struct GSUBGPOS const ScriptList &get_script_list () const { switch (u.version.major) { - case 1: return this+u.version1.scriptList; + case 1: hb_barrier (); return this+u.version1.scriptList; #ifndef HB_NO_BEYOND_64K - case 2: return this+u.version2.scriptList; + case 2: hb_barrier (); return this+u.version2.scriptList; #endif default: return Null (ScriptList); } @@ -4547,9 +4685,9 @@ struct GSUBGPOS const FeatureList &get_feature_list () const { switch (u.version.major) { - case 1: return this+u.version1.featureList; + case 1: hb_barrier (); return this+u.version1.featureList; #ifndef HB_NO_BEYOND_64K - case 2: return this+u.version2.featureList; + case 2: hb_barrier (); return this+u.version2.featureList; #endif default: return Null (FeatureList); } @@ -4557,9 +4695,9 @@ struct GSUBGPOS unsigned int get_lookup_count () const { switch (u.version.major) { - case 1: return (this+u.version1.lookupList).len; + case 1: hb_barrier (); return (this+u.version1.lookupList).len; #ifndef HB_NO_BEYOND_64K - case 2: return (this+u.version2.lookupList).len; + case 2: hb_barrier (); return (this+u.version2.lookupList).len; #endif default: return 0; } @@ -4567,9 +4705,9 @@ struct GSUBGPOS const Lookup& get_lookup (unsigned int i) const { switch (u.version.major) { - case 1: return (this+u.version1.lookupList)[i]; + case 1: hb_barrier (); return (this+u.version1.lookupList)[i]; #ifndef HB_NO_BEYOND_64K - case 2: return (this+u.version2.lookupList)[i]; + case 2: hb_barrier (); return (this+u.version2.lookupList)[i]; #endif default: return Null (Lookup); } @@ -4577,9 +4715,9 @@ struct GSUBGPOS const FeatureVariations &get_feature_variations () const { switch (u.version.major) { - case 1: return (u.version.to_int () >= 0x00010001u ? this+u.version1.featureVars : Null (FeatureVariations)); + case 1: hb_barrier (); return (u.version.to_int () >= 0x00010001u && hb_barrier () ? this+u.version1.featureVars : Null (FeatureVariations)); #ifndef HB_NO_BEYOND_64K - case 2: return this+u.version2.featureVars; + case 2: hb_barrier (); return this+u.version2.featureVars; #endif default: return Null (FeatureVariations); } @@ -4613,13 +4751,14 @@ struct GSUBGPOS { return get_feature_list ().find_index (tag, index); } bool find_variations_index (const int *coords, unsigned int num_coords, - unsigned int *index) const + unsigned int *index, + ItemVarStoreInstancer *instancer) const { #ifdef HB_NO_VAR *index = FeatureVariations::NOT_FOUND_INDEX; return false; #endif - return get_feature_variations ().find_index (coords, num_coords, index); + return get_feature_variations ().find_index (coords, num_coords, index, instancer); } const Feature& get_feature_variation (unsigned int feature_index, unsigned int variations_index) const @@ -4638,11 +4777,11 @@ struct GSUBGPOS } void feature_variation_collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, + const hb_hashmap_t> *feature_record_cond_idx_map, hb_set_t *lookup_indexes /* OUT */) const { #ifndef HB_NO_VAR - get_feature_variations ().collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes); + get_feature_variations ().collect_lookups (feature_indexes, feature_record_cond_idx_map, lookup_indexes); #endif } @@ -4772,7 +4911,12 @@ struct GSUBGPOS ~accelerator_t () { for (unsigned int i = 0; i < this->lookup_count; i++) - hb_free (this->accels[i]); + { + auto *accel = this->accels[i].get_relaxed (); + if (accel) + accel->fini (); + hb_free (accel); + } hb_free (this->accels); this->table.destroy (); } @@ -4793,6 +4937,7 @@ struct GSUBGPOS if (unlikely (!accels[lookup_index].cmpexch (nullptr, accel))) { + accel->fini (); hb_free (accel); goto retry; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-jstf-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-jstf-table.hh index 948c8826925..823520f7483 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-jstf-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-jstf-table.hh @@ -214,6 +214,7 @@ struct JSTF { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && scriptList.sanitize (c, this)); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc index 49465acb75e..787119dc62b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc @@ -87,7 +87,7 @@ using OT::Layout::GPOS; bool hb_ot_layout_has_kerning (hb_face_t *face) { - return face->table.kern->has_data (); + return face->table.kern->table->has_data (); } /** @@ -103,7 +103,7 @@ hb_ot_layout_has_kerning (hb_face_t *face) bool hb_ot_layout_has_machine_kerning (hb_face_t *face) { - return face->table.kern->has_state_machine (); + return face->table.kern->table->has_state_machine (); } /** @@ -123,7 +123,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face) bool hb_ot_layout_has_cross_kerning (hb_face_t *face) { - return face->table.kern->has_cross_stream (); + return face->table.kern->table->has_cross_stream (); } void @@ -132,7 +132,7 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer) { hb_blob_t *blob = font->face->table.kern.get_blob (); - const AAT::kern& kern = *blob->as (); + const auto& kern = *font->face->table.kern; AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); @@ -246,6 +246,18 @@ OT::GDEF::is_blocklisted (hb_blob_t *blob, /* sha1sum: c26e41d567ed821bed997e937bc0c41435689e85 Padauk.ttf * "Padauk Regular" "Version 2.5", see https://crbug.com/681813 */ case HB_CODEPOINT_ENCODE3 (1004, 59092, 14836): + /* 88d2006ca084f04af2df1954ed714a8c71e8400f Courier New.ttf from macOS 15 */ + case HB_CODEPOINT_ENCODE3 (588, 5078, 14418): + /* 608e3ebb6dd1aee521cff08eb07d500a2c59df68 Courier New Bold.ttf from macOS 15 */ + case HB_CODEPOINT_ENCODE3 (588, 5078, 14238): + /* d13221044ff054efd78f1cd8631b853c3ce85676 cour.ttf from Windows 10 */ + case HB_CODEPOINT_ENCODE3 (894, 17162, 33960): + /* 68ed4a22d8067fcf1622ac6f6e2f4d3a2e3ec394 courbd.ttf from Windows 10 */ + case HB_CODEPOINT_ENCODE3 (894, 17154, 34472): + /* 4cdb0259c96b7fd7c103821bb8f08f7cc6b211d7 cour.ttf from Windows 8.1 */ + case HB_CODEPOINT_ENCODE3 (816, 7868, 17052): + /* 920483d8a8ed37f7f0afdabbe7f679aece7c75d8 courbd.ttf from Windows 8.1 */ + case HB_CODEPOINT_ENCODE3 (816, 7868, 17138): return true; } return false; @@ -1443,8 +1455,12 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, unsigned int *variations_index /* out */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + const OT::GDEF &gdef = *face->table.GDEF->table; - return g.find_variations_index (coords, num_coords, variations_index); + auto instancer = OT::ItemVarStoreInstancer(&gdef.get_var_store(), nullptr, + hb_array (coords, num_coords)); + + return g.find_variations_index (coords, num_coords, variations_index, &instancer); } @@ -1907,9 +1923,10 @@ apply_forward (OT::hb_ot_apply_context_t *c, while (buffer->idx < buffer->len && buffer->successful) { bool applied = false; - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props)) + auto &cur = buffer->cur(); + if (accel.digest.may_have (cur.codepoint) && + (cur.mask & c->lookup_mask) && + c->check_glyph_property (&cur, c->lookup_props)) { applied = accel.apply (c, subtable_count, use_cache); } @@ -1935,9 +1952,10 @@ apply_backward (OT::hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; do { - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props)) + auto &cur = buffer->cur(); + if (accel.digest.may_have (cur.codepoint) && + (cur.mask & c->lookup_mask) && + c->check_glyph_property (&cur, c->lookup_props)) ret |= accel.apply (c, subtable_count, false); /* The reverse lookup doesn't "advance" cursor (for good reason). */ @@ -2017,7 +2035,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, * (plus some past glyphs). * * Only try applying the lookup if there is any overlap. */ - if (accel->digest.may_have (c.digest)) + if (accel->digest.may_intersect (c.digest)) { c.set_lookup_index (lookup_index); c.set_lookup_mask (lookup.mask, false); @@ -2043,7 +2061,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (stage->pause_func (plan, font, buffer)) { /* Refresh working buffer digest since buffer changed. */ - c.digest = buffer->digest (); + buffer->collect_codepoints (c.digest); } } } @@ -2127,7 +2145,7 @@ hb_ot_layout_get_font_extents (hb_font_t *font, hb_tag_t language_tag, hb_font_extents_t *extents) { - hb_position_t min, max; + hb_position_t min = 0, max = 0; if (font->face->table.BASE->get_min_max (font, direction, script_tag, language_tag, HB_TAG_NONE, &min, &max)) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh index 2d9a184a893..71074a87401 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh @@ -173,12 +173,12 @@ _hb_next_syllable (hb_buffer_t *buffer, unsigned int start) /* Design: * unicode_props() is a two-byte number. The low byte includes: - * - General_Category: 5 bits. + * - Modified General_Category: 5 bits. * - A bit each for: * * Is it Default_Ignorable(); we have a modified Default_Ignorable(). * * Whether it's one of the four Mongolian Free Variation Selectors, * CGJ, or other characters that are hidden but should not be ignored - * like most other Default_Ignorable()s do during matching. + * like most other Default_Ignorable()s do during GSUB matching. * * Whether it's a grapheme continuation. * * The high-byte has different meanings, switched by the Gen-Cat: @@ -186,17 +186,23 @@ _hb_next_syllable (hb_buffer_t *buffer, unsigned int start) * - For Cf: whether it's ZWJ, ZWNJ, or something else. * - For Ws: index of which space character this is, if space fallback * is needed, ie. we don't set this by default, only if asked to. + * + * Above I said "modified" General_Category. This is because we need to + * remember Variation Selectors, and we don't have bits left. So we + * change their Gen_Cat from Mn to Cf, and use a bit of the high byte to + * remember them. */ enum hb_unicode_props_flags_t { UPROPS_MASK_GEN_CAT = 0x001Fu, UPROPS_MASK_IGNORABLE = 0x0020u, - UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters */ + UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters, or CGJ sometimes */ UPROPS_MASK_CONTINUATION=0x0080u, /* If GEN_CAT=FORMAT, top byte masks: */ UPROPS_MASK_Cf_ZWJ = 0x0100u, - UPROPS_MASK_Cf_ZWNJ = 0x0200u + UPROPS_MASK_Cf_ZWNJ = 0x0200u, + UPROPS_MASK_Cf_VS = 0x0400u }; HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); @@ -229,7 +235,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) /* TAG characters need similar treatment. Fixes: * https://github.com/harfbuzz/harfbuzz/issues/463 */ else if (unlikely (hb_in_range (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN; - /* COMBINING GRAPHEME JOINER should not be skipped; at least some times. + /* COMBINING GRAPHEME JOINER should not be skipped during GSUB either. * https://github.com/harfbuzz/harfbuzz/issues/554 */ else if (unlikely (u == 0x034Fu)) { @@ -302,6 +308,27 @@ _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) : hb_unicode_funcs_t::NOT_SPACE; } +static inline bool +_hb_glyph_info_is_variation_selector (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_get_general_category (info) == + HB_UNICODE_GENERAL_CATEGORY_FORMAT && + (info->unicode_props() & UPROPS_MASK_Cf_VS); +} +static inline void +_hb_glyph_info_set_variation_selector (hb_glyph_info_t *info, bool customize) +{ + if (customize) + { + _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_FORMAT); + info->unicode_props() |= UPROPS_MASK_Cf_VS; + } + else + { + // Reset to their original condition + _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK); + } +} static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info); @@ -311,12 +338,20 @@ _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_substituted (info); } +static inline void +_hb_glyph_info_set_default_ignorable (hb_glyph_info_t *info) +{ + info->unicode_props() |= UPROPS_MASK_IGNORABLE; +} +static inline void +_hb_glyph_info_clear_default_ignorable (hb_glyph_info_t *info) +{ + info->unicode_props() &= ~ UPROPS_MASK_IGNORABLE; +} static inline bool -_hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info) +_hb_glyph_info_is_hidden (const hb_glyph_info_t *info) { - return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_HIDDEN)) - == UPROPS_MASK_IGNORABLE) && - !_hb_glyph_info_substituted (info); + return info->unicode_props() & UPROPS_MASK_HIDDEN; } static inline void _hb_glyph_info_unhide (hb_glyph_info_t *info) @@ -330,7 +365,7 @@ _hb_glyph_info_set_continuation (hb_glyph_info_t *info) info->unicode_props() |= UPROPS_MASK_CONTINUATION; } static inline void -_hb_glyph_info_reset_continuation (hb_glyph_info_t *info) +_hb_glyph_info_clear_continuation (hb_glyph_info_t *info) { info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION; } @@ -603,8 +638,7 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer) } /* Make sure no one directly touches our props... */ -#undef unicode_props0 -#undef unicode_props1 +#undef unicode_props #undef lig_props #undef glyph_props diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc index 261ce43049c..a0cdfddfa63 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc @@ -390,5 +390,19 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, } } +unsigned int hb_ot_map_t::get_feature_tags (unsigned int start_offset, unsigned int *tag_count, hb_tag_t *tags) const +{ + if (tag_count) + { + auto sub_features = features.as_array ().sub_array (start_offset, tag_count); + if (tags) + { + for (unsigned int i = 0; i < sub_features.length; i++) + tags[i] = sub_features[i].tag; + } + } + + return features.length; +} #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh index 110361552c0..68af9792439 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh @@ -166,6 +166,9 @@ struct hb_ot_map_t const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; + HB_INTERNAL unsigned int get_feature_tags (unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */) const; public: hb_tag_t chosen_script[2]; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh index 63bcd132cf4..c1b2a27b21d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh @@ -333,6 +333,7 @@ struct MathKern { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_array (mathValueRecordsZ.arrayZ, 2 * heightCount + 1) && sanitize_math_value_records (c)); } @@ -343,27 +344,20 @@ struct MathKern const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount; int sign = font->y_scale < 0 ? -1 : +1; - /* The description of the MathKern table is a ambiguous, but interpreting - * "between the two heights found at those indexes" for 0 < i < len as - * - * correctionHeight[i-1] < correction_height <= correctionHeight[i] - * - * makes the result consistent with the limit cases and we can just use the - * binary search algorithm of std::upper_bound: + /* According to OpenType spec (v1.9), except for the boundary cases, the index + * chosen for kern value should be i such that + * correctionHeight[i-1] <= correction_height < correctionHeight[i] + * We can use the binary search algorithm of std::upper_bound(). Or, we can + * use the internal hb_bsearch_impl. */ - unsigned int i = 0; - unsigned int count = heightCount; - while (count > 0) - { - unsigned int half = count / 2; - hb_position_t height = correctionHeight[i + half].get_y_value (font, this); - if (sign * height < sign * correction_height) - { - i += half + 1; - count -= half + 1; - } else - count = half; - } + unsigned int pos; + auto cmp = +[](const void* key, const void* p, + int sign, hb_font_t* font, const MathKern* mathKern) -> int { + return sign * *(hb_position_t*)key - sign * ((MathValueRecord*)p)->get_y_value(font, mathKern); + }; + unsigned int i = hb_bsearch_impl(&pos, correction_height, correctionHeight, + heightCount, MathValueRecord::static_size, + cmp, sign, font, this) ? pos + 1 : pos; return kernValue[i].get_x_value (font, this); } @@ -984,6 +978,7 @@ struct MathVariants return_trace (c->check_struct (this) && vertGlyphCoverage.sanitize (c, this) && horizGlyphCoverage.sanitize (c, this) && + hb_barrier () && c->check_array (glyphConstruction.arrayZ, vertGlyphCount + horizGlyphCount) && sanitize_offsets (c)); } @@ -1103,6 +1098,7 @@ struct MATH TRACE_SANITIZE (this); return_trace (version.sanitize (c) && likely (version.major == 1) && + hb_barrier () && mathConstants.sanitize (c, this) && mathGlyphInfo.sanitize (c, this) && mathVariants.sanitize (c, this)); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh index f7f2e860e4a..f6eeda40ed6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh @@ -85,7 +85,7 @@ struct maxp TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); - + hb_barrier (); if (version.major == 1) { const maxpV1Tail &v1 = StructAfter (*this); @@ -103,6 +103,7 @@ struct maxp maxp_prime->numGlyphs = hb_min (c->plan->num_output_glyphs (), 0xFFFFu); if (maxp_prime->version.major == 1) { + hb_barrier (); const maxpV1Tail *src_v1 = &StructAfter (*this); maxpV1Tail *dest_v1 = c->serializer->embed (src_v1); if (unlikely (!dest_v1)) return_trace (false); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-meta-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-meta-table.hh index 1f011882807..20c62b83edb 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-meta-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-meta-table.hh @@ -51,6 +51,7 @@ struct DataMap { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && dataZ.sanitize (c, base, dataLength))); } @@ -101,6 +102,7 @@ struct meta { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version == 1 && dataMaps.sanitize (c, this))); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh index 30ae335d703..24e9c970353 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh @@ -209,6 +209,23 @@ struct OS2 return ret; } + static unsigned calc_avg_char_width (const hb_hashmap_t>& hmtx_map) + { + unsigned num = 0; + unsigned total_width = 0; + for (const auto& _ : hmtx_map.values_ref ()) + { + unsigned width = _.first; + if (width) + { + total_width += width; + num++; + } + } + + return num ? (unsigned) roundf ((double) total_width / (double) num) : 0; + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -239,17 +256,23 @@ struct OS2 if (os2_prime->version >= 2) { + hb_barrier (); auto *table = & const_cast (os2_prime->v2 ()); HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_X_HEIGHT, sxHeight); HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_CAP_HEIGHT, sCapHeight); } + + unsigned avg_char_width = calc_avg_char_width (c->plan->hmtx_map); + if (!c->serializer->check_assign (os2_prime->xAvgCharWidth, avg_char_width, + HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); } #endif Triple *axis_range; if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t'), &axis_range)) { - unsigned weight_class = static_cast (roundf (hb_clamp (axis_range->middle, 1.0f, 1000.0f))); + unsigned weight_class = static_cast (roundf (hb_clamp (axis_range->middle, 1.0, 1000.0))); if (os2_prime->usWeightClass != weight_class) os2_prime->usWeightClass = weight_class; } @@ -261,12 +284,12 @@ struct OS2 os2_prime->usWidthClass = width_class; } + os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->os2_info.min_cmap_codepoint); + os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->os2_info.max_cmap_codepoint); + if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) return_trace (true); - os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_min ()); - os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_max ()); - _update_unicode_ranges (&c->plan->unicodes, os2_prime->ulUnicodeRange); return_trace (true); @@ -334,6 +357,7 @@ struct OS2 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); if (unlikely (version >= 1 && !v1X.sanitize (c))) return_trace (false); if (unlikely (version >= 2 && !v2X.sanitize (c))) return_trace (false); if (unlikely (version >= 5 && !v5X.sanitize (c))) return_trace (false); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh index d44233610a6..67d1b6aa713 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh @@ -84,9 +84,9 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const old_gid_new_index_map.alloc (num_glyphs); glyph_name_to_new_index.alloc (num_glyphs); - for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++) + for (auto _ : c->plan->new_to_old_gid_list) { - hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); + hb_codepoint_t old_gid = _.second; unsigned old_index = glyphNameIndex[old_gid]; unsigned new_index; @@ -125,13 +125,22 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const old_gid_new_index_map.set (old_gid, new_index); } + if (old_gid_new_index_map.in_error()) + return_trace (false); + auto index_iter = + hb_range (num_glyphs) - | hb_map (reverse_glyph_map) - | hb_map_retains_sorting ([&](hb_codepoint_t old_gid) + | hb_map_retains_sorting ([&](hb_codepoint_t new_gid) { - unsigned new_index = old_gid_new_index_map.get (old_gid); - return hb_pair_t (old_gid, new_index); + hb_codepoint_t *old_gid; + /* use 0 for retain-gid holes, which refers to the name .notdef, + * as the glyphNameIndex entry for that glyph ID."*/ + unsigned new_index = 0; + if (reverse_glyph_map.has (new_gid, &old_gid)) { + new_index = old_gid_new_index_map.get (*old_gid); + return hb_pair_t (*old_gid, new_index); + } + return hb_pair_t (new_gid, new_index); }) ; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh index d41c86f8bd3..83d310e16a0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh @@ -116,13 +116,16 @@ struct post Triple *axis_range; if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t'), &axis_range)) { - float italic_angle = hb_max (-90.f, hb_min (axis_range->middle, 90.f)); + float italic_angle = hb_max (-90.0, hb_min (axis_range->middle, 90.0)); if (post_prime->italicAngle.to_float () != italic_angle) post_prime->italicAngle.set_float (italic_angle); } if (glyph_names && version.major == 2) + { + hb_barrier (); return_trace (v2X.subset (c)); + } return_trace (true); } @@ -138,6 +141,7 @@ struct post version = table->version.to_int (); if (version != 0x00020000) return; + hb_barrier (); const postV2Tail &v2 = table->v2X; @@ -217,10 +221,16 @@ struct post unsigned int get_glyph_count () const { if (version == 0x00010000) + { + hb_barrier (); return format1_names_length; + } if (version == 0x00020000) + { + hb_barrier (); return glyphNameIndex->len; + } return 0; } @@ -245,13 +255,18 @@ struct post { if (version == 0x00010000) { + hb_barrier (); if (glyph >= format1_names_length) return hb_bytes_t (); return format1_names (glyph); } - if (version != 0x00020000 || glyph >= glyphNameIndex->len) + if (version != 0x00020000) + return hb_bytes_t (); + hb_barrier (); + + if (glyph >= glyphNameIndex->len) return hb_bytes_t (); unsigned int index = glyphNameIndex->arrayZ[glyph]; @@ -284,8 +299,9 @@ struct post { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (version.to_int () == 0x00010000 || - (version.to_int () == 0x00020000 && v2X.sanitize (c)) || + (version.to_int () == 0x00020000 && hb_barrier () && v2X.sanitize (c)) || version.to_int () == 0x00030000)); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc index b1acc7e7db3..cb941bc7fbd 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc @@ -74,23 +74,6 @@ * Indic shaper may want to disallow recomposing of two matras. */ -static bool -decompose_unicode (const hb_ot_shape_normalize_context_t *c, - hb_codepoint_t ab, - hb_codepoint_t *a, - hb_codepoint_t *b) -{ - return (bool) c->unicode->decompose (ab, a, b); -} - -static bool -compose_unicode (const hb_ot_shape_normalize_context_t *c, - hb_codepoint_t a, - hb_codepoint_t b, - hb_codepoint_t *ab) -{ - return (bool) c->unicode->compose (a, b, ab); -} static inline void set_glyph (hb_glyph_info_t &info, hb_font_t *font) @@ -170,7 +153,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor hb_codepoint_t u = buffer->cur().codepoint; hb_codepoint_t glyph = 0; - if (shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found)) + if (shortest && c->font->get_nominal_glyph (u, &glyph, buffer->not_found)) { next_char (buffer, glyph); return; @@ -182,7 +165,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor return; } - if (!shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found)) + if (!shortest && c->font->get_nominal_glyph (u, &glyph, buffer->not_found)) { next_char (buffer, glyph); return; @@ -237,6 +220,12 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, /* Just pass on the two characters separately, let GSUB do its magic. */ set_glyph (buffer->cur(), font); (void) buffer->next_glyph (); + + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK; + _hb_glyph_info_set_variation_selector (&buffer->cur(), true); + if (buffer->not_found_variation_selector != HB_CODEPOINT_INVALID) + _hb_glyph_info_clear_default_ignorable (&buffer->cur()); + set_glyph (buffer->cur(), font); (void) buffer->next_glyph (); } @@ -307,15 +296,15 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS; } - const hb_ot_shape_normalize_context_t c = { + hb_ot_shape_normalize_context_t c = { plan, buffer, font, buffer->unicode, - buffer->not_found, - plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode, - plan->shaper->compose ? plan->shaper->compose : compose_unicode + plan->shaper->decompose ? plan->shaper->decompose : hb_ot_shape_normalize_context_t::decompose_unicode, + plan->shaper->compose ? plan->shaper->compose : hb_ot_shape_normalize_context_t::compose_unicode }; + c.override_decompose_and_compose (plan->shaper->decompose, plan->shaper->compose); bool always_short_circuit = mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE; bool might_short_circuit = always_short_circuit || diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh index afd62dd4072..9f17bdbb243 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.hh @@ -28,6 +28,7 @@ #define HB_OT_SHAPE_NORMALIZE_HH #include "hb.hh" +#include "hb-unicode.hh" /* buffer var allocations, used during the normalization process */ @@ -52,11 +53,42 @@ HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper, struct hb_ot_shape_normalize_context_t { + static bool + decompose_unicode (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t ab, + hb_codepoint_t *a, + hb_codepoint_t *b) + { + return (bool) c->unicode->decompose (ab, a, b); + } + + static bool + compose_unicode (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t a, + hb_codepoint_t b, + hb_codepoint_t *ab) + { + return (bool) c->unicode->compose (a, b, ab); + } + + void + override_decompose_and_compose (bool (*decompose) (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t ab, + hb_codepoint_t *a, + hb_codepoint_t *b), + bool (*compose) (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t a, + hb_codepoint_t b, + hb_codepoint_t *ab)) + { + this->decompose = decompose ? decompose : decompose_unicode; + this->compose = compose ? compose : compose_unicode; + } + const hb_ot_shape_plan_t *plan; hb_buffer_t *buffer; hb_font_t *font; hb_unicode_funcs_t *unicode; - const hb_codepoint_t not_found; bool (*decompose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t ab, hb_codepoint_t *a, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc index f936ac45f37..6265f0eb17d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc @@ -46,6 +46,8 @@ #include "hb-set.hh" #include "hb-aat-layout.hh" +#include "hb-ot-stat-table.hh" + static inline bool _hb_codepoint_is_regional_indicator (hb_codepoint_t u) @@ -85,7 +87,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac , apply_morx (_hb_apply_morx (face, props)) #endif { - shaper = hb_ot_shaper_categorize (this); + shaper = hb_ot_shaper_categorize (props.script, props.direction, map.chosen_script[0]); script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; script_fallback_mark_positioning = shaper->fallback_position; @@ -121,10 +123,6 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.kern_mask = plan.map.get_mask (kern_tag); plan.requested_kerning = !!plan.kern_mask; #endif -#ifndef HB_NO_AAT_SHAPE - plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k')); - plan.requested_tracking = !!plan.trak_mask; -#endif bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX; bool disable_gpos = plan.shaper->gpos_tag && @@ -155,7 +153,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, #endif bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face); if (false) - ; + {} #ifndef HB_NO_AAT_SHAPE /* Prefer GPOS over kerx if GSUB is present; * https://github.com/harfbuzz/harfbuzz/issues/3008 */ @@ -167,15 +165,16 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos)) { + if (false) {} #ifndef HB_NO_AAT_SHAPE - if (has_kerx) + else if (has_kerx) plan.apply_kerx = true; - else #endif #ifndef HB_NO_OT_KERN - if (hb_ot_layout_has_kerning (face)) + else if (hb_ot_layout_has_kerning (face)) plan.apply_kern = true; #endif + else {} } plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); @@ -206,9 +205,6 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, https://github.com/harfbuzz/harfbuzz/issues/2967. */ if (plan.apply_morx) plan.adjust_mark_positioning_when_zeroing = false; - - /* Currently we always apply trak. */ - plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); #endif } @@ -273,11 +269,6 @@ hb_ot_shape_plan_t::position (hb_font_t *font, #endif else if (this->apply_fallback_kern) _hb_ot_shape_fallback_kern (this, font, buffer); - -#ifndef HB_NO_AAT_SHAPE - if (this->apply_trak) - hb_aat_layout_track (this, font, buffer); -#endif } @@ -345,13 +336,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, /* Random! */ map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE); -#ifndef HB_NO_AAT_SHAPE - /* Tracking. We enable dummy feature here just to allow disabling - * AAT 'trak' table using features. - * https://github.com/harfbuzz/harfbuzz/issues/1303 */ - map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK); -#endif - map->enable_feature (HB_TAG ('H','a','r','f')); /* Considered required. */ map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */ @@ -836,6 +820,28 @@ hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer) pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; } +static void +hb_ot_deal_with_variation_selectors (hb_buffer_t *buffer) +{ + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK) || + buffer->not_found_variation_selector == HB_CODEPOINT_INVALID) + return; + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + + for (unsigned int i = 0; i < count; i++) + { + if (_hb_glyph_info_is_variation_selector (&info[i])) + { + info[i].codepoint = buffer->not_found_variation_selector; + pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; + _hb_glyph_info_set_variation_selector (&info[i], false); + } + } +} + static void hb_ot_hide_default_ignorables (hb_buffer_t *buffer, hb_font_t *font) @@ -965,6 +971,7 @@ hb_ot_substitute_post (const hb_ot_shape_context_t *c) hb_aat_layout_remove_deleted_glyphs (c->buffer); #endif + hb_ot_deal_with_variation_selectors (c->buffer); hb_ot_hide_default_ignorables (c->buffer, c->font); if (c->plan->shaper->postprocess_glyphs && @@ -1253,6 +1260,36 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, } +/** + * hb_ot_shape_plan_get_feature_tags: + * @shape_plan: A shaping plan + * @start_offset: The index of first feature to retrieve + * @tag_count: (inout): Input = the maximum number of features to return; + * Output = the actual number of features returned (may be zero) + * @tags: (out) (array length=tag_count): The array of enabled feature + * + * Fetches the list of OpenType feature tags enabled for a shaping plan, if possible. + * + * Return value: Total number of feature tagss. + * + * Since: 10.3.0 + */ +unsigned int +hb_ot_shape_plan_get_feature_tags (hb_shape_plan_t *shape_plan, + unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */) +{ +#ifndef HB_NO_OT_SHAPE + return shape_plan->ot.map.get_feature_tags (start_offset, tag_count, tags); +#else + if (tag_count) + *tag_count = 0; + return 0; +#endif +} + + /* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */ static void add_char (hb_font_t *font, diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.h b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.h index 545e2c3f1b4..1732831b132 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.h @@ -48,6 +48,12 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, hb_tag_t table_tag, hb_set_t *lookup_indexes /* OUT */); +HB_EXTERN unsigned int +hb_ot_shape_plan_get_feature_tags (hb_shape_plan_t *shape_plan, + unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */); + HB_END_DECLS #endif /* HB_OT_SHAPE_H */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh index 2fa121ced81..d5ee82d4c0b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.hh @@ -51,7 +51,8 @@ struct hb_ot_shape_plan_key_t bool equal (const hb_ot_shape_plan_key_t *other) { - return 0 == hb_memcmp (this, other, sizeof (*this)); + return variations_index[0] == other->variations_index[0] && + variations_index[1] == other->variations_index[1]; } }; @@ -79,22 +80,12 @@ struct hb_ot_shape_plan_t #else static constexpr hb_mask_t kern_mask = 0; #endif -#ifndef HB_NO_AAT_SHAPE - hb_mask_t trak_mask; -#else - static constexpr hb_mask_t trak_mask = 0; -#endif #ifndef HB_NO_OT_KERN bool requested_kerning : 1; #else static constexpr bool requested_kerning = false; #endif -#ifndef HB_NO_AAT_SHAPE - bool requested_tracking : 1; -#else - static constexpr bool requested_tracking = false; -#endif #ifndef HB_NO_OT_SHAPE_FRACTIONS bool has_frac : 1; #else @@ -117,11 +108,9 @@ struct hb_ot_shape_plan_t #ifndef HB_NO_AAT_SHAPE bool apply_kerx : 1; bool apply_morx : 1; - bool apply_trak : 1; #else static constexpr bool apply_kerx = false; static constexpr bool apply_morx = false; - static constexpr bool apply_trak = false; #endif void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh index 858a9872726..ff0b2acede1 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh @@ -355,6 +355,8 @@ arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) if (fallback_plan->lookup_array[i]) { + if (fallback_plan->accel_array[i]) + fallback_plan->accel_array[i]->fini (); hb_free (fallback_plan->accel_array[i]); if (fallback_plan->free_lookups) hb_free (fallback_plan->lookup_array[i]); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh index a5a7b84af45..e38686e3ebb 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-15.1.0.txt - * # Date: 2023-01-05 - * # Scripts-15.1.0.txt - * # Date: 2023-07-28, 16:01:07 GMT + * # ArabicShaping-16.0.0.txt + * # Date: 2024-07-30 + * # Scripts-16.0.0.txt + * # Date: 2024-04-30, 21:48:40 GMT */ #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh index 8c2504438d9..19bd72d4218 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-15.1.0.txt - * # Date: 2023-01-05 - * # Blocks-15.1.0.txt - * # Date: 2023-07-28, 15:47:20 GMT + * # ArabicShaping-16.0.0.txt + * # Date: 2024-07-30 + * # Blocks-16.0.0.txt + * # Date: 2024-02-02 * UnicodeData.txt does not have a header. */ @@ -136,7 +136,13 @@ static const uint8_t joining_table[] = /* 10D00 */ L,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 10D20 */ D,D,R,D, -#define joining_offset_0x10f30u 1182 +#define joining_offset_0x10ec2u 1182 + + /* Arabic Extended-C */ + + /* 10EC0 */ R,D,D, + +#define joining_offset_0x10f30u 1185 /* Sogdian */ @@ -155,14 +161,14 @@ static const uint8_t joining_table[] = /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D, /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L, -#define joining_offset_0x110bdu 1338 +#define joining_offset_0x110bdu 1341 /* Kaithi */ /* 110A0 */ U,X,X, /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, -#define joining_offset_0x1e900u 1355 +#define joining_offset_0x1e900u 1358 /* Adlam */ @@ -170,7 +176,7 @@ static const uint8_t joining_table[] = /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 1E940 */ D,D,D,D,X,X,X,X,X,X,X,T, -}; /* Table items: 1431; occupancy: 57% */ +}; /* Table items: 1434; occupancy: 57% */ static unsigned int @@ -198,6 +204,7 @@ joining_type (hb_codepoint_t u) if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u]; if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; if (hb_in_range (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; + if (hb_in_range (u, 0x10EC2u, 0x10EC4u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; if (hb_in_range (u, 0x10F30u, 0x10FCBu)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; break; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc index 87d76e1a101..67db6cb26c4 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc @@ -233,10 +233,7 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ); /* https://github.com/harfbuzz/harfbuzz/issues/1573 */ if (!map->has_feature (HB_TAG('r','c','l','t'))) - { map->add_gsub_pause (nullptr); - map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ); - } map->enable_feature (HB_TAG('l','i','g','a'), F_MANUAL_ZWJ); map->enable_feature (HB_TAG('c','l','i','g'), F_MANUAL_ZWJ); @@ -560,9 +557,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%u,%u,%u)", step == MEASURE ? "measuring" : "cutting", context, start, end); - DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %d", start - context, w_total); - DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%d", n_fixed, w_fixed); - DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%d", n_repeating, w_repeating); + DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %" PRId32, start - context, w_total); + DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%" PRId32, n_fixed, w_fixed); + DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%" PRId32, n_repeating, w_repeating); /* Number of additional times to repeat each repeating tile. */ int n_copies = 0; @@ -602,7 +599,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, if (info[k - 1].arabic_shaping_action() == STCH_REPEATING) repeat += n_copies; - DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u", + DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %" PRIu32 "; j=%u", repeat, info[k - 1].codepoint, j); pos[k - 1].x_advance = 0; for (unsigned int n = 0; n < repeat; n++) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hebrew.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hebrew.cc index bb9950d02d2..0ad1cea9532 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hebrew.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-hebrew.cc @@ -78,7 +78,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, return found; #endif - if (!found && !c->plan->has_gpos_mark) + if (!found && (c->plan && !c->plan->has_gpos_mark)) { /* Special-case Hebrew presentation forms that are excluded from * standard normalization, but wanted for old fonts. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh index 6a6db44840e..25e6d85ef80 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh @@ -68,6 +68,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_Ra 15u #define indic_syllable_machine_ex_Repha 14u #define indic_syllable_machine_ex_SM 8u +#define indic_syllable_machine_ex_SMPst 57u #define indic_syllable_machine_ex_Symbol 17u #define indic_syllable_machine_ex_V 2u #define indic_syllable_machine_ex_VD 9u @@ -76,251 +77,916 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 80 "hb-ot-shaper-indic-machine.hh" +#line 81 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { - 8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, - 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, - 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, - 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 5u, 13u, 8u, 8u, 1u, 18u, - 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, - 1u, 15u, 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 3u, 16u, 3u, 16u, 4u, 16u, - 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, - 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 13u, 3u, 16u, 3u, 16u, - 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, - 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 13u, 4u, 13u, 3u, 16u, 3u, 16u, - 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, - 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 13u, 5u, 13u, - 5u, 13u, 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, + 8u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, + 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 4u, 57u, + 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 8u, 57u, + 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 5u, 57u, 8u, 57u, 1u, 57u, + 3u, 57u, 3u, 57u, 4u, 57u, 1u, 57u, 5u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, + 1u, 57u, 1u, 57u, 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 4u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, + 1u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, + 1u, 57u, 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, 3u, 57u, 3u, 57u, + 4u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, + 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 4u, 57u, 3u, 57u, 3u, 57u, + 4u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, + 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 15u, 0 }; static const char _indic_syllable_machine_key_spans[] = { - 1, 10, 9, 9, 1, 10, 10, 10, - 1, 9, 9, 1, 10, 10, 10, 10, - 1, 9, 9, 1, 10, 10, 10, 1, - 9, 9, 1, 10, 10, 9, 1, 18, - 14, 14, 13, 15, 5, 5, 1, 5, - 15, 15, 15, 11, 10, 9, 9, 10, - 5, 7, 5, 14, 14, 14, 14, 13, - 15, 14, 14, 13, 15, 5, 1, 5, - 15, 15, 11, 10, 9, 9, 10, 5, - 5, 7, 5, 14, 14, 10, 14, 14, - 13, 15, 14, 15, 5, 1, 5, 15, - 15, 11, 10, 9, 9, 14, 10, 5, - 5, 7, 5, 14, 10, 10, 14, 14, - 13, 15, 14, 15, 5, 1, 5, 15, - 15, 11, 10, 9, 9, 14, 10, 5, - 5, 7, 5, 16, 14, 16, 10, 9, - 9, 1, 5, 15, 7, 5, 5, 1, + 50, 54, 53, 53, 1, 54, 54, 54, + 50, 53, 53, 1, 54, 54, 54, 54, + 50, 53, 53, 1, 54, 54, 54, 50, + 53, 53, 1, 54, 54, 53, 50, 57, + 55, 55, 54, 57, 53, 53, 1, 5, + 57, 57, 57, 55, 54, 53, 53, 54, + 53, 55, 53, 55, 55, 55, 55, 54, + 57, 55, 55, 54, 57, 53, 1, 5, + 57, 57, 55, 54, 53, 53, 54, 53, + 53, 55, 53, 55, 55, 54, 55, 55, + 54, 57, 55, 57, 53, 1, 5, 57, + 57, 55, 54, 53, 53, 55, 54, 53, + 53, 55, 53, 55, 54, 54, 55, 55, + 54, 57, 55, 57, 53, 1, 5, 57, + 57, 55, 54, 53, 53, 55, 54, 53, + 53, 55, 53, 57, 55, 57, 54, 53, + 53, 1, 5, 57, 55, 53, 53, 1, 5, 15 }; static const short _indic_syllable_machine_index_offsets[] = { - 0, 2, 13, 23, 33, 35, 46, 57, - 68, 70, 80, 90, 92, 103, 114, 125, - 136, 138, 148, 158, 160, 171, 182, 193, - 195, 205, 215, 217, 228, 239, 249, 251, - 270, 285, 300, 314, 330, 336, 342, 344, - 350, 366, 382, 398, 410, 421, 431, 441, - 452, 458, 466, 472, 487, 502, 517, 532, - 546, 562, 577, 592, 606, 622, 628, 630, - 636, 652, 668, 680, 691, 701, 711, 722, - 728, 734, 742, 748, 763, 778, 789, 804, - 819, 833, 849, 864, 880, 886, 888, 894, - 910, 926, 938, 949, 959, 969, 984, 995, - 1001, 1007, 1015, 1021, 1036, 1047, 1058, 1073, - 1088, 1102, 1118, 1133, 1149, 1155, 1157, 1163, - 1179, 1195, 1207, 1218, 1228, 1238, 1253, 1264, - 1270, 1276, 1284, 1290, 1307, 1322, 1339, 1350, - 1360, 1370, 1372, 1378, 1394, 1402, 1408, 1414, - 1416, 1422 + 0, 51, 106, 160, 214, 216, 271, 326, + 381, 432, 486, 540, 542, 597, 652, 707, + 762, 813, 867, 921, 923, 978, 1033, 1088, + 1139, 1193, 1247, 1249, 1304, 1359, 1413, 1464, + 1522, 1578, 1634, 1689, 1747, 1801, 1855, 1857, + 1863, 1921, 1979, 2037, 2093, 2148, 2202, 2256, + 2311, 2365, 2421, 2475, 2531, 2587, 2643, 2699, + 2754, 2812, 2868, 2924, 2979, 3037, 3091, 3093, + 3099, 3157, 3215, 3271, 3326, 3380, 3434, 3489, + 3543, 3597, 3653, 3707, 3763, 3819, 3874, 3930, + 3986, 4041, 4099, 4155, 4213, 4267, 4269, 4275, + 4333, 4391, 4447, 4502, 4556, 4610, 4666, 4721, + 4775, 4829, 4885, 4939, 4995, 5050, 5105, 5161, + 5217, 5272, 5330, 5386, 5444, 5498, 5500, 5506, + 5564, 5622, 5678, 5733, 5787, 5841, 5897, 5952, + 6006, 6060, 6116, 6170, 6228, 6284, 6342, 6397, + 6451, 6505, 6507, 6513, 6571, 6627, 6681, 6735, + 6737, 6743 }; static const unsigned char _indic_syllable_machine_indicies[] = { - 1, 0, 2, 3, 3, 4, 5, 0, - 0, 0, 0, 4, 0, 3, 3, 4, - 6, 0, 0, 0, 0, 4, 0, 3, - 3, 4, 5, 0, 0, 0, 0, 4, - 0, 4, 0, 7, 3, 3, 4, 5, - 0, 0, 0, 0, 4, 0, 2, 3, - 3, 4, 5, 0, 0, 0, 8, 4, - 0, 10, 11, 11, 12, 13, 9, 9, - 9, 9, 12, 9, 14, 9, 11, 11, - 12, 15, 9, 9, 9, 9, 12, 9, - 11, 11, 12, 13, 9, 9, 9, 9, - 12, 9, 12, 9, 16, 11, 11, 12, - 13, 9, 9, 9, 9, 12, 9, 10, - 11, 11, 12, 13, 9, 9, 9, 17, - 12, 9, 10, 11, 11, 12, 13, 9, - 9, 9, 18, 12, 9, 20, 21, 21, - 22, 23, 19, 19, 19, 24, 22, 19, - 25, 19, 21, 21, 22, 27, 26, 26, - 26, 26, 22, 26, 21, 21, 22, 23, - 19, 19, 19, 19, 22, 19, 22, 26, - 20, 21, 21, 22, 23, 19, 19, 19, - 19, 22, 19, 28, 21, 21, 22, 23, - 19, 19, 19, 19, 22, 19, 30, 31, - 31, 32, 33, 29, 29, 29, 34, 32, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 2, 3, 3, 4, 5, + 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 3, 3, 4, 6, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, + 3, 3, 4, 5, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 4, 0, + 7, 3, 3, 4, 5, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 2, + 3, 3, 4, 5, 0, 0, 0, 8, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 10, 11, + 11, 12, 13, 9, 9, 9, 9, 12, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 13, 9, 14, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 14, 9, + 11, 11, 12, 15, 9, 9, 9, 9, + 12, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 15, 9, 11, 11, + 12, 13, 9, 9, 9, 9, 12, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 13, 9, 12, 9, 16, 11, + 11, 12, 13, 9, 9, 9, 9, 12, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 13, 9, 10, 11, 11, + 12, 13, 9, 9, 9, 17, 12, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 13, 9, 10, 11, 11, 12, + 13, 9, 9, 9, 18, 12, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 13, 9, 20, 21, 21, 22, 23, + 19, 19, 19, 24, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 23, 19, 25, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 25, 19, 21, 21, 22, + 27, 26, 26, 26, 26, 22, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 27, 26, 21, 21, 22, 23, 19, + 19, 19, 19, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 23, + 19, 22, 26, 20, 21, 21, 22, 23, + 19, 19, 19, 19, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 23, 19, 28, 21, 21, 22, 23, 19, + 19, 19, 19, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 23, + 19, 30, 31, 31, 32, 33, 29, 29, + 29, 34, 32, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 33, 29, + 35, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 35, 29, 31, 31, 32, 36, 29, - 29, 29, 29, 32, 29, 31, 31, 32, - 33, 29, 29, 29, 29, 32, 29, 32, + 29, 29, 29, 32, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 36, + 29, 31, 31, 32, 33, 29, 29, 29, + 29, 32, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 33, 29, 32, 29, 30, 31, 31, 32, 33, 29, 29, - 29, 29, 32, 29, 37, 31, 31, 32, - 33, 29, 29, 29, 29, 32, 29, 21, + 29, 29, 32, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 33, 29, + 37, 31, 31, 32, 33, 29, 29, 29, + 29, 32, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 33, 29, 21, 21, 22, 38, 0, 0, 0, 0, 22, - 0, 40, 39, 42, 43, 44, 45, 46, - 47, 22, 23, 48, 49, 49, 24, 22, - 50, 51, 52, 53, 54, 41, 56, 57, - 58, 59, 4, 5, 60, 55, 55, 8, - 4, 55, 55, 61, 55, 62, 57, 63, - 63, 4, 5, 60, 55, 55, 55, 4, - 55, 55, 61, 55, 57, 63, 63, 4, - 5, 60, 55, 55, 55, 4, 55, 55, - 61, 55, 42, 55, 55, 55, 64, 65, - 55, 1, 60, 55, 55, 55, 55, 55, - 42, 55, 66, 66, 55, 1, 60, 55, - 60, 55, 55, 67, 60, 55, 60, 55, - 60, 55, 55, 55, 60, 55, 42, 55, - 68, 55, 66, 66, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 42, 55, - 55, 55, 66, 66, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 42, 55, - 55, 55, 66, 65, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 69, 70, - 71, 71, 4, 5, 60, 55, 55, 55, - 4, 55, 70, 71, 71, 4, 5, 60, - 55, 55, 55, 4, 55, 71, 71, 4, - 5, 60, 55, 55, 55, 4, 55, 60, - 55, 55, 67, 60, 55, 55, 55, 4, - 55, 72, 73, 73, 4, 5, 60, 55, - 55, 55, 4, 55, 64, 74, 55, 1, - 60, 55, 64, 55, 66, 66, 55, 1, - 60, 55, 66, 74, 55, 1, 60, 55, - 56, 57, 63, 63, 4, 5, 60, 55, - 55, 55, 4, 55, 55, 61, 55, 56, - 57, 58, 63, 4, 5, 60, 55, 55, - 8, 4, 55, 55, 61, 55, 76, 77, - 78, 79, 12, 13, 80, 75, 75, 18, - 12, 75, 75, 81, 75, 82, 77, 83, - 79, 12, 13, 80, 75, 75, 75, 12, - 75, 75, 81, 75, 77, 83, 79, 12, - 13, 80, 75, 75, 75, 12, 75, 75, - 81, 75, 84, 75, 75, 75, 85, 86, - 75, 14, 80, 75, 75, 75, 75, 75, - 84, 75, 87, 77, 88, 89, 12, 13, - 80, 75, 75, 17, 12, 75, 75, 81, - 75, 90, 77, 83, 83, 12, 13, 80, - 75, 75, 75, 12, 75, 75, 81, 75, - 77, 83, 83, 12, 13, 80, 75, 75, - 75, 12, 75, 75, 81, 75, 84, 75, - 75, 75, 91, 86, 75, 14, 80, 75, - 75, 75, 75, 75, 84, 75, 80, 75, - 75, 92, 80, 75, 80, 75, 80, 75, - 75, 75, 80, 75, 84, 75, 93, 75, - 91, 91, 75, 14, 80, 75, 75, 75, - 75, 75, 84, 75, 84, 75, 75, 75, - 91, 91, 75, 14, 80, 75, 75, 75, - 75, 75, 84, 75, 94, 95, 96, 96, - 12, 13, 80, 75, 75, 75, 12, 75, - 95, 96, 96, 12, 13, 80, 75, 75, - 75, 12, 75, 96, 96, 12, 13, 80, - 75, 75, 75, 12, 75, 80, 75, 75, - 92, 80, 75, 75, 75, 12, 75, 97, - 98, 98, 12, 13, 80, 75, 75, 75, - 12, 75, 85, 99, 75, 14, 80, 75, - 91, 91, 75, 14, 80, 75, 85, 75, - 91, 91, 75, 14, 80, 75, 91, 99, - 75, 14, 80, 75, 87, 77, 83, 83, - 12, 13, 80, 75, 75, 75, 12, 75, - 75, 81, 75, 87, 77, 88, 83, 12, - 13, 80, 75, 75, 17, 12, 75, 75, - 81, 75, 10, 11, 11, 12, 13, 75, - 75, 75, 75, 12, 75, 76, 77, 83, - 79, 12, 13, 80, 75, 75, 75, 12, - 75, 75, 81, 75, 101, 45, 102, 102, - 22, 23, 48, 100, 100, 100, 22, 100, - 100, 52, 100, 45, 102, 102, 22, 23, - 48, 100, 100, 100, 22, 100, 100, 52, - 100, 103, 100, 100, 100, 104, 105, 100, - 25, 48, 100, 100, 100, 100, 100, 103, - 100, 44, 45, 106, 107, 22, 23, 48, - 100, 100, 24, 22, 100, 100, 52, 100, - 103, 100, 100, 100, 108, 105, 100, 25, - 48, 100, 100, 100, 100, 100, 103, 100, - 48, 100, 100, 109, 48, 100, 48, 100, - 48, 100, 100, 100, 48, 100, 103, 100, - 110, 100, 108, 108, 100, 25, 48, 100, - 100, 100, 100, 100, 103, 100, 103, 100, - 100, 100, 108, 108, 100, 25, 48, 100, - 100, 100, 100, 100, 103, 100, 111, 112, - 113, 113, 22, 23, 48, 100, 100, 100, - 22, 100, 112, 113, 113, 22, 23, 48, - 100, 100, 100, 22, 100, 113, 113, 22, - 23, 48, 100, 100, 100, 22, 100, 48, - 100, 100, 109, 48, 100, 100, 100, 22, - 100, 44, 45, 102, 102, 22, 23, 48, - 100, 100, 100, 22, 100, 100, 52, 100, - 114, 115, 115, 22, 23, 48, 100, 100, - 100, 22, 100, 104, 116, 100, 25, 48, - 100, 108, 108, 100, 25, 48, 100, 104, - 100, 108, 108, 100, 25, 48, 100, 108, - 116, 100, 25, 48, 100, 44, 45, 106, - 102, 22, 23, 48, 100, 100, 24, 22, - 100, 100, 52, 100, 20, 21, 21, 22, - 23, 117, 117, 117, 24, 22, 117, 20, - 21, 21, 22, 23, 117, 117, 117, 117, - 22, 117, 119, 120, 121, 122, 32, 33, - 123, 118, 118, 34, 32, 118, 118, 124, - 118, 125, 120, 122, 122, 32, 33, 123, - 118, 118, 118, 32, 118, 118, 124, 118, - 120, 122, 122, 32, 33, 123, 118, 118, - 118, 32, 118, 118, 124, 118, 126, 118, - 118, 118, 127, 128, 118, 35, 123, 118, - 118, 118, 118, 118, 126, 118, 119, 120, - 121, 49, 32, 33, 123, 118, 118, 34, - 32, 118, 118, 124, 118, 126, 118, 118, - 118, 129, 128, 118, 35, 123, 118, 118, - 118, 118, 118, 126, 118, 123, 118, 118, - 130, 123, 118, 123, 118, 123, 118, 118, - 118, 123, 118, 126, 118, 131, 118, 129, - 129, 118, 35, 123, 118, 118, 118, 118, - 118, 126, 118, 126, 118, 118, 118, 129, - 129, 118, 35, 123, 118, 118, 118, 118, - 118, 126, 118, 132, 133, 134, 134, 32, - 33, 123, 118, 118, 118, 32, 118, 133, - 134, 134, 32, 33, 123, 118, 118, 118, - 32, 118, 134, 134, 32, 33, 123, 118, - 118, 118, 32, 118, 123, 118, 118, 130, - 123, 118, 118, 118, 32, 118, 119, 120, - 122, 122, 32, 33, 123, 118, 118, 118, - 32, 118, 118, 124, 118, 135, 136, 136, - 32, 33, 123, 118, 118, 118, 32, 118, - 127, 137, 118, 35, 123, 118, 129, 129, - 118, 35, 123, 118, 127, 118, 129, 129, - 118, 35, 123, 118, 129, 137, 118, 35, - 123, 118, 42, 43, 44, 45, 106, 102, - 22, 23, 48, 49, 49, 24, 22, 100, - 42, 52, 100, 56, 138, 58, 59, 4, - 5, 60, 55, 55, 8, 4, 55, 55, - 61, 55, 42, 43, 44, 45, 139, 140, - 22, 141, 142, 55, 49, 24, 22, 55, - 42, 52, 55, 20, 143, 143, 22, 141, - 60, 55, 55, 24, 22, 55, 60, 55, - 55, 67, 60, 55, 55, 55, 22, 55, - 142, 55, 55, 144, 142, 55, 55, 55, - 22, 55, 142, 55, 142, 55, 55, 55, - 142, 55, 42, 55, 68, 20, 143, 143, - 22, 141, 60, 55, 55, 55, 22, 55, - 42, 55, 146, 145, 147, 147, 145, 40, - 148, 145, 147, 147, 145, 40, 148, 145, - 148, 145, 145, 149, 148, 145, 148, 145, - 148, 145, 145, 145, 148, 145, 42, 117, - 117, 117, 117, 117, 117, 117, 117, 49, - 117, 117, 117, 117, 42, 117, 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 38, 0, 40, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 40, 39, + 42, 43, 44, 45, 46, 47, 22, 23, + 48, 49, 49, 24, 22, 50, 51, 52, + 53, 54, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 55, 41, 57, 58, 59, 60, 4, 5, + 61, 56, 56, 8, 4, 56, 56, 62, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 63, 58, 64, 64, 4, 5, + 61, 56, 56, 56, 4, 56, 56, 62, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 58, 64, 64, 4, 5, 61, + 56, 56, 56, 4, 56, 56, 62, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 5, + 56, 42, 56, 56, 56, 65, 66, 56, + 1, 61, 56, 56, 56, 56, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 67, 67, 56, 1, 61, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 1, + 56, 61, 56, 56, 68, 61, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 68, 56, 61, + 56, 61, 56, 56, 56, 61, 56, 42, + 56, 69, 56, 67, 67, 56, 1, 61, + 56, 56, 56, 56, 56, 42, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 1, + 56, 42, 56, 56, 56, 67, 67, 56, + 1, 61, 56, 56, 56, 56, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 42, 56, 56, 56, 67, + 66, 56, 1, 61, 56, 56, 56, 56, + 56, 42, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 70, 71, 72, + 72, 4, 5, 61, 56, 56, 56, 4, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 5, 56, 71, 72, 72, + 4, 5, 61, 56, 56, 56, 4, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 5, 56, 72, 72, 4, 5, + 61, 56, 56, 56, 4, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 61, 56, 56, 68, 61, 56, + 56, 56, 4, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 68, 56, + 73, 74, 74, 4, 5, 61, 56, 56, + 56, 4, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 5, 56, 65, + 75, 56, 1, 61, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 65, 56, 67, + 67, 56, 1, 61, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 67, 75, 56, + 1, 61, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 57, 58, 64, 64, 4, + 5, 61, 56, 56, 56, 4, 56, 56, + 62, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 5, 56, 57, 58, 59, 64, 4, + 5, 61, 56, 56, 8, 4, 56, 56, + 62, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 5, 56, 77, 78, 79, 80, 12, + 13, 81, 76, 76, 18, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 83, 78, 84, 80, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 78, 84, 80, 12, 13, + 81, 76, 76, 76, 12, 76, 76, 82, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 85, 76, 76, 76, 86, 87, + 76, 14, 81, 76, 76, 76, 76, 76, + 85, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 14, 76, 88, 78, 89, 90, + 12, 13, 81, 76, 76, 17, 12, 76, + 76, 82, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 91, 78, 84, 84, + 12, 13, 81, 76, 76, 76, 12, 76, + 76, 82, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 78, 84, 84, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 85, 76, 76, 76, 92, + 87, 76, 14, 81, 76, 76, 76, 76, + 76, 85, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 81, 76, 76, + 93, 81, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 93, 76, 81, 76, 81, 76, 76, + 76, 81, 76, 85, 76, 94, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 85, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 85, 76, 76, + 76, 92, 92, 76, 14, 81, 76, 76, + 76, 76, 76, 85, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 14, 76, 95, + 96, 97, 97, 12, 13, 81, 76, 76, + 76, 12, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 13, 76, 96, + 97, 97, 12, 13, 81, 76, 76, 76, + 12, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 13, 76, 97, 97, + 12, 13, 81, 76, 76, 76, 12, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 81, 76, 76, 93, + 81, 76, 76, 76, 12, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 93, 76, 98, 99, 99, 12, 13, 81, + 76, 76, 76, 12, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 13, + 76, 86, 100, 76, 14, 81, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 14, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 86, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 92, 100, 76, + 14, 81, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 14, 76, 88, 78, 84, 84, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 88, 78, 89, 84, 12, + 13, 81, 76, 76, 17, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 10, 11, 11, 12, 13, + 76, 76, 76, 76, 12, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 77, 78, 84, 80, 12, 13, + 81, 76, 76, 76, 12, 76, 76, 82, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 102, 45, 103, 103, 22, 23, + 48, 101, 101, 101, 22, 101, 101, 52, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 23, 101, 45, 103, 103, 22, 23, 48, + 101, 101, 101, 22, 101, 101, 52, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 23, + 101, 104, 101, 101, 101, 105, 106, 101, + 25, 48, 101, 101, 101, 101, 101, 104, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 25, 101, 44, 45, 107, 108, 22, + 23, 48, 101, 101, 24, 22, 101, 101, + 52, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 23, 101, 104, 101, 101, 101, 109, + 106, 101, 25, 48, 101, 101, 101, 101, + 101, 104, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 48, 101, 101, + 110, 48, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 110, 101, 48, 101, 48, 101, 101, + 101, 48, 101, 104, 101, 111, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 104, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 104, 101, 101, + 101, 109, 109, 101, 25, 48, 101, 101, + 101, 101, 101, 104, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 25, 101, 112, + 113, 114, 114, 22, 23, 48, 101, 101, + 101, 22, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 23, 101, 113, + 114, 114, 22, 23, 48, 101, 101, 101, + 22, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 23, 101, 114, 114, + 22, 23, 48, 101, 101, 101, 22, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 23, 101, 48, 26, 26, 110, + 48, 26, 26, 26, 22, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 110, 26, 44, 45, 103, 103, 22, 23, + 48, 101, 101, 101, 22, 101, 101, 52, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 23, 101, 115, 116, 116, 22, 23, 48, + 101, 101, 101, 22, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 23, + 101, 105, 117, 101, 25, 48, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 25, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 105, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 109, 117, 101, + 25, 48, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 25, 101, 44, 45, 107, 103, 22, + 23, 48, 101, 101, 24, 22, 101, 101, + 52, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 23, 101, 20, 21, 21, 22, 23, + 118, 118, 118, 24, 22, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 23, 118, 20, 21, 21, 22, 23, 118, + 118, 118, 118, 22, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 23, + 118, 120, 121, 122, 123, 32, 33, 124, + 119, 119, 34, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 126, 121, 123, 123, 32, 33, 124, + 119, 119, 119, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 121, 123, 123, 32, 33, 124, 119, + 119, 119, 32, 119, 119, 125, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 33, 119, + 127, 119, 119, 119, 128, 129, 119, 35, + 124, 119, 119, 119, 119, 119, 127, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 35, 119, 120, 121, 122, 49, 32, 33, + 124, 119, 119, 34, 32, 119, 119, 125, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 33, 119, 127, 119, 119, 119, 130, 129, + 119, 35, 124, 119, 119, 119, 119, 119, + 127, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 124, 119, 119, 131, + 124, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 131, 119, 124, 119, 124, 119, 119, 119, + 124, 119, 127, 119, 132, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 127, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 127, 119, 119, 119, + 130, 130, 119, 35, 124, 119, 119, 119, + 119, 119, 127, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 35, 119, 133, 134, + 135, 135, 32, 33, 124, 119, 119, 119, + 32, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 33, 119, 134, 135, + 135, 32, 33, 124, 119, 119, 119, 32, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 33, 119, 135, 135, 32, + 33, 124, 119, 119, 119, 32, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 33, 119, 124, 119, 119, 131, 124, + 119, 119, 119, 32, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 131, + 119, 120, 121, 123, 123, 32, 33, 124, + 119, 119, 119, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 136, 137, 137, 32, 33, 124, 119, + 119, 119, 32, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 33, 119, + 128, 138, 119, 35, 124, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 35, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 128, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 130, 138, 119, 35, + 124, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 35, 119, 42, 43, 44, 45, 107, 103, + 22, 23, 48, 49, 49, 24, 22, 101, + 42, 52, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 23, 101, 57, 139, 59, 60, + 4, 5, 61, 56, 56, 8, 4, 56, + 56, 62, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 5, 56, 42, 43, 44, 45, + 140, 141, 22, 142, 143, 56, 49, 24, + 22, 56, 42, 52, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 142, 56, 20, 144, + 144, 22, 142, 61, 56, 56, 24, 22, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 142, 56, 61, 56, 56, + 68, 61, 56, 56, 56, 22, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 68, 56, 143, 56, 56, 145, 143, + 56, 56, 56, 22, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 145, + 56, 143, 56, 143, 56, 56, 56, 143, + 56, 42, 56, 69, 20, 144, 144, 22, + 142, 61, 56, 56, 56, 22, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 142, 56, 147, 146, 148, 148, 146, + 40, 149, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 40, 146, 148, 148, 146, 40, 149, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 40, + 146, 149, 146, 146, 150, 149, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 150, 146, 149, + 146, 149, 146, 146, 146, 149, 146, 42, + 118, 118, 118, 118, 118, 118, 118, 118, + 49, 118, 118, 118, 118, 42, 118, 0 }; static const unsigned char _indic_syllable_machine_trans_targs[] = { @@ -330,41 +996,41 @@ static const unsigned char _indic_syllable_machine_trans_targs[] = { 93, 84, 31, 19, 98, 31, 107, 24, 113, 116, 117, 108, 26, 122, 127, 31, 134, 31, 32, 53, 79, 81, 100, 101, - 85, 102, 123, 124, 94, 132, 137, 31, - 33, 35, 6, 52, 38, 47, 34, 1, - 36, 40, 0, 39, 41, 44, 45, 3, - 48, 5, 49, 31, 54, 56, 14, 77, - 62, 70, 55, 7, 57, 72, 64, 58, - 13, 76, 59, 8, 63, 65, 67, 68, - 10, 71, 12, 73, 31, 80, 20, 82, - 96, 87, 15, 99, 16, 86, 88, 90, - 91, 18, 95, 21, 97, 31, 31, 103, - 105, 22, 27, 109, 118, 104, 106, 120, - 111, 23, 110, 112, 114, 115, 25, 119, - 28, 121, 125, 126, 131, 128, 129, 29, - 130, 31, 133, 30, 135, 136 + 85, 102, 123, 124, 94, 132, 137, 92, + 31, 33, 35, 6, 52, 38, 47, 34, + 1, 36, 40, 0, 39, 41, 44, 45, + 3, 48, 5, 49, 31, 54, 56, 14, + 77, 62, 70, 55, 7, 57, 72, 64, + 58, 13, 76, 59, 8, 63, 65, 67, + 68, 10, 71, 12, 73, 31, 80, 20, + 82, 96, 87, 15, 99, 16, 86, 88, + 90, 91, 18, 95, 21, 97, 31, 31, + 103, 105, 22, 27, 109, 118, 104, 106, + 120, 111, 23, 110, 112, 114, 115, 25, + 119, 28, 121, 125, 126, 131, 128, 129, + 29, 130, 31, 133, 30, 135, 136 }; static const char _indic_syllable_machine_trans_actions[] = { 1, 0, 2, 0, 2, 0, 0, 2, 2, 3, 2, 0, 2, 0, 0, 0, - 2, 2, 2, 4, 2, 0, 5, 0, + 2, 2, 2, 4, 2, 0, 5, 5, 5, 0, 6, 0, 2, 7, 2, 0, 2, 0, 2, 0, 0, 2, 0, 8, 0, 11, 2, 2, 5, 0, 12, 12, 0, 2, 5, 2, 5, 2, 0, 13, - 2, 0, 0, 2, 0, 2, 2, 0, - 2, 2, 0, 0, 2, 2, 2, 0, - 0, 0, 2, 14, 2, 0, 0, 2, - 0, 2, 2, 0, 2, 2, 2, 2, + 14, 2, 0, 0, 2, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 2, - 0, 0, 0, 2, 15, 5, 0, 5, - 2, 2, 0, 5, 0, 0, 2, 5, - 5, 0, 0, 0, 2, 16, 17, 2, - 0, 0, 0, 0, 2, 2, 2, 2, - 2, 0, 0, 2, 2, 2, 0, 0, - 0, 2, 0, 18, 18, 0, 0, 0, - 0, 19, 2, 0, 0, 0 + 0, 0, 0, 2, 15, 2, 0, 0, + 2, 0, 2, 2, 0, 2, 2, 2, + 2, 0, 2, 2, 0, 0, 2, 2, + 2, 0, 0, 0, 2, 16, 5, 0, + 5, 2, 2, 0, 5, 0, 0, 2, + 5, 5, 0, 0, 0, 2, 17, 18, + 2, 0, 0, 0, 0, 2, 2, 2, + 2, 2, 0, 0, 2, 2, 2, 0, + 0, 0, 2, 0, 19, 19, 0, 0, + 0, 0, 20, 2, 0, 0, 0 }; static const char _indic_syllable_machine_to_state_actions[] = { @@ -414,20 +1080,20 @@ static const short _indic_syllable_machine_eof_trans[] = { 10, 10, 10, 10, 10, 10, 10, 20, 20, 27, 20, 27, 20, 20, 30, 30, 30, 30, 30, 30, 30, 1, 40, 0, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 101, - 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 118, 118, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 101, 56, 56, 56, 56, - 56, 56, 56, 56, 146, 146, 146, 146, - 146, 118 + 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 27, 102, 102, 102, + 102, 102, 102, 102, 119, 119, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 102, 57, 57, 57, 57, + 57, 57, 57, 57, 147, 147, 147, 147, + 147, 119 }; static const int indic_syllable_machine_start = 31; @@ -441,7 +1107,7 @@ static const int indic_syllable_machine_en_main = 31; -#line 118 "hb-ot-shaper-indic-machine.rl" +#line 121 "hb-ot-shaper-indic-machine.rl" #define found_syllable(syllable_type) \ @@ -460,7 +1126,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 464 "hb-ot-shaper-indic-machine.hh" +#line 1130 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -468,7 +1134,7 @@ find_syllables_indic (hb_buffer_t *buffer) act = 0; } -#line 138 "hb-ot-shaper-indic-machine.rl" +#line 141 "hb-ot-shaper-indic-machine.rl" p = 0; @@ -476,7 +1142,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 480 "hb-ot-shaper-indic-machine.hh" +#line 1146 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -490,7 +1156,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 494 "hb-ot-shaper-indic-machine.hh" +#line 1160 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -513,51 +1179,51 @@ _eof_trans: {te = p+1;} break; case 11: -#line 114 "hb-ot-shaper-indic-machine.rl" +#line 117 "hb-ot-shaper-indic-machine.rl" {te = p+1;{ found_syllable (indic_non_indic_cluster); }} break; - case 13: -#line 109 "hb-ot-shaper-indic-machine.rl" + case 14: +#line 111 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_consonant_syllable); }} break; - case 14: -#line 110 "hb-ot-shaper-indic-machine.rl" + case 15: +#line 112 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_vowel_syllable); }} break; - case 17: -#line 111 "hb-ot-shaper-indic-machine.rl" + case 18: +#line 113 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_standalone_cluster); }} break; - case 19: -#line 112 "hb-ot-shaper-indic-machine.rl" + case 20: +#line 114 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_symbol_cluster); }} break; - case 15: -#line 113 "hb-ot-shaper-indic-machine.rl" + case 16: +#line 116 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; - case 16: -#line 114 "hb-ot-shaper-indic-machine.rl" + case 17: +#line 117 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_non_indic_cluster); }} break; case 1: -#line 109 "hb-ot-shaper-indic-machine.rl" +#line 111 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} break; case 3: -#line 110 "hb-ot-shaper-indic-machine.rl" +#line 112 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} break; case 7: -#line 111 "hb-ot-shaper-indic-machine.rl" +#line 113 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} break; case 8: -#line 112 "hb-ot-shaper-indic-machine.rl" +#line 114 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} break; case 4: -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 116 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 6: @@ -567,33 +1233,42 @@ _eof_trans: {{p = ((te))-1;} found_syllable (indic_consonant_syllable); } break; case 5: - {{p = ((te))-1;} found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } break; case 6: + {{p = ((te))-1;} found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + case 7: {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } break; } } break; - case 18: + case 19: #line 1 "NONE" {te = p+1;} -#line 109 "hb-ot-shaper-indic-machine.rl" +#line 111 "hb-ot-shaper-indic-machine.rl" {act = 1;} break; - case 5: + case 13: #line 1 "NONE" {te = p+1;} -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 115 "hb-ot-shaper-indic-machine.rl" {act = 5;} break; - case 12: + case 5: #line 1 "NONE" {te = p+1;} -#line 114 "hb-ot-shaper-indic-machine.rl" +#line 116 "hb-ot-shaper-indic-machine.rl" {act = 6;} break; -#line 597 "hb-ot-shaper-indic-machine.hh" + case 12: +#line 1 "NONE" + {te = p+1;} +#line 117 "hb-ot-shaper-indic-machine.rl" + {act = 7;} + break; +#line 1272 "hb-ot-shaper-indic-machine.hh" } _again: @@ -602,7 +1277,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 606 "hb-ot-shaper-indic-machine.hh" +#line 1281 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) @@ -618,7 +1293,7 @@ _again: } -#line 146 "hb-ot-shaper-indic-machine.rl" +#line 149 "hb-ot-shaper-indic-machine.rl" } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc index d9899a633c1..b87c530853b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-15.1.0.txt - * # Date: 2023-01-05 - * # IndicPositionalCategory-15.1.0.txt - * # Date: 2023-01-05 - * # Blocks-15.1.0.txt - * # Date: 2023-07-28, 15:47:20 GMT + * # IndicSyllabicCategory-16.0.0.txt + * # Date: 2024-04-30, 21:48:21 GMT + * # IndicPositionalCategory-16.0.0.txt + * # Date: 2024-04-30, 21:48:21 GMT + * # Blocks-16.0.0.txt + * # Date: 2024-02-02 */ #include "hb.hh" @@ -48,6 +48,7 @@ #define OT_CM I_Cat(CM) #define OT_Symbol I_Cat(Symbol) #define OT_CS I_Cat(CS) +#define OT_SMPst I_Cat(SMPst) /* khmer */ #define OT_VAbv K_Cat(VAbv) #define OT_VBlw K_Cat(VBlw) @@ -89,12 +90,13 @@ static_assert (OT_VPst == M_Cat(VPst), ""); #define _OT_MW OT_MW /* 2 chars; MW */ #define _OT_MY OT_MY /* 3 chars; MY */ #define _OT_N OT_N /* 17 chars; N */ -#define _OT_GB OT_PLACEHOLDER /* 165 chars; PLACEHOLDER */ +#define _OT_GB OT_PLACEHOLDER /* 185 chars; PLACEHOLDER */ #define _OT_PT OT_PT /* 8 chars; PT */ #define _OT_R OT_Ra /* 14 chars; Ra */ #define _OT_Rf OT_Repha /* 1 chars; Repha */ #define _OT_Rt OT_Robatic /* 3 chars; Robatic */ -#define _OT_SM OT_SM /* 56 chars; SM */ +#define _OT_SM OT_SM /* 50 chars; SM */ +#define _OT_SP OT_SMPst /* 6 chars; SMPst */ #define _OT_S OT_Symbol /* 22 chars; Symbol */ #define _OT_V OT_V /* 172 chars; V */ #define _OT_VA OT_VAbv /* 18 chars; VAbv */ @@ -112,7 +114,7 @@ static_assert (OT_VPst == M_Cat(VPst), ""); #define _POS_A POS_AFTER_MAIN /* 3 chars; AFTER_MAIN */ #define _POS_AP POS_AFTER_POST /* 50 chars; AFTER_POST */ #define _POS_AS POS_AFTER_SUB /* 51 chars; AFTER_SUB */ -#define _POS_C POS_BASE_C /* 833 chars; BASE_C */ +#define _POS_C POS_BASE_C /* 853 chars; BASE_C */ #define _POS_BS POS_BEFORE_SUB /* 25 chars; BEFORE_SUB */ #define _POS_B POS_BELOW_C /* 13 chars; BELOW_C */ #define _POS_X POS_END /* 71 chars; END */ @@ -145,7 +147,7 @@ static const uint16_t indic_table[] = { /* Latin-1 Supplement */ - /* 00B0 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X), + /* 00B0 */ _(X,X), _(X,X),_(SP,SM),_(SP,SM), _(X,X), _(X,X), _(X,X), _(X,X), /* 00B8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), /* 00C0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), /* 00C8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), @@ -398,9 +400,9 @@ static const uint16_t indic_table[] = { /* Superscripts and Subscripts */ - /* 2070 */ _(X,X), _(X,X), _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(X,X), + /* 2070 */ _(X,X), _(X,X), _(X,X), _(X,X),_(SP,SM), _(X,X), _(X,X), _(X,X), /* 2078 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 2080 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), + /* 2080 */ _(X,X), _(X,X),_(SP,SM),_(SP,SM),_(SP,SM), _(X,X), _(X,X), _(X,X), #define indic_offset_0x25f8u 1592 @@ -458,7 +460,16 @@ static const uint16_t indic_table[] = { /* 11338 */ _(X,X), _(X,X), _(X,X), _(N,X), _(N,X), _(X,X), _(X,X), _(X,X), -}; /* Table items: 1728; occupancy: 71% */ +#define indic_offset_0x116d0u 1728 + + + /* Myanmar Extended-C */ + + /* 116D0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 116D8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 116E0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), + +}; /* Table items: 1752; occupancy: 71% */ uint16_t hb_indic_get_categories (hb_codepoint_t u) @@ -498,6 +509,7 @@ hb_indic_get_categories (hb_codepoint_t u) case 0x11u: if (hb_in_range (u, 0x11300u, 0x11307u)) return indic_table[u - 0x11300u + indic_offset_0x11300u]; if (hb_in_range (u, 0x11338u, 0x1133Fu)) return indic_table[u - 0x11338u + indic_offset_0x11338u]; + if (hb_in_range (u, 0x116D0u, 0x116E7u)) return indic_table[u - 0x116D0u + indic_offset_0x116d0u]; break; default: @@ -530,6 +542,7 @@ hb_indic_get_categories (hb_codepoint_t u) #undef _OT_Rf #undef _OT_Rt #undef _OT_SM +#undef _OT_SP #undef _OT_S #undef _OT_V #undef _OT_VA diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh index 3dcf61b938f..64eb761b4ea 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh @@ -68,6 +68,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_PT 39u #define myanmar_syllable_machine_ex_Ra 15u #define myanmar_syllable_machine_ex_SM 8u +#define myanmar_syllable_machine_ex_SMPst 57u #define myanmar_syllable_machine_ex_VAbv 20u #define myanmar_syllable_machine_ex_VBlw 21u #define myanmar_syllable_machine_ex_VPre 22u @@ -77,35 +78,35 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 81 "hb-ot-shaper-myanmar-machine.hh" +#line 82 "hb-ot-shaper-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { - 1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, - 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u, - 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 41u, - 3u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, - 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 41u, 3u, 39u, - 3u, 39u, 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u, - 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 1u, 41u, 1u, 15u, 0 + 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 1u, 57u, 1u, 15u, 0 }; static const char _myanmar_syllable_machine_key_spans[] = { - 41, 39, 35, 4, 39, 37, 37, 35, - 35, 37, 37, 39, 35, 15, 37, 37, - 38, 37, 39, 39, 37, 39, 39, 39, - 39, 39, 35, 4, 39, 37, 37, 35, - 35, 37, 37, 39, 35, 15, 39, 37, - 37, 38, 37, 39, 39, 37, 39, 39, - 39, 39, 39, 39, 39, 41, 15 + 57, 55, 53, 53, 55, 53, 55, 55, + 55, 55, 55, 53, 15, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 53, 53, 55, 53, 55, 55, 55, + 55, 55, 53, 15, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 57, 15 }; static const short _myanmar_syllable_machine_index_offsets[] = { - 0, 42, 82, 118, 123, 163, 201, 239, - 275, 311, 349, 387, 427, 463, 479, 517, - 555, 594, 632, 672, 712, 750, 790, 830, - 870, 910, 950, 986, 991, 1031, 1069, 1107, - 1143, 1179, 1217, 1255, 1295, 1331, 1347, 1387, - 1425, 1463, 1502, 1540, 1580, 1620, 1658, 1698, - 1738, 1778, 1818, 1858, 1898, 1938, 1980 + 0, 58, 114, 168, 222, 278, 332, 388, + 444, 500, 556, 612, 666, 682, 738, 794, + 850, 906, 962, 1018, 1074, 1130, 1186, 1242, + 1298, 1354, 1408, 1462, 1518, 1572, 1628, 1684, + 1740, 1796, 1852, 1906, 1922, 1978, 2034, 2090, + 2146, 2202, 2258, 2314, 2370, 2426, 2482, 2538, + 2594, 2650, 2706, 2762, 2820 }; static const char _myanmar_syllable_machine_indicies[] = { @@ -114,273 +115,378 @@ static const char _myanmar_syllable_machine_indicies[] = { 0, 8, 0, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 15, 16, 17, 18, 19, - 20, 0, 22, 23, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 31, - 21, 21, 32, 33, 34, 35, 36, 37, - 38, 21, 24, 24, 21, 25, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 39, 21, 21, - 21, 21, 21, 21, 36, 21, 24, 24, - 21, 25, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 40, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 41, 21, 21, 42, 21, 21, 21, 36, - 21, 41, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 36, - 21, 43, 21, 24, 24, 21, 25, 36, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 44, 21, - 21, 21, 21, 21, 21, 36, 21, 24, - 24, 21, 25, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 44, 21, 21, 21, 21, 21, - 21, 36, 21, 24, 24, 21, 25, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 36, 21, 22, - 21, 24, 24, 21, 25, 26, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 40, 21, 21, 30, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 36, 21, 22, 21, 24, - 24, 21, 25, 26, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 40, 21, - 21, 30, 21, 21, 21, 21, 21, 21, - 21, 21, 41, 21, 21, 21, 21, 21, - 21, 36, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 40, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 41, 21, 21, 21, 21, 21, 21, 36, - 21, 41, 21, 24, 24, 21, 25, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 30, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 36, 21, 1, - 1, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 1, 21, 22, - 21, 24, 24, 21, 25, 26, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 27, 28, 21, 30, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 36, 21, 22, 21, 24, - 24, 21, 25, 26, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 28, - 21, 30, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 36, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 27, 28, 29, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 36, - 45, 21, 22, 21, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 36, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 31, 21, 21, - 32, 33, 34, 35, 36, 21, 38, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 45, 21, 21, - 21, 21, 21, 21, 36, 21, 38, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 45, 21, 21, - 21, 21, 21, 21, 36, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 32, 21, - 34, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 45, 21, 21, 32, 21, - 21, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 46, 21, 21, 32, 33, - 34, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 32, 33, - 34, 21, 36, 21, 38, 21, 22, 23, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 31, 21, 21, 32, 33, - 34, 35, 36, 21, 38, 21, 48, 48, + 20, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 38, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 25, 25, 22, 26, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 31, 22, 22, 22, + 22, 22, 22, 22, 22, 40, 22, 22, + 22, 22, 22, 22, 37, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 26, 22, + 25, 25, 22, 26, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 37, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 26, 22, 41, 22, + 25, 25, 22, 26, 37, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 26, 22, 22, 22, 22, + 22, 22, 37, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 26, 22, 25, 25, + 22, 26, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 26, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 44, 22, 22, 22, + 37, 22, 43, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 22, 22, 22, 22, + 37, 22, 43, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 25, 25, 22, 26, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 1, 1, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 1, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 29, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 45, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 22, 22, 22, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 33, 22, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 33, 22, 22, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 46, + 22, 22, 33, 34, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 33, 34, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 48, 48, 47, 5, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 12, 47, 47, 47, + 47, 47, 47, 47, 47, 49, 47, 47, + 47, 47, 47, 47, 18, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 5, 47, + 48, 48, 50, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 18, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 5, 50, 51, 47, + 48, 48, 47, 5, 18, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 5, 47, 47, 47, 47, + 47, 47, 18, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 5, 47, 48, 48, 47, 5, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 5, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 53, 47, 47, 54, 47, 47, 47, + 18, 47, 53, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 53, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, 12, 47, 47, 47, 47, 47, 47, 47, - 47, 49, 47, 47, 47, 47, 47, 47, - 18, 47, 48, 48, 47, 5, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 47, 53, 47, 47, 47, 47, 47, 47, + 18, 47, 53, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 50, 47, 47, 12, 47, 47, 47, 47, - 47, 47, 47, 47, 51, 47, 47, 52, - 47, 47, 47, 18, 47, 51, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 47, 47, 5, 47, 48, 48, 47, 5, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 12, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 18, 47, 53, 47, 48, - 48, 47, 5, 18, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 54, 47, 47, 47, 47, 47, - 47, 18, 47, 48, 48, 47, 5, 47, + 5, 47, 55, 55, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 55, 47, 2, 3, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 13, + 47, 47, 14, 15, 16, 17, 18, 19, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 54, 47, - 47, 47, 47, 47, 47, 18, 47, 48, - 48, 47, 5, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 18, 47, 2, 47, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 50, 47, 47, 12, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 10, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 18, - 47, 2, 47, 48, 48, 47, 5, 6, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 50, 47, 47, 12, 47, 47, - 47, 47, 47, 47, 47, 47, 51, 47, - 47, 47, 47, 47, 47, 18, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 50, 47, 47, 12, 47, 47, 47, 47, - 47, 47, 47, 47, 51, 47, 47, 47, - 47, 47, 47, 18, 47, 51, 47, 48, - 48, 47, 5, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 12, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 56, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 18, 47, 55, 55, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 55, 47, 2, 3, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 9, 10, 11, 12, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 13, 47, 47, 14, 15, 16, 17, 18, - 19, 20, 47, 2, 47, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 9, 10, 47, 12, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 18, - 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 10, 47, 12, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 13, + 47, 47, 14, 15, 16, 17, 18, 47, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 18, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 56, + 47, 47, 47, 47, 47, 47, 18, 47, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 9, 10, 11, 12, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 56, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 18, 56, 47, 2, 47, - 48, 48, 47, 5, 6, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 9, - 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 18, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 13, 47, 47, 14, 15, 16, 17, - 18, 47, 20, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 56, 47, 47, 47, 47, 47, 47, - 18, 47, 20, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 56, 47, 47, 47, 47, 47, 47, - 18, 47, 2, 47, 48, 48, 47, 5, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 14, 47, 16, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 56, 47, 47, 14, 47, 47, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 57, 47, 47, 14, 15, 16, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 14, 15, 16, 47, 18, 47, - 20, 47, 2, 3, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 3, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 13, 47, 47, 14, 15, 16, 17, 18, 47, - 20, 47, 22, 23, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 58, - 21, 21, 32, 33, 34, 35, 36, 37, - 38, 21, 22, 59, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 31, - 21, 21, 32, 33, 34, 35, 36, 21, - 38, 21, 1, 1, 2, 3, 48, 48, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 58, + 22, 22, 33, 34, 35, 36, 37, 38, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 59, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 1, 1, 2, 3, 48, 48, 47, 5, 6, 1, 1, 47, 47, 47, 1, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 13, 47, 47, 14, 15, 16, 17, - 18, 19, 20, 47, 1, 1, 60, 60, + 18, 19, 20, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 1, 1, 60, 60, 60, 60, 60, 60, 60, 1, 1, 60, 60, 60, 1, 60, 0 }; static const char _myanmar_syllable_machine_trans_targs[] = { - 0, 1, 26, 37, 0, 27, 29, 51, - 54, 39, 40, 41, 28, 43, 44, 46, - 47, 48, 30, 50, 45, 0, 2, 13, - 0, 3, 5, 14, 15, 16, 4, 18, - 19, 21, 22, 23, 6, 25, 20, 12, - 9, 10, 11, 7, 8, 17, 24, 0, - 0, 36, 33, 34, 35, 31, 32, 38, - 42, 49, 52, 53, 0 + 0, 1, 25, 35, 0, 26, 30, 49, + 52, 37, 38, 39, 29, 41, 42, 44, + 45, 46, 27, 48, 43, 26, 0, 2, + 12, 0, 3, 7, 13, 14, 15, 6, + 17, 18, 20, 21, 22, 4, 24, 19, + 11, 5, 8, 9, 10, 16, 23, 0, + 0, 34, 0, 28, 31, 32, 33, 36, + 40, 47, 50, 51, 0 }; static const char _myanmar_syllable_machine_trans_actions[] = { - 3, 0, 0, 0, 4, 0, 0, 0, + 3, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 7, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9 + 0, 0, 0, 0, 0, 0, 0, 9, + 10, 0, 11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12 }; static const char _myanmar_syllable_machine_to_state_actions[] = { @@ -390,7 +496,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0 }; static const char _myanmar_syllable_machine_from_state_actions[] = { @@ -400,17 +506,17 @@ static const char _myanmar_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0 }; static const short _myanmar_syllable_machine_eof_trans[] = { - 0, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 48, 48, 48, 48, 48, 48, + 0, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 48, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 22, 22, 48, 61 + 48, 23, 23, 48, 61 }; static const int myanmar_syllable_machine_start = 0; @@ -424,7 +530,7 @@ static const int myanmar_syllable_machine_en_main = 0; -#line 117 "hb-ot-shaper-myanmar-machine.rl" +#line 118 "hb-ot-shaper-myanmar-machine.rl" #define found_syllable(syllable_type) \ @@ -443,7 +549,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 447 "hb-ot-shaper-myanmar-machine.hh" +#line 553 "hb-ot-shaper-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -451,7 +557,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) act = 0; } -#line 137 "hb-ot-shaper-myanmar-machine.rl" +#line 138 "hb-ot-shaper-myanmar-machine.rl" p = 0; @@ -459,7 +565,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 463 "hb-ot-shaper-myanmar-machine.hh" +#line 569 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -473,7 +579,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 477 "hb-ot-shaper-myanmar-machine.hh" +#line 583 "hb-ot-shaper-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -491,35 +597,59 @@ _eof_trans: goto _again; switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { - case 6: -#line 110 "hb-ot-shaper-myanmar-machine.rl" + case 8: +#line 111 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_consonant_syllable); }} break; case 4: -#line 111 "hb-ot-shaper-myanmar-machine.rl" +#line 112 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; - case 8: -#line 112 "hb-ot-shaper-myanmar-machine.rl" + case 10: +#line 113 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 3: -#line 113 "hb-ot-shaper-myanmar-machine.rl" +#line 114 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; - case 5: -#line 110 "hb-ot-shaper-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} - break; case 7: -#line 112 "hb-ot-shaper-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} +#line 111 "hb-ot-shaper-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} break; case 9: #line 113 "hb-ot-shaper-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} + break; + case 12: +#line 114 "hb-ot-shaper-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 523 "hb-ot-shaper-myanmar-machine.hh" + case 11: +#line 1 "NONE" + { switch( act ) { + case 2: + {{p = ((te))-1;} found_syllable (myanmar_non_myanmar_cluster); } + break; + case 3: + {{p = ((te))-1;} found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + } + } + break; + case 6: +#line 1 "NONE" + {te = p+1;} +#line 112 "hb-ot-shaper-myanmar-machine.rl" + {act = 2;} + break; + case 5: +#line 1 "NONE" + {te = p+1;} +#line 113 "hb-ot-shaper-myanmar-machine.rl" + {act = 3;} + break; +#line 653 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -528,7 +658,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 532 "hb-ot-shaper-myanmar-machine.hh" +#line 662 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) @@ -544,7 +674,7 @@ _again: } -#line 145 "hb-ot-shaper-myanmar-machine.rl" +#line 146 "hb-ot-shaper-myanmar-machine.rl" } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh index 47b0e6bbdcc..46f66f7d285 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh @@ -81,6 +81,7 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_N 4u #define use_syllable_machine_ex_O 0u #define use_syllable_machine_ex_R 18u +#define use_syllable_machine_ex_RK 56u #define use_syllable_machine_ex_SB 51u #define use_syllable_machine_ex_SE 52u #define use_syllable_machine_ex_SMAbv 41u @@ -99,62 +100,62 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 103 "hb-ot-shaper-use-machine.hh" +#line 104 "hb-ot-shaper-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 49u, 51u, 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, + 49u, 51u, 0u, 56u, 11u, 56u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, - 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 53u, + 12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, - 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, - 1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, - 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, - 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, - 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u, 1u, 48u, - 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, - 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, - 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, - 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 14u, 42u, 14u, 42u, 1u, 5u, - 14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 53u, 0 + 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, + 1u, 14u, 1u, 48u, 14u, 14u, 13u, 14u, 4u, 14u, 11u, 56u, 11u, 56u, 1u, 53u, + 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, + 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, + 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, 1u, 14u, + 1u, 48u, 14u, 14u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, + 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, + 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, + 12u, 53u, 11u, 56u, 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 56u, 14u, 42u, + 14u, 42u, 1u, 5u, 14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 56u, 0 }; static const char _use_syllable_machine_key_spans[] = { - 3, 54, 43, 43, 53, 35, 34, 34, + 3, 57, 46, 46, 53, 35, 34, 34, 34, 33, 33, 1, 35, 35, 35, 14, 35, 40, 40, 40, 40, 42, 40, 42, - 42, 42, 43, 14, 48, 29, 29, 43, + 42, 42, 46, 14, 48, 29, 29, 46, 53, 35, 34, 34, 34, 33, 33, 1, 35, 35, 35, 14, 35, 40, 40, 40, - 40, 42, 40, 42, 42, 42, 43, 14, - 14, 48, 2, 11, 43, 43, 53, 35, - 34, 34, 34, 33, 33, 1, 35, 35, - 35, 14, 35, 40, 40, 40, 40, 42, - 40, 42, 42, 42, 43, 14, 14, 48, - 43, 53, 35, 34, 34, 34, 33, 33, - 1, 35, 35, 35, 14, 35, 40, 40, - 40, 40, 42, 40, 42, 42, 42, 43, - 14, 48, 11, 2, 53, 29, 29, 5, - 42, 38, 39, 41, 43 + 40, 42, 40, 42, 42, 42, 46, 14, + 14, 48, 1, 2, 11, 46, 46, 53, + 35, 34, 34, 34, 33, 33, 1, 35, + 35, 35, 14, 35, 40, 40, 40, 40, + 42, 40, 42, 42, 42, 46, 14, 14, + 48, 1, 46, 53, 35, 34, 34, 34, + 33, 33, 1, 35, 35, 35, 14, 35, + 40, 40, 40, 40, 42, 40, 42, 42, + 42, 46, 14, 48, 11, 2, 56, 29, + 29, 5, 42, 38, 39, 41, 46 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 4, 59, 103, 147, 201, 237, 272, - 307, 342, 376, 410, 412, 448, 484, 520, - 535, 571, 612, 653, 694, 735, 778, 819, - 862, 905, 948, 992, 1007, 1056, 1086, 1116, - 1160, 1214, 1250, 1285, 1320, 1355, 1389, 1423, - 1425, 1461, 1497, 1533, 1548, 1584, 1625, 1666, - 1707, 1748, 1791, 1832, 1875, 1918, 1961, 2005, - 2020, 2035, 2084, 2087, 2099, 2143, 2187, 2241, - 2277, 2312, 2347, 2382, 2416, 2450, 2452, 2488, - 2524, 2560, 2575, 2611, 2652, 2693, 2734, 2775, - 2818, 2859, 2902, 2945, 2988, 3032, 3047, 3062, - 3111, 3155, 3209, 3245, 3280, 3315, 3350, 3384, - 3418, 3420, 3456, 3492, 3528, 3543, 3579, 3620, - 3661, 3702, 3743, 3786, 3827, 3870, 3913, 3956, - 4000, 4015, 4064, 4076, 4079, 4133, 4163, 4193, - 4199, 4242, 4281, 4321, 4363 + 0, 4, 62, 109, 156, 210, 246, 281, + 316, 351, 385, 419, 421, 457, 493, 529, + 544, 580, 621, 662, 703, 744, 787, 828, + 871, 914, 957, 1004, 1019, 1068, 1098, 1128, + 1175, 1229, 1265, 1300, 1335, 1370, 1404, 1438, + 1440, 1476, 1512, 1548, 1563, 1599, 1640, 1681, + 1722, 1763, 1806, 1847, 1890, 1933, 1976, 2023, + 2038, 2053, 2102, 2104, 2107, 2119, 2166, 2213, + 2267, 2303, 2338, 2373, 2408, 2442, 2476, 2478, + 2514, 2550, 2586, 2601, 2637, 2678, 2719, 2760, + 2801, 2844, 2885, 2928, 2971, 3014, 3061, 3076, + 3091, 3140, 3142, 3189, 3243, 3279, 3314, 3349, + 3384, 3418, 3452, 3454, 3490, 3526, 3562, 3577, + 3613, 3654, 3695, 3736, 3777, 3820, 3861, 3904, + 3947, 3990, 4037, 4052, 4101, 4113, 4116, 4173, + 4203, 4233, 4239, 4282, 4321, 4361, 4403 }; static const unsigned char _use_syllable_machine_indicies[] = { @@ -165,571 +166,578 @@ static const unsigned char _use_syllable_machine_indicies[] = { 19, 20, 21, 8, 22, 23, 24, 25, 5, 26, 27, 28, 5, 29, 30, 31, 32, 33, 34, 35, 32, 1, 5, 36, - 5, 37, 5, 39, 40, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 39, - 51, 52, 53, 54, 38, 55, 56, 57, - 38, 58, 59, 38, 60, 61, 62, 63, - 60, 38, 38, 38, 38, 64, 38, 39, - 40, 38, 41, 38, 38, 38, 38, 38, - 38, 38, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 39, 51, 52, 53, 54, - 38, 55, 56, 57, 38, 38, 38, 38, - 60, 61, 62, 63, 60, 38, 38, 38, - 38, 64, 38, 39, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 43, 44, 45, 46, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 55, - 56, 57, 38, 38, 38, 38, 38, 61, - 62, 63, 65, 38, 38, 38, 38, 43, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 38, 43, 44, 45, 46, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 55, 56, 57, 38, 38, 38, 38, 38, - 61, 62, 63, 65, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 44, - 45, 46, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 61, 62, 63, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 45, 46, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 61, - 62, 63, 38, 41, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 46, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 61, 62, 63, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 61, 62, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 62, 38, 41, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 55, 56, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 44, 45, 46, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 56, 57, 38, 38, 38, 38, 38, 61, - 62, 63, 65, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 66, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 41, 38, 41, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 44, 45, 46, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 61, 62, - 63, 65, 38, 41, 38, 38, 38, 38, - 38, 38, 38, 42, 43, 44, 45, 46, - 38, 38, 38, 38, 38, 38, 52, 53, - 54, 38, 55, 56, 57, 38, 38, 38, - 38, 38, 61, 62, 63, 65, 38, 38, - 38, 38, 43, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 43, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 52, - 53, 54, 38, 55, 56, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 38, 38, 38, 43, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 38, 43, 44, - 45, 46, 38, 38, 38, 38, 38, 38, - 38, 53, 54, 38, 55, 56, 57, 38, - 38, 38, 38, 38, 61, 62, 63, 65, - 38, 38, 38, 38, 43, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 38, 43, - 44, 45, 46, 38, 38, 38, 38, 38, - 38, 38, 38, 54, 38, 55, 56, 57, - 38, 38, 38, 38, 38, 61, 62, 63, - 65, 38, 38, 38, 38, 43, 38, 67, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 42, 43, 44, 45, 46, 38, 48, - 49, 38, 38, 38, 52, 53, 54, 38, - 55, 56, 57, 38, 38, 38, 38, 38, - 61, 62, 63, 65, 38, 38, 38, 38, - 43, 38, 41, 38, 38, 38, 38, 38, - 38, 38, 38, 43, 44, 45, 46, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 55, 56, 57, 38, 38, 38, 38, - 38, 61, 62, 63, 65, 38, 38, 38, - 38, 43, 38, 67, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 42, 43, 44, - 45, 46, 38, 38, 49, 38, 38, 38, - 52, 53, 54, 38, 55, 56, 57, 38, - 38, 38, 38, 38, 61, 62, 63, 65, - 38, 38, 38, 38, 43, 38, 67, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 42, 43, 44, 45, 46, 38, 38, 38, - 38, 38, 38, 52, 53, 54, 38, 55, - 56, 57, 38, 38, 38, 38, 38, 61, - 62, 63, 65, 38, 38, 38, 38, 43, - 38, 67, 38, 41, 38, 38, 38, 38, - 38, 38, 38, 42, 43, 44, 45, 46, - 47, 48, 49, 38, 38, 38, 52, 53, - 54, 38, 55, 56, 57, 38, 38, 38, - 38, 38, 61, 62, 63, 65, 38, 38, - 38, 38, 43, 38, 39, 40, 38, 41, - 38, 38, 38, 38, 38, 38, 38, 42, + 5, 37, 5, 5, 38, 5, 40, 41, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 40, 52, 53, 54, 55, 39, + 56, 57, 58, 39, 59, 60, 39, 61, + 62, 63, 64, 61, 39, 39, 39, 39, + 65, 39, 39, 64, 39, 40, 41, 39, + 42, 39, 39, 39, 39, 39, 39, 39, 43, 44, 45, 46, 47, 48, 49, 50, - 38, 51, 52, 53, 54, 38, 55, 56, - 57, 38, 38, 38, 38, 60, 61, 62, - 63, 60, 38, 38, 38, 38, 64, 38, - 39, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 41, 38, 39, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 43, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 55, 56, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 58, 59, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 59, 38, 4, 69, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 4, 80, 81, 82, 83, 68, 84, 85, - 86, 68, 68, 68, 68, 87, 88, 89, - 90, 91, 68, 68, 68, 68, 92, 68, - 4, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 72, 73, - 74, 75, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 84, 85, 86, 68, - 68, 68, 68, 68, 88, 89, 90, 93, - 68, 68, 68, 68, 72, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 72, - 73, 74, 75, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 84, 85, 86, - 68, 68, 68, 68, 68, 88, 89, 90, - 93, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 73, 74, 75, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 88, 89, 90, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 74, 75, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 88, 89, 90, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 75, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 88, - 89, 90, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 88, 89, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 89, 68, 70, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 73, 74, 75, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 84, 85, 86, 68, 68, 68, 68, 68, - 88, 89, 90, 93, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 73, - 74, 75, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 85, 86, 68, - 68, 68, 68, 68, 88, 89, 90, 93, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 73, 74, 75, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 86, 68, 68, 68, 68, 68, - 88, 89, 90, 93, 68, 95, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 96, 94, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 73, 74, - 75, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 88, 89, 90, 93, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 71, 72, 73, 74, 75, 68, 68, 68, - 68, 68, 68, 81, 82, 83, 68, 84, - 85, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 93, 68, 68, 68, 68, 72, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 72, 73, 74, 75, 68, 68, - 68, 68, 68, 68, 81, 82, 83, 68, - 84, 85, 86, 68, 68, 68, 68, 68, - 88, 89, 90, 93, 68, 68, 68, 68, - 72, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 72, 73, 74, 75, 68, - 68, 68, 68, 68, 68, 68, 82, 83, - 68, 84, 85, 86, 68, 68, 68, 68, - 68, 88, 89, 90, 93, 68, 68, 68, - 68, 72, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 72, 73, 74, 75, - 68, 68, 68, 68, 68, 68, 68, 68, - 83, 68, 84, 85, 86, 68, 68, 68, - 68, 68, 88, 89, 90, 93, 68, 68, - 68, 68, 72, 68, 97, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 71, 72, - 73, 74, 75, 68, 77, 78, 68, 68, - 68, 81, 82, 83, 68, 84, 85, 86, - 68, 68, 68, 68, 68, 88, 89, 90, - 93, 68, 68, 68, 68, 72, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 68, - 72, 73, 74, 75, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 84, 85, - 86, 68, 68, 68, 68, 68, 88, 89, - 90, 93, 68, 68, 68, 68, 72, 68, - 97, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 71, 72, 73, 74, 75, 68, - 68, 78, 68, 68, 68, 81, 82, 83, - 68, 84, 85, 86, 68, 68, 68, 68, - 68, 88, 89, 90, 93, 68, 68, 68, - 68, 72, 68, 97, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 71, 72, 73, - 74, 75, 68, 68, 68, 68, 68, 68, - 81, 82, 83, 68, 84, 85, 86, 68, - 68, 68, 68, 68, 88, 89, 90, 93, - 68, 68, 68, 68, 72, 68, 97, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 71, 72, 73, 74, 75, 76, 77, 78, - 68, 68, 68, 81, 82, 83, 68, 84, - 85, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 93, 68, 68, 68, 68, 72, - 68, 4, 69, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 68, 80, 81, - 82, 83, 68, 84, 85, 86, 68, 68, - 68, 68, 87, 88, 89, 90, 91, 68, - 68, 68, 68, 92, 68, 4, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 99, 98, 4, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, - 94, 96, 94, 4, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 72, 73, 74, 75, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 84, - 85, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 93, 68, 101, 102, 100, 6, - 103, 103, 103, 103, 103, 103, 103, 103, - 103, 104, 103, 105, 106, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 105, - 116, 117, 118, 119, 68, 120, 121, 122, - 68, 58, 59, 68, 123, 124, 125, 126, - 127, 68, 68, 68, 68, 128, 68, 105, - 106, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 105, 116, 117, 118, 119, - 68, 120, 121, 122, 68, 68, 68, 68, - 123, 124, 125, 126, 127, 68, 68, 68, - 68, 128, 68, 105, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 108, 109, 110, 111, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 120, - 121, 122, 68, 68, 68, 68, 68, 124, - 125, 126, 129, 68, 68, 68, 68, 108, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 108, 109, 110, 111, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 120, 121, 122, 68, 68, 68, 68, 68, - 124, 125, 126, 129, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 109, - 110, 111, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 124, 125, 126, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 110, 111, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 124, - 125, 126, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 111, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 124, 125, 126, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 124, 125, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 125, 68, 70, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 109, 110, - 111, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 120, 121, 122, 68, 68, - 68, 68, 68, 124, 125, 126, 129, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 109, 110, 111, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 121, 122, 68, 68, 68, 68, 68, 124, - 125, 126, 129, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 109, 110, - 111, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 122, 68, 68, - 68, 68, 68, 124, 125, 126, 129, 68, - 130, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 96, 94, 70, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 109, 110, 111, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 124, 125, - 126, 129, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 107, 108, 109, 110, 111, - 68, 68, 68, 68, 68, 68, 117, 118, - 119, 68, 120, 121, 122, 68, 68, 68, - 68, 68, 124, 125, 126, 129, 68, 68, - 68, 68, 108, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 108, 109, 110, - 111, 68, 68, 68, 68, 68, 68, 117, - 118, 119, 68, 120, 121, 122, 68, 68, - 68, 68, 68, 124, 125, 126, 129, 68, - 68, 68, 68, 108, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 108, 109, - 110, 111, 68, 68, 68, 68, 68, 68, - 68, 118, 119, 68, 120, 121, 122, 68, - 68, 68, 68, 68, 124, 125, 126, 129, - 68, 68, 68, 68, 108, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 108, - 109, 110, 111, 68, 68, 68, 68, 68, - 68, 68, 68, 119, 68, 120, 121, 122, - 68, 68, 68, 68, 68, 124, 125, 126, - 129, 68, 68, 68, 68, 108, 68, 131, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 107, 108, 109, 110, 111, 68, 113, - 114, 68, 68, 68, 117, 118, 119, 68, - 120, 121, 122, 68, 68, 68, 68, 68, - 124, 125, 126, 129, 68, 68, 68, 68, - 108, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 108, 109, 110, 111, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 120, 121, 122, 68, 68, 68, 68, - 68, 124, 125, 126, 129, 68, 68, 68, - 68, 108, 68, 131, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 107, 108, 109, - 110, 111, 68, 68, 114, 68, 68, 68, - 117, 118, 119, 68, 120, 121, 122, 68, - 68, 68, 68, 68, 124, 125, 126, 129, - 68, 68, 68, 68, 108, 68, 131, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 107, 108, 109, 110, 111, 68, 68, 68, - 68, 68, 68, 117, 118, 119, 68, 120, - 121, 122, 68, 68, 68, 68, 68, 124, - 125, 126, 129, 68, 68, 68, 68, 108, - 68, 131, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 107, 108, 109, 110, 111, - 112, 113, 114, 68, 68, 68, 117, 118, - 119, 68, 120, 121, 122, 68, 68, 68, - 68, 68, 124, 125, 126, 129, 68, 68, - 68, 68, 108, 68, 105, 106, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 107, - 108, 109, 110, 111, 112, 113, 114, 115, - 68, 116, 117, 118, 119, 68, 120, 121, - 122, 68, 68, 68, 68, 123, 124, 125, - 126, 127, 68, 68, 68, 68, 128, 68, - 105, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 99, 98, 105, - 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 96, 94, 105, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 108, 109, 110, 111, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 120, 121, 122, 68, 68, 68, - 68, 68, 124, 125, 126, 129, 68, 8, - 9, 132, 11, 132, 132, 132, 132, 132, - 132, 132, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 8, 22, 23, 24, 25, - 132, 26, 27, 28, 132, 132, 132, 132, - 32, 33, 34, 35, 32, 132, 132, 132, - 132, 37, 132, 8, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 132, 14, 15, 16, 17, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 26, - 27, 28, 132, 132, 132, 132, 132, 33, - 34, 35, 133, 132, 132, 132, 132, 14, - 132, 11, 132, 132, 132, 132, 132, 132, - 132, 132, 14, 15, 16, 17, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 26, 27, 28, 132, 132, 132, 132, 132, - 33, 34, 35, 133, 132, 11, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 15, - 16, 17, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 33, 34, 35, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 16, 17, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 33, - 34, 35, 132, 11, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 17, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 33, 34, 35, 132, 11, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 33, 34, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 34, 132, 11, 132, 11, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 15, 16, - 17, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 26, 27, 28, 132, 132, - 132, 132, 132, 33, 34, 35, 133, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 15, 16, 17, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 27, 28, 132, 132, 132, 132, 132, 33, - 34, 35, 133, 132, 11, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 15, 16, - 17, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 28, 132, 132, - 132, 132, 132, 33, 34, 35, 133, 132, - 134, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 11, 132, 11, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 15, 16, 17, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 33, 34, - 35, 133, 132, 11, 132, 132, 132, 132, - 132, 132, 132, 13, 14, 15, 16, 17, - 132, 132, 132, 132, 132, 132, 23, 24, - 25, 132, 26, 27, 28, 132, 132, 132, - 132, 132, 33, 34, 35, 133, 132, 132, - 132, 132, 14, 132, 11, 132, 132, 132, - 132, 132, 132, 132, 132, 14, 15, 16, - 17, 132, 132, 132, 132, 132, 132, 23, - 24, 25, 132, 26, 27, 28, 132, 132, - 132, 132, 132, 33, 34, 35, 133, 132, - 132, 132, 132, 14, 132, 11, 132, 132, - 132, 132, 132, 132, 132, 132, 14, 15, - 16, 17, 132, 132, 132, 132, 132, 132, - 132, 24, 25, 132, 26, 27, 28, 132, - 132, 132, 132, 132, 33, 34, 35, 133, - 132, 132, 132, 132, 14, 132, 11, 132, - 132, 132, 132, 132, 132, 132, 132, 14, - 15, 16, 17, 132, 132, 132, 132, 132, - 132, 132, 132, 25, 132, 26, 27, 28, - 132, 132, 132, 132, 132, 33, 34, 35, - 133, 132, 132, 132, 132, 14, 132, 135, - 132, 11, 132, 132, 132, 132, 132, 132, - 132, 13, 14, 15, 16, 17, 132, 19, - 20, 132, 132, 132, 23, 24, 25, 132, - 26, 27, 28, 132, 132, 132, 132, 132, - 33, 34, 35, 133, 132, 132, 132, 132, - 14, 132, 11, 132, 132, 132, 132, 132, - 132, 132, 132, 14, 15, 16, 17, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 26, 27, 28, 132, 132, 132, 132, - 132, 33, 34, 35, 133, 132, 132, 132, - 132, 14, 132, 135, 132, 11, 132, 132, - 132, 132, 132, 132, 132, 13, 14, 15, - 16, 17, 132, 132, 20, 132, 132, 132, - 23, 24, 25, 132, 26, 27, 28, 132, - 132, 132, 132, 132, 33, 34, 35, 133, - 132, 132, 132, 132, 14, 132, 135, 132, - 11, 132, 132, 132, 132, 132, 132, 132, - 13, 14, 15, 16, 17, 132, 132, 132, - 132, 132, 132, 23, 24, 25, 132, 26, - 27, 28, 132, 132, 132, 132, 132, 33, - 34, 35, 133, 132, 132, 132, 132, 14, - 132, 135, 132, 11, 132, 132, 132, 132, - 132, 132, 132, 13, 14, 15, 16, 17, - 18, 19, 20, 132, 132, 132, 23, 24, - 25, 132, 26, 27, 28, 132, 132, 132, - 132, 132, 33, 34, 35, 133, 132, 132, - 132, 132, 14, 132, 8, 9, 132, 11, - 132, 132, 132, 132, 132, 132, 132, 13, - 14, 15, 16, 17, 18, 19, 20, 21, - 132, 22, 23, 24, 25, 132, 26, 27, - 28, 132, 132, 132, 132, 32, 33, 34, - 35, 32, 132, 132, 132, 132, 37, 132, - 8, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 11, 132, 8, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 11, 132, 132, 132, - 132, 132, 132, 132, 132, 14, 15, 16, - 17, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 26, 27, 28, 132, 132, - 132, 132, 132, 33, 34, 35, 133, 132, - 136, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 11, 132, 10, 11, 132, 4, - 132, 132, 132, 4, 132, 132, 132, 132, - 132, 8, 9, 10, 11, 132, 132, 132, - 132, 132, 132, 132, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 8, 22, 23, - 24, 25, 132, 26, 27, 28, 132, 29, - 30, 132, 32, 33, 34, 35, 32, 132, - 132, 132, 132, 37, 132, 11, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 29, 30, 132, 11, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 30, - 132, 4, 137, 137, 137, 4, 137, 139, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 140, 138, 141, 138, 141, - 142, 138, 139, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 1, 140, 140, - 138, 139, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 140, 138, 141, - 138, 139, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 140, 138, 141, - 138, 141, 138, 39, 40, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 39, - 51, 52, 53, 54, 38, 55, 56, 57, - 38, 58, 59, 38, 60, 61, 62, 63, - 60, 1, 38, 2, 38, 64, 38, 0 + 51, 40, 52, 53, 54, 55, 39, 56, + 57, 58, 39, 39, 39, 39, 61, 62, + 63, 64, 61, 39, 39, 39, 39, 65, + 39, 39, 64, 39, 40, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 44, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 56, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 39, 39, 39, + 44, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 39, 44, 45, 46, 47, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 56, 57, 58, 39, 39, 39, 39, + 39, 62, 63, 64, 66, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 45, 46, 47, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 62, 63, 64, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 62, 63, 64, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 47, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 62, 63, 64, 39, 42, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 62, 63, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 63, 39, 42, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 56, 57, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 67, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 42, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 45, 46, 47, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 62, + 63, 64, 66, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 43, 44, 45, 46, + 47, 39, 39, 39, 39, 39, 39, 53, + 54, 55, 39, 56, 57, 58, 39, 39, + 39, 39, 39, 62, 63, 64, 66, 39, + 39, 39, 39, 44, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 44, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 53, 54, 55, 39, 56, 57, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 39, 39, 39, 44, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 39, 44, + 45, 46, 47, 39, 39, 39, 39, 39, + 39, 39, 54, 55, 39, 56, 57, 58, + 39, 39, 39, 39, 39, 62, 63, 64, + 66, 39, 39, 39, 39, 44, 39, 42, + 39, 39, 39, 39, 39, 39, 39, 39, + 44, 45, 46, 47, 39, 39, 39, 39, + 39, 39, 39, 39, 55, 39, 56, 57, + 58, 39, 39, 39, 39, 39, 62, 63, + 64, 66, 39, 39, 39, 39, 44, 39, + 68, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 43, 44, 45, 46, 47, 39, + 49, 50, 39, 39, 39, 53, 54, 55, + 39, 56, 57, 58, 39, 39, 39, 39, + 39, 62, 63, 64, 66, 39, 39, 39, + 39, 44, 39, 42, 39, 39, 39, 39, + 39, 39, 39, 39, 44, 45, 46, 47, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 56, 57, 58, 39, 39, 39, + 39, 39, 62, 63, 64, 66, 39, 39, + 39, 39, 44, 39, 68, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 43, 44, + 45, 46, 47, 39, 39, 50, 39, 39, + 39, 53, 54, 55, 39, 56, 57, 58, + 39, 39, 39, 39, 39, 62, 63, 64, + 66, 39, 39, 39, 39, 44, 39, 68, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 43, 44, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 53, 54, 55, 39, + 56, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 39, 39, 39, + 44, 39, 68, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 43, 44, 45, 46, + 47, 48, 49, 50, 39, 39, 39, 53, + 54, 55, 39, 56, 57, 58, 39, 39, + 39, 39, 39, 62, 63, 64, 66, 39, + 39, 39, 39, 44, 39, 40, 41, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 39, 52, 53, 54, 55, 39, 56, + 57, 58, 39, 39, 39, 39, 61, 62, + 63, 64, 61, 39, 39, 39, 39, 65, + 39, 39, 64, 39, 40, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 42, 39, 40, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 39, 44, 45, 46, 47, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 56, + 57, 58, 39, 39, 39, 39, 39, 62, + 63, 64, 66, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 59, + 60, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 60, 39, + 4, 70, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 4, 81, 82, 83, + 84, 69, 85, 86, 87, 69, 69, 69, + 69, 88, 89, 90, 91, 92, 69, 69, + 69, 69, 93, 69, 69, 94, 69, 4, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 73, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 85, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 69, 69, 69, 73, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 69, 73, 74, + 75, 76, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 85, 86, 87, 69, + 69, 69, 69, 69, 89, 90, 91, 95, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 74, 75, 76, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 89, 90, 91, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 89, 90, 91, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 76, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 89, 90, + 91, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 89, 90, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 90, 69, 71, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 85, + 86, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 97, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 98, 96, 71, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 74, 75, 76, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 89, 90, 91, 95, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 72, + 73, 74, 75, 76, 69, 69, 69, 69, + 69, 69, 82, 83, 84, 69, 85, 86, + 87, 69, 69, 69, 69, 69, 89, 90, + 91, 95, 69, 69, 69, 69, 73, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 73, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 82, 83, 84, 69, 85, + 86, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 69, 69, 69, 73, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 73, 74, 75, 76, 69, 69, + 69, 69, 69, 69, 69, 83, 84, 69, + 85, 86, 87, 69, 69, 69, 69, 69, + 89, 90, 91, 95, 69, 69, 69, 69, + 73, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 73, 74, 75, 76, 69, + 69, 69, 69, 69, 69, 69, 69, 84, + 69, 85, 86, 87, 69, 69, 69, 69, + 69, 89, 90, 91, 95, 69, 69, 69, + 69, 73, 69, 99, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 72, 73, 74, + 75, 76, 69, 78, 79, 69, 69, 69, + 82, 83, 84, 69, 85, 86, 87, 69, + 69, 69, 69, 69, 89, 90, 91, 95, + 69, 69, 69, 69, 73, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 73, + 74, 75, 76, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 85, 86, 87, + 69, 69, 69, 69, 69, 89, 90, 91, + 95, 69, 69, 69, 69, 73, 69, 99, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 72, 73, 74, 75, 76, 69, 69, + 79, 69, 69, 69, 82, 83, 84, 69, + 85, 86, 87, 69, 69, 69, 69, 69, + 89, 90, 91, 95, 69, 69, 69, 69, + 73, 69, 99, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 72, 73, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 82, + 83, 84, 69, 85, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 69, 69, 69, 73, 69, 99, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 72, + 73, 74, 75, 76, 77, 78, 79, 69, + 69, 69, 82, 83, 84, 69, 85, 86, + 87, 69, 69, 69, 69, 69, 89, 90, + 91, 95, 69, 69, 69, 69, 73, 69, + 4, 70, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 69, 81, 82, 83, + 84, 69, 85, 86, 87, 69, 69, 69, + 69, 88, 89, 90, 91, 92, 69, 69, + 69, 69, 93, 69, 69, 94, 69, 4, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 101, 100, 4, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 98, 96, 4, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 73, 74, 75, 76, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 85, 86, 87, 69, 69, 69, 69, + 69, 89, 90, 91, 95, 69, 101, 100, + 103, 104, 102, 6, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 106, 105, 107, + 108, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 107, 118, 119, 120, 121, + 69, 122, 123, 124, 69, 59, 60, 69, + 125, 126, 127, 128, 129, 69, 69, 69, + 69, 130, 69, 69, 131, 69, 107, 108, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 107, 118, 119, 120, 121, 69, + 122, 123, 124, 69, 69, 69, 69, 125, + 126, 127, 128, 129, 69, 69, 69, 69, + 130, 69, 69, 131, 69, 107, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 110, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 122, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 69, 69, + 69, 110, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 69, 110, 111, 112, 113, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 122, 123, 124, 69, 69, 69, + 69, 69, 126, 127, 128, 132, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 111, 112, 113, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 126, 127, + 128, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 126, 127, 128, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 113, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 126, 127, 128, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 126, + 127, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 127, 69, 71, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 122, 123, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 133, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 98, + 96, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 111, 112, 113, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 126, 127, 128, 132, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 109, 110, 111, + 112, 113, 69, 69, 69, 69, 69, 69, + 119, 120, 121, 69, 122, 123, 124, 69, + 69, 69, 69, 69, 126, 127, 128, 132, + 69, 69, 69, 69, 110, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 110, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 119, 120, 121, 69, 122, 123, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 69, 69, 69, 110, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 110, 111, 112, 113, 69, 69, 69, 69, + 69, 69, 69, 120, 121, 69, 122, 123, + 124, 69, 69, 69, 69, 69, 126, 127, + 128, 132, 69, 69, 69, 69, 110, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 110, 111, 112, 113, 69, 69, 69, + 69, 69, 69, 69, 69, 121, 69, 122, + 123, 124, 69, 69, 69, 69, 69, 126, + 127, 128, 132, 69, 69, 69, 69, 110, + 69, 134, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 109, 110, 111, 112, 113, + 69, 115, 116, 69, 69, 69, 119, 120, + 121, 69, 122, 123, 124, 69, 69, 69, + 69, 69, 126, 127, 128, 132, 69, 69, + 69, 69, 110, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 110, 111, 112, + 113, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 122, 123, 124, 69, 69, + 69, 69, 69, 126, 127, 128, 132, 69, + 69, 69, 69, 110, 69, 134, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 109, + 110, 111, 112, 113, 69, 69, 116, 69, + 69, 69, 119, 120, 121, 69, 122, 123, + 124, 69, 69, 69, 69, 69, 126, 127, + 128, 132, 69, 69, 69, 69, 110, 69, + 134, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 109, 110, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 119, 120, 121, + 69, 122, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 69, 69, + 69, 110, 69, 134, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 109, 110, 111, + 112, 113, 114, 115, 116, 69, 69, 69, + 119, 120, 121, 69, 122, 123, 124, 69, + 69, 69, 69, 69, 126, 127, 128, 132, + 69, 69, 69, 69, 110, 69, 107, 108, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 69, 118, 119, 120, 121, 69, + 122, 123, 124, 69, 69, 69, 69, 125, + 126, 127, 128, 129, 69, 69, 69, 69, + 130, 69, 69, 131, 69, 107, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 101, 100, 107, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 98, 96, 107, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 110, 111, 112, 113, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 122, + 123, 124, 69, 69, 69, 69, 69, 126, + 127, 128, 132, 69, 101, 100, 8, 9, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 8, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 135, 135, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 8, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 14, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 26, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 135, 135, + 135, 14, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 135, 14, 15, 16, 17, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 26, 27, 28, 135, 135, 135, + 135, 135, 33, 34, 38, 136, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 15, 16, 17, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 33, 34, + 38, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 33, 34, 38, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 17, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 33, 34, 38, 135, + 11, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 33, + 34, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 34, 135, 11, 137, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 26, 27, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 138, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 11, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 15, 16, 17, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 33, 34, 38, 136, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 13, 14, 15, + 16, 17, 135, 135, 135, 135, 135, 135, + 23, 24, 25, 135, 26, 27, 28, 135, + 135, 135, 135, 135, 33, 34, 38, 136, + 135, 135, 135, 135, 14, 135, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 14, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 23, 24, 25, 135, 26, 27, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 135, 135, 135, 14, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 135, + 14, 15, 16, 17, 135, 135, 135, 135, + 135, 135, 135, 24, 25, 135, 26, 27, + 28, 135, 135, 135, 135, 135, 33, 34, + 38, 136, 135, 135, 135, 135, 14, 135, + 11, 135, 135, 135, 135, 135, 135, 135, + 135, 14, 15, 16, 17, 135, 135, 135, + 135, 135, 135, 135, 135, 25, 135, 26, + 27, 28, 135, 135, 135, 135, 135, 33, + 34, 38, 136, 135, 135, 135, 135, 14, + 135, 139, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 13, 14, 15, 16, 17, + 135, 19, 20, 135, 135, 135, 23, 24, + 25, 135, 26, 27, 28, 135, 135, 135, + 135, 135, 33, 34, 38, 136, 135, 135, + 135, 135, 14, 135, 11, 135, 135, 135, + 135, 135, 135, 135, 135, 14, 15, 16, + 17, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 26, 27, 28, 135, 135, + 135, 135, 135, 33, 34, 38, 136, 135, + 135, 135, 135, 14, 135, 139, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 13, + 14, 15, 16, 17, 135, 135, 20, 135, + 135, 135, 23, 24, 25, 135, 26, 27, + 28, 135, 135, 135, 135, 135, 33, 34, + 38, 136, 135, 135, 135, 135, 14, 135, + 139, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 13, 14, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 23, 24, 25, + 135, 26, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 135, 135, + 135, 14, 135, 139, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 13, 14, 15, + 16, 17, 18, 19, 20, 135, 135, 135, + 23, 24, 25, 135, 26, 27, 28, 135, + 135, 135, 135, 135, 33, 34, 38, 136, + 135, 135, 135, 135, 14, 135, 8, 9, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 135, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 135, 135, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 8, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 11, 135, 8, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 135, 14, 15, 16, 17, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 26, 27, 28, 135, 135, 135, 135, 135, + 33, 34, 38, 136, 135, 140, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 11, + 135, 10, 11, 135, 4, 135, 135, 135, + 4, 135, 135, 135, 135, 135, 8, 9, + 10, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 8, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 29, 30, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 29, 30, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 30, + 135, 4, 141, 141, 141, 4, 141, 143, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 144, 142, 145, 142, 145, + 146, 142, 143, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 1, 144, 144, + 142, 143, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 144, 142, 145, + 142, 143, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 144, 142, 145, + 142, 145, 142, 40, 41, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 40, + 52, 53, 54, 55, 39, 56, 57, 58, + 39, 59, 60, 39, 61, 62, 63, 64, + 61, 1, 39, 2, 39, 65, 39, 39, + 64, 39, 0 }; static const char _use_syllable_machine_trans_targs[] = { - 1, 120, 0, 2, 31, 1, 58, 60, - 88, 89, 114, 1, 116, 102, 90, 91, - 92, 93, 106, 108, 109, 110, 111, 103, - 104, 105, 97, 98, 99, 117, 118, 119, - 112, 94, 95, 96, 124, 113, 1, 3, - 4, 1, 17, 5, 6, 7, 8, 21, - 23, 24, 25, 26, 18, 19, 20, 12, - 13, 14, 29, 30, 27, 9, 10, 11, - 28, 15, 16, 22, 1, 32, 1, 45, - 33, 34, 35, 36, 49, 51, 52, 53, - 54, 46, 47, 48, 40, 41, 42, 55, - 37, 38, 39, 56, 57, 43, 1, 44, - 1, 50, 1, 1, 1, 59, 1, 1, - 1, 61, 62, 75, 63, 64, 65, 66, - 79, 81, 82, 83, 84, 76, 77, 78, - 70, 71, 72, 85, 67, 68, 69, 86, - 87, 73, 74, 80, 1, 100, 101, 107, - 115, 1, 1, 1, 121, 122, 123 + 1, 122, 0, 2, 31, 1, 59, 61, + 90, 91, 116, 1, 118, 104, 92, 93, + 94, 95, 108, 110, 111, 112, 113, 105, + 106, 107, 99, 100, 101, 119, 120, 121, + 114, 96, 97, 98, 126, 115, 98, 1, + 3, 4, 1, 17, 5, 6, 7, 8, + 21, 23, 24, 25, 26, 18, 19, 20, + 12, 13, 14, 29, 30, 27, 9, 10, + 11, 28, 15, 16, 22, 1, 32, 1, + 45, 33, 34, 35, 36, 49, 51, 52, + 53, 54, 46, 47, 48, 40, 41, 42, + 55, 37, 38, 39, 56, 57, 58, 43, + 1, 44, 1, 50, 1, 1, 1, 60, + 1, 1, 1, 62, 63, 76, 64, 65, + 66, 67, 80, 82, 83, 84, 85, 77, + 78, 79, 71, 72, 73, 86, 68, 69, + 70, 87, 88, 89, 74, 75, 81, 1, + 102, 1, 103, 109, 117, 1, 1, 1, + 123, 124, 125 }; static const char _use_syllable_machine_trans_actions[] = { @@ -737,20 +745,21 @@ static const char _use_syllable_machine_trans_actions[] = { 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 0, 7, 0, - 0, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 7, 0, 8, 9, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 10, 0, + 0, 0, 0, 0, 0, 11, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 11, 0, - 12, 0, 13, 14, 15, 0, 16, 17, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 14, 0, 15, 16, 17, 0, + 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 0, 0, - 0, 20, 21, 22, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, + 0, 22, 0, 0, 0, 23, 24, 25, + 0, 0, 0 }; static const char _use_syllable_machine_to_state_actions[] = { @@ -769,7 +778,7 @@ static const char _use_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }; static const char _use_syllable_machine_from_state_actions[] = { @@ -788,26 +797,26 @@ static const char _use_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }; static const short _use_syllable_machine_eof_trans[] = { - 1, 0, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 95, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 99, - 95, 69, 101, 104, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 95, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 99, 95, 69, - 133, 133, 133, 133, 133, 133, 133, 133, - 133, 133, 133, 133, 133, 133, 133, 133, - 133, 133, 133, 133, 133, 133, 133, 133, - 133, 133, 133, 133, 133, 133, 133, 138, - 139, 139, 139, 139, 39 + 1, 0, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 97, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 101, + 97, 70, 101, 103, 106, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 97, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 101, 97, + 70, 101, 136, 136, 136, 136, 136, 136, + 136, 136, 138, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 142, 143, 143, 143, 143, 40 }; static const int use_syllable_machine_start = 1; @@ -821,7 +830,7 @@ static const int use_syllable_machine_en_main = 1; -#line 184 "hb-ot-shaper-use-machine.rl" +#line 186 "hb-ot-shaper-use-machine.rl" #define found_syllable(syllable_type) \ @@ -920,7 +929,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 924 "hb-ot-shaper-use-machine.hh" +#line 933 "hb-ot-shaper-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -928,12 +937,12 @@ find_syllables_use (hb_buffer_t *buffer) act = 0; } -#line 284 "hb-ot-shaper-use-machine.rl" +#line 286 "hb-ot-shaper-use-machine.rl" unsigned int syllable_serial = 1; -#line 937 "hb-ot-shaper-use-machine.hh" +#line 946 "hb-ot-shaper-use-machine.hh" { int _slen; int _trans; @@ -947,7 +956,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 951 "hb-ot-shaper-use-machine.hh" +#line 960 "hb-ot-shaper-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -965,87 +974,111 @@ _eof_trans: goto _again; switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 6: + case 7: #line 1 "NONE" {te = p+1;} break; - case 14: -#line 172 "hb-ot-shaper-use-machine.rl" + case 16: +#line 173 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_virama_terminated_cluster); }} break; - case 12: -#line 173 "hb-ot-shaper-use-machine.rl" + case 14: +#line 174 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }} break; - case 10: -#line 174 "hb-ot-shaper-use-machine.rl" + case 12: +#line 175 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_standard_cluster); }} break; - case 18: -#line 175 "hb-ot-shaper-use-machine.rl" + case 20: +#line 176 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }} break; - case 16: -#line 176 "hb-ot-shaper-use-machine.rl" + case 18: +#line 177 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_numeral_cluster); }} break; - case 8: -#line 177 "hb-ot-shaper-use-machine.rl" + case 10: +#line 178 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_symbol_cluster); }} break; - case 22: -#line 178 "hb-ot-shaper-use-machine.rl" + case 25: +#line 179 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_hieroglyph_cluster); }} break; case 5: -#line 179 "hb-ot-shaper-use-machine.rl" +#line 181 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 4: -#line 180 "hb-ot-shaper-use-machine.rl" +#line 182 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_non_cluster); }} break; - case 13: -#line 172 "hb-ot-shaper-use-machine.rl" + case 15: +#line 173 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }} break; - case 11: -#line 173 "hb-ot-shaper-use-machine.rl" + case 13: +#line 174 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} break; - case 9: -#line 174 "hb-ot-shaper-use-machine.rl" + case 11: +#line 175 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_standard_cluster); }} break; - case 17: -#line 175 "hb-ot-shaper-use-machine.rl" + case 19: +#line 176 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} break; - case 15: -#line 176 "hb-ot-shaper-use-machine.rl" + case 17: +#line 177 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_numeral_cluster); }} break; - case 7: -#line 177 "hb-ot-shaper-use-machine.rl" + case 9: +#line 178 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_symbol_cluster); }} break; - case 21: -#line 178 "hb-ot-shaper-use-machine.rl" + case 24: +#line 179 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} break; - case 19: -#line 179 "hb-ot-shaper-use-machine.rl" + case 21: +#line 181 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; - case 20: -#line 180 "hb-ot-shaper-use-machine.rl" + case 23: +#line 182 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_non_cluster); }} break; case 1: -#line 177 "hb-ot-shaper-use-machine.rl" +#line 178 "hb-ot-shaper-use-machine.rl" {{p = ((te))-1;}{ found_syllable (use_symbol_cluster); }} break; -#line 1049 "hb-ot-shaper-use-machine.hh" + case 22: +#line 1 "NONE" + { switch( act ) { + case 8: + {{p = ((te))-1;} found_syllable (use_non_cluster); } + break; + case 9: + {{p = ((te))-1;} found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + } + } + break; + case 6: +#line 1 "NONE" + {te = p+1;} +#line 180 "hb-ot-shaper-use-machine.rl" + {act = 8;} + break; + case 8: +#line 1 "NONE" + {te = p+1;} +#line 181 "hb-ot-shaper-use-machine.rl" + {act = 9;} + break; +#line 1082 "hb-ot-shaper-use-machine.hh" } _again: @@ -1054,7 +1087,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1058 "hb-ot-shaper-use-machine.hh" +#line 1091 "hb-ot-shaper-use-machine.hh" } if ( ++p != pe ) @@ -1070,7 +1103,7 @@ _again: } -#line 289 "hb-ot-shaper-use-machine.rl" +#line 291 "hb-ot-shaper-use-machine.rl" } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh index 491b2f940e1..d3c49949aa8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh @@ -6,18 +6,18 @@ * * on files with these headers: * - * # IndicSyllabicCategory-15.1.0.txt - * # Date: 2023-01-05 - * # IndicPositionalCategory-15.1.0.txt - * # Date: 2023-01-05 - * # ArabicShaping-15.1.0.txt - * # Date: 2023-01-05 - * # DerivedCoreProperties-15.1.0.txt - * # Date: 2023-08-07, 15:21:24 GMT - * # Blocks-15.1.0.txt - * # Date: 2023-07-28, 15:47:20 GMT - * # Scripts-15.1.0.txt - * # Date: 2023-07-28, 16:01:07 GMT + * # IndicSyllabicCategory-16.0.0.txt + * # Date: 2024-04-30, 21:48:21 GMT + * # IndicPositionalCategory-16.0.0.txt + * # Date: 2024-04-30, 21:48:21 GMT + * # ArabicShaping-16.0.0.txt + * # Date: 2024-07-30 + * # DerivedCoreProperties-16.0.0.txt + * # Date: 2024-05-31, 18:09:32 GMT + * # Blocks-16.0.0.txt + * # Date: 2024-02-02 + * # Scripts-16.0.0.txt + * # Date: 2024-04-30, 21:48:40 GMT * # Override values For Indic_Syllabic_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -27,6 +27,7 @@ * # Updated for Unicode 14.0 by Andrew Glass 2021-09-25 * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16 * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14 + * # Updated for Unicode 16.0 by Andrew Glass 2024-09-11 * # Override values For Indic_Positional_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -38,6 +39,7 @@ * # Updated for Unicode 14.0 by Andrew Glass 2021-09-28 * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16 * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14 + * # Updated for Unicode 16.0 by Andrew Glass 2024-09-11 * UnicodeData.txt does not have a header. */ @@ -65,6 +67,7 @@ #define N USE(N) /* BASE_NUM */ #define O USE(O) /* OTHER */ #define R USE(R) /* REPHA */ +#define RK USE(RK) /* REORDERING_KILLER */ #define SB USE(SB) /* HIEROGLYPH_SEGMENT_BEGIN */ #define SE USE(SE) /* HIEROGLYPH_SEGMENT_END */ #define SUB USE(SUB) /* CONS_SUB */ @@ -99,16 +102,16 @@ #ifndef HB_OPTIMIZE_SIZE static const uint8_t -hb_use_u8[3187] = +hb_use_u8[3345] = { - 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61, + 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, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 14, 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2, + 15, 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2, 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 2, 2, 17, 18, 19, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 33, 2, 2, 2, @@ -121,24 +124,26 @@ hb_use_u8[3187] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 48, 2, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2, - 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 2, 2, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 2, 66, 67, 2, 68, 69, 70, 71, - 2, 72, 2, 73, 74, 75, 76, 2, 2, 77, 78, 79, 80, 2, 81, 82, - 2, 83, 83, 83, 83, 83, 83, 83, 83, 84, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 56, 2, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 2, 70, 71, 72, 73, + 2, 74, 2, 75, 76, 77, 78, 2, 2, 79, 80, 81, 82, 2, 83, 84, + 2, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 87, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 89, 90, 2, 2, 2, 91, 2, 2, 2, 92, + 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 94, 94, 94, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 85, 86, 2, 2, 2, 2, 2, 2, 2, 87, - 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 89, 89, 89, 90, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2, + 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, 92, 2, 2, 2, 2, 2, - 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 94, 2, 2, 95, 2, 2, 2, 96, 2, 2, 2, 2, 2, - 2, 2, 2, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 98, 98, 99, 100, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 2, 2, 99, 2, 2, 100, 2, 2, 2, 101, 2, 102, 2, 2, 2, + 2, 2, 2, 103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 104, 104, 105, 106, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -167,7 +172,7 @@ hb_use_u8[3187] = 0, 0, 0, 27, 31, 2, 9, 0, 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, - 2, 2, 2, 2, 2, 2, 52, 53, 23, 23, 19, 31, 48, 33, 48, 34, + 2, 2, 2, 2, 2, 2, 52, 53, 23, 19, 20, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, @@ -195,9 +200,9 @@ hb_use_u8[3187] = 0, 2, 2, 100, 101, 102, 103, 61, 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, - 0, 0, 0, 0, 0, 0, 109, 110, 111, 111, 111, 0, 0, 0, 0, 0, - 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 112, 61, - 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 109, 110, 110, 110, 110, 0, 0, 0, 0, 0, + 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 111, 61, + 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 112, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, @@ -226,6 +231,7 @@ hb_use_u8[3187] = 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, + 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, @@ -244,39 +250,45 @@ hb_use_u8[3187] = 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, - 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 0, 163, 164, 0, 0, 0, 0, 0, 0, - 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 165, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, - 166, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, - 0, 23, 19, 20, 20, 21, 16, 82, 166, 38, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 10, 167, 25, 20, 22, 22, 165, 9, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, - 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, - 19, 20, 21, 22, 105, 166, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, - 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 168, - 169, 170, 171, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, - 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, - 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 172, 173, 11, 15, 174, 72, - 175, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, - 2, 2, 2, 158, 158, 158, 176, 176, 176, 176, 176, 176, 15, 177, 0, 30, - 0, 22, 20, 20, 31, 22, 22, 11, 166, 0, 61, 61, 61, 61, 61, 61, - 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, - 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 178, 174, 0, 0, 0, - 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, - 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 179, 66, 47, 0, 0, 0, - 0, 11, 180, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, - 48, 16, 143, 0, 0, 0, 0, 0, 0, 181, 181, 181, 181, 181, 181, 181, - 181, 182, 182, 182, 183, 184, 182, 181, 181, 185, 181, 181, 186, 187, 187, 187, - 187, 187, 187, 187, 0, 0, 0, 0, 0, 11, 11, 11, 46, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 0, 58, 188, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, - 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 58, - 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, - 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, - 22, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, + 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20, + 20, 31, 33, 32, 32, 25, 163, 29, 164, 165, 37, 0, 0, 0, 0, 0, + 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, + 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, + 166, 167, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, + 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 65, 25, 20, 20, 0, 48, 48, 11, 169, 37, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, + 169, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 170, + 25, 20, 22, 22, 168, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, + 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 169, 37, 0, + 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, + 2, 23, 23, 18, 32, 33, 12, 171, 165, 172, 173, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, + 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, + 2, 2, 174, 175, 11, 15, 176, 61, 177, 0, 0, 1, 147, 0, 0, 0, + 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 178, 178, + 178, 178, 178, 178, 15, 179, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, + 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, + 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, + 27, 11, 159, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, + 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 156, 0, 0, 184, 184, 184, 184, 184, 184, 184, + 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190, + 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 192, 193, + 194, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, + 58, 195, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, + 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, + 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, + 20, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv, VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, @@ -290,20 +302,21 @@ hb_use_u8[3187] = FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, - VPst, H, B, O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv, + VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv, CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B, CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, - IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, - B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst, - CMBlw, B,FMBlw, VBlw,VMAbv, R, MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, - VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, - HM, O, VBlw, + IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, + O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, + VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, + IS, VBlw, IS, R, MBlw, GB, VAbv, R,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[808] = +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, @@ -332,28 +345,31 @@ hb_use_u16[808] = 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0,166,166,167, 34,168, 0, 0, 0, 0, 169,170, 10,171, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,172, 0, - 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 0, 0, 0, 0, - 10, 10,176,173, 0, 0, 0, 0, 0, 0, 0, 10,177,178, 0, 10, - 179, 0, 0,180,181, 0, 0, 0,182, 10, 10,183,184,185,186,187, - 188, 10, 10,189,190, 0, 0, 0,191, 10,192,193,194, 10, 10,195, - 188, 10, 10,196,197,106,198,103, 10, 34,199,200,201, 0, 0, 0, - 202,203, 95, 10, 10,204,205, 2,206, 21, 22,207,208,209,210,211, - 10, 10, 10,212,213,214,215, 0,198, 10, 10,216,217, 2, 0, 0, - 10, 10,218,219,220,221, 0, 0, 10, 10, 10,222,223, 2, 0, 0, - 10, 10,224,225, 2, 0, 0, 0, 10,226,227,104,228, 0, 0, 0, - 10, 10,229,230, 0, 0, 0, 0,231,232, 10,233,234, 2, 0, 0, - 0, 0,235, 10, 10,236,237, 0,238, 10, 10,239,240,241, 10, 10, - 242,243, 0, 0, 0, 0, 0, 0, 22, 10,218,244, 8, 10, 71, 19, - 10,245, 74,246, 0, 0, 0, 0,247, 10, 10,248,249, 2,250, 10, - 251,252, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,253, - 254, 49, 10,255,256, 2, 0, 0,257,257,257,257,257,257,257,257, - 257,257,257,258,259,260, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 10, 10, 10,261, 0, 0, 0, 0, 10, 10, 10, 10,262,263,264,264, - 265,266, 0, 0, 0, 0,267, 0, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10,268, 0, 0, 10, 10, 10, 10, 10, 10,106, 71, - 95,269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,270, - 10, 10, 71,271,272, 0, 0, 0, 0, 10,273, 0, 10, 10,274, 2, - 0, 0, 0, 0, 0, 10,275, 2, 10, 10, 10, 10,276, 2, 0, 0, + 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 9, 10,176, 10, + 177, 0, 0, 0, 0, 0, 0, 0, 10, 10,178,173, 0, 0, 0, 0, + 0, 0, 0, 10,179,180, 0, 10,181, 0, 0,182,183, 0, 0, 0, + 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0, 0, 0, + 193, 10,194,195,196, 10, 10,197,190, 10, 10,198,199,106,200,103, + 10, 34,201,202,203, 0, 0, 0,204,205, 95, 10, 10,206,207, 2, + 208, 21, 22,209,210,211,212,213,214, 10, 10,215,216,217,218, 0, + 10, 10, 10,219,220,221,222, 0,200, 10, 10,223,224, 2, 0, 0, + 10, 10,225,226,227,228, 0, 0, 10, 10, 10,229,230, 2, 0, 0, + 10, 10,231,232, 2, 10,141, 0, 10,233,234,104,235, 0, 0, 0, + 10, 10,236,237, 0, 0, 0, 0,238,239, 10,240,241, 2, 0, 0, + 0, 0,242, 10, 10,243,244, 0,245, 10, 10,246,247,248, 10, 10, + 249,250, 0, 0, 0, 0, 0, 0, 22, 10,225,251, 8, 10, 71, 19, + 10,252, 74,253, 0, 0, 0, 0,254, 10, 10,255,256, 2,257, 10, + 258,259, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,260, + 261, 49, 10,262,263,264, 0, 0,265,265,265,265,265,265,265,265, + 265,265,265,266,267,268,265,265,265,265,265,265,265,265,265,269, + 10,270,271, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 10, 10, 10,272, 0, 0, 0, 0, 0, 0, 0, 0,273, 10,274, 2, + 10, 10, 10, 10,275,276,277,277,278,279, 0, 0, 0, 0,280, 0, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,177, 0,281, + 10, 10, 10, 10, 10, 10,106, 71, 95,282, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,283, 10, 10, 71,284,285, 0, 0, 0, + 0, 10,286, 0, 10, 10,287, 2, 0, 0, 0, 0, 0, 10,288, 2, + 0, 0, 0, 0, 0, 10,289,106, 10, 10, 10, 10,290, 2, 0, 0, 130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,130, }; @@ -366,23 +382,23 @@ hb_use_b4 (const uint8_t* a, unsigned i) static inline uint_fast8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[2809+(((hb_use_u8[593+(((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<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; } #else static const uint8_t -hb_use_u8[3483] = +hb_use_u8[3657] = { - 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61, + 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, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 14, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 1, + 15, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 1, 11, 12, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 19, 1, 1, 20, 1, 1, 1, 1, 21, 1, 22, 1, 1, 1, 1, 1, 23, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -390,14 +406,15 @@ hb_use_u8[3483] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 32, 33, 1, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1, 48, 49, 50, - 51, 52, 52, 52, 52, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 54, 55, 1, 1, 1, - 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 57, 58, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 59, 1, 1, - 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 61, 62, 1, 63, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, - 1, 65, 66, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 51, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 56, 57, 1, 58, 1, + 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 60, 61, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 1, + 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 64, 65, 1, 66, 67, 1, 1, 1, 68, 1, 1, 1, 1, 1, + 1, 69, 70, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 9, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, @@ -414,23 +431,25 @@ hb_use_u8[3483] = 122, 0, 0, 0, 0, 0, 0, 56, 123, 124, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 127, 128, 129, 0, 0, 130, 131, 132, 0, 0, 0, 51, 133, 0, 0, 0, 0, 134, 135, 0, - 0, 56, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 137, 0, - 0, 0, 101, 138, 101, 139, 140, 141, 0, 142, 143, 144, 145, 146, 147, 148, - 0, 149, 150, 151, 152, 146, 153, 154, 155, 156, 157, 158, 0, 159, 160, 161, - 162, 163, 164, 165, 166, 0, 0, 0, 0, 56, 167, 168, 169, 170, 171, 172, - 0, 0, 0, 0, 0, 56, 173, 174, 0, 56, 175, 176, 0, 56, 177, 67, - 0, 178, 179, 180, 0, 0, 0, 0, 0, 56, 181, 0, 0, 0, 0, 0, - 0, 182, 183, 184, 0, 0, 185, 186, 187, 188, 189, 190, 56, 191, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 0, 0, 198, 199, 200, 201, 202, 67, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 0, - 0, 207, 207, 207, 207, 207, 207, 207, 207, 207, 208, 209, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 210, 0, 0, 0, 0, 0, - 0, 56, 56, 211, 212, 213, 0, 0, 214, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 215, 0, 56, 56, 56, 216, 217, 0, 0, - 0, 0, 0, 0, 218, 0, 0, 0, 0, 56, 219, 220, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 101, 221, 56, 222, 0, 0, 0, 0, 0, 0, 101, - 223, 56, 56, 224, 0, 0, 0, 0, 0, 225, 225, 225, 225, 225, 225, 225, - 225, 226, 226, 226, 226, 226, 226, 226, 227, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 136, 7, 137, 138, 0, 0, 0, 0, 0, 0, 0, 56, 139, 0, + 0, 0, 101, 140, 101, 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, 150, + 0, 151, 152, 153, 154, 148, 155, 156, 157, 158, 159, 160, 0, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 56, 173, 174, 175, 176, 177, 178, + 0, 0, 0, 0, 0, 56, 179, 180, 0, 56, 181, 182, 0, 56, 183, 184, + 185, 186, 187, 188, 0, 0, 0, 0, 0, 56, 189, 0, 0, 0, 0, 0, + 0, 190, 191, 192, 0, 0, 193, 194, 195, 196, 197, 198, 56, 199, 0, 0, + 0, 200, 201, 202, 203, 204, 205, 0, 0, 206, 207, 208, 209, 210, 67, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 211, 212, 213, 214, 0, 0, 0, 0, + 0, 215, 215, 215, 215, 215, 215, 215, 215, 215, 216, 217, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, 218, 219, 220, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 221, 0, 0, 0, 0, 0, + 0, 0, 0, 222, 223, 0, 0, 0, 0, 56, 56, 224, 225, 226, 0, 0, + 227, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 228, + 229, 56, 56, 56, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, + 0, 56, 233, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 235, 56, + 236, 0, 0, 0, 0, 0, 0, 101, 237, 0, 0, 0, 0, 0, 0, 101, + 238, 56, 56, 239, 0, 0, 0, 0, 0, 240, 240, 240, 240, 240, 240, 240, + 240, 241, 241, 241, 241, 241, 241, 241, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, @@ -460,7 +479,7 @@ hb_use_u8[3483] = 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 52, 53, - 23, 23, 19, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, + 23, 19, 20, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, 25, 0, 23, 0, 0, 0, 0, 0, @@ -488,9 +507,9 @@ hb_use_u8[3483] = 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 109, 110, - 111, 111, 111, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, - 2, 60, 61, 59, 25, 22, 112, 61, 2, 2, 2, 2, 107, 22, 23, 45, - 45, 102, 14, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, + 110, 110, 110, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, + 2, 60, 61, 59, 25, 22, 111, 61, 2, 2, 2, 2, 107, 22, 23, 45, + 45, 102, 112, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 118, 0, @@ -518,7 +537,8 @@ hb_use_u8[3483] = 0, 128, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, - 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, + 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, + 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, @@ -536,39 +556,45 @@ hb_use_u8[3483] = 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, - 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, - 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, - 163, 164, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, - 160, 11, 165, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 65, 25, 20, 20, 0, 48, 48, 11, 166, 37, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, - 166, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 167, - 25, 20, 22, 22, 165, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, - 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 166, 37, 0, - 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, - 2, 23, 23, 18, 32, 33, 12, 168, 169, 170, 171, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, - 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, - 2, 2, 172, 173, 11, 15, 174, 72, 175, 0, 0, 1, 147, 0, 0, 0, - 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 176, 176, - 176, 176, 176, 176, 15, 177, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, - 166, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, - 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, - 27, 11, 159, 178, 174, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, - 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, - 0, 2, 179, 66, 47, 0, 0, 0, 0, 11, 180, 2, 2, 2, 2, 2, - 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, - 0, 181, 181, 181, 181, 181, 181, 181, 181, 182, 182, 182, 183, 184, 182, 181, - 181, 185, 181, 181, 186, 187, 187, 187, 187, 187, 187, 187, 0, 0, 0, 0, - 0, 11, 11, 11, 46, 0, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, - 58, 188, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, - 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, - 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 44, 44, 44, 92, 0, + 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, + 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, + 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, + 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 168, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, + 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, + 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, + 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, + 19, 20, 21, 22, 105, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, + 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, + 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 174, 175, 11, 15, 176, 61, + 177, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, + 2, 2, 2, 158, 158, 158, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, + 0, 22, 20, 20, 31, 22, 22, 11, 169, 0, 61, 61, 61, 61, 61, 61, + 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, + 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 180, 181, 0, 0, 0, + 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, + 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 182, 66, 47, 0, 0, 0, + 0, 11, 183, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, + 48, 16, 143, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 156, 0, + 0, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 186, 187, 185, 184, + 184, 188, 184, 184, 189, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, + 0, 184, 184, 184, 184, 184, 191, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 22, 22, 22, 22, 22, 22, 192, 193, 194, 11, 11, 11, 46, 0, 0, 0, + 0, 29, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 47, + 0, 2, 2, 2, 2, 2, 9, 0, 58, 195, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, + 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 2, 2, 2, 0, 58, + 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, + 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, + 22, 2, 2, 2, 2, 2, 2, 2, 20, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst, FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv, VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, @@ -582,20 +608,21 @@ hb_use_u8[3483] = VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS, FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, - SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMBlw,SMAbv,SMAbv, - SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, + SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, + IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv, VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, - VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, - VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R, MBlw, MBlw, - GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, G, G, J, J, J, - SB, SE, J, HR, G, G, HM, HM, HM, O, VBlw, + VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, + CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw, + VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R, + 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[456] = +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, @@ -614,18 +641,20 @@ hb_use_u16[456] = 148,149,150, 10, 10,151,152, 2,153, 99,154,155,156, 2, 10,157, 10,158,159, 0,160,161,162, 2,163, 0, 0,164, 0,165, 0,166, 166,167, 34,168,169,170, 10,171, 95, 0,172, 0, 10,173,174, 0, - 175, 2,176,173,177,178,179, 0, 0,180,181, 0,182, 10, 10,183, - 184,185,186,187,188, 10, 10,189,190, 0,191, 10,192,193,194, 10, - 10,195, 10,196,197,106,198,103, 10, 34,199,200,201, 0,202,203, - 95, 10, 10,204,205, 2,206, 21, 22,207,208,209,210,211, 10,212, - 213,214,215, 0,198, 10, 10,216,217, 2,218,219,220,221, 10,222, - 223, 2,224,225, 10,226,227,104,228, 0,229,230,231,232, 10,233, - 234, 2,235, 10, 10,236,237, 0,238, 10, 10,239,240,241,242,243, - 22, 10,218,244, 8, 10, 71, 19, 10,245, 74,246,247, 10, 10,248, - 249, 2,250, 10,251,252, 10,253,254, 49, 10,255,256, 2,257,257, - 257,258,259,260, 10,261,262,263,264,264,265,266,267, 0, 10,268, - 106, 71, 95,269, 0,270, 71,271,272, 0,273, 0,274, 2,275, 2, - 276, 2,130,130,163,163,163,130, + 175, 2,176, 10,177, 0,178,173,179,180,181, 0, 0,182,183, 0, + 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0,193, 10, + 194,195,196, 10, 10,197, 10,198,199,106,200,103, 10, 34,201,202, + 203, 0,204,205, 95, 10, 10,206,207, 2,208, 21, 22,209,210,211, + 212,213,214, 10, 10,215,216,217,218, 0, 10,219,220,221,222, 0, + 200, 10, 10,223,224, 2,225,226,227,228, 10,229,230, 2,231,232, + 2, 10,141, 0, 10,233,234,104,235, 0,236,237,238,239, 10,240, + 241, 2,242, 10, 10,243,244, 0,245, 10, 10,246,247,248,249,250, + 22, 10,225,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, 10,255, + 256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264,265,265, + 265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10,274, 2, + 275,276,277,277,278,279,280, 0, 10,177, 0,281,106, 71, 95,282, + 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,106,290, 2, + 130,130,163,163,163,130, }; static inline unsigned @@ -636,7 +665,7 @@ hb_use_b4 (const uint8_t* a, unsigned i) static inline uint_fast8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[3105+(((hb_use_u8[889+(((hb_use_u16[((hb_use_u8[353+(((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<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; } #endif @@ -656,6 +685,7 @@ hb_use_get_category (unsigned u) #undef N #undef O #undef R +#undef RK #undef SB #undef SE #undef SUB diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc index 35693254ec0..4a112e1c289 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc @@ -10,8 +10,8 @@ * # Date: 2015-03-12, 21:17:00 GMT [AG] * # Date: 2019-11-08, 23:22:00 GMT [AG] * - * # Scripts-15.1.0.txt - * # Date: 2023-07-28, 16:01:07 GMT + * # Scripts-16.0.0.txt + * # Date: 2024-04-30, 21:48:40 GMT */ #include "hb.hh" @@ -24,7 +24,7 @@ static void _output_dotted_circle (hb_buffer_t *buffer) { (void) buffer->output_glyph (0x25CCu); - _hb_glyph_info_reset_continuation (&buffer->prev()); + _hb_glyph_info_clear_continuation (&buffer->prev()); } static void diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh index 39a04ec2348..48cd5296ffd 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper.hh @@ -174,9 +174,11 @@ HB_OT_SHAPERS_IMPLEMENT_SHAPERS static inline const hb_ot_shaper_t * -hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) +hb_ot_shaper_categorize (hb_script_t script, + hb_direction_t direction, + hb_tag_t gsub_script) { - switch ((hb_tag_t) planner->props.script) + switch ((hb_tag_t) script) { default: return &_hb_ot_shaper_default; @@ -192,9 +194,8 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) * This is because we do fallback shaping for Arabic script (and not others). * But note that Arabic shaping is applicable only to horizontal layout; for * vertical text, just use the generic shaper instead. */ - if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || - planner->props.script == HB_SCRIPT_ARABIC) && - HB_DIRECTION_IS_HORIZONTAL(planner->props.direction)) + if ((gsub_script != HB_OT_TAG_DEFAULT_SCRIPT || script == HB_SCRIPT_ARABIC) && + HB_DIRECTION_IS_HORIZONTAL (direction)) return &_hb_ot_shaper_arabic; else return &_hb_ot_shaper_default; @@ -235,10 +236,10 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) * Otherwise, use the specific shaper. * * If it's indy3 tag, send to USE. */ - if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || - planner->map.chosen_script[0] == HB_TAG ('l','a','t','n')) + if (gsub_script == HB_TAG ('D','F','L','T') || + gsub_script == HB_TAG ('l','a','t','n')) return &_hb_ot_shaper_default; - else if ((planner->map.chosen_script[0] & 0x000000FF) == '3') + else if ((gsub_script & 0x000000FF) == '3') return &_hb_ot_shaper_use; else return &_hb_ot_shaper_indic; @@ -254,9 +255,9 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) * If designer designed for 'mymr' tag, also send to default * shaper. That's tag used from before Myanmar shaping spec * was developed. The shaping spec uses 'mym2' tag. */ - if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || - planner->map.chosen_script[0] == HB_TAG ('l','a','t','n') || - planner->map.chosen_script[0] == HB_TAG ('m','y','m','r')) + if (gsub_script == HB_TAG ('D','F','L','T') || + gsub_script == HB_TAG ('l','a','t','n') || + gsub_script == HB_TAG ('m','y','m','r')) return &_hb_ot_shaper_default; else return &_hb_ot_shaper_myanmar; @@ -386,13 +387,22 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_KAWI: case HB_SCRIPT_NAG_MUNDARI: + /* Unicode-16.0 additions */ + case HB_SCRIPT_GARAY: + case HB_SCRIPT_GURUNG_KHEMA: + case HB_SCRIPT_KIRAT_RAI: + case HB_SCRIPT_OL_ONAL: + case HB_SCRIPT_SUNUWAR: + case HB_SCRIPT_TODHRI: + case HB_SCRIPT_TULU_TIGALARI: + /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. * Otherwise, use the specific shaper. * Note that for some simple scripts, there may not be *any* * GSUB/GPOS needed, so there may be no scripts found! */ - if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || - planner->map.chosen_script[0] == HB_TAG ('l','a','t','n')) + if (gsub_script == HB_TAG ('D','F','L','T') || + gsub_script == HB_TAG ('l','a','t','n')) return &_hb_ot_shaper_default; else return &_hb_ot_shaper_use; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh index 7f6b52d7977..10165f57b75 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh @@ -63,8 +63,9 @@ static bool axis_value_is_outside_axis_range (hb_tag_t axis_tag, float axis_valu if (!user_axes_location->has (axis_tag)) return false; + double axis_value_double = static_cast(axis_value); Triple axis_range = user_axes_location->get (axis_tag); - return (axis_value < axis_range.minimum || axis_value > axis_range.maximum); + return (axis_value_double < axis_range.minimum || axis_value_double > axis_range.maximum); } struct StatAxisRecord @@ -327,6 +328,7 @@ struct AxisValueFormat4 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && axisValues.sanitize (c, axisCount))); } @@ -348,15 +350,15 @@ struct AxisValueFormat4 struct AxisValue { - bool get_value (unsigned int axis_index) const + float get_value (unsigned int axis_index) const { switch (u.format) { - case 1: return u.format1.get_value (); - case 2: return u.format2.get_value (); - case 3: return u.format3.get_value (); - case 4: return u.format4.get_axis_record (axis_index).get_value (); - default:return 0; + case 1: hb_barrier (); return u.format1.get_value (); + case 2: hb_barrier (); return u.format2.get_value (); + case 3: hb_barrier (); return u.format3.get_value (); + case 4: hb_barrier (); return u.format4.get_axis_record (axis_index).get_value (); + default:return 0.f; } } @@ -364,9 +366,9 @@ struct AxisValue { switch (u.format) { - case 1: return u.format1.get_axis_index (); - case 2: return u.format2.get_axis_index (); - case 3: return u.format3.get_axis_index (); + case 1: hb_barrier (); return u.format1.get_axis_index (); + case 2: hb_barrier (); return u.format2.get_axis_index (); + case 3: hb_barrier (); return u.format3.get_axis_index (); /* case 4: Makes more sense for variable fonts which are handled by fvar in hb-style */ default:return -1; } @@ -376,10 +378,10 @@ struct AxisValue { switch (u.format) { - case 1: return u.format1.get_value_name_id (); - case 2: return u.format2.get_value_name_id (); - case 3: return u.format3.get_value_name_id (); - case 4: return u.format4.get_value_name_id (); + case 1: hb_barrier (); return u.format1.get_value_name_id (); + case 2: hb_barrier (); return u.format2.get_value_name_id (); + case 3: hb_barrier (); return u.format3.get_value_name_id (); + case 4: hb_barrier (); return u.format4.get_value_name_id (); default:return HB_OT_NAME_ID_INVALID; } } @@ -390,10 +392,10 @@ struct AxisValue if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); TRACE_DISPATCH (this, u.format); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); - case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); - case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); - case 4: return_trace (c->dispatch (u.format4, std::forward (ds)...)); + case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); + case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -403,10 +405,10 @@ struct AxisValue { switch (u.format) { - case 1: return u.format1.keep_axis_value (axis_records, user_axes_location); - case 2: return u.format2.keep_axis_value (axis_records, user_axes_location); - case 3: return u.format3.keep_axis_value (axis_records, user_axes_location); - case 4: return u.format4.keep_axis_value (axis_records, user_axes_location); + case 1: hb_barrier (); return u.format1.keep_axis_value (axis_records, user_axes_location); + case 2: hb_barrier (); return u.format2.keep_axis_value (axis_records, user_axes_location); + case 3: hb_barrier (); return u.format3.keep_axis_value (axis_records, user_axes_location); + case 4: hb_barrier (); return u.format4.keep_axis_value (axis_records, user_axes_location); default:return false; } } @@ -416,13 +418,14 @@ struct AxisValue TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 3: return_trace (u.format3.sanitize (c)); - case 4: return_trace (u.format4.sanitize (c)); + case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); + case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); + case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); + case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); default:return_trace (true); } } @@ -483,7 +486,7 @@ struct STAT hb_array_t> axis_values = get_axis_value_offsets (); for (unsigned int i = 0; i < axis_values.length; i++) { - const AxisValue& axis_value = this+axis_values[i]; + const AxisValue& axis_value = this+offsetToAxisValueOffsets+axis_values[i]; if (axis_value.get_axis_index () == axis_index) { if (value) @@ -560,6 +563,7 @@ struct STAT { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && version.minor > 0 && designAxesOffset.sanitize (c, this, designAxisCount) && diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh index 8ee42e638e0..50ddf5f6967 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * - * File-Date: 2023-08-02 + * + * File-Date: 2025-01-21 */ #ifndef HB_OT_TAG_TABLE_HH @@ -26,12 +26,12 @@ static const LangTag ot_languages2[] = { {HB_TAG('a','y',' ',' '), HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */ {HB_TAG('a','z',' ',' '), HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */ {HB_TAG('b','a',' ',' '), HB_TAG('B','S','H',' ')}, /* Bashkir */ - {HB_TAG('b','e',' ',' '), HB_TAG('B','E','L',' ')}, /* Belarusian -> Belarussian */ + {HB_TAG('b','e',' ',' '), HB_TAG('B','E','L',' ')}, /* Belarusian */ {HB_TAG('b','g',' ',' '), HB_TAG('B','G','R',' ')}, /* Bulgarian */ {HB_TAG('b','i',' ',' '), HB_TAG('B','I','S',' ')}, /* Bislama */ {HB_TAG('b','i',' ',' '), HB_TAG('C','P','P',' ')}, /* Bislama -> Creoles */ {HB_TAG('b','m',' ',' '), HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */ - {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bengali */ + {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bangla */ {HB_TAG('b','o',' ',' '), HB_TAG('T','I','B',' ')}, /* Tibetan */ {HB_TAG('b','r',' ',' '), HB_TAG('B','R','E',' ')}, /* Breton */ {HB_TAG('b','s',' ',' '), HB_TAG('B','O','S',' ')}, /* Bosnian */ @@ -64,7 +64,8 @@ static const LangTag ot_languages2[] = { {HB_TAG('f','r',' ',' '), HB_TAG('F','R','A',' ')}, /* French */ {HB_TAG('f','y',' ',' '), HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */ {HB_TAG('g','a',' ',' '), HB_TAG('I','R','I',' ')}, /* Irish */ - {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */ + {HB_TAG('g','a',' ',' '), HB_TAG('I','R','T',' ')}, /* Irish -> Irish Traditional */ + {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */ {HB_TAG('g','l',' ',' '), HB_TAG('G','A','L',' ')}, /* Galician */ {HB_TAG('g','n',' ',' '), HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ {HB_TAG('g','u',' ',' '), HB_TAG('G','U','J',' ')}, /* Gujarati */ @@ -153,7 +154,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('o','c',' ',' '), HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ {HB_TAG('o','j',' ',' '), HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] -> Ojibway */ {HB_TAG('o','m',' ',' '), HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ - {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) [macrolanguage] */ + {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia [macrolanguage] */ {HB_TAG('o','s',' ',' '), HB_TAG('O','S','S',' ')}, /* Ossetian */ {HB_TAG('p','a',' ',' '), HB_TAG('P','A','N',' ')}, /* Punjabi */ {HB_TAG('p','i',' ',' '), HB_TAG('P','A','L',' ')}, /* Pali */ @@ -166,7 +167,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('r','o',' ',' '), HB_TAG('R','O','M',' ')}, /* Romanian */ {HB_TAG('r','u',' ',' '), HB_TAG('R','U','S',' ')}, /* Russian */ {HB_TAG('r','w',' ',' '), HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ - {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit */ + {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit [macrolanguage] */ {HB_TAG('s','c',' ',' '), HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ {HB_TAG('s','d',' ',' '), HB_TAG('S','N','D',' ')}, /* Sindhi */ {HB_TAG('s','e',' ',' '), HB_TAG('N','S','M',' ')}, /* Northern Sami */ @@ -223,6 +224,7 @@ static const LangTag ot_languages2[] = { static const LangTag ot_languages3[] = { {HB_TAG('a','a','e',' '), HB_TAG('S','Q','I',' ')}, /* Arbëreshë Albanian -> Albanian */ {HB_TAG('a','a','o',' '), HB_TAG('A','R','A',' ')}, /* Algerian Saharan Arabic -> Arabic */ +/*{HB_TAG('a','a','q',' '), HB_TAG('A','A','Q',' ')},*/ /* Eastern Abnaki -> Eastern Abenaki */ {HB_TAG('a','a','t',' '), HB_TAG('S','Q','I',' ')}, /* Arvanitika Albanian -> Albanian */ {HB_TAG('a','b','a',' '), HB_TAG_NONE }, /* Abé != Abaza */ {HB_TAG('a','b','h',' '), HB_TAG('A','R','A',' ')}, /* Tajiki Arabic -> Arabic */ @@ -238,6 +240,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('a','c','r',' '), HB_TAG('M','Y','N',' ')}, /* Achi -> Mayan */ {HB_TAG('a','c','w',' '), HB_TAG('A','R','A',' ')}, /* Hijazi Arabic -> Arabic */ {HB_TAG('a','c','x',' '), HB_TAG('A','R','A',' ')}, /* Omani Arabic -> Arabic */ + {HB_TAG('a','c','y',' '), HB_TAG('A','C','Y',' ')}, /* Cypriot Arabic */ {HB_TAG('a','c','y',' '), HB_TAG('A','R','A',' ')}, /* Cypriot Arabic -> Arabic */ {HB_TAG('a','d','a',' '), HB_TAG('D','N','G',' ')}, /* Adangme -> Dangme */ {HB_TAG('a','d','f',' '), HB_TAG('A','R','A',' ')}, /* Dhofari Arabic -> Arabic */ @@ -288,6 +291,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('a','s','t',' '), HB_TAG('A','S','T',' ')},*/ /* Asturian */ /*{HB_TAG('a','t','h',' '), HB_TAG('A','T','H',' ')},*/ /* Athapascan [collection] -> Athapaskan */ {HB_TAG('a','t','j',' '), HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */ +/*{HB_TAG('a','t','s',' '), HB_TAG('A','T','S',' ')},*/ /* Gros Ventre (Atsina) */ {HB_TAG('a','t','v',' '), HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */ {HB_TAG('a','u','j',' '), HB_TAG('B','B','R',' ')}, /* Awjilah -> Berber */ {HB_TAG('a','u','z',' '), HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */ @@ -326,6 +330,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('b','c','l',' '), HB_TAG('B','I','K',' ')}, /* Central Bikol -> Bikol */ {HB_TAG('b','c','q',' '), HB_TAG('B','C','H',' ')}, /* Bench */ {HB_TAG('b','c','r',' '), HB_TAG('A','T','H',' ')}, /* Babine -> Athapaskan */ +/*{HB_TAG('b','d','c',' '), HB_TAG('B','D','C',' ')},*/ /* Emberá-Baudó */ /*{HB_TAG('b','d','y',' '), HB_TAG('B','D','Y',' ')},*/ /* Bandjalang */ {HB_TAG('b','e','a',' '), HB_TAG('A','T','H',' ')}, /* Beaver -> Athapaskan */ {HB_TAG('b','e','b',' '), HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */ @@ -421,6 +426,8 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','a','f',' '), HB_TAG('A','T','H',' ')}, /* Southern Carrier -> Athapaskan */ {HB_TAG('c','a','k',' '), HB_TAG('C','A','K',' ')}, /* Kaqchikel */ {HB_TAG('c','a','k',' '), HB_TAG('M','Y','N',' ')}, /* Kaqchikel -> Mayan */ +/*{HB_TAG('c','a','y',' '), HB_TAG('C','A','Y',' ')},*/ /* Cayuga */ +/*{HB_TAG('c','b','g',' '), HB_TAG('C','B','G',' ')},*/ /* Chimila */ {HB_TAG('c','b','k',' '), HB_TAG('C','B','K',' ')}, /* Chavacano -> Zamboanga Chavacano */ {HB_TAG('c','b','k',' '), HB_TAG('C','P','P',' ')}, /* Chavacano -> Creoles */ {HB_TAG('c','b','l',' '), HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin -> Chin */ @@ -465,7 +472,9 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','l','d',' '), HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic -> Syriac */ {HB_TAG('c','l','e',' '), HB_TAG('C','C','H','N')}, /* Lealao Chinantec -> Chinantec */ {HB_TAG('c','l','j',' '), HB_TAG('Q','I','N',' ')}, /* Laitu Chin -> Chin */ + {HB_TAG('c','l','s',' '), HB_TAG('S','A','N',' ')}, /* Classical Sanskrit -> Sanskrit */ {HB_TAG('c','l','t',' '), HB_TAG('Q','I','N',' ')}, /* Lautu Chin -> Chin */ +/*{HB_TAG('c','m','i',' '), HB_TAG('C','M','I',' ')},*/ /* Emberá-Chamí */ {HB_TAG('c','m','n',' '), HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese, Simplified */ {HB_TAG('c','m','r',' '), HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */ {HB_TAG('c','n','b',' '), HB_TAG('Q','I','N',' ')}, /* Chinbon Chin -> Chin */ @@ -479,6 +488,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','n','w',' '), HB_TAG('Q','I','N',' ')}, /* Ngawn Chin -> Chin */ {HB_TAG('c','o','a',' '), HB_TAG('M','L','Y',' ')}, /* Cocos Islands Malay -> Malay */ {HB_TAG('c','o','b',' '), HB_TAG('M','Y','N',' ')}, /* Chicomuceltec -> Mayan */ +/*{HB_TAG('c','o','o',' '), HB_TAG('C','O','O',' ')},*/ /* Comox */ /*{HB_TAG('c','o','p',' '), HB_TAG('C','O','P',' ')},*/ /* Coptic */ {HB_TAG('c','o','q',' '), HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */ {HB_TAG('c','p','a',' '), HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */ @@ -528,6 +538,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('c','t','g',' '), HB_TAG('C','T','G',' ')},*/ /* Chittagonian */ {HB_TAG('c','t','h',' '), HB_TAG('Q','I','N',' ')}, /* Thaiphum Chin -> Chin */ {HB_TAG('c','t','l',' '), HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */ +/*{HB_TAG('c','t','o',' '), HB_TAG('C','T','O',' ')},*/ /* Emberá-Catío */ {HB_TAG('c','t','s',' '), HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */ /*{HB_TAG('c','t','t',' '), HB_TAG('C','T','T',' ')},*/ /* Wayanad Chetti */ {HB_TAG('c','t','u',' '), HB_TAG('M','Y','N',' ')}, /* Chol -> Mayan */ @@ -551,7 +562,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('d','e','p',' '), HB_TAG('C','P','P',' ')}, /* Pidgin Delaware -> Creoles */ {HB_TAG('d','g','o',' '), HB_TAG('D','G','O',' ')}, /* Dogri (individual language) */ {HB_TAG('d','g','o',' '), HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) */ - {HB_TAG('d','g','r',' '), HB_TAG('A','T','H',' ')}, /* Dogrib -> Athapaskan */ + {HB_TAG('d','g','r',' '), HB_TAG('A','T','H',' ')}, /* Tlicho -> Athapaskan */ {HB_TAG('d','h','d',' '), HB_TAG('M','A','W',' ')}, /* Dhundari -> Marwari */ /*{HB_TAG('d','h','g',' '), HB_TAG('D','H','G',' ')},*/ /* Dhangu */ {HB_TAG('d','h','v',' '), HB_TAG_NONE }, /* Dehu != Divehi (Dhivehi, Maldivian) (deprecated) */ @@ -590,6 +601,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('e','k','y',' '), HB_TAG('K','R','N',' ')}, /* Eastern Kayah -> Karen */ {HB_TAG('e','m','k',' '), HB_TAG('E','M','K',' ')}, /* Eastern Maninkakan */ {HB_TAG('e','m','k',' '), HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan -> Maninka */ +/*{HB_TAG('e','m','p',' '), HB_TAG('E','M','P',' ')},*/ /* Northern Emberá */ {HB_TAG('e','m','y',' '), HB_TAG('M','Y','N',' ')}, /* Epigraphic Mayan -> Mayan */ {HB_TAG('e','n','b',' '), HB_TAG('K','A','L',' ')}, /* Markweeta -> Kalenjin */ {HB_TAG('e','n','f',' '), HB_TAG('F','N','E',' ')}, /* Forest Enets */ @@ -637,7 +649,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('g','a','a',' '), HB_TAG('G','A','D',' ')}, /* Ga */ {HB_TAG('g','a','c',' '), HB_TAG('C','P','P',' ')}, /* Mixed Great Andamanese -> Creoles */ {HB_TAG('g','a','d',' '), HB_TAG_NONE }, /* Gaddang != Ga */ - {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic (Gaelic) */ + {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic */ /*{HB_TAG('g','a','g',' '), HB_TAG('G','A','G',' ')},*/ /* Gagauz */ {HB_TAG('g','a','l',' '), HB_TAG_NONE }, /* Galolen != Galician */ {HB_TAG('g','a','n',' '), HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese, Simplified */ @@ -654,6 +666,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('g','e','z',' '), HB_TAG('G','E','Z',' ')},*/ /* Geez */ {HB_TAG('g','g','o',' '), HB_TAG('G','O','N',' ')}, /* Southern Gondi (retired code) -> Gondi */ {HB_TAG('g','h','a',' '), HB_TAG('B','B','R',' ')}, /* Ghadamès -> Berber */ + {HB_TAG('g','h','c',' '), HB_TAG('I','R','T',' ')}, /* Hiberno-Scottish Gaelic -> Irish Traditional */ {HB_TAG('g','h','k',' '), HB_TAG('K','R','N',' ')}, /* Geko Karen -> Karen */ {HB_TAG('g','h','o',' '), HB_TAG('B','B','R',' ')}, /* Ghomara -> Berber */ {HB_TAG('g','i','b',' '), HB_TAG('C','P','P',' ')}, /* Gibanawa -> Creoles */ @@ -732,6 +745,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('h','n','d',' '), HB_TAG('H','N','D',' ')},*/ /* Southern Hindko -> Hindko */ {HB_TAG('h','n','e',' '), HB_TAG('C','H','H',' ')}, /* Chhattisgarhi -> Chattisgarhi */ {HB_TAG('h','n','j',' '), HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */ + {HB_TAG('h','n','m',' '), HB_TAG('Z','H','S',' ')}, /* Hainanese -> Chinese, Simplified */ {HB_TAG('h','n','o',' '), HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */ {HB_TAG('h','o','c',' '), HB_TAG('H','O',' ',' ')}, /* Ho */ {HB_TAG('h','o','i',' '), HB_TAG('A','T','H',' ')}, /* Holikachuk -> Athapaskan */ @@ -743,6 +757,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('h','s','n',' '), HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese, Simplified */ {HB_TAG('h','u','j',' '), HB_TAG('H','M','N',' ')}, /* Northern Guiyang Hmong -> Hmong */ {HB_TAG('h','u','p',' '), HB_TAG('A','T','H',' ')}, /* Hupa -> Athapaskan */ +/*{HB_TAG('h','u','r',' '), HB_TAG('H','U','R',' ')},*/ /* Halkomelem */ {HB_TAG('h','u','s',' '), HB_TAG('M','Y','N',' ')}, /* Huastec -> Mayan */ {HB_TAG('h','w','c',' '), HB_TAG('C','P','P',' ')}, /* Hawai'i Creole English -> Creoles */ {HB_TAG('h','y','w',' '), HB_TAG('H','Y','E',' ')}, /* Western Armenian -> Armenian */ @@ -780,6 +795,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('j','b','n',' '), HB_TAG('B','B','R',' ')}, /* Nafusi -> Berber */ /*{HB_TAG('j','b','o',' '), HB_TAG('J','B','O',' ')},*/ /* Lojban */ /*{HB_TAG('j','c','t',' '), HB_TAG('J','C','T',' ')},*/ /* Krymchak */ +/*{HB_TAG('j','d','t',' '), HB_TAG('J','D','T',' ')},*/ /* Judeo-Tat */ {HB_TAG('j','g','o',' '), HB_TAG('B','M','L',' ')}, /* Ngomba -> Bamileke */ {HB_TAG('j','i','i',' '), HB_TAG_NONE }, /* Jiiddu != Yiddish */ {HB_TAG('j','k','m',' '), HB_TAG('K','R','N',' ')}, /* Mobwa Karen -> Karen */ @@ -794,6 +810,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','a','m',' '), HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ {HB_TAG('k','a','r',' '), HB_TAG('K','R','N',' ')}, /* Karen [collection] */ /*{HB_TAG('k','a','w',' '), HB_TAG('K','A','W',' ')},*/ /* Kawi (Old Javanese) */ +/*{HB_TAG('k','b','c',' '), HB_TAG('K','B','C',' ')},*/ /* Kadiwéu */ {HB_TAG('k','b','d',' '), HB_TAG('K','A','B',' ')}, /* Kabardian */ {HB_TAG('k','b','y',' '), HB_TAG('K','N','R',' ')}, /* Manga Kanuri -> Kanuri */ {HB_TAG('k','c','a',' '), HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */ @@ -814,6 +831,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','f','x',' '), HB_TAG('K','U','L',' ')}, /* Kullu Pahari -> Kulvi */ {HB_TAG('k','f','y',' '), HB_TAG('K','M','N',' ')}, /* Kumaoni */ {HB_TAG('k','g','e',' '), HB_TAG_NONE }, /* Komering != Khutsuri Georgian */ +/*{HB_TAG('k','g','f',' '), HB_TAG('K','G','F',' ')},*/ /* Kube */ {HB_TAG('k','h','a',' '), HB_TAG('K','S','I',' ')}, /* Khasi */ {HB_TAG('k','h','b',' '), HB_TAG('X','B','D',' ')}, /* Lü */ {HB_TAG('k','h','k',' '), HB_TAG('M','N','G',' ')}, /* Halh Mongolian -> Mongolian */ @@ -829,6 +847,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','j','b',' '), HB_TAG('M','Y','N',' ')}, /* Q'anjob'al -> Mayan */ /*{HB_TAG('k','j','d',' '), HB_TAG('K','J','D',' ')},*/ /* Southern Kiwai */ {HB_TAG('k','j','h',' '), HB_TAG('K','H','A',' ')}, /* Khakas -> Khakass */ +/*{HB_TAG('k','j','j',' '), HB_TAG('K','J','J',' ')},*/ /* Khinalugh -> Khinalug */ {HB_TAG('k','j','p',' '), HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ {HB_TAG('k','j','p',' '), HB_TAG('K','R','N',' ')}, /* Pwo Eastern Karen -> Karen */ {HB_TAG('k','j','t',' '), HB_TAG('K','R','N',' ')}, /* Phrae Pwo Karen -> Karen */ @@ -838,6 +857,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','l','m',' '), HB_TAG_NONE }, /* Migum != Kalmyk */ {HB_TAG('k','l','n',' '), HB_TAG('K','A','L',' ')}, /* Kalenjin [macrolanguage] */ {HB_TAG('k','m','b',' '), HB_TAG('M','B','N',' ')}, /* Kimbundu -> Mbundu */ +/*{HB_TAG('k','m','g',' '), HB_TAG('K','M','G',' ')},*/ /* Kâte */ {HB_TAG('k','m','n',' '), HB_TAG_NONE }, /* Awtuw != Kumaoni */ {HB_TAG('k','m','o',' '), HB_TAG_NONE }, /* Kwoma != Komo */ {HB_TAG('k','m','r',' '), HB_TAG('K','U','R',' ')}, /* Northern Kurdish -> Kurdish */ @@ -881,6 +901,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','s','i',' '), HB_TAG_NONE }, /* Krisa != Khasi */ {HB_TAG('k','s','m',' '), HB_TAG_NONE }, /* Kumba != Kildin Sami */ {HB_TAG('k','s','s',' '), HB_TAG('K','I','S',' ')}, /* Southern Kisi -> Kisii */ +/*{HB_TAG('k','s','u',' '), HB_TAG('K','S','U',' ')},*/ /* Khamyang */ {HB_TAG('k','s','w',' '), HB_TAG('K','S','W',' ')}, /* S’gaw Karen */ {HB_TAG('k','s','w',' '), HB_TAG('K','R','N',' ')}, /* S'gaw Karen -> Karen */ {HB_TAG('k','t','b',' '), HB_TAG('K','E','B',' ')}, /* Kambaata -> Kebena */ @@ -894,6 +915,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','u','y',' '), HB_TAG_NONE }, /* Kuuku-Ya'u != Kuy */ {HB_TAG('k','v','b',' '), HB_TAG('M','L','Y',' ')}, /* Kubu -> Malay */ {HB_TAG('k','v','l',' '), HB_TAG('K','R','N',' ')}, /* Kayaw -> Karen */ + {HB_TAG('k','v','q',' '), HB_TAG('K','V','Q',' ')}, /* Geba Karen */ {HB_TAG('k','v','q',' '), HB_TAG('K','R','N',' ')}, /* Geba Karen -> Karen */ {HB_TAG('k','v','r',' '), HB_TAG('M','L','Y',' ')}, /* Kerinci -> Malay */ {HB_TAG('k','v','t',' '), HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */ @@ -930,6 +952,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('l','i','j',' '), HB_TAG('L','I','J',' ')},*/ /* Ligurian */ {HB_TAG('l','i','r',' '), HB_TAG('C','P','P',' ')}, /* Liberian English -> Creoles */ /*{HB_TAG('l','i','s',' '), HB_TAG('L','I','S',' ')},*/ /* Lisu */ +/*{HB_TAG('l','i','v',' '), HB_TAG('L','I','V',' ')},*/ /* Liv */ {HB_TAG('l','i','w',' '), HB_TAG('M','L','Y',' ')}, /* Col -> Malay */ {HB_TAG('l','i','y',' '), HB_TAG('B','A','D','0')}, /* Banda-Bambari -> Banda */ /*{HB_TAG('l','j','p',' '), HB_TAG('L','J','P',' ')},*/ /* Lampung Api -> Lampung */ @@ -959,9 +982,11 @@ static const LangTag ot_languages3[] = { {HB_TAG('l','t','o',' '), HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */ {HB_TAG('l','t','s',' '), HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */ /*{HB_TAG('l','u','a',' '), HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */ + {HB_TAG('l','u','h',' '), HB_TAG('Z','H','S',' ')}, /* Leizhou Chinese -> Chinese, Simplified */ /*{HB_TAG('l','u','o',' '), HB_TAG('L','U','O',' ')},*/ /* Luo (Kenya and Tanzania) */ {HB_TAG('l','u','s',' '), HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */ {HB_TAG('l','u','s',' '), HB_TAG('Q','I','N',' ')}, /* Lushai -> Chin */ +/*{HB_TAG('l','u','t',' '), HB_TAG('L','U','T',' ')},*/ /* Lushootseed */ {HB_TAG('l','u','y',' '), HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */ {HB_TAG('l','u','z',' '), HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */ {HB_TAG('l','v','i',' '), HB_TAG_NONE }, /* Lavi != Latvian */ @@ -995,12 +1020,14 @@ static const LangTag ot_languages3[] = { {HB_TAG('m','e','n',' '), HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */ {HB_TAG('m','e','o',' '), HB_TAG('M','L','Y',' ')}, /* Kedah Malay -> Malay */ /*{HB_TAG('m','e','r',' '), HB_TAG('M','E','R',' ')},*/ /* Meru */ +/*{HB_TAG('m','e','v',' '), HB_TAG('M','E','V',' ')},*/ /* Mano */ {HB_TAG('m','f','a',' '), HB_TAG('M','F','A',' ')}, /* Pattani Malay */ {HB_TAG('m','f','a',' '), HB_TAG('M','L','Y',' ')}, /* Pattani Malay -> Malay */ {HB_TAG('m','f','b',' '), HB_TAG('M','L','Y',' ')}, /* Bangka -> Malay */ {HB_TAG('m','f','e',' '), HB_TAG('M','F','E',' ')}, /* Morisyen */ {HB_TAG('m','f','e',' '), HB_TAG('C','P','P',' ')}, /* Morisyen -> Creoles */ {HB_TAG('m','f','p',' '), HB_TAG('C','P','P',' ')}, /* Makassar Malay -> Creoles */ + {HB_TAG('m','g','a',' '), HB_TAG('S','G','A',' ')}, /* Middle Irish (900-1200) -> Old Irish */ {HB_TAG('m','h','c',' '), HB_TAG('M','Y','N',' ')}, /* Mocho -> Mayan */ {HB_TAG('m','h','r',' '), HB_TAG('L','M','A',' ')}, /* Eastern Mari -> Low Mari */ {HB_TAG('m','h','v',' '), HB_TAG('A','R','K',' ')}, /* Arakanese (retired code) -> Rakhine */ @@ -1126,6 +1153,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('n','o','d',' '), HB_TAG('N','T','A',' ')}, /* Northern Thai -> Northern Tai */ /*{HB_TAG('n','o','e',' '), HB_TAG('N','O','E',' ')},*/ /* Nimadi */ /*{HB_TAG('n','o','g',' '), HB_TAG('N','O','G',' ')},*/ /* Nogai */ +/*{HB_TAG('n','o','p',' '), HB_TAG('N','O','P',' ')},*/ /* Numanggang */ /*{HB_TAG('n','o','v',' '), HB_TAG('N','O','V',' ')},*/ /* Novial */ {HB_TAG('n','p','i',' '), HB_TAG('N','E','P',' ')}, /* Nepali */ {HB_TAG('n','p','l',' '), HB_TAG('N','A','H',' ')}, /* Southeastern Puebla Nahuatl -> Nahuatl */ @@ -1136,6 +1164,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('n','s','u',' '), HB_TAG('N','A','H',' ')}, /* Sierra Negra Nahuatl -> Nahuatl */ {HB_TAG('n','t','o',' '), HB_TAG_NONE }, /* Ntomba != Esperanto */ {HB_TAG('n','u','e',' '), HB_TAG('B','A','D','0')}, /* Ngundu -> Banda */ +/*{HB_TAG('n','u','k',' '), HB_TAG('N','U','K',' ')},*/ /* Nuu-chah-nulth */ {HB_TAG('n','u','u',' '), HB_TAG('B','A','D','0')}, /* Ngbundu -> Banda */ {HB_TAG('n','u','z',' '), HB_TAG('N','A','H',' ')}, /* Tlamacazapa Nahuatl -> Nahuatl */ {HB_TAG('n','w','e',' '), HB_TAG('B','M','L',' ')}, /* Ngwe -> Bamileke */ @@ -1153,6 +1182,8 @@ static const LangTag ot_languages3[] = { {HB_TAG('o','k','i',' '), HB_TAG('K','A','L',' ')}, /* Okiek -> Kalenjin */ {HB_TAG('o','k','m',' '), HB_TAG('K','O','H',' ')}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */ {HB_TAG('o','k','r',' '), HB_TAG('I','J','O',' ')}, /* Kirike -> Ijo */ +/*{HB_TAG('o','n','e',' '), HB_TAG('O','N','E',' ')},*/ /* Oneida */ +/*{HB_TAG('o','n','o',' '), HB_TAG('O','N','O',' ')},*/ /* Onondaga */ {HB_TAG('o','n','x',' '), HB_TAG('C','P','P',' ')}, /* Onin Based Pidgin -> Creoles */ {HB_TAG('o','o','r',' '), HB_TAG('C','P','P',' ')}, /* Oorlams -> Creoles */ {HB_TAG('o','r','c',' '), HB_TAG('O','R','O',' ')}, /* Orma -> Oromo */ @@ -1160,7 +1191,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('o','r','o',' '), HB_TAG_NONE }, /* Orokolo != Oromo */ {HB_TAG('o','r','r',' '), HB_TAG('I','J','O',' ')}, /* Oruma -> Ijo */ {HB_TAG('o','r','s',' '), HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */ - {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) */ + {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia */ {HB_TAG('o','t','w',' '), HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */ {HB_TAG('o','u','a',' '), HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */ {HB_TAG('p','a','a',' '), HB_TAG_NONE }, /* Papuan [collection] != Palestinian Aramaic */ @@ -1193,7 +1224,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('p','i','s',' '), HB_TAG('C','P','P',' ')}, /* Pijin -> Creoles */ {HB_TAG('p','k','h',' '), HB_TAG('Q','I','N',' ')}, /* Pankhu -> Chin */ {HB_TAG('p','k','o',' '), HB_TAG('K','A','L',' ')}, /* Pökoot -> Kalenjin */ - {HB_TAG('p','l','g',' '), HB_TAG_NONE }, /* Pilagá != Palaung */ + {HB_TAG('p','l','g',' '), HB_TAG('P','L','G','0')}, /* Pilagá */ {HB_TAG('p','l','k',' '), HB_TAG_NONE }, /* Kohistani Shina != Polish */ {HB_TAG('p','l','l',' '), HB_TAG('P','L','G',' ')}, /* Shwe Palaung -> Palaung */ {HB_TAG('p','l','n',' '), HB_TAG('C','P','P',' ')}, /* Palenquero -> Creoles */ @@ -1353,6 +1384,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('s','d','h',' '), HB_TAG('K','U','R',' ')}, /* Southern Kurdish -> Kurdish */ {HB_TAG('s','d','n',' '), HB_TAG('S','R','D',' ')}, /* Gallurese Sardinian -> Sardinian */ {HB_TAG('s','d','s',' '), HB_TAG('B','B','R',' ')}, /* Sened -> Berber */ +/*{HB_TAG('s','e','e',' '), HB_TAG('S','E','E',' ')},*/ /* Seneca */ {HB_TAG('s','e','h',' '), HB_TAG('S','N','A',' ')}, /* Sena */ {HB_TAG('s','e','k',' '), HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */ /*{HB_TAG('s','e','l',' '), HB_TAG('S','E','L',' ')},*/ /* Selkup */ @@ -1374,9 +1406,13 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('s','i','d',' '), HB_TAG('S','I','D',' ')},*/ /* Sidamo */ {HB_TAG('s','i','g',' '), HB_TAG_NONE }, /* Paasaal != Silte Gurage */ {HB_TAG('s','i','z',' '), HB_TAG('B','B','R',' ')}, /* Siwi -> Berber */ +/*{HB_TAG('s','j','a',' '), HB_TAG('S','J','A',' ')},*/ /* Epena */ + {HB_TAG('s','j','c',' '), HB_TAG('Z','H','S',' ')}, /* Shaojiang Chinese -> Chinese, Simplified */ {HB_TAG('s','j','d',' '), HB_TAG('K','S','M',' ')}, /* Kildin Sami */ +/*{HB_TAG('s','j','e',' '), HB_TAG('S','J','E',' ')},*/ /* Pite Sami */ {HB_TAG('s','j','o',' '), HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */ {HB_TAG('s','j','s',' '), HB_TAG('B','B','R',' ')}, /* Senhaja De Srair -> Berber */ +/*{HB_TAG('s','j','u',' '), HB_TAG('S','J','U',' ')},*/ /* Ume Sami */ {HB_TAG('s','k','g',' '), HB_TAG('M','L','G',' ')}, /* Sakalava Malagasy -> Malagasy */ {HB_TAG('s','k','r',' '), HB_TAG('S','R','K',' ')}, /* Saraiki */ {HB_TAG('s','k','s',' '), HB_TAG_NONE }, /* Maia != Skolt Sami */ @@ -1395,7 +1431,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('s','n','k',' '), HB_TAG('S','N','K',' ')},*/ /* Soninke */ {HB_TAG('s','o','g',' '), HB_TAG_NONE }, /* Sogdian != Sodo Gurage */ /*{HB_TAG('s','o','p',' '), HB_TAG('S','O','P',' ')},*/ /* Songe */ - {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */ + {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia */ {HB_TAG('s','p','y',' '), HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */ {HB_TAG('s','r','b',' '), HB_TAG_NONE }, /* Sora != Serbian */ {HB_TAG('s','r','c',' '), HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */ @@ -1410,6 +1446,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('s','s','m',' '), HB_TAG_NONE }, /* Semnam != Southern Sami */ {HB_TAG('s','t','a',' '), HB_TAG('C','P','P',' ')}, /* Settla -> Creoles */ /*{HB_TAG('s','t','q',' '), HB_TAG('S','T','Q',' ')},*/ /* Saterfriesisch -> Saterland Frisian */ +/*{HB_TAG('s','t','r',' '), HB_TAG('S','T','R',' ')},*/ /* Straits Salish */ {HB_TAG('s','t','v',' '), HB_TAG('S','I','G',' ')}, /* Silt'e -> Silte Gurage */ /*{HB_TAG('s','u','k',' '), HB_TAG('S','U','K',' ')},*/ /* Sukuma */ {HB_TAG('s','u','q',' '), HB_TAG('S','U','R',' ')}, /* Suri */ @@ -1431,10 +1468,12 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','a','a',' '), HB_TAG('A','T','H',' ')}, /* Lower Tanana -> Athapaskan */ /*{HB_TAG('t','a','b',' '), HB_TAG('T','A','B',' ')},*/ /* Tabassaran -> Tabasaran */ {HB_TAG('t','a','j',' '), HB_TAG_NONE }, /* Eastern Tamang != Tajiki */ + {HB_TAG('t','a','q',' '), HB_TAG('T','A','Q',' ')}, /* Tamasheq */ {HB_TAG('t','a','q',' '), HB_TAG('T','M','H',' ')}, /* Tamasheq -> Tamashek */ {HB_TAG('t','a','q',' '), HB_TAG('B','B','R',' ')}, /* Tamasheq -> Berber */ {HB_TAG('t','a','s',' '), HB_TAG('C','P','P',' ')}, /* Tay Boi -> Creoles */ {HB_TAG('t','a','u',' '), HB_TAG('A','T','H',' ')}, /* Upper Tanana -> Athapaskan */ +/*{HB_TAG('t','b','v',' '), HB_TAG('T','B','V',' ')},*/ /* Tobo */ {HB_TAG('t','c','b',' '), HB_TAG('A','T','H',' ')}, /* Tanacross -> Athapaskan */ {HB_TAG('t','c','e',' '), HB_TAG('A','T','H',' ')}, /* Southern Tutchone -> Athapaskan */ {HB_TAG('t','c','h',' '), HB_TAG('C','P','P',' ')}, /* Turks And Caicos Creole English -> Creoles */ @@ -1442,6 +1481,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','c','s',' '), HB_TAG('C','P','P',' ')}, /* Torres Strait Creole -> Creoles */ {HB_TAG('t','c','y',' '), HB_TAG('T','U','L',' ')}, /* Tulu */ {HB_TAG('t','c','z',' '), HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */ +/*{HB_TAG('t','d','c',' '), HB_TAG('T','D','C',' ')},*/ /* Emberá-Tadó */ /*{HB_TAG('t','d','d',' '), HB_TAG('T','D','D',' ')},*/ /* Tai Nüa -> Dehong Dai */ {HB_TAG('t','d','x',' '), HB_TAG('M','L','G',' ')}, /* Tandroy-Mahafaly Malagasy -> Malagasy */ {HB_TAG('t','e','c',' '), HB_TAG('K','A','L',' ')}, /* Terik -> Kalenjin */ @@ -1455,9 +1495,12 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','g','r',' '), HB_TAG_NONE }, /* Tareng != Tigre */ {HB_TAG('t','g','x',' '), HB_TAG('A','T','H',' ')}, /* Tagish -> Athapaskan */ {HB_TAG('t','g','y',' '), HB_TAG_NONE }, /* Togoyo != Tigrinya */ +/*{HB_TAG('t','h','p',' '), HB_TAG('T','H','P',' ')},*/ /* Thompson */ {HB_TAG('t','h','t',' '), HB_TAG('A','T','H',' ')}, /* Tahltan -> Athapaskan */ + {HB_TAG('t','h','v',' '), HB_TAG('T','H','V',' ')}, /* Tahaggart Tamahaq */ {HB_TAG('t','h','v',' '), HB_TAG('T','M','H',' ')}, /* Tahaggart Tamahaq -> Tamashek */ {HB_TAG('t','h','v',' '), HB_TAG('B','B','R',' ')}, /* Tahaggart Tamahaq -> Berber */ + {HB_TAG('t','h','z',' '), HB_TAG('T','H','Z',' ')}, /* Tayart Tamajeq */ {HB_TAG('t','h','z',' '), HB_TAG('T','M','H',' ')}, /* Tayart Tamajeq -> Tamashek */ {HB_TAG('t','h','z',' '), HB_TAG('B','B','R',' ')}, /* Tayart Tamajeq -> Berber */ {HB_TAG('t','i','a',' '), HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */ @@ -1468,6 +1511,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','k','g',' '), HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ {HB_TAG('t','k','m',' '), HB_TAG_NONE }, /* Takelma != Turkmen */ /*{HB_TAG('t','l','i',' '), HB_TAG('T','L','I',' ')},*/ /* Tlingit */ +/*{HB_TAG('t','l','y',' '), HB_TAG('T','L','Y',' ')},*/ /* Talysh */ {HB_TAG('t','m','g',' '), HB_TAG('C','P','P',' ')}, /* Ternateño -> Creoles */ {HB_TAG('t','m','h',' '), HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */ {HB_TAG('t','m','h',' '), HB_TAG('B','B','R',' ')}, /* Tamashek [macrolanguage] -> Berber */ @@ -1493,11 +1537,13 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('t','s','j',' '), HB_TAG('T','S','J',' ')},*/ /* Tshangla */ {HB_TAG('t','t','c',' '), HB_TAG('M','Y','N',' ')}, /* Tektiteko -> Mayan */ {HB_TAG('t','t','m',' '), HB_TAG('A','T','H',' ')}, /* Northern Tutchone -> Athapaskan */ + {HB_TAG('t','t','q',' '), HB_TAG('T','T','Q',' ')}, /* Tawallammat Tamajaq */ {HB_TAG('t','t','q',' '), HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */ {HB_TAG('t','t','q',' '), HB_TAG('B','B','R',' ')}, /* Tawallammat Tamajaq -> Berber */ {HB_TAG('t','u','a',' '), HB_TAG_NONE }, /* Wiarumus != Turoyo Aramaic */ {HB_TAG('t','u','l',' '), HB_TAG_NONE }, /* Tula != Tulu */ /*{HB_TAG('t','u','m',' '), HB_TAG('T','U','M',' ')},*/ /* Tumbuka */ +/*{HB_TAG('t','u','s',' '), HB_TAG('T','U','S',' ')},*/ /* Tuscarora */ {HB_TAG('t','u','u',' '), HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */ {HB_TAG('t','u','v',' '), HB_TAG_NONE }, /* Turkana != Tuvin */ {HB_TAG('t','u','y',' '), HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */ @@ -1514,6 +1560,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','z','o',' '), HB_TAG('T','Z','O',' ')}, /* Tzotzil */ {HB_TAG('t','z','o',' '), HB_TAG('M','Y','N',' ')}, /* Tzotzil -> Mayan */ {HB_TAG('u','b','l',' '), HB_TAG('B','I','K',' ')}, /* Buhi'non Bikol -> Bikol */ +/*{HB_TAG('u','d','i',' '), HB_TAG('U','D','I',' ')},*/ /* Udi */ /*{HB_TAG('u','d','m',' '), HB_TAG('U','D','M',' ')},*/ /* Udmurt */ {HB_TAG('u','k','i',' '), HB_TAG('K','U','I',' ')}, /* Kui (India) */ {HB_TAG('u','l','n',' '), HB_TAG('C','P','P',' ')}, /* Unserdeutsch -> Creoles */ @@ -1532,13 +1579,17 @@ static const LangTag ot_languages3[] = { {HB_TAG('v','k','t',' '), HB_TAG('M','L','Y',' ')}, /* Tenggarong Kutai Malay -> Malay */ {HB_TAG('v','l','s',' '), HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */ {HB_TAG('v','m','w',' '), HB_TAG('M','A','K',' ')}, /* Makhuwa */ -/*{HB_TAG('v','r','o',' '), HB_TAG('V','R','O',' ')},*/ /* Võro */ + {HB_TAG('v','r','o',' '), HB_TAG('V','R','O',' ')}, /* Võro */ + {HB_TAG('v','r','o',' '), HB_TAG('E','T','I',' ')}, /* Võro -> Estonian */ + {HB_TAG('v','s','n',' '), HB_TAG('S','A','N',' ')}, /* Vedic Sanskrit -> Sanskrit */ {HB_TAG('w','a','g',' '), HB_TAG_NONE }, /* Wa'ema != Wagdi */ /*{HB_TAG('w','a','r',' '), HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */ +/*{HB_TAG('w','b','l',' '), HB_TAG('W','B','L',' ')},*/ /* Wakhi */ {HB_TAG('w','b','m',' '), HB_TAG('W','A',' ',' ')}, /* Wa */ {HB_TAG('w','b','r',' '), HB_TAG('W','A','G',' ')}, /* Wagdi */ {HB_TAG('w','b','r',' '), HB_TAG('R','A','J',' ')}, /* Wagdi -> Rajasthani */ /*{HB_TAG('w','c','i',' '), HB_TAG('W','C','I',' ')},*/ /* Waci Gbe */ +/*{HB_TAG('w','d','t',' '), HB_TAG('W','D','T',' ')},*/ /* Wendat */ {HB_TAG('w','e','a',' '), HB_TAG('K','R','N',' ')}, /* Wewaw -> Karen */ {HB_TAG('w','e','s',' '), HB_TAG('C','P','P',' ')}, /* Cameroon Pidgin -> Creoles */ {HB_TAG('w','e','u',' '), HB_TAG('Q','I','N',' ')}, /* Rawngtu Chin -> Chin */ @@ -1550,6 +1601,9 @@ static const LangTag ot_languages3[] = { {HB_TAG('w','s','g',' '), HB_TAG('G','O','N',' ')}, /* Adilabad Gondi -> Gondi */ /*{HB_TAG('w','t','m',' '), HB_TAG('W','T','M',' ')},*/ /* Mewati */ {HB_TAG('w','u','u',' '), HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese, Simplified */ + {HB_TAG('w','y','a',' '), HB_TAG('W','D','T',' ')}, /* Wyandot (retired code) -> Wendat */ + {HB_TAG('w','y','a',' '), HB_TAG('W','Y','N',' ')}, /* Wyandot (retired code) */ +/*{HB_TAG('w','y','n',' '), HB_TAG('W','Y','N',' ')},*/ /* Wyandot */ {HB_TAG('x','a','l',' '), HB_TAG('K','L','M',' ')}, /* Kalmyk */ {HB_TAG('x','a','l',' '), HB_TAG('T','O','D',' ')}, /* Kalmyk -> Todo */ {HB_TAG('x','a','n',' '), HB_TAG('S','E','K',' ')}, /* Xamtanga -> Sekota */ @@ -1582,7 +1636,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('y','b','a',' '), HB_TAG_NONE }, /* Yala != Yoruba */ {HB_TAG('y','b','b',' '), HB_TAG('B','M','L',' ')}, /* Yemba -> Bamileke */ {HB_TAG('y','b','d',' '), HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */ - {HB_TAG('y','c','r',' '), HB_TAG_NONE }, /* Yilan Creole != Y-Cree */ + {HB_TAG('y','c','r',' '), HB_TAG('C','P','P',' ')}, /* Yilan Creole -> Creoles */ {HB_TAG('y','d','d',' '), HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */ /*{HB_TAG('y','g','p',' '), HB_TAG('Y','G','P',' ')},*/ /* Gepo */ {HB_TAG('y','i','h',' '), HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */ @@ -1591,6 +1645,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('y','o','s',' '), HB_TAG('Q','I','N',' ')}, /* Yos (retired code) -> Chin */ {HB_TAG('y','u','a',' '), HB_TAG('M','Y','N',' ')}, /* Yucateco -> Mayan */ {HB_TAG('y','u','e',' '), HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Traditional, Hong Kong SAR */ +/*{HB_TAG('y','u','f',' '), HB_TAG('Y','U','F',' ')},*/ /* Havasupai-Walapai-Yavapai */ /*{HB_TAG('y','w','q',' '), HB_TAG('Y','W','Q',' ')},*/ /* Wuding-Luquan Yi */ {HB_TAG('z','c','h',' '), HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */ {HB_TAG('z','d','j',' '), HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */ @@ -2335,6 +2390,26 @@ out: *count = i; return true; } + if (lang_matches (&lang_str[1], limit, "nm-hant-hk", 10)) + { + /* Hainanese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "nm-hant-mo", 10)) + { + /* Hainanese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } if (lang_matches (&lang_str[1], limit, "sn-hant-hk", 10)) { /* Xiang Chinese; Han (Traditional variant); Hong Kong */ @@ -2369,6 +2444,20 @@ out: *count = 1; return true; } + if (lang_matches (&lang_str[1], limit, "nm-hans", 7)) + { + /* Hainanese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "nm-hant", 7)) + { + /* Hainanese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (lang_matches (&lang_str[1], limit, "sn-hans", 7)) { /* Xiang Chinese; Han (Simplified variant) */ @@ -2413,6 +2502,36 @@ out: *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Hainanese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Hainanese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Hainanese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (0 == strncmp (&lang_str[1], "sn-", 3) && subtag_matches (lang_str, limit, "-hk", 3)) { @@ -2474,6 +2593,40 @@ out: } break; case 'l': + if (lang_matches (&lang_str[1], limit, "uh-hant-hk", 10)) + { + /* Leizhou Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hant-mo", 10)) + { + /* Leizhou Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hans", 7)) + { + /* Leizhou Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hant", 7)) + { + /* Leizhou Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (lang_matches (&lang_str[1], limit, "zh-hans", 7)) { /* Literary Chinese; Han (Simplified variant) */ @@ -2481,6 +2634,36 @@ out: *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Leizhou Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Leizhou Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Leizhou Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } break; case 'm': if (lang_matches (&lang_str[1], limit, "np-hant-hk", 10)) @@ -2652,6 +2835,72 @@ out: return true; } break; + case 's': + if (lang_matches (&lang_str[1], limit, "jc-hant-hk", 10)) + { + /* Shaojiang Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hant-mo", 10)) + { + /* Shaojiang Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hans", 7)) + { + /* Shaojiang Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hant", 7)) + { + /* Shaojiang Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Shaojiang Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Shaojiang Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Shaojiang Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + break; case 'w': if (lang_matches (&lang_str[1], limit, "uu-hant-hk", 10)) { @@ -2816,9 +3065,10 @@ out: * @tag: A language tag. * * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to - * many language tags) and the best tag is not the alphabetically first, or if - * the best tag consists of multiple subtags, or if the best tag does not appear - * in #ot_languages. + * many language tags) and the best tag is not the first (sorted alphabetically, + * with two-letter tags having priority over all three-letter tags), or if the + * best tag consists of multiple subtags, or if the best tag does not appear in + * #ot_languages2 or #ot_languages3. * * Return value: The #hb_language_t corresponding to the BCP 47 language tag, * or #HB_LANGUAGE_INVALID if @tag is not ambiguous. @@ -2832,8 +3082,6 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("alt", -1); /* Southern Altai */ case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */ return hb_language_from_string ("und-fonnapa", -1); /* Undetermined; North American Phonetic Alphabet */ - case HB_TAG('A','R','A',' '): /* Arabic */ - return hb_language_from_string ("ar", -1); /* Arabic [macrolanguage] */ case HB_TAG('A','R','K',' '): /* Rakhine */ return hb_language_from_string ("rki", -1); /* Rakhine */ case HB_TAG('A','T','H',' '): /* Athapaskan */ @@ -2854,12 +3102,6 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("din", -1); /* Dinka [macrolanguage] */ case HB_TAG('D','R','I',' '): /* Dari */ return hb_language_from_string ("prs", -1); /* Dari */ - case HB_TAG('D','Z','N',' '): /* Dzongkha */ - return hb_language_from_string ("dz", -1); /* Dzongkha */ - case HB_TAG('E','T','I',' '): /* Estonian */ - return hb_language_from_string ("et", -1); /* Estonian [macrolanguage] */ - case HB_TAG('F','A','R',' '): /* Persian */ - return hb_language_from_string ("fa", -1); /* Persian [macrolanguage] */ case HB_TAG('G','O','N',' '): /* Gondi */ return hb_language_from_string ("gon", -1); /* Gondi [macrolanguage] */ case HB_TAG('H','M','A',' '): /* High Mari */ @@ -2874,50 +3116,34 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("iba", -1); /* Iban */ case HB_TAG('I','J','O',' '): /* Ijo */ return hb_language_from_string ("ijo", -1); /* Ijo [collection] */ - case HB_TAG('I','N','U',' '): /* Inuktitut */ - return hb_language_from_string ("iu", -1); /* Inuktitut [macrolanguage] */ - case HB_TAG('I','P','K',' '): /* Inupiat */ - return hb_language_from_string ("ik", -1); /* Inupiaq [macrolanguage] */ case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */ return hb_language_from_string ("und-fonipa", -1); /* Undetermined; International Phonetic Alphabet */ case HB_TAG('I','R','T',' '): /* Irish Traditional */ - return hb_language_from_string ("ga-Latg", -1); /* Irish; Latin (Gaelic variant) */ + return hb_language_from_string ("ghc", -1); /* Hiberno-Scottish Gaelic */ case HB_TAG('J','I','I',' '): /* Yiddish */ return hb_language_from_string ("yi", -1); /* Yiddish [macrolanguage] */ case HB_TAG('K','A','L',' '): /* Kalenjin */ return hb_language_from_string ("kln", -1); /* Kalenjin [macrolanguage] */ case HB_TAG('K','G','E',' '): /* Khutsuri Georgian */ return hb_language_from_string ("und-Geok", -1); /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */ - case HB_TAG('K','N','R',' '): /* Kanuri */ - return hb_language_from_string ("kr", -1); /* Kanuri [macrolanguage] */ case HB_TAG('K','O','H',' '): /* Korean Old Hangul */ return hb_language_from_string ("okm", -1); /* Middle Korean (10th-16th cent.) */ case HB_TAG('K','O','K',' '): /* Konkani */ return hb_language_from_string ("kok", -1); /* Konkani [macrolanguage] */ - case HB_TAG('K','O','M',' '): /* Komi */ - return hb_language_from_string ("kv", -1); /* Komi [macrolanguage] */ case HB_TAG('K','P','L',' '): /* Kpelle */ return hb_language_from_string ("kpe", -1); /* Kpelle [macrolanguage] */ case HB_TAG('K','R','N',' '): /* Karen */ return hb_language_from_string ("kar", -1); /* Karen [collection] */ case HB_TAG('K','U','I',' '): /* Kui */ return hb_language_from_string ("uki", -1); /* Kui (India) */ - case HB_TAG('K','U','R',' '): /* Kurdish */ - return hb_language_from_string ("ku", -1); /* Kurdish [macrolanguage] */ case HB_TAG('L','M','A',' '): /* Low Mari */ return hb_language_from_string ("mhr", -1); /* Eastern Mari */ case HB_TAG('L','U','H',' '): /* Luyia */ return hb_language_from_string ("luy", -1); /* Luyia [macrolanguage] */ - case HB_TAG('L','V','I',' '): /* Latvian */ - return hb_language_from_string ("lv", -1); /* Latvian [macrolanguage] */ case HB_TAG('M','A','W',' '): /* Marwari */ return hb_language_from_string ("mwr", -1); /* Marwari [macrolanguage] */ - case HB_TAG('M','L','G',' '): /* Malagasy */ - return hb_language_from_string ("mg", -1); /* Malagasy [macrolanguage] */ case HB_TAG('M','L','Y',' '): /* Malay */ return hb_language_from_string ("ms", -1); /* Malay [macrolanguage] */ - case HB_TAG('M','N','G',' '): /* Mongolian */ - return hb_language_from_string ("mn", -1); /* Mongolian [macrolanguage] */ case HB_TAG('M','N','K',' '): /* Maninka */ return hb_language_from_string ("man", -1); /* Mandingo [macrolanguage] */ case HB_TAG('M','O','L',' '): /* Moldavian */ @@ -2928,26 +3154,16 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("myn", -1); /* Mayan [collection] */ case HB_TAG('N','A','H',' '): /* Nahuatl */ return hb_language_from_string ("nah", -1); /* Nahuatl [collection] */ - case HB_TAG('N','E','P',' '): /* Nepali */ - return hb_language_from_string ("ne", -1); /* Nepali [macrolanguage] */ case HB_TAG('N','I','S',' '): /* Nisi */ return hb_language_from_string ("njz", -1); /* Nyishi */ case HB_TAG('N','O','R',' '): /* Norwegian */ return hb_language_from_string ("no", -1); /* Norwegian [macrolanguage] */ - case HB_TAG('O','J','B',' '): /* Ojibway */ - return hb_language_from_string ("oj", -1); /* Ojibwa [macrolanguage] */ - case HB_TAG('O','R','O',' '): /* Oromo */ - return hb_language_from_string ("om", -1); /* Oromo [macrolanguage] */ - case HB_TAG('P','A','S',' '): /* Pashto */ - return hb_language_from_string ("ps", -1); /* Pashto [macrolanguage] */ case HB_TAG('P','G','R',' '): /* Polytonic Greek */ return hb_language_from_string ("el-polyton", -1); /* Modern Greek (1453-); Polytonic Greek */ case HB_TAG('P','R','O',' '): /* Provençal / Old Provençal */ return hb_language_from_string ("pro", -1); /* Old Provençal (to 1500) */ case HB_TAG('Q','U','H',' '): /* Quechua (Bolivia) */ return hb_language_from_string ("quh", -1); /* South Bolivian Quechua */ - case HB_TAG('Q','U','Z',' '): /* Quechua */ - return hb_language_from_string ("qu", -1); /* Quechua [macrolanguage] */ case HB_TAG('Q','V','I',' '): /* Quechua (Ecuador) */ return hb_language_from_string ("qvi", -1); /* Imbabura Highland Quichua */ case HB_TAG('Q','W','H',' '): /* Quechua (Peru) */ @@ -2958,8 +3174,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("ro", -1); /* Romanian */ case HB_TAG('R','O','Y',' '): /* Romany */ return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */ - case HB_TAG('S','Q','I',' '): /* Albanian */ - return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */ + case HB_TAG('S','G','A',' '): /* Old Irish */ + return hb_language_from_string ("sga", -1); /* Old Irish (to 900) */ case HB_TAG('S','R','B',' '): /* Serbian */ return hb_language_from_string ("sr", -1); /* Serbian */ case HB_TAG('S','X','T',' '): /* Sutu */ @@ -2976,6 +3192,10 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("tmh", -1); /* Tamashek [macrolanguage] */ case HB_TAG('T','O','D',' '): /* Todo */ return hb_language_from_string ("xwo", -1); /* Written Oirat */ + case HB_TAG('W','D','T',' '): /* Wendat */ + return hb_language_from_string ("wdt", -1); /* Wendat */ + case HB_TAG('W','Y','N',' '): /* Wyandot */ + return hb_language_from_string ("wyn", -1); /* Wyandot */ case HB_TAG('Z','H','H',' '): /* Chinese, Traditional, Hong Kong SAR */ return hb_language_from_string ("zh-HK", -1); /* Chinese [macrolanguage]; Hong Kong */ case HB_TAG('Z','H','S',' '): /* Chinese, Simplified */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc index 9f0ae3b4dc1..3cdb703203b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc @@ -547,7 +547,7 @@ hb_ot_tag_to_language (hb_tag_t tag) buf[3] = '-'; str += 4; } - snprintf (str, 16, "x-hbot-%08x", tag); + snprintf (str, 16, "x-hbot-%08" PRIx32, tag); return hb_language_from_string (&*buf, -1); } } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh index 0aaf68adb0b..e26687c34ed 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh @@ -57,7 +57,7 @@ struct avarV2Tail protected: Offset32To varIdxMap; /* Offset from the beginning of 'avar' table. */ - Offset32To varStore; /* Offset from the beginning of 'avar' table. */ + Offset32To varStore; /* Offset from the beginning of 'avar' table. */ public: DEFINE_SIZE_STATIC (8); @@ -80,7 +80,7 @@ struct AxisValueMap bool is_outside_axis_range (const Triple& axis_range) const { - float from_coord = coords[0].to_float (); + double from_coord = (double) coords[0].to_float (); return !axis_range.contains (from_coord); } @@ -100,8 +100,8 @@ struct AxisValueMap float from_coord = coords[0].to_float (); float to_coord = coords[1].to_float (); - from_coord = renormalizeValue (from_coord, unmapped_range, triple_distances); - to_coord = renormalizeValue (to_coord, axis_range, triple_distances); + from_coord = renormalizeValue ((double) from_coord, unmapped_range, triple_distances); + to_coord = renormalizeValue ((double) to_coord, axis_range, triple_distances); coords[0].set_float (from_coord); coords[1].set_float (to_coord); @@ -197,7 +197,7 @@ struct SegmentMaps : Array16Of unmapped_val.set_int (unmap (val.to_int ())); float unmapped_max = unmapped_val.to_float (); - return Triple{unmapped_min, unmapped_middle, unmapped_max}; + return Triple{(double) unmapped_min, (double) unmapped_middle, (double) unmapped_max}; } bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const @@ -230,7 +230,7 @@ struct SegmentMaps : Array16Of * duplicates here */ if (mapping.must_include ()) continue; - value_mappings.push (std::move (mapping)); + value_mappings.push (mapping); } AxisValueMap m; @@ -273,6 +273,7 @@ struct avar { TRACE_SANITIZE (this); if (!(version.sanitize (c) && + hb_barrier () && (version.major == 1 #ifndef HB_NO_AVAR2 || version.major == 2 @@ -293,6 +294,7 @@ struct avar #ifndef HB_NO_AVAR2 if (version.major < 2) return_trace (true); + hb_barrier (); const auto &v2 = * (const avarV2Tail *) map; if (unlikely (!v2.sanitize (c, this))) @@ -316,6 +318,7 @@ struct avar #ifndef HB_NO_AVAR2 if (version.major < 2) return; + hb_barrier (); for (; count < axisCount; count++) map = &StructAfter (*map); @@ -340,7 +343,7 @@ struct avar for (unsigned i = 0; i < coords_length; i++) coords[i] = out[i]; - OT::VariationStore::destroy_cache (var_store_cache); + OT::ItemVariationStore::destroy_cache (var_store_cache); #endif } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh index 271250f91c3..72deddef213 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh @@ -28,215 +28,11 @@ #include "hb-ot-layout-common.hh" #include "hb-priority-queue.hh" +#include "hb-subset-instancer-iup.hh" namespace OT { -template -struct DeltaSetIndexMapFormat01 -{ - friend struct DeltaSetIndexMap; - - unsigned get_size () const - { return min_size + mapCount * get_width (); } - - private: - DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - return_trace (c->embed (this)); - } - - template - bool serialize (hb_serialize_context_t *c, const T &plan) - { - unsigned int width = plan.get_width (); - unsigned int inner_bit_count = plan.get_inner_bit_count (); - const hb_array_t output_map = plan.get_output_map (); - - TRACE_SERIALIZE (this); - if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) - return_trace (false); - if (unlikely (!c->extend_min (this))) return_trace (false); - - entryFormat = ((width-1)<<4)|(inner_bit_count-1); - mapCount = output_map.length; - HBUINT8 *p = c->allocate_size (width * output_map.length); - if (unlikely (!p)) return_trace (false); - for (unsigned int i = 0; i < output_map.length; i++) - { - unsigned int v = output_map.arrayZ[i]; - if (v) - { - unsigned int outer = v >> 16; - unsigned int inner = v & 0xFFFF; - unsigned int u = (outer << inner_bit_count) | inner; - for (unsigned int w = width; w > 0;) - { - p[--w] = u; - u >>= 8; - } - } - p += width; - } - return_trace (true); - } - - 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; - - if (v >= mapCount) - v = mapCount - 1; - - unsigned int u = 0; - { /* Fetch it. */ - unsigned int w = get_width (); - const HBUINT8 *p = mapDataZ.arrayZ + w * v; - for (; w; w--) - u = (u << 8) + *p++; - } - - { /* Repack it. */ - unsigned int n = get_inner_bit_count (); - unsigned int outer = u >> n; - unsigned int inner = u & ((1 << n) - 1); - u = (outer<<16) | inner; - } - - return u; - } - - unsigned get_map_count () const { return mapCount; } - unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } - unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } - - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - c->check_range (mapDataZ.arrayZ, - mapCount, - get_width ())); - } - - protected: - HBUINT8 format; /* Format identifier--format = 0 */ - HBUINT8 entryFormat; /* A packed field that describes the compressed - * representation of delta-set indices. */ - MapCountT mapCount; /* The number of mapping entries. */ - UnsizedArrayOf - mapDataZ; /* The delta-set index mapping data. */ - - public: - DEFINE_SIZE_ARRAY (2+MapCountT::static_size, mapDataZ); -}; - -struct DeltaSetIndexMap -{ - template - bool serialize (hb_serialize_context_t *c, const T &plan) - { - TRACE_SERIALIZE (this); - unsigned length = plan.get_output_map ().length; - u.format = length <= 0xFFFF ? 0 : 1; - switch (u.format) { - case 0: return_trace (u.format0.serialize (c, plan)); - case 1: return_trace (u.format1.serialize (c, plan)); - default:return_trace (false); - } - } - - uint32_t map (unsigned v) const - { - switch (u.format) { - case 0: return (u.format0.map (v)); - case 1: return (u.format1.map (v)); - default:return v; - } - } - - unsigned get_map_count () const - { - switch (u.format) { - case 0: return u.format0.get_map_count (); - case 1: return u.format1.get_map_count (); - default:return 0; - } - } - - unsigned get_width () const - { - switch (u.format) { - case 0: return u.format0.get_width (); - case 1: return u.format1.get_width (); - default:return 0; - } - } - - unsigned get_inner_bit_count () const - { - switch (u.format) { - case 0: return u.format0.get_inner_bit_count (); - case 1: return u.format1.get_inner_bit_count (); - default:return 0; - } - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) { - case 0: return_trace (u.format0.sanitize (c)); - case 1: return_trace (u.format1.sanitize (c)); - default:return_trace (true); - } - } - - DeltaSetIndexMap* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - switch (u.format) { - case 0: return_trace (reinterpret_cast (u.format0.copy (c))); - case 1: return_trace (reinterpret_cast (u.format1.copy (c))); - default:return_trace (nullptr); - } - } - - protected: - union { - HBUINT8 format; /* Format identifier */ - DeltaSetIndexMapFormat01 format0; - DeltaSetIndexMapFormat01 format1; - } u; - public: - DEFINE_SIZE_UNION (1, format); -}; - - -struct VarStoreInstancer -{ - VarStoreInstancer (const VariationStore *varStore, - const DeltaSetIndexMap *varIdxMap, - hb_array_t coords) : - varStore (varStore), varIdxMap (varIdxMap), coords (coords) {} - - operator bool () const { return varStore && bool (coords); } - - /* according to the spec, if colr table has varStore but does not have - * varIdxMap, then an implicit identity mapping is used */ - float operator() (uint32_t varIdx, unsigned short offset = 0) const - { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; } - - const VariationStore *varStore; - const DeltaSetIndexMap *varIdxMap; - hb_array_t coords; -}; /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ struct TupleVariationHeader @@ -296,15 +92,15 @@ struct TupleVariationHeader start = hb_min (peak, 0.f); end = hb_max (peak, 0.f); } - axis_tuples.set (*axis_tag, Triple (start, peak, end)); + axis_tuples.set (*axis_tag, Triple ((double) start, (double) peak, (double) end)); } return true; } - float 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 + 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 { const F2DOT14 *peak_tuple; @@ -318,13 +114,13 @@ struct TupleVariationHeader { unsigned int index = get_index (); if (unlikely ((index + 1) * coord_count > shared_tuples.length)) - return 0.f; + return 0.0; peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ; if (shared_tuple_active_idx) { if (unlikely (index >= shared_tuple_active_idx->length)) - return 0.f; + return 0.0; auto _ = (*shared_tuple_active_idx).arrayZ[index]; if (_.second != -1) { @@ -349,7 +145,7 @@ struct TupleVariationHeader end_tuple = get_end_tuple (coord_count).arrayZ; } - float scalar = 1.f; + double scalar = 1.0; for (unsigned int i = start_idx; i < end_idx; i += step) { int peak = peak_tuple[i].to_int (); @@ -364,15 +160,15 @@ 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.f; + if (v < start || v > end) return 0.0; if (v < peak) - { if (peak != start) scalar *= (float) (v - start) / (peak - start); } + { if (peak != start) scalar *= (double) (v - start) / (peak - start); } else - { if (peak != end) scalar *= (float) (end - v) / (end - peak); } + { if (peak != end) scalar *= (double) (end - v) / (end - peak); } } - else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.f; + else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.0; else - scalar *= (float) v / peak; + scalar *= (double) v / peak; } return scalar; } @@ -425,15 +221,10 @@ struct TupleVariationHeader DEFINE_SIZE_MIN (4); }; -enum packed_delta_flag_t -{ - DELTAS_ARE_ZERO = 0x80, - DELTAS_ARE_WORDS = 0x40, - DELTA_RUN_COUNT_MASK = 0x3F -}; - struct tuple_delta_t { + static constexpr bool realloc_move = true; // Watch out when adding new members! + public: hb_hashmap_t axis_tuples; @@ -447,8 +238,8 @@ struct tuple_delta_t /* compiled data: header and deltas * compiled point data is saved in a hashmap within tuple_variations_t cause * some point sets might be reused by different tuple variations */ - hb_vector_t compiled_tuple_header; - hb_vector_t compiled_deltas; + hb_vector_t compiled_tuple_header; + hb_vector_t compiled_deltas; /* compiled peak coords, empty for non-gvar tuples */ hb_vector_t compiled_peak_coords; @@ -456,7 +247,7 @@ struct tuple_delta_t tuple_delta_t () = default; tuple_delta_t (const tuple_delta_t& o) = default; - friend void swap (tuple_delta_t& a, tuple_delta_t& b) + friend void swap (tuple_delta_t& a, tuple_delta_t& b) noexcept { hb_swap (a.axis_tuples, b.axis_tuples); hb_swap (a.indices, b.indices); @@ -467,10 +258,10 @@ struct tuple_delta_t hb_swap (a.compiled_peak_coords, b.compiled_peak_coords); } - tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + tuple_delta_t (tuple_delta_t&& o) noexcept : tuple_delta_t () { hb_swap (*this, o); } - tuple_delta_t& operator = (tuple_delta_t&& o) + tuple_delta_t& operator = (tuple_delta_t&& o) noexcept { hb_swap (*this, o); return *this; @@ -514,14 +305,19 @@ struct tuple_delta_t return *this; unsigned num = indices.length; - for (unsigned i = 0; i < num; i++) - { - if (!indices.arrayZ[i]) continue; - - deltas_x[i] *= scalar; - if (deltas_y) + if (deltas_y) + for (unsigned i = 0; i < num; i++) + { + if (!indices.arrayZ[i]) continue; + deltas_x[i] *= scalar; deltas_y[i] *= scalar; - } + } + else + for (unsigned i = 0; i < num; i++) + { + if (!indices.arrayZ[i]) continue; + deltas_x[i] *= scalar; + } return *this; } @@ -536,18 +332,18 @@ struct tuple_delta_t return out; } - if ((tent->minimum < 0.f && tent->maximum > 0.f) || + if ((tent->minimum < 0.0 && tent->maximum > 0.0) || !(tent->minimum <= tent->middle && tent->middle <= tent->maximum)) return out; - if (tent->middle == 0.f) + if (tent->middle == 0.0) { out.push (*this); return out; } - result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances); - for (auto t : solutions) + rebase_tent_result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances); + for (auto &t : solutions) { tuple_delta_t new_var = *this; if (t.second == Triple ()) @@ -600,7 +396,9 @@ struct tuple_delta_t const hb_map_t& axes_old_index_tag_map, const hb_hashmap_t*, unsigned>* shared_tuples_idx_map) { - if (!compiled_deltas) return false; + /* compiled_deltas could be empty after iup delta optimization, we can skip + * compiling this tuple and return true */ + if (!compiled_deltas) return true; unsigned cur_axis_count = axes_index_map.get_population (); /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ @@ -714,37 +512,42 @@ struct tuple_delta_t } bool compile_deltas () + { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } + + static bool compile_deltas (hb_array_t point_indices, + hb_array_t x_deltas, + hb_array_t y_deltas, + hb_vector_t &compiled_deltas /* OUT */) { hb_vector_t rounded_deltas; - if (unlikely (!rounded_deltas.alloc (indices.length))) + if (unlikely (!rounded_deltas.alloc (point_indices.length))) return false; - for (unsigned i = 0; i < indices.length; i++) + for (unsigned i = 0; i < point_indices.length; i++) { - if (!indices[i]) continue; - int rounded_delta = (int) roundf (deltas_x[i]); + if (!point_indices[i]) continue; + int rounded_delta = (int) roundf (x_deltas.arrayZ[i]); rounded_deltas.push (rounded_delta); } - if (!rounded_deltas) return false; - /* allocate enough memories 3 * num_deltas */ - unsigned alloc_len = 3 * rounded_deltas.length; - if (deltas_y) + if (!rounded_deltas) return true; + /* allocate enough memories 5 * num_deltas */ + unsigned alloc_len = 5 * rounded_deltas.length; + if (y_deltas) alloc_len *= 2; if (unlikely (!compiled_deltas.resize (alloc_len))) return false; - unsigned i = 0; - unsigned encoded_len = encode_delta_run (i, compiled_deltas.as_array (), rounded_deltas); + unsigned encoded_len = compile_deltas (compiled_deltas, rounded_deltas); - if (deltas_y) + if (y_deltas) { - /* reuse the rounded_deltas vector, check that deltas_y have the same num of deltas as deltas_x */ + /* reuse the rounded_deltas vector, check that y_deltas have the same num of deltas as x_deltas */ unsigned j = 0; - for (unsigned idx = 0; idx < indices.length; idx++) + for (unsigned idx = 0; idx < point_indices.length; idx++) { - if (!indices[idx]) continue; - int rounded_delta = (int) roundf (deltas_y[idx]); + if (!point_indices[idx]) continue; + int rounded_delta = (int) roundf (y_deltas.arrayZ[idx]); if (j >= rounded_deltas.length) return false; @@ -752,174 +555,15 @@ struct tuple_delta_t } if (j != rounded_deltas.length) return false; - /* reset i because we reuse rounded_deltas for deltas_y */ - i = 0; - encoded_len += encode_delta_run (i, compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); + encoded_len += compile_deltas (compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); } return compiled_deltas.resize (encoded_len); } - unsigned encode_delta_run (unsigned& i, - hb_array_t encoded_bytes, - const hb_vector_t& deltas) const - { - unsigned num_deltas = deltas.length; - unsigned encoded_len = 0; - while (i < num_deltas) - { - int val = deltas[i]; - if (val == 0) - encoded_len += encode_delta_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), deltas); - else if (val >= -128 && val <= 127) - encoded_len += encode_delta_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), deltas); - else - encoded_len += encode_delta_run_as_words (i, encoded_bytes.sub_array (encoded_len), deltas); - } - return encoded_len; - } - - unsigned encode_delta_run_as_zeroes (unsigned& i, - hb_array_t encoded_bytes, - const hb_vector_t& deltas) const - { - unsigned num_deltas = deltas.length; - unsigned run_length = 0; - auto it = encoded_bytes.iter (); - unsigned encoded_len = 0; - while (i < num_deltas && deltas[i] == 0) - { - i++; - run_length++; - } - - while (run_length >= 64) - { - *it++ = char (DELTAS_ARE_ZERO | 63); - run_length -= 64; - encoded_len++; - } - - if (run_length) - { - *it++ = char (DELTAS_ARE_ZERO | (run_length - 1)); - encoded_len++; - } - return encoded_len; - } - - unsigned encode_delta_run_as_bytes (unsigned &i, - hb_array_t encoded_bytes, - const hb_vector_t& deltas) const - { - unsigned start = i; - unsigned num_deltas = deltas.length; - while (i < num_deltas) - { - int val = deltas[i]; - if (val > 127 || val < -128) - break; - - /* from fonttools: if there're 2 or more zeros in a sequence, - * it is better to start a new run to save bytes. */ - if (val == 0 && i + 1 < num_deltas && deltas[i+1] == 0) - break; - - i++; - } - unsigned run_length = i - start; - - unsigned encoded_len = 0; - auto it = encoded_bytes.iter (); - - while (run_length >= 64) - { - *it++ = 63; - encoded_len++; - - for (unsigned j = 0; j < 64; j++) - { - *it++ = static_cast (deltas[start + j]); - encoded_len++; - } - - start += 64; - run_length -= 64; - } - - if (run_length) - { - *it++ = run_length - 1; - encoded_len++; - - while (start < i) - { - *it++ = static_cast (deltas[start++]); - encoded_len++; - } - } - - return encoded_len; - } - - unsigned encode_delta_run_as_words (unsigned &i, - hb_array_t encoded_bytes, - const hb_vector_t& deltas) const + static unsigned compile_deltas (hb_array_t encoded_bytes, + hb_array_t deltas) { - unsigned start = i; - unsigned num_deltas = deltas.length; - while (i < num_deltas) - { - int val = deltas[i]; - - /* start a new run for a single zero value*/ - if (val == 0) break; - - /* from fonttools: continue word-encoded run if there's only one - * single value in the range [-128, 127] because it is more compact. - * Only start a new run when there're 2 continuous such values. */ - if (val >= -128 && val <= 127 && - i + 1 < num_deltas && - deltas[i+1] >= -128 && deltas[i+1] <= 127) - break; - - i++; - } - - unsigned run_length = i - start; - auto it = encoded_bytes.iter (); - unsigned encoded_len = 0; - while (run_length >= 64) - { - *it++ = (DELTAS_ARE_WORDS | 63); - encoded_len++; - - for (unsigned j = 0; j < 64; j++) - { - int16_t delta_val = deltas[start + j]; - *it++ = static_cast (delta_val >> 8); - *it++ = static_cast (delta_val & 0xFF); - - encoded_len += 2; - } - - start += 64; - run_length -= 64; - } - - if (run_length) - { - *it++ = (DELTAS_ARE_WORDS | (run_length - 1)); - encoded_len++; - while (start < i) - { - int16_t delta_val = deltas[start++]; - *it++ = static_cast (delta_val >> 8); - *it++ = static_cast (delta_val & 0xFF); - - encoded_len += 2; - } - } - return encoded_len; + return TupleValues::compile (deltas, encoded_bytes); } bool calc_inferred_deltas (const contour_point_vector_t& orig_points) @@ -982,10 +626,14 @@ struct tuple_delta_t { i = next_index (i, start_point, end_point); if (i == next) break; - deltas_x.arrayZ[i] = infer_delta (orig_points.arrayZ[i].x, orig_points.arrayZ[prev].x, orig_points.arrayZ[next].x, - deltas_x.arrayZ[prev], deltas_x.arrayZ[next]); - deltas_y.arrayZ[i] = infer_delta (orig_points.arrayZ[i].y, orig_points.arrayZ[prev].y, orig_points.arrayZ[next].y, - deltas_y.arrayZ[prev], deltas_y.arrayZ[next]); + deltas_x.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].x, + (double) orig_points.arrayZ[prev].x, + (double) orig_points.arrayZ[next].x, + (double) deltas_x.arrayZ[prev], (double) deltas_x.arrayZ[next]); + deltas_y.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].y, + (double) orig_points.arrayZ[prev].y, + (double) orig_points.arrayZ[next].y, + (double) deltas_y.arrayZ[prev], (double) deltas_y.arrayZ[next]); inferred_idxes.add (i); if (--unref_count == 0) goto no_more_gaps; } @@ -1002,8 +650,8 @@ struct tuple_delta_t { if (!inferred_idxes.has (i)) { - deltas_x.arrayZ[i] = 0.f; - deltas_y.arrayZ[i] = 0.f; + deltas_x.arrayZ[i] = 0.0; + deltas_y.arrayZ[i] = 0.0; } indices[i] = true; } @@ -1011,16 +659,181 @@ struct tuple_delta_t return true; } - static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta) + bool optimize (const contour_point_vector_t& contour_points, + bool is_composite, + double tolerance = 0.5 + 1e-10) + { + unsigned count = contour_points.length; + if (deltas_x.length != count || + deltas_y.length != count) + return false; + + hb_vector_t opt_indices; + hb_vector_t rounded_x_deltas, rounded_y_deltas; + + if (unlikely (!rounded_x_deltas.alloc (count) || + !rounded_y_deltas.alloc (count))) + return false; + + for (unsigned i = 0; i < count; i++) + { + int rounded_x_delta = (int) roundf (deltas_x.arrayZ[i]); + int rounded_y_delta = (int) roundf (deltas_y.arrayZ[i]); + rounded_x_deltas.push (rounded_x_delta); + rounded_y_deltas.push (rounded_y_delta); + } + + if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, tolerance)) + return false; + + unsigned ref_count = 0; + for (bool ref_flag : opt_indices) + ref_count += ref_flag; + + if (ref_count == count) return true; + + hb_vector_t opt_deltas_x, opt_deltas_y; + bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); + if (is_comp_glyph_wo_deltas) + { + if (unlikely (!opt_deltas_x.resize (count) || + !opt_deltas_y.resize (count))) + return false; + + opt_indices.arrayZ[0] = true; + for (unsigned i = 1; i < count; i++) + opt_indices.arrayZ[i] = false; + } + + hb_vector_t opt_point_data; + if (!compile_point_set (opt_indices, opt_point_data)) + return false; + hb_vector_t opt_deltas_data; + if (!compile_deltas (opt_indices, + is_comp_glyph_wo_deltas ? opt_deltas_x : deltas_x, + is_comp_glyph_wo_deltas ? opt_deltas_y : deltas_y, + opt_deltas_data)) + return false; + + hb_vector_t point_data; + if (!compile_point_set (indices, point_data)) + return false; + hb_vector_t deltas_data; + if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data)) + return false; + + if (opt_point_data.length + opt_deltas_data.length < point_data.length + deltas_data.length) + { + indices.fini (); + indices = std::move (opt_indices); + + if (is_comp_glyph_wo_deltas) + { + deltas_x.fini (); + deltas_x = std::move (opt_deltas_x); + + deltas_y.fini (); + deltas_y = std::move (opt_deltas_y); + } + } + return !indices.in_error () && !deltas_x.in_error () && !deltas_y.in_error (); + } + + static bool compile_point_set (const hb_vector_t &point_indices, + hb_vector_t& compiled_points /* OUT */) + { + unsigned num_points = 0; + for (bool i : point_indices) + if (i) num_points++; + + /* when iup optimization is enabled, num of referenced points could be 0 */ + if (!num_points) return true; + + unsigned indices_length = point_indices.length; + /* If the points set consists of all points in the glyph, it's encoded with a + * single zero byte */ + if (num_points == indices_length) + return compiled_points.resize (1); + + /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ + unsigned num_bytes = 2 + 3 *num_points; + if (unlikely (!compiled_points.resize (num_bytes, false))) + return false; + + unsigned pos = 0; + /* binary data starts with the total number of reference points */ + if (num_points < 0x80) + compiled_points.arrayZ[pos++] = num_points; + else + { + compiled_points.arrayZ[pos++] = ((num_points >> 8) | 0x80); + compiled_points.arrayZ[pos++] = num_points & 0xFF; + } + + const unsigned max_run_length = 0x7F; + unsigned i = 0; + unsigned last_value = 0; + unsigned num_encoded = 0; + while (i < indices_length && num_encoded < num_points) + { + unsigned run_length = 0; + unsigned header_pos = pos; + compiled_points.arrayZ[pos++] = 0; + + bool use_byte_encoding = false; + bool new_run = true; + while (i < indices_length && num_encoded < num_points && + run_length <= max_run_length) + { + // find out next referenced point index + while (i < indices_length && !point_indices[i]) + i++; + + if (i >= indices_length) break; + + unsigned cur_value = i; + unsigned delta = cur_value - last_value; + + if (new_run) + { + use_byte_encoding = (delta <= 0xFF); + new_run = false; + } + + if (use_byte_encoding && delta > 0xFF) + break; + + if (use_byte_encoding) + compiled_points.arrayZ[pos++] = delta; + else + { + compiled_points.arrayZ[pos++] = delta >> 8; + compiled_points.arrayZ[pos++] = delta & 0xFF; + } + i++; + last_value = cur_value; + run_length++; + num_encoded++; + } + + if (use_byte_encoding) + compiled_points.arrayZ[header_pos] = run_length - 1; + else + compiled_points.arrayZ[header_pos] = (run_length - 1) | 0x80; + } + return compiled_points.resize (pos, false); + } + + static double infer_delta (double target_val, double prev_val, double next_val, double prev_delta, double next_delta) { if (prev_val == next_val) - return (prev_delta == next_delta) ? prev_delta : 0.f; + return (prev_delta == next_delta) ? prev_delta : 0.0; else if (target_val <= hb_min (prev_val, next_val)) return (prev_val < next_val) ? prev_delta : next_delta; else if (target_val >= hb_max (prev_val, next_val)) return (prev_val > next_val) ? prev_delta : next_delta; - float r = (target_val - prev_val) / (next_val - prev_val); + double r = (target_val - prev_val) / (next_val - prev_val); return prev_delta + r * (next_delta - prev_delta); } @@ -1028,6 +841,7 @@ struct tuple_delta_t { return (i >= end) ? start : (i + 1); } }; +template struct TupleVariationData { bool sanitize (hb_sanitize_context_t *c) const @@ -1062,19 +876,22 @@ struct TupleVariationData private: /* referenced point set->compiled point data map */ - hb_hashmap_t*, hb_bytes_t> point_data_map; + hb_hashmap_t*, hb_vector_t> point_data_map; /* referenced point set-> count map, used in finding shared points */ hb_hashmap_t*, unsigned> point_set_count_map; /* empty for non-gvar tuples. - * shared_points_bytes is just a copy of some value in the point_data_map, + * shared_points_bytes is a pointer to some value in the point_data_map, * which will be freed during map destruction. Save it for serialization, so * no need to do find_shared_points () again */ - hb_bytes_t shared_points_bytes; + hb_vector_t *shared_points_bytes = nullptr; - /* total compiled byte size as TupleVariationData format, initialized to its - * min_size: 4 */ - unsigned compiled_byte_size = 4; + /* total compiled byte size as TupleVariationData format, initialized to 0 */ + unsigned compiled_byte_size = 0; + bool needs_padding = false; + + /* for gvar iup delta optimization: whether this is a composite glyph */ + bool is_composite = false; public: tuple_variations_t () = default; @@ -1082,21 +899,18 @@ struct TupleVariationData tuple_variations_t& operator=(const tuple_variations_t&) = delete; tuple_variations_t (tuple_variations_t&&) = default; tuple_variations_t& operator=(tuple_variations_t&&) = default; - ~tuple_variations_t () { fini (); } - void fini () - { - for (auto _ : point_data_map.values ()) - _.fini (); - - point_set_count_map.fini (); - tuple_vars.fini (); - } + ~tuple_variations_t () = default; explicit operator bool () const { return bool (tuple_vars); } unsigned get_var_count () const { - unsigned count = tuple_vars.length; - if (shared_points_bytes.length) + unsigned count = 0; + /* when iup delta opt is enabled, compiled_deltas could be empty and we + * should skip this tuple */ + for (auto& tuple: tuple_vars) + if (tuple.compiled_deltas) count++; + + if (shared_points_bytes && shared_points_bytes->length) count |= TupleVarCount::SharedPointNumbers; return count; } @@ -1110,26 +924,27 @@ struct TupleVariationData bool is_gvar, const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, - const hb_array_t shared_tuples) + const hb_array_t shared_tuples, + bool is_composite_glyph) { do { const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); if (unlikely (!iterator.var_data_bytes.check_range (p, length))) - { fini (); return false; } + return false; hb_hashmap_t axis_tuples; if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples) || axis_tuples.is_empty ()) - { fini (); return false; } + return false; hb_vector_t private_indices; bool has_private_points = iterator.current_tuple->has_private_points (); const HBUINT8 *end = p + length; if (has_private_points && - !TupleVariationData::unpack_points (p, private_indices, end)) - { fini (); return false; } + !TupleVariationData::decompile_points (p, private_indices, end)) + return false; const hb_vector_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); @@ -1138,43 +953,46 @@ struct TupleVariationData hb_vector_t deltas_x; if (unlikely (!deltas_x.resize (num_deltas, false) || - !TupleVariationData::unpack_deltas (p, deltas_x, end))) - { fini (); return false; } + !TupleVariationData::decompile_deltas (p, deltas_x, end))) + return false; hb_vector_t deltas_y; if (is_gvar) { if (unlikely (!deltas_y.resize (num_deltas, false) || - !TupleVariationData::unpack_deltas (p, deltas_y, end))) - { fini (); return false; } + !TupleVariationData::decompile_deltas (p, deltas_y, end))) + return false; } tuple_delta_t var; var.axis_tuples = std::move (axis_tuples); if (unlikely (!var.indices.resize (point_count) || !var.deltas_x.resize (point_count, false))) - { fini (); return false; } + return false; if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) - { fini (); return false; } + return false; for (unsigned i = 0; i < num_deltas; i++) { unsigned idx = apply_to_all ? i : indices[i]; if (idx >= point_count) continue; var.indices[idx] = true; - var.deltas_x[idx] = static_cast (deltas_x[i]); + var.deltas_x[idx] = deltas_x[i]; if (is_gvar) - var.deltas_y[idx] = static_cast (deltas_y[i]); + var.deltas_y[idx] = deltas_y[i]; } tuple_vars.push (std::move (var)); } while (iterator.move_to_next ()); + + is_composite = is_composite_glyph; return true; } bool create_from_item_var_data (const VarData &var_data, const hb_vector_t>& regions, const hb_map_t& axes_old_index_tag_map, + unsigned& item_count, const hb_inc_bimap_t* inner_map = nullptr) { /* NULL offset, to keep original varidx valid, just return */ @@ -1184,7 +1002,8 @@ struct TupleVariationData unsigned num_regions = var_data.get_region_index_count (); if (!tuple_vars.alloc (num_regions)) return false; - unsigned item_count = inner_map ? inner_map->get_population () : var_data.get_item_count (); + item_count = inner_map ? inner_map->get_population () : var_data.get_item_count (); + if (!item_count) return true; unsigned row_size = var_data.get_row_size (); const HBUINT8 *delta_bytes = var_data.get_delta_bytes (); @@ -1237,7 +1056,7 @@ struct TupleVariationData Triple *axis_limit; if (!normalized_axes_location.has (axis_tag, &axis_limit)) return false; - TripleDistances axis_triple_distances{1.f, 1.f}; + TripleDistances axis_triple_distances{1.0, 1.0}; if (axes_triple_distances.has (axis_tag)) axis_triple_distances = axes_triple_distances.get (axis_tag); @@ -1250,7 +1069,7 @@ struct TupleVariationData unsigned new_len = new_vars.length + out.length; if (unlikely (!new_vars.alloc (new_len, false))) - { fini (); return false;} + return false; for (unsigned i = 0; i < out.length; i++) new_vars.push (std::move (out[i])); @@ -1261,8 +1080,9 @@ struct TupleVariationData return true; } - /* merge tuple variations with overlapping tents */ - void merge_tuple_variations () + /* merge tuple variations with overlapping tents, if iup delta optimization + * is enabled, add default deltas to contour_points */ + bool merge_tuple_variations (contour_point_vector_t* contour_points = nullptr) { hb_vector_t new_vars; hb_hashmap_t*, unsigned> m; @@ -1270,7 +1090,15 @@ struct TupleVariationData for (const tuple_delta_t& var : tuple_vars) { /* if all axes are pinned, drop the tuple variation */ - if (var.axis_tuples.is_empty ()) continue; + if (var.axis_tuples.is_empty ()) + { + /* if iup_delta_optimize is enabled, add deltas to contour coords */ + if (contour_points && !contour_points->add_deltas (var.deltas_x, + var.deltas_y, + var.indices)) + return false; + continue; + } unsigned *idx; if (m.has (&(var.axis_tuples), &idx)) @@ -1280,98 +1108,14 @@ struct TupleVariationData else { new_vars.push (var); - m.set (&(var.axis_tuples), i); + if (!m.set (&(var.axis_tuples), i)) + return false; i++; } } tuple_vars.fini (); tuple_vars = std::move (new_vars); - } - - hb_bytes_t compile_point_set (const hb_vector_t &point_indices) - { - unsigned num_points = 0; - for (bool i : point_indices) - if (i) num_points++; - - unsigned indices_length = point_indices.length; - /* If the points set consists of all points in the glyph, it's encoded with a - * single zero byte */ - if (num_points == indices_length) - { - char *p = (char *) hb_calloc (1, sizeof (char)); - if (unlikely (!p)) return hb_bytes_t (); - - return hb_bytes_t (p, 1); - } - - /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ - unsigned num_bytes = 2 + 3 *num_points; - char *p = (char *) hb_calloc (num_bytes, sizeof (char)); - if (unlikely (!p)) return hb_bytes_t (); - - unsigned pos = 0; - /* binary data starts with the total number of reference points */ - if (num_points < 0x80) - p[pos++] = num_points; - else - { - p[pos++] = ((num_points >> 8) | 0x80); - p[pos++] = num_points & 0xFF; - } - - const unsigned max_run_length = 0x7F; - unsigned i = 0; - unsigned last_value = 0; - unsigned num_encoded = 0; - while (i < indices_length && num_encoded < num_points) - { - unsigned run_length = 0; - unsigned header_pos = pos; - p[pos++] = 0; - - bool use_byte_encoding = false; - bool new_run = true; - while (i < indices_length && num_encoded < num_points && - run_length <= max_run_length) - { - // find out next referenced point index - while (i < indices_length && !point_indices[i]) - i++; - - if (i >= indices_length) break; - - unsigned cur_value = i; - unsigned delta = cur_value - last_value; - - if (new_run) - { - use_byte_encoding = (delta <= 0xFF); - new_run = false; - } - - if (use_byte_encoding && delta > 0xFF) - break; - - if (use_byte_encoding) - p[pos++] = delta; - else - { - p[pos++] = delta >> 8; - p[pos++] = delta & 0xFF; - } - i++; - last_value = cur_value; - run_length++; - num_encoded++; - } - - if (use_byte_encoding) - p[header_pos] = run_length - 1; - else - p[header_pos] = (run_length - 1) | 0x80; - } - return hb_bytes_t (p, pos); + return true; } /* compile all point set and store byte data in a point_set->hb_bytes_t hashmap, @@ -1391,11 +1135,11 @@ struct TupleVariationData continue; } - hb_bytes_t compiled_data = compile_point_set (*points_set); - if (unlikely (compiled_data == hb_bytes_t ())) + hb_vector_t compiled_point_data; + if (!tuple_delta_t::compile_point_set (*points_set, compiled_point_data)) return false; - if (!point_data_map.set (points_set, compiled_data) || + if (!point_data_map.set (points_set, std::move (compiled_point_data)) || !point_set_count_map.set (points_set, 1)) return false; } @@ -1403,31 +1147,33 @@ struct TupleVariationData } /* find shared points set which saves most bytes */ - hb_bytes_t find_shared_points () + void find_shared_points () { unsigned max_saved_bytes = 0; - hb_bytes_t res{}; - for (const auto& _ : point_data_map.iter ()) + for (const auto& _ : point_data_map.iter_ref ()) { const hb_vector_t* points_set = _.first; unsigned data_length = _.second.length; + if (!data_length) continue; unsigned *count; if (unlikely (!point_set_count_map.has (points_set, &count) || *count <= 1)) - return hb_bytes_t (); + { + shared_points_bytes = nullptr; + return; + } unsigned saved_bytes = data_length * ((*count) -1); if (saved_bytes > max_saved_bytes) { max_saved_bytes = saved_bytes; - res = _.second; + shared_points_bytes = &(_.second); } } - return res; } - bool calc_inferred_deltas (contour_point_vector_t& contour_points) + bool calc_inferred_deltas (const contour_point_vector_t& contour_points) { for (tuple_delta_t& var : tuple_vars) if (!var.calc_inferred_deltas (contour_points)) @@ -1436,10 +1182,21 @@ struct TupleVariationData return true; } + bool iup_optimize (const contour_point_vector_t& contour_points) + { + for (tuple_delta_t& var : tuple_vars) + { + if (!var.optimize (contour_points, is_composite)) + return false; + } + return true; + } + public: bool instantiate (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances, - contour_point_vector_t* contour_points = nullptr) + contour_point_vector_t* contour_points = nullptr, + bool optimize = false) { if (!tuple_vars) return true; if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) @@ -1449,41 +1206,70 @@ struct TupleVariationData if (!calc_inferred_deltas (*contour_points)) return false; - merge_tuple_variations (); + /* if iup delta opt is on, contour_points can't be null */ + if (optimize && !contour_points) + return false; + + if (!merge_tuple_variations (optimize ? contour_points : nullptr)) + return false; + + if (optimize && !iup_optimize (*contour_points)) return false; return !tuple_vars.in_error (); } bool compile_bytes (const hb_map_t& axes_index_map, const hb_map_t& axes_old_index_tag_map, bool use_shared_points, + bool is_gvar = false, const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr) { + // return true for empty glyph + if (!tuple_vars) + return true; + // compile points set and store data in hashmap if (!compile_all_point_sets ()) return false; + /* total compiled byte size as TupleVariationData format, initialized to its + * min_size: 4 */ + compiled_byte_size += 4; + if (use_shared_points) { - shared_points_bytes = find_shared_points (); - compiled_byte_size += shared_points_bytes.length; + find_shared_points (); + if (shared_points_bytes) + compiled_byte_size += shared_points_bytes->length; } // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { const hb_vector_t* points_set = &(tuple.indices); - hb_bytes_t *points_data; + hb_vector_t *points_data; if (unlikely (!point_data_map.has (points_set, &points_data))) return false; + /* when iup optimization is enabled, num of referenced points could be 0 + * and thus the compiled points bytes is empty, we should skip compiling + * this tuple */ + if (!points_data->length) + continue; if (!tuple.compile_deltas ()) return false; - unsigned points_data_length = (*points_data != shared_points_bytes) ? points_data->length : 0; + unsigned points_data_length = (points_data != shared_points_bytes) ? points_data->length : 0; if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, shared_tuples_idx_map)) return false; compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length; } + + if (is_gvar && (compiled_byte_size % 2)) + { + needs_padding = true; + compiled_byte_size += 1; + } + return true; } @@ -1502,25 +1288,31 @@ struct TupleVariationData bool serialize_var_data (hb_serialize_context_t *c, bool is_gvar) const { TRACE_SERIALIZE (this); - if (is_gvar) - shared_points_bytes.copy (c); + if (is_gvar && shared_points_bytes) + { + hb_ubytes_t s (shared_points_bytes->arrayZ, shared_points_bytes->length); + s.copy (c); + } for (const auto& tuple: tuple_vars) { const hb_vector_t* points_set = &(tuple.indices); - hb_bytes_t *point_data; + hb_vector_t *point_data; if (!point_data_map.has (points_set, &point_data)) return_trace (false); - if (!is_gvar || *point_data != shared_points_bytes) - point_data->copy (c); + if (!is_gvar || point_data != shared_points_bytes) + { + hb_ubytes_t s (point_data->arrayZ, point_data->length); + s.copy (c); + } tuple.compiled_deltas.as_array ().copy (c); if (c->in_error ()) return_trace (false); } /* padding for gvar */ - if (is_gvar && (compiled_byte_size % 2)) + if (is_gvar && needs_padding) { HBUINT8 pad; pad = 0; @@ -1551,7 +1343,7 @@ struct TupleVariationData { const HBUINT8 *base = &(table_base+var_data->data); const HBUINT8 *p = base; - if (!unpack_points (p, shared_indices, (const HBUINT8 *) (var_data_bytes.arrayZ + var_data_bytes.length))) return false; + if (!decompile_points (p, shared_indices, (const HBUINT8 *) (var_data_bytes.arrayZ + var_data_bytes.length))) return false; data_offset = p - base; } return true; @@ -1601,9 +1393,9 @@ struct TupleVariationData bool has_shared_point_numbers () const { return tupleVarCount.has_shared_point_numbers (); } - static bool unpack_points (const HBUINT8 *&p /* IN/OUT */, - hb_vector_t &points /* OUT */, - const HBUINT8 *end) + static bool decompile_points (const HBUINT8 *&p /* IN/OUT */, + hb_vector_t &points /* OUT */, + const HBUINT8 *end) { enum packed_point_flag_t { @@ -1653,43 +1445,13 @@ struct TupleVariationData return true; } - static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */, - hb_vector_t &deltas /* IN/OUT */, - const HBUINT8 *end) + template + static bool decompile_deltas (const HBUINT8 *&p /* IN/OUT */, + hb_vector_t &deltas /* IN/OUT */, + const HBUINT8 *end, + bool consume_all = false) { - unsigned i = 0; - unsigned count = deltas.length; - while (i < count) - { - if (unlikely (p + 1 > end)) return false; - unsigned control = *p++; - unsigned run_count = (control & DELTA_RUN_COUNT_MASK) + 1; - unsigned stop = i + run_count; - if (unlikely (stop > count)) return false; - if (control & DELTAS_ARE_ZERO) - { - for (; i < stop; i++) - deltas.arrayZ[i] = 0; - } - else if (control & DELTAS_ARE_WORDS) - { - if (unlikely (p + run_count * HBUINT16::static_size > end)) return false; - for (; i < stop; i++) - { - deltas.arrayZ[i] = * (const HBINT16 *) p; - p += HBUINT16::static_size; - } - } - else - { - if (unlikely (p + run_count > end)) return false; - for (; i < stop; i++) - { - deltas.arrayZ[i] = * (const HBINT8 *) p++; - } - } - } - return true; + return TupleValues::decompile (p, deltas, end, consume_all); } bool has_data () const { return tupleVarCount; } @@ -1700,13 +1462,15 @@ struct TupleVariationData const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, const hb_array_t shared_tuples, - tuple_variations_t& tuple_variations /* OUT */) const + tuple_variations_t& tuple_variations, /* OUT */ + bool is_composite_glyph = false) const { return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, point_count, is_gvar, axes_old_index_tag_map, shared_indices, - shared_tuples); + shared_tuples, + is_composite_glyph); } bool serialize (hb_serialize_context_t *c, @@ -1758,15 +1522,16 @@ struct TupleVariationData * low 12 bits are the number of tuple variation tables * for this glyph. The number of tuple variation tables * can be any number between 1 and 4095. */ - Offset16To + OffsetTo data; /* Offset from the start of the base table * to the serialized data. */ /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */ public: - DEFINE_SIZE_MIN (4); + DEFINE_SIZE_MIN (2 + OffType::static_size); }; -using tuple_variations_t = TupleVariationData::tuple_variations_t; +// TODO: Move tuple_variations_t to outside of TupleVariationData +using tuple_variations_t = TupleVariationData::tuple_variations_t; struct item_variations_t { using region_t = const hb_hashmap_t*; @@ -1775,6 +1540,14 @@ struct item_variations_t * have the same num of deltas (rows) */ hb_vector_t vars; + /* num of retained rows for each subtable, there're 2 cases when var_data is empty: + * 1. retained item_count is zero + * 2. regions is empty and item_count is non-zero. + * when converting to tuples, both will be dropped because the tuple is empty, + * however, we need to retain 2. as all-zero rows to keep original varidx + * valid, so we need a way to remember the num of rows for each subtable */ + hb_vector_t var_data_num_rows; + /* original region list, decompiled from item varstore, used when rebuilding * region list after instantiation */ hb_vector_t> orig_region_list; @@ -1812,7 +1585,7 @@ struct item_variations_t const hb_map_t& get_varidx_map () const { return varidx_map; } - bool instantiate (const VariationStore& varStore, + bool instantiate (const ItemVariationStore& varStore, const hb_subset_plan_t *plan, bool optimize=true, bool use_no_variation_idx=true, @@ -1826,7 +1599,7 @@ struct item_variations_t } /* keep below APIs public only for unit test: test-item-varstore */ - bool create_from_item_varstore (const VariationStore& varStore, + bool create_from_item_varstore (const ItemVariationStore& varStore, const hb_map_t& axes_old_index_tag_map, const hb_array_t inner_maps = hb_array_t ()) { @@ -1836,22 +1609,26 @@ struct item_variations_t unsigned num_var_data = varStore.get_sub_table_count (); if (inner_maps && inner_maps.length != num_var_data) return false; - if (!vars.alloc (num_var_data)) return false; + if (!vars.alloc (num_var_data) || + !var_data_num_rows.alloc (num_var_data)) return false; for (unsigned i = 0; i < num_var_data; i++) { if (inner_maps && !inner_maps.arrayZ[i].get_population ()) continue; tuple_variations_t var_data_tuples; + unsigned item_count = 0; if (!var_data_tuples.create_from_item_var_data (varStore.get_sub_table (i), orig_region_list, axes_old_index_tag_map, + item_count, inner_maps ? &(inner_maps.arrayZ[i]) : nullptr)) return false; + var_data_num_rows.push (item_count); vars.push (std::move (var_data_tuples)); } - return !vars.in_error (); + return !vars.in_error () && !var_data_num_rows.in_error () && vars.length == var_data_num_rows.length; } bool instantiate_tuple_vars (const hb_hashmap_t& normalized_axes_location, @@ -1904,7 +1681,9 @@ struct item_variations_t } } - if (!all_regions || !all_unique_regions) return false; + /* regions are empty means no variation data, return true */ + if (!all_regions || !all_unique_regions) return true; + if (!region_list.alloc (all_regions.get_population ())) return false; @@ -1969,16 +1748,13 @@ struct item_variations_t bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true) { - if (!region_list) return false; + /* return true if no variation data */ + if (!region_list) return true; unsigned num_cols = region_list.length; /* pre-alloc a 2D vector for all sub_table's VarData rows */ unsigned total_rows = 0; - for (unsigned major = 0; major < vars.length; major++) - { - const tuple_variations_t& tuples = vars[major]; - /* all tuples in each sub_table should have same num of deltas(num rows) */ - total_rows += tuples.tuple_vars[0].deltas_x.length; - } + for (unsigned major = 0; major < var_data_num_rows.length; major++) + total_rows += var_data_num_rows[major]; if (!delta_rows.resize (total_rows)) return false; /* init all rows to [0]*num_cols */ @@ -1998,7 +1774,7 @@ struct item_variations_t /* deltas are stored in tuples(column based), convert them back into items * (row based) delta */ const tuple_variations_t& tuples = vars[major]; - unsigned num_rows = tuples.tuple_vars[0].deltas_x.length; + unsigned num_rows = var_data_num_rows[major]; for (const tuple_delta_t& tuple: tuples.tuple_vars) { if (tuple.deltas_x.length != num_rows) @@ -2223,6 +1999,7 @@ struct item_variations_t } }; + } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh index a44a8e99998..3dc4ebaebd8 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh @@ -45,11 +45,12 @@ struct cvar { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - version.sanitize (c) && likely (version.major == 1) && + hb_barrier () && + likely (version.major == 1) && tupleVariationData.sanitize (c)); } - const TupleVariationData* get_tuple_var_data (void) const + const TupleVariationData<>* get_tuple_var_data (void) const { return &tupleVariationData; } bool decompile_tuple_variations (unsigned axis_count, @@ -57,12 +58,12 @@ struct cvar hb_blob_t *blob, bool is_gvar, const hb_map_t *axes_old_index_tag_map, - TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const + TupleVariationData<>::tuple_variations_t& tuple_variations /* OUT */) const { hb_vector_t shared_indices; - TupleVariationData::tuple_iterator_t iterator; + TupleVariationData<>::tuple_iterator_t iterator; hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4); - if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this, + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, this, shared_indices, &iterator)) return false; @@ -76,16 +77,16 @@ struct cvar static bool calculate_cvt_deltas (unsigned axis_count, hb_array_t coords, unsigned num_cvt_item, - const TupleVariationData *tuple_var_data, + const TupleVariationData<> *tuple_var_data, const void *base, hb_vector_t& cvt_deltas /* OUT */) { if (!coords) return true; hb_vector_t shared_indices; - TupleVariationData::tuple_iterator_t iterator; + TupleVariationData<>::tuple_iterator_t iterator; unsigned var_data_length = tuple_var_data->get_size (axis_count); hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast (tuple_var_data), var_data_length); - if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, base, + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, base, shared_indices, &iterator)) return true; /* isn't applied at all */ @@ -106,14 +107,14 @@ struct cvar bool has_private_points = iterator.current_tuple->has_private_points (); if (has_private_points && - !TupleVariationData::unpack_points (p, private_indices, end)) + !TupleVariationData<>::decompile_points (p, private_indices, end)) return false; const hb_vector_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length; if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false; - if (unlikely (!TupleVariationData::unpack_deltas (p, unpacked_deltas, end))) return false; + if (unlikely (!TupleVariationData<>::decompile_deltas (p, unpacked_deltas, end))) return false; for (unsigned int i = 0; i < num_deltas; i++) { @@ -128,7 +129,7 @@ struct cvar } bool serialize (hb_serialize_context_t *c, - TupleVariationData::tuple_variations_t& tuple_variations) const + TupleVariationData<>::tuple_variations_t& tuple_variations) const { TRACE_SERIALIZE (this); if (!tuple_variations) return_trace (false); @@ -143,7 +144,7 @@ struct cvar if (c->plan->all_axes_pinned) return_trace (false); - OT::TupleVariationData::tuple_variations_t tuple_variations; + OT::TupleVariationData<>::tuple_variations_t tuple_variations; unsigned axis_count = c->plan->axes_old_index_tag_map.get_population (); const hb_tag_t cvt = HB_TAG('c','v','t',' '); @@ -168,7 +169,7 @@ struct cvar } static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan, - const TupleVariationData *tuple_var_data, + const TupleVariationData<> *tuple_var_data, const void *base) { const hb_tag_t cvt = HB_TAG('c','v','t',' '); @@ -208,7 +209,7 @@ struct cvar protected: FixedVersion<>version; /* Version of the CVT variation table * initially set to 0x00010000u */ - TupleVariationData tupleVariationData; /* TupleVariationDate for cvar table */ + TupleVariationData<> tupleVariationData; /* TupleVariationDate for cvar table */ public: DEFINE_SIZE_MIN (8); }; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh index d60c3dbcf4e..f2725eaa282 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh @@ -43,7 +43,7 @@ static bool axis_coord_pinned_or_within_axis_range (const hb_array_t(coords[axis_index].to_float ()); if (axis_limit.is_point ()) { if (axis_limit.minimum != axis_coord) @@ -131,6 +131,7 @@ struct InstanceRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_array (coordinatesZ.arrayZ, axis_count)); } @@ -232,7 +233,10 @@ struct AxisRecord { float min, default_, max; get_coordinates (min, default_, max); - return TripleDistances (min, default_, max); + return TripleDistances ( + static_cast(min), + static_cast(default_), + static_cast(max)); } bool subset (hb_subset_context_t *c) const @@ -277,8 +281,10 @@ struct fvar { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && c->check_struct (this) && + hb_barrier () && axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && get_axes ().sanitize (c) && diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh index fd32ef03f30..c3040187f6e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh @@ -28,6 +28,7 @@ #ifndef HB_OT_VAR_GVAR_TABLE_HH #define HB_OT_VAR_GVAR_TABLE_HH +#include "hb-decycler.hh" #include "hb-open-type.hh" #include "hb-ot-var-common.hh" @@ -36,15 +37,37 @@ * https://docs.microsoft.com/en-us/typography/opentype/spec/gvar */ #define HB_OT_TAG_gvar HB_TAG('g','v','a','r') +#define HB_OT_TAG_GVAR HB_TAG('G','V','A','R') -namespace OT { +struct hb_glyf_scratch_t +{ + // glyf + contour_point_vector_t all_points; + contour_point_vector_t comp_points; + hb_decycler_t decycler; + + // gvar + contour_point_vector_t orig_points; + hb_vector_t x_deltas; + hb_vector_t y_deltas; + contour_point_vector_t deltas; + hb_vector_t shared_indices; + hb_vector_t private_indices; + + // VARC + hb_vector_t axisIndices; + hb_vector_t axisValues; +}; -struct GlyphVariationData : TupleVariationData -{}; +namespace OT { +template struct glyph_variations_t { - using tuple_variations_t = TupleVariationData::tuple_variations_t; + // TODO: Move tuple_variations_t to outside of TupleVariationData + using tuple_variations_t = typename TupleVariationData::tuple_variations_t; + using GlyphVariationData = TupleVariationData; + hb_vector_t glyph_variations; hb_vector_t compiled_shared_tuples; @@ -72,7 +95,7 @@ struct glyph_variations_t const hb_subset_plan_t *plan, const hb_hashmap_t& new_gid_var_data_map) { - if (unlikely (!glyph_variations.alloc (plan->new_to_old_gid_list.length, true))) + if (unlikely (!glyph_variations.alloc_exact (plan->new_to_old_gid_list.length))) return false; auto it = hb_iter (plan->new_to_old_gid_list); @@ -86,10 +109,11 @@ struct glyph_variations_t hb_bytes_t var_data = new_gid_var_data_map.get (new_gid); const GlyphVariationData* p = reinterpret_cast (var_data.arrayZ); - hb_vector_t shared_indices; - GlyphVariationData::tuple_iterator_t iterator; + typename GlyphVariationData::tuple_iterator_t iterator; tuple_variations_t tuple_vars; + hb_vector_t shared_indices; + /* in case variation data is empty, push an empty struct into the vector, * keep the vector in sync with the new_to_old_gid_list */ if (!var_data || ! p->has_data () || !all_contour_points->length || @@ -101,10 +125,14 @@ struct glyph_variations_t continue; } + bool is_composite_glyph = false; + is_composite_glyph = plan->composite_new_gids.has (new_gid); + if (!p->decompile_tuple_variations (all_contour_points->length, true /* is_gvar */, iterator, &(plan->axes_old_index_tag_map), shared_indices, shared_tuples, - tuple_vars /* OUT */)) + tuple_vars, /* OUT */ + is_composite_glyph)) return false; glyph_variations.push (std::move (tuple_vars)); } @@ -114,13 +142,15 @@ struct glyph_variations_t bool instantiate (const hb_subset_plan_t *plan) { unsigned count = plan->new_to_old_gid_list.length; + bool iup_optimize = false; + iup_optimize = plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS; for (unsigned i = 0; i < count; i++) { hb_codepoint_t new_gid = plan->new_to_old_gid_list[i].first; contour_point_vector_t *all_points; if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) return false; - if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points)) + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points, iup_optimize)) return false; } return true; @@ -134,6 +164,7 @@ struct glyph_variations_t for (tuple_variations_t& vars: glyph_variations) if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map, true, /* use shared points*/ + true, &shared_tuples_idx_map)) return false; @@ -252,7 +283,7 @@ struct glyph_variations_t hb_codepoint_t last_gid = 0; unsigned idx = 0; - TupleVariationData* cur_glyph = c->start_embed (); + GlyphVariationData* cur_glyph = c->start_embed (); if (!cur_glyph) return_trace (false); for (auto &_ : it) { @@ -266,7 +297,7 @@ struct glyph_variations_t if (idx >= glyph_variations.length) return_trace (false); if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false); - TupleVariationData* next_glyph = c->start_embed (); + GlyphVariationData* next_glyph = c->start_embed (); glyph_offset += (char *) next_glyph - (char *) cur_glyph; if (long_offset) @@ -289,14 +320,21 @@ struct glyph_variations_t } }; -struct gvar +template +struct gvar_GVAR { - static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar; + static constexpr hb_tag_t tableTag = TableTag; + + using GlyphVariationData = TupleVariationData; + + bool has_data () const { return version.to_int () != 0; } bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (version.major == 1) && + return_trace (c->check_struct (this) && + hb_barrier () && + (version.major == 1) && sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) && (is_long_offset () ? c->check_array (get_long_offset_array (), c->get_num_glyphs () + 1) : @@ -308,7 +346,7 @@ struct gvar { return sanitize_shallow (c); } bool decompile_glyph_variations (hb_subset_context_t *c, - glyph_variations_t& glyph_vars /* OUT */) const + glyph_variations_t& glyph_vars /* OUT */) const { hb_hashmap_t new_gid_var_data_map; auto it = hb_iter (c->plan->new_to_old_gid_list); @@ -335,13 +373,14 @@ struct gvar template bool serialize (hb_serialize_context_t *c, - const glyph_variations_t& glyph_vars, + const glyph_variations_t& glyph_vars, Iterator it, unsigned axis_count, - unsigned num_glyphs) const + unsigned num_glyphs, + bool force_long_offsets) const { TRACE_SERIALIZE (this); - gvar *out = c->allocate_min (); + gvar_GVAR *out = c->allocate_min (); if (unlikely (!out)) return_trace (false); out->version.major = 1; @@ -350,7 +389,10 @@ struct gvar out->glyphCountX = hb_min (0xFFFFu, num_glyphs); unsigned glyph_var_data_size = glyph_vars.compiled_byte_size (); - bool long_offset = glyph_var_data_size & ~0xFFFFu; + /* According to the spec: If the short format (Offset16) is used for offsets, + * the value stored is the offset divided by 2, so the maximum data size should + * be 2 * 0xFFFFu, which is 0x1FFFEu */ + bool long_offset = glyph_var_data_size > 0x1FFFEu || force_long_offsets; out->flags = long_offset ? 1 : 0; HBUINT8 *glyph_var_data_offsets = c->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1), false); @@ -380,7 +422,7 @@ struct gvar bool instantiate (hb_subset_context_t *c) const { TRACE_SUBSET (this); - glyph_variations_t glyph_vars; + glyph_variations_t glyph_vars; if (!decompile_glyph_variations (c, glyph_vars)) return_trace (false); @@ -391,7 +433,12 @@ struct gvar unsigned axis_count = c->plan->axes_index_map.get_population (); unsigned num_glyphs = c->plan->num_output_glyphs (); auto it = hb_iter (c->plan->new_to_old_gid_list); - return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs)); + + bool force_long_offsets = false; +#ifdef HB_EXPERIMENTAL_API + force_long_offsets = c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS; +#endif + return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs, force_long_offsets)); } bool subset (hb_subset_context_t *c) const @@ -405,7 +452,7 @@ struct gvar unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0; - gvar *out = c->serializer->allocate_min (); + gvar_GVAR *out = c->serializer->allocate_min (); if (unlikely (!out)) return_trace (false); out->version.major = 1; @@ -426,7 +473,13 @@ struct gvar subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; } - bool long_offset = subset_data_size & ~0xFFFFu; + /* According to the spec: If the short format (Offset16) is used for offsets, + * the value stored is the offset divided by 2, so the maximum data size should + * be 2 * 0xFFFFu, which is 0x1FFFEu */ + bool long_offset = subset_data_size > 0x1FFFEu; +#ifdef HB_EXPERIMENTAL_API + long_offset = long_offset || (c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS); +#endif out->flags = long_offset ? 1 : 0; HBUINT8 *subset_offsets = c->serializer->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1), false); @@ -444,6 +497,8 @@ struct gvar hb_memcpy (tuples, this+sharedTuples, shared_tuple_size); } + /* This ordering relative to the shared tuples array, which puts the glyphVariationData + last in the table, is required when HB_SUBSET_FLAGS_IFTB_REQUIREMENTS is set */ char *subset_data = c->serializer->allocate_size (subset_data_size, false); if (!subset_data) return_trace (false); out->dataZ = subset_data - (char *) out; @@ -521,7 +576,7 @@ struct gvar unsigned get_offset (unsigned glyph_count, unsigned i) const { if (unlikely (i > glyph_count)) return 0; - _hb_compiler_memory_r_barrier (); + hb_barrier (); return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2; } @@ -531,9 +586,11 @@ struct gvar public: struct accelerator_t { + bool has_data () const { return table->has_data (); } + accelerator_t (hb_face_t *face) { - table = hb_sanitize_context_t ().reference_table (face); + 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; @@ -599,37 +656,42 @@ struct gvar public: bool apply_deltas_to_points (hb_codepoint_t glyph, - hb_array_t coords, + hb_array_t coords, const hb_array_t points, + hb_glyf_scratch_t &scratch, bool phantom_only = false) const { if (unlikely (glyph >= glyphCount)) return true; hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph); if (!var_data_bytes.as ()->has_data ()) return true; - hb_vector_t shared_indices; - GlyphVariationData::tuple_iterator_t iterator; + + auto &shared_indices = scratch.shared_indices; + shared_indices.clear (); + + typename GlyphVariationData::tuple_iterator_t iterator; if (!GlyphVariationData::get_tuple_iterator (var_data_bytes, table->axisCount, var_data_bytes.arrayZ, shared_indices, &iterator)) return true; /* so isn't applied at all */ /* Save original points for inferred delta calculation */ - contour_point_vector_t orig_points_vec; // Populated lazily + auto &orig_points_vec = scratch.orig_points; + orig_points_vec.clear (); // Populated lazily auto orig_points = orig_points_vec.as_array (); /* flag is used to indicate referenced point */ - contour_point_vector_t deltas_vec; // Populated lazily + auto &deltas_vec = scratch.deltas; + deltas_vec.clear (); // Populated lazily auto deltas = deltas_vec.as_array (); - hb_vector_t end_points; // Populated lazily - unsigned num_coords = table->axisCount; hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * num_coords); - hb_vector_t private_indices; - hb_vector_t x_deltas; - hb_vector_t y_deltas; + auto &private_indices = scratch.private_indices; + auto &x_deltas = scratch.x_deltas; + auto &y_deltas = scratch.y_deltas; + unsigned count = points.length; bool flush = false; do @@ -654,16 +716,16 @@ struct gvar bool has_private_points = iterator.current_tuple->has_private_points (); if (has_private_points && - !GlyphVariationData::unpack_points (p, private_indices, end)) + !GlyphVariationData::decompile_points (p, private_indices, end)) return false; 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; if (unlikely (!x_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::unpack_deltas (p, x_deltas, end))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end))) return false; if (unlikely (!y_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end))) return false; if (!apply_to_all) { @@ -700,8 +762,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } } else @@ -712,10 +774,9 @@ struct gvar if (apply_to_all) for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { - unsigned int pt_index = i; - auto &delta = deltas.arrayZ[pt_index]; - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + auto &delta = deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } else for (unsigned int i = 0; i < num_deltas; i++) @@ -725,8 +786,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } } else @@ -734,10 +795,9 @@ struct gvar if (apply_to_all) for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { - unsigned int pt_index = i; - auto &delta = deltas.arrayZ[pt_index]; - delta.x += x_deltas.arrayZ[i]; - delta.y += y_deltas.arrayZ[i]; + auto &delta = deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i], + y_deltas.arrayZ[i]); } else for (unsigned int i = 0; i < num_deltas; i++) @@ -747,8 +807,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i]; - delta.y += y_deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i], + y_deltas.arrayZ[i]); } } } @@ -756,17 +816,14 @@ struct gvar /* infer deltas for unreferenced points */ if (!apply_to_all && !phantom_only) { - if (!end_points) - { - for (unsigned i = 0; i < count; ++i) - if (points.arrayZ[i].is_end_point) - end_points.push (i); - if (unlikely (end_points.in_error ())) return false; - } - unsigned start_point = 0; - for (unsigned end_point : end_points) + unsigned end_point = 0; + while (true) { + while (end_point < count && !points.arrayZ[end_point].is_end_point) + end_point++; + if (unlikely (end_point == count)) break; + /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ unsigned unref_count = 0; for (unsigned i = start_point; i < end_point + 1; i++) @@ -809,7 +866,7 @@ struct gvar } } no_more_gaps: - start_point = end_point + 1; + start_point = end_point = end_point + 1; } } @@ -829,7 +886,7 @@ struct gvar unsigned int get_axis_count () const { return table->axisCount; } private: - hb_blob_ptr_t table; + hb_blob_ptr_t table; unsigned glyphCount; hb_vector_t> shared_tuple_active_idx; }; @@ -847,7 +904,7 @@ struct gvar NNOffset32To> sharedTuples; /* Offset from the start of this table to the shared tuple records. * Array of tuple records shared across all glyph variation data tables. */ - HBUINT16 glyphCountX; /* The number of glyphs in this font. This must match the number of + GidOffsetType glyphCountX; /* The number of glyphs in this font. This must match the number of * glyphs stored elsewhere in the font. */ HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows. * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the @@ -862,9 +919,15 @@ struct gvar DEFINE_SIZE_ARRAY (20, offsetZ); }; +using gvar = gvar_GVAR; +using GVAR = gvar_GVAR; + struct gvar_accelerator_t : gvar::accelerator_t { gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {} }; +struct GVAR_accelerator_t : GVAR::accelerator_t { + GVAR_accelerator_t (hb_face_t *face) : GVAR::accelerator_t (face) {} +}; } /* namespace OT */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh index c1b40dcb49d..40a85a62b78 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh @@ -188,7 +188,7 @@ struct hvarvvar_subset_plan_t ~hvarvvar_subset_plan_t() { fini (); } void init (const hb_array_t &index_maps, - const VariationStore &_var_store, + const ItemVariationStore &_var_store, const hb_subset_plan_t *plan) { index_map_plans.resize (index_maps.length); @@ -263,7 +263,7 @@ struct hvarvvar_subset_plan_t hb_inc_bimap_t outer_map; hb_vector_t inner_maps; hb_vector_t index_map_plans; - const VariationStore *var_store; + const ItemVariationStore *var_store; protected: hb_vector_t inner_sets; @@ -288,6 +288,7 @@ struct HVARVVAR { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && varStore.sanitize (c, this) && advMap.sanitize (c, this) && @@ -295,7 +296,7 @@ struct HVARVVAR rsbMap.sanitize (c, this)); } - const VariationStore& get_var_store () const + const ItemVariationStore& get_var_store () const { return this+varStore; } void listup_index_maps (hb_vector_t &index_maps) const @@ -383,7 +384,7 @@ struct HVARVVAR float get_advance_delta_unscaled (hb_codepoint_t glyph, const int *coords, unsigned int coord_count, - VariationStore::cache_t *store_cache = nullptr) const + ItemVariationStore::cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, @@ -404,7 +405,7 @@ struct HVARVVAR public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ - Offset32To + Offset32To varStore; /* Offset to item variation store table. */ Offset32To advMap; /* Offset to advance var-idx mapping. */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh index ced04d89da3..c5a58d6f6bf 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh @@ -56,7 +56,7 @@ struct VariationValueRecord public: Tag valueTag; /* Four-byte tag identifying a font-wide measure. */ - VarIdx varIdx; /* Outer/inner index into VariationStore item. */ + VarIdx varIdx; /* Outer/inner index into ItemVariationStore item. */ public: DEFINE_SIZE_STATIC (8); @@ -77,8 +77,10 @@ struct MVAR { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && c->check_struct (this) && + hb_barrier () && valueRecordSize >= VariationValueRecord::static_size && varStore.sanitize (c, this) && c->check_range (valuesZ.arrayZ, @@ -104,7 +106,7 @@ struct MVAR out->valueRecordCount = valueRecordCount; item_variations_t item_vars; - const VariationStore& src_var_store = this+varStore; + const ItemVariationStore& src_var_store = this+varStore; if (!item_vars.instantiate (src_var_store, c->plan)) return_trace (false); @@ -157,7 +159,7 @@ protected: HBUINT16 valueRecordSize;/* The size in bytes of each value record — * must be greater than zero. */ HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ - Offset16To + Offset16To varStore; /* Offset to item variation store table. */ UnsizedArrayOf valuesZ; /* Array of value records. The records must be diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-varc-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-varc-table.hh new file mode 100644 index 00000000000..603aeb258cf --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-varc-table.hh @@ -0,0 +1,32 @@ +/* + * Copyright © 2024 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): Behdad Esfahbod + */ + +#ifndef HB_OT_VAR_VARC_TABLE_HH +#define HB_OT_VAR_VARC_TABLE_HH + +#include "OT/Var/VARC/VARC.hh" + +#endif /* HB_OT_VAR_VARC_TABLE_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh index dd3039924ef..b2300a327da 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh @@ -117,6 +117,7 @@ struct VORG { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && version.major == 1 && vertYOrigins.sanitize (c)); } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh index 518228c414b..18aa638c7ad 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint-extents.hh @@ -28,169 +28,8 @@ #include "hb.hh" #include "hb-paint.h" +#include "hb-geometry.hh" -typedef struct hb_extents_t -{ - hb_extents_t () {} - 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; } - bool is_void () const { return xmin > xmax; } - - void union_ (const hb_extents_t &o) - { - xmin = hb_min (xmin, o.xmin); - ymin = hb_min (ymin, o.ymin); - xmax = hb_max (xmax, o.xmax); - ymax = hb_max (ymax, o.ymax); - } - - void intersect (const hb_extents_t &o) - { - xmin = hb_max (xmin, o.xmin); - ymin = hb_max (ymin, o.ymin); - xmax = hb_min (xmax, o.xmax); - ymax = hb_min (ymax, o.ymax); - } - - void - add_point (float x, float y) - { - if (unlikely (is_void ())) - { - xmin = xmax = x; - ymin = ymax = y; - } - else - { - xmin = hb_min (xmin, x); - ymin = hb_min (ymin, y); - xmax = hb_max (xmax, x); - ymax = hb_max (ymax, y); - } - } - - float xmin = 0.f; - float ymin = 0.f; - float xmax = -1.f; - float ymax = -1.f; -} hb_extents_t; - -typedef struct hb_transform_t -{ - hb_transform_t () {} - 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) {} - - void multiply (const hb_transform_t &o) - { - /* 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; - } - - void transform_distance (float &dx, float &dy) const - { - 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 - { - transform_distance (x, y); - x += x0; - y += y0; - } - - void transform_extents (hb_extents_t &extents) const - { - float quad_x[4], quad_y[4]; - - quad_x[0] = extents.xmin; - quad_y[0] = extents.ymin; - quad_x[1] = extents.xmin; - quad_y[1] = extents.ymax; - quad_x[2] = extents.xmax; - quad_y[2] = extents.ymin; - quad_x[3] = extents.xmax; - quad_y[3] = extents.ymax; - - extents = hb_extents_t {}; - for (unsigned i = 0; i < 4; i++) - { - transform_point (quad_x[i], quad_y[i]); - extents.add_point (quad_x[i], quad_y[i]); - } - } - - float xx = 1.f; - float yx = 0.f; - float xy = 0.f; - float yy = 1.f; - float x0 = 0.f; - float y0 = 0.f; -} hb_transform_t; - -typedef struct hb_bounds_t -{ - enum status_t { - UNBOUNDED, - BOUNDED, - EMPTY, - }; - - hb_bounds_t (status_t status) : status (status) {} - hb_bounds_t (const hb_extents_t &extents) : - status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} - - void union_ (const hb_bounds_t &o) - { - if (o.status == UNBOUNDED) - status = UNBOUNDED; - else if (o.status == BOUNDED) - { - if (status == EMPTY) - *this = o; - else if (status == BOUNDED) - extents.union_ (o.extents); - } - } - - void intersect (const hb_bounds_t &o) - { - if (o.status == EMPTY) - status = EMPTY; - else if (o.status == BOUNDED) - { - if (status == UNBOUNDED) - *this = o; - else if (status == BOUNDED) - { - extents.intersect (o.extents); - if (extents.is_empty ()) - status = EMPTY; - } - } - } - - status_t status; - hb_extents_t extents; -} hb_bounds_t; typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; @@ -231,7 +70,10 @@ struct hb_paint_extents_context_t const hb_transform_t &t = transforms.tail (); t.transform_extents (extents); - clips.push (hb_bounds_t {extents}); + auto bounds = hb_bounds_t {extents}; + bounds.intersect (clips.tail ()); + + clips.push (bounds); } void pop_clip () diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.h b/src/java.desktop/share/native/libharfbuzz/hb-paint.h index 6215488e2e7..f0d9438506d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-paint.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-paint.h @@ -146,7 +146,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index. * - * Return value: %true if the glyph was painted, %false otherwise. + * Return value: `true` if the glyph was painted, `false` otherwise. * * Since: 8.2.0 */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh index 2c8ccbfb688..274d5df4c54 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh @@ -55,6 +55,9 @@ struct hb_priority_queue_t bool in_error () const { return heap.in_error (); } + bool alloc (unsigned size) + { return heap.alloc (size); } + #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif @@ -160,7 +163,7 @@ struct hb_priority_queue_t goto repeat; } - void swap (unsigned a, unsigned b) + void swap (unsigned a, unsigned b) noexcept { assert (a < heap.length); assert (b < heap.length); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh index e9cd376ad37..cb4fdeead2e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh @@ -238,6 +238,54 @@ bool _try_isolating_subgraphs (const hb_vector_t& over return true; } +static inline +bool _resolve_shared_overflow(const hb_vector_t& overflows, + int overflow_index, + graph_t& sorted_graph) +{ + const graph::overflow_record_t& r = overflows[overflow_index]; + + // Find all of the parents in overflowing links that link to this + // same child node. We will then try duplicating the child node and + // re-assigning all of these parents to the duplicate. + hb_set_t parents; + parents.add(r.parent); + for (int i = overflow_index - 1; i >= 0; i--) { + const graph::overflow_record_t& r2 = overflows[i]; + if (r2.child == r.child) { + parents.add(r2.parent); + } + } + + unsigned result = sorted_graph.duplicate(&parents, r.child); + if (result == (unsigned) -1 && parents.get_population() > 2) { + // All links to the child are overflowing, so we can't include all + // in the duplication. Remove one parent from the duplication. + // Remove the lowest index parent, which will be the closest to the child. + parents.del(parents.get_min()); + result = sorted_graph.duplicate(&parents, r.child); + } + + if (result == (unsigned) -1) return result; + + if (parents.get_population() > 1) { + // If the duplicated node has more than one parent pre-emptively raise it's priority to the maximum. + // This will place it close to the parents. Node's with only one parent, don't need this as normal overflow + // resolution will raise priority if needed. + // + // Reasoning: most of the parents to this child are likely at the same layer in the graph. Duplicating + // the child will theoretically allow it to be placed closer to it's parents. However, due to the shortest + // distance sort by default it's placement will remain in the same layer, thus it will remain in roughly the + // same position (and distance from parents) as the original child node. The overflow resolution will attempt + // to move nodes closer, but only for non-shared nodes. Since this node is shared, it will simply be given + // further duplication which defeats the attempt to duplicate with multiple parents. To fix this we + // pre-emptively raise priority now which allows the duplicated node to pack into the same layer as it's parents. + sorted_graph.vertices_[result].give_max_priority(); + } + + return result; +} + static inline bool _process_overflows (const hb_vector_t& overflows, hb_set_t& priority_bumped_parents, @@ -254,7 +302,7 @@ 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 (sorted_graph.duplicate (r.parent, r.child) == (unsigned) -1) continue; + if (!_resolve_shared_overflow(overflows, i, sorted_graph)) continue; return true; } @@ -289,9 +337,10 @@ bool _process_overflows (const hb_vector_t& overflows, inline bool hb_resolve_graph_overflows (hb_tag_t table_tag, unsigned max_rounds , - bool recalculate_extensions, + bool always_recalculate_extensions, graph_t& sorted_graph /* IN/OUT */) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Repacking %c%c%c%c.", HB_UNTAG(table_tag)); sorted_graph.sort_shortest_distance (); if (sorted_graph.in_error ()) { @@ -303,12 +352,12 @@ hb_resolve_graph_overflows (hb_tag_t table_tag, if (!will_overflow) return true; + bool is_gsub_or_gpos = (table_tag == HB_OT_TAG_GPOS || table_tag == HB_OT_TAG_GSUB); graph::gsubgpos_graph_context_t ext_context (table_tag, sorted_graph); - if ((table_tag == HB_OT_TAG_GPOS - || table_tag == HB_OT_TAG_GSUB) - && will_overflow) + if (is_gsub_or_gpos && will_overflow) { - if (recalculate_extensions) + DEBUG_MSG (SUBSET_REPACK, nullptr, "Applying GSUB/GPOS repacking specializations."); + if (always_recalculate_extensions) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Splitting subtables if needed."); if (!_presplit_subtables_if_needed (ext_context)) { @@ -364,6 +413,13 @@ hb_resolve_graph_overflows (hb_tag_t table_tag, if (graph::will_overflow (sorted_graph)) { + if (is_gsub_or_gpos && !always_recalculate_extensions) { + // If this a GSUB/GPOS table and we didn't try to extension promotion and table splitting then + // as a last ditch effort, re-run the repacker with it enabled. + DEBUG_MSG (SUBSET_REPACK, nullptr, "Failed to find a resolution. Re-running with extension promotion and table splitting enabled."); + return hb_resolve_graph_overflows (table_tag, max_rounds, true, sorted_graph); + } + DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed."); return false; } @@ -388,7 +444,7 @@ template inline hb_blob_t* hb_resolve_overflows (const T& packed, hb_tag_t table_tag, - unsigned max_rounds = 20, + unsigned max_rounds = 32, bool recalculate_extensions = false) { graph_t sorted_graph (packed); if (sorted_graph.in_error ()) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh index 3a6ec4fed9c..1f8ba32bae2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh @@ -72,8 +72,8 @@ * * === The sanitize() contract === * - * The sanitize() method of each object type shall return true if it's safe to - * call other methods of the object, and %false otherwise. + * The sanitize() method of each object type shall return `true` if it's safe to + * call other methods of the object, and `false` otherwise. * * Note that what sanitize() checks for might align with what the specification * describes as valid table data, but does not have to be. In particular, we @@ -134,7 +134,10 @@ struct hb_sanitize_context_t : const char *get_name () { return "SANITIZE"; } template bool may_dispatch (const T *obj HB_UNUSED, const F *format) - { return format->sanitize (this); } + { + return format->sanitize (this) && + hb_barrier (); + } static return_t default_return_value () { return true; } static return_t no_dispatch_return_value () { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh index 675eb03cadf..704d0ffd12b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh @@ -36,9 +36,7 @@ #include "hb-map.hh" #include "hb-pool.hh" -#ifdef HB_EXPERIMENTAL_API -#include "hb-subset-repacker.h" -#endif +#include "hb-subset-serialize.h" /* * Serialize @@ -75,23 +73,41 @@ struct hb_serialize_context_t object_t () = default; -#ifdef HB_EXPERIMENTAL_API - object_t (const hb_object_t &o) + object_t (const hb_subset_serialize_object_t &o) { head = o.head; tail = o.tail; next = nullptr; - real_links.alloc (o.num_real_links, true); + real_links.alloc_exact (o.num_real_links); for (unsigned i = 0 ; i < o.num_real_links; i++) real_links.push (o.real_links[i]); - virtual_links.alloc (o.num_virtual_links, true); + virtual_links.alloc_exact (o.num_virtual_links); for (unsigned i = 0; i < o.num_virtual_links; i++) virtual_links.push (o.virtual_links[i]); } -#endif - friend void swap (object_t& a, object_t& b) + bool add_virtual_link (objidx_t objidx) + { + if (!objidx) + return false; + + auto& link = *virtual_links.push (); + if (virtual_links.in_error ()) + return false; + + link.objidx = objidx; + // Remaining fields were previously zero'd by push(): + // link.width = 0; + // link.is_signed = 0; + // link.whence = 0; + // link.position = 0; + // link.bias = 0; + + return true; + } + + friend void swap (object_t& a, object_t& b) noexcept { hb_swap (a.head, b.head); hb_swap (a.tail, b.tail); @@ -128,8 +144,7 @@ struct hb_serialize_context_t link_t () = default; -#ifdef HB_EXPERIMENTAL_API - link_t (const hb_link_t &o) + link_t (const hb_subset_serialize_link_t &o) { width = o.width; is_signed = 0; @@ -138,7 +153,6 @@ struct hb_serialize_context_t bias = 0; objidx = o.objidx; } -#endif HB_INTERNAL static int cmp (const void* a, const void* b) { @@ -156,9 +170,9 @@ struct hb_serialize_context_t object_t *next; auto all_links () const HB_AUTO_RETURN - (( hb_concat (this->real_links, this->virtual_links) )); + (( hb_concat (real_links, virtual_links) )); auto all_links_writer () HB_AUTO_RETURN - (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) )); + (( hb_concat (real_links.writer (), virtual_links.writer ()) )); }; struct snapshot_t @@ -380,6 +394,7 @@ struct hb_serialize_context_t { merge_virtual_links (obj, objidx); obj->fini (); + object_pool.release (obj); return objidx; } } @@ -443,9 +458,11 @@ struct hb_serialize_context_t while (packed.length > 1 && packed.tail ()->head < tail) { - packed_map.del (packed.tail ()); - assert (!packed.tail ()->next); - packed.tail ()->fini (); + object_t *obj = packed.tail (); + packed_map.del (obj); + assert (!obj->next); + obj->fini (); + object_pool.release (obj); packed.pop (); } if (packed.length > 1) @@ -469,16 +486,40 @@ struct hb_serialize_context_t assert (current); - auto& link = *current->virtual_links.push (); - if (current->virtual_links.in_error ()) + if (!current->add_virtual_link(objidx)) err (HB_SERIALIZE_ERROR_OTHER); + } - link.width = 0; - link.objidx = objidx; - link.is_signed = 0; - link.whence = 0; - link.position = 0; - link.bias = 0; + objidx_t last_added_child_index() const { + if (unlikely (in_error ())) return (objidx_t) -1; + + assert (current); + if (!bool(current->real_links)) { + return (objidx_t) -1; + } + + return current->real_links[current->real_links.length - 1].objidx; + } + + // For the current object ensure that the sub-table bytes for child objidx are always placed + // after the subtable bytes for any other existing children. This only ensures that the + // repacker will not move the target subtable before the other children + // (by adding virtual links). It is up to the caller to ensure the initial serialization + // order is correct. + void repack_last(objidx_t objidx) { + if (unlikely (in_error ())) return; + + if (!objidx) + return; + + assert (current); + for (auto& l : current->real_links) { + if (l.objidx == objidx) { + continue; + } + + packed[l.objidx]->add_virtual_link(objidx); + } } template diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh index c1e107b4c29..7bd14a28193 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh @@ -56,7 +56,7 @@ * - For each glyph, if it doesn't match the subtable digest, * skip it. * - * The main filter we use is a combination of three bits-pattern + * The main filter we use is a combination of four bits-pattern * filters. A bits-pattern filter checks a number of bits (5 or 6) * of the input number (glyph-id in this case) and checks whether * its pattern is amongst the patterns of any of the accepted values. @@ -64,43 +64,60 @@ * check is done using four bitwise operations only. */ -template -struct hb_set_digest_bits_pattern_t +static constexpr unsigned hb_set_digest_shifts[] = {4, 0, 6}; + +struct hb_set_digest_t { + // No science in these. Intuition and testing only. + using mask_t = uint64_t; + + static constexpr unsigned n = ARRAY_LENGTH_CONST (hb_set_digest_shifts); static constexpr unsigned mask_bytes = sizeof (mask_t); static constexpr unsigned mask_bits = sizeof (mask_t) * 8; - static constexpr unsigned num_bits = 0 - + (mask_bytes >= 1 ? 3 : 0) - + (mask_bytes >= 2 ? 1 : 0) - + (mask_bytes >= 4 ? 1 : 0) - + (mask_bytes >= 8 ? 1 : 0) - + (mask_bytes >= 16? 1 : 0) - + 0; + static constexpr hb_codepoint_t mb1 = mask_bits - 1; + static constexpr mask_t one = 1; + static constexpr mask_t all = (mask_t) -1; - static_assert ((shift < sizeof (hb_codepoint_t) * 8), ""); - static_assert ((shift + num_bits <= sizeof (hb_codepoint_t) * 8), ""); + void init () + { for (unsigned i = 0; i < n; i++) masks[i] = 0; } - void init () { mask = 0; } + void clear () { init (); } - void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; } + static hb_set_digest_t full () + { + hb_set_digest_t d; + for (unsigned i = 0; i < n; i++) d.masks[i] = all; + return d; + } - void add (hb_codepoint_t g) { mask |= mask_for (g); } + void union_ (const hb_set_digest_t &o) + { for (unsigned i = 0; i < n; i++) masks[i] |= o.masks[i]; } bool add_range (hb_codepoint_t a, hb_codepoint_t b) { - if (mask == (mask_t) -1) return false; - if ((b >> shift) - (a >> shift) >= mask_bits - 1) - { - mask = (mask_t) -1; - return false; - } - else + bool ret; + + ret = false; + for (unsigned i = 0; i < n; i++) + if (masks[i] != all) + ret = true; + if (!ret) return false; + + ret = false; + for (unsigned i = 0; i < n; i++) { - mask_t ma = mask_for (a); - mask_t mb = mask_for (b); - mask |= mb + (mb - ma) - (mb < ma); - return true; + mask_t shift = hb_set_digest_shifts[i]; + if ((b >> shift) - (a >> shift) >= mb1) + masks[i] = all; + else + { + mask_t ma = one << ((a >> shift) & mb1); + mask_t mb = one << ((b >> shift) & mb1); + masks[i] |= mb + (mb - ma) - (mb < ma); + ret = true; + } } + return ret; } template @@ -123,95 +140,37 @@ struct hb_set_digest_bits_pattern_t template bool add_sorted_array (const hb_sorted_array_t& arr) { return add_sorted_array (&arr, arr.len ()); } - bool may_have (const hb_set_digest_bits_pattern_t &o) const - { return mask & o.mask; } - - bool may_have (hb_codepoint_t g) const - { return mask & mask_for (g); } - - private: - - static mask_t mask_for (hb_codepoint_t g) - { return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); } - mask_t mask; -}; - -template -struct hb_set_digest_combiner_t -{ - void init () - { - head.init (); - tail.init (); - } + bool operator [] (hb_codepoint_t g) const + { return may_have (g); } - void add (const hb_set_digest_combiner_t &o) - { - head.add (o.head); - tail.add (o.tail); - } void add (hb_codepoint_t g) { - head.add (g); - tail.add (g); - } - - bool add_range (hb_codepoint_t a, hb_codepoint_t b) - { - return (int) head.add_range (a, b) | (int) tail.add_range (a, b); - } - template - void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - head.add_array (array, count, stride); - tail.add_array (array, count, stride); - } - template - void add_array (const hb_array_t& arr) { add_array (&arr, arr.len ()); } - template - bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - return head.add_sorted_array (array, count, stride) && - tail.add_sorted_array (array, count, stride); + for (unsigned i = 0; i < n; i++) + masks[i] |= one << ((g >> hb_set_digest_shifts[i]) & mb1); } - template - bool add_sorted_array (const hb_sorted_array_t& arr) { return add_sorted_array (&arr, arr.len ()); } - bool may_have (const hb_set_digest_combiner_t &o) const + HB_ALWAYS_INLINE + bool may_have (hb_codepoint_t g) const { - return head.may_have (o.head) && tail.may_have (o.tail); + for (unsigned i = 0; i < n; i++) + if (!(masks[i] & (one << ((g >> hb_set_digest_shifts[i]) & mb1)))) + return false; + return true; } - bool may_have (hb_codepoint_t g) const + bool may_intersect (const hb_set_digest_t &o) const { - return head.may_have (g) && tail.may_have (g); + for (unsigned i = 0; i < n; i++) + if (!(masks[i] & o.masks[i])) + return false; + return true; } private: - head_t head; - tail_t tail; -}; - -/* - * hb_set_digest_t - * - * This is a combination of digests that performs "best". - * There is not much science to this: it's a result of intuition - * and testing. - */ -using hb_set_digest_t = - hb_set_digest_combiner_t - < - hb_set_digest_bits_pattern_t, - hb_set_digest_combiner_t - < - hb_set_digest_bits_pattern_t, - hb_set_digest_bits_pattern_t - > - > -; + mask_t masks[n] = {}; +}; #endif /* HB_SET_DIGEST_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-set.hh index 4aa682616a2..eaa892ab9f5 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-set.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-set.hh @@ -35,6 +35,8 @@ template struct hb_sparseset_t { + static constexpr bool realloc_move = true; + hb_object_header_t header; impl_t s; @@ -42,10 +44,10 @@ struct hb_sparseset_t ~hb_sparseset_t () { fini (); } hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); } - hb_sparseset_t (hb_sparseset_t&& other) : hb_sparseset_t () { s = std::move (other.s); } + hb_sparseset_t (hb_sparseset_t&& other) noexcept : hb_sparseset_t () { s = std::move (other.s); } hb_sparseset_t& operator = (const hb_sparseset_t& other) { set (other); return *this; } - hb_sparseset_t& operator = (hb_sparseset_t&& other) { s = std::move (other.s); return *this; } - friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) { hb_swap (a.s, b.s); } + hb_sparseset_t& operator = (hb_sparseset_t&& other) noexcept { s = std::move (other.s); return *this; } + friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) noexcept { hb_swap (a.s, b.s); } hb_sparseset_t (std::initializer_list lst) : hb_sparseset_t () { @@ -84,7 +86,7 @@ struct hb_sparseset_t uint32_t hash () const { return s.hash (); } void add (hb_codepoint_t g) { s.add (g); } - bool add_range (hb_codepoint_t a, hb_codepoint_t b) { return s.add_range (a, b); } + bool add_range (hb_codepoint_t first, hb_codepoint_t last) { return s.add_range (first, last); } template void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) @@ -104,6 +106,7 @@ struct hb_sparseset_t void del_range (hb_codepoint_t a, hb_codepoint_t b) { s.del_range (a, b); } bool get (hb_codepoint_t g) const { return s.get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -118,6 +121,9 @@ struct hb_sparseset_t hb_sparseset_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool may_intersect (const hb_sparseset_t &other) const + { return s.may_intersect (other.s); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { return s.intersects (first, last); } @@ -164,7 +170,7 @@ struct hb_set_t : hb_sparseset_t ~hb_set_t () = default; hb_set_t () : sparseset () {}; hb_set_t (const hb_set_t &o) : sparseset ((sparseset &) o) {}; - hb_set_t (hb_set_t&& o) : sparseset (std::move ((sparseset &) o)) {} + hb_set_t (hb_set_t&& o) noexcept : sparseset (std::move ((sparseset &) o)) {} hb_set_t& operator = (const hb_set_t&) = default; hb_set_t& operator = (hb_set_t&&) = default; hb_set_t (std::initializer_list lst) : sparseset (lst) {} diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc b/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc index 970aaa0b40b..19188f8006a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-shape-plan.cc @@ -233,7 +233,7 @@ hb_shape_plan_create2 (hb_face_t *face, num_coords, shaper_list); - if (unlikely (props->direction == HB_DIRECTION_INVALID)) + if (unlikely (!HB_DIRECTION_IS_VALID (props->direction))) return hb_shape_plan_get_empty (); hb_shape_plan_t *shape_plan; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shape.h b/src/java.desktop/share/native/libharfbuzz/hb-shape.h index bf7eafd2b4f..294105d3cb0 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-shape.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-shape.h @@ -53,6 +53,7 @@ hb_shape_full (hb_font_t *font, unsigned int num_features, const char * const *shaper_list); +#ifdef HB_EXPERIMENTAL_API HB_EXTERN hb_bool_t hb_shape_justify (hb_font_t *font, hb_buffer_t *buffer, @@ -64,6 +65,7 @@ hb_shape_justify (hb_font_t *font, float *advance, /* IN/OUT */ hb_tag_t *var_tag, /* OUT */ float *var_value /* OUT */); +#endif HB_EXTERN const char ** hb_shape_list_shapers (void); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-style.cc b/src/java.desktop/share/native/libharfbuzz/hb-style.cc index 20d4696b926..7378a8895f4 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-style.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-style.cc @@ -61,8 +61,8 @@ _hb_ratio_to_angle (float r) * @style_tag: a style tag. * * Searches variation axes of a #hb_font_t object for a specific axis first, - * if not set, then tries to get default style values from different - * tables of the font. + * if not set, first tries to get default style values in `STAT` table + * then tries to polyfill from different tables of the font. * * Returns: Corresponding axis or default value to a style tag. * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh index 4213f7e71c5..62206e0f5aa 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh @@ -115,7 +115,7 @@ struct str_encoder_t encode_byte (OpCode_BCD); // Based on: - // https://github.com/fonttools/fonttools/blob/97ed3a61cde03e17b8be36f866192fbd56f1d1a7/Lib/fontTools/misc/psCharStrings.py#L265-L294 + // https://github.com/fonttools/fonttools/blob/0738c41dfbcbc213ab9263f486ef0cccc6eb5ce5/Lib/fontTools/misc/psCharStrings.py#L267-L316 char buf[16]; /* FontTools has the following comment: @@ -133,6 +133,10 @@ struct str_encoder_t (void) hb_uselocale (((void) freelocale (clocale), oldlocale)); char *s = buf; + size_t len; + char *comma = strchr (s, ','); + if (comma) // Comma for some European locales in case no uselocale available. + *comma = '.'; if (s[0] == '0' && s[1] == '.') s++; else if (s[0] == '-' && s[1] == '0' && s[2] == '.') @@ -140,6 +144,45 @@ struct str_encoder_t s[1] = '-'; s++; } + else if ((len = strlen (s)) > 3 && !strcmp (s + len - 3, "000")) + { + unsigned exponent = len - 3; + char *s2 = s + exponent - 1; + while (*s2 == '0' && exponent > 1) + { + s2--; + exponent++; + } + snprintf (s2 + 1, sizeof (buf) - (s2 + 1 - buf), "E%u", exponent); + } + else + { + char *dot = strchr (s, '.'); + char *e = strchr (s, 'E'); + if (dot && e) + { + memmove (dot, dot + 1, e - (dot + 1)); + int exponent = atoi (e + 1); + int new_exponent = exponent - (e - (dot + 1)); + if (new_exponent == 1) + { + e[-1] = '0'; + e[0] = '\0'; + } + else + snprintf (e - 1, sizeof (buf) - (e - 1 - buf), "E%d", new_exponent); + } + } + if ((s[0] == '.' && s[1] == '0') || (s[0] == '-' && s[1] == '.' && s[2] == '0')) + { + int sign = s[0] == '-'; + char *s2 = s + sign + 1; + while (*s2 == '0') + s2++; + len = strlen (s2); + memmove (s + sign, s2, len); + snprintf (s + sign + len, sizeof (buf) - (s + sign + len - buf), "E-%u", (unsigned) (strlen (s + sign) - 1)); + } hb_vector_t nibbles; while (*s) { @@ -155,20 +198,22 @@ struct str_encoder_t { s++; nibbles.push (0x0C); // E- - continue; + } else { + if (c2 == '+') + s++; + nibbles.push (0x0B); // E } - if (c2 == '+') + if (*s == '0') s++; - nibbles.push (0x0B); // E continue; } - case '.': case ',': // Comma for some European locales in case no uselocale available. + case '.': nibbles.push (0x0A); // . continue; case '-': - nibbles.push (0x0E); // . + nibbles.push (0x0E); // - continue; } @@ -1083,7 +1128,7 @@ struct subr_subsetter_t if (opstr.op == OpCode_callsubr || opstr.op == OpCode_callgsubr) size += 3; } - if (!buff.alloc (buff.length + size, true)) + if (!buff.alloc_exact (buff.length + size)) return false; for (auto &opstr : str.values) diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc index 780bf34efaf..4938c048d6d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc @@ -45,7 +45,7 @@ struct remap_sid_t void alloc (unsigned size) { map.alloc (size); - vector.alloc (size, true); + vector.alloc_exact (size); } bool in_error () const @@ -620,6 +620,12 @@ struct cff1_subset_plan drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING; desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE; + #ifdef HB_EXPERIMENTAL_API + min_charstrings_off_size = (plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS) ? 4 : 0; + #else + min_charstrings_off_size = 0; + #endif + subset_charset = !acc.is_predef_charset (); if (!subset_charset) /* check whether the subset renumbers any glyph IDs */ @@ -778,13 +784,43 @@ struct cff1_subset_plan unsigned int topDictModSIDs[name_dict_values_t::ValCount]; bool desubroutinize = false; + + unsigned min_charstrings_off_size = 0; }; } // namespace OT +static bool _serialize_cff1_charstrings (hb_serialize_context_t *c, + struct OT::cff1_subset_plan &plan, + const OT::cff1::accelerator_subset_t &acc) +{ + c->push (); + + unsigned data_size = 0; + unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size, plan.min_charstrings_off_size); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + + auto *cs = c->start_embed (); + if (unlikely (!cs->serialize (c, plan.subset_charstrings, &data_size, plan.min_charstrings_off_size))) { + c->pop_discard (); + return false; + } + + plan.info.char_strings_link = c->pop_pack (false); + return true; +} + bool OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c, struct OT::cff1_subset_plan &plan) const { + /* push charstrings onto the object stack first which will ensure it packs as the last + object in the table. Keeping the chastrings last satisfies the requirements for patching + via IFTB. If this ordering needs to be changed in the future, charstrings should be left + at the end whenever HB_SUBSET_FLAGS_ITFB_REQUIREMENTS is enabled. */ + if (!_serialize_cff1_charstrings(c, plan, *this)) + return false; + /* private dicts & local subrs */ for (int i = (int) privateDicts.length; --i >= 0 ;) { @@ -823,25 +859,6 @@ OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c, if (!is_CID ()) plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo; - /* CharStrings */ - { - c->push (); - - unsigned data_size = 0; - unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size); - if (unlikely (!c->start_zerocopy (total_size))) - return false; - - auto *cs = c->start_embed (); - if (likely (cs->serialize (c, plan.subset_charstrings, &data_size))) - plan.info.char_strings_link = c->pop_pack (false); - else - { - c->pop_discard (); - return false; - } - } - /* FDArray (FD Index) */ if (fdArray != &Null (CFF1FDArray)) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc index 1f9bc209e88..1074d240386 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc @@ -248,7 +248,7 @@ struct cff2_subr_subsetter_t : subr_subsetter_t normalized_coords) : c (c), varStore (varStore), normalized_coords (normalized_coords) {} @@ -284,7 +284,7 @@ struct cff2_private_blend_encoder_param_t unsigned ivs = 0; unsigned region_count = 0; hb_vector_t scalars; - const CFF2VariationStore *varStore = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; hb_array_t normalized_coords; }; @@ -378,7 +378,7 @@ struct cff2_private_dict_blend_opset_t : dict_opset_t struct cff2_private_dict_op_serializer_t : op_serializer_t { cff2_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_, bool pinned_, - const CFF::CFF2VariationStore* varStore_, + const CFF::CFF2ItemVariationStore* varStore_, hb_array_t normalized_coords_) : desubroutinize (desubroutinize_), drop_hints (drop_hints_), pinned (pinned_), varStore (varStore_), normalized_coords (normalized_coords_) {} @@ -416,7 +416,7 @@ struct cff2_private_dict_op_serializer_t : op_serializer_t const bool desubroutinize; const bool drop_hints; const bool pinned; - const CFF::CFF2VariationStore* varStore; + const CFF::CFF2ItemVariationStore* varStore; hb_array_t normalized_coords; }; @@ -439,6 +439,12 @@ struct cff2_subset_plan desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE || pinned; // For instancing we need this path + #ifdef HB_EXPERIMENTAL_API + min_charstrings_off_size = (plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS) ? 4 : 0; + #else + min_charstrings_off_size = 0; + #endif + if (desubroutinize) { /* Flatten global & local subrs */ @@ -510,14 +516,45 @@ struct cff2_subset_plan bool drop_hints = false; bool desubroutinize = false; + + unsigned min_charstrings_off_size = 0; }; } // namespace OT +static bool _serialize_cff2_charstrings (hb_serialize_context_t *c, + cff2_subset_plan &plan, + const OT::cff2::accelerator_subset_t &acc) +{ + c->push (); + + unsigned data_size = 0; + unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size, plan.min_charstrings_off_size); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + + auto *cs = c->start_embed (); + if (unlikely (!cs->serialize (c, plan.subset_charstrings, &data_size, plan.min_charstrings_off_size))) + { + c->pop_discard (); + return false; + } + + plan.info.char_strings_link = c->pop_pack (false); + return true; +} + bool OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, struct cff2_subset_plan &plan, hb_array_t normalized_coords) const { + /* push charstrings onto the object stack first which will ensure it packs as the last + object in the table. Keeping the chastrings last satisfies the requirements for patching + via IFTB. If this ordering needs to be changed in the future, charstrings should be left + at the end whenever HB_SUBSET_FLAGS_ITFB_REQUIREMENTS is enabled. */ + if (!_serialize_cff2_charstrings(c, plan, *this)) + return false; + /* private dicts & local subrs */ hb_vector_t private_dict_infos; if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false; @@ -556,25 +593,6 @@ OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, } } - /* CharStrings */ - { - c->push (); - - unsigned data_size = 0; - unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size); - if (unlikely (!c->start_zerocopy (total_size))) - return false; - - auto *cs = c->start_embed (); - if (likely (cs->serialize (c, plan.subset_charstrings, &data_size))) - plan.info.char_strings_link = c->pop_pack (false); - else - { - c->pop_discard (); - return false; - } - } - /* FDSelect */ if (fdSelect != &Null (CFF2FDSelect)) { @@ -610,10 +628,10 @@ OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, } /* variation store */ - if (varStore != &Null (CFF2VariationStore) && + if (varStore != &Null (CFF2ItemVariationStore) && !plan.pinned) { - auto *dest = c->push (); + auto *dest = c->push (); if (unlikely (!dest->serialize (c, varStore))) { c->pop_discard (); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc index 8c67f7f23f4..bbe50b1fb36 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc @@ -24,6 +24,7 @@ * Google Author(s): Garret Rieger, Rod Sheeter, Behdad Esfahbod */ +#include "hb-subset-instancer-solver.hh" #include "hb-subset.hh" #include "hb-set.hh" #include "hb-utf.hh" @@ -50,7 +51,6 @@ hb_subset_input_t::hb_subset_input_t () HB_TAG ('k', 'e', 'r', 'n'), // Copied from fontTools: - HB_TAG ('B', 'A', 'S', 'E'), HB_TAG ('J', 'S', 'T', 'F'), HB_TAG ('D', 'S', 'I', 'G'), HB_TAG ('E', 'B', 'D', 'T'), @@ -123,6 +123,12 @@ hb_subset_input_t::hb_subset_input_t () //justify HB_TAG ('j', 'a', 'l', 't'), // HarfBuzz doesn't use; others might + //East Asian spacing + HB_TAG ('c', 'h', 'w', 's'), + HB_TAG ('v', 'c', 'h', 'w'), + HB_TAG ('h', 'a', 'l', 't'), + HB_TAG ('v', 'h', 'a', 'l'), + //private HB_TAG ('H', 'a', 'r', 'f'), HB_TAG ('H', 'A', 'R', 'F'), @@ -406,11 +412,52 @@ hb_subset_input_keep_everything (hb_subset_input_t *input) hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NOTDEF_OUTLINE | HB_SUBSET_FLAGS_GLYPH_NAMES | + HB_SUBSET_FLAGS_NAME_LEGACY | HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES | HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED); } #ifndef HB_NO_VAR +/** + * hb_subset_input_pin_all_axes_to_default: (skip) + * @input: a #hb_subset_input_t object. + * @face: a #hb_face_t object. + * + * Pin all axes to default locations in the given subset input object. + * + * All axes in a font must be pinned. Additionally, `CFF2` table, if present, + * will be de-subroutinized. + * + * Return value: `true` if success, `false` otherwise + * + * Since: 8.3.1 + **/ +HB_EXTERN hb_bool_t +hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input, + hb_face_t *face) +{ + unsigned axis_count = hb_ot_var_get_axis_count (face); + if (!axis_count) return false; + + hb_ot_var_axis_info_t *axis_infos = (hb_ot_var_axis_info_t *) hb_calloc (axis_count, sizeof (hb_ot_var_axis_info_t)); + if (unlikely (!axis_infos)) return false; + + (void) hb_ot_var_get_axis_infos (face, 0, &axis_count, axis_infos); + + for (unsigned i = 0; i < axis_count; i++) + { + hb_tag_t axis_tag = axis_infos[i].tag; + double default_val = (double) axis_infos[i].default_value; + if (!input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val))) + { + hb_free (axis_infos); + return false; + } + } + hb_free (axis_infos); + return true; +} + /** * hb_subset_input_pin_axis_to_default: (skip) * @input: a #hb_subset_input_t object. @@ -435,7 +482,7 @@ hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - float default_val = axis_info.default_value; + double default_val = (double) axis_info.default_value; return input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val)); } @@ -465,37 +512,32 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value); + double val = hb_clamp((double) axis_value, (double) axis_info.min_value, (double) axis_info.max_value); return input->axes_location.set (axis_tag, Triple (val, val, val)); } -#ifdef HB_EXPERIMENTAL_API /** * hb_subset_input_set_axis_range: (skip) * @input: a #hb_subset_input_t object. * @face: a #hb_face_t object. * @axis_tag: Tag of the axis - * @axis_min_value: Minimum value of the axis variation range to set - * @axis_max_value: Maximum value of the axis variation range to set - * @axis_def_value: Default value of the axis variation range to set, in case of - * null, it'll be determined automatically + * @axis_min_value: Minimum value of the axis variation range to set, if NaN the existing min will be used. + * @axis_max_value: Maximum value of the axis variation range to set if NaN the existing max will be used. + * @axis_def_value: Default value of the axis variation range to set, if NaN the existing default will be used. * * Restricting the range of variation on an axis in the given subset input object. * New min/default/max values will be clamped if they're not within the fvar axis range. - * If the new default value is null: - * If the fvar axis default value is within the new range, then new default - * value is the same as original default value. + * * If the fvar axis default value is not within the new range, the new default * value will be changed to the new min or max value, whichever is closer to the fvar * axis default. * * Note: input min value can not be bigger than input max value. If the input * default value is not within the new min/max range, it'll be clamped. - * Note: currently it supports gvar and cvar tables only. * * Return value: `true` if success, `false` otherwise * - * XSince: EXPERIMENTAL + * Since: 8.5.0 **/ HB_EXTERN hb_bool_t hb_subset_input_set_axis_range (hb_subset_input_t *input, @@ -503,22 +545,195 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_tag_t axis_tag, float axis_min_value, float axis_max_value, - float *axis_def_value /* IN, maybe NULL */) + float axis_def_value) { - if (axis_min_value > axis_max_value) - return false; - hb_ot_var_axis_info_t axis_info; if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value); - float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value); - float new_default_val = axis_def_value ? *axis_def_value : axis_info.default_value; - new_default_val = hb_clamp(new_default_val, new_min_val, new_max_val); - return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val)); + float min = !std::isnan(axis_min_value) ? axis_min_value : axis_info.min_value; + float max = !std::isnan(axis_max_value) ? axis_max_value : axis_info.max_value; + float def = !std::isnan(axis_def_value) ? axis_def_value : axis_info.default_value; + + if (min > max) + return false; + + float new_min_val = hb_clamp(min, axis_info.min_value, axis_info.max_value); + float new_max_val = hb_clamp(max, axis_info.min_value, axis_info.max_value); + float new_default_val = hb_clamp(def, new_min_val, new_max_val); + return input->axes_location.set (axis_tag, Triple ((double) new_min_val, (double) new_default_val, (double) new_max_val)); +} + +/** + * hb_subset_input_get_axis_range: (skip) + * @input: a #hb_subset_input_t object. + * @axis_tag: Tag of the axis + * @axis_min_value: Set to the previously configured minimum value of the axis variation range. + * @axis_max_value: Set to the previously configured maximum value of the axis variation range. + * @axis_def_value: Set to the previously configured default value of the axis variation range. + * + * Gets the axis range assigned by previous calls to hb_subset_input_set_axis_range. + * + * Return value: `true` if a range has been set for this axis tag, `false` otherwise. + * + * Since: 8.5.0 + **/ +HB_EXTERN hb_bool_t +hb_subset_input_get_axis_range (hb_subset_input_t *input, + hb_tag_t axis_tag, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value) + +{ + Triple* triple; + if (!input->axes_location.has(axis_tag, &triple)) { + return false; + } + + *axis_min_value = triple->minimum; + *axis_def_value = triple->middle; + *axis_max_value = triple->maximum; + return true; +} + +/** + * hb_subset_axis_range_from_string: + * @str: a string to parse + * @len: length of @str, or -1 if str is NULL terminated + * @axis_min_value: (out): the axis min value to initialize with the parsed value + * @axis_max_value: (out): the axis max value to initialize with the parsed value + * @axis_def_value: (out): the axis default value to initialize with the parse + * value + * + * Parses a string into a subset axis range(min, def, max). + * Axis positions string is in the format of min:def:max or min:max + * When parsing axis positions, empty values as meaning the existing value for that part + * E.g: :300:500 + * Specifies min = existing, def = 300, max = 500 + * In the output axis_range, if a value should be set to it's default value, + * then it will be set to NaN + * + * Return value: + * `true` if @str is successfully parsed, `false` otherwise + * + * Since: 10.2.0 + */ +HB_EXTERN hb_bool_t +hb_subset_axis_range_from_string (const char *str, int len, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value) +{ + if (len < 0) + len = strlen (str); + + const char *end = str + len; + const char* part = strpbrk (str, ":"); + if (!part) + { + // Single value. + if (strcmp (str, "drop") == 0) + { + *axis_min_value = NAN; + *axis_def_value = NAN; + *axis_max_value = NAN; + return true; + } + + double v; + if (!hb_parse_double (&str, end, &v)) return false; + + *axis_min_value = v; + *axis_def_value = v; + *axis_max_value = v; + return true; + } + + float values[3]; + int count = 0; + for (int i = 0; i < 3; i++) { + count++; + if (!*str || part == str) + { + values[i] = NAN; + + if (part == NULL) break; + str = part + 1; + part = strpbrk (str, ":"); + continue; + } + + double v; + if (!hb_parse_double (&str, part, &v)) return false; + values[i] = v; + + if (part == NULL) break; + str = part + 1; + part = strpbrk (str, ":"); + } + + if (count == 2) + { + *axis_min_value = values[0]; + *axis_def_value = NAN; + *axis_max_value = values[1]; + return true; + } + else if (count == 3) + { + *axis_min_value = values[0]; + *axis_def_value = values[1]; + *axis_max_value = values[2]; + return true; + } + return false; +} + +/** + * hb_subset_axis_range_to_string: + * @input: a #hb_subset_input_t object. + * @axis_tag: an axis to convert + * @buf: (array length=size) (out caller-allocates): output string + * @size: the allocated size of @buf + * + * Converts an axis range into a `NULL`-terminated string in the format + * understood by hb_subset_axis_range_from_string(). The client in responsible for + * allocating big enough size for @buf, 128 bytes is more than enough. + * + * Since: 10.2.0 + */ +HB_EXTERN void +hb_subset_axis_range_to_string (hb_subset_input_t *input, + hb_tag_t axis_tag, + char *buf, unsigned size) +{ + if (unlikely (!size)) return; + Triple* triple; + if (!input->axes_location.has(axis_tag, &triple)) { + return; + } + + char s[128]; + unsigned len = 0; + + hb_locale_t clocale HB_UNUSED; + hb_locale_t oldlocale HB_UNUSED; + oldlocale = hb_uselocale (clocale = newlocale (LC_ALL_MASK, "C", NULL)); + len += hb_max (0, snprintf (s, ARRAY_LENGTH (s) - len, "%g", (double) triple->minimum)); + s[len++] = ':'; + + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) triple->middle)); + s[len++] = ':'; + + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) triple->maximum)); + (void) hb_uselocale (((void) freelocale (clocale), oldlocale)); + + assert (len < ARRAY_LENGTH (s)); + len = hb_min (len, size - 1); + hb_memcpy (buf, s, len); + buf[len] = '\0'; } -#endif #endif /** @@ -653,7 +868,7 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, src = hb_utf8_t::next (src, src_end, &unicode, replacement); if (unicode >= 0x0080u) { - printf ("Non-ascii character detected, ignored...This API supports acsii characters only for mac platform\n"); + printf ("Non-ascii character detected, ignored...This API supports ascii characters only for mac platform\n"); return false; } } @@ -667,5 +882,4 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, input->name_table_overrides.set (hb_ot_name_record_ids_t (platform_id, encoding_id, language_id, name_id), name_bytes); return true; } - #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh new file mode 100644 index 00000000000..01987bd258d --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-iup.hh @@ -0,0 +1,37 @@ +/* + * Copyright © 2024 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. + */ + +#ifndef HB_SUBSET_INSTANCER_IUP_HH +#define HB_SUBSET_INSTANCER_IUP_HH + +#include "hb-subset-plan.hh" +/* given contour points and deltas, optimize a set of referenced points within error + * tolerance. Returns optimized referenced point indices */ +HB_INTERNAL bool iup_delta_optimize (const contour_point_vector_t& contour_points, + const hb_vector_t& x_deltas, + const hb_vector_t& y_deltas, + hb_vector_t& opt_indices, /* OUT */ + double tolerance = 0.0); + +#endif /* HB_SUBSET_INSTANCER_IUP_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc index 8ec36e3e80d..c67fee421c2 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc @@ -32,17 +32,17 @@ * This should be safe. */ -constexpr static float EPSILON = 1.f / (1 << 14); -constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14); +constexpr static double EPSILON = 1.0 / (1 << 14); +constexpr static double MAX_F2DOT14 = double (0x7FFF) / (1 << 14); static inline Triple _reverse_negate(const Triple &v) { return {-v.maximum, -v.middle, -v.minimum}; } -static inline float supportScalar (float coord, const Triple &tent) +static inline double supportScalar (double coord, const Triple &tent) { /* Copied from VarRegionAxis::evaluate() */ - float start = tent.minimum, peak = tent.middle, end = tent.maximum; + double start = tent.minimum, peak = tent.middle, end = tent.maximum; if (unlikely (start > peak || peak > end)) return 1.; @@ -62,20 +62,20 @@ static inline float supportScalar (float coord, const Triple &tent) return (end - coord) / (end - peak); } -static inline result_t +static inline rebase_tent_result_t _solve (Triple tent, Triple axisLimit, bool negative = false) { - float axisMin = axisLimit.minimum; - float axisDef = axisLimit.middle; - float axisMax = axisLimit.maximum; - float lower = tent.minimum; - float peak = tent.middle; - float upper = tent.maximum; + double axisMin = axisLimit.minimum; + double axisDef = axisLimit.middle; + double axisMax = axisLimit.maximum; + double lower = tent.minimum; + double peak = tent.middle; + double upper = tent.maximum; // Mirror the problem such that axisDef <= peak if (axisDef > peak) { - result_t vec = _solve (_reverse_negate (tent), + rebase_tent_result_t vec = _solve (_reverse_negate (tent), _reverse_negate (axisLimit), !negative); @@ -98,7 +98,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * axisMin axisDef axisMax lower upper */ if (axisMax <= lower && axisMax < peak) - return result_t{}; // No overlap + return rebase_tent_result_t{}; // No overlap /* case 2: Only the peak and outermost bound fall outside the new limit; * we keep the deltaset, update peak and outermost bound and scale deltas @@ -130,10 +130,10 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) */ if (axisMax < peak) { - float mult = supportScalar (axisMax, tent); + double mult = supportScalar (axisMax, tent); tent = Triple{lower, axisMax, axisMax}; - result_t vec = _solve (tent, axisLimit); + rebase_tent_result_t vec = _solve (tent, axisLimit); for (auto &p : vec) p = hb_pair (p.first * mult, p.second); @@ -143,13 +143,13 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // lower <= axisDef <= peak <= axisMax - float gain = supportScalar (axisDef, tent); - result_t out {hb_pair (gain, Triple{})}; + double gain = supportScalar (axisDef, tent); + rebase_tent_result_t out {hb_pair (gain, Triple{})}; // First, the positive side // outGain is the scalar of axisMax at the tent. - float outGain = supportScalar (axisMax, tent); + double outGain = supportScalar (axisMax, tent); /* Case 3a: Gain is more than outGain. The tent down-slope crosses * the axis into negative. We have to split it into multiples. @@ -168,13 +168,15 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * | * crossing */ - if (gain > outGain) + if (gain >= outGain) { + // Note that this is the branch taken if both gain and outGain are 0. + // Crossing point on the axis. - float crossing = peak + (1 - gain) * (upper - peak); + double crossing = peak + (1 - gain) * (upper - peak); - Triple loc{axisDef, peak, crossing}; - float scalar = 1.f; + Triple loc{hb_max (lower, axisDef), peak, crossing}; + double scalar = 1.0; // The part before the crossing point. out.push (hb_pair (scalar - gain, loc)); @@ -189,7 +191,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) if (upper >= axisMax) { Triple loc {crossing, axisMax, axisMax}; - float scalar = outGain; + double scalar = outGain; out.push (hb_pair (scalar - gain, loc)); } @@ -219,11 +221,11 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // Downslope. Triple loc1 {crossing, upper, axisMax}; - float scalar1 = 0.f; + double scalar1 = 0.0; // Eternity justify. Triple loc2 {upper, axisMax, axisMax}; - float scalar2 = 0.f; + double scalar2 = 0.0; out.push (hb_pair (scalar1 - gain, loc1)); out.push (hb_pair (scalar2 - gain, loc2)); @@ -252,9 +254,12 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * | | newUpper * axisDef axisMax */ - float newUpper = peak + (1 - gain) * (upper - peak); - assert (axisMax <= newUpper); // Because outGain >= gain - if (newUpper <= axisDef + (axisMax - axisDef) * 2) + double newUpper = peak + (1 - gain) * (upper - peak); + assert (axisMax <= newUpper); // Because outGain > gain + /* Disabled because ots doesn't like us: + * https://github.com/fonttools/fonttools/issues/3350 */ + + if (false && (newUpper <= axisDef + (axisMax - axisDef) * 2)) { upper = newUpper; if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper) @@ -265,7 +270,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) } Triple loc {hb_max (axisDef, lower), peak, upper}; - float scalar = 1.f; + double scalar = 1.0; out.push (hb_pair (scalar - gain, loc)); } @@ -289,10 +294,10 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) else { Triple loc1 {hb_max (axisDef, lower), peak, axisMax}; - float scalar1 = 1.f; + double scalar1 = 1.0; Triple loc2 {peak, axisMax, axisMax}; - float scalar2 = outGain; + double scalar2 = outGain; out.push (hb_pair (scalar1 - gain, loc1)); // Don't add a dirac delta! @@ -320,7 +325,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) if (lower <= axisMin) { Triple loc {axisMin, axisMin, axisDef}; - float scalar = supportScalar (axisMin, tent); + double scalar = supportScalar (axisMin, tent); out.push (hb_pair (scalar - gain, loc)); } @@ -348,11 +353,11 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // Downslope. Triple loc1 {axisMin, lower, axisDef}; - float scalar1 = 0.f; + double scalar1 = 0.0; // Eternity justify. Triple loc2 {axisMin, axisMin, lower}; - float scalar2 = 0.f; + double scalar2 = 0.0; out.push (hb_pair (scalar1 - gain, loc1)); out.push (hb_pair (scalar2 - gain, loc2)); @@ -364,19 +369,19 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) static inline TripleDistances _reverse_triple_distances (const TripleDistances &v) { return TripleDistances (v.positive, v.negative); } -float renormalizeValue (float v, const Triple &triple, - const TripleDistances &triple_distances, bool extrapolate) +double renormalizeValue (double v, const Triple &triple, + const TripleDistances &triple_distances, bool extrapolate) { - float lower = triple.minimum, def = triple.middle, upper = triple.maximum; + double lower = triple.minimum, def = triple.middle, upper = triple.maximum; assert (lower <= def && def <= upper); if (!extrapolate) - v = hb_max (hb_min (v, upper), lower); + v = hb_clamp (v, lower, upper); if (v == def) - return 0.f; + return 0.0; - if (def < 0.f) + if (def < 0.0) return -renormalizeValue (-v, _reverse_negate (triple), _reverse_triple_distances (triple_distances), extrapolate); @@ -385,14 +390,14 @@ float renormalizeValue (float v, const Triple &triple, return (v - def) / (upper - def); /* v < def */ - if (lower >= 0.f) + if (lower >= 0.0) return (v - def) / (def - lower); /* lower < 0 and v < default */ - float total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def; + double total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def; - float v_distance; - if (v >= 0.f) + double v_distance; + if (v >= 0.0) v_distance = (def - v) * triple_distances.positive; else v_distance = (-v) * triple_distances.negative + triple_distances.positive * def; @@ -400,18 +405,18 @@ float renormalizeValue (float v, const Triple &triple, return (-v_distance) /total_distance; } -result_t +rebase_tent_result_t rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances) { - assert (-1.f <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.f); - assert (-2.f <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.f); - assert (tent.middle != 0.f); + assert (-1.0 <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.0); + assert (-2.0 <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.0); + assert (tent.middle != 0.0); - result_t sols = _solve (tent, axisLimit); + rebase_tent_result_t sols = _solve (tent, axisLimit); - auto n = [&axisLimit, &axis_triple_distances] (float v) { return renormalizeValue (v, axisLimit, axis_triple_distances); }; + auto n = [&axisLimit, &axis_triple_distances] (double v) { return renormalizeValue (v, axisLimit, axis_triple_distances); }; - result_t out; + rebase_tent_result_t out; for (auto &p : sols) { if (!p.first) continue; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh index e8ca1dc4e63..9764dcc1725 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh @@ -30,24 +30,24 @@ /* pre-normalized distances */ struct TripleDistances { - TripleDistances (): negative (1.f), positive (1.f) {} - TripleDistances (float neg_, float pos_): negative (neg_), positive (pos_) {} - TripleDistances (float min, float default_, float max) + TripleDistances (): negative (1.0), positive (1.0) {} + TripleDistances (double neg_, double pos_): negative (neg_), positive (pos_) {} + TripleDistances (double min, double default_, double max) { negative = default_ - min; positive = max - default_; } - float negative; - float positive; + double negative; + double positive; }; struct Triple { Triple () : - minimum (0.f), middle (0.f), maximum (0.f) {} + minimum (0.0), middle (0.0), maximum (0.0) {} - Triple (float minimum_, float middle_, float maximum_) : + Triple (double minimum_, double middle_, double maximum_) : minimum (minimum_), middle (middle_), maximum (maximum_) {} bool operator == (const Triple &o) const @@ -63,7 +63,7 @@ struct Triple { bool is_point () const { return minimum == middle && middle == maximum; } - bool contains (float point) const + bool contains (double point) const { return minimum <= point && point <= maximum; } /* from hb_array_t hash ()*/ @@ -82,18 +82,18 @@ struct Triple { } - float minimum; - float middle; - float maximum; + double minimum; + double middle; + double maximum; }; -using result_item_t = hb_pair_t; -using result_t = hb_vector_t; +using rebase_tent_result_item_t = hb_pair_t; +using rebase_tent_result_t = hb_vector_t; /* renormalize a normalized value v to the range of an axis, * considering the prenormalized distances as well as the new axis limits. * Ported from fonttools */ -HB_INTERNAL float renormalizeValue (float v, const Triple &triple, +HB_INTERNAL double renormalizeValue (double v, const Triple &triple, const TripleDistances &triple_distances, bool extrapolate = true); /* Given a tuple (lower,peak,upper) "tent" and new axis limits @@ -107,6 +107,8 @@ HB_INTERNAL float renormalizeValue (float v, const Triple &triple, * If tent value is Triple{}, that is a special deltaset that should * be always-enabled (called "gain"). */ -HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances); +HB_INTERNAL rebase_tent_result_t rebase_tent (Triple tent, + Triple axisLimit, + TripleDistances axis_triple_distances); #endif /* HB_SUBSET_INSTANCER_SOLVER_HH */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh index 8bc1fcb5682..ade8278c40f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh @@ -70,6 +70,9 @@ HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_colred) HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_lookups) HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_lookups) +//use_mark_sets mapping: old->new +HB_SUBSET_PLAN_MEMBER (hb_map_t, used_mark_sets_map) + //active langsys we'd like to retain HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_langsys) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_langsys) @@ -87,9 +90,24 @@ HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpo HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), gsub_feature_substitutes_map) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), gpos_feature_substitutes_map) +// old feature_indexes set, used to reinstate the old features +HB_SUBSET_PLAN_MEMBER (hb_set_t, gsub_old_features) +HB_SUBSET_PLAN_MEMBER (hb_set_t, gpos_old_features) + +//feature_index->pair of (address of old feature, feature tag), used for inserting a catch all record +//if necessary +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E()>), gsub_old_feature_idx_tag_map) +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E()>), gpos_old_feature_idx_tag_map) + //active layers/palettes we'd like to retain HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_layers) HB_SUBSET_PLAN_MEMBER (hb_map_t, colr_palettes) +//colrv1 varstore retained varidx mapping +HB_SUBSET_PLAN_MEMBER (hb_vector_t, colrv1_varstore_inner_maps) +//colrv1 retained varidx -> (new varidx, delta) mapping +HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), colrv1_variation_idx_delta_map) +//colrv1 retained new delta set index -> new varidx mapping +HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_new_deltaset_idx_varidx_map) //Old layout item variation index -> (New varidx, delta) mapping HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), layout_variation_idx_delta_map) @@ -128,6 +146,15 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t, bounds_height_vec) //map: new_gid -> contour points vector HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(), new_gid_contour_points_map) +//new gids set for composite glyphs +HB_SUBSET_PLAN_MEMBER (hb_set_t, composite_new_gids) + +//Old BASE item variation index -> (New varidx, 0) mapping +HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), base_variation_idx_map) + +//BASE table varstore retained varidx mapping +HB_SUBSET_PLAN_MEMBER (hb_vector_t, base_varstore_inner_maps) + #ifdef HB_EXPERIMENTAL_API // name table overrides map: hb_ot_name_record_ids_t-> name string new value or // None to indicate should remove diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc index b9cc4fd0bcd..fb5282916b9 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc @@ -32,6 +32,7 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-gsub-table.hh" @@ -150,7 +151,8 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, hb_set_t *feature_indices, /* OUT */ hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */ hb_hashmap_t *feature_substitutes_map, /* OUT */ - bool& insert_catch_all_feature_variation_record) + hb_set_t& catch_all_record_feature_idxes, /* OUT */ + hb_hashmap_t>& catch_all_record_idx_feature_map /* OUT */) { unsigned num_features = table.get_feature_count (); hb_vector_t features; @@ -186,7 +188,7 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, &plan->axes_location, feature_record_cond_idx_map, feature_substitutes_map, - insert_catch_all_feature_variation_record, + catch_all_record_feature_idxes, feature_indices, false, false, @@ -208,17 +210,25 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, f->add_lookup_indexes_to (lookup_indices); } +#ifndef HB_NO_VAR + if (catch_all_record_feature_idxes) + { + for (unsigned feature_index : catch_all_record_feature_idxes) + { + const OT::Feature& f = table.get_feature (feature_index); + f.add_lookup_indexes_to (lookup_indices); + const void *tag = reinterpret_cast (&(table.get_feature_list ().get_tag (feature_index))); + catch_all_record_idx_feature_map.set (feature_index, hb_pair (&f, tag)); + } + } + // If all axes are pinned then all feature variations will be dropped so there's no need // to collect lookups from them. if (!plan->all_axes_pinned) - { - // TODO(qxliu76): this collection doesn't work correctly for feature variations that are dropped - // but not applied. The collection will collect and retain the lookup indices - // associated with those dropped but not activated rules. Since partial instancing - // isn't yet supported this isn't an issue yet but will need to be fixed for - // partial instancing. - table.feature_variation_collect_lookups (feature_indices, feature_substitutes_map, lookup_indices); - } + table.feature_variation_collect_lookups (feature_indices, + plan->user_axes_location.is_empty () ? nullptr: feature_record_cond_idx_map, + lookup_indices); +#endif } @@ -302,7 +312,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, script_langsys_map *langsys_map, hb_hashmap_t> *feature_record_cond_idx_map, hb_hashmap_t *feature_substitutes_map, - bool& insert_catch_all_feature_variation_record) + hb_set_t &catch_all_record_feature_idxes, + hb_hashmap_t>& catch_all_record_idx_feature_map) { hb_blob_ptr_t table = plan->source_table (); hb_tag_t table_tag = table->tableTag; @@ -313,7 +324,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, &feature_indices, feature_record_cond_idx_map, feature_substitutes_map, - insert_catch_all_feature_variation_record); + catch_all_record_feature_idxes, + catch_all_record_idx_feature_map); if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) hb_ot_layout_lookups_substitute_closure (plan->source, @@ -386,13 +398,56 @@ _get_hb_font_with_variations (const hb_subset_plan_t *plan) return font; } +static inline void +_remap_variation_indices (const OT::ItemVariationStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */) +{ + if (&var_store == &Null (OT::ItemVariationStore)) return; + unsigned subtable_count = var_store.get_sub_table_count (); + float *store_cache = var_store.create_cache (); + + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (variation_indices.get_min ()) >> 16; + for (unsigned idx : variation_indices) + { + int delta = 0; + if (calculate_delta) + delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, + normalized_coords.length, store_cache)); + + if (no_variations) + { + variation_idx_delta_map.set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); + continue; + } + + uint16_t major = idx >> 16; + if (major >= subtable_count) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + unsigned new_idx = (new_major << 16) + new_minor; + variation_idx_delta_map.set (idx, hb_pair_t (new_idx, delta)); + ++new_minor; + last_major = major; + } + var_store.destroy_cache (store_cache); +} + static inline void _collect_layout_variation_indices (hb_subset_plan_t* plan) { hb_blob_ptr_t gdef = plan->source_table (); hb_blob_ptr_t gpos = plan->source_table (); - if (!gdef->has_data ()) + if (!gdef->has_data () || !gdef->has_var_store ()) { gdef.destroy (); gpos.destroy (); @@ -408,18 +463,47 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) if (hb_ot_layout_has_positioning (plan->source)) gpos->collect_variation_indices (&c); - gdef->remap_layout_variation_indices (&varidx_set, - plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - &plan->layout_variation_idx_delta_map); + _remap_variation_indices (gdef->get_var_store (), + varidx_set, plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->layout_variation_idx_delta_map); - unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0; + unsigned subtable_count = gdef->get_var_store ().get_sub_table_count (); _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); gdef.destroy (); gpos.destroy (); } + +#ifndef HB_NO_BASE +static inline void +_collect_base_variation_indices (hb_subset_plan_t* plan) +{ + hb_blob_ptr_t base = plan->source_table (); + if (!base->has_var_store ()) + { + base.destroy (); + return; + } + + hb_set_t varidx_set; + base->collect_variation_indices (plan, varidx_set); + const OT::ItemVariationStore &var_store = base->get_var_store (); + unsigned subtable_count = var_store.get_sub_table_count (); + + + _remap_variation_indices (var_store, varidx_set, + plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->base_variation_idx_map); + _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); + + base.destroy (); +} + +#endif #endif static inline void @@ -431,12 +515,45 @@ _cmap_closure (hb_face_t *face, cmap.table->closure_glyphs (unicodes, glyphset); } -static void _colr_closure (hb_face_t *face, - hb_map_t *layers_map, - hb_map_t *palettes_map, +#ifndef HB_NO_VAR +static void +_remap_colrv1_delta_set_index_indices (const OT::DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */) +{ + if (!index_map.get_map_count ()) + return; + + hb_hashmap_t> delta_set_idx_delta_map; + unsigned new_delta_set_idx = 0; + for (unsigned delta_set_idx : delta_set_idxes) + { + unsigned var_idx = index_map.map (delta_set_idx); + unsigned new_varidx = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + int delta = 0; + + if (var_idx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + { + hb_pair_t *new_varidx_delta; + if (!variation_idx_delta_map.has (var_idx, &new_varidx_delta)) continue; + + new_varidx = hb_first (*new_varidx_delta); + delta = hb_second (*new_varidx_delta); + } + + new_deltaset_idx_varidx_map.set (new_delta_set_idx, new_varidx); + delta_set_idx_delta_map.set (delta_set_idx, hb_pair_t (new_delta_set_idx, delta)); + new_delta_set_idx++; + } + variation_idx_delta_map = std::move (delta_set_idx_delta_map); +} +#endif + +static void _colr_closure (hb_subset_plan_t* plan, hb_set_t *glyphs_colred) { - OT::COLR::accelerator_t colr (face); + OT::COLR::accelerator_t colr (plan->source); if (!colr.is_valid ()) return; hb_set_t palette_indices, layer_indices; @@ -448,11 +565,45 @@ static void _colr_closure (hb_face_t *face, glyphs_colred->union_ (glyphset_colrv0); //closure for COLRv1 - colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); + hb_set_t variation_indices, delta_set_indices; + colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices, &variation_indices, &delta_set_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); - _remap_indexes (&layer_indices, layers_map); - _remap_palette_indexes (&palette_indices, palettes_map); + _remap_indexes (&layer_indices, &plan->colrv1_layers); + _remap_palette_indexes (&palette_indices, &plan->colr_palettes); + +#ifndef HB_NO_VAR + if (!colr.has_var_store () || !variation_indices) return; + + const OT::ItemVariationStore &var_store = colr.get_var_store (); + // generated inner_maps is used by ItemVariationStore serialize(), which is subset only + unsigned subtable_count = var_store.get_sub_table_count (); + _generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); + + /* colr variation indices mapping during planning phase: + * generate colrv1_variation_idx_delta_map. When delta set index map is not + * included, it's a mapping from varIdx-> (new varIdx,delta). Otherwise, it's + * a mapping from old delta set idx-> (new delta set idx, delta). Mapping + * delta set indices is the same as gid mapping. + * Besides, we need to generate a delta set idx-> new var_idx map for updating + * delta set index map if exists. This map will be updated again after + * instancing. */ + if (!plan->all_axes_pinned) + { + _remap_variation_indices (var_store, + variation_indices, + plan->normalized_coords, + false, /* no need to calculate delta for COLR during planning */ + plan->all_axes_pinned, + plan->colrv1_variation_idx_delta_map); + + if (colr.has_delta_set_index_map ()) + _remap_colrv1_delta_set_index_indices (colr.get_delta_set_index_map (), + delta_set_indices, + plan->colrv1_variation_idx_delta_map, + plan->colrv1_new_deltaset_idx_varidx_map); + } +#endif } static inline void @@ -465,6 +616,24 @@ _math_closure (hb_subset_plan_t *plan, math.destroy (); } +static inline void +_remap_used_mark_sets (hb_subset_plan_t *plan, + hb_map_t& used_mark_sets_map) +{ + hb_blob_ptr_t gdef = plan->source_table (); + + if (!gdef->has_data () || !gdef->has_mark_glyph_sets ()) + { + gdef.destroy (); + return; + } + + hb_set_t used_mark_sets; + gdef->get_mark_glyph_sets ().collect_used_mark_sets (plan->_glyphset_gsub, used_mark_sets); + gdef.destroy (); + + _remap_indexes (&used_mark_sets, &used_mark_sets_map); +} static inline void _remove_invalid_gids (hb_set_t *glyphs, @@ -473,6 +642,36 @@ _remove_invalid_gids (hb_set_t *glyphs, glyphs->del_range (num_glyphs, HB_SET_VALUE_INVALID); } +template +static void +_fill_unicode_and_glyph_map(hb_subset_plan_t *plan, + I unicode_iterator, + F unicode_to_gid_for_iterator, + G unicode_to_gid_general) +{ + for (hb_codepoint_t cp : unicode_iterator) + { + hb_codepoint_t gid = unicode_to_gid_for_iterator(cp); + if (!GID_ALWAYS_EXISTS && gid == HB_MAP_VALUE_INVALID) + { + DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); + continue; + } + + plan->codepoint_to_glyph->set (cp, gid); + plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + } +} + +template +static void +_fill_unicode_and_glyph_map(hb_subset_plan_t *plan, + I unicode_iterator, + F unicode_to_gid_for_iterator) +{ + _fill_unicode_and_glyph_map(plan, unicode_iterator, unicode_to_gid_for_iterator, unicode_to_gid_for_iterator); +} + static void _populate_unicodes_to_retain (const hb_set_t *unicodes, const hb_set_t *glyphs, @@ -480,6 +679,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, { OT::cmap::accelerator_t cmap (plan->source); unsigned size_threshold = plan->source->get_num_glyphs (); + if (glyphs->is_empty () && unicodes->get_population () < size_threshold) { @@ -492,35 +692,21 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, // not excessively large (eg. an inverted set). plan->unicode_to_new_gid_list.alloc (unicodes->get_population ()); if (!unicode_to_gid) { - for (hb_codepoint_t cp : *unicodes) - { + _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { hb_codepoint_t gid; - if (!cmap.get_nominal_glyph (cp, &gid)) - { - DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); - continue; + if (!cmap.get_nominal_glyph (cp, &gid)) { + return HB_MAP_VALUE_INVALID; } - - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); - } + return gid; + }); } else { // Use in memory unicode to gid map it's faster then looking up from // the map. This code is mostly duplicated from above to avoid doing // conditionals on the presence of the unicode_to_gid map each // iteration. - for (hb_codepoint_t cp : *unicodes) - { - hb_codepoint_t gid = unicode_to_gid->get (cp); - if (gid == HB_MAP_VALUE_INVALID) - { - DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); - continue; - } - - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); - } + _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + return unicode_to_gid->get (cp); + }); } } else @@ -550,42 +736,46 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, plan->codepoint_to_glyph->alloc (unicodes->get_population () + glyphs->get_population ()); auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes; + for (hb_codepoint_t gid : *glyphs) { auto unicodes = gid_to_unicodes.get (gid); - - for (hb_codepoint_t cp : unicodes) - { - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); - } + _fill_unicode_and_glyph_map(plan, unicodes, [&] (hb_codepoint_t cp) { + return gid; + }, + [&] (hb_codepoint_t cp) { + return unicode_glyphid_map->get(cp); + }); } - for (hb_codepoint_t cp : *unicodes) - { - /* Don't double-add entry. */ + + _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + /* Don't double-add entry. */ if (plan->codepoint_to_glyph->has (cp)) - continue; + return HB_MAP_VALUE_INVALID; - hb_codepoint_t *gid; - if (!unicode_glyphid_map->has(cp, &gid)) - continue; + return unicode_glyphid_map->get(cp); + }, + [&] (hb_codepoint_t cp) { + return unicode_glyphid_map->get(cp); + }); - plan->codepoint_to_glyph->set (cp, *gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, *gid)); - } plan->unicode_to_new_gid_list.qsort (); } else { plan->codepoint_to_glyph->alloc (cmap_unicodes->get_population ()); - for (hb_codepoint_t cp : *cmap_unicodes) + hb_codepoint_t first = HB_SET_VALUE_INVALID, last = HB_SET_VALUE_INVALID; + for (; cmap_unicodes->next_range (&first, &last); ) { - hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; - if (!unicodes->has (cp) && !glyphs->has (gid)) - continue; - - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + _fill_unicode_and_glyph_map(plan, hb_range(first, last + 1), [&] (hb_codepoint_t cp) { + hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; + if (!unicodes->has (cp) && !glyphs->has (gid)) + return HB_MAP_VALUE_INVALID; + return gid; + }, + [&] (hb_codepoint_t cp) { + return unicode_glyphid_map->get(cp); + }); } } @@ -608,11 +798,22 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, plan->unicodes.add_sorted_array (&arr.arrayZ->first, arr.length, sizeof (*arr.arrayZ)); plan->_glyphset_gsub.add_array (&arr.arrayZ->second, arr.length, sizeof (*arr.arrayZ)); } -} -#ifndef HB_COMPOSITE_OPERATIONS_PER_GLYPH -#define HB_COMPOSITE_OPERATIONS_PER_GLYPH 64 -#endif + // Variation selectors don't have glyphs associated with them in the cmap so they will have been filtered out above + // but should still be retained. Add them back here. + + // However, the min and max codepoints for OS/2 should be calculated without considering variation selectors, + // 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() + | hb_filter(unicodes) + | hb_sink(&plan->unicodes) + ; +} static unsigned _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, @@ -639,18 +840,6 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, operation_count, depth); -#ifndef HB_NO_VAR_COMPOSITES - for (auto &item : glyph.get_var_composite_iterator ()) - { - operation_count = - _glyf_add_gid_and_children (glyf, - item.get_gid (), - gids_to_retain, - operation_count, - depth); - } -#endif - return operation_count; } @@ -714,7 +903,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, &plan->gsub_langsys, &plan->gsub_feature_record_cond_idx_map, &plan->gsub_feature_substitutes_map, - plan->gsub_insert_catch_all_feature_variation_rec); + plan->gsub_old_features, + plan->gsub_old_feature_idx_tag_map); if (!drop_tables->has (HB_OT_TAG_GPOS)) _closure_glyphs_lookups_features ( @@ -725,7 +915,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, &plan->gpos_langsys, &plan->gpos_feature_record_cond_idx_map, &plan->gpos_feature_substitutes_map, - plan->gpos_insert_catch_all_feature_variation_rec); + plan->gpos_old_features, + plan->gpos_old_feature_idx_tag_map); #endif _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ()); @@ -739,19 +930,21 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, hb_set_t cur_glyphset = plan->_glyphset_mathed; if (!drop_tables->has (HB_OT_TAG_COLR)) { - _colr_closure (plan->source, &plan->colrv1_layers, &plan->colr_palettes, &cur_glyphset); + _colr_closure (plan, &cur_glyphset); _remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ()); } plan->_glyphset_colred = cur_glyphset; + // XXX TODO VARC closure / subset + _nameid_closure (plan, drop_tables); /* Populate a full set of glyphs to retain by adding all referenced * composite glyphs. */ if (glyf.has_data ()) for (hb_codepoint_t gid : cur_glyphset) _glyf_add_gid_and_children (glyf, gid, &plan->_glyphset, - cur_glyphset.get_population () * HB_COMPOSITE_OPERATIONS_PER_GLYPH); + cur_glyphset.get_population () * HB_MAX_COMPOSITE_OPERATIONS_PER_GLYPH); else plan->_glyphset.union_ (cur_glyphset); #ifndef HB_NO_SUBSET_CFF @@ -871,9 +1064,11 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, *num_glyphs = max_glyph + 1; } + reverse_glyph_map->alloc (reverse_glyph_map->get_population () + new_to_old_gid_list->length); + hb_iter (new_to_old_gid_list) | hb_sink (reverse_glyph_map) ; + glyph_map->alloc (glyph_map->get_population () + new_to_old_gid_list->length); + hb_iter (new_to_old_gid_list) | hb_map (&hb_codepoint_pair_t::reverse) | hb_sink (glyph_map) @@ -932,9 +1127,9 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) 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.f), - static_cast (normalized_default / 16384.f), - static_cast (normalized_max / 16384.f))); + plan->axes_location.set (axis_tag, Triple (static_cast (normalized_min / 16384.0), + static_cast (normalized_default / 16384.0), + static_cast (normalized_max / 16384.0))); if (normalized_default != 0) plan->pinned_at_default = false; @@ -957,8 +1152,8 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) OT::cff2::accelerator_t cff2 (plan->source); if (!cff2.is_valid ()) return; - hb_font_t *font = nullptr; - if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) + hb_font_t *font = _get_hb_font_with_variations (plan); + if (unlikely (!plan->check_success (font != nullptr))) { hb_font_destroy (font); return; @@ -1036,8 +1231,8 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) static bool _get_instance_glyphs_contour_points (hb_subset_plan_t *plan) { - /* contour_points vector only needed for updating gvar table (infer delta) - * during partial instancing */ + /* contour_points vector only needed for updating gvar table (infer delta and + * iup delta optimization) during partial instancing */ if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) return true; @@ -1055,10 +1250,15 @@ _get_instance_glyphs_contour_points (hb_subset_plan_t *plan) } hb_codepoint_t old_gid = _.second; - if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points))) + auto glyph = glyf.glyph_for_gid (old_gid); + if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) return false; if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) return false; + + /* composite new gids are only needed by iup delta optimization */ + if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) + plan->composite_new_gids.add (new_gid); } return true; } @@ -1093,6 +1293,7 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, user_axes_location = input->axes_location; all_axes_pinned = false; pinned_at_default = true; + has_gdef_varstore = false; #ifdef HB_EXPERIMENTAL_API for (auto _ : input->name_table_overrides) @@ -1112,6 +1313,10 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, attach_accelerator_data = input->attach_accelerator_data; force_long_loca = input->force_long_loca; +#ifdef HB_EXPERIMENTAL_API + force_long_loca = force_long_loca || (flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS); +#endif + if (accel) accelerator = (hb_subset_accelerator_t*) accel; @@ -1160,6 +1365,16 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, for (auto &v : bounds_height_vec) v = 0xFFFFFFFF; + if (!drop_tables.has (HB_OT_TAG_GDEF)) + _remap_used_mark_sets (this, used_mark_sets_map); + +#ifndef HB_NO_VAR +#ifndef HB_NO_BASE + if (!drop_tables.has (HB_OT_TAG_BASE)) + _collect_base_variation_indices (this); +#endif +#endif + if (unlikely (in_error ())) return; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh index 40a6ff112af..a6bae23966a 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh @@ -41,6 +41,13 @@ namespace OT { struct Feature; } +struct os2_info_t { + hb_codepoint_t min_cmap_codepoint; + hb_codepoint_t max_cmap_codepoint; +}; + +typedef struct os2_info_t os2_info_t; + struct head_maxp_info_t { head_maxp_info_t () @@ -78,10 +85,16 @@ struct contour_point_t y = x * matrix[1] + y * matrix[3]; x = x_; } + + void add_delta (float delta_x, float delta_y) + { + x += delta_x; + y += delta_y; + } + HB_ALWAYS_INLINE void translate (const contour_point_t &p) { x += p.x; y += p.y; } - float x; float y; uint8_t flag; @@ -90,14 +103,20 @@ struct contour_point_t struct contour_point_vector_t : hb_vector_t { - void extend (const hb_array_t &a) + bool add_deltas (hb_array_t deltas_x, + hb_array_t deltas_y, + hb_array_t indices) { - unsigned int old_len = length; - if (unlikely (!resize (old_len + a.length, false))) - return; - auto arrayZ = this->arrayZ + old_len; - unsigned count = a.length; - hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); + if (indices.length != deltas_x.length || + indices.length != deltas_y.length) + return false; + + for (unsigned i = 0; i < indices.length; i++) + { + if (!indices.arrayZ[i]) continue; + arrayZ[i].add_delta (deltas_x.arrayZ[i], deltas_y.arrayZ[i]); + } + return true; } }; @@ -147,6 +166,9 @@ struct hb_subset_plan_t bool gsub_insert_catch_all_feature_variation_rec; bool gpos_insert_catch_all_feature_variation_rec; + // whether GDEF ItemVariationStore is retained + mutable bool has_gdef_varstore; + #define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name; #include "hb-subset-plan-member-list.hh" #undef HB_SUBSET_PLAN_MEMBER @@ -154,6 +176,8 @@ struct hb_subset_plan_t //recalculated head/maxp table info after instancing mutable head_maxp_info_t head_maxp_info; + os2_info_t os2_info; + const hb_subset_accelerator_t* accelerator; hb_subset_accelerator_t* inprogress_accelerator; diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-serialize.h b/src/java.desktop/share/native/libharfbuzz/hb-subset-serialize.h new file mode 100644 index 00000000000..9035d4ced7a --- /dev/null +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-serialize.h @@ -0,0 +1,83 @@ +/* + * Copyright © 2022 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. + * + */ + +#ifndef HB_SUBSET_SERIALIZE_H +#define HB_SUBSET_SERIALIZE_H + +#include "hb.h" + +HB_BEGIN_DECLS + +/** + * hb_subset_serialize_link_t: + * @width: offsetSize in bytes + * @position: position of the offset field in bytes from + * beginning of subtable + * @objidx: index of subtable + * + * Represents a link between two objects in the object graph + * to be serialized. + * + * Since: 10.2.0 + */ +typedef struct hb_subset_serialize_link_t { + unsigned int width; + unsigned int position; + unsigned int objidx; +} hb_subset_serialize_link_t; + +/** + * hb_subset_serialize_object_t: + * @head: start of object data + * @tail: end of object data + * @num_real_links: number of offset field in the object + * @real_links: array of offset info + * @num_virtual_links: number of objects that must be packed + * after current object in the final + * serialized order + * @virtual_links: array of virtual link info + * + * Represents an object in the object graph to be serialized. + * + * Since: 10.2.0 + */ +typedef struct hb_subset_serialize_object_t { + char *head; + char *tail; + unsigned int num_real_links; + hb_subset_serialize_link_t *real_links; + unsigned int num_virtual_links; + hb_subset_serialize_link_t *virtual_links; +} hb_subset_serialize_object_t; + +HB_EXTERN hb_blob_t * +hb_subset_serialize_or_fail (hb_tag_t table_tag, + hb_subset_serialize_object_t *hb_objects, + unsigned num_hb_objs); + + +HB_END_DECLS + +#endif /* HB_SUBSET_SERIALIZE_H */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc index c125a435b2b..595cafc283e 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc @@ -48,6 +48,7 @@ #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" #include "hb-ot-name-table.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-var-avar-table.hh" @@ -294,8 +295,8 @@ _try_subset (const TableType *table, DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (c->table_tag), buf_size); - if (unlikely (buf_size > c->source_blob->length * 16 || - !buf->alloc (buf_size, true))) + if (unlikely (buf_size > c->source_blob->length * 256 || + !buf->alloc_exact (buf_size))) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (c->table_tag), buf_size); @@ -460,9 +461,10 @@ _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, case HB_OT_TAG_hmtx: case HB_OT_TAG_vmtx: case HB_OT_TAG_maxp: + case HB_OT_TAG_OS2: return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf); case HB_OT_TAG_GPOS: - return !plan->normalized_coords || plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); + return plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); default: return true; } @@ -502,6 +504,7 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_CBLC: return _subset (plan, buf); case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ case HB_OT_TAG_MATH: return _subset (plan, buf); + case HB_OT_TAG_BASE: return _subset (plan, buf); #ifndef HB_NO_SUBSET_CFF case HB_OT_TAG_CFF1: return _subset (plan, buf); @@ -547,6 +550,7 @@ _subset_table (hb_subset_plan_t *plan, } #endif return _passthrough (plan, tag); + default: if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) return _passthrough (plan, tag); @@ -590,14 +594,20 @@ static void _attach_accelerator_data (hb_subset_plan_t* plan, * @input: input to use for the subsetting. * * Subsets a font according to provided input. Returns nullptr - * if the subset operation fails. + * if the subset operation fails or the face has no glyphs. * * Since: 2.9.0 **/ hb_face_t * hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input) { - if (unlikely (!input || !source)) return hb_face_get_empty (); + if (unlikely (!input || !source)) return nullptr; + + if (unlikely (!source->get_num_glyphs ())) + { + DEBUG_MSG (SUBSET, nullptr, "No glyphs in source font."); + return nullptr; + } hb_subset_plan_t *plan = hb_subset_plan_create_or_fail (source, input); if (unlikely (!plan)) { diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.h b/src/java.desktop/share/native/libharfbuzz/hb-subset.h index 8ea24da41b9..13fcd5332e6 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-subset.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.h @@ -73,6 +73,11 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * OS/2 will not be recalculated. * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout * substitution rules (GSUB). Since: 7.2.0. + * @HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS: If set perform IUP delta optimization on the + * remaining gvar table's deltas. Since: 8.5.0 + * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset + * to allow it to be used with incremental font transfer IFTB patches. Primarily, + * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL * * List of boolean properties that can be configured on the subset input. * @@ -90,6 +95,10 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u, HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, + HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS = 0x00000400u, +#ifdef HB_EXPERIMENTAL_API + HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00000800u, +#endif } hb_subset_flags_t; /** @@ -164,6 +173,10 @@ HB_EXTERN void hb_subset_input_set_flags (hb_subset_input_t *input, unsigned value); +HB_EXTERN hb_bool_t +hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input, + hb_face_t *face); + HB_EXTERN hb_bool_t hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, hb_face_t *face, @@ -175,15 +188,34 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, hb_tag_t axis_tag, float axis_value); -#ifdef HB_EXPERIMENTAL_API +HB_EXTERN hb_bool_t +hb_subset_input_get_axis_range (hb_subset_input_t *input, + hb_tag_t axis_tag, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value); + HB_EXTERN hb_bool_t hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_min_value, float axis_max_value, - float *axis_def_value); + float axis_def_value); + +HB_EXTERN hb_bool_t +hb_subset_axis_range_from_string (const char *str, int len, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value); +HB_EXTERN void +hb_subset_axis_range_to_string (hb_subset_input_t *input, + hb_tag_t axis_tag, + char *buf, + unsigned size); + +#ifdef HB_EXPERIMENTAL_API HB_EXTERN hb_bool_t hb_subset_input_override_name_table (hb_subset_input_t *input, hb_ot_name_id_t name_id, @@ -192,7 +224,6 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, unsigned language_id, const char *name_str, int str_len); - #endif HB_EXTERN hb_face_t * diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh index 8d3807a80f0..8731a0bcf8d 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh @@ -4,7 +4,7 @@ * * ./gen-ucd-table.py ucd.nounihan.grouped.xml * - * on file with this description: Unicode 15.1.0 + * on file with this description: Unicode 16.0.0 */ #ifndef HB_UCD_TABLE_HH @@ -13,7 +13,7 @@ #include "hb.hh" static const hb_script_t -_hb_ucd_sc_map[165] = +_hb_ucd_sc_map[172] = { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -97,7 +97,10 @@ _hb_ucd_sc_map[165] = HB_SCRIPT_OLD_UYGHUR, HB_SCRIPT_TANGSA, HB_SCRIPT_TOTO, HB_SCRIPT_VITHKUQI, HB_SCRIPT_MATH, HB_SCRIPT_KAWI, - HB_SCRIPT_NAG_MUNDARI, + HB_SCRIPT_NAG_MUNDARI, HB_SCRIPT_GARAY, + HB_SCRIPT_GURUNG_KHEMA, HB_SCRIPT_KIRAT_RAI, + HB_SCRIPT_OL_ONAL, HB_SCRIPT_SUNUWAR, + HB_SCRIPT_TODHRI, HB_SCRIPT_TULU_TIGALARI, }; static const uint16_t _hb_ucd_dm1_p0_map[825] = @@ -868,7 +871,7 @@ _hb_ucd_dm2_u32_map[638] = HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu), }; static const uint64_t -_hb_ucd_dm2_u64_map[388] = +_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), @@ -1051,13 +1054,23 @@ _hb_ucd_dm2_u64_map[388] = 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 (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 (0x1D157u, 0x1D165u, 0x0000u), + 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), @@ -1069,90 +1082,59 @@ _hb_ucd_dm2_u64_map[388] = #ifndef HB_OPTIMIZE_SIZE static const uint8_t -_hb_ucd_u8[17884] = +_hb_ucd_u8[17612] = { - 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, 11, 12, 13, 13, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7, - 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42, - 7, 7, 43, 7, 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 45, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 47, + 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, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, + 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 33, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73, - 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83, - 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34, - 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96, - 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105, - 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, - 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117, - 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131, - 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146, - 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122, - 160,161,162,163,164,165,166,122,167,168,169,170,122,171,172,173, - 34, 34, 34, 34, 34, 34, 34,174,175, 34,176,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,177, - 34, 34, 34, 34, 34, 34, 34, 34,178,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122, 34, 34, 34, 34,179,122,122,122, - 34, 34, 34, 34,180,181,182,183,122,122,122,122,184,185,186,187, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,188, - 34, 34, 34, 34, 34, 34, 34, 34, 34,189,190,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,191, - 34, 34,192, 34, 34,193,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,194,195,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,196,197, - 69,198,199,200,201,202,203,122,204,205,206,207,208,209,210,211, - 69, 69, 69, 69,212,213,122,122,122,122,122,122,122,122,214,122, - 215,216,217,122,122,218,122,122,122,219,122,122,122,122,122,220, - 34,221,222,122,122,122,122,122,223,224,225,122,226,227,122,122, - 228,229,230,231,232,122, 69,233, 69, 69, 69, 69, 69,234,235,236, - 237,238, 69, 69,239,240, 69,241,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,242, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34, - 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34, - 34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122, - 34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122, - 251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255, + 16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45, + 46, 47, 48, 39, 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, 49, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101, + 17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, + 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, + 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, + 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, + 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, + 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, + 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, + 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, + 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, + 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -1189,7 +1171,7 @@ _hb_ucd_u8[17884] = 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43, + 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, @@ -1262,13 +1244,13 @@ _hb_ucd_u8[17884] = 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64, + 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, + 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, + 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, @@ -1296,33 +1278,33 @@ _hb_ucd_u8[17884] = 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67, - 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67, - 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, - 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, - 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67, - 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149, - 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44, - 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57, - 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61, - 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2, - 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2, - 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44, - 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 44, 44, 44, 44, 44, 1, 2,154,155, 4, 4, 4, 4, - 4, 67, 4, 4, 4, 4,156,157,158,105,105,105,105, 43, 43, 86, - 159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69, - 36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36, - 67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55, - 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67, - 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2, + 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, + 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, + 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, + 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, + 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, + 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, + 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, + 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, + 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, + 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, + 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, + 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, + 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, + 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, + 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, + 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, + 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, + 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, + 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, + 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, + 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, + 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, + 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, + 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, + 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, @@ -1330,7 +1312,7 @@ _hb_ucd_u8[17884] = 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44, + 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, @@ -1391,8 +1373,10 @@ _hb_ucd_u8[17884] = 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44, - 36, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 43, + 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, + 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, + 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, + 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, @@ -1410,14 +1394,18 @@ _hb_ucd_u8[17884] = 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43, - 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71, - 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87, - 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44, - 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44, - 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86, - 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44, + 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, + 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, + 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, + 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, + 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, + 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, + 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, + 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, + 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, @@ -1427,49 +1415,52 @@ _hb_ucd_u8[17884] = 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44, - 2, 36, 36, 36, 36, 36, 36, 36, 44, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 89, 43, 43, 43, 85, 43, 87, 80, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57, - 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36, - 36, 36, 36, 36, 36, 86, 86, 90, 43, 89, 87, 87, 61, 44, 44, 44, - 36, 70, 85,107, 64, 44, 44, 44, 43, 94, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 43, 43, 80, 44, 86, 85, 60, 2, 2, 2, 2, 2, 2, + 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, + 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, + 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, + 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, + 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, + 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, + 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, + 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, + 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44, + 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, + 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44, + 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81, - 36, 61, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44, - 36, 61, 62, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44, - 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44, - 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86, - 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67, - 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44, - 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16, - 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, - 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11, - 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16, - 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16, - 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11, - 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, - 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43, + 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, + 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, + 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, + 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, + 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, + 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, + 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, + 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, + 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, + 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, + 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, + 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, + 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, + 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, + 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, + 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, + 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, @@ -1479,22 +1470,23 @@ _hb_ucd_u8[17884] = 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27, - 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27, - 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163, - 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36, - 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44, - 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, - 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, - 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, - 8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, - 55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67, - 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, - 67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44, - 67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41, - 67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67, - 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55, - 67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67, + 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, + 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, + 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, + 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, + 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, + 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, + 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, + 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, + 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, + 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, + 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, + 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, + 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, @@ -1520,366 +1512,350 @@ _hb_ucd_u8[17884] = 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, - 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, - 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, + 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, - 0, 0, 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, - 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, - 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, - 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, - 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, - 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, - 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, - 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, - 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, - 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, - 0, 79, 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, - 0, 87, 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, - 80, 0, 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, - 51, 0, 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, - 0, 0, 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, - 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, - 0,107, 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, - 0, 0,110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, - 0, 0, 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, - 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, - 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, - 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, - 0, 27, 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, - 33, 0, 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, - 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, - 42, 0, 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, - 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, - 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, - 0, 56, 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, - 0, 0, 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, - 0, 0, 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, - 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, - 0, 81, 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, - 84, 0, 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, - 0, 0, 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, - 0, 0, 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, - 0, 0, 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, - 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0, - 102, 0, 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106, - 107, 0, 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, - 33, 0,111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, - 0, 0, 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, - 0, 0, 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0, - 121, 0, 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, - 0, 0, 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128, - 129, 0,130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, - 0, 0, 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0, - 138, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, - 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, - 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, - 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, - 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, - 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, - 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, - 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, - 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, - 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, - 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, - 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, - 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, - 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, - 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, - 1, 52, 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, - 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, - 0, 78, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, - 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, - 81, 99,100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, - 0, 0, 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, - 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, - 61, 0, 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, - 0, 0, 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, - 0, 0, 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, + 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, + 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, + 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, + 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, + 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, + 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, + 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, + 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, + 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, + 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, + 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, + 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, + 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, + 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, + 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, + 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, + 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, + 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, + 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, + 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, + 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, + 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, + 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, + 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, + 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, + 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, + 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, + 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, + 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, + 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, + 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, + 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, + 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, + 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, + 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, + 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, + 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, + 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, + 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, + 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, + 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, + 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, + 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, + 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, + 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, + 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, + 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, + 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, + 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, + 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, + 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, + 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, + 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, + 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, + 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, + 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, + 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, + 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, + 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, + 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, + 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, + 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, + 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, + 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, + 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, + 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, + 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, + 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, - 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, - 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, - 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, - 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, - 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, - 0, 0, 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, - 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, - 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, - 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, - 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230, - 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, - 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220, - 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, - 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, - 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230, - 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230, - 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230, - 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0, - 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, - 230,220,220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, - 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, - 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, - 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, - 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, - 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, - 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, - 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, - 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, - 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0, - 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, - 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, - 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, - 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, - 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, - 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, - 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, - 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, - 230,230, 7, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, - 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, + 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, + 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, + 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, + 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, + 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, + 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, + 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, + 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, + 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, + 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, + 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, + 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, + 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, + 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, + 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, + 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, + 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, + 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, + 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, + 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, + 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, + 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, + 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, + 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, + 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, + 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, + 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, + 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, + 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, + 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, + 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, + 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, + 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, + 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, + 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, + 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 17, + 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113, + 129,169, 17, 27, 28, 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, 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, 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, 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, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,237, 0, 1, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, 0, 0, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, 25, 26, 0, 27, 0, 28, - 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 33, 34, 35, 36, 0, - 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, - 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 11, 12, - 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, 17, 18, 0, 19, - 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, 20, 20, 20, 8, - 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, 0, 0, 26, 27, - 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, 0, 0, 20, 0, - 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 20, - 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20, - 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20, - 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0, - 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, 0, 1, 0, 1, 0, 0, - 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45, - 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1, - 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, - 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13, - 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7, - 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, + 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, + 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, + 0, 0, 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, + 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, + 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, + 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, + 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, + 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, + 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, + 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, + 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, + 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, + 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, + 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, + 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, + 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 16, 17, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 20, 20, 20, 20, 20, 20, + 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 20, 33, + 34, 35, 34, 34, 36, 37, 20, 20, 20, 20, 20, 20, 38, 20, 39, 40, + 41, 41, 41, 41, 41, 42, 43, 44, 20, 20, 20, 20, 20, 20, 20, 45, + 46, 20, 20, 47, 20, 20, 20, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 20, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1, - 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, - 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, - 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109, - 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123, - 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138, - 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151, - 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164, - 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169, - 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173, - 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182, - 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189, - 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197, - 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208, - 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212, - 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218, - 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226, - 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233, - 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70, - 70, 70, 70, 70, 70,241, 70, 70, 70, 70,242, 96, 96, 96, 70, 70, - 70, 70,243, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70, 70, 70,244, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70,245, 96, 96, 96, 96, 96, 96, 96, 96,246, 96, - 247,248, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, - 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, - 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, - 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, - 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, - 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, - 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, - 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, - 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, - 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, - 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, - 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, - 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, - 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, - 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, - 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, - 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, - 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, - 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, - 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, - 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, - 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, - 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, - 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, - 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, - 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, - 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, - 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, - 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, - 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, - 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, - 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, - 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, - 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, - 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62, - 62, 62, 62, 62, 62, 2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 60, 13, 13, + 13, 61, 62, 13, 13, 13, 13, 63, 13, 13, 13, 13, 13, 13, 64, 65, + 20, 20, 66, 20, 13, 13, 13, 13, 67, 13, 13, 13, 68, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, + 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, + 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, + 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 2, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, + 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, + 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3, + 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 0, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, + 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, + 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, + 2, 2, 2, 2, 2, 3, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, + 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, + 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, + 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, + 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, + 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, + 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, + 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, + 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, + 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, + 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, + 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, + 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, + 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, + 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, + 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, + 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, + 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, + 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, + 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, + 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, + 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, + 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, + 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, + 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, + 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, + 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, + 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, + 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, + 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25, + 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, + 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, + 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, + 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, + 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, + 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, + 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, + 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, + 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, + 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, + 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, + 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, + 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, + 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, + 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 2, 62, 62, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, - 73, 73, 73, 73, 73, 73, 6, 2, 2, 2, 2, 2, 2, 2, 8, 8, + 73, 73, 73, 73, 73, 73, 6, 6, 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, @@ -1896,31 +1872,30 @@ _hb_ucd_u8[17884] = 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, - 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, - 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, - 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, - 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, - 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, - 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, - 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 0, 0, - 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 12, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, + 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, + 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, + 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 19, 19, - 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2, - 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 65, 65, + 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 19, 19, + 2, 19, 2, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, @@ -1943,36 +1918,38 @@ _hb_ucd_u8[17884] = 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, - 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3, - 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, - 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, - 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, - 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, - 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, - 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, - 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, - 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, - 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, - 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, - 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, - 19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, + 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, + 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, + 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, + 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, + 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, + 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118, + 118,118,118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, + 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, + 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135, + 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106, + 106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104, + 104,104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,161,161, + 161,161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161, + 161, 2,161,161, 2,161,161,161, 2,161,161,161,161,161,161,161, + 2,161,161, 2, 2, 2,170,170,170,170,170,170,170,170,170,170, + 170,170, 2, 2, 2, 2,110,110,110,110,110,110,110,110,110,110, + 110,110,110,110,110, 2,110,110,110,110,110,110, 2, 2, 19, 19, + 19, 19, 19, 19, 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, @@ -1998,122 +1975,135 @@ _hb_ucd_u8[17884] = 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, - 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,156,156, + 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,165,165, + 165,165,165,165,165,165,165,165,165,165,165,165, 2, 2, 2,165, + 165,165,165,165,165,165, 2, 2, 2, 2, 2, 2,165,165,156,156, 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3,147,147, - 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, - 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, - 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, - 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, - 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, - 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, - 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, - 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, - 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, - 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, - 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, - 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, - 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, - 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, - 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, - 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, - 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, - 107,107,107, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 3, 3,147,147,147,147,147,147,147,147,148,148, + 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,158,158, + 158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153, + 153,153,153,153,153,153,153,153,153,153, 2, 2, 2, 2,149,149, + 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, + 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101, 2, + 2, 2, 2, 2, 2, 2,101,101, 2, 2, 2, 2, 2, 2, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111, 2,100,100, + 100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 2, 2, 2,108,108,108,108,108,108,108,108,108,108, + 2,108,108,108,108,108,108,108, 2, 2, 2, 2, 2, 2,129,129, + 129,129,129,129,129, 2,129, 2,129,129,129,129, 2,129,129,129, + 129,129,129,129,129,129,129,129,129,129,129,129, 2,129,129,129, + 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, + 109, 2, 2, 2, 2, 2,109,109, 2, 2, 2, 2, 2, 2,107,107, + 107,107, 2,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, + 2,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2, + 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107, + 2, 1,107,107,107,107,107, 2, 2,107,107,107, 2, 2,107, 2, + 2, 2, 2, 2, 2,107, 2, 2, 2, 2, 2,107,107,107,107,107, + 107,107, 2, 2,107,107,107,107,107,107,107, 2, 2, 2,171,171, + 171,171,171,171,171,171,171,171, 2,171, 2, 2,171, 2,171,171, + 171,171,171,171, 2,171,171, 2,171, 2, 2,171, 2,171,171,171, + 171, 2,171,171,171,171,171, 2, 2, 2, 2, 2, 2, 2, 2,171, + 171, 2, 2, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2,124,124, 124,124,124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123, 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,114,114, 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 2, 2, 2,102,102, - 102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2,126,126, - 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, - 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, - 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, - 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, - 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, - 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, - 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, - 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, - 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, - 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, - 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, - 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, - 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, - 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, - 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, - 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, - 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, - 163, 2, 2, 2,163,163,163,163, 2, 2, 2, 2, 2, 2, 86, 2, - 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, - 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, - 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127, 2, 79, 2, + 102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2, 33, 33, + 33, 33, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, + 126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,126,126, + 126,126,126,126,126, 2,142,142,142,142,142,142,142,142,142,142, + 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125, + 125, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,125,154,154, + 154,154,154,154,154, 2, 2,154, 2, 2,154,154,154,154,154,154, + 154,154, 2,154,154, 2,154,154,154,154,154,154,154,154,154,154, + 154,154,154,154, 2,154,154, 2, 2,154,154,154,154,154,154,154, + 2, 2, 2, 2, 2, 2,150,150,150,150,150,150,150,150, 2, 2, + 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2,141,141, + 141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140, + 140, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121, 2, + 2, 2, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2,169,169, + 169,169,169,169,169,169,169,169, 2, 2, 2, 2, 2, 2,133,133, + 133,133,133,133,133,133,133, 2,133,133,133,133,133,133,133,133, + 133,133,133,133,133, 2,133,133,133,133,133,133, 2, 2,133,133, + 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134, 2, 2, + 134,134,134,134,134,134, 2,134,134,134,134,134,134,134,134,134, + 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138, + 2,138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2, + 138, 2,138,138, 2,138,138,138, 2, 2, 2, 2, 2, 2,143,143, + 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143, + 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143, + 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, + 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2, + 2, 2, 2, 2, 2, 2,163,163,163,163,163,163,163,163,163, 2, + 163,163,163,163,163,163,163,163,163, 2, 2, 2,163,163,163,163, + 163, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, + 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, + 63, 63, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157, + 157, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 2, 2, 80, 80, 80, 2, 2, 2, 2, 2,127,127, + 127,127,127,127,127,127,127,127,127,127,127,127,127, 2,166,166, + 166,166,166,166,166,166,166,166, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159, 159,159,159,159,159,159,159,159,159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, 103,103,103,103, 2, 2,119,119,119,119,119,119,119,119,119,119, 119,119,119,119, 2, 2,119,119, 2,119,119,119,119,119, 2, 2, - 2, 2, 2,119,119,119,146,146,146,146,146,146,146,146,146,146, + 2, 2, 2,119,119,119,167,167,167,167,167,167,167,167,167,167, + 2, 2, 2, 2, 2, 2,146,146,146,146,146,146,146,146,146,146, 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136,136,136,136,136,136,136,155,155, - 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2,136, 2, - 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, - 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, - 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, - 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, - 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, - 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, - 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, - 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, - 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, - 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, - 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, - 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, - 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, - 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, - 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, - 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, - 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, - 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, - 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2, 30, 30, - 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, - 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, - 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, - 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, - 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, - 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, + 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2, 2, 2, + 2, 2, 2, 2, 2,155,136, 2, 2, 2, 2, 2, 2, 2, 17, 17, + 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, 15, + 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, + 15, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 17, 2, 2, 2, 2, + 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139, + 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, + 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, + 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 1, 1, + 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131, + 131,131,131,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 2, + 2,131,131,131,131,131, 2,131,131,131,131,131,131,131, 2, 2, + 2, 2, 2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56, 2, 56, 2, + 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56, + 56, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 6,151,151,151,151,151,151,151,151,151,151, + 151,151,151, 2, 2, 2,151,151,151,151,151,151, 2, 2,151,151, + 2, 2, 2, 2,151,151,160,160,160,160,160,160,160,160,160,160, + 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, + 2, 2, 2, 2, 2,152,164,164,164,164,164,164,164,164,164,164, + 2, 2, 2, 2, 2, 2,168,168,168,168,168,168,168,168,168,168, + 168, 2, 2, 2, 2,168, 30, 30, 30, 30, 2, 30, 30, 2,113,113, + 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, + 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, + 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, + 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, + 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, + 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 0, 0, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, + 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -2123,13 +2113,14 @@ _hb_ucd_u8[17884] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 9, + 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -2137,8 +2128,7 @@ _hb_ucd_u8[17884] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2175,23 +2165,29 @@ _hb_ucd_u8[17884] = 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147, 148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,162, 0,163, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,164,165, 0, 0, 0, 0, 0, 0, 0,166, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 167, 0, 0, 0,168,169, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,171, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,173, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176, - 177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192, - 193,194,195,196,197,198,199,200,201,202,203,204,205,206, 0, 0, + 0,176,177, 0, 0, 0, 0,178,179, 0, 0, 0,180,181,182,183, + 184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207,208,209,210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[9344] = +_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, @@ -2210,9 +2206,10 @@ _hb_ucd_u16[9344] = 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, - 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, - 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, + 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, + 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, @@ -2225,28 +2222,34 @@ _hb_ucd_u16[9344] = 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282, - 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271, - 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209, - 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279, - 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305, - 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308, - 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, - 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140, - 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209, - 325, 326, 327, 328, 136, 48, 48, 48, 48, 329, 178, 48, 48, 48, 48, 330, - 331, 48, 48, 136, 48, 48, 48, 48, 200, 332, 48, 48, 209, 209, 333, 48, - 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, - 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48, - 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342, - 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, - 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, - 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151, - 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, - 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11, - 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206, - 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, + 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, + 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, + 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, + 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, + 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, 140, 209, + 324, 325, 326, 327, 136, 48, 48, 48, 48, 328, 178, 48, 48, 48, 48, 329, + 330, 48, 48, 136, 48, 48, 48, 48, 200, 331, 48, 48, 209, 209, 332, 48, + 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, + 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, + 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, + 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, + 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, + 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, + 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, + 383, 384, 314, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, @@ -2257,108 +2260,204 @@ _hb_ucd_u16[9344] = 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, - 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140, - 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, + 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, + 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, - 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476, - 48, 48, 477, 478, 140, 140, 140, 479, 48, 464, 480, 48, 62, 481, 140, 48, - 482, 140, 140, 48, 483, 140, 48, 314, 484, 48, 48, 485, 486, 457, 487, 488, - 222, 48, 48, 489, 490, 48, 196, 192, 491, 48, 492, 493, 494, 48, 48, 495, - 222, 48, 48, 496, 497, 498, 499, 500, 48, 97, 501, 502, 503, 140, 140, 140, - 504, 505, 506, 48, 48, 507, 508, 192, 509, 83, 84, 510, 511, 512, 513, 514, - 48, 48, 48, 515, 516, 517, 478, 140, 48, 48, 48, 518, 519, 192, 140, 140, - 48, 48, 520, 521, 522, 523, 140, 140, 48, 48, 48, 524, 525, 192, 526, 140, - 48, 48, 527, 528, 192, 140, 140, 140, 48, 173, 529, 530, 314, 140, 140, 140, - 48, 48, 501, 531, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 532, - 533, 534, 48, 535, 536, 192, 140, 140, 140, 140, 537, 48, 48, 538, 539, 140, - 540, 48, 48, 541, 542, 543, 48, 48, 544, 545, 546, 48, 48, 48, 48, 196, - 547, 140, 140, 140, 140, 140, 140, 140, 84, 48, 520, 548, 549, 148, 175, 550, - 48, 551, 552, 553, 140, 140, 140, 140, 554, 48, 48, 555, 556, 192, 557, 48, - 558, 559, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 560, - 561, 115, 48, 562, 563, 192, 140, 140, 140, 140, 140, 100, 271, 564, 565, 566, - 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 567, 568, - 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 569, - 48, 48, 48, 570, 571, 572, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 573, - 48, 48, 48, 574, 575, 576, 577, 578, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 579, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 580, 581, 582, 582, 583, 584, 140, 140, 140, 140, 585, 586, - 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 587, - 48, 48, 588, 589, 140, 590, 591, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 592, 593, 140, 140, 140, 140, 140, - 32, 32, 594, 32, 595, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 596, 209, 209, 209, 597, 598, - 599, 209, 600, 209, 209, 209, 288, 140, 209, 209, 209, 209, 601, 140, 140, 140, - 140, 140, 140, 140, 271, 602, 271, 602, 209, 209, 209, 209, 209, 287, 271, 461, - 9, 603, 11, 604, 605, 606, 241, 9, 607, 608, 609, 610, 611, 9, 603, 11, - 612, 613, 11, 614, 615, 616, 617, 9, 618, 11, 9, 603, 11, 604, 605, 11, - 241, 9, 607, 617, 9, 618, 11, 9, 603, 11, 619, 9, 620, 621, 622, 623, - 11, 624, 9, 625, 626, 627, 628, 11, 629, 9, 630, 11, 631, 632, 632, 632, - 32, 32, 32, 633, 32, 32, 634, 635, 636, 637, 45, 140, 140, 140, 140, 140, - 638, 639, 640, 140, 140, 140, 140, 140, 641, 642, 643, 27, 27, 27, 644, 140, - 645, 140, 140, 140, 140, 140, 140, 140, 48, 48, 151, 646, 647, 140, 140, 140, - 140, 48, 648, 140, 48, 48, 649, 650, 140, 140, 140, 140, 140, 48, 651, 192, - 140, 140, 140, 140, 140, 140, 652, 200, 48, 48, 48, 48, 653, 595, 140, 140, - 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499, - 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140, - 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668, - 209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324, - 671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209, - 674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677, - 209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679, - 209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209, - 680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426, - 675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192, - 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48, - 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 71, 48, 48, 48, - 48, 48, 48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570, + 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, + 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, + 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, + 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, + 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, + 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, + 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, + 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, + 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, + 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, + 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, + 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, + 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, + 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, + 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, + 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, + 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, + 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, + 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, + 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, + 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, + 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, + 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, + 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, + 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, + 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, + 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, + 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, + 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, + 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, + 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, + 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, + 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, + 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, + 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, + 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, + 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, + 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, + 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, + 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, + 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, + 11, 11, 12, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 57, 58, 59, 60, 60, 60, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 7, 4, 4, 4, 4, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 114, 0, + 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 124, 125, 126, 126, 126, 127, + 128, 129, 130, 131, 132, 60, 133, 134, 135, 136, 0, 137, 138, 139, 0, 0, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 0, 126, 126, 126, 126, 126, 126, 126, 126, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 141, 142, 143, 143, 143, 143, 144, 11, 145, 146, 147, 4, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 166, 167, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 126, 126, 126, 126, 126, 169, 126, 170, 171, 172, 19, 173, + 19, 19, 19, 19, 174, 19, 175, 176, 177, 178, 19, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 168, 168, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 206, 206, 206, 207, 208, 209, 168, + 210, 211, 212, 213, 214, 168, 215, 216, 217, 218, 219, 220, 221, 222, 223, 168, + 224, 225, 226, 227, 228, 229, 230, 168, 168, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 168, 168, 258, 259, 260, 261, 262, 263, 264, 265, 168, 168, + 266, 168, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 168, 168, 278, + 279, 280, 281, 168, 282, 283, 284, 168, 168, 168, 168, 285, 286, 287, 288, 289, + 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, 168, + 290, 292, 290, 290, 290, 293, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 294, 295, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 297, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 298, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 301, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 302, 302, 302, 302, 302, 302, 302, 302, 303, 304, 305, 306, 307, 308, 309, 168, + 168, 168, 168, 168, 168, 310, 168, 168, 168, 311, 312, 168, 313, 314, 315, 316, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 318, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 319, 319, 319, 319, + 319, 319, 319, 320, 321, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 322, + 323, 324, 324, 324, 325, 326, 327, 327, 327, 327, 327, 328, 168, 168, 168, 168, + 329, 330, 331, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 333, 168, 334, 335, 0, 336, + 0, 0, 0, 337, 338, 339, 340, 341, 189, 342, 168, 343, 0, 344, 168, 168, + 0, 345, 346, 347, 348, 349, 0, 0, 0, 0, 350, 0, 0, 0, 0, 351, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 353, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 354, 168, 168, 168, + 355, 356, 357, 168, 358, 359, 168, 168, 168, 168, 360, 361, 168, 168, 168, 168, + 168, 168, 168, 362, 168, 168, 168, 363, 168, 168, 168, 168, 168, 168, 168, 364, + 365, 365, 365, 366, 367, 368, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 369, 370, 168, 371, 168, 168, 168, 372, 373, 374, 375, 168, 168, 168, 168, + 376, 0, 377, 378, 0, 0, 379, 380, 381, 382, 168, 168, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 384, 0, 385, + 386, 387, 388, 389, 0, 0, 0, 0, 0, 390, 391, 392, 0, 0, 393, 332, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 394, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 395, 126, 126, 126, + 396, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 397, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 398, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, + 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, 168, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 400, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 401, 168, + 402, 0, 168, 168, 7, 7, 7, 403, 0, 1, 2, 3, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, - 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, - 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, - 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, - 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, - 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, - 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 31, 31, - 31, 50, 51, 31, 31, 31, 31, 31, 31, 31, 31, 31, 52, 31, 31, 31, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, - 56, 57, 58, 59, 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, - 68, 69, 70, 71, 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, - 80, 81, 82, 83, 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, - 92, 93, 94, 95, 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, - 103, 104, 105, 106, 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, - 113, 114, 115, 113, 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, - 122, 123, 124, 122, 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, - 131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, - 136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, - 146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, - 150, 151, 152, 152, 153, 152, 152, 154, 155, 156, 152, 157, 26, 26, 26, 26, - 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 160, 159, 158, - 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, 26, 26, 26, 26, - 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, + 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, + 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, + 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, + 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, + 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, + 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, + 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, + 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, + 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, + 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, + 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, + 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, + 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, + 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, + 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131, + 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141, + 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148, + 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154, + 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, + 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 172, 171, 170, 170, 170, 170, - 170, 171, 170, 170, 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 170, 170, - 170, 170, 171, 170, 170, 170, 170, 170, 170, 170, 170, 173, 170, 170, 170, 174, - 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, + 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, + 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, @@ -2368,208 +2467,164 @@ _hb_ucd_u16[9344] = 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220, 9, 9, 9, 221, 26, 26, 26, 26, 26, 26, - 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 224, - 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 227, 228, - 229, 229, 229, 229, 229, 229, 229, 230, 229, 231, 232, 232, 232, 232, 232, 232, - 18, 233, 165, 165, 165, 165, 165, 234, 225, 26, 235, 9, 236, 237, 238, 239, - 2, 2, 2, 2, 240, 241, 2, 2, 2, 2, 2, 242, 243, 244, 2, 245, - 2, 2, 2, 2, 2, 2, 2, 246, 9, 9, 9, 9, 9, 9, 9, 9, - 14, 14, 247, 247, 14, 14, 14, 14, 247, 247, 14, 248, 14, 14, 14, 247, - 14, 14, 14, 14, 14, 14, 249, 14, 249, 14, 250, 251, 14, 14, 252, 253, - 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 256, 257, - 0, 258, 2, 259, 0, 0, 0, 0, 260, 26, 9, 9, 9, 9, 261, 26, - 0, 0, 0, 0, 262, 263, 4, 0, 0, 264, 0, 0, 2, 2, 2, 2, - 2, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 258, 26, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, - 0, 0, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 2, 2, 2, 2, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 271, 272, - 165, 165, 165, 165, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, - 170, 170, 172, 26, 172, 172, 172, 172, 172, 172, 172, 172, 18, 18, 18, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, + 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 222, + 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, + 228, 228, 228, 228, 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, + 18, 232, 165, 165, 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, + 2, 2, 2, 2, 239, 240, 2, 2, 2, 2, 2, 241, 242, 243, 2, 244, + 2, 2, 2, 2, 2, 2, 2, 245, 14, 14, 246, 246, 14, 14, 14, 14, + 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 14, 14, 14, 14, 248, 14, + 248, 14, 249, 250, 14, 14, 251, 252, 0, 253, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, 0, 0, 0, 0, + 259, 26, 9, 9, 9, 9, 260, 26, 0, 0, 0, 0, 261, 262, 4, 0, + 0, 263, 0, 0, 2, 2, 2, 2, 2, 264, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, + 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 268, 0, + 0, 0, 269, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273, + 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172, + 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 276, 26, 26, 26, 26, 277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 0, 0, 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, - 292, 293, 293, 293, 293, 293, 294, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 295, 0, 0, 293, 293, 293, 293, 0, 0, 0, 0, 296, 297, 290, 290, - 169, 169, 169, 295, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 298, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 290, 290, 290, 290, 299, + 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, + 0, 0, 0, 0, 276, 296, 290, 290, 169, 169, 169, 295, 0, 0, 0, 0, + 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 290, 290, 290, 290, 290, 298, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, - 277, 277, 277, 277, 277, 277, 277, 277, 0, 0, 0, 0, 0, 0, 0, 0, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 301, 300, 300, 300, 300, 300, 300, 302, 26, 303, 303, 303, 303, 303, 303, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 305, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 26, - 0, 0, 0, 0, 307, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 308, 2, 2, 2, 2, 2, 2, 2, 309, 310, 311, 26, 26, 312, 2, - 313, 313, 313, 313, 313, 314, 0, 315, 316, 316, 316, 316, 316, 316, 316, 26, - 317, 317, 317, 317, 317, 317, 317, 317, 318, 319, 317, 320, 53, 53, 53, 53, - 321, 321, 321, 321, 321, 322, 323, 323, 323, 323, 324, 325, 169, 169, 169, 326, - 327, 327, 327, 327, 327, 327, 327, 327, 327, 328, 327, 329, 164, 164, 164, 330, - 331, 331, 331, 331, 331, 331, 332, 26, 331, 333, 331, 334, 164, 164, 164, 164, - 335, 335, 335, 335, 335, 335, 335, 335, 336, 26, 26, 337, 338, 338, 339, 26, - 340, 340, 340, 26, 172, 172, 2, 2, 2, 2, 2, 341, 342, 343, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 338, 338, 338, 338, 338, 344, 338, 345, - 169, 169, 169, 169, 346, 26, 169, 169, 295, 347, 169, 169, 169, 169, 169, 346, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 348, 26, 26, 26, 26, - 349, 26, 350, 351, 25, 25, 352, 353, 354, 25, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 355, 26, 356, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 357, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 358, 31, 31, 31, 31, 31, 31, 359, 26, 26, 26, 26, 31, 31, - 9, 9, 0, 315, 9, 360, 0, 0, 0, 0, 361, 0, 258, 296, 362, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 363, - 364, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 365, 290, 289, 290, - 290, 290, 290, 366, 169, 169, 169, 295, 367, 367, 367, 368, 258, 258, 26, 369, - 370, 371, 370, 370, 372, 370, 370, 373, 370, 374, 370, 374, 26, 26, 26, 26, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 375, - 376, 0, 0, 0, 0, 0, 377, 0, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 253, 0, 378, 379, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 380, - 381, 381, 381, 382, 383, 383, 383, 383, 383, 383, 384, 26, 385, 0, 0, 296, - 386, 386, 386, 386, 387, 388, 389, 389, 389, 390, 391, 391, 391, 391, 391, 392, - 393, 393, 393, 394, 395, 395, 395, 395, 396, 395, 397, 26, 26, 26, 26, 26, - 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399, 399, 399, 399, 399, 399, - 400, 400, 400, 401, 400, 402, 403, 403, 403, 403, 404, 403, 403, 403, 403, 404, - 405, 405, 405, 405, 405, 26, 406, 406, 406, 406, 406, 406, 407, 408, 409, 410, - 409, 410, 411, 409, 412, 409, 412, 413, 26, 26, 26, 26, 26, 26, 26, 26, - 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, - 414, 414, 414, 414, 414, 414, 415, 26, 414, 414, 416, 26, 414, 26, 26, 26, - 417, 2, 2, 2, 2, 2, 418, 309, 26, 26, 26, 26, 26, 26, 26, 26, - 419, 420, 421, 421, 421, 421, 422, 423, 424, 424, 425, 424, 426, 426, 426, 426, - 427, 427, 427, 428, 429, 427, 26, 26, 26, 26, 26, 26, 430, 430, 431, 432, - 433, 433, 433, 434, 435, 435, 435, 436, 26, 26, 26, 26, 26, 26, 26, 26, - 437, 437, 437, 437, 438, 438, 438, 439, 438, 438, 440, 438, 438, 438, 438, 438, - 441, 442, 443, 444, 445, 445, 446, 447, 445, 448, 445, 448, 449, 449, 449, 449, - 450, 450, 450, 450, 26, 26, 26, 26, 451, 451, 451, 451, 452, 453, 452, 26, - 454, 454, 454, 454, 454, 454, 455, 456, 457, 457, 458, 457, 459, 459, 460, 459, - 461, 461, 462, 463, 26, 464, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 465, 465, 465, 465, 465, 465, 465, 465, 465, 466, 26, 26, 26, 26, 26, 26, - 467, 467, 467, 467, 467, 467, 468, 26, 467, 467, 467, 467, 467, 467, 468, 469, - 470, 470, 470, 470, 470, 26, 470, 471, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, - 472, 472, 472, 472, 472, 473, 474, 26, 26, 26, 26, 26, 26, 26, 26, 475, - 476, 476, 476, 476, 476, 26, 477, 477, 477, 477, 477, 478, 26, 26, 479, 479, - 479, 480, 26, 26, 26, 26, 481, 481, 481, 482, 26, 26, 483, 483, 484, 26, - 485, 485, 485, 485, 485, 485, 485, 485, 485, 486, 487, 485, 485, 485, 486, 488, - 489, 489, 489, 489, 489, 489, 489, 489, 490, 491, 492, 492, 492, 493, 492, 494, - 495, 495, 495, 495, 495, 495, 496, 495, 495, 26, 497, 497, 497, 497, 498, 26, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 500, 137, 501, 26, - 502, 502, 503, 502, 502, 502, 502, 502, 504, 26, 26, 26, 26, 26, 26, 26, - 505, 506, 507, 508, 507, 509, 510, 510, 510, 510, 510, 510, 510, 511, 510, 512, - 513, 514, 515, 516, 516, 517, 518, 519, 514, 520, 521, 522, 523, 524, 524, 26, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 526, 527, 26, 26, 26, - 528, 528, 528, 528, 528, 528, 528, 528, 528, 26, 528, 529, 26, 26, 26, 26, - 530, 530, 530, 530, 530, 530, 531, 530, 530, 530, 530, 531, 26, 26, 26, 26, - 532, 532, 532, 532, 532, 532, 532, 532, 533, 26, 532, 534, 198, 535, 26, 26, - 536, 536, 536, 536, 536, 536, 536, 537, 536, 537, 26, 26, 26, 26, 26, 26, - 538, 538, 538, 539, 538, 540, 538, 538, 541, 26, 26, 26, 26, 26, 26, 26, - 542, 542, 542, 542, 542, 542, 542, 543, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 546, - 547, 548, 549, 550, 550, 550, 551, 552, 547, 26, 550, 553, 26, 26, 26, 26, - 26, 26, 26, 26, 554, 555, 554, 554, 554, 554, 554, 555, 556, 26, 26, 26, - 557, 557, 557, 557, 557, 557, 557, 557, 557, 26, 558, 558, 558, 558, 558, 558, - 558, 558, 558, 558, 559, 26, 178, 178, 560, 560, 560, 560, 560, 560, 560, 561, - 53, 562, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 563, 564, 563, 563, 563, 563, 565, 563, 566, 26, 563, 563, 563, 567, 568, 568, - 568, 568, 569, 568, 568, 570, 571, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 572, 573, 574, 574, 574, 574, 572, 575, 574, 26, 574, 576, 577, 578, 579, 579, - 579, 580, 581, 582, 579, 583, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 584, 584, 584, 585, - 586, 586, 587, 586, 586, 586, 586, 588, 586, 586, 586, 589, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 590, 26, 108, 108, 108, 108, 108, 108, 591, 592, - 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, - 593, 593, 593, 594, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 595, 596, 26, - 593, 593, 593, 593, 593, 593, 593, 593, 597, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 599, 26, - 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, - 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601, 26, 26, 26, 26, 26, - 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, - 602, 602, 602, 602, 602, 602, 602, 602, 603, 26, 26, 26, 26, 26, 26, 26, - 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 306, 306, 306, 306, 306, 306, 306, 604, 605, 605, 605, 606, 605, 607, 608, 608, - 608, 608, 608, 608, 608, 608, 608, 609, 608, 610, 611, 611, 611, 612, 612, 26, - 613, 613, 613, 613, 613, 613, 613, 613, 614, 26, 613, 615, 615, 613, 613, 616, - 613, 613, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 617, 617, 617, 617, 617, 617, 617, 617, - 617, 617, 617, 618, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 619, 619, 619, 619, 619, 619, 619, 619, 619, 620, 619, 619, 619, 619, 619, 619, - 619, 621, 619, 619, 26, 26, 26, 26, 26, 26, 26, 26, 622, 26, 348, 26, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 26, - 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, - 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625, 26, 26, 26, 26, 26, - 623, 626, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 627, 628, - 629, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 630, 26, 631, 26, 26, 26, 632, 26, 633, 26, 634, 634, - 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, - 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 635, - 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 636, 638, - 636, 639, 636, 640, 296, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 9, 9, 9, 9, 9, 641, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 26, - 0, 0, 0, 0, 258, 364, 0, 0, 0, 0, 0, 0, 642, 643, 0, 644, - 645, 646, 0, 0, 0, 647, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, - 14, 14, 14, 14, 14, 14, 14, 14, 247, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 296, 26, 0, 0, 296, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 26, 0, 0, 0, 260, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 255, 648, 649, 0, 650, 651, 0, 0, 0, 0, 0, 0, 0, - 269, 652, 255, 255, 0, 0, 0, 653, 654, 655, 656, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, - 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, - 657, 658, 26, 659, 660, 657, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 2, 2, 2, 349, 661, 309, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 662, 270, 270, 663, 664, 665, 18, 18, 18, 18, 18, 18, 18, 666, 26, 26, - 26, 667, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 668, 668, 668, 668, 668, 669, 668, 670, 668, 671, 26, 26, 26, 26, 26, 26, - 26, 26, 672, 672, 672, 673, 26, 26, 674, 674, 674, 674, 674, 674, 674, 675, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 676, 676, 676, 676, 676, 677, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 172, 678, 170, 172, - 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, - 679, 679, 679, 679, 679, 679, 679, 679, 680, 679, 681, 26, 26, 26, 26, 26, - 682, 682, 682, 682, 682, 682, 682, 682, 682, 683, 682, 684, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 364, 0, - 0, 0, 0, 0, 0, 0, 378, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 364, 0, 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, 26, 26, 26, 26, - 685, 31, 31, 31, 686, 687, 688, 689, 690, 691, 686, 692, 686, 688, 688, 693, - 31, 694, 31, 695, 696, 694, 31, 695, 26, 26, 26, 26, 26, 26, 51, 26, - 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 26, 0, 258, 364, 0, 364, 0, 364, 0, 0, 0, 276, 26, - 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, 26, 26, 697, 0, 0, 0, - 698, 26, 0, 0, 0, 0, 0, 296, 0, 260, 315, 26, 276, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 699, 0, 378, 0, 378, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 700, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 315, 0, 296, 260, 26, - 0, 296, 0, 0, 0, 0, 0, 0, 0, 26, 0, 315, 0, 0, 0, 0, - 0, 26, 0, 0, 0, 276, 315, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 26, 0, 276, 0, 378, - 0, 260, 0, 0, 0, 0, 0, 269, 276, 697, 0, 296, 0, 260, 0, 260, - 0, 0, 361, 0, 0, 0, 0, 0, 0, 266, 26, 26, 26, 26, 0, 315, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, 26, 26, - 277, 277, 277, 277, 277, 277, 277, 348, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 348, 26, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 701, 26, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, - 277, 277, 277, 280, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 702, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 703, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299, + 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 304, 26, 26, 18, 18, 18, 18, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2, + 2, 307, 2, 2, 2, 2, 2, 2, 2, 308, 309, 258, 26, 26, 310, 2, + 311, 311, 311, 311, 311, 312, 0, 265, 313, 313, 313, 313, 313, 313, 313, 26, + 314, 314, 314, 314, 314, 314, 314, 314, 315, 316, 314, 317, 53, 53, 53, 53, + 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, + 324, 324, 324, 324, 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, + 328, 328, 328, 328, 328, 328, 329, 26, 328, 330, 328, 331, 164, 164, 164, 164, + 332, 332, 332, 332, 332, 332, 332, 332, 333, 26, 26, 334, 335, 335, 336, 26, + 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, 339, 340, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, + 169, 169, 169, 169, 343, 26, 169, 169, 295, 344, 169, 169, 169, 169, 169, 343, + 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 280, 277, 277, + 277, 277, 277, 345, 26, 26, 26, 26, 346, 26, 347, 348, 25, 25, 349, 350, + 351, 25, 31, 31, 31, 31, 31, 31, 352, 26, 353, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 354, 31, 31, 355, 31, 31, 31, 31, 31, + 31, 356, 26, 26, 26, 26, 31, 31, 9, 9, 0, 265, 9, 357, 0, 0, + 0, 0, 358, 0, 257, 359, 360, 31, 31, 31, 31, 31, 31, 31, 31, 361, + 362, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 363, 290, 289, 290, + 290, 290, 290, 364, 169, 169, 169, 295, 365, 365, 365, 366, 257, 257, 26, 367, + 368, 369, 368, 368, 370, 368, 368, 371, 368, 372, 368, 372, 26, 26, 26, 26, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 373, + 374, 0, 0, 0, 0, 0, 375, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 252, 0, 376, 377, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 378, + 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, + 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, + 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 26, 26, 26, 26, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, + 398, 398, 398, 399, 398, 400, 401, 401, 401, 401, 402, 401, 401, 401, 401, 402, + 403, 403, 403, 403, 403, 26, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, + 407, 408, 409, 407, 410, 407, 410, 411, 412, 412, 412, 412, 412, 412, 413, 26, + 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 415, 26, + 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, + 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, + 428, 428, 428, 429, 430, 428, 26, 26, 26, 26, 26, 26, 431, 431, 432, 433, + 434, 434, 434, 435, 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, + 439, 439, 441, 439, 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, + 446, 449, 446, 449, 450, 450, 450, 450, 451, 451, 451, 451, 26, 26, 26, 26, + 452, 452, 452, 452, 453, 454, 453, 26, 455, 455, 455, 455, 455, 455, 456, 457, + 458, 458, 459, 458, 460, 460, 461, 460, 462, 462, 463, 464, 26, 465, 26, 26, + 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, 26, 26, 26, 26, 26, 26, + 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 468, 468, 468, 468, 469, 470, + 471, 471, 471, 471, 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, + 474, 476, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, + 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, 26, 26, 26, 481, + 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, 26, 26, 485, 485, + 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, 489, 489, 490, 26, + 491, 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, + 495, 495, 495, 495, 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, + 501, 501, 501, 501, 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, + 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 137, 507, 26, + 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, 26, 26, 26, 26, + 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, + 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, + 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, + 541, 541, 541, 541, 541, 541, 541, 541, 541, 26, 541, 542, 26, 26, 26, 26, + 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, 26, 26, 26, 26, + 545, 545, 545, 545, 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, + 549, 549, 549, 549, 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, + 552, 552, 552, 553, 552, 554, 552, 552, 555, 26, 26, 26, 26, 26, 26, 26, + 556, 556, 556, 556, 556, 556, 556, 557, 26, 26, 26, 26, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, + 561, 26, 564, 567, 26, 26, 26, 26, 26, 26, 26, 26, 568, 569, 568, 568, + 568, 568, 568, 569, 570, 26, 26, 26, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 26, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, + 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 26, 26, 26, 26, + 577, 577, 577, 577, 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, + 582, 26, 579, 579, 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, + 588, 589, 590, 590, 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, + 595, 596, 597, 598, 595, 599, 26, 26, 26, 26, 26, 26, 600, 600, 600, 601, + 602, 602, 603, 602, 602, 602, 602, 604, 602, 602, 602, 605, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, + 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 610, 26, 26, 26, 26, + 609, 609, 609, 609, 609, 611, 612, 26, 613, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 618, 619, 619, 619, 619, 619, 619, 619, 619, + 620, 26, 26, 26, 26, 26, 26, 26, 621, 621, 621, 621, 621, 621, 621, 622, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 623, + 624, 624, 624, 625, 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, + 627, 629, 630, 630, 630, 631, 631, 26, 632, 632, 632, 632, 632, 632, 632, 632, + 633, 26, 632, 634, 634, 632, 632, 635, 632, 632, 26, 26, 26, 26, 26, 26, + 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 639, 26, 26, 26, 26, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 641, 640, 640, 640, 640, 640, 640, 640, 642, 640, 640, 26, 26, 26, 26, + 26, 26, 26, 26, 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 644, + 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, 645, 645, 645, 645, + 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 649, 650, 651, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 652, 26, 653, 26, + 26, 26, 654, 26, 655, 26, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 658, 658, 658, + 658, 658, 658, 658, 658, 659, 658, 660, 658, 661, 658, 662, 359, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 265, 0, 0, 0, 0, 0, 0, 359, 26, + 9, 9, 9, 9, 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, + 359, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 276, 26, + 0, 0, 0, 0, 257, 362, 0, 0, 0, 0, 0, 0, 664, 665, 0, 666, + 667, 668, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, + 246, 26, 26, 26, 26, 26, 26, 26, 0, 0, 359, 26, 0, 0, 359, 26, + 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 0, + 0, 0, 0, 254, 670, 671, 0, 672, 673, 0, 0, 0, 0, 0, 0, 0, + 269, 674, 254, 254, 0, 0, 0, 675, 676, 677, 678, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 276, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 680, 26, 681, 682, 679, 26, 26, + 2, 2, 2, 346, 683, 419, 26, 26, 684, 270, 270, 685, 686, 687, 18, 18, + 18, 18, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, 26, 26, 26, 26, + 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 26, 26, + 26, 26, 694, 694, 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, + 26, 26, 698, 698, 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, + 26, 26, 26, 26, 172, 702, 170, 172, 703, 703, 703, 703, 703, 703, 703, 703, + 704, 703, 705, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 706, 706, 706, + 706, 707, 706, 708, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 362, 0, + 0, 0, 0, 0, 0, 0, 376, 26, 362, 0, 0, 0, 0, 0, 0, 276, + 709, 31, 31, 31, 710, 711, 712, 713, 714, 715, 710, 716, 710, 712, 712, 717, + 31, 718, 31, 719, 720, 718, 31, 719, 26, 26, 26, 26, 26, 26, 721, 26, + 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 359, 26, 0, 257, 362, 0, + 362, 0, 362, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26, + 26, 26, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, + 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, + 0, 0, 0, 0, 0, 0, 257, 725, 0, 0, 0, 265, 0, 359, 259, 26, + 0, 359, 0, 0, 0, 0, 0, 0, 0, 26, 0, 265, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 276, 0, 359, 265, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 359, 26, 0, 276, 0, 376, 0, 726, 0, 0, 0, 0, 0, 0, + 257, 722, 0, 727, 0, 265, 0, 259, 0, 0, 358, 0, 0, 0, 0, 0, + 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 345, + 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 345, 26, 277, 277, + 277, 277, 277, 277, 728, 26, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, + 277, 729, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, + 730, 26, 26, 26, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, @@ -2732,17 +2787,24 @@ _hb_ucd_u16[9344] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950, - 1951,1952,1953,1954,1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959, - 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0,1939, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943,1944, 0, 0, 0, + 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, 0, 0,1947, 0, + 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953,1952, 0,1954, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, 0, 0, 0, 0, + 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1969,1970, + 1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976,1977,1978,1980,1979, + 1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, @@ -2799,12 +2861,12 @@ _hb_ucd_i16[196] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_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<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; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(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<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; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -2814,107 +2876,76 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9548+(((_hb_ucd_u8[9428+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + 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; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[11070+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10334+(((_hb_ucd_u8[9884+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; + 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; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6032+(((_hb_ucd_u8[17084+(((_hb_ucd_u8[16702+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + 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; } #elif !defined(HB_NO_UCD_UNASSIGNED) static const uint8_t -_hb_ucd_u8[14752] = +_hb_ucd_u8[17524] = { - 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, 11, 12, 13, 13, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7, - 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42, - 7, 7, 43, 7, 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 45, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 47, + 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, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, + 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 33, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73, - 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83, - 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34, - 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96, - 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105, - 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, - 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117, - 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131, - 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146, - 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122, - 160,161,162,163,164,165,166,122,167,168,169,170,122,171,172,173, - 34, 34, 34, 34, 34, 34, 34,174,175, 34,176,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,177, - 34, 34, 34, 34, 34, 34, 34, 34,178,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122, 34, 34, 34, 34,179,122,122,122, - 34, 34, 34, 34,180,181,182,183,122,122,122,122,184,185,186,187, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,188, - 34, 34, 34, 34, 34, 34, 34, 34, 34,189,190,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,191, - 34, 34,192, 34, 34,193,122,122,122,122,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,194,195,122,122,122,122,122,122, - 122,122,122,122,122,122,122,122,122,122,122,122,122,122,196,197, - 69,198,199,200,201,202,203,122,204,205,206,207,208,209,210,211, - 69, 69, 69, 69,212,213,122,122,122,122,122,122,122,122,214,122, - 215,216,217,122,122,218,122,122,122,219,122,122,122,122,122,220, - 34,221,222,122,122,122,122,122,223,224,225,122,226,227,122,122, - 228,229,230,231,232,122, 69,233, 69, 69, 69, 69, 69,234,235,236, - 237,238, 69, 69,239,240, 69,241,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,242, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34, - 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34, - 34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122, - 34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122, - 251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255, + 16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45, + 46, 47, 48, 39, 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, 49, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101, + 17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, + 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, + 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, + 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, + 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, + 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, + 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, + 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, + 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, + 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, + 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -2951,7 +2982,7 @@ _hb_ucd_u8[14752] = 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43, + 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, @@ -3024,13 +3055,13 @@ _hb_ucd_u8[14752] = 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64, + 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, + 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, + 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, @@ -3058,33 +3089,33 @@ _hb_ucd_u8[14752] = 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67, - 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67, - 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, - 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, - 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67, - 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149, - 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44, - 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57, - 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61, - 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2, - 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2, - 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44, - 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 44, 44, 44, 44, 44, 1, 2,154,155, 4, 4, 4, 4, - 4, 67, 4, 4, 4, 4,156,157,158,105,105,105,105, 43, 43, 86, - 159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69, - 36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36, - 67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55, - 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67, - 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2, + 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, + 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, + 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, + 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, + 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, + 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, + 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, + 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, + 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, + 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, + 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, + 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, + 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, + 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, + 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, + 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, + 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, + 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, + 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, + 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, + 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, + 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, + 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, + 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, + 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, @@ -3092,7 +3123,7 @@ _hb_ucd_u8[14752] = 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44, + 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, @@ -3153,8 +3184,10 @@ _hb_ucd_u8[14752] = 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44, - 36, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 43, + 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, + 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, + 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, + 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, @@ -3172,14 +3205,18 @@ _hb_ucd_u8[14752] = 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43, - 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71, - 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87, - 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44, - 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44, - 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86, - 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44, + 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, + 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, + 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, + 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, + 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, + 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, + 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, + 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, + 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, @@ -3189,49 +3226,52 @@ _hb_ucd_u8[14752] = 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44, - 2, 36, 36, 36, 36, 36, 36, 36, 44, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 89, 43, 43, 43, 85, 43, 87, 80, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57, - 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36, - 36, 36, 36, 36, 36, 86, 86, 90, 43, 89, 87, 87, 61, 44, 44, 44, - 36, 70, 85,107, 64, 44, 44, 44, 43, 94, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 43, 43, 80, 44, 86, 85, 60, 2, 2, 2, 2, 2, 2, + 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, + 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, + 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, + 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, + 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, + 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, + 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, + 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, + 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44, + 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, + 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44, + 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81, - 36, 61, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44, - 36, 61, 62, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44, - 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44, - 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86, - 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67, - 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44, - 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16, - 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, - 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11, - 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16, - 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16, - 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11, - 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, - 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43, + 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, + 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, + 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, + 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, + 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, + 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, + 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, + 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, + 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, + 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, + 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, + 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, + 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, + 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, + 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, + 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, + 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, @@ -3241,22 +3281,23 @@ _hb_ucd_u8[14752] = 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27, - 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27, - 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163, - 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36, - 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44, - 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, - 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, - 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, - 8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, - 55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67, - 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, - 67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44, - 67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41, - 67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67, - 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55, - 67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67, + 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, + 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, + 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, + 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, + 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, + 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, + 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, + 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, + 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, + 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, + 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, + 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, + 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, @@ -3282,420 +3323,609 @@ _hb_ucd_u8[14752] = 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, - 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, - 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, + 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, - 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, - 0, 0, 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, - 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, - 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, - 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, - 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, - 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, - 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, - 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, - 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, - 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, - 0, 79, 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, - 0, 87, 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, - 80, 0, 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, - 51, 0, 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, - 0, 0, 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, - 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, - 0,107, 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, - 0, 0,110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, - 0, 0, 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, - 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, - 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, - 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, - 0, 27, 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, - 33, 0, 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, - 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, - 42, 0, 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, - 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, - 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, - 0, 56, 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, - 0, 0, 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, - 0, 0, 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, - 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, - 0, 81, 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, - 84, 0, 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, - 0, 0, 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, - 0, 0, 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, - 0, 0, 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, - 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0, - 102, 0, 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106, - 107, 0, 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, - 33, 0,111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, - 0, 0, 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, - 0, 0, 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0, - 121, 0, 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, - 0, 0, 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128, - 129, 0,130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, - 0, 0, 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0, - 138, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, - 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, - 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, - 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, - 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, - 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, - 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, - 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, - 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, - 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, - 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, - 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, - 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, - 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, - 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, - 1, 52, 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, - 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, - 0, 78, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, - 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, - 81, 99,100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, - 0, 0, 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, - 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, - 61, 0, 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, - 0, 0, 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, - 0, 0, 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, + 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, + 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, + 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, + 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, + 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, + 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, + 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, + 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, + 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, + 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, + 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, + 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, + 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, + 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, + 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, + 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, + 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, + 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, + 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, + 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, + 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, + 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, + 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, + 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, + 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, + 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, + 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, + 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, + 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, + 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, + 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, + 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, + 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, + 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, + 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, + 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, + 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, + 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, + 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, + 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, + 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, + 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, + 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, + 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, + 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, + 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, + 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, + 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, + 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, + 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, + 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, + 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, + 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, + 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, + 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, + 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, + 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, + 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, + 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, + 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, + 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, + 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, + 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, + 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, + 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, + 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, + 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, + 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, - 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, - 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, - 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, - 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, - 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, - 0, 0, 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, - 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, - 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, - 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, - 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230, - 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, - 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220, - 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, - 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, - 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230, - 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230, - 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230, - 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0, - 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, - 230,220,220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, - 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, - 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, - 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, - 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, - 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, - 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, - 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, - 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, - 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0, - 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, - 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, - 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, - 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, - 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, - 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, - 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, - 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, - 230,230, 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, - 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, + 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, + 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, + 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, + 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, + 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, + 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, + 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, + 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, + 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, + 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, + 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, + 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, + 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, + 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, + 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, + 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, + 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, + 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, + 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, + 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, + 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, + 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, + 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, + 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, + 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, + 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, + 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, + 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, + 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, + 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, + 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, + 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, + 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, + 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, + 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, + 17, 49, 17, 17, 84, 97,135,145, 26, 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, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, - 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, - 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, - 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, - 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, - 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, - 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, - 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, - 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, - 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, - 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, - 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, - 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, - 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, - 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, - 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, - 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, - 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, - 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, - 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, - 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, - 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, - 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, - 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, - 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, - 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, - 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, - 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, - 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, - 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, - 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, - 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, - 9, 1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, - 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13, - 13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32, - 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, - 7, 41, 13, 42, 7, 7, 43, 7, 44, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, - 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, - 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, - 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101, - 102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116, - 117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131, - 132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145, - 96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158, - 159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164, - 167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171, - 171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96, - 96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185, - 186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204, - 205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96, - 96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215, - 96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221, - 222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59, - 59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 70, 70, - 70, 70,242, 96, 96, 96, 70, 70, 70, 70,243, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,244, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,245, 96, 96, - 96, 96, 96, 96, 96, 96,246, 96,247,248, 0, 1, 2, 2, 0, 1, - 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, - 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, - 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, - 9, 2, 9, 2, 9, 9, 9, 9, 2, 9, 9, 9, 55, 55, 55, 55, - 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 2, 2, 2, 2, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, - 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, - 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, - 2, 2, 90, 90, 90, 2, 95, 95, 95, 95, 2, 2, 95, 2, 3, 3, - 3, 2, 3, 3, 2, 2, 3, 3, 0, 3, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, - 5, 5, 5, 2, 2, 5, 5, 2, 5, 5, 5, 2, 5, 2, 2, 2, - 5, 5, 5, 5, 2, 2, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, - 2, 5, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 2, 11, 2, 2, 11, 2, 11, 2, 2, 2, 11, 11, 2, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, - 2, 2, 10, 2, 2, 2, 2, 2, 10, 10, 2, 21, 21, 21, 21, 21, - 21, 21, 21, 2, 2, 21, 21, 2, 21, 21, 21, 21, 2, 2, 21, 21, - 2, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, - 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 23, 23, 23, 23, 23, 2, - 23, 23, 23, 23, 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, - 2, 2, 2, 2, 23, 23, 2, 2, 2, 23, 16, 16, 16, 16, 16, 2, - 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 2, 16, 16, 2, 2, 2, - 16, 16, 20, 20, 20, 20, 20, 2, 20, 20, 2, 2, 20, 20, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, - 2, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 2, - 36, 2, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, - 18, 2, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, 2, 2, 18, 2, - 18, 2, 25, 25, 25, 25, 2, 25, 25, 25, 25, 2, 2, 2, 25, 2, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 33, 33, 33, 33, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 8, 2, 2, 8, 8, 8, 0, 12, 12, - 12, 12, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 2, 2, 30, 30, 30, 30, 2, 2, 2, 29, 29, 29, 29, 29, 29, - 2, 2, 28, 28, 28, 28, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, - 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 0, - 0, 2, 43, 43, 43, 43, 46, 46, 46, 46, 46, 2, 46, 46, 31, 31, - 31, 31, 31, 31, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 2, 2, 32, 2, 2, 2, 32, 32, 32, 2, 28, 28, - 2, 2, 48, 48, 48, 48, 48, 48, 48, 2, 48, 2, 2, 2, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, - 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 2, 2, - 54, 54, 91, 91, 91, 91, 91, 91, 91, 2, 91, 2, 2, 91, 91, 91, - 2, 2, 1, 1, 1, 2, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62, - 62, 2, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 2, 2, - 2, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 6, 2, - 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 19, 19, - 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, - 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, 9, 9, 2, 2, 2, 9, - 2, 9, 2, 9, 9, 9, 1, 1, 0, 0, 0, 2, 0, 0, 0, 19, - 2, 2, 0, 0, 0, 19, 0, 0, 0, 2, 19, 2, 2, 2, 0, 2, - 2, 2, 1, 2, 2, 2, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, - 27, 27, 2, 2, 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 2, 55, - 55, 55, 61, 61, 61, 61, 2, 2, 2, 61, 61, 2, 2, 2, 0, 0, - 2, 2, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 2, 2, 0, 13, - 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 2, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, - 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 2, 26, - 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 2, 12, 12, - 12, 0, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 2, 86, 86, - 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 19, 19, 19, 2, 19, 19, - 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 19, 19, 60, 60, - 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, - 2, 2, 2, 2, 75, 75, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, - 74, 74, 2, 2, 2, 74, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, - 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, 33, 2, 68, 68, - 68, 68, 68, 68, 68, 2, 68, 68, 2, 2, 92, 92, 92, 92, 92, 92, - 92, 2, 2, 2, 2, 92, 87, 87, 87, 87, 87, 87, 87, 2, 19, 9, - 19, 19, 19, 19, 0, 0, 87, 87, 2, 2, 2, 2, 2, 12, 2, 2, - 2, 4, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 2, 2, - 2, 3, 3, 3, 0, 0, 2, 2, 3, 3, 1, 1, 6, 6, 3, 2, - 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 0, 0, 2, 2, 12, 12, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 2, 49, 49, 2, 49, 49, 49, 2, 2, 9, 2, 2, 2, 0, 1, - 2, 2, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 2, - 2, 2, 42, 42, 42, 42, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, - 41, 2,118,118,118,118,118,118,118, 2, 53, 53, 53, 53, 53, 53, - 2, 53, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 51, 51, - 51, 51, 50, 50, 50, 50, 50, 50, 2, 2,135,135,135,135,106,106, - 106,106,104,104,104,104, 2, 2, 2,104,161,161,161,161,161,161, - 161, 2,161,161, 2,161,161, 2, 2, 2,110,110,110,110,110,110, - 110, 2,110,110, 2, 2, 19, 2, 19, 19, 47, 47, 47, 47, 47, 47, - 2, 2, 47, 2, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, - 2, 47, 81, 81, 81, 81, 81, 81, 2, 81,120,120,120,120,116,116, - 116,116,116,116,116, 2, 2, 2, 2,116,128,128,128,128,128,128, - 128, 2,128,128, 2, 2, 2, 2, 2,128, 66, 66, 66, 66, 2, 2, - 2, 66, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, - 98, 98, 97, 97, 97, 97, 2, 2, 97, 97, 57, 57, 57, 57, 2, 57, - 57, 2, 2, 57, 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, - 2, 57, 57, 2, 2, 2, 88, 88, 88, 88,117,117,117,117,112,112, - 112,112,112,112,112, 2, 2, 2, 2,112, 78, 78, 78, 78, 78, 78, - 2, 2, 2, 78, 78, 78, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, - 82, 82, 82, 82, 82, 2,122,122,122,122,122,122, 2, 2, 2,122, - 122,122,122, 2, 2, 2, 89, 89, 89, 89, 89, 2, 2, 2,130,130, - 130,130,130,130,130, 2, 2, 2,130,130,144,144,144,144,144,144, - 2, 2,156,156,156,156,156,156, 2,156,156,156, 2, 2, 2, 3, - 3, 3,147,147,147,147,148,148,148,148,148,148, 2, 2,158,158, - 158,158,158,158, 2, 2,153,153,153,153,149,149,149,149,149,149, - 149, 2, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 2, 2, - 2, 94, 85, 85, 85, 85, 85, 85, 85, 2, 2, 85, 2, 2,101,101, - 101,101,101, 2, 2, 2,101,101, 2, 2, 96, 96, 96, 96, 96, 2, - 96, 96,111,111,111,111,111,111,111, 2,100,100,100,100,108,108, - 108,108,108,108, 2,108,108,108, 2, 2,129,129,129,129,129,129, - 129, 2,129, 2,129,129,129,129, 2,129,129,129, 2, 2,109,109, - 109,109,109,109,109, 2,109,109, 2, 2,107,107,107,107, 2,107, - 107,107,107, 2, 2,107,107, 2,107,107,107,107, 2, 1,107,107, - 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2,107,107,137,137, - 137,137, 2,137,137,137,137,137, 2, 2,124,124,124,124,124,124, - 2, 2,123,123,123,123,123,123, 2, 2,114,114,114,114,114, 2, - 2, 2,114,114, 2, 2,102,102,102,102,102,102, 2, 2,126,126, - 126,126,126,126,126, 2, 2,126,126,126,142,142,142,142,125,125, - 125,125,125,125,125, 2, 2, 2, 2,125,154,154,154,154,154,154, - 154, 2, 2,154, 2, 2, 2,154,154, 2,154,154, 2,154,154, 2, - 2,154,154,154, 2, 2,150,150,150,150, 2, 2,150,150,150, 2, - 2, 2,141,141,141,141,140,140,140,140,140,140,140, 2,121,121, - 121,121,121, 2, 2, 2, 7, 7, 2, 2,133,133,133,133,133, 2, - 133,133,133,133,133, 2,133,133, 2, 2,133, 2, 2, 2,134,134, - 134,134, 2, 2,134,134, 2,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138, 2, 2,138, 2,138,138, - 2, 2,143,143,143,143,143,143, 2,143,143, 2,143,143,143,143, - 143, 2,143, 2, 2, 2,143,143, 2, 2,145,145,145,145,145, 2, - 2, 2,163,163,163,163,163, 2,163,163,163,163,163, 2, 2, 2, - 163,163,163,163, 2, 2, 86, 2, 2, 2, 63, 63, 63, 63, 63, 63, - 2, 2, 63, 63, 63, 2, 63, 2, 2, 2,157,157,157,157,157,157, - 157, 2, 80, 80, 80, 80, 80, 80, 2, 2,127,127,127,127,127,127, - 127, 2, 79, 2, 2, 2,115,115,115,115,115,115,115, 2,115,115, - 2, 2, 2, 2,115,115,159,159,159,159,159,159,159, 2,159,159, - 2, 2,103,103,103,103,103,103, 2, 2,119,119,119,119,119,119, - 2, 2,119,119, 2,119, 2,119,119,119,146,146,146,146,146,146, - 146, 2, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99,136,139, - 13, 13,155, 2, 2, 2,136,136,136,136,155,155,155,155,155,155, - 2, 2,136, 2, 2, 2, 2, 17, 17, 17, 2, 17, 17, 2, 17, 15, - 15, 15, 17, 17, 17, 2, 2, 2, 15, 2, 2, 17, 2, 2,139,139, - 139,139,105,105,105,105,105,105,105, 2,105, 2, 2, 2,105,105, - 2, 2, 1, 1, 2, 2, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, - 1, 1, 2, 2, 0, 2, 2, 0, 0, 2, 0, 2, 0, 2,131,131, - 131,131, 2, 2, 2,131, 2,131,131,131, 56, 56, 56, 2, 56, 2, - 2, 56, 56, 56, 2, 56, 56, 2, 56, 56, 6, 6, 2, 2, 2, 2, - 2, 6,151,151,151,151,151, 2, 2, 2,151,151, 2, 2, 2, 2, - 151,151,160,160,160,160,160,160,160, 2,152,152,152,152,152,152, - 2, 2, 2, 2, 2,152,164,164,164,164,164,164, 2, 2, 2, 30, - 30, 2,113,113,113,113,113, 2, 2,113,113,113,113, 2,132,132, - 132,132,132,132, 2, 2, 2, 2,132,132, 2, 3, 3, 2, 3, 2, - 2, 3, 2, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, - 2, 3, 15, 0, 0, 2, 13, 2, 2, 2, 13, 13, 13, 2, 2, 0, - 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, - 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, + 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, + 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, + 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, + 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, + 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, + 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, + 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, + 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, + 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, + 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, + 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, + 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, + 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, + 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, + 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, + 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, + 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, + 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, + 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, + 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, + 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, + 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, + 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, + 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, + 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, + 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, + 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, + 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, + 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 9, 16, 17, 18, 9, 19, 20, 21, 22, 23, 24, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 25, 26, 27, 5, 28, 29, 5, 30, 31, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 32, 0, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 1, 29, 30, 31, + 32, 32, 33, 32, 32, 32, 34, 32, 32, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 46, 46, + 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 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, 17, 17, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 44, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, + 95, 96, 97, 98, 56, 56, 56, 56, 56, 56, 56, 56, 56, 99,100,100, + 100,100,101,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,102,103,103,104, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,105, + 56, 56, 56, 56, 56, 56,106,106,107,108, 56,109,110,111,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 112,112,112,112,112,113,112,112,112,114,115,116, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,117,118,119, + 120, 56, 56, 56, 56, 56, 56, 56, 56, 56,121, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,122, 32,123,124,125,126, + 127,128,129,130,131,132,133,133,134, 56, 56, 56, 56,135,136,137, + 138, 56,139,140, 56,141,142,143, 56, 56,144,145,146, 56,147,148, + 149, 32, 32, 32,150,151,152, 32,153,154, 56, 56, 56, 56, 44, 44, + 44, 44, 44, 44,155, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44,156,157, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,158, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44,159, 44, 44,160, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 44, 44,161, 56, 56, 56, 56, 56, 44, 44, + 44,162, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44,163, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,164,165, + 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, + 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, + 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, + 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, + 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, + 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, + 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, + 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, + 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, + 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, + 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, + 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, + 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, + 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, + 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, + 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, + 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, + 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, + 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, + 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, + 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, + 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, + 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, + 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, + 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, + 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, + 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, + 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, + 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, + 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, + 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, + 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, + 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, + 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, + 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, + 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, + 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, + 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, + 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, + 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, + 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, + 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, + 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, + 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, + 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, + 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, + 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, + 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, + 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, + 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, + 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, + 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, + 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, + 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, + 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, + 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 6, + 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, + 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, + 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, + 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, + 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, + 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, + 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, + 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, + 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, + 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, + 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, + 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, + 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, + 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, + 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, + 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, + 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, + 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 2, 2, + 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, + 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, + 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, + 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, + 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, + 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, + 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, + 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, + 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, + 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, + 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, + 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, + 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, + 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, + 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, + 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, + 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, + 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, + 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, + 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, + 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,170,170, + 170,170,170,170,170,170,170,170,170,170, 2, 2, 2, 2,110,110, + 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, + 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 47, 47, + 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, + 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116, + 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, + 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128, + 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, + 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, + 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, + 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, + 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, + 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, + 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112, + 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, + 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122, + 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, + 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130, + 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, + 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, + 2, 2, 2, 2, 2, 2,165,165,165,165,165,165,165,165,165,165, + 165,165,165,165, 2, 2, 2,165,165,165,165,165,165,165, 2, 2, + 2, 2, 2, 2,165,165,156,156,156,156,156,156,156,156,156,156, + 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,147,147, + 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, + 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, + 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, + 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, + 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, + 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, + 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, + 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, + 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, + 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, + 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, + 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, + 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, + 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, + 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, + 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, + 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, + 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, + 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, + 107,107,107, 2, 2, 2,171,171,171,171,171,171,171,171,171,171, + 2,171, 2, 2,171, 2,171,171,171,171,171,171, 2,171,171, 2, + 171, 2, 2,171, 2,171,171,171,171, 2,171,171,171,171,171, 2, + 2, 2, 2, 2, 2, 2, 2,171,171, 2, 2, 2, 2, 2,137,137, + 137,137,137,137,137,137,137,137,137,137, 2,137,137,137,137,137, + 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, + 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, + 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, + 114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, + 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, + 2, 2, 2, 2, 2, 2, 33, 33, 33, 33, 2, 2, 2, 2,126,126, + 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, + 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, + 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, + 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, + 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, + 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, + 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, + 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, + 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, + 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, + 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, + 2, 2, 2, 2, 2, 2,169,169,169,169,169,169,169,169,169,169, + 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, + 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, + 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, + 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, + 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, + 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, + 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, + 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, + 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, + 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, + 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, + 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, + 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, + 163, 2, 2, 2,163,163,163,163,163, 2, 2, 2, 2, 2, 86, 2, + 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, + 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, + 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2, 80, 80, + 80, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, + 127,127,127,127,127, 2,166,166,166,166,166,166,166,166,166,166, + 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, + 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, + 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, + 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, + 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, + 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,167,167, + 167,167,167,167,167,167,167,167, 2, 2, 2, 2, 2, 2,146,146, + 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, + 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, + 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, + 155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2,155,136, 2, + 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, + 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, + 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, + 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, + 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, + 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, + 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, + 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, + 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, + 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, + 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, + 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, + 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, + 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, + 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, + 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, + 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, + 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, + 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2,168,168, + 168,168,168,168,168,168,168,168,168, 2, 2, 2, 2,168, 30, 30, + 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, + 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, + 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, + 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, + 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, + 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, + 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 13, 2, + 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, + 21, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -3704,60 +3934,66 @@ _hb_ucd_u8[14752] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, - 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, + 9, 9, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, + 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, + 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, + 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, + 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, + 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, + 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, + 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, - 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, - 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, - 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0, + 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, + 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124, + 125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138,139, + 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, + 156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102, - 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0, - 108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, - 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0,127, + 162, 0,163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, + 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0, + 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, 0, - 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, - 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0, - 173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188, - 189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204, - 205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178, + 179, 0, 0, 0,180,181,182,183,184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, + 208,209,210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[10060] = +_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, @@ -3776,9 +4012,10 @@ _hb_ucd_u16[10060] = 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, - 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, - 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, + 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, + 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, @@ -3791,28 +4028,34 @@ _hb_ucd_u16[10060] = 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282, - 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271, - 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209, - 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279, - 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305, - 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308, - 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, - 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140, - 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209, - 325, 326, 327, 328, 136, 48, 48, 48, 48, 329, 178, 48, 48, 48, 48, 330, - 331, 48, 48, 136, 48, 48, 48, 48, 200, 332, 48, 48, 209, 209, 333, 48, - 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, - 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48, - 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342, - 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, - 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, - 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151, - 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, - 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11, - 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206, - 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, + 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, + 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, + 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, + 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, + 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, + 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, 140, 209, + 324, 325, 326, 327, 136, 48, 48, 48, 48, 328, 178, 48, 48, 48, 48, 329, + 330, 48, 48, 136, 48, 48, 48, 48, 200, 331, 48, 48, 209, 209, 332, 48, + 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, + 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, + 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, + 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, + 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, + 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, + 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, + 383, 384, 314, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, @@ -3823,571 +4066,540 @@ _hb_ucd_u16[10060] = 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, - 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140, - 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, + 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, + 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, - 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476, - 48, 48, 477, 478, 140, 140, 140, 479, 48, 464, 480, 48, 62, 481, 140, 48, - 482, 140, 140, 48, 483, 140, 48, 314, 484, 48, 48, 485, 486, 457, 487, 488, - 222, 48, 48, 489, 490, 48, 196, 192, 491, 48, 492, 493, 494, 48, 48, 495, - 222, 48, 48, 496, 497, 498, 499, 500, 48, 97, 501, 502, 503, 140, 140, 140, - 504, 505, 506, 48, 48, 507, 508, 192, 509, 83, 84, 510, 511, 512, 513, 514, - 48, 48, 48, 515, 516, 517, 478, 140, 48, 48, 48, 518, 519, 192, 140, 140, - 48, 48, 520, 521, 522, 523, 140, 140, 48, 48, 48, 524, 525, 192, 526, 140, - 48, 48, 527, 528, 192, 140, 140, 140, 48, 173, 529, 530, 314, 140, 140, 140, - 48, 48, 501, 531, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 532, - 533, 534, 48, 535, 536, 192, 140, 140, 140, 140, 537, 48, 48, 538, 539, 140, - 540, 48, 48, 541, 542, 543, 48, 48, 544, 545, 546, 48, 48, 48, 48, 196, - 547, 140, 140, 140, 140, 140, 140, 140, 84, 48, 520, 548, 549, 148, 175, 550, - 48, 551, 552, 553, 140, 140, 140, 140, 554, 48, 48, 555, 556, 192, 557, 48, - 558, 559, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 560, - 561, 115, 48, 562, 563, 192, 140, 140, 140, 140, 140, 100, 271, 564, 565, 566, - 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 567, 568, - 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 569, - 48, 48, 48, 570, 571, 572, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 573, - 48, 48, 48, 574, 575, 576, 577, 578, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 579, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 580, 581, 582, 582, 583, 584, 140, 140, 140, 140, 585, 586, - 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 587, - 48, 48, 588, 589, 140, 590, 591, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 592, 593, 140, 140, 140, 140, 140, - 32, 32, 594, 32, 595, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 596, 209, 209, 209, 597, 598, - 599, 209, 600, 209, 209, 209, 288, 140, 209, 209, 209, 209, 601, 140, 140, 140, - 140, 140, 140, 140, 271, 602, 271, 602, 209, 209, 209, 209, 209, 287, 271, 461, - 9, 603, 11, 604, 605, 606, 241, 9, 607, 608, 609, 610, 611, 9, 603, 11, - 612, 613, 11, 614, 615, 616, 617, 9, 618, 11, 9, 603, 11, 604, 605, 11, - 241, 9, 607, 617, 9, 618, 11, 9, 603, 11, 619, 9, 620, 621, 622, 623, - 11, 624, 9, 625, 626, 627, 628, 11, 629, 9, 630, 11, 631, 632, 632, 632, - 32, 32, 32, 633, 32, 32, 634, 635, 636, 637, 45, 140, 140, 140, 140, 140, - 638, 639, 640, 140, 140, 140, 140, 140, 641, 642, 643, 27, 27, 27, 644, 140, - 645, 140, 140, 140, 140, 140, 140, 140, 48, 48, 151, 646, 647, 140, 140, 140, - 140, 48, 648, 140, 48, 48, 649, 650, 140, 140, 140, 140, 140, 48, 651, 192, - 140, 140, 140, 140, 140, 140, 652, 200, 48, 48, 48, 48, 653, 595, 140, 140, - 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499, - 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140, - 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668, - 209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324, - 671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209, - 674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677, - 209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679, - 209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209, - 680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426, - 675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192, - 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48, - 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 71, 48, 48, 48, - 48, 48, 48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570, + 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, + 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, + 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, + 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, + 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, + 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, + 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, + 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, + 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, + 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, + 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, + 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, + 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, + 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, + 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, + 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, + 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, + 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, + 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, + 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, + 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, + 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, + 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, + 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, + 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, + 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, + 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, + 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, + 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, + 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, + 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, + 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, + 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, + 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, + 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, + 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, + 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, + 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, + 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, + 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686, - 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, - 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 11, 11, 11, 13, 11, - 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, - 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, - 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, - 39, 39, 40, 41, 42, 43, 44, 27, 45, 46, 27, 27, 27, 27, 47, 27, - 48, 48, 48, 48, 48, 49, 50, 48, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 109, 110, 111, 112, 109, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 122, 123, 122, 124, 125, 125, 126, 127, 128, 129, 130, 131, 125, 125, - 132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137, 125, 125, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141, - 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 143, 143, 144, 145, 143, 143, - 144, 143, 143, 146, 147, 148, 143, 143, 143, 147, 143, 143, 143, 149, 143, 150, - 143, 151, 152, 152, 152, 152, 152, 153, 154, 154, 154, 154, 154, 154, 154, 154, - 155, 156, 157, 157, 157, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 168, 168, 168, 168, 169, 170, 170, 171, 172, 173, 173, 173, 173, 173, 174, - 173, 173, 175, 154, 154, 154, 154, 176, 177, 178, 179, 179, 180, 181, 182, 183, - 184, 184, 185, 184, 186, 187, 168, 168, 188, 189, 190, 190, 190, 191, 190, 192, - 193, 193, 194, 8, 195, 125, 125, 125, 196, 196, 196, 196, 197, 196, 196, 198, - 199, 199, 199, 199, 200, 200, 200, 201, 202, 202, 202, 203, 204, 205, 205, 205, - 206, 139, 139, 207, 208, 209, 210, 211, 4, 4, 212, 4, 4, 213, 214, 215, - 4, 4, 4, 216, 8, 8, 8, 8, 11, 217, 11, 11, 217, 218, 11, 219, - 11, 11, 11, 220, 220, 221, 11, 222, 223, 0, 0, 0, 0, 0, 224, 225, - 226, 227, 0, 0, 228, 8, 8, 229, 0, 0, 230, 231, 232, 0, 4, 4, - 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 234, 125, 235, 125, 0, 0, 236, 236, 236, 236, 236, 236, 236, 236, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 238, 0, 0, 0, 0, 0, 0, - 239, 239, 239, 239, 239, 239, 4, 4, 240, 240, 240, 240, 240, 240, 240, 241, - 139, 139, 140, 242, 242, 242, 243, 244, 143, 245, 246, 246, 246, 246, 14, 14, - 0, 0, 0, 0, 0, 247, 125, 125, 248, 249, 248, 248, 248, 248, 248, 250, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 125, 0, - 252, 0, 253, 254, 255, 256, 256, 256, 256, 257, 258, 259, 259, 259, 259, 260, - 261, 262, 262, 263, 142, 142, 142, 142, 264, 0, 262, 262, 0, 0, 265, 259, - 142, 264, 0, 0, 0, 0, 142, 266, 0, 0, 0, 0, 0, 259, 259, 267, - 259, 259, 259, 259, 259, 268, 0, 0, 248, 248, 248, 248, 0, 0, 0, 0, - 269, 269, 269, 269, 269, 269, 269, 269, 270, 269, 269, 269, 271, 272, 272, 272, - 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 125, 14, 14, 14, 14, - 14, 14, 275, 275, 275, 275, 275, 276, 0, 0, 277, 4, 4, 4, 4, 4, - 278, 4, 4, 4, 279, 280, 125, 281, 282, 282, 283, 284, 285, 285, 285, 286, - 287, 287, 287, 287, 288, 289, 48, 48, 290, 290, 291, 292, 292, 293, 142, 294, - 295, 295, 295, 295, 296, 297, 138, 298, 299, 299, 299, 300, 301, 302, 138, 138, - 303, 303, 303, 303, 304, 305, 306, 307, 308, 309, 246, 4, 4, 310, 311, 152, - 152, 152, 152, 152, 306, 306, 312, 313, 142, 142, 314, 142, 315, 142, 142, 316, - 125, 125, 125, 125, 125, 125, 125, 125, 248, 248, 248, 248, 248, 248, 317, 248, - 248, 248, 248, 248, 248, 318, 125, 125, 319, 320, 21, 321, 322, 27, 27, 27, - 27, 27, 27, 27, 323, 324, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 325, 27, 27, 27, 27, 27, 326, 27, 27, 327, 125, 125, 27, - 8, 284, 328, 0, 0, 329, 330, 331, 27, 27, 27, 27, 27, 27, 27, 332, - 333, 0, 1, 2, 1, 2, 334, 258, 259, 335, 142, 264, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 344, 125, 125, 341, 341, 341, 341, 341, 341, 341, 345, - 346, 0, 0, 347, 11, 11, 11, 11, 348, 349, 350, 125, 125, 0, 0, 351, - 352, 353, 354, 354, 354, 355, 356, 357, 358, 358, 359, 360, 361, 362, 362, 363, - 364, 365, 366, 366, 367, 368, 125, 125, 369, 369, 369, 369, 369, 370, 370, 370, - 371, 372, 373, 374, 374, 375, 374, 376, 377, 377, 378, 379, 379, 379, 380, 381, - 381, 382, 383, 384, 125, 125, 125, 125, 385, 385, 385, 385, 385, 385, 385, 385, - 385, 385, 385, 386, 385, 387, 388, 125, 389, 4, 4, 390, 125, 125, 125, 125, - 391, 392, 392, 393, 394, 395, 396, 396, 397, 398, 399, 125, 125, 125, 400, 401, - 402, 403, 404, 405, 125, 125, 125, 125, 406, 406, 407, 408, 407, 409, 407, 407, - 410, 411, 412, 413, 414, 414, 415, 415, 416, 416, 125, 125, 417, 417, 418, 419, - 420, 420, 420, 421, 422, 423, 424, 425, 426, 427, 428, 125, 125, 125, 125, 125, - 429, 429, 429, 429, 430, 125, 125, 125, 431, 431, 431, 432, 431, 431, 431, 433, - 434, 434, 435, 436, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 27, 45, - 437, 437, 438, 439, 125, 125, 125, 440, 441, 441, 442, 443, 443, 444, 125, 445, - 446, 125, 125, 447, 448, 125, 449, 450, 451, 451, 451, 451, 452, 453, 451, 454, - 455, 455, 455, 455, 456, 457, 458, 459, 460, 460, 460, 461, 462, 463, 463, 464, - 465, 465, 465, 465, 465, 465, 466, 467, 468, 469, 468, 468, 470, 125, 125, 125, - 471, 472, 473, 474, 474, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 485, 485, 485, 485, 486, 487, 125, 488, 488, 488, 488, 489, 490, 125, 125, - 491, 491, 491, 492, 491, 493, 125, 125, 494, 494, 494, 494, 495, 496, 497, 125, - 498, 498, 498, 499, 499, 125, 125, 125, 500, 501, 502, 500, 503, 125, 125, 125, - 504, 504, 504, 505, 125, 125, 125, 125, 125, 125, 506, 506, 506, 506, 506, 507, - 508, 509, 510, 511, 512, 513, 125, 125, 125, 125, 514, 515, 515, 514, 516, 125, - 517, 517, 517, 517, 518, 519, 519, 519, 519, 519, 520, 154, 521, 521, 521, 522, - 523, 125, 125, 125, 125, 125, 125, 125, 524, 525, 525, 526, 527, 525, 528, 529, - 529, 530, 531, 532, 125, 125, 125, 125, 533, 534, 534, 535, 536, 537, 538, 539, - 540, 541, 542, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 543, 544, - 545, 546, 545, 547, 545, 548, 125, 125, 125, 125, 125, 549, 550, 550, 550, 551, - 552, 552, 552, 552, 552, 552, 552, 552, 552, 553, 125, 125, 125, 125, 125, 125, - 552, 552, 552, 552, 552, 552, 554, 555, 552, 552, 552, 552, 556, 125, 125, 125, - 125, 557, 557, 557, 557, 557, 557, 558, 559, 559, 559, 559, 559, 559, 559, 559, - 559, 559, 559, 559, 559, 560, 125, 125, 561, 561, 561, 561, 561, 561, 561, 561, - 561, 561, 561, 561, 562, 125, 125, 125, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 563, 564, 565, 566, 567, 567, 567, 567, 568, 569, 570, 571, 572, - 573, 573, 573, 573, 574, 575, 576, 577, 573, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 578, 578, 578, 578, 578, 579, 125, 125, 125, 125, 125, 125, - 580, 580, 580, 580, 581, 580, 580, 580, 582, 580, 125, 125, 125, 125, 583, 584, - 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 586, - 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 125, 125, - 589, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 590, - 591, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 592, 593, 125, 594, 595, 596, 596, 596, 596, 596, 596, 596, 596, 596, - 596, 596, 596, 596, 596, 596, 596, 597, 598, 598, 598, 598, 598, 598, 599, 600, - 601, 602, 603, 125, 125, 125, 125, 125, 8, 8, 604, 8, 605, 0, 0, 0, - 0, 0, 0, 0, 603, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 606, - 0, 0, 607, 0, 0, 0, 608, 609, 610, 0, 611, 0, 0, 0, 235, 125, - 11, 11, 11, 11, 612, 125, 125, 125, 125, 125, 125, 125, 0, 603, 0, 603, - 0, 0, 0, 0, 0, 234, 0, 613, 0, 0, 0, 0, 0, 224, 0, 0, - 0, 614, 615, 616, 617, 0, 0, 0, 618, 619, 0, 620, 621, 622, 0, 0, - 0, 0, 623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 624, 0, 0, 0, - 625, 625, 625, 625, 625, 625, 625, 625, 626, 627, 628, 125, 125, 125, 125, 125, - 4, 629, 630, 125, 125, 125, 125, 125, 631, 632, 633, 14, 14, 14, 634, 125, - 635, 125, 125, 125, 125, 125, 125, 125, 636, 636, 637, 638, 639, 125, 125, 125, - 125, 640, 641, 125, 642, 642, 642, 643, 125, 125, 125, 125, 125, 644, 644, 645, - 125, 125, 125, 125, 125, 125, 646, 647, 648, 648, 648, 648, 648, 648, 648, 648, - 648, 648, 648, 648, 649, 650, 125, 125, 651, 651, 651, 651, 652, 653, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 333, 0, 0, 0, 654, 125, 125, 125, 125, - 333, 0, 0, 247, 125, 125, 125, 125, 655, 27, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 663, 125, 125, 125, 665, 0, 0, 357, 0, 0, 0, 0, 0, - 0, 603, 226, 333, 333, 333, 0, 606, 0, 0, 247, 125, 125, 125, 666, 0, - 667, 0, 0, 357, 613, 668, 606, 125, 0, 0, 0, 0, 0, 669, 349, 349, - 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 284, 357, 228, - 357, 0, 0, 0, 671, 284, 0, 0, 671, 0, 247, 668, 125, 125, 125, 125, - 0, 0, 0, 0, 0, 603, 247, 349, 613, 0, 0, 672, 673, 357, 613, 613, - 0, 329, 0, 0, 235, 125, 125, 284, 248, 248, 248, 248, 248, 248, 125, 125, - 248, 248, 248, 318, 248, 248, 248, 248, 248, 317, 248, 248, 248, 248, 248, 248, - 248, 248, 584, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 674, 248, - 248, 248, 248, 248, 248, 317, 125, 125, 248, 317, 125, 125, 125, 125, 125, 125, - 248, 248, 248, 248, 675, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125, - 676, 125, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2, - 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, - 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 8, 8, 8, 8, 16, 8, 8, 8, 17, 18, 18, 18, - 19, 19, 19, 19, 19, 20, 19, 19, 21, 22, 22, 22, 22, 22, 22, 22, - 22, 23, 21, 22, 22, 22, 23, 21, 24, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 12, 12, 25, 25, 26, 27, 25, 28, 12, 12, 29, 30, 29, 31, - 29, 29, 32, 32, 29, 29, 29, 29, 31, 29, 33, 7, 7, 34, 29, 29, - 35, 29, 29, 29, 29, 29, 29, 30, 36, 36, 36, 37, 36, 36, 36, 36, - 36, 36, 38, 39, 40, 40, 40, 40, 41, 12, 12, 12, 42, 42, 42, 42, - 42, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 45, 45, 45, 47, - 48, 48, 48, 48, 48, 48, 48, 49, 36, 36, 38, 12, 29, 29, 29, 50, - 51, 12, 29, 29, 52, 29, 29, 29, 53, 53, 53, 53, 54, 55, 53, 53, - 53, 56, 53, 53, 57, 58, 57, 59, 59, 57, 57, 57, 57, 57, 60, 57, - 61, 62, 63, 57, 57, 59, 59, 64, 12, 65, 12, 66, 57, 62, 57, 57, - 57, 57, 57, 64, 67, 67, 68, 69, 70, 71, 71, 71, 71, 71, 72, 71, - 72, 73, 74, 72, 68, 69, 70, 74, 75, 12, 67, 76, 12, 77, 71, 71, - 71, 68, 12, 12, 78, 78, 79, 80, 80, 79, 79, 79, 79, 79, 81, 79, - 81, 78, 82, 79, 79, 80, 80, 82, 83, 12, 12, 12, 79, 84, 79, 79, - 82, 12, 78, 79, 85, 85, 86, 87, 87, 86, 86, 86, 86, 86, 88, 86, - 88, 85, 89, 86, 86, 87, 87, 89, 12, 85, 12, 90, 86, 91, 86, 86, - 86, 86, 12, 12, 92, 93, 94, 92, 95, 96, 97, 95, 98, 99, 94, 92, - 100, 100, 96, 92, 94, 92, 95, 96, 99, 98, 12, 12, 12, 92, 100, 100, - 100, 100, 94, 12, 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101, - 101, 101, 103, 101, 101, 102, 102, 103, 12, 104, 105, 106, 101, 107, 101, 101, - 12, 108, 101, 101, 109, 109, 109, 110, 110, 109, 109, 109, 109, 109, 110, 109, - 109, 111, 112, 109, 109, 110, 110, 112, 12, 113, 12, 113, 109, 114, 109, 109, - 111, 12, 12, 12, 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115, - 115, 116, 116, 115, 12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119, - 119, 120, 121, 119, 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125, - 119, 126, 119, 119, 12, 121, 119, 119, 121, 127, 12, 12, 128, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 130, 131, 129, 129, 129, 12, 12, 12, 12, 12, - 132, 133, 134, 135, 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137, - 135, 138, 135, 134, 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139, - 139, 139, 139, 141, 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144, 12, - 145, 145, 145, 145, 146, 146, 146, 146, 146, 147, 12, 148, 146, 146, 149, 146, - 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153, - 152, 153, 151, 154, 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155, - 151, 151, 151, 156, 151, 151, 153, 12, 157, 157, 157, 157, 157, 158, 157, 158, - 159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162, - 162, 162, 163, 164, 162, 162, 165, 12, 166, 166, 166, 166, 166, 167, 12, 168, - 169, 169, 169, 169, 169, 170, 12, 12, 171, 171, 171, 171, 171, 12, 12, 12, - 172, 172, 172, 173, 173, 12, 12, 12, 174, 174, 174, 174, 174, 174, 174, 175, - 174, 174, 175, 12, 176, 177, 178, 178, 178, 178, 179, 12, 178, 178, 178, 178, - 178, 178, 180, 12, 178, 178, 181, 12, 159, 182, 12, 12, 183, 183, 183, 183, - 183, 183, 183, 184, 183, 183, 183, 12, 185, 183, 183, 183, 186, 186, 186, 186, - 186, 186, 186, 187, 186, 188, 12, 12, 189, 189, 189, 189, 189, 189, 189, 12, - 189, 189, 190, 12, 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194, - 195, 195, 195, 195, 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198, 12, - 195, 195, 195, 198, 7, 7, 7, 199, 200, 200, 200, 200, 200, 200, 200, 201, - 200, 200, 200, 202, 203, 203, 203, 203, 204, 204, 204, 204, 204, 12, 12, 204, - 205, 205, 205, 205, 205, 205, 206, 205, 205, 205, 207, 208, 209, 209, 209, 209, - 19, 19, 210, 12, 146, 146, 211, 212, 203, 203, 12, 12, 213, 7, 7, 7, - 214, 7, 215, 216, 0, 215, 217, 12, 2, 218, 219, 2, 2, 2, 2, 220, - 221, 218, 222, 2, 2, 2, 223, 2, 2, 2, 2, 224, 8, 225, 8, 225, - 8, 8, 226, 226, 8, 8, 8, 225, 8, 15, 8, 8, 8, 10, 8, 227, - 10, 15, 8, 14, 0, 0, 0, 228, 0, 229, 0, 0, 230, 0, 0, 231, - 0, 0, 0, 232, 2, 2, 2, 233, 234, 12, 12, 12, 235, 12, 12, 12, - 0, 236, 237, 0, 4, 0, 0, 0, 0, 0, 0, 4, 2, 2, 5, 12, - 0, 232, 12, 12, 0, 0, 232, 12, 238, 238, 238, 238, 0, 239, 0, 0, - 0, 240, 0, 0, 241, 241, 241, 241, 18, 18, 18, 18, 18, 12, 242, 18, - 243, 243, 243, 243, 243, 243, 12, 244, 245, 12, 12, 244, 151, 154, 12, 12, - 151, 154, 151, 154, 0, 0, 0, 246, 247, 247, 247, 247, 247, 247, 248, 247, - 247, 12, 12, 12, 247, 249, 12, 12, 0, 250, 0, 0, 251, 247, 252, 253, - 0, 0, 247, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 256, 257, 258, - 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259, 12, 262, 263, 263, - 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265, 0, 12, 12, 131, - 150, 150, 150, 266, 260, 260, 260, 261, 260, 260, 0, 0, 267, 267, 267, 267, - 267, 267, 267, 268, 267, 269, 12, 12, 270, 270, 270, 270, 271, 271, 271, 271, - 271, 271, 271, 12, 272, 272, 272, 272, 272, 272, 12, 12, 237, 2, 2, 2, - 2, 2, 231, 2, 2, 2, 273, 12, 274, 275, 276, 12, 277, 2, 2, 2, - 278, 278, 278, 278, 278, 278, 278, 279, 0, 0, 246, 12, 280, 280, 280, 280, - 280, 280, 12, 12, 281, 281, 281, 281, 281, 282, 12, 283, 281, 281, 282, 12, - 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286, 286, 12, 12, 287, - 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290, 289, 289, 291, 292, - 145, 145, 145, 293, 294, 294, 294, 294, 294, 295, 12, 12, 294, 294, 294, 296, - 294, 294, 296, 294, 297, 297, 297, 297, 298, 12, 12, 12, 12, 12, 299, 297, - 300, 300, 300, 300, 300, 301, 12, 12, 155, 154, 155, 154, 155, 154, 12, 12, - 2, 2, 3, 2, 2, 302, 303, 12, 300, 300, 300, 304, 300, 300, 304, 12, - 150, 12, 12, 12, 150, 265, 305, 150, 150, 150, 150, 12, 247, 247, 247, 249, - 247, 247, 249, 12, 2, 273, 12, 12, 306, 22, 12, 24, 25, 26, 25, 307, - 308, 309, 25, 25, 50, 12, 12, 12, 310, 29, 29, 29, 29, 29, 29, 311, - 312, 29, 29, 29, 29, 29, 12, 310, 7, 7, 7, 313, 232, 0, 0, 0, - 0, 232, 0, 12, 29, 314, 29, 29, 29, 29, 29, 315, 316, 0, 0, 0, - 0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150, 319, 150, 319, 288, - 0, 232, 0, 232, 12, 12, 316, 246, 320, 320, 320, 321, 320, 320, 320, 320, - 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324, 320, 320, 322, 12, - 232, 131, 0, 0, 0, 131, 0, 0, 8, 8, 8, 14, 0, 0, 0, 234, - 325, 12, 12, 12, 0, 0, 0, 326, 327, 327, 327, 327, 327, 327, 327, 328, - 329, 329, 329, 329, 330, 12, 12, 12, 215, 0, 0, 0, 0, 0, 0, 12, - 331, 331, 331, 331, 331, 12, 12, 332, 333, 333, 333, 333, 333, 333, 334, 12, - 335, 335, 335, 335, 335, 335, 336, 12, 337, 337, 337, 337, 337, 337, 337, 338, - 339, 339, 339, 339, 339, 12, 339, 339, 339, 340, 12, 12, 341, 341, 341, 341, - 342, 342, 342, 342, 343, 343, 343, 343, 343, 343, 343, 344, 343, 343, 344, 12, - 345, 345, 345, 345, 345, 12, 345, 345, 345, 345, 345, 12, 346, 346, 346, 346, - 346, 346, 12, 12, 347, 347, 347, 347, 347, 12, 12, 348, 349, 349, 350, 349, - 350, 351, 349, 349, 351, 349, 349, 349, 351, 349, 351, 352, 353, 353, 353, 353, - 353, 354, 12, 12, 353, 355, 12, 12, 353, 353, 12, 12, 2, 274, 2, 2, - 356, 2, 273, 12, 357, 358, 359, 357, 357, 357, 357, 357, 357, 360, 361, 362, - 363, 363, 363, 363, 363, 364, 363, 363, 365, 365, 365, 365, 366, 366, 366, 366, - 366, 366, 366, 367, 12, 368, 366, 366, 369, 369, 369, 369, 370, 371, 372, 369, - 373, 373, 373, 373, 373, 373, 373, 374, 375, 375, 375, 375, 375, 375, 376, 377, - 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 12, 379, 380, 379, 379, 379, - 381, 382, 12, 381, 381, 383, 383, 381, 381, 381, 381, 381, 381, 384, 385, 386, - 381, 381, 387, 12, 388, 388, 388, 388, 389, 389, 389, 389, 390, 390, 390, 390, - 390, 391, 392, 390, 390, 391, 12, 12, 393, 393, 393, 393, 393, 394, 395, 393, - 396, 396, 396, 396, 396, 397, 396, 396, 398, 398, 398, 398, 399, 12, 398, 398, - 400, 400, 400, 400, 401, 12, 402, 403, 12, 12, 402, 400, 404, 404, 404, 404, - 404, 404, 405, 12, 406, 406, 406, 406, 407, 12, 12, 12, 407, 12, 408, 406, - 409, 409, 409, 409, 409, 409, 12, 12, 409, 409, 410, 12, 411, 411, 411, 411, - 411, 411, 412, 413, 413, 12, 12, 12, 12, 12, 12, 414, 415, 415, 415, 415, - 415, 415, 12, 12, 416, 416, 416, 416, 416, 416, 417, 12, 418, 418, 418, 418, - 418, 418, 419, 12, 420, 420, 420, 420, 420, 420, 420, 12, 421, 421, 421, 421, - 421, 422, 12, 12, 423, 423, 423, 423, 423, 423, 423, 424, 425, 423, 423, 423, - 423, 424, 12, 426, 427, 427, 427, 427, 428, 12, 12, 429, 430, 430, 430, 430, - 430, 430, 431, 12, 430, 430, 432, 12, 433, 433, 433, 433, 433, 434, 433, 433, - 433, 433, 12, 12, 435, 435, 435, 435, 435, 436, 12, 12, 437, 437, 437, 437, - 118, 119, 119, 119, 119, 127, 12, 12, 438, 438, 438, 438, 439, 438, 438, 438, - 440, 12, 12, 12, 441, 442, 443, 444, 441, 441, 441, 444, 441, 441, 445, 12, - 446, 446, 446, 446, 446, 446, 447, 12, 446, 446, 448, 12, 449, 450, 449, 451, - 451, 449, 449, 449, 449, 449, 452, 449, 452, 450, 453, 449, 449, 451, 451, 454, - 455, 456, 12, 450, 449, 457, 449, 455, 449, 455, 12, 12, 458, 458, 458, 458, - 458, 458, 458, 459, 460, 12, 12, 12, 461, 461, 461, 461, 461, 461, 12, 12, - 461, 461, 462, 12, 463, 463, 463, 463, 463, 464, 463, 463, 463, 463, 463, 464, - 465, 465, 465, 465, 465, 466, 12, 12, 465, 465, 467, 12, 178, 178, 178, 180, - 468, 468, 468, 468, 468, 468, 469, 12, 470, 470, 470, 470, 470, 470, 471, 472, - 470, 470, 470, 12, 470, 471, 12, 12, 473, 473, 473, 473, 473, 473, 473, 12, - 474, 474, 474, 474, 475, 12, 12, 476, 477, 478, 479, 477, 477, 480, 477, 477, - 477, 477, 477, 477, 477, 481, 482, 477, 477, 478, 12, 12, 477, 477, 483, 12, - 484, 484, 485, 484, 484, 484, 484, 484, 484, 486, 12, 12, 487, 487, 487, 487, - 487, 487, 12, 12, 488, 488, 488, 488, 489, 12, 12, 12, 490, 490, 490, 490, - 490, 490, 491, 12, 53, 53, 492, 12, 493, 493, 494, 493, 493, 493, 493, 493, - 493, 495, 493, 493, 493, 496, 12, 12, 493, 493, 493, 497, 498, 498, 498, 498, - 499, 498, 498, 498, 498, 498, 500, 498, 498, 501, 12, 12, 502, 503, 504, 502, - 502, 502, 502, 502, 502, 503, 505, 504, 502, 502, 12, 12, 502, 502, 506, 12, - 507, 508, 509, 507, 507, 507, 507, 507, 507, 507, 507, 510, 508, 507, 511, 12, - 507, 507, 512, 12, 513, 513, 513, 513, 513, 513, 514, 12, 515, 515, 515, 515, - 516, 515, 515, 515, 515, 515, 517, 518, 515, 515, 519, 12, 520, 12, 12, 12, - 100, 100, 100, 100, 96, 12, 12, 98, 521, 521, 521, 521, 521, 521, 522, 12, - 521, 521, 521, 523, 521, 524, 12, 12, 521, 12, 12, 12, 525, 525, 525, 525, - 526, 12, 12, 12, 527, 527, 527, 527, 527, 528, 12, 12, 529, 529, 529, 529, - 529, 530, 12, 12, 272, 272, 531, 12, 532, 532, 532, 532, 532, 532, 532, 533, - 532, 532, 534, 535, 536, 536, 536, 536, 536, 536, 536, 537, 536, 536, 538, 12, - 539, 539, 539, 539, 539, 539, 539, 540, 539, 540, 12, 12, 541, 541, 541, 541, - 541, 542, 12, 12, 541, 541, 543, 541, 543, 541, 541, 541, 541, 541, 12, 544, - 545, 545, 545, 545, 545, 545, 546, 12, 547, 547, 547, 547, 547, 547, 548, 549, - 547, 547, 12, 549, 550, 551, 12, 12, 249, 12, 12, 12, 552, 552, 552, 552, - 552, 552, 12, 12, 553, 553, 553, 553, 553, 554, 12, 12, 552, 552, 555, 12, - 260, 556, 260, 557, 558, 255, 255, 255, 559, 12, 12, 12, 560, 12, 12, 12, - 256, 561, 12, 12, 12, 260, 12, 12, 562, 562, 562, 562, 562, 562, 562, 12, - 563, 563, 563, 563, 563, 563, 564, 12, 563, 563, 563, 565, 563, 563, 565, 12, - 563, 563, 566, 563, 0, 12, 12, 12, 7, 7, 7, 567, 7, 199, 12, 12, - 0, 246, 12, 12, 0, 232, 316, 0, 0, 568, 228, 0, 0, 0, 568, 7, - 213, 569, 7, 0, 0, 0, 570, 228, 8, 225, 12, 12, 0, 0, 234, 12, - 0, 0, 0, 229, 571, 572, 316, 229, 0, 0, 240, 316, 0, 316, 0, 0, - 0, 240, 232, 316, 0, 229, 0, 229, 0, 0, 240, 232, 0, 573, 239, 0, - 229, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 239, 574, 574, 574, 574, - 574, 574, 574, 12, 12, 12, 575, 574, 576, 574, 574, 574, 2, 2, 2, 273, - 12, 275, 273, 12, 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577, 12, - 19, 19, 19, 581, 12, 12, 12, 582, 583, 583, 583, 583, 583, 583, 583, 584, - 583, 583, 583, 585, 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, - 589, 589, 589, 589, 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593, 12, - 151, 154, 151, 594, 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, - 595, 597, 12, 12, 598, 598, 598, 598, 598, 598, 598, 12, 598, 598, 599, 600, - 0, 234, 12, 12, 29, 414, 29, 29, 601, 602, 414, 29, 50, 29, 603, 12, - 604, 310, 603, 414, 601, 602, 603, 603, 601, 602, 50, 29, 50, 29, 414, 605, - 29, 29, 606, 29, 29, 29, 29, 12, 414, 414, 606, 29, 51, 12, 12, 12, - 12, 239, 0, 0, 607, 12, 12, 12, 246, 12, 12, 12, 0, 0, 12, 0, - 0, 232, 131, 0, 0, 0, 12, 12, 0, 0, 0, 240, 0, 246, 12, 239, - 608, 12, 12, 12, 247, 247, 609, 12, 610, 12, 12, 12, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, - 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041, - 1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127, - 1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227, - 1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, - 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, - 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, - 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0, - 1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032, - 1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0, - 1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264, - 1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283, - 1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, + 0, 0, 1, 1, 0, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 0, 6, 7, 7, 7, 8, 9, 10, 11, 12, + 13, 13, 13, 13, 14, 13, 13, 13, 13, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 23, 23, 26, 23, 27, 28, 29, 23, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 23, 23, 39, 40, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 82, 86, 86, 87, 88, 89, 90, 91, 82, + 92, 92, 92, 92, 92, 93, 94, 95, 96, 96, 96, 96, 96, 96, 96, 96, + 97, 97, 98, 97, 99, 100, 101, 97, 102, 97, 103, 104, 105, 106, 106, 107, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 110, 110, 111, + 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 120, 121, 120, 122, 108, 123, + 124, 125, 126, 127, 128, 129, 130, 116, 131, 132, 133, 134, 135, 136, 137, 82, + 138, 138, 139, 138, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 4, 151, 152, 153, 4, 154, 7, 7, 155, 11, 156, 157, 11, 158, 159, 160, + 161, 0, 0, 162, 163, 0, 164, 165, 0, 166, 167, 4, 168, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, + 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 172, 173, 0, 0, 0, + 174, 174, 174, 4, 175, 175, 175, 176, 93, 177, 178, 179, 180, 181, 181, 13, + 0, 0, 182, 82, 183, 184, 184, 185, 184, 184, 184, 184, 184, 184, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 96, 96, 198, 199, 0, 200, + 201, 0, 0, 202, 0, 0, 203, 204, 194, 194, 205, 0, 0, 0, 0, 0, + 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 0, 0, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 206, 208, 209, + 210, 210, 210, 210, 210, 210, 210, 210, 210, 211, 13, 13, 13, 212, 212, 213, + 0, 214, 4, 4, 215, 4, 216, 217, 218, 219, 220, 221, 222, 222, 223, 40, + 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 92, 234, 234, 235, 236, + 237, 238, 239, 240, 106, 106, 241, 242, 96, 96, 96, 96, 96, 243, 244, 245, + 82, 82, 82, 82, 82, 82, 82, 82, 184, 184, 184, 246, 184, 184, 247, 82, + 248, 249, 250, 23, 23, 23, 251, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 252, 23, 23, 253, 23, 254, 255, 256, 257, 258, 259, 23, 23, 23, 260, + 261, 1, 1, 262, 263, 201, 264, 265, 266, 267, 268, 82, 269, 269, 269, 270, + 271, 272, 11, 11, 273, 274, 187, 275, 82, 82, 82, 82, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 82, 287, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 303, 304, 305, 306, 307, 82, 82, 308, 309, 310, 311, 312, 313, 82, 314, + 315, 316, 82, 82, 317, 318, 319, 320, 321, 322, 323, 324, 325, 82, 326, 327, + 328, 329, 330, 331, 332, 333, 82, 82, 334, 334, 335, 82, 336, 337, 336, 338, + 339, 340, 341, 342, 343, 82, 82, 82, 82, 82, 82, 344, 345, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 357, 358, 359, 360, 360, 361, 362, + 363, 364, 365, 366, 367, 367, 367, 368, 369, 370, 371, 82, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 384, 385, 386, 387, 387, 388, 82, + 82, 82, 82, 82, 389, 390, 391, 82, 392, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 82, 82, 82, 82, 82, 402, 403, 82, 82, 82, 404, 404, 405, + 406, 407, 408, 82, 82, 409, 410, 411, 412, 412, 413, 414, 414, 415, 416, 417, + 418, 82, 82, 82, 82, 82, 419, 420, 421, 422, 423, 424, 425, 426, 82, 82, + 427, 428, 429, 430, 431, 432, 82, 82, 82, 82, 82, 82, 82, 82, 82, 433, + 434, 435, 436, 82, 82, 437, 438, 439, 440, 440, 440, 440, 440, 440, 440, 440, + 440, 440, 440, 440, 441, 82, 82, 82, 440, 440, 440, 442, 440, 440, 440, 440, + 440, 440, 443, 82, 82, 82, 82, 82, 82, 82, 82, 82, 444, 445, 445, 446, + 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 449, 450, 450, 450, 450, 450, 450, 450, 450, + 450, 450, 451, 82, 82, 82, 82, 82, 452, 453, 82, 82, 82, 82, 82, 82, + 212, 212, 212, 212, 212, 212, 212, 212, 212, 454, 455, 456, 457, 458, 459, 460, + 461, 461, 462, 463, 464, 82, 82, 82, 82, 82, 465, 466, 82, 82, 82, 82, + 82, 82, 467, 467, 468, 82, 82, 82, 469, 469, 470, 469, 471, 82, 82, 472, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 474, + 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 477, + 478, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 479, + 480, 191, 191, 191, 191, 191, 191, 191, 191, 481, 482, 483, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 485, 486, 486, 486, 487, 488, 489, 82, 82, + 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 491, 82, 82, + 7, 492, 493, 0, 0, 0, 489, 82, 0, 0, 0, 0, 0, 0, 0, 494, + 0, 495, 0, 496, 497, 498, 0, 170, 11, 11, 499, 82, 82, 82, 491, 491, + 0, 0, 500, 501, 82, 82, 82, 82, 0, 0, 502, 0, 503, 504, 505, 0, + 506, 507, 508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, + 0, 0, 0, 0, 0, 0, 510, 0, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 512, 513, 82, 82, 514, 515, 82, 82, 82, 82, 82, 82, + 516, 517, 13, 518, 519, 82, 82, 82, 520, 521, 522, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 523, 524, 525, 526, 82, 82, 82, 82, 82, 82, 527, 528, + 82, 82, 82, 82, 82, 82, 529, 530, 82, 82, 82, 82, 82, 82, 82, 531, + 532, 532, 532, 532, 532, 532, 533, 82, 534, 534, 535, 82, 82, 82, 82, 82, + 82, 82, 82, 536, 0, 537, 82, 82, 261, 182, 82, 82, 82, 82, 82, 82, + 538, 539, 540, 541, 542, 543, 82, 544, 0, 545, 0, 0, 491, 546, 547, 494, + 0, 0, 0, 0, 0, 548, 82, 549, 550, 551, 552, 553, 82, 82, 82, 82, + 0, 0, 0, 0, 0, 0, 554, 555, 0, 0, 0, 556, 0, 0, 490, 557, + 545, 0, 558, 0, 559, 560, 561, 82, 0, 0, 491, 562, 563, 0, 564, 565, + 0, 0, 0, 0, 258, 0, 0, 490, 184, 184, 184, 184, 184, 184, 184, 82, + 184, 247, 184, 184, 184, 184, 184, 184, 566, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 567, 184, 184, 184, 184, 184, 184, 184, 184, 184, 568, + 184, 184, 566, 82, 82, 82, 82, 82, 566, 82, 82, 82, 82, 82, 82, 82, + 184, 184, 569, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 570, 82, 82, + 571, 0, 0, 0, 82, 82, 82, 82, 7, 7, 7, 7, 7, 7, 7, 572, + 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 4, 2, 2, 5, 2, + 2, 2, 2, 2, 2, 2, 2, 6, 7, 8, 0, 0, 9, 9, 9, 9, + 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, + 16, 17, 14, 14, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 20, 21, + 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, + 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, + 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 29, 37, 38, 37, 37, + 37, 37, 37, 37, 37, 39, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, + 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, + 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 52, 31, 31, 31, + 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, + 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, + 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, + 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, + 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, + 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, + 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, + 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, + 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, + 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, + 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, + 153, 152, 152, 154, 155, 156, 152, 157, 158, 158, 158, 158, 158, 159, 158, 158, + 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, + 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, + 169, 169, 169, 169, 170, 170, 170, 170, 170, 171, 172, 171, 170, 171, 170, 170, + 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 171, 170, 170, 170, 170, 173, + 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 177, 177, + 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 182, 181, 183, + 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, + 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, + 198, 198, 198, 198, 198, 198, 198, 200, 198, 201, 178, 178, 178, 178, 202, 26, + 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, + 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 214, 214, 214, 215, + 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, + 216, 220, 9, 9, 9, 221, 26, 26, 222, 222, 222, 222, 222, 223, 222, 222, + 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, 228, 228, 228, 228, + 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, 18, 232, 165, 165, + 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, 239, 240, 2, 2, + 2, 2, 2, 241, 242, 243, 2, 244, 2, 2, 2, 245, 14, 14, 246, 246, + 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 248, 14, 248, 14, 249, 250, + 14, 14, 251, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, + 259, 26, 9, 9, 9, 9, 260, 26, 261, 262, 4, 0, 0, 263, 0, 0, + 2, 264, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 267, 267, 267, 267, + 0, 0, 268, 0, 0, 0, 269, 0, 270, 270, 270, 270, 17, 17, 17, 17, + 17, 17, 271, 272, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, + 170, 170, 172, 26, 172, 172, 172, 172, 0, 0, 0, 276, 277, 277, 277, 278, + 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 280, 26, 26, 26, 0, 0, + 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, + 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, + 276, 296, 290, 290, 169, 169, 169, 295, 169, 169, 169, 297, 0, 0, 290, 290, + 290, 290, 290, 298, 290, 290, 290, 0, 299, 299, 299, 299, 299, 300, 299, 299, + 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 304, 26, 26, + 305, 305, 305, 305, 305, 305, 305, 26, 306, 2, 2, 2, 2, 307, 2, 2, + 2, 308, 309, 258, 26, 26, 310, 2, 311, 311, 311, 311, 311, 312, 0, 265, + 313, 313, 313, 313, 313, 313, 313, 26, 314, 314, 314, 314, 315, 316, 314, 317, + 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, + 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, 328, 328, 328, 328, + 328, 328, 329, 26, 328, 330, 328, 331, 332, 332, 332, 332, 333, 26, 26, 334, + 335, 335, 336, 26, 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, + 339, 340, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, 343, 26, 169, 169, + 295, 344, 169, 169, 169, 169, 169, 343, 277, 280, 277, 277, 277, 277, 277, 345, + 346, 26, 347, 348, 25, 25, 349, 350, 351, 25, 31, 31, 352, 26, 353, 31, + 31, 31, 31, 354, 31, 31, 355, 31, 31, 356, 26, 26, 26, 26, 31, 31, + 9, 9, 0, 265, 9, 357, 0, 0, 0, 0, 358, 0, 257, 359, 360, 31, + 31, 31, 31, 361, 362, 0, 0, 0, 363, 290, 289, 290, 290, 290, 290, 364, + 365, 365, 365, 366, 257, 257, 26, 367, 368, 369, 368, 368, 370, 368, 368, 371, + 368, 372, 368, 372, 368, 368, 368, 368, 368, 368, 368, 373, 374, 0, 0, 0, + 0, 0, 375, 0, 14, 252, 0, 376, 377, 26, 26, 26, 0, 0, 0, 378, + 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, + 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, + 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 396, 396, 396, 396, + 396, 396, 397, 397, 397, 397, 397, 397, 398, 398, 398, 399, 398, 400, 401, 401, + 401, 401, 402, 401, 401, 401, 401, 402, 403, 403, 403, 403, 403, 26, 404, 404, + 404, 404, 404, 404, 405, 406, 407, 408, 407, 408, 409, 407, 410, 407, 410, 411, + 412, 412, 412, 412, 412, 412, 413, 26, 414, 414, 414, 414, 414, 414, 415, 26, + 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, + 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, + 428, 428, 428, 429, 430, 428, 26, 26, 431, 431, 432, 433, 434, 434, 434, 435, + 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, 439, 439, 441, 439, + 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, 446, 449, 446, 449, + 450, 450, 450, 450, 451, 451, 451, 451, 452, 452, 452, 452, 453, 454, 453, 26, + 455, 455, 455, 455, 455, 455, 456, 457, 458, 458, 459, 458, 460, 460, 461, 460, + 462, 462, 463, 464, 26, 465, 26, 26, 466, 466, 466, 466, 466, 467, 26, 26, + 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 469, 470, 471, 471, 471, 471, + 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, 474, 476, 26, 26, + 31, 31, 31, 50, 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, + 26, 26, 26, 481, 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, + 26, 26, 485, 485, 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, + 489, 489, 490, 26, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, + 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, 501, 501, 501, 501, + 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, 505, 505, 505, 505, + 506, 137, 507, 26, 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, + 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, + 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, + 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, + 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, 541, 541, 541, 541, + 541, 26, 541, 542, 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, + 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, 549, 549, 549, 549, + 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, 552, 552, 552, 553, + 552, 554, 552, 552, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 557, + 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, + 561, 26, 564, 567, 568, 569, 568, 568, 568, 568, 568, 569, 570, 26, 26, 26, + 571, 571, 571, 571, 571, 26, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, + 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 577, 577, 577, 577, + 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, 582, 26, 579, 579, + 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, 588, 589, 590, 590, + 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, 595, 596, 597, 598, + 595, 599, 26, 26, 600, 600, 600, 601, 602, 602, 603, 602, 602, 602, 602, 604, + 602, 602, 602, 605, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, + 609, 609, 609, 609, 609, 609, 609, 610, 609, 611, 612, 26, 613, 26, 26, 26, + 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, 616, 616, 616, 616, + 616, 616, 617, 26, 616, 616, 616, 618, 619, 619, 619, 619, 620, 26, 26, 26, + 621, 621, 621, 621, 621, 621, 621, 622, 305, 305, 305, 623, 624, 624, 624, 625, + 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, 627, 629, 630, 630, + 630, 631, 631, 26, 632, 632, 632, 632, 633, 26, 632, 634, 634, 632, 632, 635, + 632, 632, 26, 26, 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, + 638, 638, 638, 639, 640, 640, 640, 640, 640, 641, 640, 640, 640, 642, 640, 640, + 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, + 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 649, 650, + 651, 286, 286, 286, 652, 26, 653, 26, 26, 26, 654, 26, 655, 26, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 659, 658, 660, + 658, 661, 658, 662, 359, 26, 26, 26, 0, 0, 0, 265, 0, 0, 359, 26, + 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 276, 26, 257, 362, 0, 0, + 664, 665, 0, 666, 667, 668, 0, 0, 0, 669, 0, 0, 246, 26, 26, 26, + 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 254, + 670, 671, 0, 672, 673, 0, 0, 0, 269, 674, 254, 254, 0, 0, 0, 675, + 676, 677, 678, 0, 276, 0, 0, 0, 0, 268, 0, 0, 679, 679, 679, 679, + 679, 680, 26, 681, 682, 679, 26, 26, 2, 2, 2, 346, 683, 419, 26, 26, + 684, 270, 270, 685, 686, 687, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, + 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 694, 694, + 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, 26, 26, 698, 698, + 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, 172, 702, 170, 172, + 703, 703, 703, 703, 704, 703, 705, 26, 706, 706, 706, 706, 706, 707, 706, 708, + 26, 26, 362, 0, 0, 0, 376, 26, 709, 31, 31, 31, 710, 711, 712, 713, + 714, 715, 710, 716, 710, 712, 712, 717, 31, 718, 31, 719, 720, 718, 31, 719, + 26, 26, 721, 26, 0, 359, 0, 0, 0, 257, 362, 0, 362, 0, 362, 0, + 0, 276, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, + 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, + 0, 0, 257, 725, 0, 359, 259, 26, 0, 26, 0, 265, 0, 26, 0, 0, + 0, 276, 0, 359, 265, 26, 26, 26, 0, 276, 0, 376, 0, 726, 0, 0, + 257, 722, 0, 727, 0, 265, 0, 259, 277, 277, 277, 280, 345, 26, 277, 277, + 728, 26, 277, 277, 277, 729, 277, 277, 277, 277, 26, 26, 730, 26, 26, 26, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976, + 1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082, + 1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161, + 1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269, + 1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, + 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, + 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191, + 1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025, + 1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0, + 1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252, + 1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271, + 1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120, + 1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090, - 1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, - 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, - 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, - 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248, - 1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, - 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10, - 1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, + 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339, + 1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241, + 1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348, + 1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197, + 1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, + 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364, + 1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0, + 1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458, + 1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503, + 1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0, + 1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, + 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0, + 1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571, + 1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573, + 1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, + 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, + 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617, + 1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628, + 1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, + 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638, + 1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644, + 1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, + 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653, + 1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0, + 1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0, + 1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, + 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0, + 1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0, + 1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, + 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, + 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170, + 1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185, + 1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213, + 1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224, + 1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249, + 1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259, + 1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393, + 1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295, + 1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, + 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345, + 1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, + 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198, + 1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401, + 1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410, + 1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, + 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719, + 1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735, + 1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755, + 1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774, + 1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783, + 1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, + 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812, + 1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28, + 1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724, + 1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760, + 1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817, + 1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12, + 1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14, + 1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, + 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17, + 1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18, + 1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, + 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0, + 1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, + 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, + 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520, - 1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, - 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, - 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, - 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, - 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555, - 1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563, - 1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607, - 1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, + 1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872, + 1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0, - 1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, - 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0, - 1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, - 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, - 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, - 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, - 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, + 1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0, + 1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, + 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0, + 1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0, + 1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, + 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0, + 1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, + 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, + 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, + 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, + 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, + 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, + 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, + 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, + 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, + 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, + 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, + 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, + 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, + 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, + 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, + 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, + 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, + 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, + 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, + 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, + 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, + 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, + 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, + 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, + 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, + 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, + 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, + 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, + 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, + 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, + 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, - 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152, - 1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, - 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205, - 1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216, - 1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385, - 1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256, - 1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282, - 1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289, - 1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311, - 1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132, - 1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377, - 1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355, - 1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357, - 1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404, - 1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297, - 1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705, - 1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731, - 1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741, - 1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768, - 1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779, - 1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788, - 1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798, - 1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22, - 1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710, - 1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746, - 1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803, - 1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474, - 1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484, - 1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, - 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25, - 1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512, - 1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, + 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603, + 1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589, + 1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582, + 1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, + 1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0, - 1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0, - 1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0, - 1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0, - 1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0, - 1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, - 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0, - 1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, - 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894, - 1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0, - 1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0, - 1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, - 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921, - 1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0, - 1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, - 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, - 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, - 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, - 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, - 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, - 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, - 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, - 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, - 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, - 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, - 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, - 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, - 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, - 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, - 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, - 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, - 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, - 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, - 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, - 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, - 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, - 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, - 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, - 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, - 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, - 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, - 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, - 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, - 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, - 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580, - 1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595, - 1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954, - 1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, - 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, - 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, - 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, - 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, - 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, - 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, - 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, - 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, - 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, - 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, - 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, - 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, - 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, - 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, - 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, - 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, - 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, - 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, - 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, - 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, - 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, - 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, - 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, - 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, - 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, - 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, - 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, - 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, - 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, - 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, - 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, - 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, 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, + 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943, + 1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, + 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953, + 1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, + 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976, + 1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, + 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, + 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, + 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, + 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, + 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, + 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, + 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, + 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, + 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, + 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, + 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, + 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, + 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, + 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, + 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, + 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, + 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, + 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, + 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, + 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, + 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, + 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, + 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, + 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, + 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, + 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, + 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, + 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, + 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, + 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, + 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, + 94, 927, 787, 787, 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[92] = @@ -4403,12 +4615,12 @@ _hb_ucd_i16[92] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_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<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; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(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<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; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -4418,55 +4630,55 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9692+(((_hb_ucd_u8[9460+(((_hb_ucd_u8[9364+(((_hb_ucd_b4(9300+_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<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; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[11126+(((_hb_ucd_u16[4040+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10390+(((_hb_ucd_u8[9940+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + 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; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6748+(((_hb_ucd_u8[13952+(((_hb_ucd_u8[13570+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + 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; } #else static const uint8_t -_hb_ucd_u8[13386] = +_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, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 21, 21, 21, 21, 23, 7, 7, - 7, 24, 21, 21, 21, 25, 26, 27, 21, 28, 29, 30, 31, 32, 33, 34, + 14, 15, 16, 17, 18, 19, 20, 7, 21, 22, 22, 22, 23, 24, 7, 7, + 7, 25, 22, 22, 22, 26, 27, 28, 22, 29, 30, 31, 32, 33, 34, 35, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, 21, 36, - 7, 7, 7, 7, 37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 38, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 22, 36, + 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 38, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, @@ -4486,30 +4698,30 @@ _hb_ucd_u8[13386] = 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119, - 120,121,122,123,124,125,126,127, 34,128,129,111,130,131,132,133, - 134,135,136,137,138,139,140,111,141,142,111,143,144,145,146,111, - 147,148,149,150,151,152,153,111,154,155,156,157,111,158,159,160, - 34, 34, 34, 34, 34, 34, 34, 34,161, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,162, - 34, 34, 34, 34, 34, 34, 34, 34,163,111,111,111,111,111,111,111, + 120,121,122,123,124,125,126,127, 34,128,129,130,131,132,133,134, + 135,136,137,138,139,140,141,142,143,144,111,145,146,147,148,111, + 149,150,151,152,153,154,155,156,157,158,159,160,111,161,162,163, + 34, 34, 34, 34, 34, 34, 34, 34,164, 34, 34,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,165, + 34, 34, 34, 34, 34, 34, 34, 34,166, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111, - 34, 34, 34, 34,164,165,166, 34,111,111,111,111,167,168,169,170, + 111,111,167,111,111,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34,168,169,170, 34,111,111,171,111,172,173,174,175, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34,171,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,172, 67, - 67, 67,173,174,175,130, 65,111,176,177,178,179,180,181,182,183, - 67, 67, 67, 67,184,185,111,111,111,111,111,111,111,111,186,111, - 187,188,189,111,111,190,111,111,111,191,111,111,111,111,111, 34, - 34,192,193,111,111,111,111,111,130,194,195,111, 34,196,111,111, - 67, 67,197, 67, 67,111, 67,198, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67,199,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, + 111,111,111,111,111,111,111,111, 34,176,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67, 67,178, 67, + 67, 67,179,180,181,131, 65,111,182,183,184,185,186,187,188,189, + 67, 67, 67, 67,190,191,111,111,111,111,111,111,111,111,192,111, + 193,194,195,111,111,196,111,111,111,197,111,198,111,111,111, 34, + 34,199,200,111,111,111,111,111,131,201,202,111, 34,203,111,111, + 67, 67,204, 67, 67,111, 67,205, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, - 200,111,188,188,111,111,111,111,111,111,111,111,111,111,111,111, + 206,111,194,194,111,111,111,111,111,111,111,111,111,111,111,111, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -4544,8 +4756,8 @@ _hb_ucd_u8[13386] = 36, 36, 36, 36, 36, 64, 43, 43, 43, 43, 40, 21, 2, 40, 69, 20, 36, 36, 36, 43, 43, 69, 43, 43, 43, 43, 69, 43, 69, 43, 43, 43, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 64, 43, 43, 2, - 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 59, 43, 43, 43, 43, - 36, 36, 36, 36, 75, 43, 43, 43, 43, 76, 43, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 75, 43, 43, 43, 43, + 36, 36, 36, 36, 76, 43, 43, 43, 43, 75, 43, 43, 43, 43, 43, 43, 43, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 65, 78, 79, 43, 43, 43, 77, 78, 79, 78, 64, 43, 43, 43, 36, 36, 36, 36, 36, 43, 2, 7, 7, 7, 7, 7, 80, 36, 36, 36, 36, 36, 36, 36, @@ -4590,130 +4802,135 @@ _hb_ucd_u8[13386] = 36, 43, 77, 78, 78, 78, 78, 81, 36, 43, 97, 2, 2, 2, 2, 2, 36, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 79, 43, 43, 43, 78, 78, 78, 78, 77, 79, 43, 43, 43, 43, 43, 2, 80, 2, 60, 64, 43, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 76, - 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, + 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 75, + 36, 76, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, 36, 36, 36, 36, 64, 36, 36, 36, 43, 77, 78, 79, 77, 78, 78, 78, 78, 77, 78, 78, 79, 43, 43, 43, 61, 61, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 64, 77, 79, 43, 2, 36, 36, 82, 77, 43, 43, 43, 43, 77, 77, 79, 43, 43, 43, 77, 78, 78, 79, 43, 43, 43, 43, 43, 43, 2, 2, 2, 80, 2, 2, 2, 2, 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 81, 36, 36, 36, 36, 36, - 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 36, + 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 2, 89, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 21, 2, 43, 81, 36, 36, 36, 36, 36, 36, 82, 43, 43, 78, 43, 79, 43, 36, 36, 36, 36, 77, 43, 78, 79, 79, 43, 78, 78, 78, 78, 78, 2, 2, 36, 36, 78, 78, 78, 78, 43, 43, 43, 43, 78, 43, 43, 57, 2, 2, 7, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 43, 57, 43, 43, 43, 43, 43, 43, 77, 43, 43, 43, 65, 36, 64, 36, - 36, 36, 65, 82, 43, 36, 36, 36, 16, 16, 16, 16, 16, 16, 40, 40, - 40, 40, 40, 40, 40, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, - 16, 16, 16, 16, 16,100, 40, 40, 32, 32, 32, 16, 16, 16, 16, 32, - 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 16, 34, 11, 11, 11, - 16, 16, 16, 16,101,101,101,101, 16, 16, 16, 16, 11, 11,102,103, - 41, 16, 16, 16, 11, 11,102, 41, 16, 16, 16, 16, 11, 11,104, 41, - 105,105,105,105,105,106, 59, 59, 51, 51, 51, 2,107,108,107,108, - 2, 2, 2, 2,109, 59, 59,110, 2, 2, 2, 2,111,112, 2,113, - 114, 2,115,116, 2, 2, 2, 2, 2, 9,114, 2, 2, 2, 2,117, - 59, 59, 59, 59, 59, 59, 59, 59,118, 40, 27, 27, 27, 8,115,119, - 27, 27, 27, 27, 27, 8,115, 94, 20, 20, 20, 20, 20, 20, 20, 20, - 43, 43, 43, 43, 43, 43,120, 48, 99, 48, 99, 43, 43, 43, 43, 43, - 61,121, 61,122, 61, 34, 11, 16, 11, 32,122, 61, 46, 11, 11, 61, - 61, 61,121,121,121, 11, 11,123, 11, 11, 35, 36, 39, 61, 16, 11, - 8, 8, 46, 16, 16, 26, 61,124, 95, 95, 95, 95, 95, 95, 95, 95, - 95,125,126, 95,127, 61, 61, 61, 8, 8,128, 61, 61, 8, 61, 61, - 128, 26, 61,128, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 61, 8, - 61,128,128, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 61, 61, 61, 61, 4, 4, 61, 61, - 8, 61, 61, 61,129,130, 61, 61, 61, 61, 61, 61, 61, 61,128, 61, - 61, 61, 61, 61, 61, 26, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, - 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, - 61, 61, 61, 26, 61, 61, 61, 61, 26, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, 26, - 61, 61, 61, 61, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 61, 61, 61, 61, 61, 61, 8, 8,115,131, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,115,132,132,132,132,132,132, - 132,132,132,132,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,128, 26, 8, 8,128, 61, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,124, 61, 61,122, 34,133, 43, 32, 16, 16, 50, 2, 90, 2, - 36, 36, 36, 36, 36, 36, 36, 75, 2, 2, 2, 2, 2, 2, 2, 56, - 2,107,107, 2,111,112,107, 2, 2, 2, 2, 6, 2, 98,107, 2, - 107, 4, 4, 4, 4, 2, 2, 80, 2, 2, 2, 2, 2, 51, 2, 2, - 98,134, 2, 2, 2, 2, 2, 2, 61, 2,135,132,132,132,136, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 1, 2,137,138, 4, 4, 4, 4, - 4, 61, 4, 4, 4, 4,139, 94,140, 95, 95, 95, 95, 43, 43, 78, - 141, 40, 40, 61, 95,142, 58, 61, 72, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 64,143,144, 63, 36, 36, 36, 36, 36, 58, 40, 63, - 61, 27, 27, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 61, 61, 61, - 61, 61, 61, 61, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,146, 2, - 32, 32, 32, 32, 32, 32, 32, 64, 48,147, 43, 43, 43, 43, 43, 80, - 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36, 95, 95, 95, 95, 95, - 43, 2, 2, 2, 2, 2, 2, 2, 41, 41, 41,144, 40, 40, 40, 40, - 41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, - 44, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,148, 34, 35, - 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, - 11, 11, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 34, 16, 16, 16, - 32, 16, 16, 32, 32, 16, 16, 16, 16, 40,149, 35, 40, 35, 36, 36, - 36, 65, 36, 65, 36, 64, 36, 36, 36, 82, 79, 77, 61, 61, 43, 43, - 27, 27, 27, 61,150, 61, 61, 61, 36, 36, 2, 2, 2, 2, 2, 2, - 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 78, 78, 78, 78, 78, 78, - 78, 78, 43, 43, 43, 43, 43, 2, 43, 36, 36, 36, 2, 66, 66, 64, - 36, 36, 36, 43, 43, 43, 43, 2, 36, 36, 36, 64, 43, 43, 43, 43, - 43, 78, 78, 78, 78, 78, 78, 97, 36, 64, 78, 43, 43, 78, 43, 78, - 97, 2, 2, 2, 2, 2, 2, 80, 7, 7, 7, 7, 7, 7, 7, 2, - 36, 36, 64, 63, 36, 36, 36, 36, 36, 36, 36, 36, 64, 43, 43, 77, - 79, 77, 79, 43, 43, 43, 43, 43, 36, 64, 36, 36, 36, 36, 77, 78, - 7, 7, 7, 7, 7, 7, 2, 2, 63, 36, 36, 71, 61, 82, 77, 36, - 65, 43, 65, 64, 65, 36, 36, 43, 36, 36, 36, 36, 36, 36, 75, 2, - 36, 36, 36, 36, 36, 82, 43, 78, 2, 75,151, 43, 43, 43, 43, 43, - 16, 16, 16, 16, 16,103, 40, 40, 16, 16, 16, 16,100, 41, 41, 41, - 36, 82, 79, 78, 77, 97, 79, 43,152,152,152,152,152,152,152,152, - 153,153,153,153,153,153,153,153, 16, 16, 16, 16, 16, 16, 35, 65, - 36, 36, 36, 36,154, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41, 74, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,132, - 36, 36, 36, 36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 36,150, 61, - 2, 2, 2,135,116, 2, 2, 2, 6,155,156,132,132,132,132,132, - 132,132,116,135,116, 2,113,157, 2, 2, 2, 2,139,132,132,116, - 2,158, 8, 8, 60, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36,159, - 2, 2, 3, 2, 4, 5, 6, 2, 16, 16, 16, 16, 16, 17, 18,115, - 116, 4, 2, 36, 36, 36, 36, 36, 63, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 40, 20,160, 53, 20, 26, 8,128, 61, - 61, 61, 61, 61,161, 59, 61, 61, 2, 2, 2, 90, 27, 27, 27, 27, - 27, 27, 27, 84, 61, 61, 61, 61, 95, 95,127, 27, 84, 61, 61, 61, - 61, 61, 61, 61, 61, 27, 61, 61, 61, 61, 61, 61, 61, 61, 47, 43, - 162,162,162,162,162,162,162,162,163, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 87, 36,138, 36, 36, 36, 36, 95, 95, 95, - 36, 36, 36, 36, 36, 36, 36, 58,164, 95, 95, 95, 95, 95, 95, 95, - 11, 11, 11, 32, 16, 16, 16, 16, 36, 36, 36, 58, 27, 27, 27, 27, - 36, 36, 36, 71,145, 27, 27, 27, 36, 36, 36,165, 27, 27, 27, 27, - 36, 36, 36, 36, 36,165, 27, 27, 36, 36, 36, 27, 27, 27, 27, 30, - 36, 36, 36, 36, 36, 36, 27, 36, 64, 43, 43, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,165, 30, - 36, 36, 36, 36, 36, 36,165, 27, 36, 36, 36, 36, 72, 36, 36, 36, - 36, 36, 64, 43, 43,163, 27, 27, 36, 36, 36, 36, 58, 2, 2, 2, - 36, 36, 36, 36, 27, 27, 27, 27, 16, 16, 16, 16, 16, 27, 27, 27, - 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 64,166, 51, - 27, 27, 27, 87, 36, 36, 36, 36,163, 27, 30, 2, 2, 2, 2, 2, - 36, 43, 43, 2, 2, 2, 2, 2, 36, 36,165, 27, 27, 27, 27, 27, - 79, 81, 36, 36, 36, 36, 36, 36, 43, 43, 43, 57, 2, 2, 2, 2, - 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 7, 7, 7, - 65, 64, 65, 36, 36, 36, 36, 64, 78, 79, 43, 77, 79, 57, 73, 2, - 2, 43, 43, 43, 43, 43, 67, 59, 36, 36, 36, 64, 43, 43, 79, 43, - 43, 43, 43, 7, 7, 7, 7, 7, 2, 2, 82, 81, 36, 36, 36, 36, - 36, 64, 2, 36, 36, 36, 36, 36, 36, 82, 78, 43, 43, 43, 43, 77, - 81, 36, 58, 2, 56, 43, 57, 79, 7, 7, 7, 7, 7, 58, 58, 2, - 90, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 78, 79, - 43, 78, 77, 43, 2, 2, 2, 65, 36, 36, 36, 36, 36, 36, 36, 64, - 77, 78, 78, 78, 78, 78, 78, 78, 36, 36, 36, 82, 78, 78, 81, 36, - 36, 78, 78, 43, 43, 43, 43, 43, 36, 36, 82, 78, 43, 43, 43, 43, - 78, 43, 77, 65, 36, 58, 2, 2, 7, 7, 7, 7, 7, 2, 2, 65, - 78, 79, 43, 43, 77, 77, 78, 79, 77, 43, 36, 66, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 82, 78, 43, 43, 43, 78, 78, 43, 79, - 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 43, - 78, 79, 43, 43, 43, 77, 79, 79, 57, 2, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 64, 79, 78, 43, 43, 43, 79, 58, 2, 2, 2, + 16, 16, 16, 16, 34, 16, 16, 16, 43, 57, 43, 43, 43, 43, 43, 43, + 77, 43, 43, 43, 65, 36, 64, 36, 36, 36, 65, 82, 43, 36, 36, 36, + 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 44, 16, 16, + 16, 16, 16, 16, 44, 16, 16, 16, 16, 16, 16, 16, 16,100, 40, 40, + 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, + 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,101,101,101,101, + 16, 16, 16, 16, 11, 11,102,103, 41, 16, 16, 16, 11, 11,102, 41, + 16, 16, 16, 16, 11, 11,104, 41,105,105,105,105,105,106, 59, 59, + 51, 51, 51, 2,107,108,107,108, 2, 2, 2, 2,109, 59, 59,110, + 2, 2, 2, 2,111,112, 2,113,114, 2,115,116, 2, 2, 2, 2, + 2, 9,114, 2, 2, 2, 2,117, 59, 59, 59, 59, 59, 59, 59, 59, + 118, 40, 27, 27, 27, 8,115,119, 27, 27, 27, 27, 27, 8,115, 94, + 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,120, 48, + 99, 48, 99, 43, 43, 43, 43, 43, 61,121, 61,122, 61, 34, 11, 16, + 11, 32,122, 61, 46, 11, 11, 61, 61, 61,121,121,121, 11, 11,123, + 11, 11, 35, 36, 39, 61, 16, 11, 8, 8, 46, 16, 16, 26, 61,124, + 95, 95, 95, 95, 95, 95, 95, 95, 95,125,126, 95,127, 61, 61, 61, + 8, 8,128, 61, 61, 8, 61, 61,128, 26, 61,128, 61, 61, 61,128, + 61, 61, 61, 61, 61, 61, 61, 8, 61,128,128, 61, 61, 61, 61, 61, + 61, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 61, 61, 61, 61, 4, 4, 61, 61, 8, 61, 61, 61,129,130, 61, 61, + 61, 61, 61, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 26, 8, 8, + 8, 8, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, + 8, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 27, 61, 61, + 61, 61, 61, 61, 61, 27, 27, 27, 61, 61, 61, 26, 61, 61, 61, 61, + 26, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, + 61, 61, 61, 61, 61, 61, 61, 26, 61, 61, 61, 61, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, + 8, 8,115,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,115,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,128, 26, 8, 8,128, 61, 32, 11, 32, 34, 34, 34, 34, 11, + 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,124, 61, 61,122, 34,133, + 43, 32, 16, 16, 50, 2, 90, 2, 36, 36, 36, 36, 36, 36, 36, 76, + 2, 2, 2, 2, 2, 2, 2, 56, 2,107,107, 2,111,112,107, 2, + 2, 2, 2, 6, 2, 98,107, 2,107, 4, 4, 4, 4, 2, 2, 80, + 2, 2, 2, 2, 2, 51, 2, 2, 98,134, 2, 2, 2, 2, 2, 2, + 61, 2,135,132,132,132,136, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 1, 2,137,138, 4, 4, 4, 4, 4, 61, 4, 4, 4, 4,139, 94, + 140, 95, 95, 95, 95, 43, 43, 78,141, 40, 40, 61, 95,142, 58, 61, + 72, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64,143,144, 63, + 36, 36, 36, 36, 36, 58, 40, 63, 61, 27, 27, 61, 61, 61, 61, 61, + 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, + 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 76, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 64, + 48,147, 43, 43, 43, 43, 43, 80, 32, 32, 32, 32, 32, 32, 40, 43, + 36, 36, 36, 95, 95, 95, 95, 95, 43, 2, 2, 2, 2, 2, 2, 2, + 41, 41, 41,144, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 42,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, + 32, 32, 11, 11, 34, 34, 32, 16, 32, 16, 16, 32, 32, 32, 11, 11, + 11, 40,149, 35, 40, 35, 36, 36, 36, 65, 36, 65, 36, 64, 36, 36, + 36, 82, 79, 77, 61, 61, 43, 43, 27, 27, 27, 61,150, 61, 61, 61, + 36, 36, 2, 2, 2, 2, 2, 2, 78, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 78, 78, 78, 78, 78, 78, 78, 78, 43, 43, 43, 43, 43, 2, + 43, 36, 36, 36, 2, 66, 66, 64, 36, 36, 36, 43, 43, 43, 43, 2, + 36, 36, 36, 64, 43, 43, 43, 43, 43, 78, 78, 78, 78, 78, 78, 97, + 36, 64, 78, 43, 43, 78, 43, 78, 97, 2, 2, 2, 2, 2, 2, 80, + 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 64, 63, 36, 36, 36, 36, + 36, 36, 36, 36, 64, 43, 43, 77, 79, 77, 79, 43, 43, 43, 43, 43, + 36, 64, 36, 36, 36, 36, 77, 78, 7, 7, 7, 7, 7, 7, 2, 2, + 63, 36, 36, 71, 61, 82, 77, 36, 65, 43, 65, 64, 65, 36, 36, 43, + 36, 36, 36, 36, 36, 36, 76, 2, 36, 36, 36, 36, 36, 82, 43, 78, + 2, 76,151, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16,103, 40, 40, + 16, 16, 16, 16,100, 41, 41, 41, 36, 82, 79, 78, 77, 97, 79, 43, + 152,152,152,152,152,152,152,152,153,153,153,153,153,153,153,153, + 16, 16, 16, 16, 16, 16, 35, 65, 36, 36, 36, 36,154, 36, 36, 36, + 36, 41, 41, 41, 41, 41, 41, 41, 41, 74, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,132, 36, 36, 36, 36, 36, 36, 36, 71, + 36, 36, 36, 36, 36, 36,150, 61, 2, 2, 2,135,116, 2, 2, 2, + 6,155,156,132,132,132,132,132,132,132,116,135,116, 2,113,157, + 2, 2, 2, 2,139,132,132,116, 2,158, 8, 8, 60, 2, 2, 2, + 36, 36, 36, 36, 36, 36, 36,159, 2, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,115,116, 4, 2, 36, 36, 36, 36, 36, + 63, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, + 20,160, 53, 20, 26, 8,128, 61, 61, 61, 61, 61,161, 59, 61, 61, + 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, + 95, 95,127, 27, 84, 61, 61, 61, 61, 61, 61, 61, 61, 27, 61, 61, + 61, 61, 61, 61, 61, 61, 47, 43,162,162,162,162,162,162,162,162, + 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 87, 36, + 138, 36, 36, 36, 36, 95, 95, 95, 36, 36, 36, 36, 36, 36, 36, 58, + 164, 95, 95, 95, 95, 95, 95, 95, 11, 11, 11, 32, 16, 16, 16, 16, + 36, 36, 36, 58, 27, 27, 27, 27, 36, 36, 36, 71,145, 27, 27, 27, + 36, 36, 36,165, 27, 27, 27, 27, 36, 36, 36, 36, 36,165, 27, 27, + 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, + 64, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36,165, 30, 36, 36, 36, 36, 36, 36,165, 27, + 36, 36, 36, 36, 72, 36, 36, 36, 36, 36, 64, 43, 43,163, 27, 27, + 36, 36, 36, 36, 58, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, + 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 43, 43, 43, 43, 43, 43, + 7, 7, 7, 7, 7, 36, 36, 63, 11, 11, 11, 11,166, 43, 43,141, + 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 64,167, 51, + 36, 36, 36, 36, 36, 36, 43, 43, 27, 27, 27, 87, 36, 36, 36, 36, + 163, 27, 30, 2, 2, 2, 2, 2, 36, 43, 43, 2, 2, 2, 2, 2, + 36, 36,165, 27, 27, 27, 27, 27, 79, 81, 36, 36, 36, 36, 36, 36, + 43, 43, 43, 57, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 7, 7, 7, 7, 7, 65, 64, 65, 36, 36, 36, 36, 64, + 78, 79, 43, 77, 79, 57, 73, 2, 2, 43, 43, 43, 43, 43, 67, 59, + 36, 36, 36, 64, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, + 2, 2, 82, 81, 36, 36, 36, 36, 36, 64, 2, 36, 36, 36, 36, 36, + 36, 82, 78, 43, 43, 43, 43, 77, 81, 36, 58, 2, 56, 43, 57, 79, + 7, 7, 7, 7, 7, 58, 58, 2, 90, 27, 27, 27, 27, 27, 27, 27, + 36, 36, 36, 36, 36, 36, 78, 79, 43, 78, 77, 43, 2, 2, 2, 65, + 36, 36, 36, 36, 36, 36, 36, 64, 77, 78, 78, 78, 78, 78, 78, 78, + 36, 36, 36, 82, 78, 78, 81, 36, 36, 78, 78, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 78, 79, 43, 43, 43, 78, 78, 78, 78, 78, 78, 77, + 65, 65, 2, 2, 2, 2, 2, 2, 56, 43, 43, 43, 43, 43, 43, 43, + 36, 36, 82, 78, 43, 43, 43, 43, 78, 43, 77, 65, 36, 58, 2, 2, + 7, 7, 7, 7, 7, 2, 2, 65, 78, 79, 43, 43, 77, 77, 78, 79, + 77, 43, 36, 66, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82, + 78, 43, 43, 43, 78, 78, 43, 79, 57, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 43, 43, 78, 79, 43, 43, 43, 77, 79, 79, + 57, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 79, 78, + 43, 43, 43, 79, 58, 2, 2, 2, 36, 36, 36, 36, 36, 36, 64, 79, 78, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 89, 43, 43, 43, 43, 79, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 87, 78, 78, 78, 78, 78, 79, 77, 65, 81, 79, 2, 2, 2, 2, 2, 2, @@ -4721,39 +4938,41 @@ _hb_ucd_u8[13386] = 78, 78, 78, 78, 78, 78, 78, 78, 64, 43, 43, 43, 43, 65, 36, 36, 36, 64, 43, 43, 77, 64, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43, 64, 43, 43, 77, 79, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, - 43, 43, 43, 77, 43, 2, 66, 2, 43, 43, 43, 43, 43, 43, 43, 79, - 58, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, + 43, 43, 43, 77, 43, 2, 66, 2, 58, 2, 2, 2, 2, 2, 2, 2, + 43, 43, 43, 43, 43, 43, 43, 79, 2, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 77, 43, 43, 43, 77, 43, 79, 43, 43, 43, 43, 43, 43, 43, 43, 64, 43, 43, 43, 43, 36, 36, 36, 36, 36, 78, 78, 78, 43, 77, 79, 79, 36, 36, 36, 36, 36, 64, 77, 97, 2, 2, 2, 2, 43, 82, 36, 36, 36, 36, 36, 36, 36, 36, 78, 43, 43, 43, 43, 78, - 77, 57, 2, 2, 2, 2, 2, 2, 27, 27, 84, 61, 61, 61, 53, 20, - 150, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 21, - 65, 36, 36, 64, 43, 43, 43, 43, 43, 43, 57, 2, 2, 2, 2, 2, - 43, 43, 43, 57, 2, 2, 61, 61, 40, 40, 89, 61, 61, 61, 61, 61, - 7, 7, 7, 7, 7,167, 27, 27, 27, 87, 36, 36, 36, 36, 36, 36, - 27, 27, 27, 30, 2, 2, 2, 2, 82, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 79, 43, 68, 40, 40, 40, 40, 40, 40, - 40, 80, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 47, 57, - 61, 61,168, 79, 43, 61,168, 78, 78,169, 59, 59, 59, 76, 43, 43, - 43, 70, 47, 43, 43, 43, 61, 61, 61, 61, 61, 61, 61, 43, 43, 61, - 61, 43, 70, 61, 61, 61, 61, 61, 11, 11, 11, 11, 11, 16, 16, 16, - 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, - 11, 11, 11, 16, 16, 16, 16, 16, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 16, 7, 43, 43, 43, 70, 61, 47, 43, 43, - 43, 43, 43, 43, 43, 43, 70, 61, 61, 61, 47, 61, 61, 61, 61, 61, - 61, 61, 70, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 43, 43, - 16, 16, 16, 16, 16, 39, 16, 16, 43, 43, 43, 68, 40, 40, 40, 40, - 7, 7, 7, 7, 7, 7, 7, 71, 36, 36, 36, 36, 36, 36, 36, 43, - 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 7, 7,170, - 36, 36, 36, 36, 36, 75, 43, 43, 16, 16, 43, 43, 43, 68, 40, 40, - 27, 27, 27, 27, 27, 27,145, 27,171, 27, 27, 27, 27, 27, 27, 27, + 77, 57, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 43, 43, 43, + 27, 27, 84, 61, 61, 61, 53, 20,150, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 21, 65, 36, 36, 64, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 78, 79, 43, + 43, 43, 57, 2, 2, 2, 2, 2, 43, 43, 43, 57, 2, 2, 61, 61, + 40, 40, 89, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7,168, 27, 27, + 27, 87, 36, 36, 36, 36, 36, 36, 40, 63, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 76,146, 2, 27, 27, 27, 30, 2, 2, 2, 2, + 82, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, + 43, 68, 40, 40, 40, 40, 40, 40, 40, 80, 43, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 36, 36, 47, 57, 61, 61,169, 79, 43, 61,169, 78, + 78,170, 59, 59, 59, 75, 43, 43, 43, 70, 47, 43, 43, 43, 61, 61, + 61, 61, 61, 61, 61, 43, 43, 61, 61, 43, 70, 61, 61, 61, 61, 61, + 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, + 43, 43, 43, 70, 61, 47, 43, 43, 43, 43, 43, 43, 43, 43, 70, 61, + 61, 61, 47, 61, 61, 61, 61, 61, 61, 61, 70, 21, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 56, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, + 43, 43, 43, 68, 40, 40, 40, 40, 7, 7, 7, 7, 7, 7, 7, 71, + 7, 7, 7, 7, 7, 7, 7,171, 36, 36, 36, 36, 36, 76, 43, 43, + 172, 7, 7, 7, 7, 7, 7, 85, 16, 16, 43, 43, 43, 68, 40, 40, + 27, 27, 27, 27, 27, 27,145, 27,173, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, @@ -4764,8 +4983,8 @@ _hb_ucd_u8[13386] = 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, 9, 6, 5, 21, 17, 17, 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21, 7, 21, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, - 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 7, 6, - 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, + 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 1, 12, + 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, 21, 26, 21, 15, 17, 7, 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, 29, 29, 29, 1, 20, 19, @@ -4776,247 +4995,250 @@ _hb_ucd_u8[13386] = 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, - 21, 14, 7, 15, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, 23, 15, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, - 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 21, 14, 7, 15, 9, 12, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, + 7, 13, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, + 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, - 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, - 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, - 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, - 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, - 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, - 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, - 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, - 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, - 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, - 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, - 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, 0, 79, - 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, 0, 87, - 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, 80, 0, - 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, 51, 0, - 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, - 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, 0, 0, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, 0,107, - 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, 0, 0, - 110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, - 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, - 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, - 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, - 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, - 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, - 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, - 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, - 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, - 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, - 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, - 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, - 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, - 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, - 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, - 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, - 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, - 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, - 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, - 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, - 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0,102, 0, - 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106,107, 0, - 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, 33, 0, - 111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, 0, 0, - 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, 0, 0, - 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0,121, 0, - 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, 0, 0, - 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128,129, 0, - 130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, 0, 0, - 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0,138, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, - 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, - 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, - 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, - 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, - 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, - 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 0, - 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, - 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, - 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, - 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, - 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, - 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, - 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, - 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, - 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, - 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, - 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, - 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99, - 100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, - 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, - 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, - 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, - 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, - 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, + 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, + 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, + 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, + 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, + 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, + 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, + 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, + 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, + 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, + 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, 0, 78, + 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, 86, 87, + 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, 93, 0, + 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, 0, 0, + 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, 0,102, + 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104,105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, 0, 0, + 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, 0, 0, + 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, 0,118, + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, + 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, + 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, + 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, + 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, + 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, + 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, + 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, + 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, + 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, + 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, + 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, + 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, + 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, + 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, + 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, + 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, + 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, + 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0,103, 0, + 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107,108, 0, + 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, 33, 0, + 112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0,117, 0, + 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, 88, 0, + 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, 0,122, + 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, 0, 0, + 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, 0,128, + 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0,134,135, + 136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 0, + 138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, + 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, + 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, + 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, + 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, + 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, + 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, 0, 0, + 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, + 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, + 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, + 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, + 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, + 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, + 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, + 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, + 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, + 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, + 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, + 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, + 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0, + 101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, + 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, + 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, + 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0, + 109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, 0, 38, - 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, 55, 0, - 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, - 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, 8, 91, - 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, 0,118, - 119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, 38, 58, - 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, 0, 0, - 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, 0, 0, - 0, 0,230,230,230,230,230,232,220,220,220,220,232,216,220,220, - 220,220,220,202,202,220,220,220,220,202,202,220,220,220, 1, 1, - 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220,220,220, - 230,230,230,220,220, 0,230,230,230,220,220,220,220,230,232,220, - 220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, 0,220, - 230,230,230,230,220,230,230,230,222,220,230,230,220,220,230,222, - 228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, - 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, - 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230, - 230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0, - 220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,220,220, - 230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0,230,230, - 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220,230,220, - 220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, 0, 9, - 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, 0, 84, - 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,103,103, - 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122,220,220, - 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, - 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, 9, 0, - 230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, - 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, - 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, 0, 0, - 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234, - 214,220,202,230,230,230,230,230,232,228,228,220,218,230,233,220, - 230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, - 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, 0, 0, - 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, 0,220, - 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, 0, 0, - 230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, - 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226, - 216,216,216,216,216, 0,220,220,220, 0,232,232,220,230,230,230, - 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, 26, 17, + 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,115, 0, + 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, + 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, + 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, + 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, + 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, + 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, 4,122, + 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230,230,232, + 220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220, + 220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230, + 230,230,230,240,230,220,220,220,230,230,230,220,220, 0,230,230, + 230,220,220,220,220,230,232,220,220,230,233,234,234,233,234,234, + 233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230,230,230, + 222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, + 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, + 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, 0, 0, + 230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, + 0, 0,230,220,230,230,220,220,230,220,220,230,220,230,220,230, + 230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230,230,230, + 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, 27, 28, + 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, + 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, + 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, + 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, + 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, + 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, + 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, 0,228, + 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,230,220, + 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,230, 0, + 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230,230,230, + 232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, 1, 1, + 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,232,222, + 224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,220, 0, + 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230, + 220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, 0, 7, + 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, 0,216, + 216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,220,220, + 220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, 17, 49, + 17, 17, 84, 97,135,145, 26, 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, 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,177, 0, 1, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, + 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, + 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, + 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, + 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, + 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, + 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, + 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, + 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, + 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, + 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, + 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, + 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, + 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, + 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, + 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, + 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, + 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, + 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, + 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, + 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, + 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, + 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, + 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, + 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, + 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, + 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, + 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, + 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 3, 3, 3, 3, 3, + 3, 15, 3, 16, 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, 17, 17, 17, - 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, - 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, - 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, - 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, - 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, - 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, - 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, - 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, - 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, - 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, - 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, - 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, - 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, - 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, - 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, - 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, - 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, - 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, - 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, - 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, - 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, - 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, - 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, - 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, - 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, - 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, - 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, - 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, - 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, - 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, - 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, - 0, 0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 3, 3, 3, 3, 3, 3, 3, 15, 3, 16, 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, 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, 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, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 18, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 17, 17, 18, 17, 19, 20, 21, 22, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 25, 25, 26, 27, 28, 29, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, + 18, 17, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 25, 25, 26, 27, + 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 31, + 31, 31, 31, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 57, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 58, 31, 31, 31, + 59, 60, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 64, 65, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 66, 67, 68, 31, 31, 31, 31, 69, 31, 31, 31, 31, 31, + 31, 31, 17, 70, 71, 72, 17, 17, 73, 74, 31, 75, 76, 77, 78, 79, + 80, 31, 81, 82, 17, 83, 17, 17, 17, 17, 31, 31, 23, 23, 23, 23, + 23, 23, 23, 84, 31, 31, 31, 31, 23, 84, 31, 31, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 52, 53, 31, 31, 31, 31, 54, 55, 55, 56, 31, - 31, 31, 31, 31, 31, 31, 57, 58, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 59, 60, 31, 61, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 64, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 66, 67, 31, 31, - 31, 31, 68, 31, 31, 31, 31, 31, 31, 31, 31, 69, 70, 71, 17, 17, - 72, 73, 31, 74, 75, 76, 77, 78, 79, 31, 80, 81, 17, 82, 17, 17, - 17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 23, 83, 31, 31, 31, 31, - 23, 83, 31, 31, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 84, 0, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, - 4, 5, 6, 7, 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, - 7, 8, 9, 10, 11, 11, 12, 11, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 19, 27, 28, 29, 30, 30, 31, 31, 32, 32, - 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 40, 41, 41, - 42, 42, 42, 43, 44, 44, 45, 46, 47, 47, 47, 47, 48, 48, 48, 48, - 48, 48, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, - 54, 55, 56, 56, 57, 58, 59, 51, 60, 61, 62, 63, 64, 65, 66, 7, - 67, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 7, 4, 4, 4, 4, - 77, 77, 77, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 85, 85, 85, 85, 0, 0, 0, 0, 86, 87, 88, 88, - 89, 90, 48, 91, 0, 0, 92, 92, 92, 92, 92, 93, 94, 95, 96, 97, - 98, 47, 99,100,101,102, 0,103,104,105, 0, 0, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0,106,106,106,106, - 106,106,106,106,106,106,106,107,108,108,108,108,108, 11,109,110, - 111, 4,112, 4,113,114,115,116,117,118,119,120,121,122,123,124, - 125,126, 50,127, 47, 47, 47, 47, 47, 47, 47, 47,128,128,128,128, - 128,128,128,128,128,128,128,128, 92, 92, 92, 92, 92, 92, 92, 92, - 129,130, 19, 19, 19, 19, 19, 19,131, 19, 19, 19,132,133, 19,134, - 135,136,137,101,138,138,138,138, 0, 77,139,140,128,128,141,142, - 143,144,145,146,147,148,149,150,151,152,153,153,154,154,154,154, - 154,154, 4, 4,155,156,157,158,159,160,161,162,163,164,165,166, - 167,168,169,169,170,170,171,171,172,172,128,128, 19, 19,173,174, - 175,176,177,178,179,179,180,181,182,183,184,185,186,186,187,188, - 189,190,128,128,191,191,192,192,128,128,193,193,194,195,196,196, - 197,197,128,128,198,198,199,199,200,200,201,201,202,203,204,205, - 28, 28,128,128,206,207,208,208,209,210,211,211,128,128,212,212, - 213,213,214, 34,215,215,215,215,215,215,215,215,215,215,215,215, - 215,215,128,128,128,128,128,128,128,128,216,216,217,217,217,217, - 217,217,217,217,217,217,128,128,128,128,128,128,218,218,218,218, - 218,218,218,218,218,218,128,128,128,128,128,128,110,110,110,110, - 110,110,110,110,110,219,220,221,222,222,222,222,223,223,223,223, - 224,224,224,225,226,226,226,226,226,226,226,226,226,226,226,226, - 227,227,227,227,227,227,227,227,226,226,128,128,128,128,128,128, - 128,128,104,104,228,229,229,229,230,231,232,232,232,232,232,232, - 128,128,128,128,233,233,234, 0,128,128,128,128,128,128,128,128, - 7,235, 0, 0, 0, 0, 0, 0, 0,236,237, 0, 77, 77, 0, 0, - 0, 0,128,128,238,238,238,238,238,238,238,238,238,238,238,238, - 128,128,128,128,128,128,128,128, 4, 4,128,128,239, 11, 11, 11, - 240,240,128,128,128,128,241,242,128,128,128,128,128,128,243,243, - 128,128,128,128,128,128,128,128,128,128, 48, 48,244,244,244,244, - 245,245,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, - 128,128,128,128,246, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 85, 0, 0, 1, + 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, + 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 11, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 19, 27, + 28, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, + 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 42, 43, 44, 44, 45, 46, + 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 50, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 51, + 60, 61, 62, 63, 64, 65, 66, 7, 67, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 7, 4, 4, 4, 4, 77, 77, 77, 77, 78, 79, 80, 81, + 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, + 0, 0, 0, 0, 86, 87, 88, 88, 89, 90, 48, 91, 0, 0, 92, 92, + 92, 92, 92, 93, 94, 95, 96, 97, 98, 47, 99,100,101,102, 0,103, + 104,105, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 0,106,106,106,106,106,106,106,106,106,106,106,107, + 108,108,108,108,108, 11,109,110,111, 4,112, 4,113,114,115,116, + 117,118,119,120,121,122,123,124,125,126, 50,127, 47, 47, 47, 47, + 47, 47, 47, 47,128,128,128,128,128,128,128,128,128,128,128,128, + 92, 92, 92, 92, 92, 92, 92, 92,129,130, 19, 19, 19, 19, 19, 19, + 131, 19, 19, 19,132,133, 19,134,135,136,137,101,138,138,138,138, + 0, 77,139,140,128,128,141,142,143,144,145,146,147,148,149,150, + 151,152,153,154,155,155,155,155,155,155, 4, 4,156,157,158,159, + 160,161,162,163,164,165,166,167,168,169,170,170,171,171,172,172, + 173,174,174,174, 19, 19,175,176,177,178,179,180,181,181,182,183, + 184,185,186,187,188,188,189,190,191,192,193,193,194,194,195,195, + 128,128,196,196,197,198,199,200,201,201,128,128,202,202,203,203, + 204,204,205,205,206,207,208,209, 28, 28,210,210,211,212,213,213, + 214,215,216,216,128,128,217,217,218,218,219, 34,220,220,220,220, + 220,220,220,220,220,220,220,220,220,220,128,128,128,128,128,128, + 128,128,221,221,222,222,222,222,222,222,222,222,223,223,223,223, + 223,223,223,223,223,223,128,128,128,128,128,128,128,128,128,128, + 224,224,128,128,110,110,110,110,110,110,110,110,110,225,226,227, + 228,228,228,228,128,128,128,128,229,229,128,128,230,230,230,230, + 231,231,231,232,233,233,233,233,233,233,233,233,233,233,233,233, + 234,234,234,234,234,234,234,234,233,233,128,128,128,128,128,128, + 128,128,104,104,235,236,236,236,237,238,239,239,239,239,239,239, + 128,128,128,128,240,240,241, 0,128,128,128,128, 0, 0, 0, 0, + 7,242, 0, 0, 0, 0, 0, 0, 0,243,244, 0, 77, 77, 0, 0, + 0, 0,128,128,245,245,245,245,245,245,245,245,245,245,245,245, + 128,128,128,128,128,128,128,128, 4, 4,128,128,246, 11, 11, 11, + 247,247,128,128,128,128,248,249,128,128,128,128,128,128,250,250, + 128,128,251,251,128,128,128,128,128,128, 48, 48,252,252,252,252, + 253,253,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, + 128,128,128,128,254, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, 128,128,128,128, 0, 0,128,128, 7, 7, 7, 7, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, @@ -5056,30 +5278,32 @@ _hb_ucd_u8[13386] = 137,137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142, 143,143,144,144,144,144,144,144,145,145,145,145,145,146,146,146, 147,147,147,148,148,148,148,148,149,149,149,150,150,150,150,151, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,155,155, - 156,156,156,156,156,156,157,157,158,158,159,159,159,159,159,159, - 160,160,161,161,161,161,161,161,162,162,162,162,162,162,163,163, - 164,164,164,164,165,165,165,165,166,166,166,166,167,167,168,168, - 169,169,169,169,170,170,170,170,171,171,171,171,172,172,172,172, - 173,173,173,173,173,173,173,174,175,175,175,176,176,176,176,177, - 177,177,177,178,178,178,179,179,180,180,180,180,181,181,181,181, - 181,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185, - 185,185,186, 43,187,187,187,187,188,188,188,189,189,189,189,189, - 190,190,190,191,190,190,190,190,192,192,192,192,193,193,193,193, - 194,194,194,194,195,195,195,195,195,195, 66, 66,196,196,196,196, - 197,197,197,197,198,198,198,198,199,199,199,199,200,200,200,200, - 201,201,201,201,202,202,202,202,202,203,203,203,203,203,203, 55, - 204,204,204,204,205,205,205,205,205,205,205,206,206,206,206,206, - 207,207,207,207,207,207,208,208,208,208,208,208,209,209,209,209, - 210,210,210,210,110,110,110,110,211,211,211,211,212,212,212,212, - 213,213,213,213,214,214,214,214,215,215,215,216,216,216,216,216, - 216,217,217,217,218,218,218,218,219,219,219,219,220,220,220,220, - 220,220,221, 94,222,222,222,222,223,223,223,223,224, 99, 99, 99, - 99, 99, 99, 99, 99, 99,102,225, 99,226,102,227,227,227,227,227, - 228,228,228,228,228,228, 0, 0, 8, 0, 0, 0, 0, 0,229,230, - 231, 0,232, 0,233,233,233,233, 91, 91, 91, 13,234,234,234,234, - 235,235,235,235,236,236,236,236,237,237,237,237,238,238,238,238, - 239,239,239,239,240, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, + 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, + 155,155,156,156,157,157,157,157,157,157,158,158,159,159,160,160, + 160,160,160,160,161,161,162,162,162,162,162,162,163,163,163,163, + 163,163,164,164,165,165,165,165,166,166,166,166,167,167,167,167, + 168,168,169,169,170,170,170,170,171,171,171,171,172,172,172,172, + 173,173,173,173,174,174,174,174,175,175,175,175,176, 21, 21, 21, + 177,177,177,178,178,178,178,179,179,179,179,180,180,180,181,181, + 182,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185, + 185,186,186,186,187,187,187,187,187,187,188, 43,189,189,189,189, + 190,190,190,191,191,191,191,191,192,192,192,193,192,192,192,192, + 194,194,194,194,195,195,195,195,196,196,196,196,197,197,197,197, + 198,198,198,198,198,198, 66, 66,199,199,199,199,199, 49, 49, 49, + 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, + 204,204,204,204,205,205,205,205,205,206,206,206,206,206,206, 55, + 207,207,207,207,208,208,208,208,209,209,209,209,209,209,209,210, + 210,210,210,210,211,211,211,211,211,211,212,212,212,212,212,212, + 213,213,213,213,214,214,214,214,110,110,110,110,215,215,215,215, + 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, + 220,220,220,221,221,221,221,221,221,222,222,222,223,223,223,223, + 224,224,224,224,225,225,225,225,226,226,226,226,226,226,227, 94, + 228,228,228,228,229,229,229,229,230, 99, 99, 99, 99, 99, 99, 99, + 99, 99,102,231, 99,232,102,233,233,233,233,233,234,234,234,234, + 234,234, 0, 0, 8, 0, 0, 0, 0, 0,235,236,237, 0,238, 0, + 239,239,239,239, 91, 91, 91, 13,240,240,240,240,241,241,241,241, + 242,242,242,242,243,243,243,243,244,244,244,244,245,245,245,245, + 246,246,246,246,247, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, @@ -5123,98 +5347,102 @@ _hb_ucd_u8[13386] = 163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166, 167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170, 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174, - 174,174,174,175,176,176,176,176,177,177,177,177,178,178,178,178, + 175,175,175,175,176,176,176,176,177, 20, 20, 20,178,178,178,178, 179,179,179,179,180,180,180,180,181,181,181,181,182,182,182,182, 183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186, - 187, 45, 45, 45,188,188,188,188,189,189,189,189,190,190,190,190, - 191,191,191,191,191,191,192,191,193,193,193,193,194,194,194,194, + 187,187,187,187,188,188,188,188,189, 45, 45, 45,190,190,190,190, + 191,191,191,191,192,192,192,192,193,193,193,193,193,193,194,193, 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198, 199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202, 203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206, 207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210, 211,211,211,211,212,212,212,212,213,213,213,213,214,214,214,214, 215,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218, - 219,219,219,219,220,220,220,220,221,221,221,221,222,223,223,223, - 224,224,224,224,223,223,223,223,225,106,106,106,226,106,106,106, - 106,227,109,109,228,228,228,228,229,229,229,229, 0,230, 86, 0, - 0, 0,230, 7, 82,138, 7, 0, 0, 0,231, 86,232,232,232,232, - 233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236, - 237,237,237,237,238,238,238,238,239, 0, 0, 0, 0, 0, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, - 19, 0, 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, - 0, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, - 55, 55, 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, - 4, 4, 4, 4, 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, - 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, - 1, 1, 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, - 64, 64, 64, 64, 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, - 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, - 5, 5, 5, 5, 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, - 22, 22, 22, 22, 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, - 36, 36, 36, 36, 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, - 8, 8, 8, 8, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, - 29, 29, 29, 29, 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, - 35, 35, 35, 0, 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, - 44, 0, 0, 0, 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, - 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, - 52, 52, 52, 52, 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, - 62, 62, 62, 62, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, - 73, 73, 73, 73, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, - 0, 1, 0, 0, 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, - 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, - 19, 19, 19, 9, 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, - 27, 27, 27, 27, 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, - 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, - 12, 12, 12, 0, 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, - 79, 79, 79, 79, 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, - 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, - 84, 84, 84, 0, 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, - 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, - 3, 3, 0, 0, 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, - 49, 49, 49, 49, 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, - 42, 42, 42, 42, 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, - 59, 59, 59, 59, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, - 135,135,135,135,106,106,106,106,104,104,104,104,161,161,161,161, + 219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222, + 223,223,223,223,224,224,224,224,225,225,225,225,226,226,226,226, + 227,227,227,227,228,229,229,229,230,230,230,230,229,229,229,229, + 231,106,106,106,232,106,106,106,106,233,109,109,234,234,234,234, + 235,235,235,235, 0,236, 86, 0, 0, 0,236, 7, 82,138, 7, 0, + 0, 0,237, 86,238,238,238,238,239,239,239,239,240,240,240,240, + 241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244, + 245,245,245,245,246, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, + 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, + 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, + 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, + 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, + 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, + 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, + 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, + 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, + 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, + 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, + 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, + 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, + 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, + 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, + 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, + 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, + 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, + 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, + 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, + 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, + 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, + 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, + 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, + 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, + 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, + 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, + 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, + 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, + 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, + 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, + 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, + 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, + 106,106,106,106,104,104,104,104,161,161,161,161,170,170,170,170, 110,110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120, 116,116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88, 117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130,130,130,130, - 144,144,144,144,156,156,156,156,156, 3, 3, 3,147,147,147,147, - 148,148,148,148,158,158,158,158,153,153,153,153,149,149,149,149, - 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, 96, 96, 96, 96, - 111,111,111,111,100,100,100,100,100, 36, 36, 36,108,108,108,108, - 129,129,129,129,109,109,109,109,107,107,107,107,107,107,107, 1, - 137,137,137,137,124,124,124,124,123,123,123,123,114,114,114,114, - 102,102,102,102,126,126,126,126,142,142,142,142,125,125,125,125, - 154,154,154,154,150,150,150,150,141,141,141,141,140,140,140,140, - 121,121,121,121,133,133,133,133,134,134,134,134,138,138,138,138, - 143,143,143,143,145,145,145,145,163,163,163,163, 63, 63, 63, 63, - 157,157,157,157, 80, 80, 80, 80,127,127,127,127,115,115,115,115, - 159,159,159,159,103,103,103,103,119,119,119,119,146,146,146,146, - 99, 99, 99, 99,136,139, 13, 13,155,155,155,155,136,136,136,136, - 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17,139,139,139,139, - 105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131, - 151,151,151,151,160,160,160,160,152,152,152,152,164,164,164,164, - 113,113,113,113,132,132,132,132, 15, 0, 0, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, - 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 144,144,144,144,165,165,165,165,156,156,156,156,156,156, 3, 3, + 147,147,147,147,148,148,148,148,158,158,158,158,153,153,153,153, + 149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, + 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36, + 108,108,108,108,129,129,129,129,109,109,109,109,107,107,107,107, + 107,107,107, 1,171,171,171,171,137,137,137,137,124,124,124,124, + 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, + 142,142,142,142,125,125,125,125,154,154,154,154,150,150,150,150, + 141,141,141,141,140,140,140,140,121,121,121,121,169,169,169,169, + 133,133,133,133,134,134,134,134,138,138,138,138,143,143,143,143, + 145,145,145,145,163,163,163,163, 63, 63, 63, 63,157,157,157,157, + 80, 80, 80, 80,127,127,127,127,166,166,166,166,115,115,115,115, + 159,159,159,159,103,103,103,103,119,119,119,119,167,167,167,167, + 146,146,146,146, 99, 99, 99, 99,136,139, 13, 13,155,155,155,155, + 136,136,136,136, 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17, + 139,139,139,139,105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1, + 131,131,131,131,151,151,151,151,160,160,160,160,152,152,152,152, + 164,164,164,164,168,168,168,168,113,113,113,113,132,132,132,132, + 15, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, + 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, + 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 23, 9, 9, 9, 9, 9, 24, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -5223,60 +5451,66 @@ _hb_ucd_u8[13386] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, - 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, - 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, + 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, + 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, - 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, - 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, - 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, - 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, + 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, + 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, - 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,110, 0, - 111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119, - 120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131,132,133, - 134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149, - 150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160,161, 0, + 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, + 101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, + 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0, + 115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, + 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, + 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,165, 0, + 0, 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141, + 142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, + 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0, + 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, + 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169, - 170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176,177,178, - 179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194, - 195,196,197,198,199,200,201,202,203,204,205,206, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 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, + 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, + 0, 0,180,181,182,183,184,185,186,187,188,189,190,191,192,193, + 194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, + 210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 3, 4, }; static const uint16_t -_hb_ucd_u16[4920] = +_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, @@ -5303,82 +5537,85 @@ _hb_ucd_u16[4920] = 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146, 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32, 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183, - 47, 47, 184, 185, 186, 61, 47, 187, 11, 9, 9, 9, 66, 188, 189, 190, - 11, 11, 191, 27, 27, 27, 192, 193, 11, 194, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 195, 13, 13, 13, 13, 13, 13, - 196, 196, 196, 196, 196, 197, 196, 11, 198, 198, 198, 199, 200, 201, 201, 200, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 27, 211, 211, 211, 212, 213, 32, - 214, 215, 216, 217, 218, 145, 219, 219, 220, 221, 222, 146, 223, 224, 146, 225, - 226, 226, 226, 226, 226, 226, 226, 226, 227, 146, 228, 146, 146, 146, 146, 229, - 146, 230, 226, 231, 146, 232, 233, 146, 146, 146, 146, 146, 146, 146, 145, 145, - 145, 234, 146, 146, 146, 146, 235, 145, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 236, 237, 146, 146, 238, 146, 146, 146, 146, 146, 146, 239, 146, - 146, 146, 146, 146, 146, 146, 240, 241, 145, 242, 146, 146, 243, 226, 244, 226, - 245, 246, 226, 226, 226, 247, 226, 248, 146, 146, 146, 226, 249, 146, 146, 146, - 9, 9, 9, 11, 11, 11, 250, 251, 13, 13, 13, 13, 13, 13, 252, 253, - 11, 11, 11, 47, 47, 47, 254, 255, 47, 47, 47, 47, 47, 47, 32, 32, - 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, 267, 47, 47, 47, - 47, 268, 148, 47, 47, 47, 47, 269, 47, 270, 47, 47, 146, 146, 146, 47, - 146, 146, 271, 146, 272, 273, 146, 146, 271, 146, 146, 273, 146, 146, 146, 146, - 47, 47, 47, 47, 146, 146, 146, 146, 47, 274, 47, 47, 47, 47, 47, 47, - 47, 146, 146, 146, 146, 47, 47, 187, 275, 47, 61, 47, 13, 13, 276, 277, - 13, 278, 47, 47, 47, 47, 279, 280, 31, 281, 282, 283, 13, 13, 13, 284, - 285, 286, 287, 288, 289, 290, 11, 291, 292, 47, 293, 294, 47, 47, 47, 295, - 296, 47, 47, 297, 298, 160, 32, 299, 61, 47, 300, 47, 301, 302, 47, 47, - 72, 47, 47, 303, 304, 305, 306, 61, 47, 47, 307, 308, 309, 310, 47, 311, - 47, 47, 47, 312, 58, 313, 314, 315, 47, 47, 47, 11, 11, 316, 317, 11, - 11, 11, 11, 11, 47, 47, 318, 160, 319, 319, 319, 319, 319, 319, 319, 319, - 320, 320, 320, 320, 320, 320, 320, 320, 11, 321, 322, 47, 47, 47, 47, 47, - 47, 47, 47, 323, 31, 324, 47, 47, 47, 47, 47, 325, 146, 47, 47, 47, - 47, 47, 47, 47, 326, 146, 146, 327, 32, 328, 32, 329, 330, 331, 332, 47, - 47, 47, 47, 47, 47, 47, 47, 333, 334, 2, 3, 4, 5, 335, 336, 337, - 47, 338, 47, 47, 47, 47, 339, 340, 341, 145, 145, 342, 219, 219, 219, 343, - 344, 146, 146, 146, 146, 146, 146, 345, 346, 346, 346, 346, 346, 346, 346, 346, - 47, 47, 47, 47, 47, 47, 347, 145, 47, 47, 348, 47, 349, 47, 47, 60, - 47, 350, 47, 47, 47, 351, 219, 219, 9, 9, 147, 11, 11, 47, 47, 47, - 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 350, 9, - 9, 352, 11, 11, 11, 11, 11, 11, 27, 27, 27, 27, 27, 27, 27, 27, - 47, 47, 47, 47, 47, 353, 47, 354, 47, 47, 355, 145, 145, 145, 47, 356, - 47, 357, 47, 350, 66, 66, 66, 66, 47, 47, 47, 358, 145, 145, 145, 145, - 359, 47, 47, 360, 145, 66, 47, 361, 47, 362, 145, 145, 363, 47, 364, 66, - 47, 47, 47, 365, 47, 366, 47, 366, 47, 365, 144, 145, 145, 145, 145, 145, - 9, 9, 9, 9, 11, 11, 11, 367, 47, 47, 368, 160, 160, 160, 160, 160, - 145, 145, 145, 145, 145, 145, 145, 145, 47, 47, 369, 47, 47, 47, 47, 143, - 47, 362, 370, 47, 60, 371, 66, 47, 372, 66, 66, 47, 373, 145, 47, 47, - 374, 47, 47, 360, 375, 376, 377, 378, 180, 47, 47, 379, 380, 47, 47, 160, - 97, 47, 381, 382, 383, 47, 47, 384, 180, 47, 47, 385, 386, 387, 388, 145, - 47, 47, 389, 390, 359, 32, 32, 32, 47, 47, 365, 47, 47, 391, 172, 160, - 92, 47, 47, 113, 392, 393, 394, 32, 47, 47, 47, 395, 396, 397, 47, 47, - 47, 47, 47, 398, 399, 160, 160, 160, 47, 47, 400, 401, 402, 403, 32, 32, - 47, 47, 47, 404, 405, 160, 66, 66, 47, 47, 406, 407, 160, 160, 160, 160, - 47, 143, 408, 409, 47, 47, 47, 47, 47, 47, 389, 410, 66, 66, 66, 66, - 9, 9, 9, 9, 11, 11, 128, 411, 47, 47, 47, 412, 413, 160, 160, 160, - 47, 47, 47, 47, 47, 414, 415, 416, 417, 47, 47, 418, 419, 420, 47, 47, - 421, 422, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66, - 47, 47, 400, 423, 424, 128, 145, 425, 47, 156, 426, 427, 32, 32, 32, 32, - 47, 47, 47, 359, 428, 160, 47, 47, 429, 430, 160, 160, 160, 160, 160, 160, - 47, 47, 47, 47, 47, 47, 47, 431, 432, 47, 47, 433, 434, 160, 160, 160, - 47, 47, 47, 47, 145, 435, 436, 437, 219, 219, 219, 219, 219, 219, 219, 66, - 47, 47, 47, 47, 47, 47, 47, 424, 47, 47, 47, 208, 438, 32, 32, 32, - 47, 47, 47, 47, 47, 47, 305, 47, 47, 47, 47, 47, 160, 47, 47, 439, - 47, 47, 47, 440, 441, 442, 443, 47, 9, 9, 9, 9, 9, 9, 11, 11, - 145, 444, 66, 66, 66, 66, 66, 66, 47, 47, 47, 47, 391, 445, 416, 416, - 446, 447, 27, 27, 27, 27, 448, 416, 47, 449, 208, 208, 208, 208, 208, 208, - 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 450, 451, - 452, 146, 453, 146, 146, 146, 146, 146, 146, 146, 146, 146, 454, 146, 146, 146, - 9, 455, 11, 456, 457, 11, 196, 9, 458, 459, 9, 460, 11, 9, 455, 11, - 456, 457, 11, 196, 9, 458, 459, 9, 460, 11, 9, 455, 11, 456, 457, 11, - 196, 9, 458, 459, 9, 460, 11, 9, 455, 11, 196, 9, 461, 462, 463, 464, - 11, 465, 9, 466, 467, 468, 469, 11, 470, 9, 471, 11, 472, 160, 160, 160, - 32, 32, 32, 473, 32, 32, 474, 475, 476, 477, 32, 32, 32, 32, 32, 32, - 478, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27, - 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 479, 480, 146, 146, 146, - 47, 47, 481, 32, 47, 47, 482, 483, 47, 47, 47, 47, 47, 47, 484, 160, - 47, 47, 47, 47, 355, 32, 32, 32, 9, 9, 458, 11, 485, 305, 66, 66, - 145, 145, 486, 487, 145, 145, 145, 145, 145, 145, 488, 145, 145, 145, 145, 145, - 47, 47, 47, 47, 47, 47, 47, 226, 489, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 490, 146, 146, 146, 146, 146, 146, 146, 160, - 208, 208, 208, 208, 208, 208, 208, 208, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 184, 185, 186, 61, 47, 187, 188, 9, 9, 9, 66, 189, 190, 191, + 11, 11, 192, 27, 27, 27, 193, 194, 11, 195, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 196, 13, 13, 13, 13, 13, 13, + 197, 197, 197, 197, 197, 198, 197, 11, 199, 199, 199, 200, 201, 202, 202, 201, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 27, 212, 212, 212, 213, 214, 32, + 215, 216, 217, 218, 219, 145, 220, 220, 221, 222, 223, 146, 224, 225, 146, 226, + 227, 227, 227, 227, 227, 227, 227, 227, 228, 146, 229, 146, 146, 146, 146, 230, + 146, 231, 227, 232, 146, 233, 234, 146, 146, 146, 146, 146, 146, 146, 145, 145, + 145, 235, 146, 146, 146, 146, 236, 145, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 237, 238, 146, 146, 239, 146, 146, 146, 146, 146, 146, 240, 146, + 146, 146, 146, 146, 146, 146, 241, 242, 145, 243, 146, 146, 244, 227, 245, 227, + 246, 247, 227, 227, 227, 248, 227, 249, 146, 146, 146, 227, 250, 146, 146, 146, + 9, 9, 9, 11, 11, 11, 251, 252, 13, 13, 13, 13, 13, 13, 253, 254, + 11, 11, 11, 47, 47, 47, 255, 256, 47, 47, 47, 47, 47, 47, 32, 32, + 257, 258, 259, 260, 261, 262, 263, 263, 264, 265, 266, 267, 268, 47, 47, 47, + 47, 269, 148, 47, 47, 47, 47, 270, 47, 271, 47, 47, 146, 146, 146, 47, + 146, 146, 272, 146, 273, 274, 146, 146, 272, 146, 146, 274, 146, 146, 146, 146, + 47, 47, 47, 47, 146, 146, 146, 146, 47, 275, 47, 47, 47, 47, 47, 47, + 47, 146, 146, 146, 146, 47, 47, 187, 276, 47, 61, 47, 13, 13, 277, 278, + 13, 279, 47, 47, 47, 47, 280, 281, 31, 282, 283, 284, 13, 13, 13, 285, + 286, 287, 288, 289, 290, 291, 9, 292, 293, 47, 294, 295, 47, 47, 47, 296, + 297, 47, 47, 298, 299, 160, 32, 300, 61, 47, 301, 47, 302, 303, 47, 47, + 72, 47, 47, 304, 305, 306, 307, 61, 47, 47, 308, 309, 310, 311, 47, 312, + 47, 47, 47, 313, 58, 314, 315, 316, 47, 47, 47, 11, 11, 317, 318, 11, + 11, 11, 11, 11, 47, 47, 319, 160, 320, 320, 320, 320, 320, 320, 320, 320, + 321, 321, 321, 321, 321, 321, 321, 321, 11, 322, 323, 47, 47, 47, 47, 47, + 47, 47, 47, 324, 31, 325, 47, 47, 47, 47, 47, 326, 146, 47, 47, 47, + 47, 47, 47, 47, 327, 146, 146, 328, 32, 329, 32, 330, 331, 332, 333, 47, + 47, 47, 47, 47, 47, 47, 47, 334, 335, 2, 3, 4, 5, 336, 337, 338, + 47, 339, 47, 47, 47, 47, 340, 341, 342, 145, 145, 343, 220, 220, 220, 344, + 345, 146, 146, 146, 146, 146, 146, 346, 347, 347, 347, 347, 347, 347, 347, 347, + 47, 47, 47, 47, 47, 47, 348, 145, 47, 47, 349, 47, 350, 47, 47, 60, + 47, 351, 47, 47, 47, 352, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, + 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 351, 9, + 9, 353, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, + 47, 47, 47, 47, 47, 354, 47, 355, 47, 47, 356, 145, 145, 145, 47, 357, + 47, 358, 47, 351, 66, 66, 66, 66, 47, 47, 47, 359, 145, 145, 145, 145, + 360, 47, 47, 361, 145, 66, 47, 362, 47, 363, 145, 145, 364, 47, 365, 66, + 47, 47, 47, 366, 47, 367, 47, 367, 47, 366, 144, 145, 145, 145, 145, 145, + 9, 9, 9, 9, 11, 11, 11, 368, 47, 47, 369, 160, 370, 9, 371, 11, + 372, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, + 47, 47, 373, 47, 47, 47, 47, 374, 47, 363, 375, 47, 60, 376, 66, 47, + 377, 66, 66, 47, 378, 145, 47, 47, 379, 47, 47, 361, 380, 381, 382, 383, + 180, 47, 47, 384, 385, 47, 47, 160, 97, 47, 386, 387, 388, 47, 47, 389, + 180, 47, 47, 390, 391, 392, 393, 145, 47, 47, 394, 395, 360, 32, 32, 32, + 47, 47, 366, 47, 47, 396, 172, 160, 92, 47, 47, 113, 397, 398, 399, 32, + 47, 47, 47, 400, 401, 402, 403, 32, 47, 47, 47, 404, 405, 406, 47, 47, + 47, 47, 47, 407, 408, 160, 160, 160, 47, 47, 409, 410, 411, 412, 32, 32, + 47, 47, 47, 413, 414, 160, 66, 66, 47, 47, 415, 416, 160, 160, 160, 160, + 47, 417, 418, 419, 47, 47, 47, 47, 47, 47, 394, 420, 66, 66, 66, 66, + 9, 9, 9, 9, 11, 11, 128, 421, 47, 47, 47, 422, 423, 160, 160, 160, + 47, 47, 47, 47, 47, 424, 425, 426, 427, 47, 47, 428, 429, 430, 47, 47, + 431, 432, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66, + 47, 47, 47, 47, 47, 47, 433, 160, 47, 47, 409, 434, 433, 128, 145, 435, + 47, 156, 436, 437, 32, 32, 32, 32, 47, 47, 47, 360, 438, 160, 47, 47, + 439, 440, 160, 160, 160, 160, 160, 160, 47, 47, 47, 47, 47, 47, 47, 441, + 442, 47, 47, 443, 444, 445, 32, 32, 47, 47, 47, 47, 145, 446, 447, 448, + 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 433, + 47, 47, 47, 209, 449, 32, 47, 47, 47, 450, 451, 160, 160, 160, 160, 160, + 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 452, + 47, 47, 47, 453, 454, 455, 456, 47, 27, 27, 27, 27, 457, 47, 458, 160, + 9, 9, 9, 9, 9, 9, 11, 11, 145, 459, 66, 66, 66, 66, 66, 66, + 47, 47, 47, 47, 396, 460, 426, 426, 461, 462, 27, 27, 27, 27, 463, 426, + 47, 464, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 160, + 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 465, 466, + 467, 146, 468, 146, 146, 146, 146, 146, 146, 146, 146, 146, 469, 146, 146, 146, + 9, 470, 11, 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, + 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 471, 472, 11, + 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 197, 9, 476, 477, 478, 479, + 11, 480, 9, 481, 482, 483, 484, 11, 485, 9, 486, 11, 487, 160, 160, 160, + 32, 32, 32, 488, 32, 32, 489, 490, 491, 492, 32, 32, 32, 32, 32, 32, + 493, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27, + 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 494, 495, 146, 146, 146, + 47, 47, 450, 32, 47, 47, 374, 496, 47, 47, 47, 47, 47, 47, 497, 160, + 47, 47, 47, 47, 47, 47, 450, 498, 47, 47, 47, 47, 356, 32, 32, 32, + 9, 9, 473, 11, 499, 306, 66, 66, 145, 145, 500, 501, 145, 145, 145, 145, + 145, 145, 502, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, + 503, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 504, + 209, 209, 209, 209, 209, 209, 209, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, @@ -5541,16 +5778,23 @@ _hb_ucd_u16[4920] = 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0, + 0,1936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1938, 0,1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1943,1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, + 0, 0, 0, 0, 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949, + 1951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1953,1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1955,1956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1957, 0, 0, 0, 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964, + 1963, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1967,1966,1968, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1976,1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, @@ -5601,12 +5845,12 @@ _hb_ucd_i16[92] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114112u?_hb_ucd_u8[5096+(((_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<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; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[7054+(((_hb_ucd_u8[6498+(((_hb_ucd_u8[6038+(((_hb_ucd_u8[5686+(((_hb_ucd_u8[5440+(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<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; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -5616,17 +5860,17 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7946+(((_hb_ucd_u8[7714+(((_hb_ucd_u8[7618+(((_hb_ucd_b4(7554+_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<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; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11244+(((_hb_ucd_u8[10280+(((_hb_ucd_u8[9292+(((_hb_ucd_u8[8612+(((_hb_ucd_u8[8308+(((_hb_ucd_u8[8194+(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<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; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12586+(((_hb_ucd_u8[12204+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + 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; } #endif diff --git a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh index e607e8ca829..4bc8d64c28f 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh @@ -7,13 +7,13 @@ * on file with this header: * * # emoji-data.txt - * # Date: 2023-02-01, 02:22:54 GMT - * # © 2023 Unicode®, Inc. + * # Date: 2024-05-01, 21:25:24 GMT + * # © 2024 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. - * # For terms of use, see https://www.unicode.org/terms_of_use.html + * # For terms of use and license, see https://www.unicode.org/terms_of_use.html * # * # Emoji Data for UTS #51 - * # Used with Emoji Version 15.1 and subsequent minor revisions (if any) + * # Used with Emoji Version 16.0 and subsequent minor revisions (if any) * # * # For documentation and usage, see https://www.unicode.org/reports/tr51 */ diff --git a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh index 9175df265b9..7fd3bf8828b 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-utf.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-utf.hh @@ -458,19 +458,21 @@ struct hb_ascii_t template static inline const typename utf_t::codepoint_t * hb_utf_offset_to_pointer (const typename utf_t::codepoint_t *start, + const typename utf_t::codepoint_t *text, + unsigned text_len, signed offset) { hb_codepoint_t unicode; while (offset-- > 0) start = utf_t::next (start, - start + utf_t::max_len, + text + text_len, &unicode, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT); while (offset++ < 0) start = utf_t::prev (start, - start - utf_t::max_len, + text, &unicode, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT); diff --git a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh index 001789a3037..7e755818ddd 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh @@ -37,6 +37,8 @@ template struct hb_vector_t { + static constexpr bool realloc_move = true; + typedef Type item_t; static constexpr unsigned item_size = hb_static_size (Type); using array_t = typename std::conditional, hb_array_t>::type; @@ -51,32 +53,29 @@ struct hb_vector_t } template - hb_vector_t (const Iterable &o) : hb_vector_t () + explicit hb_vector_t (const Iterable &o) : hb_vector_t () { - auto iter = hb_iter (o); - if (iter.is_random_access_iterator || iter.has_fast_len) - alloc (hb_len (iter), true); - hb_copy (iter, *this); + extend (o); } hb_vector_t (const hb_vector_t &o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o.as_array ()); } hb_vector_t (array_t o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } hb_vector_t (c_array_t o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } - hb_vector_t (hb_vector_t &&o) + hb_vector_t (hb_vector_t &&o) noexcept { allocated = o.allocated; length = o.length; @@ -85,6 +84,35 @@ struct hb_vector_t } ~hb_vector_t () { fini (); } + template + void extend (const Iterable &o) + { + auto iter = hb_iter (o); + if (iter.is_random_access_iterator || iter.has_fast_len) + alloc (hb_len (iter), true); + while (iter) + { + if (unlikely (!alloc (length + 1))) + return; + unsigned room = allocated - length; + for (unsigned i = 0; i < room && iter; i++) + push_has_room (*iter++); + } + } + void extend (array_t o) + { + alloc (length + o.length); + if (unlikely (in_error ())) return; + copy_array (o); + } + void extend (c_array_t o) + { + alloc (length + o.length); + if (unlikely (in_error ())) return; + copy_array (o); + } + public: int allocated = 0; /* < 0 means allocation failed. */ unsigned int length = 0; @@ -120,7 +148,7 @@ struct hb_vector_t resize (0); } - friend void swap (hb_vector_t& a, hb_vector_t& b) + friend void swap (hb_vector_t& a, hb_vector_t& b) noexcept { hb_swap (a.allocated, b.allocated); hb_swap (a.length, b.length); @@ -130,14 +158,15 @@ struct hb_vector_t hb_vector_t& operator = (const hb_vector_t &o) { reset (); - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return *this; + length = 0; copy_array (o.as_array ()); return *this; } - hb_vector_t& operator = (hb_vector_t &&o) + hb_vector_t& operator = (hb_vector_t &&o) noexcept { hb_swap (*this, o); return *this; @@ -216,6 +245,10 @@ struct hb_vector_t // reference to it. return std::addressof (Crap (Type)); + return push_has_room (std::forward (args)...); + } + template Type *push_has_room (Args&&... args) + { /* Emplace. */ Type *p = std::addressof (arrayZ[length++]); return new (p) Type (std::forward (args)...); @@ -268,10 +301,9 @@ struct hb_vector_t } return new_array; } - /* Specialization for hb_vector_t> to speed up. */ + /* Specialization for types that can be moved using realloc(). */ template ) || - hb_is_same (T, hb_array_t ))> + hb_enable_if (T::realloc_move)> Type * realloc_vector (unsigned new_allocated, hb_priority<1>) { @@ -310,18 +342,23 @@ struct hb_vector_t length = size; } + template + void + copy_array (hb_array_t other) + { + assert ((int) (length + other.length) <= allocated); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; + } template void copy_array (hb_array_t other) { - length = other.length; - if (!HB_OPTIMIZE_SIZE_VAL && sizeof (T) >= sizeof (long long)) - /* This runs faster because of alignment. */ - for (unsigned i = 0; i < length; i++) - arrayZ[i] = other.arrayZ[i]; - else - hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size); + assert ((int) (length + other.length) <= allocated); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; } template other) { - length = 0; - while (length < other.length) - { - length++; - new (std::addressof (arrayZ[length - 1])) Type (other.arrayZ[length - 1]); - } + assert ((int) (length + other.length) <= allocated); + for (unsigned i = 0; i < other.length; i++) + new (std::addressof (arrayZ[length + i])) Type (other.arrayZ[i]); + length += other.length; } template other) { - length = 0; - while (length < other.length) + assert ((int) (length + other.length) <= allocated); + for (unsigned i = 0; i < other.length; i++) { - length++; - new (std::addressof (arrayZ[length - 1])) Type (); - arrayZ[length - 1] = other.arrayZ[length - 1]; + new (std::addressof (arrayZ[length + i])) Type (); + arrayZ[length + i] = other.arrayZ[i]; } + length += other.length; } void @@ -431,6 +466,15 @@ struct hb_vector_t return true; } + bool alloc_exact (unsigned int size) + { + return alloc (size, true); + } + + void clear () + { + resize (0); + } bool resize (int size_, bool initialize = true, bool exact = false) { @@ -496,7 +540,7 @@ struct hb_vector_t shrink_vector (size); if (shrink_memory) - alloc (size, true); /* To force shrinking memory if needed. */ + alloc_exact (size); /* To force shrinking memory if needed. */ } diff --git a/src/java.desktop/share/native/libharfbuzz/hb-version.h b/src/java.desktop/share/native/libharfbuzz/hb-version.h index 3627da3bf0c..01edf174350 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb-version.h +++ b/src/java.desktop/share/native/libharfbuzz/hb-version.h @@ -41,26 +41,26 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 8 +#define HB_VERSION_MAJOR 10 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 2 +#define HB_VERSION_MINOR 4 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 2 +#define HB_VERSION_MICRO 0 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "8.2.2" +#define HB_VERSION_STRING "10.4.0" /** * HB_VERSION_ATLEAST: diff --git a/src/java.desktop/share/native/libharfbuzz/hb.hh b/src/java.desktop/share/native/libharfbuzz/hb.hh index 65d2dd58a20..fee1c9cd663 100644 --- a/src/java.desktop/share/native/libharfbuzz/hb.hh +++ b/src/java.desktop/share/native/libharfbuzz/hb.hh @@ -64,6 +64,7 @@ #pragma GCC diagnostic error "-Wbitwise-instead-of-logical" #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" +#pragma GCC diagnostic error "-Wcast-function-type-strict" #pragma GCC diagnostic error "-Wconstant-conversion" #pragma GCC diagnostic error "-Wcomma" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" @@ -83,6 +84,7 @@ #pragma GCC diagnostic error "-Wredundant-decls" #pragma GCC diagnostic error "-Wreorder" #pragma GCC diagnostic error "-Wsign-compare" +#pragma GCC diagnostic error "-Wstrict-flex-arrays" #pragma GCC diagnostic error "-Wstrict-prototypes" #pragma GCC diagnostic error "-Wstring-conversion" #pragma GCC diagnostic error "-Wswitch-enum" @@ -129,6 +131,7 @@ #pragma GCC diagnostic ignored "-Wclass-memaccess" #pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126 #pragma GCC diagnostic ignored "-Wdangling-reference" // https://github.com/harfbuzz/harfbuzz/issues/4043 +#pragma GCC diagnostic ignored "-Wdangling-pointer" // Trigerred by hb_decycler_node_t(). #pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" @@ -177,6 +180,11 @@ #define HB_EXTERN __declspec (dllexport) extern #endif +// https://github.com/harfbuzz/harfbuzz/pull/4619 +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif + #include "hb.h" #define HB_H_IN #include "hb-ot.h" @@ -212,6 +220,12 @@ #include #endif +#ifndef PRId32 +# define PRId32 "d" +# define PRIu32 "u" +# define PRIx32 "x" +#endif + #define HB_PASTE1(a,b) a##b #define HB_PASTE(a,b) HB_PASTE1(a,b) @@ -268,7 +282,9 @@ extern "C" void hb_free_impl(void *ptr); #define __attribute__(x) #endif -#if defined(__GNUC__) && (__GNUC__ >= 3) +#if defined(__MINGW32__) && (__GNUC__ >= 3) +#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (gnu_printf, format_idx, arg_idx))) +#elif defined(__GNUC__) && (__GNUC__ >= 3) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) #else #define HB_PRINTF_FUNC(format_idx, arg_idx)