diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2022-06-28 01:11:49 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2022-06-28 01:11:49 +0000 |
commit | 00c336bd056351261cffe1fbde346400efd0c2a8 (patch) | |
tree | 3b3fb9f696c7373ed1366e929ceaaa5772ca249f /Build/source/libs/harfbuzz/harfbuzz-src/src | |
parent | cc78cc643e23a05d17912bc5589afbd0d2c7cc4c (diff) |
harfbuzz 4.4.0
git-svn-id: svn://tug.org/texlive/trunk@63743 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src')
147 files changed, 9264 insertions, 7332 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am index 99168c6b7c5..e1b56a5e9a7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am @@ -437,6 +437,7 @@ endif TESTS_ENVIRONMENT = \ srcdir="$(srcdir)" \ + base_srcdir="$(srcdir)" \ builddir="$(builddir)" \ MAKE="$(MAKE) $(AM_MAKEFLAGS)" \ HBSOURCES="$(HBSOURCES)" \ @@ -465,7 +466,7 @@ INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) INTROSPECTION_SCANNER_ENV = CC="$(CC)" HarfBuzz-0.0.gir: libharfbuzz.la libharfbuzz-gobject.la -HarfBuzz_0_0_gir_INCLUDES = GObject-2.0 +HarfBuzz_0_0_gir_INCLUDES = GObject-2.0 freetype2-2.0 HarfBuzz_0_0_gir_CFLAGS = \ $(INCLUDES) \ $(HBCFLAGS) \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources index 20c5188e21f..02c7a46a198 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources @@ -88,6 +88,15 @@ HB_BASE_sources = \ hb-ot-layout-gdef-table.hh \ hb-ot-layout-gpos-table.hh \ hb-ot-layout-gsub-table.hh \ + OT/glyf/glyf.hh \ + OT/glyf/glyf-helpers.hh \ + OT/glyf/loca.hh \ + OT/glyf/path-builder.hh \ + OT/glyf/Glyph.hh \ + OT/glyf/GlyphHeader.hh \ + OT/glyf/SimpleGlyph.hh \ + OT/glyf/CompositeGlyph.hh \ + OT/glyf/SubsetGlyph.hh \ OT/Layout/GSUB/Common.hh \ OT/Layout/GSUB/Sequence.hh \ OT/Layout/GSUB/SingleSubstFormat1.hh \ @@ -131,30 +140,29 @@ HB_BASE_sources = \ hb-ot-os2-unicode-ranges.hh \ hb-ot-post-macroman.hh \ hb-ot-post-table.hh \ - hb-ot-shape-complex-arabic-fallback.hh \ - hb-ot-shape-complex-arabic-joining-list.hh \ - hb-ot-shape-complex-arabic-table.hh \ - hb-ot-shape-complex-arabic-win1256.hh \ - hb-ot-shape-complex-arabic.cc \ - hb-ot-shape-complex-arabic.hh \ - hb-ot-shape-complex-default.cc \ - hb-ot-shape-complex-hangul.cc \ - hb-ot-shape-complex-hebrew.cc \ - hb-ot-shape-complex-indic-table.cc \ - hb-ot-shape-complex-indic.cc \ - hb-ot-shape-complex-indic.hh \ - hb-ot-shape-complex-khmer.cc \ - hb-ot-shape-complex-khmer.hh \ - hb-ot-shape-complex-myanmar.cc \ - hb-ot-shape-complex-myanmar.hh \ - hb-ot-shape-complex-syllabic.cc \ - hb-ot-shape-complex-syllabic.hh \ - hb-ot-shape-complex-thai.cc \ - hb-ot-shape-complex-use-table.hh \ - hb-ot-shape-complex-use.cc \ - hb-ot-shape-complex-vowel-constraints.cc \ - hb-ot-shape-complex-vowel-constraints.hh \ - hb-ot-shape-complex.hh \ + hb-ot-shaper-arabic-fallback.hh \ + hb-ot-shaper-arabic-joining-list.hh \ + hb-ot-shaper-arabic-pua.hh \ + hb-ot-shaper-arabic-table.hh \ + hb-ot-shaper-arabic-win1256.hh \ + hb-ot-shaper-arabic.cc \ + hb-ot-shaper-arabic.hh \ + hb-ot-shaper-default.cc \ + hb-ot-shaper-hangul.cc \ + hb-ot-shaper-hebrew.cc \ + hb-ot-shaper-indic-table.cc \ + hb-ot-shaper-indic.cc \ + hb-ot-shaper-indic.hh \ + hb-ot-shaper-khmer.cc \ + hb-ot-shaper-myanmar.cc \ + hb-ot-shaper-syllabic.cc \ + hb-ot-shaper-syllabic.hh \ + hb-ot-shaper-thai.cc \ + hb-ot-shaper-use-table.hh \ + hb-ot-shaper-use.cc \ + hb-ot-shaper-vowel-constraints.cc \ + hb-ot-shaper-vowel-constraints.hh \ + hb-ot-shaper.hh \ hb-ot-shape-fallback.cc \ hb-ot-shape-fallback.hh \ hb-ot-shape-normalize.cc \ @@ -203,19 +211,19 @@ HB_BASE_RAGEL_GENERATED_sources = \ hb-buffer-deserialize-json.hh \ hb-buffer-deserialize-text.hh \ hb-number-parser.hh \ - hb-ot-shape-complex-indic-machine.hh \ - hb-ot-shape-complex-khmer-machine.hh \ - hb-ot-shape-complex-myanmar-machine.hh \ - hb-ot-shape-complex-use-machine.hh \ + hb-ot-shaper-indic-machine.hh \ + hb-ot-shaper-khmer-machine.hh \ + hb-ot-shaper-myanmar-machine.hh \ + hb-ot-shaper-use-machine.hh \ $(NULL) HB_BASE_RAGEL_sources = \ hb-buffer-deserialize-json.rl \ hb-buffer-deserialize-text.rl \ hb-number-parser.rl \ - hb-ot-shape-complex-indic-machine.rl \ - hb-ot-shape-complex-khmer-machine.rl \ - hb-ot-shape-complex-myanmar-machine.rl \ - hb-ot-shape-complex-use-machine.rl \ + hb-ot-shaper-indic-machine.rl \ + hb-ot-shaper-khmer-machine.rl \ + hb-ot-shaper-myanmar-machine.rl \ + hb-ot-shaper-use-machine.rl \ $(NULL) HB_BASE_headers = \ @@ -224,6 +232,7 @@ HB_BASE_headers = \ hb-blob.h \ hb-buffer.h \ hb-common.h \ + hb-cplusplus.hh \ hb-deprecated.h \ hb-draw.h \ hb-face.h \ @@ -301,6 +310,8 @@ HB_SUBSET_sources = \ hb-subset.cc \ hb-subset.hh \ hb-repacker.hh \ + graph/graph.hh \ + graph/serialize.hh \ $(NULL) HB_SUBSET_headers = \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/GSUB.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/GSUB.hh index ad153ce8d78..3f0c4b2ad9a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/GSUB.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/GSUB.hh @@ -19,6 +19,8 @@ namespace GSUB { struct GSUB : GSUBGPOS { + using Lookup = SubstLookup; + static constexpr hb_tag_t tableTag = HB_OT_TAG_GSUB; const SubstLookup& get_lookup (unsigned int i) const diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookup.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookup.hh index 3419b5a734c..8fb3b550976 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookup.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookup.hh @@ -10,7 +10,7 @@ namespace GSUB { struct SubstLookup : Lookup { - typedef SubstLookupSubTable SubTable; + using SubTable = SubstLookupSubTable; bool sanitize (hb_sanitize_context_t *c) const { return Lookup::sanitize<SubTable> (c); } @@ -73,8 +73,6 @@ struct SubstLookup : Lookup return hb_closure_lookups_context_t::default_return_value (); } - c->set_recurse_func (dispatch_closure_lookups_recurse_func); - hb_closure_lookups_context_t::return_t ret = dispatch (c); return ret; } @@ -100,8 +98,6 @@ struct SubstLookup : Lookup return dispatch (c); } - static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); - bool serialize_single (hb_serialize_context_t *c, uint32_t lookup_props, hb_sorted_array_t<const HBGlyphID16> glyphs, @@ -206,8 +202,6 @@ struct SubstLookup : Lookup return ret; } - HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned lookup_index); - template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh new file mode 100644 index 00000000000..c145beaa49a --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh @@ -0,0 +1,258 @@ +#ifndef OT_GLYF_COMPOSITEGLYPH_HH +#define OT_GLYF_COMPOSITEGLYPH_HH + + +#include "../../hb-open-type.hh" + + +namespace OT { +namespace glyf_impl { + + +struct CompositeGlyphRecord +{ + protected: + enum composite_glyph_flag_t + { + ARG_1_AND_2_ARE_WORDS = 0x0001, + ARGS_ARE_XY_VALUES = 0x0002, + ROUND_XY_TO_GRID = 0x0004, + WE_HAVE_A_SCALE = 0x0008, + MORE_COMPONENTS = 0x0020, + WE_HAVE_AN_X_AND_Y_SCALE = 0x0040, + WE_HAVE_A_TWO_BY_TWO = 0x0080, + WE_HAVE_INSTRUCTIONS = 0x0100, + USE_MY_METRICS = 0x0200, + OVERLAP_COMPOUND = 0x0400, + SCALED_COMPONENT_OFFSET = 0x0800, + UNSCALED_COMPONENT_OFFSET = 0x1000 + }; + + public: + unsigned int get_size () const + { + unsigned int size = min_size; + /* arg1 and 2 are int16 */ + if (flags & ARG_1_AND_2_ARE_WORDS) size += 4; + /* arg1 and 2 are int8 */ + else size += 2; + + /* One x 16 bit (scale) */ + if (flags & WE_HAVE_A_SCALE) size += 2; + /* Two x 16 bit (xscale, yscale) */ + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4; + /* Four x 16 bit (xscale, scale01, scale10, yscale) */ + else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8; + + return size; + } + + void drop_instructions_flag () { flags = (uint16_t) flags & ~WE_HAVE_INSTRUCTIONS; } + void set_overlaps_flag () + { + flags = (uint16_t) flags | OVERLAP_COMPOUND; + } + + bool has_instructions () const { return flags & WE_HAVE_INSTRUCTIONS; } + + bool has_more () const { return flags & MORE_COMPONENTS; } + bool is_use_my_metrics () const { return flags & USE_MY_METRICS; } + bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); } + void get_anchor_points (unsigned int &point1, unsigned int &point2) const + { + const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex); + if (flags & ARG_1_AND_2_ARE_WORDS) + { + point1 = ((const HBUINT16 *) p)[0]; + point2 = ((const HBUINT16 *) p)[1]; + } + else + { + point1 = p[0]; + point2 = p[1]; + } + } + + void transform_points (contour_point_vector_t &points) const + { + float matrix[4]; + contour_point_t trans; + if (get_transformation (matrix, trans)) + { + if (scaled_offsets ()) + { + points.translate (trans); + points.transform (matrix); + } + else + { + points.transform (matrix); + points.translate (trans); + } + } + } + + protected: + bool scaled_offsets () const + { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; } + + bool get_transformation (float (&matrix)[4], contour_point_t &trans) const + { + matrix[0] = matrix[3] = 1.f; + matrix[1] = matrix[2] = 0.f; + + int tx, ty; + const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex); + if (flags & ARG_1_AND_2_ARE_WORDS) + { + tx = *(const HBINT16 *) p; + p += HBINT16::static_size; + ty = *(const HBINT16 *) p; + p += HBINT16::static_size; + } + else + { + tx = *p++; + ty = *p++; + } + if (is_anchored ()) tx = ty = 0; + + trans.init ((float) tx, (float) ty); + + { + const F2DOT14 *points = (const F2DOT14 *) p; + if (flags & WE_HAVE_A_SCALE) + { + matrix[0] = matrix[3] = points[0].to_float (); + return true; + } + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) + { + matrix[0] = points[0].to_float (); + matrix[3] = points[1].to_float (); + return true; + } + else if (flags & WE_HAVE_A_TWO_BY_TWO) + { + matrix[0] = points[0].to_float (); + matrix[1] = points[1].to_float (); + matrix[2] = points[2].to_float (); + matrix[3] = points[3].to_float (); + return true; + } + } + return tx || ty; + } + + public: + HBUINT16 flags; + HBGlyphID16 glyphIndex; + public: + DEFINE_SIZE_MIN (4); +}; + +struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphRecord &> +{ + typedef const CompositeGlyphRecord *__item_t__; + composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) : + glyph (glyph_), current (nullptr), current_size (0) + { + set_current (current_); + } + + composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {} + + item_t __item__ () const { return *current; } + bool __more__ () const { return current; } + void __next__ () + { + if (!current->has_more ()) { current = nullptr; return; } + + set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size)); + } + composite_iter_t __end__ () const { return composite_iter_t (); } + bool operator != (const composite_iter_t& o) const + { return current != o.current; } + + + void set_current (__item_t__ current_) + { + if (!glyph.check_range (current_, CompositeGlyphRecord::min_size)) + { + current = nullptr; + current_size = 0; + return; + } + unsigned size = current_->get_size (); + if (!glyph.check_range (current_, size)) + { + current = nullptr; + current_size = 0; + return; + } + + current = current_; + current_size = size; + } + + private: + hb_bytes_t glyph; + __item_t__ current; + unsigned current_size; +}; + +struct CompositeGlyph +{ + const GlyphHeader &header; + hb_bytes_t bytes; + CompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : + header (header_), bytes (bytes_) {} + + composite_iter_t iter () const + { return composite_iter_t (bytes, &StructAfter<CompositeGlyphRecord, GlyphHeader> (header)); } + + unsigned int instructions_length (hb_bytes_t bytes) const + { + unsigned int start = bytes.length; + unsigned int end = bytes.length; + const CompositeGlyphRecord *last = nullptr; + for (auto &item : iter ()) + last = &item; + if (unlikely (!last)) return 0; + + if (last->has_instructions ()) + start = (char *) last - &bytes + last->get_size (); + if (unlikely (start > end)) return 0; + return end - start; + } + + /* Trimming for composites not implemented. + * If removing hints it falls out of that. */ + const hb_bytes_t trim_padding () const { return bytes; } + + void drop_hints () + { + for (const auto &_ : iter ()) + const_cast<CompositeGlyphRecord &> (_).drop_instructions_flag (); + } + + /* Chop instructions off the end */ + void drop_hints_bytes (hb_bytes_t &dest_start) const + { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); } + + void set_overlaps_flag () + { + CompositeGlyphRecord& glyph_chain = const_cast<CompositeGlyphRecord &> ( + StructAfter<CompositeGlyphRecord, GlyphHeader> (header)); + if (!bytes.check_range(&glyph_chain, CompositeGlyphRecord::min_size)) + return; + glyph_chain.set_overlaps_flag (); + } +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_COMPOSITEGLYPH_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh new file mode 100644 index 00000000000..365939d9a3a --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh @@ -0,0 +1,233 @@ +#ifndef OT_GLYF_GLYPH_HH +#define OT_GLYF_GLYPH_HH + + +#include "../../hb-open-type.hh" + +#include "GlyphHeader.hh" +#include "SimpleGlyph.hh" +#include "CompositeGlyph.hh" + + +namespace OT { + +struct glyf_accelerator_t; + +namespace glyf_impl { + + +enum phantom_point_index_t +{ + PHANTOM_LEFT = 0, + PHANTOM_RIGHT = 1, + PHANTOM_TOP = 2, + PHANTOM_BOTTOM = 3, + PHANTOM_COUNT = 4 +}; + +struct Glyph +{ + enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE }; + + public: + composite_iter_t get_composite_iterator () const + { + if (type != COMPOSITE) return composite_iter_t (); + return CompositeGlyph (*header, bytes).iter (); + } + + const hb_bytes_t trim_padding () const + { + switch (type) { + case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding (); + case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding (); + default: return bytes; + } + } + + void drop_hints () + { + switch (type) { + case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return; + case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return; + default: return; + } + } + + void set_overlaps_flag () + { + switch (type) { + case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return; + case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return; + default: return; + } + } + + void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const + { + switch (type) { + case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return; + case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return; + default: return; + } + } + + /* Note: Recursively calls itself. + * all_points includes phantom points + */ + template <typename accelerator_t> + bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, + contour_point_vector_t &all_points /* OUT */, + bool phantom_only = false, + unsigned int depth = 0) const + { + if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false; + contour_point_vector_t stack_points; + bool inplace = type == SIMPLE && all_points.length == 0; + contour_point_vector_t &points = inplace ? all_points : stack_points; + + switch (type) { + case COMPOSITE: + { + /* pseudo component points for each component in composite glyph */ + unsigned num_points = hb_len (CompositeGlyph (*header, bytes).iter ()); + if (unlikely (!points.resize (num_points))) return false; + break; + } + case SIMPLE: + /* Load into all_points if it's empty, as an optimization. */ + if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only))) + return false; + break; + } + + /* Init phantom points */ + if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; + hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + { + int h_delta = (int) header->xMin - + glyf_accelerator.hmtx->get_side_bearing (gid); + int v_orig = (int) header->yMax + +#ifndef HB_NO_VERTICAL + glyf_accelerator.vmtx->get_side_bearing (gid) +#else + 0 +#endif + ; + unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid); + unsigned v_adv = +#ifndef HB_NO_VERTICAL + glyf_accelerator.vmtx->get_advance (gid) +#else + - font->face->get_upem () +#endif + ; + phantoms[PHANTOM_LEFT].x = h_delta; + phantoms[PHANTOM_RIGHT].x = h_adv + h_delta; + phantoms[PHANTOM_TOP].y = v_orig; + phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; + } + +#ifndef HB_NO_VAR + glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ()); +#endif + + switch (type) { + case SIMPLE: + if (!inplace) + all_points.extend (points.as_array ()); + break; + case COMPOSITE: + { + contour_point_vector_t comp_points; + unsigned int comp_index = 0; + for (auto &item : get_composite_iterator ()) + { + comp_points.reset (); + if (unlikely (!glyf_accelerator.glyph_for_gid (item.glyphIndex) + .get_points (font, glyf_accelerator, comp_points, + phantom_only, depth + 1))) + return false; + + /* Copy phantom points from component if USE_MY_METRICS flag set */ + if (item.is_use_my_metrics ()) + for (unsigned int i = 0; i < PHANTOM_COUNT; i++) + phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; + + /* Apply component transformation & translation */ + item.transform_points (comp_points); + + /* Apply translation from gvar */ + comp_points.translate (points[comp_index]); + + if (item.is_anchored ()) + { + unsigned int p1, p2; + item.get_anchor_points (p1, p2); + if (likely (p1 < all_points.length && p2 < comp_points.length)) + { + contour_point_t delta; + delta.init (all_points[p1].x - comp_points[p2].x, + all_points[p1].y - comp_points[p2].y); + + comp_points.translate (delta); + } + } + + all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT)); + + comp_index++; + } + + all_points.extend (phantoms); + } break; + default: + all_points.extend (phantoms); + } + + if (depth == 0) /* Apply at top level */ + { + /* Undocumented rasterizer behavior: + * Shift points horizontally by the updated left side bearing + */ + contour_point_t delta; + delta.init (-phantoms[PHANTOM_LEFT].x, 0.f); + if (delta.x) all_points.translate (delta); + } + + return !all_points.in_error (); + } + + bool get_extents (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, + hb_glyph_extents_t *extents) const + { + if (type == EMPTY) return true; /* Empty glyph; zero extents. */ + return header->get_extents (font, glyf_accelerator, gid, extents); + } + + hb_bytes_t get_bytes () const { return bytes; } + + Glyph (hb_bytes_t bytes_ = hb_bytes_t (), + hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_), + header (bytes.as<GlyphHeader> ()), + gid (gid_) + { + int num_contours = header->numberOfContours; + if (unlikely (num_contours == 0)) type = EMPTY; + else if (num_contours > 0) type = SIMPLE; + else type = COMPOSITE; /* negative numbers */ + } + + protected: + hb_bytes_t bytes; + const GlyphHeader *header; + hb_codepoint_t gid; + unsigned type; +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_GLYPH_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/GlyphHeader.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/GlyphHeader.hh new file mode 100644 index 00000000000..792bd5478f5 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/GlyphHeader.hh @@ -0,0 +1,48 @@ +#ifndef OT_GLYF_GLYPHHEADER_HH +#define OT_GLYF_GLYPHHEADER_HH + + +#include "../../hb-open-type.hh" + + +namespace OT { +namespace glyf_impl { + + +struct GlyphHeader +{ + bool has_data () const { return numberOfContours; } + + template <typename accelerator_t> + bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator, + hb_codepoint_t gid, hb_glyph_extents_t *extents) const + { + /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */ + /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */ + extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid)); + extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax)); + extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax)); + extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax)); + + return true; + } + + HBINT16 numberOfContours; + /* If the number of contours is + * greater than or equal to zero, + * this is a simple glyph; if negative, + * this is a composite glyph. */ + FWORD xMin; /* Minimum x for coordinate data. */ + FWORD yMin; /* Minimum y for coordinate data. */ + FWORD xMax; /* Maximum x for coordinate data. */ + FWORD yMax; /* Maximum y for coordinate data. */ + public: + DEFINE_SIZE_STATIC (10); +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_GLYPHHEADER_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh new file mode 100644 index 00000000000..93b457cb090 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh @@ -0,0 +1,205 @@ +#ifndef OT_GLYF_SIMPLEGLYPH_HH +#define OT_GLYF_SIMPLEGLYPH_HH + + +#include "../../hb-open-type.hh" + + +namespace OT { +namespace glyf_impl { + + +struct SimpleGlyph +{ + enum simple_glyph_flag_t + { + FLAG_ON_CURVE = 0x01, + FLAG_X_SHORT = 0x02, + FLAG_Y_SHORT = 0x04, + FLAG_REPEAT = 0x08, + FLAG_X_SAME = 0x10, + FLAG_Y_SAME = 0x20, + FLAG_OVERLAP_SIMPLE = 0x40, + FLAG_RESERVED2 = 0x80 + }; + + const GlyphHeader &header; + hb_bytes_t bytes; + SimpleGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : + header (header_), bytes (bytes_) {} + + unsigned int instruction_len_offset () const + { return GlyphHeader::static_size + 2 * header.numberOfContours; } + + unsigned int length (unsigned int instruction_len) const + { return instruction_len_offset () + 2 + instruction_len; } + + unsigned int instructions_length () const + { + unsigned int instruction_length_offset = instruction_len_offset (); + if (unlikely (instruction_length_offset + 2 > bytes.length)) return 0; + + const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&bytes, instruction_length_offset); + /* Out of bounds of the current glyph */ + if (unlikely (length (instructionLength) > bytes.length)) return 0; + return instructionLength; + } + + const hb_bytes_t trim_padding () const + { + /* based on FontTools _g_l_y_f.py::trim */ + const uint8_t *glyph = (uint8_t*) bytes.arrayZ; + const uint8_t *glyph_end = glyph + bytes.length; + /* simple glyph w/contours, possibly trimmable */ + glyph += instruction_len_offset (); + + if (unlikely (glyph + 2 >= glyph_end)) return hb_bytes_t (); + unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1; + unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0); + + glyph += 2 + num_instructions; + + unsigned int coord_bytes = 0; + unsigned int coords_with_flags = 0; + while (glyph < glyph_end) + { + uint8_t flag = *glyph; + glyph++; + + unsigned int repeat = 1; + if (flag & FLAG_REPEAT) + { + if (unlikely (glyph >= glyph_end)) return hb_bytes_t (); + repeat = *glyph + 1; + glyph++; + } + + unsigned int xBytes, yBytes; + xBytes = yBytes = 0; + if (flag & FLAG_X_SHORT) xBytes = 1; + else if ((flag & FLAG_X_SAME) == 0) xBytes = 2; + + if (flag & FLAG_Y_SHORT) yBytes = 1; + else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2; + + coord_bytes += (xBytes + yBytes) * repeat; + coords_with_flags += repeat; + if (coords_with_flags >= num_coordinates) break; + } + + if (unlikely (coords_with_flags != num_coordinates)) return hb_bytes_t (); + return bytes.sub_array (0, bytes.length + coord_bytes - (glyph_end - glyph)); + } + + /* zero instruction length */ + void drop_hints () + { + GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header); + (HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0; + } + + void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const + { + unsigned int instructions_len = instructions_length (); + unsigned int glyph_length = length (instructions_len); + dest_start = bytes.sub_array (0, glyph_length - instructions_len); + dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length); + } + + void set_overlaps_flag () + { + if (unlikely (!header.numberOfContours)) return; + + unsigned flags_offset = length (instructions_length ()); + if (unlikely (flags_offset + 1 > bytes.length)) return; + + HBUINT8 &first_flag = (HBUINT8 &) StructAtOffset<HBUINT16> (&bytes, flags_offset); + first_flag = (uint8_t) first_flag | FLAG_OVERLAP_SIMPLE; + } + + static bool read_points (const HBUINT8 *&p /* IN/OUT */, + contour_point_vector_t &points_ /* IN/OUT */, + const HBUINT8 *end, + float contour_point_t::*m, + const simple_glyph_flag_t short_flag, + const simple_glyph_flag_t same_flag) + { + float v = 0; + + unsigned count = points_.length; + for (unsigned i = 0; i < count; i++) + { + uint8_t flag = points_[i].flag; + if (flag & short_flag) + { + if (unlikely (p + 1 > end)) return false; + if (flag & same_flag) + v += *p++; + else + v -= *p++; + } + else + { + if (!(flag & same_flag)) + { + if (unlikely (p + HBINT16::static_size > end)) return false; + v += *(const HBINT16 *) p; + p += HBINT16::static_size; + } + } + points_.arrayZ[i].*m = v; + } + return true; + } + + bool get_contour_points (contour_point_vector_t &points_ /* OUT */, + bool phantom_only = false) const + { + const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header); + int num_contours = header.numberOfContours; + if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours - 1]))) return false; + unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; + + points_.alloc (num_points + 4); // Allocate for phantom points, to avoid a possible copy + if (!points_.resize (num_points)) return false; + if (phantom_only) return true; + + for (int i = 0; i < num_contours; i++) + points_[endPtsOfContours[i]].is_end_point = true; + + /* Skip instructions */ + const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1], + endPtsOfContours[num_contours]); + + const HBUINT8 *end = (const HBUINT8 *) (bytes.arrayZ + bytes.length); + + /* Read flags */ + for (unsigned int i = 0; i < num_points;) + { + if (unlikely (p + 1 > end)) return false; + uint8_t flag = *p++; + 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, num_points); + for (; i < stop;) + points_.arrayZ[i++].flag = flag; + } + } + + /* Read x & y coordinates */ + return read_points (p, points_, end, &contour_point_t::x, + FLAG_X_SHORT, FLAG_X_SAME) + && read_points (p, points_, end, &contour_point_t::y, + FLAG_Y_SHORT, FLAG_Y_SAME); + } +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_SIMPLEGLYPH_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh new file mode 100644 index 00000000000..ebe43720475 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh @@ -0,0 +1,72 @@ +#ifndef OT_GLYF_SUBSETGLYPH_HH +#define OT_GLYF_SUBSETGLYPH_HH + + +#include "../../hb-open-type.hh" + + +namespace OT { +namespace glyf_impl { + + +struct SubsetGlyph +{ + hb_codepoint_t new_gid; + hb_codepoint_t old_gid; + Glyph source_glyph; + hb_bytes_t dest_start; /* region of source_glyph to copy first */ + hb_bytes_t dest_end; /* region of source_glyph to copy second */ + + bool serialize (hb_serialize_context_t *c, + bool use_short_loca, + const hb_subset_plan_t *plan) const + { + TRACE_SERIALIZE (this); + + hb_bytes_t dest_glyph = dest_start.copy (c); + dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); + unsigned int pad_length = use_short_loca ? padding () : 0; + DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); + + HBUINT8 pad; + pad = 0; + while (pad_length > 0) + { + c->embed (pad); + pad_length--; + } + + if (unlikely (!dest_glyph.length)) return_trace (true); + + /* update components gids */ + for (auto &_ : Glyph (dest_glyph).get_composite_iterator ()) + { + hb_codepoint_t new_gid; + if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid)) + const_cast<CompositeGlyphRecord &> (_).glyphIndex = new_gid; + } + + if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + Glyph (dest_glyph).drop_hints (); + + if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG) + Glyph (dest_glyph).set_overlaps_flag (); + + return_trace (true); + } + + void drop_hints_bytes () + { source_glyph.drop_hints_bytes (dest_start, dest_end); } + + unsigned int length () const { return dest_start.length + dest_end.length; } + /* pad to 2 to ensure 2-byte loca will be ok */ + unsigned int padding () const { return length () % 2; } + unsigned int padded_size () const { return length () + padding (); } +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_SUBSETGLYPH_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh new file mode 100644 index 00000000000..f51f7a81fcc --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh @@ -0,0 +1,90 @@ +#ifndef OT_GLYF_GLYF_HELPERS_HH +#define OT_GLYF_GLYF_HELPERS_HH + + +#include "../../hb-open-type.hh" +#include "../../hb-subset-plan.hh" + +#include "loca.hh" + + +namespace OT { +namespace glyf_impl { + + +template<typename IteratorIn, typename IteratorOut, + hb_requires (hb_is_source_of (IteratorIn, unsigned int)), + hb_requires (hb_is_sink_of (IteratorOut, unsigned))> +static void +_write_loca (IteratorIn it, bool short_offsets, IteratorOut dest) +{ + unsigned right_shift = short_offsets ? 1 : 0; + unsigned int offset = 0; + dest << 0; + + it + | hb_map ([=, &offset] (unsigned int padded_size) + { + offset += padded_size; + DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset); + return offset >> right_shift; + }) + | hb_sink (dest) + ; +} + +static bool +_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca) +{ + hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source); + hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob); + hb_blob_destroy (head_blob); + + if (unlikely (!head_prime_blob)) + return false; + + head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr); + head_prime->indexToLocFormat = use_short_loca ? 0 : 1; + bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob); + + hb_blob_destroy (head_prime_blob); + return success; +} + +template<typename Iterator, + hb_requires (hb_is_source_of (Iterator, unsigned int))> +static bool +_add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca) +{ + unsigned num_offsets = padded_offsets.len () + 1; + unsigned entry_size = use_short_loca ? 2 : 4; + char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets); + + if (unlikely (!loca_prime_data)) return false; + + DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d", + entry_size, num_offsets, entry_size * num_offsets); + + if (use_short_loca) + _write_loca (padded_offsets, true, hb_array ((HBUINT16 *) loca_prime_data, num_offsets)); + else + _write_loca (padded_offsets, false, hb_array ((HBUINT32 *) loca_prime_data, num_offsets)); + + hb_blob_t *loca_blob = hb_blob_create (loca_prime_data, + entry_size * num_offsets, + HB_MEMORY_MODE_WRITABLE, + loca_prime_data, + hb_free); + + bool result = plan->add_table (HB_OT_TAG_loca, loca_blob) + && _add_head_and_set_loca_version (plan, use_short_loca); + + hb_blob_destroy (loca_blob); + return result; +} + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_GLYF_HELPERS_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh new file mode 100644 index 00000000000..f74513cb968 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh @@ -0,0 +1,388 @@ +#ifndef OT_GLYF_GLYF_HH +#define OT_GLYF_GLYF_HH + + +#include "../../hb-open-type.hh" +#include "../../hb-ot-head-table.hh" +#include "../../hb-ot-hmtx-table.hh" +#include "../../hb-ot-var-gvar-table.hh" +#include "../../hb-draw.hh" + +#include "glyf-helpers.hh" +#include "Glyph.hh" +#include "SubsetGlyph.hh" +#include "loca.hh" +#include "path-builder.hh" + + +namespace OT { + + +/* + * glyf -- TrueType Glyph Data + * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf + */ +#define HB_OT_TAG_glyf HB_TAG('g','l','y','f') + + +struct glyf +{ + friend struct glyf_accelerator_t; + + static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf; + + bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const + { + TRACE_SANITIZE (this); + /* Runtime checks as eager sanitizing each glyph is costy */ + return_trace (true); + } + + /* requires source of SubsetGlyph complains the identifier isn't declared */ + template <typename Iterator> + bool serialize (hb_serialize_context_t *c, + Iterator it, + bool use_short_loca, + const hb_subset_plan_t *plan) + { + TRACE_SERIALIZE (this); + unsigned init_len = c->length (); + for (const auto &_ : it) _.serialize (c, use_short_loca, plan); + + /* As a special case when all glyph in the font are empty, add a zero byte + * to the table, so that OTS doesn’t reject it, and to make the table work + * on Windows as well. + * See https://github.com/khaledhosny/ots/issues/52 */ + if (init_len == c->length ()) + { + HBUINT8 empty_byte; + empty_byte = 0; + c->copy (empty_byte); + } + return_trace (true); + } + + /* Byte region(s) per glyph to output + unpadded, hints removed if so requested + If we fail to process a glyph we produce an empty (0-length) glyph */ + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + + glyf *glyf_prime = c->serializer->start_embed <glyf> (); + if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false); + + hb_vector_t<glyf_impl::SubsetGlyph> glyphs; + _populate_subset_glyphs (c->plan, &glyphs); + + auto padded_offsets = + + hb_iter (glyphs) + | hb_map (&glyf_impl::SubsetGlyph::padded_size) + ; + + unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0); + bool use_short_loca = max_offset < 0x1FFFF; + + + glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan); + if (!use_short_loca) { + padded_offsets = + + hb_iter (glyphs) + | hb_map (&glyf_impl::SubsetGlyph::length) + ; + } + + + if (unlikely (c->serializer->in_error ())) return_trace (false); + return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan, + padded_offsets, + use_short_loca))); + } + + void + _populate_subset_glyphs (const hb_subset_plan_t *plan, + hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const; + + protected: + UnsizedArrayOf<HBUINT8> + dataZ; /* Glyphs data. */ + public: + DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always + * check the size externally, allow Null() object of it by + * defining it _MIN instead. */ +}; + +struct glyf_accelerator_t +{ + glyf_accelerator_t (hb_face_t *face) + { + short_offset = false; + num_glyphs = 0; + loca_table = nullptr; + glyf_table = nullptr; +#ifndef HB_NO_VAR + gvar = nullptr; +#endif + hmtx = nullptr; +#ifndef HB_NO_VERTICAL + vmtx = nullptr; +#endif + const OT::head &head = *face->table.head; + if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0) + /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + return; + short_offset = 0 == head.indexToLocFormat; + + loca_table = face->table.loca.get_blob (); // Needs no destruct! + glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face); +#ifndef HB_NO_VAR + gvar = face->table.gvar; +#endif + hmtx = face->table.hmtx; +#ifndef HB_NO_VERTICAL + vmtx = face->table.vmtx; +#endif + + num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1; + num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ()); + } + ~glyf_accelerator_t () + { + glyf_table.destroy (); + } + + bool has_data () const { return num_glyphs; } + + protected: + template<typename T> + bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) 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; + + bool phantom_only = !consumer.is_consuming_contour_points (); + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, phantom_only))) + return false; + + if (consumer.is_consuming_contour_points ()) + { + unsigned count = all_points.length; + assert (count >= glyf_impl::PHANTOM_COUNT); + count -= glyf_impl::PHANTOM_COUNT; + for (unsigned point_index = 0; point_index < count; point_index++) + consumer.consume_point (all_points[point_index]); + consumer.points_end (); + } + + /* Where to write phantoms, nullptr if not requested */ + contour_point_t *phantoms = consumer.get_phantoms_sink (); + if (phantoms) + for (unsigned i = 0; i < glyf_impl::PHANTOM_COUNT; ++i) + phantoms[i] = all_points[all_points.length - glyf_impl::PHANTOM_COUNT + i]; + + return true; + } + +#ifndef HB_NO_VAR + struct points_aggregator_t + { + hb_font_t *font; + hb_glyph_extents_t *extents; + contour_point_t *phantoms; + + struct contour_bounds_t + { + contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; } + + void add (const contour_point_t &p) + { + min_x = hb_min (min_x, p.x); + min_y = hb_min (min_y, p.y); + max_x = hb_max (max_x, p.x); + max_y = hb_max (max_y, p.y); + } + + bool empty () const { return (min_x >= max_x) || (min_y >= max_y); } + + void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) + { + if (unlikely (empty ())) + { + extents->width = 0; + extents->x_bearing = 0; + extents->height = 0; + extents->y_bearing = 0; + return; + } + extents->x_bearing = font->em_scalef_x (min_x); + extents->width = font->em_scalef_x (max_x) - extents->x_bearing; + extents->y_bearing = font->em_scalef_y (max_y); + extents->height = font->em_scalef_y (min_y) - extents->y_bearing; + } + + protected: + float min_x, min_y, max_x, max_y; + } bounds; + + points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_) + { + font = font_; + extents = extents_; + phantoms = phantoms_; + if (extents) bounds = contour_bounds_t (); + } + + void consume_point (const contour_point_t &point) { bounds.add (point); } + void points_end () { bounds.get_extents (font, extents); } + + bool is_consuming_contour_points () { return extents; } + contour_point_t *get_phantoms_sink () { return phantoms; } + }; + + public: + unsigned + get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + { + if (unlikely (gid >= num_glyphs)) return 0; + + bool success = false; + + contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; + if (likely (font->num_coords == gvar->get_axis_count ())) + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms)); + + if (unlikely (!success)) + return +#ifndef HB_NO_VERTICAL + is_vertical ? vmtx->get_advance (gid) : +#endif + hmtx->get_advance (gid); + + float result = is_vertical + ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y + : phantoms[glyf_impl::PHANTOM_RIGHT].x - phantoms[glyf_impl::PHANTOM_LEFT].x; + return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); + } + + int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + { + if (unlikely (gid >= num_glyphs)) return 0; + + hb_glyph_extents_t extents; + + contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; + if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms)))) + return +#ifndef HB_NO_VERTICAL + is_vertical ? vmtx->get_side_bearing (gid) : +#endif + hmtx->get_side_bearing (gid); + + return is_vertical + ? ceilf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing + : floorf (phantoms[glyf_impl::PHANTOM_LEFT].x); + } +#endif + + public: + bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const + { + if (unlikely (gid >= num_glyphs)) return false; + +#ifndef HB_NO_VAR + if (font->num_coords) + return get_points (font, gid, points_aggregator_t (font, extents, nullptr)); +#endif + return glyph_for_gid (gid).get_extents (font, *this, extents); + } + + const glyf_impl::Glyph + glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const + { + if (unlikely (gid >= num_glyphs)) return glyf_impl::Glyph (); + + unsigned int start_offset, end_offset; + + if (short_offset) + { + const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ; + start_offset = 2 * offsets[gid]; + end_offset = 2 * offsets[gid + 1]; + } + else + { + const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ; + start_offset = offsets[gid]; + end_offset = offsets[gid + 1]; + } + + if (unlikely (start_offset > end_offset || end_offset > glyf_table.get_length ())) + return glyf_impl::Glyph (); + + glyf_impl::Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset, + end_offset - start_offset), gid); + return needs_padding_removal ? glyf_impl::Glyph (glyph.trim_padding (), gid) : glyph; + } + + 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)); } + +#ifndef HB_NO_VAR + const gvar_accelerator_t *gvar; +#endif + const hmtx_accelerator_t *hmtx; +#ifndef HB_NO_VERTICAL + const vmtx_accelerator_t *vmtx; +#endif + + private: + bool short_offset; + unsigned int num_glyphs; + hb_blob_ptr_t<loca> loca_table; + hb_blob_ptr_t<glyf> glyf_table; +}; + + +inline void +glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, + hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const +{ + OT::glyf_accelerator_t glyf (plan->source); + + + hb_range (plan->num_output_glyphs ()) + | hb_map ([&] (hb_codepoint_t new_gid) + { + glyf_impl::SubsetGlyph subset_glyph = {0}; + subset_glyph.new_gid = new_gid; + + /* should never fail: all old gids should be mapped */ + if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) + return subset_glyph; + + if (new_gid == 0 && + !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + subset_glyph.source_glyph = glyf_impl::Glyph (); + else + subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true); + if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + subset_glyph.drop_hints_bytes (); + else + subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes (); + return subset_glyph; + }) + | hb_sink (glyphs) + ; +} + + + +} /* namespace OT */ + + +#endif /* OT_GLYF_GLYF_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/loca.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/loca.hh new file mode 100644 index 00000000000..4481cba8ed2 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/loca.hh @@ -0,0 +1,43 @@ +#ifndef OT_GLYF_LOCA_HH +#define OT_GLYF_LOCA_HH + + +#include "../../hb-open-type.hh" + + +namespace OT { + + +/* + * loca -- Index to Location + * https://docs.microsoft.com/en-us/typography/opentype/spec/loca + */ +#define HB_OT_TAG_loca HB_TAG('l','o','c','a') + +struct loca +{ + friend struct glyf; + friend struct glyf_accelerator_t; + + static constexpr hb_tag_t tableTag = HB_OT_TAG_loca; + + bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const + { + TRACE_SANITIZE (this); + return_trace (true); + } + + protected: + UnsizedArrayOf<HBUINT8> + dataZ; /* Location data. */ + public: + DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always + * check the size externally, allow Null() object of it by + * defining it _MIN instead. */ +}; + + +} /* namespace OT */ + + +#endif /* OT_GLYF_LOCA_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh new file mode 100644 index 00000000000..9bfc45a1a60 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh @@ -0,0 +1,135 @@ +#ifndef OT_GLYF_PATH_BUILDER_HH +#define OT_GLYF_PATH_BUILDER_HH + + +#include "../../hb.hh" + + +namespace OT { +namespace glyf_impl { + + +struct path_builder_t +{ + hb_font_t *font; + hb_draw_session_t *draw_session; + + struct optional_point_t + { + optional_point_t () {} + optional_point_t (float x_, float y_) : has_data (true), x (x_), y (y_) {} + operator bool () const { return has_data; } + + bool has_data = false; + float x = 0.; + float y = 0.; + + optional_point_t lerp (optional_point_t p, float t) + { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); } + } first_oncurve, first_offcurve, last_offcurve; + + path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_) + { + font = font_; + draw_session = &draw_session_; + first_oncurve = first_offcurve = last_offcurve = optional_point_t (); + } + + /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287 + See also: + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html + * https://stackoverflow.com/a/20772557 */ + void consume_point (const contour_point_t &point) + { + bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE; + optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y)); + if (!first_oncurve) + { + if (is_on_curve) + { + first_oncurve = p; + draw_session->move_to (p.x, p.y); + } + else + { + if (first_offcurve) + { + optional_point_t mid = first_offcurve.lerp (p, .5f); + first_oncurve = mid; + last_offcurve = p; + draw_session->move_to (mid.x, mid.y); + } + else + first_offcurve = p; + } + } + else + { + if (last_offcurve) + { + if (is_on_curve) + { + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + p.x, p.y); + last_offcurve = optional_point_t (); + } + else + { + optional_point_t mid = last_offcurve.lerp (p, .5f); + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + last_offcurve = p; + } + } + else + { + if (is_on_curve) + draw_session->line_to (p.x, p.y); + else + last_offcurve = p; + } + } + + if (point.is_end_point) + { + if (first_offcurve && last_offcurve) + { + optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f); + 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) + draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); + else if (last_offcurve && first_oncurve) + 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 = optional_point_t (); + draw_session->close_path (); + } + } + void points_end () {} + + bool is_consuming_contour_points () { return true; } + contour_point_t *get_phantoms_sink () { return nullptr; } +}; + + +} /* namespace glyf_impl */ +} /* namespace OT */ + + +#endif /* OT_GLYF_PATH_BUILDER_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-c-linkage-decls.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-c-linkage-decls.py index 49cd29628c6..fe18eda897f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-c-linkage-decls.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-c-linkage-decls.py @@ -2,18 +2,20 @@ import sys, os -os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) +srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) +base_srcdir = os.getenv ('base_srcdir', srcdir) + +os.chdir (srcdir) + +def removeprefix(s): + abs_path = os.path.join(base_srcdir, s) + return os.path.relpath(abs_path, srcdir) -def removeprefix(s, prefix): - if s.startswith(prefix): - return s[len(prefix):] - else: - return s[:] HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] HBSOURCES = [ - removeprefix(x, 'src%s' % os.path.sep) for x in os.getenv ('HBSOURCES', '').split () + removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () ] or [ x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) ] diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-header-guards.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-header-guards.py index b45ffe1addd..35ae6bef625 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-header-guards.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-header-guards.py @@ -2,19 +2,20 @@ import sys, os, re -os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) +srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) +base_srcdir = os.getenv ('base_srcdir', srcdir) -def removeprefix(s, prefix): - if s.startswith(prefix): - return s[len(prefix):] - else: - return s[:] +os.chdir (srcdir) + +def removeprefix(s): + abs_path = os.path.join(base_srcdir, s) + return os.path.relpath(abs_path, srcdir) HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] HBSOURCES = [ - removeprefix(x, 'src%s' % os.path.sep) for x in os.getenv ('HBSOURCES', '').split () + removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () ] or [ x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) ] diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-includes.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-includes.py index ed201aa3e0a..fc95874b12b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-includes.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-includes.py @@ -2,19 +2,20 @@ import sys, os, re -os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) +srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) +base_srcdir = os.getenv ('base_srcdir', srcdir) -def removeprefix(s, prefix): - if s.startswith(prefix): - return s[len(prefix):] - else: - return s[:] +os.chdir (srcdir) + +def removeprefix(s): + abs_path = os.path.join(base_srcdir, s) + return os.path.relpath(abs_path, srcdir) HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] HBSOURCES = [ - removeprefix(x, 'src%s' % os.path.sep) for x in os.getenv ('HBSOURCES', '').split () + removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () ] or [ x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) ] diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py index 385959bdef7..11ca28dc7f4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py @@ -17,7 +17,7 @@ if not nm: print ('check-symbols.py: \'nm\' not found; skipping test') sys.exit (77) -cxxflit = shutil.which ('c++filt') +cxxfilt = shutil.which ('c++filt') tested = False stat = 0 @@ -34,10 +34,10 @@ for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-icu', 'harfbuzz-gobject' for s in re.findall (r'^.+ [BCDGIRST] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE) if not re.match (r'.* %s(%s)\b' % (symprefix, IGNORED_SYMBOLS), s)] - # run again c++flit also if is available - if cxxflit: + # run again c++filt also if is available + if cxxfilt: EXPORTED_SYMBOLS = subprocess.check_output ( - [cxxflit], input='\n'.join (EXPORTED_SYMBOLS).encode () + [cxxfilt], input='\n'.join (EXPORTED_SYMBOLS).encode () ).decode ('utf-8').splitlines () prefix = (symprefix + os.path.basename (so)).replace ('libharfbuzz', 'hb').replace ('-', '_').split ('.')[0] diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-joining-list.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-joining-list.py index 8162a4a3e26..7ec7425fd8c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-joining-list.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-joining-list.py @@ -94,13 +94,13 @@ for h in headers: print (" * %s" % (l.strip ())) print (" */") print () -print ("#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH") -print ("#define HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH") +print ("#ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH") +print ("#define HB_OT_SHAPER_ARABIC_JOINING_LIST_HH") print () print_has_arabic_joining (read (files[1]), read_joining_uu (files[0])) print () -print ("#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH */") +print ("#endif /* HB_OT_SHAPER_ARABIC_JOINING_LIST_HH */") print () print ("/* == End of generated function == */") diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py index 621d5b60c89..8278d7d69c0 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py @@ -153,12 +153,29 @@ def print_joining_table(f): print ("#undef %s" % (short)) print () +LIGATURES = ( + 0xF2EE, 0xFC08, 0xFC0E, 0xFC12, 0xFC32, 0xFC3F, 0xFC40, 0xFC41, 0xFC42, + 0xFC44, 0xFC4E, 0xFC5E, 0xFC60, 0xFC61, 0xFC62, 0xFC6A, 0xFC6D, 0xFC6F, + 0xFC70, 0xFC73, 0xFC75, 0xFC86, 0xFC8F, 0xFC91, 0xFC94, 0xFC9C, 0xFC9D, + 0xFC9E, 0xFC9F, 0xFCA1, 0xFCA2, 0xFCA3, 0xFCA4, 0xFCA8, 0xFCAA, 0xFCAC, + 0xFCB0, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE, 0xFCCF, 0xFCD0, + 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD5, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFD30, + 0xFD88, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, + 0xF201, 0xF211, 0xF2EE, +) + def print_shaping_table(f): shapes = {} ligatures = {} names = {} - for line in f: + lines = f.readlines() + lines += [ + "F201;PUA ARABIC LIGATURE LELLAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 0644 0647;;;;N;;;;;", + "F211;PUA ARABIC LIGATURE LAM WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 0645 062C;;;;N;;;;;", + "F2EE;PUA ARABIC LIGATURE SHADDA WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064B 0651;;;;N;;;;;", + ] + for line in lines: fields = [x.strip () for x in line.split (';')] if fields[5][0:1] != '<': @@ -166,14 +183,19 @@ def print_shaping_table(f): items = fields[5].split (' ') shape, items = items[0][1:-1], tuple (int (x, 16) for x in items[1:]) + c = int (fields[0], 16) if not shape in ['initial', 'medial', 'isolated', 'final']: continue - c = int (fields[0], 16) if len (items) != 1: - # We only care about lam-alef ligatures - if len (items) != 2 or items[0] != 0x0644 or items[1] not in [0x0622, 0x0623, 0x0625, 0x0627]: + # Mark ligatures start with space and are in visual order, so we + # remove the space and reverse the items. + if items[0] == 0x0020: + items = items[:0:-1] + shape = None + # We only care about a subset of ligatures + if c not in LIGATURES: continue # Save ligature @@ -209,34 +231,99 @@ def print_shaping_table(f): print ("#define SHAPING_TABLE_LAST 0x%04Xu" % max_u) print () - ligas = {} - for pair in ligatures.keys (): - for shape in ligatures[pair]: - c = ligatures[pair][shape] - if shape == 'isolated': - liga = (shapes[pair[0]]['initial'], shapes[pair[1]]['final']) - elif shape == 'final': - liga = (shapes[pair[0]]['medial'], shapes[pair[1]]['final']) + ligas_2 = {} + ligas_3 = {} + ligas_mark_2 = {} + for key in ligatures.keys (): + for shape in ligatures[key]: + c = ligatures[key][shape] + if len(key) == 3: + if shape == 'isolated': + liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial'], shapes[key[2]]['final']) + elif shape == 'final': + liga = (shapes[key[0]]['medial'], shapes[key[1]]['medial'], shapes[key[2]]['final']) + elif shape == 'initial': + liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial'], shapes[key[2]]['medial']) + else: + raise Exception ("Unexpected shape", shape) + if liga[0] not in ligas_3: + ligas_3[liga[0]] = [] + ligas_3[liga[0]].append ((liga[1], liga[2], c)) + elif len(key) == 2: + if shape is None: + liga = key + if liga[0] not in ligas_mark_2: + ligas_mark_2[liga[0]] = [] + ligas_mark_2[liga[0]].append ((liga[1], c)) + continue + elif shape == 'isolated': + liga = (shapes[key[0]]['initial'], shapes[key[1]]['final']) + elif shape == 'final': + liga = (shapes[key[0]]['medial'], shapes[key[1]]['final']) + elif shape == 'initial': + liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial']) + else: + raise Exception ("Unexpected shape", shape) + if liga[0] not in ligas_2: + ligas_2[liga[0]] = [] + ligas_2[liga[0]].append ((liga[1], c)) else: - raise Exception ("Unexpected shape", shape) - if liga[0] not in ligas: - ligas[liga[0]] = [] - ligas[liga[0]].append ((liga[1], c)) - max_i = max (len (ligas[l]) for l in ligas) + raise Exception ("Unexpected number of ligature components", key) + max_i = max (len (ligas_2[l]) for l in ligas_2) print () print ("static const struct ligature_set_t {") print (" uint16_t first;") print (" struct ligature_pairs_t {") - print (" uint16_t second;") + print (" uint16_t components[1];") print (" uint16_t ligature;") print (" } ligatures[%d];" % max_i) print ("} ligature_table[] =") print ("{") - for first in sorted (ligas.keys ()): + for first in sorted (ligas_2.keys ()): + + print (" { 0x%04Xu, {" % (first)) + for liga in ligas_2[first]: + print (" { {0x%04Xu}, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])) + print (" }},") + + print ("};") + print () + + max_i = max (len (ligas_mark_2[l]) for l in ligas_mark_2) + print () + print ("static const struct ligature_mark_set_t {") + print (" uint16_t first;") + print (" struct ligature_pairs_t {") + print (" uint16_t components[1];") + print (" uint16_t ligature;") + print (" } ligatures[%d];" % max_i) + print ("} ligature_mark_table[] =") + print ("{") + for first in sorted (ligas_mark_2.keys ()): + + print (" { 0x%04Xu, {" % (first)) + for liga in ligas_mark_2[first]: + print (" { {0x%04Xu}, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])) + print (" }},") + + print ("};") + print () + + max_i = max (len (ligas_3[l]) for l in ligas_3) + print () + print ("static const struct ligature_3_set_t {") + print (" uint16_t first;") + print (" struct ligature_triplets_t {") + print (" uint16_t components[2];") + print (" uint16_t ligature;") + print (" } ligatures[%d];" % max_i) + print ("} ligature_3_table[] =") + print ("{") + for first in sorted (ligas_3.keys ()): print (" { 0x%04Xu, {" % (first)) - for liga in ligas[first]: - print (" { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])) + for liga in ligas_3[first]: + print (" { {0x%04Xu, 0x%04Xu}, 0x%04Xu}, /* %s */" % (liga[0], liga[1], liga[2], names[liga[2]])) print (" }},") print ("};") @@ -257,8 +344,8 @@ for h in headers: print (" * %s" % (l.strip())) print (" */") print () -print ("#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH") -print ("#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH") +print ("#ifndef HB_OT_SHAPER_ARABIC_TABLE_HH") +print ("#define HB_OT_SHAPER_ARABIC_TABLE_HH") print () read_blocks (files[2]) @@ -266,6 +353,6 @@ print_joining_table (files[0]) print_shaping_table (files[1]) print () -print ("#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */") +print ("#endif /* HB_OT_SHAPER_ARABIC_TABLE_HH */") print () print ("/* == End of generated table == */") diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py index 367e55e2723..a2004e4fc41 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py @@ -26,7 +26,6 @@ ALLOWED_BLOCKS = [ 'Telugu', 'Kannada', 'Malayalam', - 'Sinhala', 'Myanmar', 'Khmer', 'Vedic Extensions', @@ -41,8 +40,7 @@ files = [open (x, encoding='utf-8') for x in sys.argv[1:]] headers = [[f.readline () for i in range (2)] for f in files] -data = [{} for _ in files] -values = [{} for _ in files] +unicode_data = [{} for _ in files] for i, f in enumerate (files): for line in f: @@ -64,15 +62,12 @@ for i, f in enumerate (files): t = fields[1] for u in range (start, end + 1): - data[i][u] = t - values[i][t] = values[i].get (t, 0) + end - start + 1 + unicode_data[i][u] = t # Merge data into one dict: defaults = ('Other', 'Not_Applicable', 'No_Block') -for i,v in enumerate (defaults): - values[i][v] = values[i].get (v, 0) + 1 combined = {} -for i,d in enumerate (data): +for i,d in enumerate (unicode_data): for u,v in d.items (): if i == 2 and not u in combined: continue @@ -80,14 +75,412 @@ for i,d in enumerate (data): combined[u] = list (defaults) combined[u][i] = v combined = {k:v for k,v in combined.items() if k in ALLOWED_SINGLES or v[2] in ALLOWED_BLOCKS} -data = combined -del combined + + +# Convert categories & positions types + +categories = { + 'indic' : [ + 'X', + 'C', + 'V', + 'N', + 'H', + 'ZWNJ', + 'ZWJ', + 'M', + 'SM', + 'A', + 'VD', + 'PLACEHOLDER', + 'DOTTEDCIRCLE', + 'RS', + 'Repha', + 'Ra', + 'CM', + 'Symbol', + 'CS', + ], + 'khmer' : [ + 'VAbv', + 'VBlw', + 'VPre', + 'VPst', + + 'Robatic', + 'Xgroup', + 'Ygroup', + ], + 'myanmar' : [ + 'VAbv', + 'VBlw', + 'VPre', + 'VPst', + + 'IV', + 'As', + 'DB', + 'GB', + 'MH', + 'MR', + 'MW', + 'MY', + 'PT', + 'VS', + 'ML', + ], +} + +category_map = { + 'Other' : 'X', + 'Avagraha' : 'Symbol', + 'Bindu' : 'SM', + 'Brahmi_Joining_Number' : 'PLACEHOLDER', # Don't care. + 'Cantillation_Mark' : 'A', + 'Consonant' : 'C', + 'Consonant_Dead' : 'C', + 'Consonant_Final' : 'CM', + 'Consonant_Head_Letter' : 'C', + 'Consonant_Initial_Postfixed' : 'C', # TODO + 'Consonant_Killer' : 'M', # U+17CD only. + 'Consonant_Medial' : 'CM', + 'Consonant_Placeholder' : 'PLACEHOLDER', + 'Consonant_Preceding_Repha' : 'Repha', + 'Consonant_Prefixed' : 'X', # Don't care. + 'Consonant_Subjoined' : 'CM', + 'Consonant_Succeeding_Repha' : 'CM', + 'Consonant_With_Stacker' : 'CS', + 'Gemination_Mark' : 'SM', # https://github.com/harfbuzz/harfbuzz/issues/552 + 'Invisible_Stacker' : 'H', + 'Joiner' : 'ZWJ', + 'Modifying_Letter' : 'X', + 'Non_Joiner' : 'ZWNJ', + 'Nukta' : 'N', + 'Number' : 'PLACEHOLDER', + 'Number_Joiner' : 'PLACEHOLDER', # Don't care. + 'Pure_Killer' : 'M', # Is like a vowel matra. + 'Register_Shifter' : 'RS', + 'Syllable_Modifier' : 'SM', + 'Tone_Letter' : 'X', + 'Tone_Mark' : 'N', + 'Virama' : 'H', + 'Visarga' : 'SM', + 'Vowel' : 'V', + 'Vowel_Dependent' : 'M', + 'Vowel_Independent' : 'V', + 'Dotted_Circle' : 'DOTTEDCIRCLE', # Ours, not Unicode's + 'Ra' : 'Ra', # Ours, not Unicode's +} +position_map = { + 'Not_Applicable' : 'END', + + 'Left' : 'PRE_C', + 'Top' : 'ABOVE_C', + 'Bottom' : 'BELOW_C', + 'Right' : 'POST_C', + + # These should resolve to the position of the last part of the split sequence. + 'Bottom_And_Right' : 'POST_C', + 'Left_And_Right' : 'POST_C', + 'Top_And_Bottom' : 'BELOW_C', + 'Top_And_Bottom_And_Left' : 'BELOW_C', + 'Top_And_Bottom_And_Right' : 'POST_C', + 'Top_And_Left' : 'ABOVE_C', + 'Top_And_Left_And_Right' : 'POST_C', + 'Top_And_Right' : 'POST_C', + + 'Overstruck' : 'AFTER_MAIN', + 'Visual_order_left' : 'PRE_M', +} + +category_overrides = { + + # These are the variation-selectors. They only appear in the Myanmar grammar + # but are not Myanmar-specific + 0xFE00: 'VS', + 0xFE01: 'VS', + 0xFE02: 'VS', + 0xFE03: 'VS', + 0xFE04: 'VS', + 0xFE05: 'VS', + 0xFE06: 'VS', + 0xFE07: 'VS', + 0xFE08: 'VS', + 0xFE09: 'VS', + 0xFE0A: 'VS', + 0xFE0B: 'VS', + 0xFE0C: 'VS', + 0xFE0D: 'VS', + 0xFE0E: 'VS', + 0xFE0F: 'VS', + + # These appear in the OT Myanmar spec, but are not Myanmar-specific + 0x2015: 'PLACEHOLDER', + 0x2022: 'PLACEHOLDER', + 0x25FB: 'PLACEHOLDER', + 0x25FC: 'PLACEHOLDER', + 0x25FD: 'PLACEHOLDER', + 0x25FE: 'PLACEHOLDER', + + + # Indic + + 0x0930: 'Ra', # Devanagari + 0x09B0: 'Ra', # Bengali + 0x09F0: 'Ra', # Bengali + 0x0A30: 'Ra', # Gurmukhi No Reph + 0x0AB0: 'Ra', # Gujarati + 0x0B30: 'Ra', # Oriya + 0x0BB0: 'Ra', # Tamil No Reph + 0x0C30: 'Ra', # Telugu Reph formed only with ZWJ + 0x0CB0: 'Ra', # Kannada + 0x0D30: 'Ra', # Malayalam No Reph, Logical Repha + + # The following act more like the Bindus. + 0x0953: 'SM', + 0x0954: 'SM', + + # The following act like consonants. + 0x0A72: 'C', + 0x0A73: 'C', + 0x1CF5: 'C', + 0x1CF6: 'C', + + # TODO: The following should only be allowed after a Visarga. + # For now, just treat them like regular tone marks. + 0x1CE2: 'A', + 0x1CE3: 'A', + 0x1CE4: 'A', + 0x1CE5: 'A', + 0x1CE6: 'A', + 0x1CE7: 'A', + 0x1CE8: 'A', + + # TODO: The following should only be allowed after some of + # the nasalization marks, maybe only for U+1CE9..U+1CF1. + # For now, just treat them like tone marks. + 0x1CED: 'A', + + # The following take marks in standalone clusters, similar to Avagraha. + 0xA8F2: 'Symbol', + 0xA8F3: 'Symbol', + 0xA8F4: 'Symbol', + 0xA8F5: 'Symbol', + 0xA8F6: 'Symbol', + 0xA8F7: 'Symbol', + 0x1CE9: 'Symbol', + 0x1CEA: 'Symbol', + 0x1CEB: 'Symbol', + 0x1CEC: 'Symbol', + 0x1CEE: 'Symbol', + 0x1CEF: 'Symbol', + 0x1CF0: 'Symbol', + 0x1CF1: 'Symbol', + + 0x0A51: 'M', # https://github.com/harfbuzz/harfbuzz/issues/524 + + # According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil, + # so the Indic shaper needs to know their categories. + 0x11301: 'SM', + 0x11302: 'SM', + 0x11303: 'SM', + 0x1133B: 'N', + 0x1133C: 'N', + + 0x0AFB: 'N', # https://github.com/harfbuzz/harfbuzz/issues/552 + 0x0B55: 'N', # https://github.com/harfbuzz/harfbuzz/issues/2849 + + 0x09FC: 'PLACEHOLDER', # https://github.com/harfbuzz/harfbuzz/pull/1613 + 0x0C80: 'PLACEHOLDER', # https://github.com/harfbuzz/harfbuzz/pull/623 + 0x0D04: 'PLACEHOLDER', # https://github.com/harfbuzz/harfbuzz/pull/3511 + + 0x25CC: 'DOTTEDCIRCLE', + + + # Khmer + + 0x179A: 'Ra', + + 0x17CC: 'Robatic', + 0x17C9: 'Robatic', + 0x17CA: 'Robatic', + + 0x17C6: 'Xgroup', + 0x17CB: 'Xgroup', + 0x17CD: 'Xgroup', + 0x17CE: 'Xgroup', + 0x17CF: 'Xgroup', + 0x17D0: 'Xgroup', + 0x17D1: 'Xgroup', + + 0x17C7: 'Ygroup', + 0x17C8: 'Ygroup', + 0x17DD: 'Ygroup', + 0x17D3: 'Ygroup', # Just guessing. Uniscribe doesn't categorize it. + + 0x17D9: 'PLACEHOLDER', # https://github.com/harfbuzz/harfbuzz/issues/2384 + + + # Myanmar + + # https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze + + 0x104E: 'C', # The spec says C, IndicSyllableCategory says Consonant_Placeholder + + 0x1004: 'Ra', + 0x101B: 'Ra', + 0x105A: 'Ra', + + 0x1032: 'A', + 0x1036: 'A', + + 0x103A: 'As', + + #0x1040: 'D0', # XXX The spec says D0, but Uniscribe doesn't seem to do. + + 0x103E: 'MH', + 0x1060: 'ML', + 0x103C: 'MR', + 0x103D: 'MW', + 0x1082: 'MW', + 0x103B: 'MY', + 0x105E: 'MY', + 0x105F: 'MY', + + 0x1063: 'PT', + 0x1064: 'PT', + 0x1069: 'PT', + 0x106A: 'PT', + 0x106B: 'PT', + 0x106C: 'PT', + 0x106D: 'PT', + 0xAA7B: 'PT', + + 0x1038: 'SM', + 0x1087: 'SM', + 0x1088: 'SM', + 0x1089: 'SM', + 0x108A: 'SM', + 0x108B: 'SM', + 0x108C: 'SM', + 0x108D: 'SM', + 0x108F: 'SM', + 0x109A: 'SM', + 0x109B: 'SM', + 0x109C: 'SM', + + 0x104A: 'PLACEHOLDER', +} +position_overrides = { + + 0x0A51: 'BELOW_C', # https://github.com/harfbuzz/harfbuzz/issues/524 + + 0x0B01: 'BEFORE_SUB', # Oriya Bindu is BeforeSub in the spec. +} + +def matra_pos_left(u, block): + return "PRE_M" +def matra_pos_right(u, block): + if block == 'Devanagari': return 'AFTER_SUB' + if block == 'Bengali': return 'AFTER_POST' + if block == 'Gurmukhi': return 'AFTER_POST' + if block == 'Gujarati': return 'AFTER_POST' + if block == 'Oriya': return 'AFTER_POST' + if block == 'Tamil': return 'AFTER_POST' + if block == 'Telugu': return 'BEFORE_SUB' if u <= 0x0C42 else 'AFTER_SUB' + if block == 'Kannada': return 'BEFORE_SUB' if u < 0x0CC3 or u > 0x0CD6 else 'AFTER_SUB' + if block == 'Malayalam': return 'AFTER_POST' + return 'AFTER_SUB' +def matra_pos_top(u, block): + # BENG and MLYM don't have top matras. + if block == 'Devanagari': return 'AFTER_SUB' + if block == 'Gurmukhi': return 'AFTER_POST' # Deviate from spec + if block == 'Gujarati': return 'AFTER_SUB' + if block == 'Oriya': return 'AFTER_MAIN' + if block == 'Tamil': return 'AFTER_SUB' + if block == 'Telugu': return 'BEFORE_SUB' + if block == 'Kannada': return 'BEFORE_SUB' + return 'AFTER_SUB' +def matra_pos_bottom(u, block): + if block == 'Devanagari': return 'AFTER_SUB' + if block == 'Bengali': return 'AFTER_SUB' + if block == 'Gurmukhi': return 'AFTER_POST' + if block == 'Gujarati': return 'AFTER_POST' + if block == 'Oriya': return 'AFTER_SUB' + if block == 'Tamil': return 'AFTER_POST' + if block == 'Telugu': return 'BEFORE_SUB' + if block == 'Kannada': return 'BEFORE_SUB' + if block == 'Malayalam': return 'AFTER_POST' + return "AFTER_SUB" +def indic_matra_position(u, pos, block): # Reposition matra + if pos == 'PRE_C': return matra_pos_left(u, block) + if pos == 'POST_C': return matra_pos_right(u, block) + if pos == 'ABOVE_C': return matra_pos_top(u, block) + if pos == 'BELOW_C': return matra_pos_bottom(u, block) + assert (False) + +def position_to_category(pos): + if pos == 'PRE_C': return 'VPre' + if pos == 'ABOVE_C': return 'VAbv' + if pos == 'BELOW_C': return 'VBlw' + if pos == 'POST_C': return 'VPst' + assert(False) + + +defaults = (category_map[defaults[0]], position_map[defaults[1]], defaults[2]) + +indic_data = {} +for k, (cat, pos, block) in combined.items(): + cat = category_map[cat] + pos = position_map[pos] + indic_data[k] = (cat, pos, block) + +for k,new_cat in category_overrides.items(): + (cat, pos, _) = indic_data.get(k, defaults) + indic_data[k] = (new_cat, pos, unicode_data[2][k]) + +# We only expect position for certain types +positioned_categories = ('CM', 'SM', 'RS', 'H', 'M') +for k, (cat, pos, block) in indic_data.items(): + if cat not in positioned_categories: + pos = 'END' + indic_data[k] = (cat, pos, block) + +# Position overrides are more complicated + +# Keep in sync with CONSONANT_FLAGS in the shaper +consonant_categories = ('C', 'CS', 'Ra','CM', 'V', 'PLACEHOLDER', 'DOTTEDCIRCLE') +smvd_categories = ('SM', 'VD', 'A', 'Symbol') +for k, (cat, pos, block) in indic_data.items(): + if cat in consonant_categories: + pos = 'BASE_C' + elif cat == 'M': + if block.startswith('Khmer') or block.startswith('Myanmar'): + cat = position_to_category(pos) + else: + pos = indic_matra_position(u, pos, block) + elif cat in smvd_categories: + pos = 'SMVD'; + indic_data[k] = (cat, pos, block) + +for k,new_pos in position_overrides.items(): + (cat, pos, _) = indic_data.get(k, defaults) + indic_data[k] = (cat, new_pos, unicode_data[2][k]) + + +values = [{_: 1} for _ in defaults] +for vv in indic_data.values(): + for i,v in enumerate(vv): + values[i][v] = values[i].get (v, 0) + 1 + + + # Move the outliers NO-BREAK SPACE and DOTTED CIRCLE out singles = {} for u in ALLOWED_SINGLES: - singles[u] = data[u] - del data[u] + singles[u] = indic_data[u] + del indic_data[u] print ("/* == Start of generated table == */") print ("/*") @@ -106,37 +499,63 @@ print ('#include "hb.hh"') print () print ('#ifndef HB_NO_OT_SHAPE') print () -print ('#include "hb-ot-shape-complex-indic.hh"') +print ('#include "hb-ot-shaper-indic.hh"') +print () +print ('#pragma GCC diagnostic push') +print ('#pragma GCC diagnostic ignored "-Wunused-macros"') +print () + +# Print categories +for shaper in categories: + print ('#include "hb-ot-shaper-%s-machine.hh"' % shaper) +print () +done = {} +for shaper, shaper_cats in categories.items(): + print ('/* %s */' % shaper) + for cat in shaper_cats: + v = shaper[0].upper() + if cat not in done: + print ("#define OT_%s %s_Cat(%s)" % (cat, v, cat)) + done[cat] = v + else: + print ('static_assert (OT_%s == %s_Cat(%s), "");' % (cat, v, cat)) print () # Shorten values short = [{ - "Bindu": 'Bi', - "Cantillation_Mark": 'Ca', - "Joiner": 'ZWJ', - "Non_Joiner": 'ZWNJ', - "Number": 'Nd', - "Visarga": 'Vs', - "Vowel": 'Vo', - "Vowel_Dependent": 'M', - "Consonant_Prefixed": 'CPrf', - "Other": 'x', + "Repha": 'Rf', + "PLACEHOLDER": 'GB', + "DOTTEDCIRCLE": 'DC', + "VPst": 'VR', + "VPre": 'VL', + "Robatic": 'Rt', + "Xgroup": 'Xg', + "Ygroup": 'Yg', + "As": 'As', },{ - "Not_Applicable": 'x', + "END": 'X', + "BASE_C": 'C', + "ABOVE_C": 'T', + "BELOW_C": 'B', + "POST_C": 'R', + "PRE_C": 'L', + "PRE_M": 'LM', + "AFTER_MAIN": 'A', + "AFTER_SUB": 'AS', + "BEFORE_SUB": 'BS', + "AFTER_POST": 'AP', + "SMVD": 'SM', }] all_shorts = [{},{}] # Add some of the values, to make them more readable, and to avoid duplicates - for i in range (2): for v,s in short[i].items (): all_shorts[i][s] = v -what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"] -what_short = ["ISC", "IMC"] -print ('#pragma GCC diagnostic push') -print ('#pragma GCC diagnostic ignored "-Wunused-macros"') +what = ["OT", "POS"] +what_short = ["_OT", "_POS"] cat_defs = [] for i in range (2): vv = sorted (values[i].keys ()) @@ -150,7 +569,7 @@ for i in range (2): raise Exception ("Duplicate short value alias", v, all_shorts[i][s]) all_shorts[i][s] = v short[i][v] = s - cat_defs.append ((what_short[i] + '_' + s, what[i] + '_' + v.upper (), str (values[i][v]), v)) + cat_defs.append ((what_short[i] + '_' + s, what[i] + '_' + (v.upper () if i else v), str (values[i][v]), v)) maxlen_s = max ([len (c[0]) for c in cat_defs]) maxlen_l = max ([len (c[1]) for c in cat_defs]) @@ -163,7 +582,9 @@ for s in what_short: print () print ('#pragma GCC diagnostic pop') print () -print ("#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)") +print ("#define INDIC_COMBINE_CATEGORIES(S,M) ((S) | ((M) << 8))") +print () +print ("#define _(S,M) INDIC_COMBINE_CATEGORIES (%s_##S, %s_##M)" % tuple(what_short)) print () print () @@ -193,7 +614,7 @@ def print_block (block, start, end, data): if block: last_block = block -uu = sorted (data.keys ()) +uu = sorted (indic_data) last = -100000 num = 0 @@ -204,17 +625,17 @@ print ("static const uint16_t indic_table[] = {") for u in uu: if u <= last: continue - block = data[u][2] + block = indic_data[u][2] start = u//8*8 end = start+1 - while end in uu and block == data[end][2]: + while end in uu and block == indic_data[end][2]: end += 1 end = (end-1)//8*8 + 7 if start != last + 1: if start - last <= 1+16*3: - print_block (None, last+1, start-1, data) + print_block (None, last+1, start-1, indic_data) else: if last >= 0: ends.append (last + 1) @@ -224,7 +645,7 @@ for u in uu: print ("#define indic_offset_0x%04xu %d" % (start, offset)) starts.append (start) - print_block (block, start, end, data) + print_block (block, start, end, indic_data) last = end ends.append (last + 1) offset += ends[-1] - starts[-1] @@ -254,10 +675,11 @@ for p in sorted(pages): print (" default:") print (" break;") print (" }") -print (" return _(x,x);") +print (" return _(X,X);") print ("}") print () print ("#undef _") +print ("#undef INDIC_COMBINE_CATEGORIES") for i in range (2): print () vv = sorted (values[i].keys ()) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py index b8718360418..7e15c08c56c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py @@ -944,6 +944,8 @@ def same_tag (bcp_47_tag, ot_tags): return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower () for language_len in (2, 3): + if language_len == 3: + print ('#ifndef HB_NO_LANGUAGE_LONG') print ('static const LangTag ot_languages%d[] = {' % language_len) for language, tags in sorted (ot.from_bcp_47.items ()): if language == '' or '-' in language: @@ -971,6 +973,8 @@ for language_len in (2, 3): write ('%s%s' % (name if len (name) > len (ot_name) else ot_name, scope)) print (' */') print ('};') + if language_len == 3: + print ('#endif') print () print ('/**') @@ -987,7 +991,7 @@ print (' * Converts a multi-subtag BCP 47 language tag to language tags.') print (' *') print (' * Return value: Whether any language systems were retrieved.') print (' **/') -print ('static bool') +print ('static inline bool') print ('hb_ot_tags_from_complex_language (const char *lang_str,') print ('\t\t\t\t const char *limit,') print ('\t\t\t\t unsigned int *count /* IN/OUT */,') @@ -1130,7 +1134,7 @@ print (' *') print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,') print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.') print (' **/') -print ('static hb_language_t') +print ('static inline hb_language_t') print ('hb_ot_ambiguous_tag_to_language (hb_tag_t tag)') print ('{') print (' switch (tag)') diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py index 48fd3889d38..5daab7063ab 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py @@ -221,7 +221,10 @@ def is_CONS_SUB(U, UISC, UDI, UGC, AJT): def is_CONS_WITH_STACKER(U, UISC, UDI, UGC, AJT): return UISC == Consonant_With_Stacker def is_HALANT(U, UISC, UDI, UGC, AJT): - return UISC == Virama + return UISC == Virama and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UDI, UGC, AJT) +def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UDI, UGC, AJT): + # Split off of HALANT + return U == 0x0DCA def is_HALANT_NUM(U, UISC, UDI, UGC, AJT): return UISC == Number_Joiner def is_HIEROGLYPH(U, UISC, UDI, UGC, AJT): @@ -280,6 +283,7 @@ use_mapping = { 'SUB': is_CONS_SUB, 'CS': is_CONS_WITH_STACKER, 'H': is_HALANT, + 'HVM': is_HALANT_OR_VOWEL_MODIFIER, 'HN': is_HALANT_NUM, 'IS': is_INVISIBLE_STACKER, 'G': is_HIEROGLYPH, @@ -329,6 +333,7 @@ use_positions = { 'Blw': [Bottom], }, 'H': None, + 'HVM': None, 'IS': None, 'B': None, 'FM': { @@ -412,12 +417,12 @@ for h in headers: print (" * %s" % (l.strip())) print (" */") print () -print ("#ifndef HB_OT_SHAPE_COMPLEX_USE_TABLE_HH") -print ("#define HB_OT_SHAPE_COMPLEX_USE_TABLE_HH") +print ("#ifndef HB_OT_SHAPER_USE_TABLE_HH") +print ("#define HB_OT_SHAPER_USE_TABLE_HH") print () print ('#include "hb.hh"') print () -print ('#include "hb-ot-shape-complex-use-machine.hh"') +print ('#include "hb-ot-shaper-use-machine.hh"') print () total = 0 @@ -542,7 +547,7 @@ for k,v in sorted(use_positions.items()): print ("#undef %s" % tag) print () print () -print ("#endif /* HB_OT_SHAPE_COMPLEX_USE_TABLE_HH */") +print ("#endif /* HB_OT_SHAPER_USE_TABLE_HH */") print ("/* == End of generated table == */") # Maintain at least 50% occupancy in the table */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py index 42afd281ed0..3c1f6211eb4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py @@ -5,7 +5,7 @@ It creates ``_hb_preprocess_text_vowel_constraints``, which inserts dotted circles into sequences prohibited by the USE script development spec. This function should be used as the ``preprocess_text`` of an -``hb_ot_complex_shaper_t``. +``hb_ot_shaper_t``. usage: ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt @@ -166,7 +166,7 @@ print ('#include "hb.hh"') print () print ('#ifndef HB_NO_OT_SHAPE') print () -print ('#include "hb-ot-shape-complex-vowel-constraints.hh"') +print ('#include "hb-ot-shaper-vowel-constraints.hh"') print () print ('static void') print ('_output_dotted_circle (hb_buffer_t *buffer)') @@ -188,7 +188,7 @@ print ('_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB print ('\t\t\t\t hb_buffer_t *buffer,') print ('\t\t\t\t hb_font_t *font HB_UNUSED)') print ('{') -print ('#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS') +print ('#ifdef HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS') print (' return;') print ('#endif') print (' if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)') diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh new file mode 100644 index 00000000000..52ca9dd142e --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh @@ -0,0 +1,860 @@ +/* + * 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. + * + * Google Author(s): Garret Rieger + */ + +#ifndef GRAPH_GRAPH_HH +#define GRAPH_GRAPH_HH + +namespace graph { + +/** + * Represents a serialized table in the form of a graph. + * Provides methods for modifying and reordering the graph. + */ +struct graph_t +{ + struct vertex_t + { + hb_serialize_context_t::object_t obj; + int64_t distance = 0 ; + int64_t space = 0 ; + hb_vector_t<unsigned> parents; + unsigned start = 0; + unsigned end = 0; + unsigned priority = 0; + + friend void swap (vertex_t& a, vertex_t& b) + { + hb_swap (a.obj, b.obj); + hb_swap (a.distance, b.distance); + hb_swap (a.space, b.space); + hb_swap (a.parents, b.parents); + hb_swap (a.start, b.start); + hb_swap (a.end, b.end); + hb_swap (a.priority, b.priority); + } + + bool is_shared () const + { + return parents.length > 1; + } + + unsigned incoming_edges () const + { + return parents.length; + } + + void remove_parent (unsigned parent_index) + { + for (unsigned i = 0; i < parents.length; i++) + { + if (parents[i] != parent_index) continue; + parents.remove (i); + break; + } + } + + void remap_parents (const hb_vector_t<unsigned>& id_map) + { + for (unsigned i = 0; i < parents.length; i++) + parents[i] = id_map[parents[i]]; + } + + void remap_parent (unsigned old_index, unsigned new_index) + { + for (unsigned i = 0; i < parents.length; i++) + { + if (parents[i] == old_index) + parents[i] = new_index; + } + } + + bool is_leaf () const + { + return !obj.real_links.length && !obj.virtual_links.length; + } + + bool raise_priority () + { + if (has_max_priority ()) return false; + priority++; + return true; + } + + bool has_max_priority () const { + return priority >= 3; + } + + int64_t modified_distance (unsigned order) const + { + // TODO(garretrieger): once priority is high enough, should try + // setting distance = 0 which will force to sort immediately after + // it's parent where possible. + + int64_t modified_distance = + hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF); + if (has_max_priority ()) { + modified_distance = 0; + } + return (modified_distance << 18) | (0x003FFFF & order); + } + + int64_t distance_modifier () const + { + if (!priority) return 0; + int64_t table_size = obj.tail - obj.head; + + if (priority == 1) + return -table_size / 2; + + return -table_size; + } + }; + + /* + * A topological sorting of an object graph. Ordered + * in reverse serialization order (first object in the + * serialization is at the end of the list). This matches + * the 'packed' object stack used internally in the + * serializer + */ + template<typename T> + graph_t (const T& objects) + : parents_invalid (true), + distance_invalid (true), + positions_invalid (true), + successful (true) + { + num_roots_for_space_.push (1); + bool removed_nil = false; + vertices_.alloc (objects.length); + vertices_scratch_.alloc (objects.length); + for (unsigned i = 0; i < objects.length; i++) + { + // TODO(grieger): check all links point to valid objects. + + // If this graph came from a serialization buffer object 0 is the + // nil object. We don't need it for our purposes here so drop it. + if (i == 0 && !objects[i]) + { + removed_nil = true; + continue; + } + + vertex_t* v = vertices_.push (); + if (check_success (!vertices_.in_error ())) + v->obj = *objects[i]; + if (!removed_nil) continue; + // Fix indices to account for removed nil object. + for (auto& l : v->obj.all_links_writer ()) { + l.objidx--; + } + } + } + + ~graph_t () + { + vertices_.fini (); + } + + bool in_error () const + { + return !successful || + vertices_.in_error () || + num_roots_for_space_.in_error (); + } + + const vertex_t& root () const + { + return vertices_[root_idx ()]; + } + + unsigned root_idx () const + { + // Object graphs are in reverse order, the first object is at the end + // of the vector. Since the graph is topologically sorted it's safe to + // assume the first object has no incoming edges. + return vertices_.length - 1; + } + + const hb_serialize_context_t::object_t& object(unsigned i) const + { + return vertices_[i].obj; + } + + /* + * Generates a new topological sorting of graph ordered by the shortest + * distance to each node. + */ + void sort_shortest_distance () + { + positions_invalid = true; + + if (vertices_.length <= 1) { + // Graph of 1 or less doesn't need sorting. + return; + } + + update_distances (); + + hb_priority_queue_t queue; + hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_; + if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; + hb_vector_t<unsigned> id_map; + if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; + + hb_vector_t<unsigned> removed_edges; + if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return; + update_parents (); + + queue.insert (root ().modified_distance (0), root_idx ()); + int new_id = root_idx (); + unsigned order = 1; + while (!queue.in_error () && !queue.is_empty ()) + { + unsigned next_id = queue.pop_minimum().second; + + hb_swap (sorted_graph[new_id], vertices_[next_id]); + const vertex_t& next = sorted_graph[new_id]; + + id_map[next_id] = new_id--; + + for (const auto& link : next.obj.all_links ()) { + removed_edges[link.objidx]++; + if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) + // Add the order that the links were encountered to the priority. + // This ensures that ties between priorities objects are broken in a consistent + // way. More specifically this is set up so that if a set of objects have the same + // distance they'll be added to the topological order in the order that they are + // referenced from the parent object. + queue.insert (vertices_[link.objidx].modified_distance (order++), + link.objidx); + } + } + + check_success (!queue.in_error ()); + check_success (!sorted_graph.in_error ()); + if (!check_success (new_id == -1)) + print_orphaned_nodes (); + + remap_all_obj_indices (id_map, &sorted_graph); + + hb_swap (vertices_, sorted_graph); + } + + /* + * Assign unique space numbers to each connected subgraph of 32 bit offset(s). + */ + bool assign_32bit_spaces () + { + unsigned root_index = root_idx (); + hb_set_t visited; + hb_set_t roots; + for (unsigned i = 0; i <= root_index; i++) + { + // Only real links can form 32 bit spaces + for (auto& l : vertices_[i].obj.real_links) + { + if (l.width == 4 && !l.is_signed) + { + roots.add (l.objidx); + find_subgraph (l.objidx, visited); + } + } + } + + // Mark everything not in the subgraphs of 32 bit roots as visited. + // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs. + visited.invert (); + + if (!roots) return false; + + while (roots) + { + unsigned next = HB_SET_VALUE_INVALID; + if (unlikely (!check_success (!roots.in_error ()))) break; + if (!roots.next (&next)) break; + + hb_set_t connected_roots; + find_connected_nodes (next, roots, visited, connected_roots); + if (unlikely (!check_success (!connected_roots.in_error ()))) break; + + isolate_subgraph (connected_roots); + if (unlikely (!check_success (!connected_roots.in_error ()))) break; + + unsigned next_space = this->next_space (); + num_roots_for_space_.push (0); + for (unsigned root : connected_roots) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Subgraph %u gets space %u", root, next_space); + vertices_[root].space = next_space; + num_roots_for_space_[next_space] = num_roots_for_space_[next_space] + 1; + distance_invalid = true; + positions_invalid = true; + } + + // TODO(grieger): special case for GSUB/GPOS use extension promotions to move 16 bit space + // into the 32 bit space as needed, instead of using isolation. + } + + + + return true; + } + + /* + * Isolates the subgraph of nodes reachable from root. Any links to nodes in the subgraph + * that originate from outside of the subgraph will be removed by duplicating the linked to + * object. + * + * Indices stored in roots will be updated if any of the roots are duplicated to new indices. + */ + bool isolate_subgraph (hb_set_t& roots) + { + update_parents (); + hb_map_t subgraph; + + // incoming edges to root_idx should be all 32 bit in length so we don't need to de-dup these + // set the subgraph incoming edge count to match all of root_idx's incoming edges + hb_set_t parents; + for (unsigned root_idx : roots) + { + subgraph.set (root_idx, wide_parents (root_idx, parents)); + find_subgraph (root_idx, subgraph); + } + + unsigned original_root_idx = root_idx (); + hb_map_t index_map; + bool made_changes = false; + for (auto entry : subgraph.iter ()) + { + const auto& node = vertices_[entry.first]; + unsigned subgraph_incoming_edges = entry.second; + + if (subgraph_incoming_edges < node.incoming_edges ()) + { + // Only de-dup objects with incoming links from outside the subgraph. + made_changes = true; + duplicate_subgraph (entry.first, index_map); + } + } + + if (!made_changes) + return false; + + if (original_root_idx != root_idx () + && parents.has (original_root_idx)) + { + // If the root idx has changed since parents was determined, update root idx in parents + parents.add (root_idx ()); + parents.del (original_root_idx); + } + + auto new_subgraph = + + subgraph.keys () + | hb_map([&] (unsigned node_idx) { + const unsigned *v; + if (index_map.has (node_idx, &v)) return *v; + return node_idx; + }) + ; + + remap_obj_indices (index_map, new_subgraph); + remap_obj_indices (index_map, parents.iter (), true); + + // Update roots set with new indices as needed. + unsigned next = HB_SET_VALUE_INVALID; + while (roots.next (&next)) + { + const unsigned *v; + if (index_map.has (next, &v)) + { + roots.del (next); + roots.add (*v); + } + } + + return true; + } + + void find_subgraph (unsigned node_idx, hb_map_t& subgraph) + { + for (const auto& link : vertices_[node_idx].obj.all_links ()) + { + const unsigned *v; + if (subgraph.has (link.objidx, &v)) + { + subgraph.set (link.objidx, *v + 1); + continue; + } + subgraph.set (link.objidx, 1); + find_subgraph (link.objidx, subgraph); + } + } + + void find_subgraph (unsigned node_idx, hb_set_t& subgraph) + { + if (subgraph.has (node_idx)) return; + subgraph.add (node_idx); + for (const auto& link : vertices_[node_idx].obj.all_links ()) + find_subgraph (link.objidx, subgraph); + } + + /* + * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign + * links. index_map is updated with mappings from old id to new id. If a duplication has already + * been performed for a given index, then it will be skipped. + */ + void duplicate_subgraph (unsigned node_idx, hb_map_t& index_map) + { + if (index_map.has (node_idx)) + return; + + index_map.set (node_idx, duplicate (node_idx)); + for (const auto& l : object (node_idx).all_links ()) { + duplicate_subgraph (l.objidx, index_map); + } + } + + /* + * Creates a copy of node_idx and returns it's new index. + */ + unsigned duplicate (unsigned node_idx) + { + positions_invalid = true; + distance_invalid = true; + + auto* clone = vertices_.push (); + auto& child = vertices_[node_idx]; + if (vertices_.in_error ()) { + return -1; + } + + clone->obj.head = child.obj.head; + clone->obj.tail = child.obj.tail; + clone->distance = child.distance; + clone->space = child.space; + clone->parents.reset (); + + unsigned clone_idx = vertices_.length - 2; + for (const auto& l : child.obj.real_links) + { + clone->obj.real_links.push (l); + vertices_[l.objidx].parents.push (clone_idx); + } + for (const auto& l : child.obj.virtual_links) + { + clone->obj.virtual_links.push (l); + vertices_[l.objidx].parents.push (clone_idx); + } + + check_success (!clone->obj.real_links.in_error ()); + check_success (!clone->obj.virtual_links.in_error ()); + + // The last object is the root of the graph, so swap back the root to the end. + // The root's obj idx does change, however since it's root nothing else refers to it. + // all other obj idx's will be unaffected. + hb_swap (vertices_[vertices_.length - 2], *clone); + + // Since the root moved, update the parents arrays of all children on the root. + for (const auto& l : root ().obj.all_links ()) + vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); + + return clone_idx; + } + + /* + * 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. + */ + bool 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++; + } + + if (vertices_[child_idx].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 %d => %d", + parent_idx, child_idx); + return false; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d", + parent_idx, child_idx); + + unsigned clone_idx = duplicate (child_idx); + if (clone_idx == (unsigned) -1) return false; + // 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 true; + } + + /* + * Raises the sorting priority of all children. + */ + bool raise_childrens_priority (unsigned parent_idx) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d", + parent_idx); + // This operation doesn't change ordering until a sort is run, so no need + // to invalidate positions. It does not change graph structure so no need + // to update distances or edge counts. + auto& parent = vertices_[parent_idx].obj; + bool made_change = false; + for (auto& l : parent.all_links_writer ()) + made_change |= vertices_[l.objidx].raise_priority (); + return made_change; + } + + void print_orphaned_nodes () + { + if (!DEBUG_ENABLED(SUBSET_REPACK)) return; + + DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); + parents_invalid = true; + update_parents(); + + for (unsigned i = 0; i < root_idx (); i++) + { + const auto& v = vertices_[i]; + if (!v.parents) + DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i); + } + } + + unsigned num_roots_for_space (unsigned space) const + { + return num_roots_for_space_[space]; + } + + unsigned next_space () const + { + return num_roots_for_space_.length; + } + + void move_to_new_space (const hb_set_t& indices) + { + num_roots_for_space_.push (0); + unsigned new_space = num_roots_for_space_.length - 1; + + for (unsigned index : indices) { + auto& node = vertices_[index]; + num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1; + num_roots_for_space_[new_space] = num_roots_for_space_[new_space] + 1; + node.space = new_space; + distance_invalid = true; + positions_invalid = true; + } + } + + unsigned space_for (unsigned index, unsigned* root = nullptr) const + { + const auto& node = vertices_[index]; + if (node.space) + { + if (root != nullptr) + *root = index; + return node.space; + } + + if (!node.parents) + { + if (root) + *root = index; + return 0; + } + + return space_for (node.parents[0], root); + } + + void err_other_error () { this->successful = false; } + + size_t total_size_in_bytes () const { + size_t total_size = 0; + for (unsigned i = 0; i < vertices_.length; i++) { + size_t size = vertices_[i].obj.tail - vertices_[i].obj.head; + total_size += size; + } + return total_size; + } + + + private: + + /* + * Returns the numbers of incoming edges that are 32bits wide. + */ + unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const + { + unsigned count = 0; + hb_set_t visited; + for (unsigned p : vertices_[node_idx].parents) + { + if (visited.has (p)) continue; + visited.add (p); + + // Only real links can be wide + for (const auto& l : vertices_[p].obj.real_links) + { + if (l.objidx == node_idx && l.width == 4 && !l.is_signed) + { + count++; + parents.add (p); + } + } + } + return count; + } + + bool check_success (bool success) + { return this->successful && (success || ((void) err_other_error (), false)); } + + public: + /* + * Creates a map from objid to # of incoming edges. + */ + void update_parents () + { + if (!parents_invalid) return; + + for (unsigned i = 0; i < vertices_.length; i++) + vertices_[i].parents.reset (); + + for (unsigned p = 0; p < vertices_.length; p++) + { + for (auto& l : vertices_[p].obj.all_links ()) + { + vertices_[l.objidx].parents.push (p); + } + } + + parents_invalid = false; + } + + /* + * compute the serialized start and end positions for each vertex. + */ + void update_positions () + { + if (!positions_invalid) return; + + unsigned current_pos = 0; + for (int i = root_idx (); i >= 0; i--) + { + auto& v = vertices_[i]; + v.start = current_pos; + current_pos += v.obj.tail - v.obj.head; + v.end = current_pos; + } + + positions_invalid = false; + } + + /* + * Finds the distance to each object in the graph + * from the initial node. + */ + void update_distances () + { + if (!distance_invalid) return; + + // Uses Dijkstra's algorithm to find all of the shortest distances. + // https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm + // + // Implementation Note: + // Since our priority queue doesn't support fast priority decreases + // we instead just add new entries into the queue when a priority changes. + // Redundant ones are filtered out later on by the visited set. + // According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf + // for practical performance this is faster then using a more advanced queue + // (such as a fibonacci queue) with a fast decrease priority. + for (unsigned i = 0; i < vertices_.length; i++) + { + if (i == vertices_.length - 1) + vertices_[i].distance = 0; + else + vertices_[i].distance = hb_int_max (int64_t); + } + + hb_priority_queue_t queue; + queue.insert (0, vertices_.length - 1); + + hb_vector_t<bool> visited; + visited.resize (vertices_.length); + + while (!queue.in_error () && !queue.is_empty ()) + { + unsigned next_idx = queue.pop_minimum ().second; + if (visited[next_idx]) continue; + const auto& next = vertices_[next_idx]; + int64_t next_distance = vertices_[next_idx].distance; + visited[next_idx] = true; + + for (const auto& link : next.obj.all_links ()) + { + if (visited[link.objidx]) continue; + + const auto& child = vertices_[link.objidx].obj; + unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide + int64_t child_weight = (child.tail - child.head) + + ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1); + int64_t child_distance = next_distance + child_weight; + + if (child_distance < vertices_[link.objidx].distance) + { + vertices_[link.objidx].distance = child_distance; + queue.insert (child_distance, link.objidx); + } + } + } + + check_success (!queue.in_error ()); + if (!check_success (queue.is_empty ())) + { + print_orphaned_nodes (); + return; + } + + distance_invalid = false; + } + + private: + /* + * Updates a link in the graph to point to a different object. Corrects the + * parents vector on the previous and new child nodes. + */ + void reassign_link (hb_serialize_context_t::object_t::link_t& link, + unsigned parent_idx, + unsigned new_idx) + { + unsigned old_idx = link.objidx; + link.objidx = new_idx; + vertices_[old_idx].remove_parent (parent_idx); + vertices_[new_idx].parents.push (parent_idx); + } + + /* + * Updates all objidx's in all links using the provided mapping. Corrects incoming edge counts. + */ + template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> + void remap_obj_indices (const hb_map_t& id_map, + Iterator subgraph, + bool only_wide = false) + { + if (!id_map) return; + for (unsigned i : subgraph) + { + for (auto& link : vertices_[i].obj.all_links_writer ()) + { + const unsigned *v; + if (!id_map.has (link.objidx, &v)) continue; + if (only_wide && !(link.width == 4 && !link.is_signed)) continue; + + reassign_link (link, i, *v); + } + } + } + + /* + * Updates all objidx's in all links using the provided mapping. + */ + void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map, + hb_vector_t<vertex_t>* sorted_graph) const + { + for (unsigned i = 0; i < sorted_graph->length; i++) + { + (*sorted_graph)[i].remap_parents (id_map); + for (auto& link : (*sorted_graph)[i].obj.all_links_writer ()) + { + link.objidx = id_map[link.objidx]; + } + } + } + + /* + * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped. + * For this search the graph is treated as being undirected. + * + * Connected targets will be added to connected and removed from targets. All visited nodes + * will be added to visited. + */ + void find_connected_nodes (unsigned start_idx, + hb_set_t& targets, + hb_set_t& visited, + hb_set_t& connected) + { + if (unlikely (!check_success (!visited.in_error ()))) return; + if (visited.has (start_idx)) return; + visited.add (start_idx); + + if (targets.has (start_idx)) + { + targets.del (start_idx); + connected.add (start_idx); + } + + const auto& v = vertices_[start_idx]; + + // Graph is treated as undirected so search children and parents of start_idx + for (const auto& l : v.obj.all_links ()) + find_connected_nodes (l.objidx, targets, visited, connected); + + for (unsigned p : v.parents) + find_connected_nodes (p, targets, visited, connected); + } + + public: + // TODO(garretrieger): make private, will need to move most of offset overflow code into graph. + hb_vector_t<vertex_t> vertices_; + hb_vector_t<vertex_t> vertices_scratch_; + private: + bool parents_invalid; + bool distance_invalid; + bool positions_invalid; + bool successful; + hb_vector_t<unsigned> num_roots_for_space_; +}; + +} + +#endif // GRAPH_GRAPH_HH diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh new file mode 100644 index 00000000000..ecc6cc5aea2 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh @@ -0,0 +1,249 @@ +/* + * 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. + * + * Google Author(s): Garret Rieger + */ + +#ifndef GRAPH_SERIALIZE_HH +#define GRAPH_SERIALIZE_HH + +namespace graph { + +struct overflow_record_t +{ + unsigned parent; + unsigned child; +}; + +inline +int64_t compute_offset ( + const graph_t& graph, + unsigned parent_idx, + const hb_serialize_context_t::object_t::link_t& link) +{ + const auto& parent = graph.vertices_[parent_idx]; + const auto& child = graph.vertices_[link.objidx]; + int64_t offset = 0; + switch ((hb_serialize_context_t::whence_t) link.whence) { + case hb_serialize_context_t::whence_t::Head: + offset = child.start - parent.start; break; + case hb_serialize_context_t::whence_t::Tail: + offset = child.start - parent.end; break; + case hb_serialize_context_t::whence_t::Absolute: + offset = child.start; break; + } + + assert (offset >= link.bias); + offset -= link.bias; + return offset; +} + +inline +bool is_valid_offset (int64_t offset, + const hb_serialize_context_t::object_t::link_t& link) +{ + if (unlikely (!link.width)) + // Virtual links can't overflow. + return link.is_signed || offset >= 0; + + if (link.is_signed) + { + if (link.width == 4) + return offset >= -((int64_t) 1 << 31) && offset < ((int64_t) 1 << 31); + else + return offset >= -(1 << 15) && offset < (1 << 15); + } + else + { + if (link.width == 4) + return offset >= 0 && offset < ((int64_t) 1 << 32); + else if (link.width == 3) + return offset >= 0 && offset < ((int32_t) 1 << 24); + else + return offset >= 0 && offset < (1 << 16); + } +} + +/* + * Will any offsets overflow on graph when it's serialized? + */ +inline bool +will_overflow (graph_t& graph, + hb_vector_t<overflow_record_t>* overflows = nullptr) +{ + if (overflows) overflows->resize (0); + graph.update_positions (); + + const auto& vertices = graph.vertices_; + for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--) + { + // Don't need to check virtual links for overflow + for (const auto& link : vertices[parent_idx].obj.real_links) + { + int64_t offset = compute_offset (graph, parent_idx, link); + if (is_valid_offset (offset, link)) + continue; + + if (!overflows) return true; + + overflow_record_t r; + r.parent = parent_idx; + r.child = link.objidx; + overflows->push (r); + } + } + + if (!overflows) return false; + return overflows->length; +} + +inline +void print_overflows (graph_t& graph, + const hb_vector_t<overflow_record_t>& overflows) +{ + if (!DEBUG_ENABLED(SUBSET_REPACK)) return; + + graph.update_parents (); + int limit = 10; + for (const auto& o : overflows) + { + if (!limit--) break; + const auto& parent = graph.vertices_[o.parent]; + const auto& child = graph.vertices_[o.child]; + DEBUG_MSG (SUBSET_REPACK, nullptr, + " overflow from " + "%4d (%4d in, %4d out, space %2d) => " + "%4d (%4d in, %4d out, space %2d)", + o.parent, + parent.incoming_edges (), + parent.obj.real_links.length + parent.obj.virtual_links.length, + graph.space_for (o.parent), + o.child, + child.incoming_edges (), + child.obj.real_links.length + child.obj.virtual_links.length, + graph.space_for (o.child)); + } + if (overflows.length > 10) { + DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %d more overflows.", overflows.length - 10); + } +} + +template <typename O> inline void +serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, + char* head, + hb_serialize_context_t* c) +{ + OT::Offset<O>* offset = reinterpret_cast<OT::Offset<O>*> (head + link.position); + *offset = 0; + c->add_link (*offset, + // serializer has an extra nil object at the start of the + // object array. So all id's are +1 of what our id's are. + link.objidx + 1, + (hb_serialize_context_t::whence_t) link.whence, + link.bias); +} + +inline +void serialize_link (const hb_serialize_context_t::object_t::link_t& link, + char* head, + hb_serialize_context_t* c) +{ + switch (link.width) + { + case 0: + // Virtual links aren't serialized. + return; + case 4: + if (link.is_signed) + { + serialize_link_of_type<OT::HBINT32> (link, head, c); + } else { + serialize_link_of_type<OT::HBUINT32> (link, head, c); + } + return; + case 2: + if (link.is_signed) + { + serialize_link_of_type<OT::HBINT16> (link, head, c); + } else { + serialize_link_of_type<OT::HBUINT16> (link, head, c); + } + return; + case 3: + serialize_link_of_type<OT::HBUINT24> (link, head, c); + return; + default: + // Unexpected link width. + assert (0); + } +} + +/* + * serialize graph into the provided serialization buffer. + */ +inline hb_blob_t* serialize (const graph_t& graph) +{ + hb_vector_t<char> buffer; + size_t size = graph.total_size_in_bytes (); + if (!buffer.alloc (size)) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer."); + return nullptr; + } + hb_serialize_context_t c((void *) buffer, size); + + c.start_serialize<void> (); + const auto& vertices = graph.vertices_; + for (unsigned i = 0; i < vertices.length; i++) { + c.push (); + + size_t size = vertices[i].obj.tail - vertices[i].obj.head; + char* start = c.allocate_size <char> (size); + if (!start) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space."); + return nullptr; + } + + memcpy (start, vertices[i].obj.head, size); + + // Only real links needs to be serialized. + for (const auto& link : vertices[i].obj.real_links) + serialize_link (link, start, &c); + + // All duplications are already encoded in the graph, so don't + // enable sharing during packing. + c.pop_pack (false); + } + c.end_serialize (); + + if (c.in_error ()) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d", + c.errors); + return nullptr; + } + + return c.copy_blob (); +} + +} // namespace graph + +#endif // GRAPH_SERIALIZE_HH diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc index b6a5957c425..05a864ae11f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc @@ -22,18 +22,18 @@ #include "hb-ot-meta.cc" #include "hb-ot-metrics.cc" #include "hb-ot-name.cc" -#include "hb-ot-shape-complex-arabic.cc" -#include "hb-ot-shape-complex-default.cc" -#include "hb-ot-shape-complex-hangul.cc" -#include "hb-ot-shape-complex-hebrew.cc" -#include "hb-ot-shape-complex-indic-table.cc" -#include "hb-ot-shape-complex-indic.cc" -#include "hb-ot-shape-complex-khmer.cc" -#include "hb-ot-shape-complex-myanmar.cc" -#include "hb-ot-shape-complex-syllabic.cc" -#include "hb-ot-shape-complex-thai.cc" -#include "hb-ot-shape-complex-use.cc" -#include "hb-ot-shape-complex-vowel-constraints.cc" +#include "hb-ot-shaper-arabic.cc" +#include "hb-ot-shaper-default.cc" +#include "hb-ot-shaper-hangul.cc" +#include "hb-ot-shaper-hebrew.cc" +#include "hb-ot-shaper-indic-table.cc" +#include "hb-ot-shaper-indic.cc" +#include "hb-ot-shaper-khmer.cc" +#include "hb-ot-shaper-myanmar.cc" +#include "hb-ot-shaper-syllabic.cc" +#include "hb-ot-shaper-thai.cc" +#include "hb-ot-shaper-use.cc" +#include "hb-ot-shaper-vowel-constraints.cc" #include "hb-ot-shape-fallback.cc" #include "hb-ot-shape-normalize.cc" #include "hb-ot-shape.cc" diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh index b77c1f4d449..3d053cb13e5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh @@ -123,7 +123,7 @@ struct RearrangementSubtable bool reverse_l = 3 == (m >> 4); bool reverse_r = 3 == (m & 0x0F); - if (end - start >= l + r) + if (end - start >= l + r && end-start <= HB_MAX_CONTEXT_LENGTH) { buffer->merge_clusters (start, hb_min (buffer->idx + 1, buffer->len)); buffer->merge_clusters (start, end); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh index 05b4df52f15..f1633d886a7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh @@ -59,7 +59,7 @@ static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ - static inline constexpr T operator ~ (T r) { return T (~(unsigned int) r); } \ + static inline constexpr unsigned operator ~ (T r) { return (~(unsigned) r); } \ static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ @@ -227,31 +227,26 @@ struct } HB_FUNCOBJ (hb_bool); -template <typename T> -static inline -constexpr T hb_coerce (const T v) { return v; } -template <typename T, typename V, - hb_enable_if (!hb_is_same (hb_decay<T>, hb_decay<V>) && std::is_pointer<V>::value)> -static inline -constexpr T hb_coerce (const V v) { return *v; } - struct { private: template <typename T> constexpr auto - impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) + impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) - template <typename T> constexpr auto - impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v))) + template <typename T> constexpr uint32_t + impl (const hb::shared_ptr<T>& v, hb_priority<1>) const + { + return v.get () ? v.get ()->hash () : 0; + } + template <typename T> constexpr uint32_t + impl (const hb::unique_ptr<T>& v, hb_priority<1>) const + { + return v.get () ? v.get ()->hash () : 0; + } - template <typename T, - hb_enable_if (std::is_integral<T>::value)> constexpr auto - impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN - ( - /* Knuth's multiplicative method: */ - (uint32_t) v * 2654435761u - ) + template <typename T> constexpr auto + impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v))) public: @@ -862,6 +857,11 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) { return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3); } +template <typename T> static inline bool +hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3, T lo4, T hi4) +{ + return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3) || hb_in_range (u, lo4, hi4); +} /* diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh index 1963698cf7f..5baeb6f7fef 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh @@ -56,7 +56,6 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> hb_array_t& operator= (const hb_array_t&) = default; hb_array_t& operator= (hb_array_t&&) = default; - constexpr hb_array_t (std::nullptr_t) : hb_array_t () {} constexpr hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} template <unsigned int length_> constexpr hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {} @@ -314,7 +313,6 @@ struct hb_sorted_array_t : hb_sorted_array_t& operator= (const hb_sorted_array_t&) = default; hb_sorted_array_t& operator= (hb_sorted_array_t&&) = default; - constexpr hb_sorted_array_t (std::nullptr_t) : hb_sorted_array_t () {} constexpr hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {} template <unsigned int length_> constexpr hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh index 5b313bf59c7..8e8c988716d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh @@ -54,17 +54,18 @@ struct hb_bimap_t if (unlikely (rhs == HB_MAP_VALUE_INVALID)) { del (lhs); return; } forw_map.set (lhs, rhs); - if (in_error ()) return; + if (unlikely (in_error ())) return; back_map.set (rhs, lhs); - if (in_error ()) forw_map.del (lhs); + if (unlikely (in_error ())) forw_map.del (lhs); } hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); } hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map.get (rhs); } hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); } - bool has (hb_codepoint_t lhs, hb_codepoint_t *vp = nullptr) const { return forw_map.has (lhs, vp); } + bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); } + void del (hb_codepoint_t lhs) { @@ -78,7 +79,7 @@ struct hb_bimap_t back_map.clear (); } - bool is_empty () const { return get_population () == 0; } + bool is_empty () const { return forw_map.is_empty (); } unsigned int get_population () const { return forw_map.get_population (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh index caea47d8d3f..27fb0732eab 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh @@ -80,7 +80,7 @@ struct hb_bit_set_invertible_t next (&v); return v == INVALID; } - uint32_t hash () const { return s.hash () ^ inverted; } + uint32_t hash () const { return s.hash () ^ (uint32_t) inverted; } hb_codepoint_t get_min () const { @@ -100,7 +100,7 @@ struct hb_bit_set_invertible_t void add (hb_codepoint_t g) { unlikely (inverted) ? s.del (g) : s.add (g); } bool add_range (hb_codepoint_t a, hb_codepoint_t b) - { return unlikely (inverted) ? (s.del_range (a, b), true) : s.add_range (a, b); } + { return unlikely (inverted) ? ((void) s.del_range (a, b), true) : s.add_range (a, b); } template <typename T> void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh index 11a4359dc90..438fb66a2cd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh @@ -56,7 +56,7 @@ struct hb_bit_set_t { successful = true; population = 0; - last_page_lookup = 0; + last_page_lookup.set_relaxed (0); page_map.init (); pages.init (); } @@ -78,7 +78,7 @@ struct hb_bit_set_t bool successful = true; /* Allocations successful */ mutable unsigned int population = 0; - mutable unsigned int last_page_lookup = 0; + mutable hb_atomic_int_t last_page_lookup = 0; hb_sorted_vector_t<page_map_t> page_map; hb_vector_t<page_t> pages; @@ -607,7 +607,7 @@ struct hb_bit_set_t const auto* page_map_array = page_map.arrayZ; unsigned int major = get_major (*codepoint); - unsigned int i = last_page_lookup; + unsigned int i = last_page_lookup.get_relaxed (); if (unlikely (i >= page_map.length || page_map_array[i].major != major)) { @@ -625,7 +625,7 @@ struct hb_bit_set_t if (pages_array[current.index].next (codepoint)) { *codepoint += current.major * page_t::PAGE_BITS; - last_page_lookup = i; + last_page_lookup.set_relaxed (i); return true; } i++; @@ -638,11 +638,11 @@ struct hb_bit_set_t if (m != INVALID) { *codepoint = current.major * page_t::PAGE_BITS + m; - last_page_lookup = i; + last_page_lookup.set_relaxed (i); return true; } } - last_page_lookup = 0; + last_page_lookup.set_relaxed (0); *codepoint = INVALID; return false; } @@ -725,7 +725,7 @@ struct hb_bit_set_t { const auto* page_map_array = page_map.arrayZ; unsigned int major = get_major (codepoint); - unsigned int i = last_page_lookup; + unsigned int i = last_page_lookup.get_relaxed (); if (unlikely (i >= page_map.length || page_map_array[i].major != major)) { page_map.bfind (major, &i, HB_NOT_FOUND_STORE_CLOSEST); @@ -766,7 +766,7 @@ struct hb_bit_set_t { const auto* page_map_array = page_map.arrayZ; unsigned int major = get_major (codepoint); - unsigned int i = last_page_lookup; + unsigned int i = last_page_lookup.get_relaxed (); if (unlikely (i >= page_map.length || page_map_array[i].major != major)) { page_map.bfind(major, &i, HB_NOT_FOUND_STORE_CLOSEST); @@ -893,15 +893,15 @@ struct hb_bit_set_t /* The extra page_map length is necessary; can't just rely on vector here, * since the next check would be tricked because a null page also has * major==0, which we can't distinguish from an actualy major==0 page... */ - if (likely (last_page_lookup < page_map.length)) + unsigned i = last_page_lookup.get_relaxed (); + if (likely (i < page_map.length)) { - auto &cached_page = page_map.arrayZ[last_page_lookup]; + auto &cached_page = page_map.arrayZ[i]; if (cached_page.major == major) return &pages[cached_page.index]; } page_map_t map = {major, pages.length}; - unsigned int i; if (!page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST)) { if (!insert) @@ -917,7 +917,7 @@ struct hb_bit_set_t page_map[i] = map; } - last_page_lookup = i; + last_page_lookup.set_relaxed (i); return &pages[page_map[i].index]; } const page_t *page_for (hb_codepoint_t g) const @@ -927,19 +927,19 @@ struct hb_bit_set_t /* The extra page_map length is necessary; can't just rely on vector here, * since the next check would be tricked because a null page also has * major==0, which we can't distinguish from an actualy major==0 page... */ - if (likely (last_page_lookup < page_map.length)) + unsigned i = last_page_lookup.get_relaxed (); + if (likely (i < page_map.length)) { - auto &cached_page = page_map.arrayZ[last_page_lookup]; + auto &cached_page = page_map.arrayZ[i]; if (cached_page.major == major) return &pages[cached_page.index]; } page_map_t key = {major}; - unsigned int i; if (!page_map.bfind (key, &i)) return nullptr; - last_page_lookup = i; + last_page_lookup.set_relaxed (i); return &pages[page_map[i].index]; } page_t &page_at (unsigned int i) { return pages[page_map[i].index]; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc index 65e44c7f6a7..b561a9374e3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc @@ -369,7 +369,7 @@ hb_blob_get_length (hb_blob_t *blob) * * Fetches the data from a blob. * - * Returns: (transfer none) (array length=length): the byte data of @blob. + * Returns: (nullable) (transfer none) (array length=length): the byte data of @blob. * * Since: 0.9.2 **/ @@ -572,7 +572,7 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file) strncpy (rsrc_name, file_name, name_len); strncpy (rsrc_name + name_len, _PATH_RSRCFORKSPEC, - sizeof (_PATH_RSRCFORKSPEC) - 1); + sizeof (_PATH_RSRCFORKSPEC)); int fd = open (rsrc_name, O_RDONLY | O_BINARY, 0); hb_free (rsrc_name); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc index 6539b89640a..3f619a113e8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc @@ -31,7 +31,7 @@ #include "hb-buffer.hh" -static const char *serialize_formats[] = { +static const char *_hb_buffer_serialize_formats[] = { "text", "json", nullptr @@ -50,7 +50,7 @@ static const char *serialize_formats[] = { const char ** hb_buffer_serialize_list_formats () { - return serialize_formats; + return _hb_buffer_serialize_formats; } /** @@ -91,8 +91,8 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) { switch ((unsigned) format) { - case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0]; - case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1]; + case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return _hb_buffer_serialize_formats[0]; + case HB_BUFFER_SERIALIZE_FORMAT_JSON: return _hb_buffer_serialize_formats[1]; default: case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr; } @@ -400,9 +400,9 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. * @font: (nullable): the #hb_font_t used to shape this buffer, needed to - * read glyph names and extents. If %NULL, and empty font will be used. + * read glyph names and extents. If %NULL, an empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -514,7 +514,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -637,9 +637,9 @@ _hb_buffer_serialize_invalid (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. * @font: (nullable): the #hb_font_t used to shape this buffer, needed to - * read glyph names and extents. If %NULL, and empty font will be used. + * read glyph names and extents. If %NULL, an empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc index dea2c11c35e..5453e1ca94e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc @@ -102,9 +102,9 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, /* Check that breaking up shaping at safe-to-break is indeed safe. */ hb_buffer_t *fragment = hb_buffer_create_similar (buffer); - hb_buffer_set_flags (fragment, hb_buffer_get_flags (fragment) & ~HB_BUFFER_FLAG_VERIFY); + hb_buffer_set_flags (fragment, (hb_buffer_flags_t (hb_buffer_get_flags (fragment) & ~HB_BUFFER_FLAG_VERIFY))); hb_buffer_t *reconstruction = hb_buffer_create_similar (buffer); - hb_buffer_set_flags (reconstruction, hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY); + hb_buffer_set_flags (reconstruction, (hb_buffer_flags_t (hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY))); unsigned int num_glyphs; hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); @@ -169,6 +169,12 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, hb_buffer_destroy (fragment); return false; } + else if (!fragment->successful || fragment->shaping_failed) + { + hb_buffer_destroy (reconstruction); + hb_buffer_destroy (fragment); + return true; + } hb_buffer_append (reconstruction, fragment, 0, -1); start = end; @@ -238,10 +244,10 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, hb_buffer_t *fragments[2] {hb_buffer_create_similar (buffer), hb_buffer_create_similar (buffer)}; - hb_buffer_set_flags (fragments[0], hb_buffer_get_flags (fragments[0]) & ~HB_BUFFER_FLAG_VERIFY); - hb_buffer_set_flags (fragments[1], hb_buffer_get_flags (fragments[1]) & ~HB_BUFFER_FLAG_VERIFY); + hb_buffer_set_flags (fragments[0], (hb_buffer_flags_t (hb_buffer_get_flags (fragments[0]) & ~HB_BUFFER_FLAG_VERIFY))); + hb_buffer_set_flags (fragments[1], (hb_buffer_flags_t (hb_buffer_get_flags (fragments[1]) & ~HB_BUFFER_FLAG_VERIFY))); hb_buffer_t *reconstruction = hb_buffer_create_similar (buffer); - hb_buffer_set_flags (reconstruction, hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY); + hb_buffer_set_flags (reconstruction, (hb_buffer_flags_t (hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY))); hb_segment_properties_t props; hb_buffer_get_segment_properties (buffer, &props); hb_buffer_set_segment_properties (fragments[0], &props); @@ -317,12 +323,22 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, ret = false; goto out; } + else if (!fragments[0]->successful || fragments[0]->shaping_failed) + { + ret = true; + goto out; + } if (!hb_shape_full (font, fragments[1], features, num_features, shapers)) { buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment."); ret = false; goto out; } + else if (!fragments[1]->successful || fragments[1]->shaping_failed) + { + ret = true; + goto out; + } if (!forward) { @@ -402,6 +418,7 @@ hb_buffer_t::verify (hb_buffer_t *text_buffer, ret = false; if (!ret) { +#ifndef HB_NO_BUFFER_SERIALIZE unsigned len = text_buffer->len; hb_vector_t<char> bytes; if (likely (bytes.resize (len * 10 + 16))) @@ -414,6 +431,7 @@ hb_buffer_t::verify (hb_buffer_t *text_buffer, HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS); buffer_verify_error (this, font, BUFFER_VERIFY_ERROR "text was: %s.", bytes.arrayZ); } +#endif } return ret; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index 6a9ee3ccc8b..2272ecf09b5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc @@ -81,8 +81,8 @@ hb_segment_properties_equal (const hb_segment_properties_t *a, unsigned int hb_segment_properties_hash (const hb_segment_properties_t *p) { - return (unsigned int) p->direction ^ - (unsigned int) p->script ^ + return ((unsigned int) p->direction * 31 + + (unsigned int) p->script) * 31 + (intptr_t) (p->language); } @@ -289,6 +289,7 @@ hb_buffer_t::clear () props = default_props; successful = true; + shaping_failed = false; have_output = false; have_positions = false; @@ -310,6 +311,7 @@ hb_buffer_t::enter () { deallocate_var_all (); serial = 0; + shaping_failed = false; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR))) { @@ -329,6 +331,7 @@ hb_buffer_t::leave () max_ops = HB_BUFFER_MAX_OPS_DEFAULT; deallocate_var_all (); serial = 0; + // Intentionally not reseting shaping_failed, such that it can be inspected. } @@ -542,7 +545,8 @@ hb_buffer_t::delete_glyph () /* The logic here is duplicated in hb_ot_hide_default_ignorables(). */ unsigned int cluster = info[idx].cluster; - if (idx + 1 < len && cluster == info[idx + 1].cluster) + if ((idx + 1 < len && cluster == info[idx + 1].cluster) || + (out_len && cluster == out_info[out_len - 1].cluster)) { /* Cluster survives; do nothing. */ goto done; @@ -623,6 +627,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_SEGMENT_PROPERTIES_DEFAULT, false, /* successful */ + true, /* shaping_failed */ false, /* have_output */ true /* have_positions */ @@ -631,7 +636,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = /** - * hb_buffer_create: (Xconstructor) + * hb_buffer_create: * * Creates a new #hb_buffer_t with all properties to defaults. * @@ -834,7 +839,7 @@ hb_buffer_set_content_type (hb_buffer_t *buffer, * Since: 0.9.5 **/ hb_buffer_content_type_t -hb_buffer_get_content_type (hb_buffer_t *buffer) +hb_buffer_get_content_type (const hb_buffer_t *buffer) { return buffer->content_type; } @@ -876,7 +881,7 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, * Since: 0.9.2 **/ hb_unicode_funcs_t * -hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) +hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer) { return buffer->unicode; } @@ -919,7 +924,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer, * Since: 0.9.2 **/ hb_direction_t -hb_buffer_get_direction (hb_buffer_t *buffer) +hb_buffer_get_direction (const hb_buffer_t *buffer) { return buffer->props.direction; } @@ -963,7 +968,7 @@ hb_buffer_set_script (hb_buffer_t *buffer, * Since: 0.9.2 **/ hb_script_t -hb_buffer_get_script (hb_buffer_t *buffer) +hb_buffer_get_script (const hb_buffer_t *buffer) { return buffer->props.script; } @@ -1007,7 +1012,7 @@ hb_buffer_set_language (hb_buffer_t *buffer, * Since: 0.9.2 **/ hb_language_t -hb_buffer_get_language (hb_buffer_t *buffer) +hb_buffer_get_language (const hb_buffer_t *buffer) { return buffer->props.language; } @@ -1043,7 +1048,7 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer, * Since: 0.9.7 **/ void -hb_buffer_get_segment_properties (hb_buffer_t *buffer, +hb_buffer_get_segment_properties (const hb_buffer_t *buffer, hb_segment_properties_t *props) { *props = buffer->props; @@ -1081,7 +1086,7 @@ hb_buffer_set_flags (hb_buffer_t *buffer, * Since: 0.9.7 **/ hb_buffer_flags_t -hb_buffer_get_flags (hb_buffer_t *buffer) +hb_buffer_get_flags (const hb_buffer_t *buffer) { return buffer->flags; } @@ -1120,7 +1125,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer, * Since: 0.9.42 **/ hb_buffer_cluster_level_t -hb_buffer_get_cluster_level (hb_buffer_t *buffer) +hb_buffer_get_cluster_level (const hb_buffer_t *buffer) { return buffer->cluster_level; } @@ -1161,7 +1166,7 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, * Since: 0.9.31 **/ hb_codepoint_t -hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) +hb_buffer_get_replacement_codepoint (const hb_buffer_t *buffer) { return buffer->replacement; } @@ -1201,7 +1206,7 @@ hb_buffer_set_invisible_glyph (hb_buffer_t *buffer, * Since: 2.0.0 **/ hb_codepoint_t -hb_buffer_get_invisible_glyph (hb_buffer_t *buffer) +hb_buffer_get_invisible_glyph (const hb_buffer_t *buffer) { return buffer->invisible; } @@ -1241,7 +1246,7 @@ hb_buffer_set_not_found_glyph (hb_buffer_t *buffer, * Since: 3.1.0 **/ hb_codepoint_t -hb_buffer_get_not_found_glyph (hb_buffer_t *buffer) +hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer) { return buffer->not_found; } @@ -1381,7 +1386,7 @@ hb_buffer_set_length (hb_buffer_t *buffer, * Since: 0.9.2 **/ unsigned int -hb_buffer_get_length (hb_buffer_t *buffer) +hb_buffer_get_length (const hb_buffer_t *buffer) { return buffer->len; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h index 14aaa5e1f57..22fb3496f2e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h @@ -289,7 +289,7 @@ hb_buffer_set_content_type (hb_buffer_t *buffer, hb_buffer_content_type_t content_type); HB_EXTERN hb_buffer_content_type_t -hb_buffer_get_content_type (hb_buffer_t *buffer); +hb_buffer_get_content_type (const hb_buffer_t *buffer); HB_EXTERN void @@ -297,21 +297,21 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, hb_unicode_funcs_t *unicode_funcs); HB_EXTERN hb_unicode_funcs_t * -hb_buffer_get_unicode_funcs (hb_buffer_t *buffer); +hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer); HB_EXTERN void hb_buffer_set_direction (hb_buffer_t *buffer, hb_direction_t direction); HB_EXTERN hb_direction_t -hb_buffer_get_direction (hb_buffer_t *buffer); +hb_buffer_get_direction (const hb_buffer_t *buffer); HB_EXTERN void hb_buffer_set_script (hb_buffer_t *buffer, hb_script_t script); HB_EXTERN hb_script_t -hb_buffer_get_script (hb_buffer_t *buffer); +hb_buffer_get_script (const hb_buffer_t *buffer); HB_EXTERN void hb_buffer_set_language (hb_buffer_t *buffer, @@ -319,14 +319,14 @@ hb_buffer_set_language (hb_buffer_t *buffer, HB_EXTERN hb_language_t -hb_buffer_get_language (hb_buffer_t *buffer); +hb_buffer_get_language (const hb_buffer_t *buffer); HB_EXTERN void hb_buffer_set_segment_properties (hb_buffer_t *buffer, const hb_segment_properties_t *props); HB_EXTERN void -hb_buffer_get_segment_properties (hb_buffer_t *buffer, +hb_buffer_get_segment_properties (const hb_buffer_t *buffer, hb_segment_properties_t *props); HB_EXTERN void @@ -373,6 +373,7 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer); * flag indicating that the @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT * glyph-flag should be produced by the shaper. By default * it will not be produced since it incurs a cost. Since: 4.0.0 + * @HB_BUFFER_FLAG_DEFINED: All currently defined flags: Since: 4.4.0 * * Flags for #hb_buffer_t. * @@ -386,7 +387,9 @@ typedef enum { /*< flags >*/ HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u, HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u, HB_BUFFER_FLAG_VERIFY = 0x00000020u, - HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u + HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u, + + HB_BUFFER_FLAG_DEFINED = 0x0000007Fu } hb_buffer_flags_t; HB_EXTERN void @@ -394,7 +397,7 @@ hb_buffer_set_flags (hb_buffer_t *buffer, hb_buffer_flags_t flags); HB_EXTERN hb_buffer_flags_t -hb_buffer_get_flags (hb_buffer_t *buffer); +hb_buffer_get_flags (const hb_buffer_t *buffer); /** * hb_buffer_cluster_level_t: @@ -436,7 +439,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer, hb_buffer_cluster_level_t cluster_level); HB_EXTERN hb_buffer_cluster_level_t -hb_buffer_get_cluster_level (hb_buffer_t *buffer); +hb_buffer_get_cluster_level (const hb_buffer_t *buffer); /** * HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT: @@ -453,21 +456,21 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, hb_codepoint_t replacement); HB_EXTERN hb_codepoint_t -hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer); +hb_buffer_get_replacement_codepoint (const hb_buffer_t *buffer); HB_EXTERN void hb_buffer_set_invisible_glyph (hb_buffer_t *buffer, hb_codepoint_t invisible); HB_EXTERN hb_codepoint_t -hb_buffer_get_invisible_glyph (hb_buffer_t *buffer); +hb_buffer_get_invisible_glyph (const hb_buffer_t *buffer); HB_EXTERN void hb_buffer_set_not_found_glyph (hb_buffer_t *buffer, hb_codepoint_t not_found); HB_EXTERN hb_codepoint_t -hb_buffer_get_not_found_glyph (hb_buffer_t *buffer); +hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer); /* @@ -549,7 +552,7 @@ hb_buffer_set_length (hb_buffer_t *buffer, unsigned int length); HB_EXTERN unsigned int -hb_buffer_get_length (hb_buffer_t *buffer); +hb_buffer_get_length (const hb_buffer_t *buffer); /* Getting glyphs out of the buffer */ @@ -583,6 +586,7 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer); * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS: serialize glyph flags. Since: 1.5.0 * @HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES: do not serialize glyph advances, * glyph offsets will reflect absolute glyph positions. Since: 1.8.0 + * @HB_BUFFER_SERIALIZE_FLAG_DEFINED: All currently defined flags. Since: 4.4.0 * * Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs(). * @@ -595,7 +599,9 @@ typedef enum { /*< flags >*/ HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u, HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u, HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u, - HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES = 0x00000020u + HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES = 0x00000020u, + + HB_BUFFER_SERIALIZE_FLAG_DEFINED = 0x0000003Fu } hb_buffer_serialize_flags_t; /** diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh index bc6992905e4..0f991936c1a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh @@ -57,6 +57,7 @@ static_assert ((sizeof (hb_glyph_info_t) == 20), ""); static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), ""); +HB_MARK_AS_FLAG_T (hb_glyph_flags_t); HB_MARK_AS_FLAG_T (hb_buffer_flags_t); HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t); HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t); @@ -69,12 +70,13 @@ enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u, HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u, + HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u, - /* Reserved for complex shapers' internal use. */ - HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u, - HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u, - HB_BUFFER_SCRATCH_FLAG_COMPLEX2 = 0x04000000u, - HB_BUFFER_SCRATCH_FLAG_COMPLEX3 = 0x08000000u, + /* Reserved for shapers' internal use. */ + HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u, + HB_BUFFER_SCRATCH_FLAG_SHAPER1 = 0x02000000u, + HB_BUFFER_SCRATCH_FLAG_SHAPER2 = 0x04000000u, + HB_BUFFER_SCRATCH_FLAG_SHAPER3 = 0x08000000u, }; HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t); @@ -106,6 +108,7 @@ struct hb_buffer_t hb_segment_properties_t props; /* Script, language, direction */ bool successful; /* Allocations successful */ + bool shaping_failed; /* Shaping failure */ bool have_output; /* Whether we have an output buffer going on */ bool have_positions; /* Whether we have positions */ @@ -130,9 +133,7 @@ struct hb_buffer_t * Managed by enter / leave */ -#ifndef HB_NDEBUG uint8_t allocated_var_bits; -#endif uint8_t serial; hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ @@ -161,38 +162,40 @@ struct hb_buffer_t void allocate_var (unsigned int start, unsigned int count) { -#ifndef HB_NDEBUG unsigned int end = start + count; assert (end <= 8); unsigned int bits = (1u<<end) - (1u<<start); assert (0 == (allocated_var_bits & bits)); allocated_var_bits |= bits; -#endif + } + bool try_allocate_var (unsigned int start, unsigned int count) + { + unsigned int end = start + count; + assert (end <= 8); + unsigned int bits = (1u<<end) - (1u<<start); + if (allocated_var_bits & bits) + return false; + allocated_var_bits |= bits; + return true; } void deallocate_var (unsigned int start, unsigned int count) { -#ifndef HB_NDEBUG unsigned int end = start + count; assert (end <= 8); unsigned int bits = (1u<<end) - (1u<<start); assert (bits == (allocated_var_bits & bits)); allocated_var_bits &= ~bits; -#endif } void assert_var (unsigned int start, unsigned int count) { -#ifndef HB_NDEBUG unsigned int end = start + count; assert (end <= 8); - unsigned int bits = (1u<<end) - (1u<<start); + HB_UNUSED unsigned int bits = (1u<<end) - (1u<<start); assert (bits == (allocated_var_bits & bits)); -#endif } void deallocate_var_all () { -#ifndef HB_NDEBUG allocated_var_bits = 0; -#endif } hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; } @@ -619,9 +622,10 @@ DECLARE_NULL_INSTANCE (hb_buffer_t); #define HB_BUFFER_XALLOCATE_VAR(b, func, var) \ b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \ sizeof (b->info[0].var)) -#define HB_BUFFER_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var ()) -#define HB_BUFFER_DEALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ()) -#define HB_BUFFER_ASSERT_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, assert_var, var ()) +#define HB_BUFFER_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var ()) +#define HB_BUFFER_TRY_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, try_allocate_var, var ()) +#define HB_BUFFER_DEALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ()) +#define HB_BUFFER_ASSERT_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, assert_var, var ()) #endif /* HB_BUFFER_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh index e617b75de90..d6b229ed653 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh @@ -32,7 +32,7 @@ /* Implements a lockfree cache for int->int functions. */ -template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits> +template <unsigned int key_bits=16, unsigned int value_bits=8 + 32 - key_bits, unsigned int cache_bits=8> struct hb_cache_t { static_assert ((key_bits >= cache_bits), ""); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc index 41229b9183e..7266d9b01f4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc @@ -160,7 +160,7 @@ hb_tag_to_string (hb_tag_t tag, char *buf) /* hb_direction_t */ -const char direction_strings[][4] = { +static const char direction_strings[][4] = { "ltr", "rtl", "ttb", diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh index 4b46dea9384..2578231d238 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh @@ -64,6 +64,7 @@ #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 @@ -145,10 +146,10 @@ #endif #ifdef HB_NO_OT_SHAPE_FALLBACK -#define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK -#define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK -#define HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK -#define HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS +#define HB_NO_OT_SHAPER_ARABIC_FALLBACK +#define HB_NO_OT_SHAPER_HEBREW_FALLBACK +#define HB_NO_OT_SHAPER_THAI_FALLBACK +#define HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS #endif #ifdef NDEBUG @@ -163,5 +164,9 @@ #endif #endif +#ifdef HB_OPTIMIZE_SIZE +#define HB_NO_OT_LAYOUT_LOOKUP_CACHE +#endif + #endif /* HB_CONFIG_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc index 6ccc1b0a2b9..300d1aa51ab 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc @@ -332,7 +332,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) return nullptr; } - if (font->coords) + if (font->num_coords) { CFMutableDictionaryRef variations = CFDictionaryCreateMutable (kCFAllocatorDefault, @@ -1151,7 +1151,7 @@ resize_and_retry: pos->x_offset = info->var1.i32; pos->y_offset = info->var2.i32; - info++, pos++; + info++; pos++; } else for (unsigned int i = 0; i < count; i++) @@ -1160,7 +1160,7 @@ resize_and_retry: pos->x_offset = info->var1.i32; pos->y_offset = info->var2.i32; - info++, pos++; + info++; pos++; } /* Fix up clusters so that we never return out-of-order indices; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh new file mode 100644 index 00000000000..86d04520800 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh @@ -0,0 +1,192 @@ +/* + * 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_CPLUSPLUS_HH +#define HB_CPLUSPLUS_HH + +#include "hb.h" + +HB_BEGIN_DECLS +HB_END_DECLS + +#ifdef __cplusplus + +#include <functional> +#include <utility> + +#if 0 +#if !(__cplusplus >= 201103L) +#error "HarfBuzz C++ helpers require C++11" +#endif +#endif + +namespace hb { + + +template <typename T> +struct vtable; + +template <typename T> +struct shared_ptr +{ + using element_type = T; + + using v = vtable<T>; + + 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& 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 () { 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); } + + operator T * () const { return p; } + T& operator * () const { return *get (); } + T* operator -> () const { return get (); } + operator bool () { return p; } + bool operator == (const shared_ptr &o) { return p == o.p; } + bool operator != (const shared_ptr &o) { return p != o.p; } + + static T* get_empty() { return v::get_empty (); } + T* reference() { return v::reference (p); } + void destroy() { v::destroy (p); } + void set_user_data (hb_user_data_key_t *key, + void *value, + hb_destroy_func_t destroy, + hb_bool_t replace) { v::set_user_data (p, key, value, destroy, replace); } + void * get_user_data (hb_user_data_key_t *key) { return v::get_user_data (p, key); } + + private: + T *p; +}; + +template<typename T> struct is_shared_ptr : std::false_type {}; +template<typename T> struct is_shared_ptr<shared_ptr<T>> : std::true_type {}; + +template <typename T> +struct unique_ptr +{ + using element_type = T; + + using v = vtable<T>; + + 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& 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 () { 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); } + + operator T * () const { return p; } + T& operator * () const { return *get (); } + T* operator -> () const { return get (); } + operator bool () { return p; } + + private: + T *p; +}; + +template<typename T> struct is_unique_ptr : std::false_type {}; +template<typename T> struct is_unique_ptr<unique_ptr<T>> : std::true_type {}; + +template <typename T, + T * (*_get_empty) (void), + T * (*_reference) (T *), + void (*_destroy) (T *), + hb_bool_t (*_set_user_data) (T *, + hb_user_data_key_t *, + void *, + hb_destroy_func_t, + hb_bool_t), + void * (*_get_user_data) (T *, + hb_user_data_key_t *)> +struct vtable_t +{ + static constexpr auto get_empty = _get_empty; + static constexpr auto reference = _reference; + static constexpr auto destroy = _destroy; + static constexpr auto set_user_data = _set_user_data; + static constexpr auto get_user_data = _get_user_data; +}; + +#define HB_DEFINE_VTABLE(name) \ + template<> \ + struct vtable<hb_##name##_t> \ + : vtable_t<hb_##name##_t, \ + &hb_##name##_get_empty, \ + &hb_##name##_reference, \ + &hb_##name##_destroy, \ + &hb_##name##_set_user_data, \ + &hb_##name##_get_user_data> {} + +HB_DEFINE_VTABLE (buffer); +HB_DEFINE_VTABLE (blob); +HB_DEFINE_VTABLE (face); +HB_DEFINE_VTABLE (font); +HB_DEFINE_VTABLE (font_funcs); +HB_DEFINE_VTABLE (map); +HB_DEFINE_VTABLE (set); +HB_DEFINE_VTABLE (shape_plan); +HB_DEFINE_VTABLE (unicode_funcs); + +#undef HB_DEFINE_VTABLE + + +} // namespace hb + +template<typename T> +struct std::hash<hb::shared_ptr<T>> +{ + std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept + { + std::size_t h = std::hash<decltype (v.get ())>{}(v.get ()); + return h; + } +}; + +template<typename T> +struct std::hash<hb::unique_ptr<T>> +{ + std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept + { + std::size_t h = std::hash<decltype (v.get ())>{}(v.get ()); + return h; + } +}; + + +#endif /* __cplusplus */ + +#endif /* HB_CPLUSPLUS_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc index b31019b07e0..fdc71102d64 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc @@ -56,12 +56,14 @@ hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data, float to_x, float to_y, void *user_data HB_UNUSED) { +#define HB_ONE_THIRD 0.33333333f dfuncs->emit_cubic_to (draw_data, *st, - (st->current_x + 2.f * control_x) / 3.f, - (st->current_y + 2.f * control_y) / 3.f, - (to_x + 2.f * control_x) / 3.f, - (to_y + 2.f * control_y) / 3.f, + (st->current_x + 2.f * control_x) * HB_ONE_THIRD, + (st->current_y + 2.f * control_y) * HB_ONE_THIRD, + (to_x + 2.f * control_x) * HB_ONE_THIRD, + (to_y + 2.f * control_y) * HB_ONE_THIRD, to_x, to_y); +#undef HB_ONE_THIRD } static void @@ -89,25 +91,46 @@ hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \ if (hb_object_is_immutable (dfuncs)) \ return; \ \ - if (dfuncs->destroy.name) \ - dfuncs->destroy.name (dfuncs->user_data.name); \ - \ - if (func) { \ - dfuncs->func.name = func; \ - dfuncs->user_data.name = user_data; \ - dfuncs->destroy.name = destroy; \ - } else { \ - dfuncs->func.name = hb_draw_##name##_nil; \ - dfuncs->user_data.name = nullptr; \ - dfuncs->destroy.name = nullptr; \ - } \ + if (dfuncs->destroy && dfuncs->destroy->name) \ + dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \ + \ + if (user_data && !dfuncs->user_data) \ + { \ + dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); \ + if (unlikely (!dfuncs->user_data)) \ + goto fail; \ + } \ + if (destroy && !dfuncs->destroy) \ + { \ + dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); \ + if (unlikely (!dfuncs->destroy)) \ + goto fail; \ + } \ + \ + if (func) { \ + dfuncs->func.name = func; \ + if (dfuncs->user_data) \ + dfuncs->user_data->name = user_data; \ + if (dfuncs->destroy) \ + dfuncs->destroy->name = destroy; \ + } else { \ + dfuncs->func.name = hb_draw_##name##_nil; \ + if (dfuncs->user_data) \ + dfuncs->user_data->name = nullptr; \ + if (dfuncs->destroy) \ + dfuncs->destroy->name = nullptr; \ + } \ + \ +fail: \ + if (destroy) \ + destroy (user_data); \ } HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS #undef HB_DRAW_FUNC_IMPLEMENT /** - * hb_draw_funcs_create: (Xconstructor) + * hb_draw_funcs_create: * * Creates a new draw callbacks object. * @@ -177,11 +200,13 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs) { if (!hb_object_destroy (dfuncs)) return; + if (dfuncs->destroy) + { #define HB_DRAW_FUNC_IMPLEMENT(name) \ - if (dfuncs->destroy.name) dfuncs->destroy.name (dfuncs->user_data.name); - HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS + if (dfuncs->destroy->name) dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); + HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS #undef HB_DRAW_FUNC_IMPLEMENT - + } hb_free (dfuncs); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh index 28bc9218e18..768f51a8756 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh @@ -54,31 +54,31 @@ struct hb_draw_funcs_t #define HB_DRAW_FUNC_IMPLEMENT(name) void *name; HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS #undef HB_DRAW_FUNC_IMPLEMENT - } user_data; + } *user_data; struct { #define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name; HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS #undef HB_DRAW_FUNC_IMPLEMENT - } destroy; + } *destroy; void emit_move_to (void *draw_data, hb_draw_state_t &st, float to_x, float to_y) { func.move_to (this, draw_data, &st, to_x, to_y, - user_data.move_to); } + !user_data ? nullptr : user_data->move_to); } void emit_line_to (void *draw_data, hb_draw_state_t &st, float to_x, float to_y) { func.line_to (this, draw_data, &st, to_x, to_y, - user_data.line_to); } + !user_data ? nullptr : user_data->line_to); } void emit_quadratic_to (void *draw_data, hb_draw_state_t &st, float control_x, float control_y, float to_x, float to_y) { func.quadratic_to (this, draw_data, &st, control_x, control_y, to_x, to_y, - user_data.quadratic_to); } + !user_data ? nullptr : user_data->quadratic_to); } void emit_cubic_to (void *draw_data, hb_draw_state_t &st, float control1_x, float control1_y, float control2_x, float control2_y, @@ -87,10 +87,10 @@ struct hb_draw_funcs_t control1_x, control1_y, control2_x, control2_y, to_x, to_y, - user_data.cubic_to); } + !user_data ? nullptr : user_data->cubic_to); } void emit_close_path (void *draw_data, hb_draw_state_t &st) { func.close_path (this, draw_data, &st, - user_data.close_path); } + !user_data ? nullptr : user_data->close_path); } void move_to (void *draw_data, hb_draw_state_t &st, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index 5365598636f..7cdd6cb49fb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc @@ -190,7 +190,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void } /** - * hb_face_create: (Xconstructor) + * hb_face_create: * @blob: #hb_blob_t to work upon * @index: The index of the face within @blob * @@ -342,7 +342,7 @@ hb_face_set_user_data (hb_face_t *face, * Since: 0.9.2 **/ void * -hb_face_get_user_data (const hb_face_t *face, +hb_face_get_user_data (hb_face_t *face, hb_user_data_key_t *key) { return hb_object_get_user_data (face, key); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h index 6ef2f8b8861..3b7477a76c0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h @@ -96,7 +96,7 @@ hb_face_set_user_data (hb_face_t *face, hb_bool_t replace); HB_EXTERN void * -hb_face_get_user_data (const hb_face_t *face, +hb_face_get_user_data (hb_face_t *face, hb_user_data_key_t *key); HB_EXTERN void diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc index 5700e06271c..51c55a6c967 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc @@ -636,16 +636,8 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) = { HB_OBJECT_HEADER_STATIC, - { -#define HB_FONT_FUNC_IMPLEMENT(name) nullptr, - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_FONT_FUNC_IMPLEMENT - }, - { -#define HB_FONT_FUNC_IMPLEMENT(name) nullptr, - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_FONT_FUNC_IMPLEMENT - }, + nullptr, + nullptr, { { #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, @@ -658,16 +650,8 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) = static const hb_font_funcs_t _hb_font_funcs_default = { HB_OBJECT_HEADER_STATIC, - { -#define HB_FONT_FUNC_IMPLEMENT(name) nullptr, - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_FONT_FUNC_IMPLEMENT - }, - { -#define HB_FONT_FUNC_IMPLEMENT(name) nullptr, - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_FONT_FUNC_IMPLEMENT - }, + nullptr, + nullptr, { { #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default, @@ -679,7 +663,7 @@ static const hb_font_funcs_t _hb_font_funcs_default = { /** - * hb_font_funcs_create: (Xconstructor) + * hb_font_funcs_create: * * Creates a new #hb_font_funcs_t structure of font functions. * @@ -746,10 +730,16 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) { if (!hb_object_destroy (ffuncs)) return; -#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ - ffuncs->destroy.name (ffuncs->user_data.name); - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS + if (ffuncs->destroy) + { +#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy->name) \ + ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT + } + + hb_free (ffuncs->destroy); + hb_free (ffuncs->user_data); hb_free (ffuncs); } @@ -841,24 +831,50 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ hb_destroy_func_t destroy) \ { \ if (hb_object_is_immutable (ffuncs)) \ + goto fail; \ + \ + if (!func) \ { \ if (destroy) \ destroy (user_data); \ - return; \ + destroy = nullptr; \ + user_data = nullptr; \ } \ \ - if (ffuncs->destroy.name) \ - ffuncs->destroy.name (ffuncs->user_data.name); \ + if (ffuncs->destroy && ffuncs->destroy->name) \ + ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \ + \ + if (user_data && !ffuncs->user_data) \ + { \ + ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); \ + if (unlikely (!ffuncs->user_data)) \ + goto fail; \ + } \ + if (destroy && !ffuncs->destroy) \ + { \ + ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); \ + if (unlikely (!ffuncs->destroy)) \ + goto fail; \ + } \ \ if (func) { \ ffuncs->get.f.name = func; \ - ffuncs->user_data.name = user_data; \ - ffuncs->destroy.name = destroy; \ + if (ffuncs->user_data) \ + ffuncs->user_data->name = user_data; \ + if (ffuncs->destroy) \ + ffuncs->destroy->name = destroy; \ } else { \ ffuncs->get.f.name = hb_font_get_##name##_default; \ - ffuncs->user_data.name = nullptr; \ - ffuncs->destroy.name = nullptr; \ + if (ffuncs->user_data) \ + ffuncs->user_data->name = nullptr; \ + if (ffuncs->destroy) \ + ffuncs->destroy->name = nullptr; \ } \ + return; \ + \ +fail: \ + if (destroy) \ + destroy (user_data); \ } HB_FONT_FUNCS_IMPLEMENT_CALLBACKS @@ -1623,6 +1639,9 @@ DEFINE_NULL_INSTANCE (hb_font_t) = { HB_OBJECT_HEADER_STATIC, + 0, /* serial */ + 0, /* serial_coords */ + nullptr, /* parent */ const_cast<hb_face_t *> (&_hb_Null_hb_face_t), @@ -1630,6 +1649,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 1000, /* y_scale */ 0., /* slant */ 0., /* slant_xy; */ + 1.f, /* x_multf */ + 1.f, /* y_multf */ 1<<16, /* x_mult */ 1<<16, /* y_mult */ @@ -1662,14 +1683,15 @@ _hb_font_create (hb_face_t *face) font->face = hb_face_reference (face); font->klass = hb_font_funcs_get_empty (); font->data.init0 (font); - font->x_scale = font->y_scale = hb_face_get_upem (face); + font->x_scale = font->y_scale = face->get_upem (); + font->x_multf = font->y_multf = 1.f; font->x_mult = font->y_mult = 1 << 16; return font; } /** - * hb_font_create: (Xconstructor) + * hb_font_create: * @face: a face. * * Constructs a new font object from the specified face. @@ -1852,6 +1874,9 @@ hb_font_set_user_data (hb_font_t *font, hb_destroy_func_t destroy /* May be NULL. */, hb_bool_t replace) { + if (!hb_object_is_immutable (font)) + font->serial++; + return hb_object_set_user_data (font, key, data, destroy, replace); } @@ -1911,6 +1936,45 @@ hb_font_is_immutable (hb_font_t *font) } /** + * hb_font_get_serial: + * @font: #hb_font_t to work upon + * + * Returns the internal serial number of the font. The serial + * number is increased every time a setting on the font is + * changed, using a setter function. + * + * Return value: serial number + * + * Since: 4.4.0. + **/ +unsigned int +hb_font_get_serial (hb_font_t *font) +{ + return font->serial; +} + +/** + * hb_font_changed: + * @font: #hb_font_t to work upon + * + * Notifies the @font that underlying font data has changed. + * This has the effect of increasing the serial as returned + * by hb_font_get_serial(), which invalidates internal caches. + * + * Since: 4.4.0. + **/ +void +hb_font_changed (hb_font_t *font) +{ + if (hb_object_is_immutable (font)) + return; + + font->serial++; + + font->mults_changed (); +} + +/** * hb_font_set_parent: * @font: #hb_font_t to work upon * @parent: The parent font object to assign @@ -1926,6 +1990,11 @@ hb_font_set_parent (hb_font_t *font, if (hb_object_is_immutable (font)) return; + if (parent == font->parent) + return; + + font->serial++; + if (!parent) parent = hb_font_get_empty (); @@ -1968,6 +2037,11 @@ hb_font_set_face (hb_font_t *font, if (hb_object_is_immutable (font)) return; + if (face == font->face) + return; + + font->serial++; + if (unlikely (!face)) face = hb_face_get_empty (); @@ -2022,6 +2096,8 @@ hb_font_set_funcs (hb_font_t *font, return; } + font->serial++; + if (font->destroy) font->destroy (font->user_data); @@ -2059,6 +2135,8 @@ hb_font_set_funcs_data (hb_font_t *font, return; } + font->serial++; + if (font->destroy) font->destroy (font->user_data); @@ -2085,6 +2163,11 @@ hb_font_set_scale (hb_font_t *font, if (hb_object_is_immutable (font)) return; + if (font->x_scale == x_scale && font->y_scale == y_scale) + return; + + font->serial++; + font->x_scale = x_scale; font->y_scale = y_scale; font->mults_changed (); @@ -2127,6 +2210,11 @@ hb_font_set_ppem (hb_font_t *font, if (hb_object_is_immutable (font)) return; + if (font->x_ppem == x_ppem && font->y_ppem == y_ppem) + return; + + font->serial++; + font->x_ppem = x_ppem; font->y_ppem = y_ppem; } @@ -2169,6 +2257,11 @@ hb_font_set_ptem (hb_font_t *font, if (hb_object_is_immutable (font)) return; + if (font->ptem == ptem) + return; + + font->serial++; + font->ptem = ptem; } @@ -2216,6 +2309,11 @@ hb_font_set_synthetic_slant (hb_font_t *font, float slant) if (hb_object_is_immutable (font)) return; + if (font->slant == slant) + return; + + font->serial++; + font->slant = slant; font->mults_changed (); } @@ -2263,6 +2361,8 @@ hb_font_set_variations (hb_font_t *font, if (hb_object_is_immutable (font)) return; + font->serial_coords = ++font->serial; + if (!variations_length) { hb_font_set_var_coords_normalized (font, nullptr, 0); @@ -2322,6 +2422,8 @@ hb_font_set_var_coords_design (hb_font_t *font, if (hb_object_is_immutable (font)) return; + font->serial_coords = ++font->serial; + int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; @@ -2355,6 +2457,8 @@ hb_font_set_var_named_instance (hb_font_t *font, if (hb_object_is_immutable (font)) return; + font->serial_coords = ++font->serial; + unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr); float *coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; @@ -2391,6 +2495,8 @@ hb_font_set_var_coords_normalized (hb_font_t *font, if (hb_object_is_immutable (font)) return; + font->serial_coords = ++font->serial; + int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h index 95488575354..ca6ecf79634 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h @@ -1002,6 +1002,12 @@ hb_font_make_immutable (hb_font_t *font); HB_EXTERN hb_bool_t hb_font_is_immutable (hb_font_t *font); +HB_EXTERN unsigned int +hb_font_get_serial (hb_font_t *font); + +HB_EXTERN void +hb_font_changed (hb_font_t *font); + HB_EXTERN void hb_font_set_parent (hb_font_t *font, hb_font_t *parent); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh index 70311b4a85d..452927ef604 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh @@ -68,13 +68,13 @@ struct hb_font_funcs_t #define HB_FONT_FUNC_IMPLEMENT(name) void *name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT - } user_data; + } *user_data; struct { #define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT - } destroy; + } *destroy; /* Don't access these directly. Call font->get_*() instead. */ union get_t { @@ -104,6 +104,8 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t); struct hb_font_t { hb_object_header_t header; + unsigned int serial; + unsigned int serial_coords; hb_font_t *parent; hb_face_t *face; @@ -112,6 +114,8 @@ struct hb_font_t int32_t y_scale; float slant; float slant_xy; + float x_multf; + float y_multf; int64_t x_mult; int64_t y_mult; @@ -137,12 +141,12 @@ struct hb_font_t { return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; } hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); } hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); } - hb_position_t em_scalef_x (float v) { return em_scalef (v, x_scale); } - hb_position_t em_scalef_y (float v) { return em_scalef (v, y_scale); } - float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); } - float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); } - float em_fscalef_x (float v) { return em_fscalef (v, x_scale); } - float em_fscalef_y (float v) { return em_fscalef (v, y_scale); } + hb_position_t em_scalef_x (float v) { return em_multf (v, x_multf); } + hb_position_t em_scalef_y (float v) { return em_multf (v, y_multf); } + float em_fscale_x (int16_t v) { return em_fmult (v, x_multf); } + float em_fscale_y (int16_t v) { return em_fmult (v, y_multf); } + float em_fscalef_x (float v) { return em_fmultf (v, x_multf); } + float em_fscalef_y (float v) { return em_fmultf (v, y_multf); } hb_position_t em_scale_dir (int16_t v, hb_direction_t direction) { return em_mult (v, dir_mult (direction)); } @@ -205,14 +209,14 @@ struct hb_font_t memset (extents, 0, sizeof (*extents)); return klass->get.f.font_h_extents (this, user_data, extents, - klass->user_data.font_h_extents); + !klass->user_data ? nullptr : klass->user_data->font_h_extents); } hb_bool_t get_font_v_extents (hb_font_extents_t *extents) { memset (extents, 0, sizeof (*extents)); return klass->get.f.font_v_extents (this, user_data, extents, - klass->user_data.font_v_extents); + !klass->user_data ? nullptr : klass->user_data->font_v_extents); } bool has_glyph (hb_codepoint_t unicode) @@ -228,7 +232,7 @@ struct hb_font_t *glyph = not_found; return klass->get.f.nominal_glyph (this, user_data, unicode, glyph, - klass->user_data.nominal_glyph); + !klass->user_data ? nullptr : klass->user_data->nominal_glyph); } unsigned int get_nominal_glyphs (unsigned int count, const hb_codepoint_t *first_unicode, @@ -240,7 +244,7 @@ struct hb_font_t count, first_unicode, unicode_stride, first_glyph, glyph_stride, - klass->user_data.nominal_glyphs); + !klass->user_data ? nullptr : klass->user_data->nominal_glyphs); } hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, @@ -250,21 +254,21 @@ struct hb_font_t *glyph = not_found; return klass->get.f.variation_glyph (this, user_data, unicode, variation_selector, glyph, - klass->user_data.variation_glyph); + !klass->user_data ? nullptr : klass->user_data->variation_glyph); } hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) { return klass->get.f.glyph_h_advance (this, user_data, glyph, - klass->user_data.glyph_h_advance); + !klass->user_data ? nullptr : klass->user_data->glyph_h_advance); } hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) { return klass->get.f.glyph_v_advance (this, user_data, glyph, - klass->user_data.glyph_v_advance); + !klass->user_data ? nullptr : klass->user_data->glyph_v_advance); } void get_glyph_h_advances (unsigned int count, @@ -277,7 +281,7 @@ struct hb_font_t count, first_glyph, glyph_stride, first_advance, advance_stride, - klass->user_data.glyph_h_advances); + !klass->user_data ? nullptr : klass->user_data->glyph_h_advances); } void get_glyph_v_advances (unsigned int count, @@ -290,7 +294,7 @@ struct hb_font_t count, first_glyph, glyph_stride, first_advance, advance_stride, - klass->user_data.glyph_v_advances); + !klass->user_data ? nullptr : klass->user_data->glyph_v_advances); } hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, @@ -299,7 +303,7 @@ struct hb_font_t *x = *y = 0; return klass->get.f.glyph_h_origin (this, user_data, glyph, x, y, - klass->user_data.glyph_h_origin); + !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); } hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, @@ -308,7 +312,7 @@ struct hb_font_t *x = *y = 0; return klass->get.f.glyph_v_origin (this, user_data, glyph, x, y, - klass->user_data.glyph_v_origin); + !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); } hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, @@ -319,7 +323,7 @@ struct hb_font_t #else return klass->get.f.glyph_h_kerning (this, user_data, left_glyph, right_glyph, - klass->user_data.glyph_h_kerning); + !klass->user_data ? nullptr : klass->user_data->glyph_h_kerning); #endif } @@ -331,7 +335,7 @@ struct hb_font_t #else return klass->get.f.glyph_v_kerning (this, user_data, top_glyph, bottom_glyph, - klass->user_data.glyph_v_kerning); + !klass->user_data ? nullptr : klass->user_data->glyph_v_kerning); #endif } @@ -342,7 +346,7 @@ struct hb_font_t return klass->get.f.glyph_extents (this, user_data, glyph, extents, - klass->user_data.glyph_extents); + !klass->user_data ? nullptr : klass->user_data->glyph_extents); } hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, @@ -352,7 +356,7 @@ struct hb_font_t return klass->get.f.glyph_contour_point (this, user_data, glyph, point_index, x, y, - klass->user_data.glyph_contour_point); + !klass->user_data ? nullptr : klass->user_data->glyph_contour_point); } hb_bool_t get_glyph_name (hb_codepoint_t glyph, @@ -362,7 +366,7 @@ struct hb_font_t return klass->get.f.glyph_name (this, user_data, glyph, name, size, - klass->user_data.glyph_name); + !klass->user_data ? nullptr : klass->user_data->glyph_name); } hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */ @@ -373,7 +377,7 @@ struct hb_font_t return klass->get.f.glyph_from_name (this, user_data, name, len, glyph, - klass->user_data.glyph_from_name); + !klass->user_data ? nullptr : klass->user_data->glyph_from_name); } void get_glyph_shape (hb_codepoint_t glyph, @@ -382,7 +386,7 @@ struct hb_font_t klass->get.f.glyph_shape (this, user_data, glyph, draw_funcs, draw_data, - klass->user_data.glyph_shape); + !klass->user_data ? nullptr : klass->user_data->glyph_shape); } @@ -444,7 +448,6 @@ struct hb_font_t { *x = get_glyph_h_advance (glyph) / 2; - /* TODO cache this somehow?! */ hb_font_extents_t extents; get_h_extents_with_fallback (&extents); *y = extents.ascender; @@ -628,20 +631,24 @@ struct hb_font_t void mults_changed () { - signed upem = face->get_upem (); - x_mult = ((int64_t) x_scale << 16) / upem; - y_mult = ((int64_t) y_scale << 16) / upem; + float upem = face->get_upem (); + x_multf = x_scale / upem; + y_multf = y_scale / upem; + bool x_neg = x_scale < 0; + x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem; + bool y_neg = y_scale < 0; + y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; slant_xy = y_scale ? slant * x_scale / y_scale : 0.f; } hb_position_t em_mult (int16_t v, int64_t mult) { return (hb_position_t) ((v * mult + 32768) >> 16); } - hb_position_t em_scalef (float v, int scale) - { return (hb_position_t) roundf (em_fscalef (v, scale)); } - float em_fscalef (float v, int scale) - { return v * scale / face->get_upem (); } - float em_fscale (int16_t v, int scale) - { return (float) v * scale / face->get_upem (); } + hb_position_t em_multf (float v, float mult) + { return (hb_position_t) roundf (em_fmultf (v, mult)); } + float em_fmultf (float v, float mult) + { return v * mult; } + float em_fmult (int16_t v, float mult) + { return (float) v * mult; } }; DECLARE_NULL_INSTANCE (hb_font_t); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc index d3c5d3db93a..b526a828657 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -37,6 +37,8 @@ #include "hb-font.hh" #include "hb-machinery.hh" #include "hb-cache.hh" +#include "hb-ot-os2-table.hh" +#include "hb-ot-shaper-arabic-pua.hh" #include FT_ADVANCES_H #include FT_MULTIPLE_MASTERS_H @@ -86,7 +88,7 @@ struct hb_ft_font_t mutable hb_mutex_t lock; FT_Face ft_face; - mutable int cached_x_scale; + mutable unsigned cached_serial; mutable hb_advance_cache_t advance_cache; }; @@ -103,7 +105,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; - ft_font->cached_x_scale = 0; + ft_font->cached_serial = (unsigned) -1; ft_font->advance_cache.init (); return ft_font; @@ -130,6 +132,58 @@ _hb_ft_font_destroy (void *data) hb_free (ft_font); } + +/* hb_font changed, update FT_Face. */ +static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) +{ + + FT_Set_Char_Size (ft_face, + abs (font->x_scale), abs (font->y_scale), + 0, 0); +#if 0 + font->x_ppem * 72 * 64 / font->x_scale, + font->y_ppem * 72 * 64 / font->y_scale); +#endif + if (font->x_scale < 0 || font->y_scale < 0) + { + FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, + 0, font->y_scale < 0 ? -1 : +1}; + FT_Set_Transform (ft_face, &matrix, nullptr); + } + +#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) + unsigned int num_coords; + const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); + if (num_coords) + { + FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); + if (ft_coords) + { + for (unsigned int i = 0; i < num_coords; i++) + ft_coords[i] = coords[i] * 4; + FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); + hb_free (ft_coords); + } + } +#endif +} + +/* Check if hb_font changed, update FT_Face. */ +static inline bool +_hb_ft_hb_font_check_changed (hb_font_t *font, + const hb_ft_font_t *ft_font) +{ + if (font->serial != ft_font->cached_serial) + { + _hb_ft_hb_font_changed (font, ft_font->ft_face); + ft_font->advance_cache.clear (); + ft_font->cached_serial = font->serial; + return true; + } + return false; +} + + /** * hb_ft_font_set_load_flags: * @font: #hb_font_t to work upon @@ -181,7 +235,7 @@ hb_ft_font_get_load_flags (hb_font_t *font) } /** - * hb_ft_font_get_face: + * hb_ft_font_get_face: (skip) * @font: #hb_font_t to work upon * * Fetches the FT_Face associated with the specified #hb_font_t @@ -203,7 +257,7 @@ hb_ft_font_get_face (hb_font_t *font) } /** - * hb_ft_font_lock_face: + * hb_ft_font_lock_face: (skip) * @font: #hb_font_t to work upon * * Gets the FT_Face associated with @font, This face will be kept around until @@ -246,7 +300,7 @@ hb_ft_font_unlock_face (hb_font_t *font) static hb_bool_t -hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, +hb_ft_get_nominal_glyph (hb_font_t *font, void *font_data, hb_codepoint_t unicode, hb_codepoint_t *glyph, @@ -258,14 +312,29 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, if (unlikely (!g)) { - if (unlikely (ft_font->symbol) && unicode <= 0x00FFu) + if (unlikely (ft_font->symbol)) { - /* For symbol-encoded OpenType fonts, we duplicate the - * U+F000..F0FF range at U+0000..U+00FF. That's what - * Windows seems to do, and that's hinted about at: - * https://docs.microsoft.com/en-us/typography/opentype/spec/recom - * under "Non-Standard (Symbol) Fonts". */ - g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode); + switch ((unsigned) font->face->table.OS2->get_font_page ()) { + case OT::OS2::font_page_t::FONT_PAGE_NONE: + if (unicode <= 0x00FFu) + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * https://docs.microsoft.com/en-us/typography/opentype/spec/recom + * under "Non-Standard (Symbol) Fonts". */ + g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode); + break; +#ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK + case OT::OS2::font_page_t::FONT_PAGE_SIMP_ARABIC: + g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_simp_map (unicode)); + break; + case OT::OS2::font_page_t::FONT_PAGE_TRAD_ARABIC: + g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_trad_map (unicode)); + break; +#endif + default: + break; + } if (!g) return false; } @@ -337,12 +406,6 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, int load_flags = ft_font->load_flags; int mult = font->x_scale < 0 ? -1 : +1; - if (font->x_scale != ft_font->cached_x_scale) - { - ft_font->advance_cache.clear (); - ft_font->cached_x_scale = font->x_scale; - } - for (unsigned int i = 0; i < count; i++) { FT_Fixed v = 0; @@ -426,6 +489,7 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + hb_lock_t lock (ft_font->lock); FT_Vector kerningv; FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED; @@ -556,6 +620,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; + metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); @@ -619,6 +684,8 @@ hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED, hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; + _hb_ft_hb_font_check_changed (font, ft_font); + if (unlikely (FT_Load_Glyph (ft_face, glyph, FT_LOAD_NO_BITMAP | ft_font->load_flags))) return; @@ -964,6 +1031,31 @@ hb_ft_font_changed (hb_font_t *font) } /** + * hb_ft_hb_font_changed: + * @font: #hb_font_t to work upon + * + * Refreshes the state of the underlying FT_Face of @font when the hb_font_t + * @font has changed. + * This function should be called after changing the size or + * variation-axis settings on the @font. + * This call is fast if nothing has changed on @font. + * + * Return value: true if changed, false otherwise + * + * Since: 4.4.0 + **/ +hb_bool_t +hb_ft_hb_font_changed (hb_font_t *font) +{ + if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) + return false; + + hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; + + return _hb_ft_hb_font_check_changed (font, ft_font); +} + +/** * hb_ft_font_create_referenced: * @ft_face: FT_Face to work upon * @@ -1081,35 +1173,7 @@ hb_ft_font_set_funcs (hb_font_t *font) if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL)) FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE); - FT_Set_Char_Size (ft_face, - abs (font->x_scale), abs (font->y_scale), - 0, 0); -#if 0 - font->x_ppem * 72 * 64 / font->x_scale, - font->y_ppem * 72 * 64 / font->y_scale); -#endif - if (font->x_scale < 0 || font->y_scale < 0) - { - FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, - 0, font->y_scale < 0 ? -1 : +1}; - FT_Set_Transform (ft_face, &matrix, nullptr); - } - -#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) - unsigned int num_coords; - const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); - if (num_coords) - { - FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); - if (ft_coords) - { - for (unsigned int i = 0; i < num_coords; i++) - ft_coords[i] = coords[i] * 4; - FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); - hb_free (ft_coords); - } - } -#endif + _hb_ft_hb_font_changed (font, ft_face); ft_face->generic.data = blob; ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h index bf07115ab92..6a8a7abe8cc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h @@ -122,10 +122,17 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags); HB_EXTERN int hb_ft_font_get_load_flags (hb_font_t *font); -/* Call when size or variations settings on underlying FT_Face change. */ +/* Call when size or variations settings on underlying FT_Face changed, + * and you want to update the hb_font_t from it. */ HB_EXTERN void hb_ft_font_changed (hb_font_t *font); +/* Call when size or variations settings on underlying hb_font_t may have + * changed, and you want to update the FT_Face from it. This call is fast + * if nothing changed on hb_font_t. Returns true if changed. */ +HB_EXTERN hb_bool_t +hb_ft_hb_font_changed (hb_font_t *font); + /* Makes an hb_font_t use FreeType internally to implement font functions. * Note: this internally creates an FT_Face. Use it when you create your * hb_face_t using hb_face_create(). */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.h.tmpl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.h.tmpl index a8467868bdb..6dd98f7fed6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.h.tmpl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.h.tmpl @@ -43,7 +43,7 @@ HB_BEGIN_DECLS /*** BEGIN value-header ***/ HB_EXTERN GType -@enum_name@_get_type () G_GNUC_CONST; +@enum_name@_get_type (void) G_GNUC_CONST; #define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) /*** END value-header ***/ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh index 43a3098f65e..d4461f166cc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh @@ -43,17 +43,12 @@ * is writable, then the iterator returns lvalues, otherwise it * returns rvalues. * - * TODO Document more. - * - * If iterator implementation implements operator!=, then can be + * If iterator implementation implements operator!=, then it can be * used in range-based for loop. That already happens if the iterator * is random-access. Otherwise, the range-based for loop incurs * one traversal to find end(), which can be avoided if written * as a while-style for loop, or if iterator implements a faster - * __end__() method. - * TODO When opting in for C++17, address this by changing return - * type of .end()? - */ + * __end__() method. */ /* * Base classes for iterators. @@ -75,10 +70,6 @@ struct hb_iter_t iter_t* thiz () { return static_cast< iter_t *> (this); } public: - /* TODO: - * Port operators below to use hb_enable_if to sniff which method implements - * an operator and use it, and remove hb_iter_fallback_mixin_t completely. */ - /* Operators. */ iter_t iter () const { return *thiz(); } iter_t operator + () const { return *thiz(); } @@ -87,8 +78,7 @@ struct hb_iter_t explicit operator bool () const { return thiz()->__more__ (); } unsigned len () const { return thiz()->__len__ (); } /* The following can only be enabled if item_t is reference type. Otherwise - * it will be returning pointer to temporary rvalue. - * TODO Use a wrapper return type to fix for non-reference type. */ + * it will be returning pointer to temporary rvalue. */ template <typename T = item_t, hb_enable_if (std::is_reference<T>::value)> hb_remove_reference<item_t>* operator -> () const { return std::addressof (**thiz()); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc index 6c83c670c93..089615c72a0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc @@ -40,7 +40,7 @@ /** - * hb_map_create: (Xconstructor) + * hb_map_create: * * Creates a new, initially empty map. * @@ -172,6 +172,25 @@ hb_map_allocation_successful (const hb_map_t *map) return map->successful; } +/** + * hb_map_copy: + * @map: A map + * + * Allocate a copy of @map. + * + * Return value: Newly-allocated map. + * + * Since: 4.4.0 + **/ +hb_map_t * +hb_map_copy (const hb_map_t *map) +{ + hb_map_t *copy = hb_map_create (); + if (unlikely (!copy)) return nullptr; + copy->resize (map->population); + hb_copy (*map, *copy); + return copy; +} /** * hb_map_set: @@ -309,3 +328,20 @@ hb_map_is_equal (const hb_map_t *map, return map->is_equal (*other); } +/** + * hb_map_hash: + * @map: A map + * + * Creates a hash representing @map. + * + * Return value: + * A hash of @map. + * + * Since: 4.4.0 + **/ +HB_EXTERN unsigned int +hb_map_hash (const hb_map_t *map) +{ + return map->hash (); +} + diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h index 3f67c50b92e..41d877d6a15 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h @@ -82,6 +82,9 @@ hb_map_get_user_data (hb_map_t *map, HB_EXTERN hb_bool_t hb_map_allocation_successful (const hb_map_t *map); +HB_EXTERN hb_map_t * +hb_map_copy (const hb_map_t *map); + HB_EXTERN void hb_map_clear (hb_map_t *map); @@ -95,6 +98,9 @@ HB_EXTERN hb_bool_t hb_map_is_equal (const hb_map_t *map, const hb_map_t *other); +HB_EXTERN unsigned int +hb_map_hash (const hb_map_t *map); + HB_EXTERN void hb_map_set (hb_map_t *map, hb_codepoint_t key, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh index aec7d87f426..cc423c3ef39 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh @@ -35,14 +35,10 @@ */ template <typename K, typename V, - typename k_invalid_t = K, - typename v_invalid_t = V, - k_invalid_t kINVALID = std::is_pointer<K>::value ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1, - v_invalid_t vINVALID = std::is_pointer<V>::value ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1> + bool minus_one = false> struct hb_hashmap_t { hb_hashmap_t () { init (); } - hb_hashmap_t (std::nullptr_t) : hb_hashmap_t () {} ~hb_hashmap_t () { fini (); } hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (population); hb_copy (o, *this); } @@ -68,38 +64,40 @@ struct hb_hashmap_t struct item_t { K key; + uint32_t hash : 30; + uint32_t is_used_ : 1; + uint32_t is_tombstone_ : 1; V value; - uint32_t hash; + + bool is_used () const { return is_used_; } + void set_used (bool is_used) { is_used_ = is_used; } + bool is_tombstone () const { return is_tombstone_; } + void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; } + bool is_real () const { return is_used_ && !is_tombstone_; } + + template <bool v = minus_one, + hb_enable_if (v == false)> + static const V& default_value () { return Null(V); }; + template <bool v = minus_one, + hb_enable_if (v == true)> + static const V& default_value () { static const V minus_1 = -1; return minus_1; }; void clear () { new (std::addressof (key)) K (); - key = hb_coerce<K> (kINVALID); new (std::addressof (value)) V (); - value = hb_coerce<V> (vINVALID); hash = 0; + is_used_ = false; + is_tombstone_ = false; } bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); } bool operator == (const item_t &o) { return *this == o.key; } - bool is_unused () const - { - const K inv = hb_coerce<K> (kINVALID); - return key == inv; - } - bool is_tombstone () const - { - const K kinv = hb_coerce<K> (kINVALID); - const V vinv = hb_coerce<V> (vINVALID); - return key != kinv && value == vinv; - } - bool is_real () const - { - const K kinv = hb_coerce<K> (kINVALID); - const V vinv = hb_coerce<V> (vINVALID); - return key != kinv && value != vinv; - } hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); } + hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); } + + uint32_t total_hash () const + { return (hash * 31) + hb_hash (value); } }; hb_object_header_t header; @@ -200,27 +198,39 @@ struct hb_hashmap_t return true; } - bool set (K key, const V& value) { return set_with_hash (key, hb_hash (key), value); } - bool set (K key, V&& value) { return set_with_hash (key, hb_hash (key), std::move (value)); } + template <typename VV> + bool set (K key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); } - V get (K key) const + const V& get (K key) const { - if (unlikely (!items)) return hb_coerce<V> (vINVALID); + if (unlikely (!items)) return item_t::default_value (); unsigned int i = bucket_for (key); - return items[i].is_real () && items[i] == key ? items[i].value : hb_coerce<V> (vINVALID); + return items[i].is_real () && items[i] == key ? items[i].value : item_t::default_value (); } - void del (K key) { set (key, hb_coerce<V> (vINVALID)); } + void del (K key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); } /* Has interface. */ typedef V value_t; value_t operator [] (K k) const { return get (k); } - bool has (K k, V *vp = nullptr) const + bool has (K key, const V **vp = nullptr) const { - V v = (*this)[k]; - if (vp) *vp = v; - const V vinv = hb_coerce<V> (vINVALID); - return v != vinv; + if (unlikely (!items)) + { + if (vp) *vp = &item_t::default_value (); + return false; + } + unsigned int i = bucket_for (key); + if (items[i].is_real () && items[i] == key) + { + if (vp) *vp = &items[i].value; + return true; + } + else + { + if (vp) *vp = &item_t::default_value (); + return false; + } } /* Projection. */ V operator () (K k) const { return get (k); } @@ -242,8 +252,9 @@ struct hb_hashmap_t uint32_t hash () const { uint32_t h = 0; - for (auto pair : iter ()) - h ^= (hb_hash (pair.first) * 31) + hb_hash (pair.second); + for (const auto &item : + hb_array (items, mask ? mask + 1 : 0) + | hb_filter (&item_t::is_real)) + h ^= item.total_hash (); return h; } @@ -271,6 +282,12 @@ struct hb_hashmap_t | hb_filter (&item_t::is_real) | hb_map (&item_t::get_pair) ) + auto iter_ref () const HB_AUTO_RETURN + ( + + hb_array (items, mask ? mask + 1 : 0) + | hb_filter (&item_t::is_real) + | hb_map (&item_t::get_pair_ref) + ) auto keys () const HB_AUTO_RETURN ( + hb_array (items, mask ? mask + 1 : 0) @@ -293,19 +310,16 @@ struct hb_hashmap_t protected: template <typename VV> - bool set_with_hash (K key, uint32_t hash, VV&& value) + bool set_with_hash (K key, uint32_t hash, VV&& value, bool is_delete=false) { if (unlikely (!successful)) return false; - const K kinv = hb_coerce<K> (kINVALID); - if (unlikely (key == kinv)) return true; if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false; unsigned int i = bucket_for_hash (key, hash); - const V vinv = hb_coerce<V> (vINVALID); - if (value == vinv && items[i].key != key) + if (is_delete && items[i].key != key) return true; /* Trying to delete non-existent key. */ - if (!items[i].is_unused ()) + if (items[i].is_used ()) { occupancy--; if (!items[i].is_tombstone ()) @@ -313,27 +327,30 @@ struct hb_hashmap_t } items[i].key = key; - items[i].value = value; + items[i].value = std::forward<VV> (value); items[i].hash = hash; + items[i].set_used (true); + items[i].set_tombstone (is_delete); occupancy++; - if (!items[i].is_tombstone ()) + if (!is_delete) population++; return true; } - unsigned int bucket_for (K key) const + unsigned int bucket_for (const K &key) const { return bucket_for_hash (key, hb_hash (key)); } - unsigned int bucket_for_hash (K key, uint32_t hash) const + unsigned int bucket_for_hash (const K &key, uint32_t hash) const { + hash &= 0x3FFFFFFF; // We only store lower 30bit of hash unsigned int i = hash % prime; unsigned int step = 0; unsigned int tombstone = (unsigned) -1; - while (!items[i].is_unused ()) + while (items[i].is_used ()) { if (items[i].hash == hash && items[i] == key) return i; @@ -402,21 +419,14 @@ struct hb_hashmap_t struct hb_map_t : hb_hashmap_t<hb_codepoint_t, hb_codepoint_t, - hb_codepoint_t, - hb_codepoint_t, - HB_MAP_VALUE_INVALID, - HB_MAP_VALUE_INVALID> + true> { using hashmap = hb_hashmap_t<hb_codepoint_t, hb_codepoint_t, - hb_codepoint_t, - hb_codepoint_t, - HB_MAP_VALUE_INVALID, - HB_MAP_VALUE_INVALID>; + true>; ~hb_map_t () = default; hb_map_t () : hashmap () {} - hb_map_t (std::nullptr_t) : hb_map_t () {} hb_map_t (const hb_map_t &o) : hashmap ((hashmap &) o) {} hb_map_t (hb_map_t &&o) : hashmap (std::move ((hashmap &) o)) {} hb_map_t& operator= (const hb_map_t&) = default; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh index 90757d38acd..e97d790fc36 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh @@ -188,7 +188,7 @@ template <> struct hb_int_max<signed long long> : hb_integral_constant<signed l template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigned long long, ULLONG_MAX> {}; #define hb_int_max(T) hb_int_max<T>::value -#if __GNUG__ && __GNUC__ < 5 +#if defined(__GNUC__) && __GNUC__ < 5 #define hb_is_trivially_copyable(T) __has_trivial_copy(T) #define hb_is_trivially_copy_assignable(T) __has_trivial_assign(T) #define hb_is_trivially_constructible(T) __has_trivial_constructor(T) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh index db38a4dfd24..78eb6474d57 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh @@ -37,7 +37,7 @@ /* Global nul-content Null pool. Enlarge as necessary. */ -#define HB_NULL_POOL_SIZE 384 +#define HB_NULL_POOL_SIZE 448 /* Use SFINAE to sniff whether T has min_size; in which case return the larger * of sizeof(T) and T::null_size, otherwise return sizeof(T). @@ -108,7 +108,7 @@ struct NullHelper /* Specializations for arbitrary-content Null objects expressed in bytes. */ #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ } /* Close namespace. */ \ - extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]; \ + extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[hb_null_size (Namespace::Type)]; \ template <> \ struct Null<Namespace::Type> { \ static Namespace::Type const & get_null () { \ @@ -118,7 +118,7 @@ struct NullHelper namespace Namespace { \ static_assert (true, "") /* Require semicolon after. */ #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ - const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size] + const unsigned char _hb_Null_##Namespace##_##Type[hb_null_size (Namespace::Type)] /* Specializations for arbitrary-content Null objects expressed as struct initializer. */ #define DECLARE_NULL_INSTANCE(Type) \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh index b5047002ac4..4aa337f78be 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh @@ -406,6 +406,8 @@ struct Charset1_2 { void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const { hb_codepoint_t gid = 1; + if (gid >= num_glyphs) + return; for (unsigned i = 0;; i++) { hb_codepoint_t sid = ranges[i].first; @@ -1138,7 +1140,8 @@ struct cff1 cff1_top_dict_interp_env_t env (fontDictStr); cff1_font_dict_interpreter_t font_interp (env); font = fontDicts.push (); - if (unlikely (font == &Crap (cff1_font_dict_values_t))) { fini (); return; } + if (unlikely (fontDicts.in_error ())) { fini (); return; } + font->init (); if (unlikely (!font_interp.interpret (*font))) { fini (); return; } PRIVDICTVAL *priv = &privateDicts[i]; @@ -1333,7 +1336,7 @@ struct cff1 if (names) { names->fini (); - free (names); + hb_free (names); } SUPER::fini (); @@ -1379,7 +1382,7 @@ struct cff1 hb_sorted_vector_t<gname_t> *names = glyph_names.get (); if (unlikely (!names)) { - names = (hb_sorted_vector_t<gname_t> *) calloc (sizeof (hb_sorted_vector_t<gname_t>), 1); + names = (hb_sorted_vector_t<gname_t> *) hb_calloc (sizeof (hb_sorted_vector_t<gname_t>), 1); if (likely (names)) { names->init (); @@ -1409,14 +1412,14 @@ struct cff1 if (names) { names->fini (); - free (names); + hb_free (names); } goto retry; } - } + } gname_t key = { hb_bytes_t (name, len), 0 }; - const gname_t *gname = glyph_names->bsearch (key); + const gname_t *gname = names ? names->bsearch (key) : nullptr; if (!gname) return false; hb_codepoint_t gid = sid_to_glyph (gname->sid); if (!gid && gname->sid) return false; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh index 7e96d9c8b32..09c9fe93f32 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh @@ -27,6 +27,8 @@ #ifndef HB_OT_CMAP_TABLE_HH #define HB_OT_CMAP_TABLE_HH +#include "hb-ot-os2-table.hh" +#include "hb-ot-shaper-arabic-pua.hh" #include "hb-open-type.hh" #include "hb-set.hh" @@ -1476,33 +1478,47 @@ struct SubtableUnicodesCache { private: const void* base; - hb_hashmap_t<intptr_t, hb_set_t*> cached_unicodes; + hb_hashmap_t<intptr_t, hb::unique_ptr<hb_set_t>> cached_unicodes; public: SubtableUnicodesCache(const void* cmap_base) : base(cmap_base), cached_unicodes() {} - ~SubtableUnicodesCache() - { - for (hb_set_t* s : cached_unicodes.values()) { - hb_set_destroy (s); - } - } - hb_set_t* set_for(const EncodingRecord* record) + hb_set_t* set_for (const EncodingRecord* record) { - if (!cached_unicodes.has ((intptr_t) record)) { - hb_set_t* new_set = hb_set_create (); - if (!cached_unicodes.set ((intptr_t) record, new_set)) { - hb_set_destroy (new_set); + if (!cached_unicodes.has ((intptr_t) record)) + { + hb_set_t *s = hb_set_create (); + if (unlikely (s->in_error ())) + return hb_set_get_empty (); + + (base+record->subtable).collect_unicodes (s); + + if (unlikely (!cached_unicodes.set ((intptr_t) record, hb::unique_ptr<hb_set_t> {s}))) return hb_set_get_empty (); - } - (base+record->subtable).collect_unicodes (cached_unicodes.get ((intptr_t) record)); + + return s; } return cached_unicodes.get ((intptr_t) record); } }; +static inline uint_fast16_t +_hb_symbol_pua_map (unsigned codepoint) +{ + if (codepoint <= 0x00FFu) + { + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * https://docs.microsoft.com/en-us/typography/opentype/spec/recom + * under "Non-Standard (Symbol) Fonts". */ + return 0xF000u + codepoint; + } + return 0; +} + struct cmap { static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap; @@ -1726,7 +1742,24 @@ struct cmap this->get_glyph_data = subtable; if (unlikely (symbol)) - this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>; + { + switch ((unsigned) face->table.OS2->get_font_page ()) { + case OS2::font_page_t::FONT_PAGE_NONE: + this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_symbol_pua_map>; + break; +#ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK + case OS2::font_page_t::FONT_PAGE_SIMP_ARABIC: + this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_arabic_pua_simp_map>; + break; + case OS2::font_page_t::FONT_PAGE_TRAD_ARABIC: + this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_arabic_pua_trad_map>; + break; +#endif + default: + this->get_glyph_funcZ = get_glyph_from<CmapSubtable>; + break; + } + } else { switch (subtable->u.format) { @@ -1808,6 +1841,7 @@ struct cmap typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); + typedef uint_fast16_t (*hb_pua_remap_func_t) (unsigned); template <typename Type> HB_INTERNAL static bool get_glyph_from (const void *obj, @@ -1818,7 +1852,7 @@ struct cmap return typed_obj->get_glyph (codepoint, glyph); } - template <typename Type> + template <typename Type, hb_pua_remap_func_t remap> HB_INTERNAL static bool get_glyph_from_symbol (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) @@ -1827,15 +1861,8 @@ struct cmap if (likely (typed_obj->get_glyph (codepoint, glyph))) return true; - if (codepoint <= 0x00FFu) - { - /* For symbol-encoded OpenType fonts, we duplicate the - * U+F000..F0FF range at U+0000..U+00FF. That's what - * Windows seems to do, and that's hinted about at: - * https://docs.microsoft.com/en-us/typography/opentype/spec/recom - * under "Non-Standard (Symbol) Fonts". */ - return typed_obj->get_glyph (0xF000u + codepoint, glyph); - } + if (hb_codepoint_t c = remap (codepoint)) + return typed_obj->get_glyph (c, glyph); return false; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh index 24476eda178..bcab77f79dc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh @@ -97,9 +97,10 @@ struct CPALV1Tail c->push (); for (const auto _ : colorLabels) { - if (!color_index_map->has (_)) continue; + const hb_codepoint_t *v; + if (!color_index_map->has (_, &v)) continue; NameID new_color_idx; - new_color_idx = color_index_map->get (_); + new_color_idx = *v; if (!c->copy<NameID> (new_color_idx)) { c->pop_discard (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh index 9741ebd4503..d0e2235fb2f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh @@ -298,6 +298,12 @@ struct sbix const PNGHeader &png = *blob->as<PNGHeader>(); + if (png.IHDR.height >= 65536 || png.IHDR.width >= 65536) + { + hb_blob_destroy (blob); + return false; + } + extents->x_bearing = x_offset; extents->y_bearing = png.IHDR.height + y_offset; extents->width = png.IHDR.width; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc index 0f44ee4d5f4..af1bc86d488 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc @@ -30,6 +30,7 @@ #include "hb-ot.h" +#include "hb-cache.hh" #include "hb-font.hh" #include "hb-machinery.hh" #include "hb-ot-face.hh" @@ -58,6 +59,41 @@ * never need to call these functions directly. **/ +struct hb_ot_font_t +{ + const hb_ot_face_t *ot_face; + + /* h_advance caching */ + mutable hb_atomic_int_t cached_coords_serial; + mutable hb_atomic_ptr_t<hb_advance_cache_t> advance_cache; +}; + +static hb_ot_font_t * +_hb_ot_font_create (hb_font_t *font) +{ + hb_ot_font_t *ot_font = (hb_ot_font_t *) hb_calloc (1, sizeof (hb_ot_font_t)); + if (unlikely (!ot_font)) + return nullptr; + + ot_font->ot_face = &font->face->table; + + return ot_font; +} + +static void +_hb_ot_font_destroy (void *font_data) +{ + hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data; + + auto *cache = ot_font->advance_cache.get_relaxed (); + if (cache) + { + cache->fini (); + hb_free (cache); + } + + hb_free (ot_font); +} static hb_bool_t hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, @@ -66,7 +102,8 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + 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; return ot_face->cmap->get_nominal_glyph (unicode, glyph); } @@ -80,7 +117,8 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, unsigned int glyph_stride, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + 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; return ot_face->cmap->get_nominal_glyphs (count, first_unicode, unicode_stride, first_glyph, glyph_stride); @@ -94,7 +132,8 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + 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; return ot_face->cmap->get_variation_glyph (unicode, variation_selector, glyph); } @@ -107,15 +146,83 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + 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; - for (unsigned int i = 0; i < count; i++) +#ifndef HB_NO_VAR + const OT::HVARVVAR &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; + + bool use_cache = font->num_coords; +#else + OT::VariationStore::cache_t *varStore_cache = nullptr; + bool use_cache = false; +#endif + + hb_advance_cache_t *cache = nullptr; + if (use_cache) { - *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font)); - first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); - first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); + retry: + cache = ot_font->advance_cache.get (); + if (unlikely (!cache)) + { + cache = (hb_advance_cache_t *) hb_malloc (sizeof (hb_advance_cache_t)); + if (unlikely (!cache)) + { + use_cache = false; + goto out; + } + + cache->init (); + if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache))) + { + hb_free (cache); + goto retry; + } + ot_font->cached_coords_serial.set (font->serial_coords); + } + } + out: + + if (!use_cache) + { + for (unsigned int i = 0; i < count; i++) + { + *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font, varStore_cache)); + first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); + } } + else + { /* Use cache. */ + if (ot_font->cached_coords_serial.get () != (int) font->serial_coords) + { + ot_font->advance_cache->init (); + ot_font->cached_coords_serial.set (font->serial_coords); + } + + for (unsigned int i = 0; i < count; i++) + { + hb_position_t v; + unsigned cv; + if (ot_font->advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = hmtx.get_advance (*first_glyph, font, varStore_cache); + ot_font->advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_x (v); + first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); + first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); + } + } + +#ifndef HB_NO_VAR + OT::VariationStore::destroy_cache (varStore_cache); +#endif } #ifndef HB_NO_VERTICAL @@ -128,16 +235,31 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; if (vmtx.has_data ()) + { +#ifndef HB_NO_VAR + const OT::HVARVVAR &VVAR = *vmtx.var_table; + const OT::VariationStore &varStore = &VVAR + VVAR.varStore; + OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; +#else + OT::VariationStore::cache_t *varStore_cache = nullptr; +#endif + for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font)); + *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font, varStore_cache)); first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } + +#ifndef HB_NO_VAR + OT::VariationStore::destroy_cache (varStore_cache); +#endif + } else { hb_font_extents_t font_extents; @@ -163,7 +285,8 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + const hb_ot_face_t *ot_face = ot_font->ot_face; *x = font->get_glyph_h_advance (glyph) / 2; @@ -208,7 +331,8 @@ hb_ot_get_glyph_extents (hb_font_t *font, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + 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; #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) if (ot_face->sbix->get_extents (font, glyph, extents)) return true; @@ -234,7 +358,9 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, char *name, unsigned int size, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + 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; + if (ot_face->post->get_glyph_name (glyph, name, size)) return true; #ifndef HB_NO_OT_FONT_CFF if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true; @@ -248,7 +374,9 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + 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; + if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true; #ifndef HB_NO_OT_FONT_CFF if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true; @@ -364,10 +492,14 @@ _hb_ot_get_font_funcs () void hb_ot_font_set_funcs (hb_font_t *font) { + hb_ot_font_t *ot_font = _hb_ot_font_create (font); + if (unlikely (!ot_font)) + return; + hb_font_set_funcs (font, _hb_ot_get_font_funcs (), - &font->face->table, - nullptr); + ot_font, + _hb_ot_font_destroy); } #ifndef HB_NO_VAR diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh index 866bb7e04c1..c32ff7636d5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh @@ -30,1334 +30,6 @@ #ifndef HB_OT_GLYF_TABLE_HH #define HB_OT_GLYF_TABLE_HH -#include "hb-open-type.hh" -#include "hb-ot-head-table.hh" -#include "hb-ot-hmtx-table.hh" -#include "hb-ot-var-gvar-table.hh" -#include "hb-draw.hh" - -namespace OT { - - -/* - * loca -- Index to Location - * https://docs.microsoft.com/en-us/typography/opentype/spec/loca - */ -#define HB_OT_TAG_loca HB_TAG('l','o','c','a') - -#ifndef HB_MAX_COMPOSITE_OPERATIONS -#define HB_MAX_COMPOSITE_OPERATIONS 100000 -#endif - - -struct loca -{ - friend struct glyf; - - static constexpr hb_tag_t tableTag = HB_OT_TAG_loca; - - bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const - { - TRACE_SANITIZE (this); - return_trace (true); - } - - protected: - UnsizedArrayOf<HBUINT8> - dataZ; /* Location data. */ - public: - DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always - * check the size externally, allow Null() object of it by - * defining it _MIN instead. */ -}; - - -/* - * glyf -- TrueType Glyph Data - * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf - */ -#define HB_OT_TAG_glyf HB_TAG('g','l','y','f') - - -struct glyf -{ - static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf; - - bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const - { - TRACE_SANITIZE (this); - /* Runtime checks as eager sanitizing each glyph is costy */ - return_trace (true); - } - - template<typename Iterator, - hb_requires (hb_is_source_of (Iterator, unsigned int))> - static bool - _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca) - { - unsigned num_offsets = padded_offsets.len () + 1; - unsigned entry_size = use_short_loca ? 2 : 4; - char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets); - - if (unlikely (!loca_prime_data)) return false; - - DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d", - entry_size, num_offsets, entry_size * num_offsets); - - if (use_short_loca) - _write_loca (padded_offsets, 1, hb_array ((HBUINT16 *) loca_prime_data, num_offsets)); - else - _write_loca (padded_offsets, 0, hb_array ((HBUINT32 *) loca_prime_data, num_offsets)); - - hb_blob_t *loca_blob = hb_blob_create (loca_prime_data, - entry_size * num_offsets, - HB_MEMORY_MODE_WRITABLE, - loca_prime_data, - hb_free); - - bool result = plan->add_table (HB_OT_TAG_loca, loca_blob) - && _add_head_and_set_loca_version (plan, use_short_loca); - - hb_blob_destroy (loca_blob); - return result; - } - - template<typename IteratorIn, typename IteratorOut, - hb_requires (hb_is_source_of (IteratorIn, unsigned int)), - hb_requires (hb_is_sink_of (IteratorOut, unsigned))> - static void - _write_loca (IteratorIn it, unsigned right_shift, IteratorOut dest) - { - unsigned int offset = 0; - dest << 0; - + it - | hb_map ([=, &offset] (unsigned int padded_size) - { - offset += padded_size; - DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset); - return offset >> right_shift; - }) - | hb_sink (dest) - ; - } - - /* requires source of SubsetGlyph complains the identifier isn't declared */ - template <typename Iterator> - bool serialize (hb_serialize_context_t *c, - Iterator it, - bool use_short_loca, - const hb_subset_plan_t *plan) - { - TRACE_SERIALIZE (this); - unsigned init_len = c->length (); - for (const auto &_ : it) _.serialize (c, use_short_loca, plan); - - /* As a special case when all glyph in the font are empty, add a zero byte - * to the table, so that OTS doesn’t reject it, and to make the table work - * on Windows as well. - * See https://github.com/khaledhosny/ots/issues/52 */ - if (init_len == c->length ()) - { - HBUINT8 empty_byte; - empty_byte = 0; - c->copy (empty_byte); - } - return_trace (true); - } - - /* Byte region(s) per glyph to output - unpadded, hints removed if so requested - If we fail to process a glyph we produce an empty (0-length) glyph */ - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - - glyf *glyf_prime = c->serializer->start_embed <glyf> (); - if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false); - - hb_vector_t<SubsetGlyph> glyphs; - _populate_subset_glyphs (c->plan, &glyphs); - - auto padded_offsets = - + hb_iter (glyphs) - | hb_map (&SubsetGlyph::padded_size) - ; - - unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0); - bool use_short_loca = max_offset < 0x1FFFF; - - - glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan); - if (!use_short_loca) { - padded_offsets = - + hb_iter (glyphs) - | hb_map (&SubsetGlyph::length) - ; - } - - - if (unlikely (c->serializer->in_error ())) return_trace (false); - return_trace (c->serializer->check_success (_add_loca_and_head (c->plan, - padded_offsets, - use_short_loca))); - } - - template <typename SubsetGlyph> - void - _populate_subset_glyphs (const hb_subset_plan_t *plan, - hb_vector_t<SubsetGlyph> *glyphs /* OUT */) const - { - OT::glyf::accelerator_t glyf (plan->source); - - + hb_range (plan->num_output_glyphs ()) - | hb_map ([&] (hb_codepoint_t new_gid) - { - SubsetGlyph subset_glyph = {0}; - subset_glyph.new_gid = new_gid; - - /* should never fail: all old gids should be mapped */ - if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) - return subset_glyph; - - if (new_gid == 0 && - !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) - subset_glyph.source_glyph = Glyph (); - else - subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true); - if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) - subset_glyph.drop_hints_bytes (); - else - subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes (); - return subset_glyph; - }) - | hb_sink (glyphs) - ; - } - - static bool - _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca) - { - hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source); - hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob); - hb_blob_destroy (head_blob); - - if (unlikely (!head_prime_blob)) - return false; - - head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr); - head_prime->indexToLocFormat = use_short_loca ? 0 : 1; - bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob); - - hb_blob_destroy (head_prime_blob); - return success; - } - - struct CompositeGlyphChain - { - protected: - enum composite_glyph_flag_t - { - ARG_1_AND_2_ARE_WORDS = 0x0001, - ARGS_ARE_XY_VALUES = 0x0002, - ROUND_XY_TO_GRID = 0x0004, - WE_HAVE_A_SCALE = 0x0008, - MORE_COMPONENTS = 0x0020, - WE_HAVE_AN_X_AND_Y_SCALE = 0x0040, - WE_HAVE_A_TWO_BY_TWO = 0x0080, - WE_HAVE_INSTRUCTIONS = 0x0100, - USE_MY_METRICS = 0x0200, - OVERLAP_COMPOUND = 0x0400, - SCALED_COMPONENT_OFFSET = 0x0800, - UNSCALED_COMPONENT_OFFSET = 0x1000 - }; - - public: - unsigned int get_size () const - { - unsigned int size = min_size; - /* arg1 and 2 are int16 */ - if (flags & ARG_1_AND_2_ARE_WORDS) size += 4; - /* arg1 and 2 are int8 */ - else size += 2; - - /* One x 16 bit (scale) */ - if (flags & WE_HAVE_A_SCALE) size += 2; - /* Two x 16 bit (xscale, yscale) */ - else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4; - /* Four x 16 bit (xscale, scale01, scale10, yscale) */ - else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8; - - return size; - } - - void set_glyph_index (hb_codepoint_t new_gid) { glyphIndex = new_gid; } - hb_codepoint_t get_glyph_index () const { return glyphIndex; } - - void drop_instructions_flag () { flags = (uint16_t) flags & ~WE_HAVE_INSTRUCTIONS; } - void set_overlaps_flag () - { - flags = (uint16_t) flags | OVERLAP_COMPOUND; - } - - bool has_instructions () const { return flags & WE_HAVE_INSTRUCTIONS; } - - bool has_more () const { return flags & MORE_COMPONENTS; } - bool is_use_my_metrics () const { return flags & USE_MY_METRICS; } - bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); } - void get_anchor_points (unsigned int &point1, unsigned int &point2) const - { - const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex); - if (flags & ARG_1_AND_2_ARE_WORDS) - { - point1 = ((const HBUINT16 *) p)[0]; - point2 = ((const HBUINT16 *) p)[1]; - } - else - { - point1 = p[0]; - point2 = p[1]; - } - } - - void transform_points (contour_point_vector_t &points) const - { - float matrix[4]; - contour_point_t trans; - if (get_transformation (matrix, trans)) - { - if (scaled_offsets ()) - { - points.translate (trans); - points.transform (matrix); - } - else - { - points.transform (matrix); - points.translate (trans); - } - } - } - - protected: - bool scaled_offsets () const - { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; } - - bool get_transformation (float (&matrix)[4], contour_point_t &trans) const - { - matrix[0] = matrix[3] = 1.f; - matrix[1] = matrix[2] = 0.f; - - int tx, ty; - const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex); - if (flags & ARG_1_AND_2_ARE_WORDS) - { - tx = *(const HBINT16 *) p; - p += HBINT16::static_size; - ty = *(const HBINT16 *) p; - p += HBINT16::static_size; - } - else - { - tx = *p++; - ty = *p++; - } - if (is_anchored ()) tx = ty = 0; - - trans.init ((float) tx, (float) ty); - - { - const F2DOT14 *points = (const F2DOT14 *) p; - if (flags & WE_HAVE_A_SCALE) - { - matrix[0] = matrix[3] = points[0].to_float (); - return true; - } - else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) - { - matrix[0] = points[0].to_float (); - matrix[3] = points[1].to_float (); - return true; - } - else if (flags & WE_HAVE_A_TWO_BY_TWO) - { - matrix[0] = points[0].to_float (); - matrix[1] = points[1].to_float (); - matrix[2] = points[2].to_float (); - matrix[3] = points[3].to_float (); - return true; - } - } - return tx || ty; - } - - protected: - HBUINT16 flags; - HBGlyphID16 glyphIndex; - public: - DEFINE_SIZE_MIN (4); - }; - - struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphChain &> - { - typedef const CompositeGlyphChain *__item_t__; - composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) : - glyph (glyph_), current (nullptr), current_size (0) - { - set_next (current_); - } - - composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {} - - const CompositeGlyphChain &__item__ () const { return *current; } - bool __more__ () const { return current; } - void __next__ () - { - if (!current->has_more ()) { current = nullptr; return; } - - set_next (&StructAtOffset<CompositeGlyphChain> (current, current_size)); - } - bool operator != (const composite_iter_t& o) const - { return glyph != o.glyph || current != o.current; } - - - void set_next (const CompositeGlyphChain *composite) - { - if (!glyph.check_range (composite, CompositeGlyphChain::min_size)) - { - current = nullptr; - current_size = 0; - return; - } - unsigned size = composite->get_size (); - if (!glyph.check_range (composite, size)) - { - current = nullptr; - current_size = 0; - return; - } - - current = composite; - current_size = size; - } - - private: - hb_bytes_t glyph; - __item_t__ current; - unsigned current_size; - }; - - enum phantom_point_index_t - { - PHANTOM_LEFT = 0, - PHANTOM_RIGHT = 1, - PHANTOM_TOP = 2, - PHANTOM_BOTTOM = 3, - PHANTOM_COUNT = 4 - }; - - struct accelerator_t; - - struct Glyph - { - enum simple_glyph_flag_t - { - FLAG_ON_CURVE = 0x01, - FLAG_X_SHORT = 0x02, - FLAG_Y_SHORT = 0x04, - FLAG_REPEAT = 0x08, - FLAG_X_SAME = 0x10, - FLAG_Y_SAME = 0x20, - FLAG_OVERLAP_SIMPLE = 0x40, - FLAG_RESERVED2 = 0x80 - }; - - private: - struct GlyphHeader - { - bool has_data () const { return numberOfContours; } - - bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator, - hb_codepoint_t gid, hb_glyph_extents_t *extents) const - { - /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */ - /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */ - extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid)); - extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax)); - extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax)); - extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax)); - - return true; - } - - HBINT16 numberOfContours; - /* If the number of contours is - * greater than or equal to zero, - * this is a simple glyph; if negative, - * this is a composite glyph. */ - FWORD xMin; /* Minimum x for coordinate data. */ - FWORD yMin; /* Minimum y for coordinate data. */ - FWORD xMax; /* Maximum x for coordinate data. */ - FWORD yMax; /* Maximum y for coordinate data. */ - public: - DEFINE_SIZE_STATIC (10); - }; - - struct SimpleGlyph - { - const GlyphHeader &header; - hb_bytes_t bytes; - SimpleGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : - header (header_), bytes (bytes_) {} - - unsigned int instruction_len_offset () const - { return GlyphHeader::static_size + 2 * header.numberOfContours; } - - unsigned int length (unsigned int instruction_len) const - { return instruction_len_offset () + 2 + instruction_len; } - - unsigned int instructions_length () const - { - unsigned int instruction_length_offset = instruction_len_offset (); - if (unlikely (instruction_length_offset + 2 > bytes.length)) return 0; - - const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&bytes, instruction_length_offset); - /* Out of bounds of the current glyph */ - if (unlikely (length (instructionLength) > bytes.length)) return 0; - return instructionLength; - } - - const Glyph trim_padding () const - { - /* based on FontTools _g_l_y_f.py::trim */ - const uint8_t *glyph = (uint8_t*) bytes.arrayZ; - const uint8_t *glyph_end = glyph + bytes.length; - /* simple glyph w/contours, possibly trimmable */ - glyph += instruction_len_offset (); - - if (unlikely (glyph + 2 >= glyph_end)) return Glyph (); - unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1; - unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0); - - glyph += 2 + num_instructions; - - unsigned int coord_bytes = 0; - unsigned int coords_with_flags = 0; - while (glyph < glyph_end) - { - uint8_t flag = *glyph; - glyph++; - - unsigned int repeat = 1; - if (flag & FLAG_REPEAT) - { - if (unlikely (glyph >= glyph_end)) return Glyph (); - repeat = *glyph + 1; - glyph++; - } - - unsigned int xBytes, yBytes; - xBytes = yBytes = 0; - if (flag & FLAG_X_SHORT) xBytes = 1; - else if ((flag & FLAG_X_SAME) == 0) xBytes = 2; - - if (flag & FLAG_Y_SHORT) yBytes = 1; - else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2; - - coord_bytes += (xBytes + yBytes) * repeat; - coords_with_flags += repeat; - if (coords_with_flags >= num_coordinates) break; - } - - if (unlikely (coords_with_flags != num_coordinates)) return Glyph (); - return Glyph (bytes.sub_array (0, bytes.length + coord_bytes - (glyph_end - glyph))); - } - - /* zero instruction length */ - void drop_hints () - { - GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header); - (HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0; - } - - void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const - { - unsigned int instructions_len = instructions_length (); - unsigned int glyph_length = length (instructions_len); - dest_start = bytes.sub_array (0, glyph_length - instructions_len); - dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length); - } - - void set_overlaps_flag () - { - if (unlikely (!header.numberOfContours)) return; - - unsigned flags_offset = length (instructions_length ()); - if (unlikely (flags_offset + 1 > bytes.length)) return; - - HBUINT8 &first_flag = (HBUINT8 &) StructAtOffset<HBUINT16> (&bytes, flags_offset); - first_flag = (uint8_t) first_flag | FLAG_OVERLAP_SIMPLE; - } - - static bool read_points (const HBUINT8 *&p /* IN/OUT */, - contour_point_vector_t &points_ /* IN/OUT */, - const hb_bytes_t &bytes, - void (* setter) (contour_point_t &_, float v), - const simple_glyph_flag_t short_flag, - const simple_glyph_flag_t same_flag) - { - float v = 0; - for (unsigned i = 0; i < points_.length; i++) - { - uint8_t flag = points_[i].flag; - if (flag & short_flag) - { - if (unlikely (!bytes.check_range (p))) return false; - if (flag & same_flag) - v += *p++; - else - v -= *p++; - } - else - { - if (!(flag & same_flag)) - { - if (unlikely (!bytes.check_range ((const HBUINT16 *) p))) return false; - v += *(const HBINT16 *) p; - p += HBINT16::static_size; - } - } - setter (points_[i], v); - } - return true; - } - - bool get_contour_points (contour_point_vector_t &points_ /* OUT */, - bool phantom_only = false) const - { - const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header); - int num_contours = header.numberOfContours; - if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours + 1]))) return false; - unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; - - points_.resize (num_points); - for (unsigned int i = 0; i < points_.length; i++) points_[i].init (); - if (phantom_only) return true; - - for (int i = 0; i < num_contours; i++) - points_[endPtsOfContours[i]].is_end_point = true; - - /* Skip instructions */ - const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1], - endPtsOfContours[num_contours]); - - /* Read flags */ - for (unsigned int i = 0; i < num_points; i++) - { - if (unlikely (!bytes.check_range (p))) return false; - uint8_t flag = *p++; - points_[i].flag = flag; - if (flag & FLAG_REPEAT) - { - if (unlikely (!bytes.check_range (p))) return false; - unsigned int repeat_count = *p++; - while ((repeat_count-- > 0) && (++i < num_points)) - points_[i].flag = flag; - } - } - - /* Read x & y coordinates */ - return read_points (p, points_, bytes, [] (contour_point_t &p, float v) { p.x = v; }, - FLAG_X_SHORT, FLAG_X_SAME) - && read_points (p, points_, bytes, [] (contour_point_t &p, float v) { p.y = v; }, - FLAG_Y_SHORT, FLAG_Y_SAME); - } - }; - - struct CompositeGlyph - { - const GlyphHeader &header; - hb_bytes_t bytes; - CompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : - header (header_), bytes (bytes_) {} - - composite_iter_t get_iterator () const - { return composite_iter_t (bytes, &StructAfter<CompositeGlyphChain, GlyphHeader> (header)); } - - unsigned int instructions_length (hb_bytes_t bytes) const - { - unsigned int start = bytes.length; - unsigned int end = bytes.length; - const CompositeGlyphChain *last = nullptr; - for (auto &item : get_iterator ()) - last = &item; - if (unlikely (!last)) return 0; - - if (last->has_instructions ()) - start = (char *) last - &bytes + last->get_size (); - if (unlikely (start > end)) return 0; - return end - start; - } - - /* Trimming for composites not implemented. - * If removing hints it falls out of that. */ - const Glyph trim_padding () const { return Glyph (bytes); } - - void drop_hints () - { - for (const auto &_ : get_iterator ()) - const_cast<CompositeGlyphChain &> (_).drop_instructions_flag (); - } - - /* Chop instructions off the end */ - void drop_hints_bytes (hb_bytes_t &dest_start) const - { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); } - - void set_overlaps_flag () - { - const_cast<CompositeGlyphChain &> (StructAfter<CompositeGlyphChain, GlyphHeader> (header)) - .set_overlaps_flag (); - } - }; - - enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE }; - - public: - composite_iter_t get_composite_iterator () const - { - if (type != COMPOSITE) return composite_iter_t (); - return CompositeGlyph (*header, bytes).get_iterator (); - } - - const Glyph trim_padding () const - { - switch (type) { - case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding (); - case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding (); - default: return bytes; - } - } - - void drop_hints () - { - switch (type) { - case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return; - case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return; - default: return; - } - } - - void set_overlaps_flag () - { - switch (type) { - case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return; - case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return; - default: return; - } - } - - void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const - { - switch (type) { - case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return; - case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return; - default: return; - } - } - - /* Note: Recursively calls itself. - * all_points includes phantom points - */ - bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, - contour_point_vector_t &all_points /* OUT */, - bool phantom_only = false, - unsigned int depth = 0) const - { - if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false; - contour_point_vector_t points; - - switch (type) { - case COMPOSITE: - { - /* pseudo component points for each component in composite glyph */ - unsigned num_points = hb_len (CompositeGlyph (*header, bytes).get_iterator ()); - if (unlikely (!points.resize (num_points))) return false; - for (unsigned i = 0; i < points.length; i++) - points[i].init (); - break; - } - case SIMPLE: - if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only))) - return false; - break; - } - - /* Init phantom points */ - if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; - hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); - { - for (unsigned i = 0; i < PHANTOM_COUNT; ++i) phantoms[i].init (); - int h_delta = (int) header->xMin - - glyf_accelerator.hmtx->get_side_bearing (gid); - int v_orig = (int) header->yMax + -#ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_side_bearing (gid) -#else - 0 -#endif - ; - unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid); - unsigned v_adv = -#ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_advance (gid) -#else - - font->face->get_upem () -#endif - ; - phantoms[PHANTOM_LEFT].x = h_delta; - phantoms[PHANTOM_RIGHT].x = h_adv + h_delta; - phantoms[PHANTOM_TOP].y = v_orig; - phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; - } - -#ifndef HB_NO_VAR - glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ()); -#endif - - switch (type) { - case SIMPLE: - all_points.extend (points.as_array ()); - break; - case COMPOSITE: - { - unsigned int comp_index = 0; - for (auto &item : get_composite_iterator ()) - { - contour_point_vector_t comp_points; - if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_glyph_index ()) - .get_points (font, glyf_accelerator, comp_points, - phantom_only, depth + 1) - || comp_points.length < PHANTOM_COUNT)) - return false; - - /* Copy phantom points from component if USE_MY_METRICS flag set */ - if (item.is_use_my_metrics ()) - for (unsigned int i = 0; i < PHANTOM_COUNT; i++) - phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; - - /* Apply component transformation & translation */ - item.transform_points (comp_points); - - /* Apply translation from gvar */ - comp_points.translate (points[comp_index]); - - if (item.is_anchored ()) - { - unsigned int p1, p2; - item.get_anchor_points (p1, p2); - if (likely (p1 < all_points.length && p2 < comp_points.length)) - { - contour_point_t delta; - delta.init (all_points[p1].x - comp_points[p2].x, - all_points[p1].y - comp_points[p2].y); - - comp_points.translate (delta); - } - } - - all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT)); - - comp_index++; - } - - all_points.extend (phantoms); - } break; - default: - all_points.extend (phantoms); - } - - if (depth == 0) /* Apply at top level */ - { - /* Undocumented rasterizer behavior: - * Shift points horizontally by the updated left side bearing - */ - contour_point_t delta; - delta.init (-phantoms[PHANTOM_LEFT].x, 0.f); - if (delta.x) all_points.translate (delta); - } - - return true; - } - - bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator, - hb_glyph_extents_t *extents) const - { - if (type == EMPTY) return true; /* Empty glyph; zero extents. */ - return header->get_extents (font, glyf_accelerator, gid, extents); - } - - hb_bytes_t get_bytes () const { return bytes; } - - Glyph (hb_bytes_t bytes_ = hb_bytes_t (), - hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_), gid (gid_), - header (bytes.as<GlyphHeader> ()) - { - int num_contours = header->numberOfContours; - if (unlikely (num_contours == 0)) type = EMPTY; - else if (num_contours > 0) type = SIMPLE; - else type = COMPOSITE; /* negative numbers */ - } - - protected: - hb_bytes_t bytes; - hb_codepoint_t gid; - const GlyphHeader *header; - unsigned type; - }; - - struct accelerator_t - { - accelerator_t (hb_face_t *face) - { - short_offset = false; - num_glyphs = 0; - loca_table = nullptr; - glyf_table = nullptr; -#ifndef HB_NO_VAR - gvar = nullptr; -#endif - hmtx = nullptr; -#ifndef HB_NO_VERTICAL - vmtx = nullptr; -#endif - const OT::head &head = *face->table.head; - if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0) - /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ - return; - short_offset = 0 == head.indexToLocFormat; - - loca_table = face->table.loca.get_blob (); // Needs no destruct! - glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face); -#ifndef HB_NO_VAR - gvar = face->table.gvar; -#endif - hmtx = face->table.hmtx; -#ifndef HB_NO_VERTICAL - vmtx = face->table.vmtx; -#endif - - num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1; - num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ()); - } - ~accelerator_t () - { - glyf_table.destroy (); - } - - bool has_data () const { return num_glyphs; } - - protected: - template<typename T> - bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) 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; - - bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, phantom_only))) - return false; - - if (consumer.is_consuming_contour_points ()) - { - for (unsigned point_index = 0; point_index + 4 < all_points.length; ++point_index) - consumer.consume_point (all_points[point_index]); - consumer.points_end (); - } - - /* Where to write phantoms, nullptr if not requested */ - contour_point_t *phantoms = consumer.get_phantoms_sink (); - if (phantoms) - for (unsigned i = 0; i < PHANTOM_COUNT; ++i) - phantoms[i] = all_points[all_points.length - PHANTOM_COUNT + i]; - - return true; - } - -#ifndef HB_NO_VAR - struct points_aggregator_t - { - hb_font_t *font; - hb_glyph_extents_t *extents; - contour_point_t *phantoms; - - struct contour_bounds_t - { - contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; } - - void add (const contour_point_t &p) - { - min_x = hb_min (min_x, p.x); - min_y = hb_min (min_y, p.y); - max_x = hb_max (max_x, p.x); - max_y = hb_max (max_y, p.y); - } - - bool empty () const { return (min_x >= max_x) || (min_y >= max_y); } - - void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) - { - if (unlikely (empty ())) - { - extents->width = 0; - extents->x_bearing = 0; - extents->height = 0; - extents->y_bearing = 0; - return; - } - extents->x_bearing = font->em_scalef_x (min_x); - extents->width = font->em_scalef_x (max_x) - extents->x_bearing; - extents->y_bearing = font->em_scalef_y (max_y); - extents->height = font->em_scalef_y (min_y) - extents->y_bearing; - } - - protected: - float min_x, min_y, max_x, max_y; - } bounds; - - points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_) - { - font = font_; - extents = extents_; - phantoms = phantoms_; - if (extents) bounds = contour_bounds_t (); - } - - void consume_point (const contour_point_t &point) { bounds.add (point); } - void points_end () { bounds.get_extents (font, extents); } - - bool is_consuming_contour_points () { return extents; } - contour_point_t *get_phantoms_sink () { return phantoms; } - }; - - public: - unsigned - get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const - { - if (unlikely (gid >= num_glyphs)) return 0; - - bool success = false; - - contour_point_t phantoms[PHANTOM_COUNT]; - if (likely (font->num_coords == gvar->get_axis_count ())) - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms)); - - if (unlikely (!success)) - return -#ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_advance (gid) : -#endif - hmtx->get_advance (gid); - - float result = is_vertical - ? phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y - : phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x; - return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); - } - - int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const - { - if (unlikely (gid >= num_glyphs)) return 0; - - hb_glyph_extents_t extents; - - contour_point_t phantoms[PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms)))) - return -#ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_side_bearing (gid) : -#endif - hmtx->get_side_bearing (gid); - - return is_vertical - ? ceilf (phantoms[PHANTOM_TOP].y) - extents.y_bearing - : floorf (phantoms[PHANTOM_LEFT].x); - } -#endif - - public: - bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const - { - if (unlikely (gid >= num_glyphs)) return false; - -#ifndef HB_NO_VAR - if (font->num_coords && font->num_coords == gvar->get_axis_count ()) - return get_points (font, gid, points_aggregator_t (font, extents, nullptr)); -#endif - return glyph_for_gid (gid).get_extents (font, *this, extents); - } - - const Glyph - glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const - { - if (unlikely (gid >= num_glyphs)) return Glyph (); - - unsigned int start_offset, end_offset; - - if (short_offset) - { - const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ; - start_offset = 2 * offsets[gid]; - end_offset = 2 * offsets[gid + 1]; - } - else - { - const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ; - start_offset = offsets[gid]; - end_offset = offsets[gid + 1]; - } - - if (unlikely (start_offset > end_offset || end_offset > glyf_table.get_length ())) - return Glyph (); - - Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset, - end_offset - start_offset), gid); - return needs_padding_removal ? glyph.trim_padding () : glyph; - } - - unsigned - add_gid_and_children (hb_codepoint_t gid, - hb_set_t *gids_to_retain, - unsigned depth = 0, - unsigned operation_count = 0) const - { - if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count; - if (unlikely (operation_count++ > HB_MAX_COMPOSITE_OPERATIONS)) return operation_count; - /* Check if is already visited */ - if (gids_to_retain->has (gid)) return operation_count; - - gids_to_retain->add (gid); - - auto it = glyph_for_gid (gid).get_composite_iterator (); - while (it) - { - auto item = *(it++); - operation_count = - add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth, operation_count); - } - - return operation_count; - } - - struct path_builder_t - { - hb_font_t *font; - hb_draw_session_t *draw_session; - - struct optional_point_t - { - optional_point_t () { has_data = false; } - optional_point_t (float x_, float y_) { x = x_; y = y_; has_data = true; } - - bool has_data; - float x; - float y; - - optional_point_t lerp (optional_point_t p, float t) - { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); } - } first_oncurve, first_offcurve, last_offcurve; - - path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_) - { - font = font_; - draw_session = &draw_session_; - first_oncurve = first_offcurve = last_offcurve = optional_point_t (); - } - - /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287 - See also: - * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html - * https://stackoverflow.com/a/20772557 */ - void consume_point (const contour_point_t &point) - { - bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE; - optional_point_t p (point.x, point.y); - if (!first_oncurve.has_data) - { - if (is_on_curve) - { - first_oncurve = p; - draw_session->move_to (font->em_fscalef_x (p.x), font->em_fscalef_y (p.y)); - } - else - { - if (first_offcurve.has_data) - { - optional_point_t mid = first_offcurve.lerp (p, .5f); - first_oncurve = mid; - last_offcurve = p; - draw_session->move_to (font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y)); - } - else - first_offcurve = p; - } - } - else - { - if (last_offcurve.has_data) - { - if (is_on_curve) - { - draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y), - font->em_fscalef_x (p.x), font->em_fscalef_y (p.y)); - last_offcurve = optional_point_t (); - } - else - { - optional_point_t mid = last_offcurve.lerp (p, .5f); - draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y), - font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y)); - last_offcurve = p; - } - } - else - { - if (is_on_curve) - draw_session->line_to (font->em_fscalef_x (p.x), font->em_fscalef_y (p.y)); - else - last_offcurve = p; - } - } - - if (point.is_end_point) - { - if (first_offcurve.has_data && last_offcurve.has_data) - { - optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f); - draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y), - font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y)); - last_offcurve = optional_point_t (); - /* now check the rest */ - } - - if (first_offcurve.has_data && first_oncurve.has_data) - draw_session->quadratic_to (font->em_fscalef_x (first_offcurve.x), font->em_fscalef_y (first_offcurve.y), - font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y)); - else if (last_offcurve.has_data && first_oncurve.has_data) - draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y), - font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y)); - else if (first_oncurve.has_data) - draw_session->line_to (font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y)); - else if (first_offcurve.has_data) - { - float x = font->em_fscalef_x (first_offcurve.x), y = font->em_fscalef_x (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 = optional_point_t (); - draw_session->close_path (); - } - } - void points_end () {} - - bool is_consuming_contour_points () { return true; } - contour_point_t *get_phantoms_sink () { return nullptr; } - }; - - bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const - { return get_points (font, gid, path_builder_t (font, draw_session)); } - -#ifndef HB_NO_VAR - const gvar_accelerator_t *gvar; -#endif - const hmtx_accelerator_t *hmtx; -#ifndef HB_NO_VERTICAL - const vmtx_accelerator_t *vmtx; -#endif - - private: - bool short_offset; - unsigned int num_glyphs; - hb_blob_ptr_t<loca> loca_table; - hb_blob_ptr_t<glyf> glyf_table; - }; - - struct SubsetGlyph - { - hb_codepoint_t new_gid; - hb_codepoint_t old_gid; - Glyph source_glyph; - hb_bytes_t dest_start; /* region of source_glyph to copy first */ - hb_bytes_t dest_end; /* region of source_glyph to copy second */ - - bool serialize (hb_serialize_context_t *c, - bool use_short_loca, - const hb_subset_plan_t *plan) const - { - TRACE_SERIALIZE (this); - - hb_bytes_t dest_glyph = dest_start.copy (c); - dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); - unsigned int pad_length = use_short_loca ? padding () : 0; - DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); - - HBUINT8 pad; - pad = 0; - while (pad_length > 0) - { - c->embed (pad); - pad_length--; - } - - if (unlikely (!dest_glyph.length)) return_trace (true); - - /* update components gids */ - for (auto &_ : Glyph (dest_glyph).get_composite_iterator ()) - { - hb_codepoint_t new_gid; - if (plan->new_gid_for_old_gid (_.get_glyph_index (), &new_gid)) - const_cast<CompositeGlyphChain &> (_).set_glyph_index (new_gid); - } - - if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) - Glyph (dest_glyph).drop_hints (); - - if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG) - Glyph (dest_glyph).set_overlaps_flag (); - - return_trace (true); - } - - void drop_hints_bytes () - { source_glyph.drop_hints_bytes (dest_start, dest_end); } - - unsigned int length () const { return dest_start.length + dest_end.length; } - /* pad to 2 to ensure 2-byte loca will be ok */ - unsigned int padding () const { return length () % 2; } - unsigned int padded_size () const { return length () + padding (); } - }; - - protected: - UnsizedArrayOf<HBUINT8> - dataZ; /* Glyphs data. */ - public: - DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always - * check the size externally, allow Null() object of it by - * defining it _MIN instead. */ -}; - -struct glyf_accelerator_t : glyf::accelerator_t { - glyf_accelerator_t (hb_face_t *face) : glyf::accelerator_t (face) {} -}; - - -} /* namespace OT */ - +#include "OT/glyf/glyf.hh" #endif /* HB_OT_GLYF_TABLE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh index d5e1fc91d25..d0e46e0b0fc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh @@ -242,7 +242,7 @@ struct hmtxvmtx return side_bearing; if (var_table.get_length ()) - return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?! + return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); #else @@ -284,7 +284,8 @@ struct hmtxvmtx } unsigned int get_advance (hb_codepoint_t glyph, - hb_font_t *font) const + hb_font_t *font, + VariationStore::cache_t *store_cache = nullptr) const { unsigned int advance = get_advance (glyph); @@ -293,7 +294,7 @@ struct hmtxvmtx return advance; if (var_table.get_length ()) - return advance + roundf (var_table->get_advance_var (glyph, font)); // TODO Optimize?! + return advance + roundf (var_table->get_advance_var (glyph, font, store_cache)); // TODO Optimize?! return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); #else @@ -310,7 +311,7 @@ struct hmtxvmtx unsigned int default_advance; - private: + public: hb_blob_ptr_t<hmtxvmtx> table; hb_blob_ptr_t<HVARVVAR> var_table; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh index b644df708d4..d3438053468 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh @@ -102,7 +102,7 @@ static void ClassDef_remap_and_serialize ( struct hb_prune_langsys_context_t { hb_prune_langsys_context_t (const void *table_, - hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_, + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map_, const hb_map_t *duplicate_feature_map_, hb_set_t *new_collected_feature_indexes_) :table (table_), @@ -122,7 +122,7 @@ struct hb_prune_langsys_context_t public: const void *table; - hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map; + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map; const hb_map_t *duplicate_feature_map; hb_set_t *new_feature_indexes; @@ -162,14 +162,14 @@ struct hb_subset_layout_context_t : hb_subset_context_t *subset_context; const hb_tag_t table_tag; const hb_map_t *lookup_index_map; - const hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map; + const hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map; const hb_map_t *feature_index_map; unsigned cur_script_index; hb_subset_layout_context_t (hb_subset_context_t *c_, hb_tag_t tag_, hb_map_t *lookup_map_, - hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_, + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map_, hb_map_t *feature_index_map_) : subset_context (c_), table_tag (tag_), @@ -659,7 +659,8 @@ struct LangSys auto *out = c->serializer->start_embed (*this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex) ? l->feature_index_map->get (reqFeatureIndex) : 0xFFFFu; + const unsigned *v; + out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; if (!l->visitFeatureIndex (featureIndex.len)) return_trace (false); @@ -722,12 +723,8 @@ struct Script if (!c->script_langsys_map->has (script_index)) { - hb_set_t* empty_set = hb_set_create (); - if (unlikely (!c->script_langsys_map->set (script_index, empty_set))) - { - hb_set_destroy (empty_set); + if (unlikely (!c->script_langsys_map->set (script_index, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) return; - } } unsigned langsys_count = get_lang_sys_count (); @@ -2004,6 +2001,8 @@ struct ClassDefFormat1 return_trace (c->check_struct (this) && classValue.sanitize (c)); } + unsigned cost () const { return 1; } + template <typename set_t> bool collect_coverage (set_t *glyphs) const { @@ -2240,6 +2239,8 @@ struct ClassDefFormat2 return_trace (rangeRecord.sanitize (c)); } + unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ } + template <typename set_t> bool collect_coverage (set_t *glyphs) const { @@ -2480,6 +2481,15 @@ struct ClassDef } } + unsigned cost () const + { + switch (u.format) { + case 1: return u.format1.cost (); + case 2: return u.format2.cost (); + default:return 0u; + } + } + /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template <typename set_t> @@ -2601,14 +2611,27 @@ struct VarRegionAxis DEFINE_SIZE_STATIC (6); }; +#define REGION_CACHE_ITEM_CACHE_INVALID 2.f + struct VarRegionList { + using cache_t = float; + float evaluate (unsigned int region_index, - const int *coords, unsigned int coord_len) const + const int *coords, unsigned int coord_len, + cache_t *cache = nullptr) const { if (unlikely (region_index >= regionCount)) 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 VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); float v = 1.; @@ -2618,9 +2641,16 @@ struct VarRegionList int coord = i < coord_len ? coords[i] : 0; float factor = axes[i].evaluate (coord); if (factor == 0.f) + { + if (cache) + *cached_value = 0.; return 0.; + } v *= factor; } + + if (cache) + *cached_value = v; return v; } @@ -2668,7 +2698,7 @@ struct VarData { return regionIndices.len; } unsigned int get_row_size () const - { return shortCount + regionIndices.len; } + { return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); } unsigned int get_size () const { return min_size @@ -2678,13 +2708,17 @@ struct VarData float get_delta (unsigned int inner, const int *coords, unsigned int coord_count, - const VarRegionList ®ions) const + const VarRegionList ®ions, + VarRegionList::cache_t *cache = nullptr) const { if (unlikely (inner >= itemCount)) return 0.; unsigned int count = regionIndices.len; - unsigned int scount = shortCount; + bool is_long = longWords (); + unsigned word_count = wordCount (); + unsigned int scount = is_long ? count - word_count : word_count; + unsigned int lcount = is_long ? word_count : 0; const HBUINT8 *bytes = get_delta_bytes (); const HBUINT8 *row = bytes + inner * (scount + count); @@ -2692,16 +2726,22 @@ struct VarData float delta = 0.; unsigned int i = 0; - const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row); + const HBINT16 *lcursor = reinterpret_cast<const HBINT16 *> (row); + for (; i < lcount; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + delta += scalar * *lcursor++; + } + const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (lcursor); for (; i < scount; i++) { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count); + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); delta += scalar * *scursor++; } const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor); for (; i < count; i++) { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count); + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); delta += scalar * *bcursor++; } @@ -2725,7 +2765,7 @@ struct VarData TRACE_SANITIZE (this); return_trace (c->check_struct (this) && regionIndices.sanitize (c) && - shortCount <= regionIndices.len && + wordCount () <= regionIndices.len && c->check_range (get_delta_bytes (), itemCount, get_row_size ())); @@ -2740,43 +2780,66 @@ struct VarData if (unlikely (!c->extend_min (this))) return_trace (false); itemCount = inner_map.get_next_value (); - /* Optimize short count */ - unsigned short ri_count = src->regionIndices.len; - enum delta_size_t { kZero=0, kByte, kShort }; + /* Optimize word count */ + unsigned ri_count = src->regionIndices.len; + enum delta_size_t { kZero=0, kNonWord, kWord }; hb_vector_t<delta_size_t> delta_sz; hb_vector_t<unsigned int> ri_map; /* maps old index to new index */ delta_sz.resize (ri_count); ri_map.resize (ri_count); - unsigned int new_short_count = 0; + unsigned int new_word_count = 0; unsigned int r; + + bool has_long = false; + if (src->longWords ()) + { + for (r = 0; r < ri_count; r++) + { + for (unsigned int i = 0; i < inner_map.get_next_value (); i++) + { + unsigned int old = inner_map.backward (i); + int32_t delta = src->get_item_delta (old, r); + if (delta < -65536 || 65535 < delta) + { + has_long = true; + break; + } + } + } + } + + signed min_threshold = has_long ? -65536 : -128; + signed max_threshold = has_long ? +65535 : +127; for (r = 0; r < ri_count; r++) { delta_sz[r] = kZero; for (unsigned int i = 0; i < inner_map.get_next_value (); i++) { unsigned int old = inner_map.backward (i); - int16_t delta = src->get_item_delta (old, r); - if (delta < -128 || 127 < delta) + int32_t delta = src->get_item_delta (old, r); + if (delta < min_threshold || max_threshold < delta) { - delta_sz[r] = kShort; - new_short_count++; + delta_sz[r] = kWord; + new_word_count++; break; } else if (delta != 0) - delta_sz[r] = kByte; + delta_sz[r] = kNonWord; } } - unsigned int short_index = 0; - unsigned int byte_index = new_short_count; + + unsigned int word_index = 0; + unsigned int non_word_index = new_word_count; unsigned int new_ri_count = 0; for (r = 0; r < ri_count; r++) if (delta_sz[r]) { - ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++; + ri_map[r] = (delta_sz[r] == kWord)? word_index++ : non_word_index++; new_ri_count++; } - shortCount = new_short_count; + wordSizeCount = new_word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0); + regionIndices.len = new_ri_count; if (unlikely (!c->extend (this))) return_trace (false); @@ -2816,28 +2879,55 @@ struct VarData HBUINT8 *get_delta_bytes () { return &StructAfter<HBUINT8> (regionIndices); } - int16_t get_item_delta (unsigned int item, unsigned int region) const + int32_t get_item_delta (unsigned int item, unsigned int region) const { if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0; - const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size (); - if (region < shortCount) - return ((const HBINT16 *)p)[region]; + const HBINT8 *p = (const HBINT8 *) get_delta_bytes () + item * get_row_size (); + unsigned word_count = wordCount (); + bool is_long = longWords (); + if (is_long) + { + if (region < word_count) + return ((const HBINT32 *) p)[region]; + else + return ((const HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count]; + } else - return (p + HBINT16::static_size * shortCount)[region - shortCount]; + { + if (region < word_count) + return ((const HBINT16 *) p)[region]; + else + return (p + HBINT16::static_size * word_count)[region - word_count]; + } } - void set_item_delta (unsigned int item, unsigned int region, int16_t delta) + void set_item_delta (unsigned int item, unsigned int region, int32_t delta) { HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size (); - if (region < shortCount) - ((HBINT16 *)p)[region] = delta; + unsigned word_count = wordCount (); + bool is_long = longWords (); + if (is_long) + { + if (region < word_count) + ((HBINT32 *) p)[region] = delta; + else + ((HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count] = delta; + } else - (p + HBINT16::static_size * shortCount)[region - shortCount] = delta; + { + if (region < word_count) + ((HBINT16 *) p)[region] = delta; + else + (p + HBINT16::static_size * word_count)[region - word_count] = delta; + } } + bool longWords () const { return wordSizeCount & 0x8000u /* LONG_WORDS */; } + unsigned wordCount () const { return wordSizeCount & 0x7FFFu /* WORD_DELTA_COUNT_MASK */; } + protected: HBUINT16 itemCount; - HBUINT16 shortCount; + HBUINT16 wordSizeCount; Array16Of<HBUINT16> regionIndices; /*UnsizedArrayOf<HBUINT8>bytesX;*/ public: @@ -2846,9 +2936,28 @@ struct VarData struct VariationStore { + using cache_t = VarRegionList::cache_t; + + cache_t *create_cache () const + { + auto &r = this+regions; + unsigned count = r.regionCount; + + float *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_free (cache); } + private: float get_delta (unsigned int outer, unsigned int inner, - const int *coords, unsigned int coord_count) const + const int *coords, unsigned int coord_count, + VarRegionList::cache_t *cache = nullptr) const { #ifdef HB_NO_VAR return 0.f; @@ -2859,16 +2968,18 @@ struct VariationStore return (this+dataSets[outer]).get_delta (inner, coords, coord_count, - this+regions); + this+regions, + cache); } public: float get_delta (unsigned int index, - const int *coords, unsigned int coord_count) const + const int *coords, unsigned int coord_count, + VarRegionList::cache_t *cache = nullptr) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; - return get_delta (outer, inner, coords, coord_count); + return get_delta (outer, inner, coords, coord_count, cache); } bool sanitize (hb_sanitize_context_t *c) const @@ -2995,6 +3106,8 @@ struct VariationStore DEFINE_SIZE_ARRAY_SIZED (8, dataSets); }; +#undef REGION_CACHE_ITEM_CACHE_INVALID + /* * Feature Variations */ @@ -3462,11 +3575,15 @@ struct VariationDevice private: - hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store) const - { return font->em_scalef_x (get_delta (font, store)); } + hb_position_t get_x_delta (hb_font_t *font, + const VariationStore &store, + VariationStore::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) const - { return font->em_scalef_y (get_delta (font, store)); } + hb_position_t get_y_delta (hb_font_t *font, + const VariationStore &store, + VariationStore::cache_t *store_cache = nullptr) const + { return font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map) const { @@ -3500,9 +3617,11 @@ struct VariationDevice private: - float get_delta (hb_font_t *font, const VariationStore &store) const + float get_delta (hb_font_t *font, + const VariationStore &store, + VariationStore::cache_t *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords); + return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache); } protected: @@ -3525,7 +3644,9 @@ struct DeviceHeader struct Device { - hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const + hb_position_t get_x_delta (hb_font_t *font, + const VariationStore &store=Null (VariationStore), + VariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -3535,13 +3656,15 @@ struct Device #endif #ifndef HB_NO_VAR case 0x8000: - return u.variation.get_x_delta (font, store); + return u.variation.get_x_delta (font, store, store_cache); #endif default: return 0; } } - hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const + hb_position_t get_y_delta (hb_font_t *font, + const VariationStore &store=Null (VariationStore), + VariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -3551,7 +3674,7 @@ struct Device #endif #ifndef HB_NO_VAR case 0x8000: - return u.variation.get_y_delta (font, store); + return u.variation.get_y_delta (font, store, store_cache); #endif default: return 0; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh index a76d644c4b2..9d47bac2b9b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh @@ -571,7 +571,7 @@ struct GDEF static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), ""); switch (klass) { - default: return 0; + default: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED; case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH; case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; case MarkGlyph: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh index 2f9186a2a75..f476397e321 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh @@ -146,23 +146,24 @@ struct ValueFormat : HBUINT16 if (!use_x_device && !use_y_device) return ret; const VariationStore &store = c->var_store; + auto *cache = c->var_store_cache; /* pixel -> fractional pixel */ if (format & xPlaDevice) { - if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store); + if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store, cache); values++; } if (format & yPlaDevice) { - if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store); + if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store, cache); values++; } if (format & xAdvDevice) { - if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store); + if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store, cache); values++; } if (format & yAdvDevice) { /* y_advance values grow downward but font-space grows upward, hence negation */ - if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store); + if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store, cache); values++; } return ret; @@ -465,9 +466,9 @@ struct AnchorFormat3 *y = font->em_fscale_y (yCoordinate); if (font->x_ppem || font->num_coords) - *x += (this+xDeviceTable).get_x_delta (font, c->var_store); + *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); if (font->y_ppem || font->num_coords) - *y += (this+yDeviceTable).get_y_delta (font, c->var_store); + *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); } bool sanitize (hb_sanitize_context_t *c) const @@ -2881,7 +2882,7 @@ struct PosLookupSubTable struct PosLookup : Lookup { - typedef struct PosLookupSubTable SubTable; + using SubTable = PosLookupSubTable; const SubTable& get_subtable (unsigned int i) const { return Lookup::get_subtable<SubTable> (i); } @@ -2917,7 +2918,6 @@ struct PosLookup : Lookup c->set_lookup_inactive (this_index); return hb_closure_lookups_context_t::default_return_value (); } - c->set_recurse_func (dispatch_closure_lookups_recurse_func); hb_closure_lookups_context_t::return_t ret = dispatch (c); return ret; @@ -2930,13 +2930,9 @@ struct PosLookup : Lookup dispatch (&c); } - static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); - template <typename context_t> static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); - HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index); - template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); } @@ -2957,6 +2953,8 @@ struct GPOS : GSUBGPOS { static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS; + using Lookup = PosLookup; + const PosLookup& get_lookup (unsigned int i) const { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); } @@ -3024,7 +3022,8 @@ static void propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int len, unsigned int i, - hb_direction_t direction) + hb_direction_t direction, + unsigned nesting_level = HB_MAX_NESTING_LEVEL) { /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate * offset of glyph they are attached to. */ @@ -3039,7 +3038,10 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, if (unlikely (j >= len)) return; - propagate_attachment_offsets (pos, len, j, direction); + if (unlikely (!nesting_level)) + return; + + propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE)); @@ -3121,13 +3123,16 @@ template <typename context_t> return l.dispatch (c); } -/*static*/ inline hb_closure_lookups_context_t::return_t PosLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index) +template <> +inline hb_closure_lookups_context_t::return_t +PosLookup::dispatch_recurse_func<hb_closure_lookups_context_t> (hb_closure_lookups_context_t *c, unsigned this_index) { const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (this_index); return l.closure_lookups (c, this_index); } -/*static*/ bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) +template <> +inline bool PosLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply_context_t *c, unsigned int lookup_index) { const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh index bef381430b5..462542025b5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh @@ -59,13 +59,16 @@ template <typename context_t> return l.dispatch (c); } -/*static*/ inline hb_closure_lookups_context_t::return_t SubstLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index) +template <> +inline hb_closure_lookups_context_t::return_t +SubstLookup::dispatch_recurse_func<hb_closure_lookups_context_t> (hb_closure_lookups_context_t *c, unsigned this_index) { const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (this_index); return l.closure_lookups (c, this_index); } -/*static*/ bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) +template <> +inline bool SubstLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply_context_t *c, unsigned int lookup_index) { const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh index c9750ff63b5..31da4986520 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh @@ -109,14 +109,10 @@ struct hb_closure_context_t : { done_lookups_glyph_count->set (lookup_index, glyphs->get_population ()); - if (!done_lookups_glyph_set->get (lookup_index)) + if (!done_lookups_glyph_set->has (lookup_index)) { - hb_set_t* empty_set = hb_set_create (); - if (unlikely (!done_lookups_glyph_set->set (lookup_index, empty_set))) - { - hb_set_destroy (empty_set); + if (unlikely (!done_lookups_glyph_set->set (lookup_index, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) return true; - } } hb_set_clear (done_lookups_glyph_set->get (lookup_index)); @@ -165,21 +161,19 @@ struct hb_closure_context_t : hb_set_t *glyphs; hb_set_t output[1]; hb_vector_t<hb_set_t> active_glyphs_stack; - recurse_func_t recurse_func; + recurse_func_t recurse_func = nullptr; unsigned int nesting_level_left; hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, hb_map_t *done_lookups_glyph_count_, - hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_, + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *done_lookups_glyph_set_, unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), - recurse_func (nullptr), nesting_level_left (nesting_level_left_), done_lookups_glyph_count (done_lookups_glyph_count_), - done_lookups_glyph_set (done_lookups_glyph_set_), - lookup_count (0) + done_lookups_glyph_set (done_lookups_glyph_set_) {} ~hb_closure_context_t () { flush (); } @@ -197,8 +191,8 @@ struct hb_closure_context_t : private: hb_map_t *done_lookups_glyph_count; - hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set; - unsigned int lookup_count; + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *done_lookups_glyph_set; + unsigned int lookup_count = 0; }; @@ -400,7 +394,6 @@ struct hb_collect_coverage_context_t : set_t *set; }; - struct hb_ot_apply_context_t : hb_dispatch_context_t<hb_ot_apply_context_t, bool, HB_DEBUG_APPLY> { @@ -416,7 +409,7 @@ struct hb_ot_apply_context_t : match_func (nullptr), match_data (nullptr) {} - typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data); + typedef bool (*match_func_t) (hb_glyph_info_t &info, const HBUINT16 &value, const void *data); void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } @@ -434,7 +427,7 @@ struct hb_ot_apply_context_t : MATCH_MAYBE }; - may_match_t may_match (const hb_glyph_info_t &info, + may_match_t may_match (hb_glyph_info_t &info, const HBUINT16 *glyph_data) const { if (!(info.mask & mask) || @@ -442,7 +435,7 @@ struct hb_ot_apply_context_t : return MATCH_NO; if (match_func) - return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; + return match_func (info, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; return MATCH_MAYBE; } @@ -530,7 +523,7 @@ struct hb_ot_apply_context_t : while (idx + num_items < end) { idx++; - const hb_glyph_info_t &info = c->buffer->info[idx]; + hb_glyph_info_t &info = c->buffer->info[idx]; matcher_t::may_skip_t skip = matcher.may_skip (c, info); if (unlikely (skip == matcher_t::SKIP_YES)) @@ -563,7 +556,7 @@ struct hb_ot_apply_context_t : while (idx > num_items - 1) { idx--; - const hb_glyph_info_t &info = c->buffer->out_info[idx]; + hb_glyph_info_t &info = c->buffer->out_info[idx]; matcher_t::may_skip_t skip = matcher.may_skip (c, info); if (unlikely (skip == matcher_t::SKIP_YES)) @@ -611,7 +604,10 @@ struct hb_ot_apply_context_t : return_t recurse (unsigned int sub_lookup_index) { if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0)) + { + buffer->shaping_failed = true; return default_return_value (); + } nesting_level_left--; bool ret = recurse_func (this, sub_lookup_index); @@ -621,35 +617,34 @@ struct hb_ot_apply_context_t : skipping_iterator_t iter_input, iter_context; + unsigned int table_index; /* GSUB/GPOS */ hb_font_t *font; hb_face_t *face; hb_buffer_t *buffer; - recurse_func_t recurse_func; + recurse_func_t recurse_func = nullptr; const GDEF &gdef; const VariationStore &var_store; + VariationStore::cache_t *var_store_cache; hb_direction_t direction; - hb_mask_t lookup_mask; - unsigned int table_index; /* GSUB/GPOS */ - unsigned int lookup_index; - unsigned int lookup_props; - unsigned int nesting_level_left; + hb_mask_t lookup_mask = 1; + unsigned int lookup_index = (unsigned) -1; + unsigned int lookup_props = 0; + unsigned int nesting_level_left = HB_MAX_NESTING_LEVEL; bool has_glyph_classes; - bool auto_zwnj; - bool auto_zwj; - bool per_syllable; - bool random; - - uint32_t random_state; - + bool auto_zwnj = true; + bool auto_zwj = true; + bool per_syllable = false; + bool random = false; + uint32_t random_state = 1; + unsigned new_syllables = (unsigned) -1; hb_ot_apply_context_t (unsigned int table_index_, hb_font_t *font_, hb_buffer_t *buffer_) : - iter_input (), iter_context (), + table_index (table_index_), font (font_), face (font->face), buffer (buffer_), - recurse_func (nullptr), gdef ( #ifndef HB_NO_OT_LAYOUT *face->table.GDEF->table @@ -658,18 +653,23 @@ struct hb_ot_apply_context_t : #endif ), var_store (gdef.get_var_store ()), + var_store_cache ( +#ifndef HB_NO_VAR + table_index == 1 && font->num_coords ? var_store.create_cache () : nullptr +#else + nullptr +#endif + ), direction (buffer_->props.direction), - lookup_mask (1), - table_index (table_index_), - lookup_index ((unsigned int) -1), - lookup_props (0), - nesting_level_left (HB_MAX_NESTING_LEVEL), - has_glyph_classes (gdef.has_glyph_classes ()), - auto_zwnj (true), - auto_zwj (true), - per_syllable (false), - random (false), - random_state (1) { init_iters (); } + has_glyph_classes (gdef.has_glyph_classes ()) + { init_iters (); } + + ~hb_ot_apply_context_t () + { +#ifndef HB_NO_VAR + VariationStore::destroy_cache (var_store_cache); +#endif + } void init_iters () { @@ -736,6 +736,9 @@ struct hb_ot_apply_context_t : bool ligature = false, bool component = false) const { + if (new_syllables != (unsigned) -1) + buffer->cur().syllable() = new_syllables; + unsigned int props = _hb_glyph_info_get_glyph_props (&buffer->cur()); props |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED; if (ligature) @@ -790,8 +793,8 @@ struct hb_ot_apply_context_t : }; -struct hb_get_subtables_context_t : - hb_dispatch_context_t<hb_get_subtables_context_t> +struct hb_accelerate_subtables_context_t : + hb_dispatch_context_t<hb_accelerate_subtables_context_t> { template <typename Type> static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) @@ -800,15 +803,53 @@ struct hb_get_subtables_context_t : return typed_obj->apply (c); } +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + template <typename T> + static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) ) + template <typename T> + static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) + template <typename Type> + static inline bool apply_cached_to (const void *obj, OT::hb_ot_apply_context_t *c) + { + const Type *typed_obj = (const Type *) obj; + return apply_cached_ (typed_obj, c, hb_prioritize); + } + + template <typename T> + static inline auto cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) ) + template <typename T> + static inline bool cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; } + template <typename Type> + static inline bool cache_func_to (const void *obj, OT::hb_ot_apply_context_t *c, bool enter) + { + const Type *typed_obj = (const Type *) obj; + return cache_func_ (typed_obj, c, enter, hb_prioritize); + } +#endif + typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c); + typedef bool (*hb_cache_func_t) (const void *obj, OT::hb_ot_apply_context_t *c, bool enter); struct hb_applicable_t { + friend struct hb_accelerate_subtables_context_t; + friend struct hb_ot_layout_lookup_accelerator_t; + template <typename T> - void init (const T &obj_, hb_apply_func_t apply_func_) + void init (const T &obj_, + hb_apply_func_t apply_func_ +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + , hb_apply_func_t apply_cached_func_ + , hb_cache_func_t cache_func_ +#endif + ) { obj = &obj_; apply_func = apply_func_; +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + apply_cached_func = apply_cached_func_; + cache_func = cache_func_; +#endif digest.init (); obj_.get_coverage ().collect_coverage (&digest); } @@ -817,38 +858,93 @@ struct hb_get_subtables_context_t : { return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c); } +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + bool apply_cached (OT::hb_ot_apply_context_t *c) const + { + return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c); + } + bool cache_enter (OT::hb_ot_apply_context_t *c) const + { + return cache_func (obj, c, true); + } + void cache_leave (OT::hb_ot_apply_context_t *c) const + { + cache_func (obj, c, false); + } +#endif private: const void *obj; hb_apply_func_t apply_func; +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + hb_apply_func_t apply_cached_func; + hb_cache_func_t cache_func; +#endif hb_set_digest_t digest; }; typedef hb_vector_t<hb_applicable_t> array_t; +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + template <typename T> + auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () ) + template <typename T> + auto cache_cost (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( 0u ) +#endif + /* Dispatch interface. */ template <typename T> return_t dispatch (const T &obj) { - hb_applicable_t *entry = array.push(); - entry->init (obj, apply_to<T>); + hb_applicable_t entry; + + entry.init (obj, + apply_to<T> +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + , apply_cached_to<T> + , cache_func_to<T> +#endif + ); + + array.push (entry); + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + /* Cache handling + * + * We allow one subtable from each lookup to use a cache. The assumption + * being that multiple subtables of the same lookup cannot use a cache + * because the resources they would use will collide. As such, we ask + * each subtable to tell us how much it costs (which a cache would avoid), + * and we allocate the cache opportunity to the costliest subtable. + */ + unsigned cost = cache_cost (obj, hb_prioritize); + if (cost > cache_user_cost && !array.in_error ()) + { + cache_user_idx = array.length - 1; + cache_user_cost = cost; + } +#endif + return hb_empty_t (); } static return_t default_return_value () { return hb_empty_t (); } - hb_get_subtables_context_t (array_t &array_) : - array (array_) {} + hb_accelerate_subtables_context_t (array_t &array_) : + array (array_) {} array_t &array; -}; - +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + unsigned cache_user_idx = (unsigned) -1; + unsigned cache_user_cost = 0; +#endif +}; typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data); typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs); typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data); -typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data); +typedef bool (*match_func_t) (hb_glyph_info_t &info, const HBUINT16 &value, const void *data); struct ContextClosureFuncs { @@ -863,6 +959,10 @@ struct ContextApplyFuncs { match_func_t match; }; +struct ChainContextApplyFuncs +{ + match_func_t match[3]; +}; static inline bool intersects_glyph (const hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) @@ -939,19 +1039,30 @@ static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, } -static inline bool match_glyph (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data HB_UNUSED) +static inline bool match_glyph (hb_glyph_info_t &info, const HBUINT16 &value, const void *data HB_UNUSED) { - return glyph_id == value; + return info.codepoint == value; } -static inline bool match_class (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data) +static inline bool match_class (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); - return class_def.get_class (glyph_id) == value; + return class_def.get_class (info.codepoint) == value; } -static inline bool match_coverage (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data) +static inline bool match_class_cached (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) +{ + unsigned klass = info.syllable(); + if (klass < 255) + return klass == value; + const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); + klass = class_def.get_class (info.codepoint); + if (likely (klass < 255)) + info.syllable() = klass; + return klass == value; +} +static inline bool match_coverage (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) { const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; - return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; + return (data+coverage).get_coverage (info.codepoint) != NOT_COVERED; } static inline bool would_match_input (hb_would_apply_context_t *c, @@ -964,8 +1075,12 @@ static inline bool would_match_input (hb_would_apply_context_t *c, return false; for (unsigned int i = 1; i < count; i++) - if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) + { + hb_glyph_info_t info; + info.codepoint = c->glyphs[i]; + if (likely (!match_func (info, input[i - 1], match_data))) return false; + } return true; } @@ -2125,19 +2240,54 @@ struct ContextFormat2 const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + unsigned cache_cost () const + { + unsigned c = (this+classDef).cost () * ruleSet.len; + return c >= 4 ? c : 0; + } + bool cache_func (hb_ot_apply_context_t *c, bool enter) const + { + 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 + { + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + return true; + } + } + + bool apply (hb_ot_apply_context_t *c, bool cached = false) const { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); const ClassDef &class_def = this+classDef; - index = class_def.get_class (c->buffer->cur().codepoint); - const RuleSet &rule_set = this+ruleSet[index]; + struct ContextApplyLookupContext lookup_context = { - {match_class}, + {cached ? match_class_cached : match_class}, &class_def }; + + if (cached && c->buffer->cur().syllable() < 255) + index = c->buffer->cur().syllable (); + else + { + index = class_def.get_class (c->buffer->cur().codepoint); + if (cached && index < 255) + c->buffer->cur().syllable() = index; + } + const RuleSet &rule_set = this+ruleSet[index]; return_trace (rule_set.apply (c, lookup_context)); } @@ -2411,7 +2561,7 @@ struct ChainContextCollectGlyphsLookupContext struct ChainContextApplyLookupContext { - ContextApplyFuncs funcs; + ChainContextApplyFuncs funcs; const void *match_data[3]; }; @@ -2499,7 +2649,7 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c return (c->zero_context ? !backtrackCount && !lookaheadCount : true) && would_match_input (c, inputCount, input, - lookup_context.funcs.match, lookup_context.match_data[1]); + lookup_context.funcs.match[1], lookup_context.match_data[1]); } static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, @@ -2518,11 +2668,11 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, unsigned match_positions[HB_MAX_CONTEXT_LENGTH]; if (!(match_input (c, inputCount, input, - lookup_context.funcs.match, lookup_context.match_data[1], + lookup_context.funcs.match[1], lookup_context.match_data[1], &match_end, match_positions) && (end_index = match_end) && match_lookahead (c, lookaheadCount, lookahead, - lookup_context.funcs.match, lookup_context.match_data[2], + lookup_context.funcs.match[2], lookup_context.match_data[2], match_end, &end_index))) { c->buffer->unsafe_to_concat (c->buffer->idx, end_index); @@ -2532,7 +2682,7 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, unsigned start_index = c->buffer->out_len; if (!match_backtrack (c, backtrackCount, backtrack, - lookup_context.funcs.match, lookup_context.match_data[0], + lookup_context.funcs.match[0], lookup_context.match_data[0], &start_index)) { c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index); @@ -2934,7 +3084,7 @@ struct ChainContextFormat1 { const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; struct ChainContextApplyLookupContext lookup_context = { - {match_glyph}, + {{match_glyph, match_glyph, match_glyph}}, {nullptr, nullptr, nullptr} }; return rule_set.would_apply (c, lookup_context); @@ -2950,7 +3100,7 @@ struct ChainContextFormat1 const ChainRuleSet &rule_set = this+ruleSet[index]; struct ChainContextApplyLookupContext lookup_context = { - {match_glyph}, + {{match_glyph, match_glyph, match_glyph}}, {nullptr, nullptr, nullptr} }; return_trace (rule_set.apply (c, lookup_context)); @@ -3134,7 +3284,7 @@ struct ChainContextFormat2 unsigned int index = input_class_def.get_class (c->glyphs[0]); const ChainRuleSet &rule_set = this+ruleSet[index]; struct ChainContextApplyLookupContext lookup_context = { - {match_class}, + {{match_class, match_class, match_class}}, {&backtrack_class_def, &input_class_def, &lookahead_class_def} @@ -3144,7 +3294,33 @@ struct ChainContextFormat2 const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + unsigned cache_cost () const + { + unsigned c = (this+lookaheadClassDef).cost () * ruleSet.len; + return c >= 4 ? c : 0; + } + bool cache_func (hb_ot_apply_context_t *c, bool enter) const + { + 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 + { + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + return true; + } + } + + bool apply (hb_ot_apply_context_t *c, bool cached = false) const { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); @@ -3154,14 +3330,27 @@ struct ChainContextFormat2 const ClassDef &input_class_def = this+inputClassDef; const ClassDef &lookahead_class_def = this+lookaheadClassDef; - index = input_class_def.get_class (c->buffer->cur().codepoint); - const ChainRuleSet &rule_set = this+ruleSet[index]; + /* For ChainContextFormat2 we cache the LookaheadClassDef instead of InputClassDef. + * The reason is that most heavy fonts want to identify a glyph in context and apply + * a lookup to it. In this scenario, the length of the input sequence is one, whereas + * the lookahead / backtrack are typically longer. The one glyph in input sequence is + * looked-up below and no input glyph is looked up in individual rules, whereas the + * lookahead and backtrack glyphs are tried. Since we match lookahead before backtrack, + * we should cache lookahead. This decisions showed a 20% improvement in shaping of + * the Gulzar font. + */ + struct ChainContextApplyLookupContext lookup_context = { - {match_class}, + {{cached && &backtrack_class_def == &input_class_def ? match_class_cached : match_class, + cached && &input_class_def == &lookahead_class_def ? match_class_cached : match_class, + cached ? match_class_cached : match_class}}, {&backtrack_class_def, &input_class_def, &lookahead_class_def} }; + + index = input_class_def.get_class (c->buffer->cur().codepoint); + const ChainRuleSet &rule_set = this+ruleSet[index]; return_trace (rule_set.apply (c, lookup_context)); } @@ -3359,7 +3548,7 @@ struct ChainContextFormat3 const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); struct ChainContextApplyLookupContext lookup_context = { - {match_coverage}, + {{match_coverage, match_coverage, match_coverage}}, {this, this, this} }; return chain_context_would_apply_lookup (c, @@ -3386,7 +3575,7 @@ struct ChainContextFormat3 const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); struct ChainContextApplyLookupContext lookup_context = { - {match_coverage}, + {{match_coverage, match_coverage, match_coverage}}, {this, this, this} }; return_trace (chain_context_apply_lookup (c, @@ -3623,25 +3812,63 @@ struct hb_ot_layout_lookup_accelerator_t lookup.collect_coverage (&digest); subtables.init (); - OT::hb_get_subtables_context_t c_get_subtables (subtables); - lookup.dispatch (&c_get_subtables); + OT::hb_accelerate_subtables_context_t c_accelerate_subtables (subtables); + lookup.dispatch (&c_accelerate_subtables); + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + cache_user_idx = c_accelerate_subtables.cache_user_idx; + for (unsigned i = 0; i < subtables.length; i++) + if (i != cache_user_idx) + subtables[i].apply_cached_func = subtables[i].apply_func; +#endif } void fini () { subtables.fini (); } bool may_have (hb_codepoint_t g) const { return digest.may_have (g); } - bool apply (hb_ot_apply_context_t *c) const + bool apply (hb_ot_apply_context_t *c, bool use_cache) const { - for (unsigned int i = 0; i < subtables.length; i++) - if (subtables[i].apply (c)) - return true; +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + if (use_cache) + { + for (unsigned int i = 0; i < subtables.length; i++) + if (subtables[i].apply_cached (c)) + return true; + } + else +#endif + { + for (unsigned int i = 0; i < subtables.length; i++) + if (subtables[i].apply (c)) + return true; + } return false; } + bool cache_enter (OT::hb_ot_apply_context_t *c) const + { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + return cache_user_idx != (unsigned) -1 && + subtables[cache_user_idx].cache_enter (c); +#else + return false; +#endif + } + void cache_leave (OT::hb_ot_apply_context_t *c) const + { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + subtables[cache_user_idx].cache_leave (c); +#endif + } + + private: hb_set_digest_t digest; - hb_get_subtables_context_t::array_t subtables; + hb_accelerate_subtables_context_t::array_t subtables; +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + unsigned cache_user_idx = (unsigned) -1; +#endif }; struct GSUBGPOS @@ -3721,6 +3948,8 @@ struct GSUBGPOS hb_set_t visited_lookups, inactive_lookups; OT::hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups); + c.set_recurse_func (TLookup::template dispatch_recurse_func<hb_closure_lookups_context_t>); + for (unsigned lookup_index : + hb_iter (lookup_indexes)) reinterpret_cast<const TLookup &> (get_lookup (lookup_index)).closure_lookups (&c, lookup_index); @@ -3729,7 +3958,7 @@ struct GSUBGPOS } void prune_langsys (const hb_map_t *duplicate_feature_map, - hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map, + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map, hb_set_t *new_feature_indexes /* OUT */) const { hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes); @@ -3787,7 +4016,7 @@ struct GSUBGPOS hb_map_t *duplicate_feature_map /* OUT */) const { if (feature_indices->is_empty ()) return; - hb_hashmap_t<hb_tag_t, hb_set_t *> unique_features; + hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_set_t>> unique_features; //find out duplicate features after subset for (unsigned i : feature_indices->iter ()) { @@ -3795,16 +4024,9 @@ struct GSUBGPOS if (t == HB_MAP_VALUE_INVALID) continue; if (!unique_features.has (t)) { - hb_set_t* indices = hb_set_create (); - if (unlikely (indices == hb_set_get_empty () || - !unique_features.set (t, indices))) - { - hb_set_destroy (indices); - for (auto _ : unique_features.iter ()) - hb_set_destroy (_.second); + if (unlikely (!unique_features.set (t, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) return; - } - if (unique_features.get (t)) + if (unique_features.has (t)) unique_features.get (t)->add (i); duplicate_feature_map->set (i, i); continue; @@ -3849,9 +4071,6 @@ struct GSUBGPOS duplicate_feature_map->set (i, i); } } - - for (auto _ : unique_features.iter ()) - hb_set_destroy (_.second); } void prune_features (const hb_map_t *lookup_indices, /* IN */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index f4ea21a4f9c..aa5321362f7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -46,7 +46,7 @@ #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-layout-base-table.hh" // Just so we compile it; unused otherwise. +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise. #include "hb-ot-name-table.hh" #include "hb-ot-os2-table.hh" @@ -260,7 +260,6 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, { _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint)); _hb_glyph_info_clear_lig_props (&buffer->info[i]); - buffer->info[i].syllable() = 0; } } @@ -1501,15 +1500,12 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, hb_set_t *glyphs /* OUT */) { hb_map_t done_lookups_glyph_count; - hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set; + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> done_lookups_glyph_set; OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set); const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); l.closure (&c, lookup_index); - - for (auto _ : done_lookups_glyph_set.iter ()) - hb_set_destroy (_.second); } /** @@ -1529,7 +1525,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, hb_set_t *glyphs /* OUT */) { hb_map_t done_lookups_glyph_count; - hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set; + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> done_lookups_glyph_set; OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set); const GSUB& gsub = *face->table.GSUB->table; @@ -1551,9 +1547,6 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, } } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES && glyphs_length != glyphs->get_population ()); - - for (auto _ : done_lookups_glyph_set.iter ()) - hb_set_destroy (_.second); } /* @@ -1803,7 +1796,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, struct GSUBProxy { static constexpr unsigned table_index = 0u; - static constexpr bool inplace = false; + static constexpr bool always_inplace = false; typedef OT::SubstLookup Lookup; GSUBProxy (hb_face_t *face) : @@ -1817,7 +1810,7 @@ struct GSUBProxy struct GPOSProxy { static constexpr unsigned table_index = 1u; - static constexpr bool inplace = true; + static constexpr bool always_inplace = true; typedef OT::PosLookup Lookup; GPOSProxy (hb_face_t *face) : @@ -1833,6 +1826,8 @@ static inline bool apply_forward (OT::hb_ot_apply_context_t *c, const OT::hb_ot_layout_lookup_accelerator_t &accel) { + bool use_cache = accel.cache_enter (c); + bool ret = false; hb_buffer_t *buffer = c->buffer; while (buffer->idx < buffer->len && buffer->successful) @@ -1842,7 +1837,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) { - applied = accel.apply (c); + applied = accel.apply (c, use_cache); } if (applied) @@ -1850,6 +1845,10 @@ apply_forward (OT::hb_ot_apply_context_t *c, else (void) buffer->next_glyph (); } + + if (use_cache) + accel.cache_leave (c); + return ret; } @@ -1864,7 +1863,7 @@ apply_backward (OT::hb_ot_apply_context_t *c, if (accel.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) - ret |= accel.apply (c); + ret |= accel.apply (c, false); /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; @@ -1890,13 +1889,13 @@ apply_string (OT::hb_ot_apply_context_t *c, if (likely (!lookup.is_reverse ())) { /* in/out forward substitution/positioning */ - if (!Proxy::inplace) + if (!Proxy::always_inplace) buffer->clear_output (); buffer->idx = 0; apply_forward (c, accel); - if (!Proxy::inplace) + if (!Proxy::always_inplace) buffer->sync (); } else @@ -1917,7 +1916,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, const unsigned int table_index = proxy.table_index; unsigned int i = 0; OT::hb_ot_apply_context_t c (table_index, font, buffer); - c.set_recurse_func (Proxy::Lookup::apply_recurse_func); + c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func<OT::hb_ot_apply_context_t>); for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh index 75bba0bc506..6395f066706 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh @@ -589,13 +589,11 @@ _hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer) { HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props); HB_BUFFER_ALLOCATE_VAR (buffer, lig_props); - HB_BUFFER_ALLOCATE_VAR (buffer, syllable); } static inline void _hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer) { - HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props); HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props); } @@ -605,7 +603,6 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer) { HB_BUFFER_ASSERT_VAR (buffer, glyph_props); HB_BUFFER_ASSERT_VAR (buffer, lig_props); - HB_BUFFER_ASSERT_VAR (buffer, syllable); } /* Make sure no one directly touches our props... */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh index c496dc2981a..0e0f2d632af 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh @@ -45,7 +45,7 @@ struct hb_ot_language_map_t }; static const hb_ot_language_map_t -hb_ms_language_map[] = +_hb_ms_language_map[] = { {0x0001, "ar"}, /* ??? */ {0x0004, "zh"}, /* ??? */ @@ -298,7 +298,7 @@ hb_ms_language_map[] = }; static const hb_ot_language_map_t -hb_mac_language_map[] = +_hb_mac_language_map[] = { { 0, "en"}, /* English */ { 1, "fr"}, /* French */ @@ -441,16 +441,16 @@ hb_language_t _hb_ot_name_language_for_ms_code (unsigned int code) { return _hb_ot_name_language_for (code, - hb_ms_language_map, - ARRAY_LENGTH (hb_ms_language_map)); + _hb_ms_language_map, + ARRAY_LENGTH (_hb_ms_language_map)); } hb_language_t _hb_ot_name_language_for_mac_code (unsigned int code) { return _hb_ot_name_language_for (code, - hb_mac_language_map, - ARRAY_LENGTH (hb_mac_language_map)); + _hb_mac_language_map, + ARRAY_LENGTH (_hb_mac_language_map)); } #endif /* HB_OT_NAME_LANGUAGE_STATIC_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh index d52367e9b1c..01107aad67b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh @@ -156,7 +156,7 @@ struct NameRecord }; static int -_hb_ot_name_entry_cmp_key (const void *pa, const void *pb) +_hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact) { const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa; const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; @@ -169,8 +169,23 @@ _hb_ot_name_entry_cmp_key (const void *pa, const void *pb) if (a->language == b->language) return 0; if (!a->language) return -1; if (!b->language) return +1; - return strcmp (hb_language_to_string (a->language), - hb_language_to_string (b->language)); + + const char *astr = hb_language_to_string (a->language); + const char *bstr = hb_language_to_string (b->language); + + signed c = strcmp (astr, bstr); + + if (!exact && c) + { + unsigned la = strlen (astr); + unsigned lb = strlen (bstr); + // 'a' is the user request, and 'b' is string in the font. + // If eg. user asks for "en-us" and font has "en", approve. + if (la > lb && astr[lb] == '-' && !strncmp (astr, bstr, lb)) + return 0; + } + + return c; } static int @@ -178,7 +193,7 @@ _hb_ot_name_entry_cmp (const void *pa, const void *pb) { /* Compare by name_id, then language, then score, then index. */ - int v = _hb_ot_name_entry_cmp_key (pa, pb); + int v = _hb_ot_name_entry_cmp_key (pa, pb, true); if (v) return v; @@ -330,7 +345,18 @@ struct name const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names, this->names.length, sizeof (hb_ot_name_entry_t), - _hb_ot_name_entry_cmp_key); + _hb_ot_name_entry_cmp_key, + true); + + if (!entry) + { + entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names, + this->names.length, + sizeof (hb_ot_name_entry_t), + _hb_ot_name_entry_cmp_key, + false); + } + if (!entry) return -1; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh index f0035e2f04e..3473afef546 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh @@ -224,9 +224,11 @@ struct OS2 *max_cp = hb_min (0xFFFFu, codepoints->get_max ()); } - /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 */ + /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 + * https://docs.microsoft.com/en-us/typography/legacy/legacy_arabic_fonts */ enum font_page_t { + FONT_PAGE_NONE = 0, FONT_PAGE_HEBREW = 0xB100, /* Hebrew Windows 3.1 font page */ FONT_PAGE_SIMP_ARABIC = 0xB200, /* Simplified Arabic Windows 3.1 font page */ FONT_PAGE_TRAD_ARABIC = 0xB300, /* Traditional Arabic Windows 3.1 font page */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh index 0f3cd8e24fe..4d427e54312 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh @@ -52,16 +52,16 @@ HB_INTERNAL bool postV2Tail::serialize (hb_serialize_context_t *c, { unsigned glyph_id = _.first; unsigned new_index = _.second; - + if (new_index < 258) continue; if (copied_indices.has (new_index)) continue; copied_indices.add (new_index); - + hb_bytes_t s = reinterpret_cast<const post::accelerator_t*> (_post)->find_glyph_name (glyph_id); HBUINT8 *o = c->allocate_size<HBUINT8> (HBUINT8::static_size * (s.length + 1)); if (unlikely (!o)) return_trace (false); if (!c->check_assign (o[0], s.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); - memcpy (o+1, s.arrayZ, HBUINT8::static_size * s.length); + hb_memcpy (o+1, s.arrayZ, HBUINT8::static_size * s.length); } return_trace (true); @@ -78,17 +78,19 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const post::accelerator_t _post (c->plan->source); - hb_hashmap_t<hb_bytes_t, unsigned, std::nullptr_t, unsigned, nullptr, (unsigned)-1> glyph_name_to_new_index; + hb_hashmap_t<hb_bytes_t, unsigned, true> glyph_name_to_new_index; for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++) { hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); unsigned old_index = glyphNameIndex[old_gid]; unsigned new_index; + const unsigned *new_index2; if (old_index <= 257) new_index = old_index; - else if (old_new_index_map.has (old_index)) new_index = old_new_index_map.get (old_index); - else + else if (old_new_index_map.has (old_index, &new_index2)) { + new_index = *new_index2; + } else { hb_bytes_t s = _post.find_glyph_name (old_gid); new_index = glyph_name_to_new_index.get (s); if (new_index == (unsigned)-1) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh deleted file mode 100644 index 74bf3ca0fae..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh +++ /dev/null @@ -1,603 +0,0 @@ - -#line 1 "hb-ot-shape-complex-indic-machine.rl" -/* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH - -#include "hb.hh" - -enum indic_syllable_type_t { - indic_consonant_syllable, - indic_vowel_syllable, - indic_standalone_cluster, - indic_symbol_cluster, - indic_broken_cluster, - indic_non_indic_cluster, -}; - - -#line 45 "hb-ot-shape-complex-indic-machine.hh" -#define indic_syllable_machine_ex_A 10u -#define indic_syllable_machine_ex_C 1u -#define indic_syllable_machine_ex_CM 17u -#define indic_syllable_machine_ex_CS 19u -#define indic_syllable_machine_ex_DOTTEDCIRCLE 12u -#define indic_syllable_machine_ex_H 4u -#define indic_syllable_machine_ex_M 7u -#define indic_syllable_machine_ex_N 3u -#define indic_syllable_machine_ex_PLACEHOLDER 11u -#define indic_syllable_machine_ex_RS 13u -#define indic_syllable_machine_ex_Ra 16u -#define indic_syllable_machine_ex_Repha 15u -#define indic_syllable_machine_ex_SM 8u -#define indic_syllable_machine_ex_Symbol 18u -#define indic_syllable_machine_ex_V 2u -#define indic_syllable_machine_ex_ZWJ 6u -#define indic_syllable_machine_ex_ZWNJ 5u - - -#line 65 "hb-ot-shape-complex-indic-machine.hh" -static const unsigned char _indic_syllable_machine_trans_keys[] = { - 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, - 4u, 13u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, - 4u, 8u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, - 6u, 6u, 16u, 16u, 4u, 8u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 7u, 5u, 8u, - 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 8u, 5u, 8u, 8u, 8u, 1u, 19u, - 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 5u, 10u, 5u, 10u, 10u, 10u, 5u, 10u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 4u, 10u, 5u, 10u, - 3u, 10u, 5u, 10u, 3u, 17u, 3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, - 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, - 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, - 5u, 10u, 3u, 17u, 3u, 17u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, - 3u, 17u, 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 1u, 16u, 3u, 10u, - 4u, 10u, 5u, 10u, 3u, 17u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, - 3u, 17u, 4u, 13u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, - 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 1u, 16u, 3u, 10u, 4u, 10u, - 5u, 10u, 3u, 17u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 1u, 17u, - 3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, - 5u, 10u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 0 -}; - -static const char _indic_syllable_machine_key_spans[] = { - 1, 5, 3, 4, 5, 1, 1, 5, - 10, 5, 1, 3, 4, 5, 1, 1, - 5, 10, 10, 10, 1, 3, 4, 5, - 1, 1, 5, 5, 10, 1, 3, 4, - 5, 1, 1, 5, 5, 4, 1, 19, - 15, 15, 14, 16, 6, 6, 1, 6, - 16, 16, 16, 8, 7, 6, 7, 6, - 8, 6, 15, 15, 15, 15, 14, 16, - 15, 15, 14, 16, 6, 1, 6, 16, - 16, 8, 7, 6, 7, 6, 6, 8, - 6, 15, 15, 5, 15, 15, 14, 16, - 15, 16, 6, 1, 6, 16, 16, 8, - 7, 6, 15, 7, 6, 6, 8, 6, - 15, 10, 5, 15, 15, 14, 16, 15, - 16, 6, 1, 6, 16, 16, 8, 7, - 6, 15, 7, 6, 6, 8, 6, 17, - 15, 17, 10, 6, 1, 6, 16, 8, - 6, 6, 1, 6, 16 -}; - -static const short _indic_syllable_machine_index_offsets[] = { - 0, 2, 8, 12, 17, 23, 25, 27, - 33, 44, 50, 52, 56, 61, 67, 69, - 71, 77, 88, 99, 110, 112, 116, 121, - 127, 129, 131, 137, 143, 154, 156, 160, - 165, 171, 173, 175, 181, 187, 192, 194, - 214, 230, 246, 261, 278, 285, 292, 294, - 301, 318, 335, 352, 361, 369, 376, 384, - 391, 400, 407, 423, 439, 455, 471, 486, - 503, 519, 535, 550, 567, 574, 576, 583, - 600, 617, 626, 634, 641, 649, 656, 663, - 672, 679, 695, 711, 717, 733, 749, 764, - 781, 797, 814, 821, 823, 830, 847, 864, - 873, 881, 888, 904, 912, 919, 926, 935, - 942, 958, 969, 975, 991, 1007, 1022, 1039, - 1055, 1072, 1079, 1081, 1088, 1105, 1122, 1131, - 1139, 1146, 1162, 1170, 1177, 1184, 1193, 1200, - 1218, 1234, 1252, 1263, 1270, 1272, 1279, 1296, - 1305, 1312, 1319, 1321, 1328 -}; - -static const unsigned char _indic_syllable_machine_indicies[] = { - 1, 0, 2, 3, 3, 4, 1, 0, - 3, 3, 4, 0, 3, 3, 4, 1, - 0, 5, 3, 3, 4, 1, 0, 6, - 0, 7, 0, 8, 3, 3, 4, 1, - 0, 2, 3, 3, 4, 1, 0, 0, - 0, 0, 9, 0, 11, 12, 12, 13, - 14, 10, 14, 10, 12, 12, 13, 10, - 12, 12, 13, 14, 10, 15, 12, 12, - 13, 14, 10, 16, 10, 17, 10, 18, - 12, 12, 13, 14, 10, 11, 12, 12, - 13, 14, 10, 10, 10, 10, 19, 10, - 11, 12, 12, 13, 14, 10, 10, 10, - 10, 20, 10, 22, 23, 23, 24, 25, - 21, 21, 21, 21, 26, 21, 25, 21, - 23, 23, 24, 27, 23, 23, 24, 25, - 21, 28, 23, 23, 24, 25, 21, 29, - 21, 30, 21, 22, 23, 23, 24, 25, - 21, 31, 23, 23, 24, 25, 21, 33, - 34, 34, 35, 36, 32, 32, 32, 32, - 37, 32, 36, 32, 34, 34, 35, 32, - 34, 34, 35, 36, 32, 38, 34, 34, - 35, 36, 32, 39, 32, 40, 32, 33, - 34, 34, 35, 36, 32, 41, 34, 34, - 35, 36, 32, 23, 23, 24, 1, 0, - 43, 42, 45, 46, 47, 48, 49, 50, - 24, 25, 44, 51, 52, 52, 26, 44, - 53, 54, 55, 56, 57, 44, 59, 60, - 61, 62, 4, 1, 58, 63, 58, 58, - 9, 58, 58, 58, 64, 58, 65, 60, - 66, 66, 4, 1, 58, 63, 58, 58, - 58, 58, 58, 58, 64, 58, 60, 66, - 66, 4, 1, 58, 63, 58, 58, 58, - 58, 58, 58, 64, 58, 45, 58, 58, - 58, 67, 68, 58, 1, 58, 63, 58, - 58, 58, 58, 58, 45, 58, 69, 69, - 58, 1, 58, 63, 58, 63, 58, 58, - 70, 58, 63, 58, 63, 58, 63, 58, - 58, 58, 58, 63, 58, 45, 58, 71, - 58, 69, 69, 58, 1, 58, 63, 58, - 58, 58, 58, 58, 45, 58, 45, 58, - 58, 58, 69, 69, 58, 1, 58, 63, - 58, 58, 58, 58, 58, 45, 58, 45, - 58, 58, 58, 69, 68, 58, 1, 58, - 63, 58, 58, 58, 58, 58, 45, 58, - 72, 7, 73, 74, 4, 1, 58, 63, - 58, 7, 73, 74, 4, 1, 58, 63, - 58, 73, 73, 4, 1, 58, 63, 58, - 75, 76, 76, 4, 1, 58, 63, 58, - 67, 77, 58, 1, 58, 63, 58, 67, - 58, 69, 69, 58, 1, 58, 63, 58, - 69, 77, 58, 1, 58, 63, 58, 59, - 60, 66, 66, 4, 1, 58, 63, 58, - 58, 58, 58, 58, 58, 64, 58, 59, - 60, 61, 66, 4, 1, 58, 63, 58, - 58, 9, 58, 58, 58, 64, 58, 79, - 80, 81, 82, 13, 14, 78, 83, 78, - 78, 20, 78, 78, 78, 84, 78, 85, - 80, 86, 82, 13, 14, 78, 83, 78, - 78, 78, 78, 78, 78, 84, 78, 80, - 86, 82, 13, 14, 78, 83, 78, 78, - 78, 78, 78, 78, 84, 78, 87, 78, - 78, 78, 88, 89, 78, 14, 78, 83, - 78, 78, 78, 78, 78, 87, 78, 90, - 80, 91, 92, 13, 14, 78, 83, 78, - 78, 19, 78, 78, 78, 84, 78, 93, - 80, 86, 86, 13, 14, 78, 83, 78, - 78, 78, 78, 78, 78, 84, 78, 80, - 86, 86, 13, 14, 78, 83, 78, 78, - 78, 78, 78, 78, 84, 78, 87, 78, - 78, 78, 94, 89, 78, 14, 78, 83, - 78, 78, 78, 78, 78, 87, 78, 83, - 78, 78, 95, 78, 83, 78, 83, 78, - 83, 78, 78, 78, 78, 83, 78, 87, - 78, 96, 78, 94, 94, 78, 14, 78, - 83, 78, 78, 78, 78, 78, 87, 78, - 87, 78, 78, 78, 94, 94, 78, 14, - 78, 83, 78, 78, 78, 78, 78, 87, - 78, 97, 17, 98, 99, 13, 14, 78, - 83, 78, 17, 98, 99, 13, 14, 78, - 83, 78, 98, 98, 13, 14, 78, 83, - 78, 100, 101, 101, 13, 14, 78, 83, - 78, 88, 102, 78, 14, 78, 83, 78, - 94, 94, 78, 14, 78, 83, 78, 88, - 78, 94, 94, 78, 14, 78, 83, 78, - 94, 102, 78, 14, 78, 83, 78, 90, - 80, 86, 86, 13, 14, 78, 83, 78, - 78, 78, 78, 78, 78, 84, 78, 90, - 80, 91, 86, 13, 14, 78, 83, 78, - 78, 19, 78, 78, 78, 84, 78, 11, - 12, 12, 13, 14, 78, 79, 80, 86, - 82, 13, 14, 78, 83, 78, 78, 78, - 78, 78, 78, 84, 78, 104, 48, 105, - 105, 24, 25, 103, 51, 103, 103, 103, - 103, 103, 103, 55, 103, 48, 105, 105, - 24, 25, 103, 51, 103, 103, 103, 103, - 103, 103, 55, 103, 106, 103, 103, 103, - 107, 108, 103, 25, 103, 51, 103, 103, - 103, 103, 103, 106, 103, 47, 48, 109, - 110, 24, 25, 103, 51, 103, 103, 26, - 103, 103, 103, 55, 103, 106, 103, 103, - 103, 111, 108, 103, 25, 103, 51, 103, - 103, 103, 103, 103, 106, 103, 51, 103, - 103, 112, 103, 51, 103, 51, 103, 51, - 103, 103, 103, 103, 51, 103, 106, 103, - 113, 103, 111, 111, 103, 25, 103, 51, - 103, 103, 103, 103, 103, 106, 103, 106, - 103, 103, 103, 111, 111, 103, 25, 103, - 51, 103, 103, 103, 103, 103, 106, 103, - 114, 30, 115, 116, 24, 25, 103, 51, - 103, 30, 115, 116, 24, 25, 103, 51, - 103, 115, 115, 24, 25, 103, 51, 103, - 47, 48, 105, 105, 24, 25, 103, 51, - 103, 103, 103, 103, 103, 103, 55, 103, - 117, 118, 118, 24, 25, 103, 51, 103, - 107, 119, 103, 25, 103, 51, 103, 111, - 111, 103, 25, 103, 51, 103, 107, 103, - 111, 111, 103, 25, 103, 51, 103, 111, - 119, 103, 25, 103, 51, 103, 47, 48, - 109, 105, 24, 25, 103, 51, 103, 103, - 26, 103, 103, 103, 55, 103, 22, 23, - 23, 24, 25, 120, 120, 120, 120, 26, - 120, 22, 23, 23, 24, 25, 120, 122, - 123, 124, 125, 35, 36, 121, 126, 121, - 121, 37, 121, 121, 121, 127, 121, 128, - 123, 125, 125, 35, 36, 121, 126, 121, - 121, 121, 121, 121, 121, 127, 121, 123, - 125, 125, 35, 36, 121, 126, 121, 121, - 121, 121, 121, 121, 127, 121, 129, 121, - 121, 121, 130, 131, 121, 36, 121, 126, - 121, 121, 121, 121, 121, 129, 121, 122, - 123, 124, 52, 35, 36, 121, 126, 121, - 121, 37, 121, 121, 121, 127, 121, 129, - 121, 121, 121, 132, 131, 121, 36, 121, - 126, 121, 121, 121, 121, 121, 129, 121, - 126, 121, 121, 133, 121, 126, 121, 126, - 121, 126, 121, 121, 121, 121, 126, 121, - 129, 121, 134, 121, 132, 132, 121, 36, - 121, 126, 121, 121, 121, 121, 121, 129, - 121, 129, 121, 121, 121, 132, 132, 121, - 36, 121, 126, 121, 121, 121, 121, 121, - 129, 121, 135, 40, 136, 137, 35, 36, - 121, 126, 121, 40, 136, 137, 35, 36, - 121, 126, 121, 136, 136, 35, 36, 121, - 126, 121, 122, 123, 125, 125, 35, 36, - 121, 126, 121, 121, 121, 121, 121, 121, - 127, 121, 138, 139, 139, 35, 36, 121, - 126, 121, 130, 140, 121, 36, 121, 126, - 121, 132, 132, 121, 36, 121, 126, 121, - 130, 121, 132, 132, 121, 36, 121, 126, - 121, 132, 140, 121, 36, 121, 126, 121, - 45, 46, 47, 48, 109, 105, 24, 25, - 103, 51, 52, 52, 26, 103, 103, 45, - 55, 103, 59, 141, 61, 62, 4, 1, - 58, 63, 58, 58, 9, 58, 58, 58, - 64, 58, 45, 46, 47, 48, 142, 143, - 24, 144, 58, 145, 58, 52, 26, 58, - 58, 45, 55, 58, 22, 146, 146, 24, - 144, 58, 63, 58, 58, 26, 58, 145, - 58, 58, 147, 58, 145, 58, 145, 58, - 145, 58, 58, 58, 58, 145, 58, 45, - 58, 71, 22, 146, 146, 24, 144, 58, - 63, 58, 58, 58, 58, 58, 45, 58, - 149, 148, 150, 150, 148, 43, 148, 151, - 148, 150, 150, 148, 43, 148, 151, 148, - 151, 148, 148, 152, 148, 151, 148, 151, - 148, 151, 148, 148, 148, 148, 151, 148, - 45, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 52, 120, 120, 120, 120, 45, - 120, 0 -}; - -static const unsigned char _indic_syllable_machine_trans_targs[] = { - 39, 45, 50, 2, 51, 5, 6, 53, - 57, 58, 39, 67, 11, 73, 68, 14, - 15, 75, 80, 81, 84, 39, 89, 21, - 95, 90, 98, 39, 24, 25, 97, 103, - 39, 112, 30, 118, 113, 121, 33, 34, - 120, 126, 39, 137, 39, 40, 60, 85, - 87, 105, 106, 91, 107, 127, 128, 99, - 135, 140, 39, 41, 43, 8, 59, 46, - 54, 42, 1, 44, 48, 0, 47, 49, - 52, 3, 4, 55, 7, 56, 39, 61, - 63, 18, 83, 69, 76, 62, 9, 64, - 78, 71, 65, 17, 82, 66, 10, 70, - 72, 74, 12, 13, 77, 16, 79, 39, - 86, 26, 88, 101, 93, 19, 104, 20, - 92, 94, 96, 22, 23, 100, 27, 102, - 39, 39, 108, 110, 28, 35, 114, 122, - 109, 111, 124, 116, 29, 115, 117, 119, - 31, 32, 123, 36, 125, 129, 130, 134, - 131, 132, 37, 133, 39, 136, 38, 138, - 139 -}; - -static const char _indic_syllable_machine_trans_actions[] = { - 1, 0, 2, 0, 2, 0, 0, 2, - 2, 2, 3, 2, 0, 2, 0, 0, - 0, 2, 2, 2, 2, 4, 2, 0, - 5, 0, 5, 6, 0, 0, 5, 2, - 7, 2, 0, 2, 0, 2, 0, 0, - 2, 2, 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, 0, 0, 0, 0, 2, 14, 2, - 0, 0, 2, 0, 2, 2, 0, 2, - 2, 2, 2, 0, 2, 2, 0, 0, - 2, 2, 0, 0, 0, 0, 2, 15, - 5, 0, 5, 2, 2, 0, 5, 0, - 0, 2, 5, 0, 0, 0, 0, 2, - 16, 17, 2, 0, 0, 0, 0, 2, - 2, 2, 2, 2, 0, 0, 2, 2, - 0, 0, 0, 0, 2, 0, 18, 18, - 0, 0, 0, 0, 19, 2, 0, 0, - 0 -}; - -static const char _indic_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, 0, 0, 0, 9, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 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 _indic_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, 0, 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, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 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 _indic_syllable_machine_eof_trans[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 22, 22, 28, 22, 22, - 22, 22, 22, 22, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 1, 43, 0, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, - 104, 121, 121, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 104, - 59, 59, 59, 59, 59, 59, 59, 149, - 149, 149, 149, 149, 121 -}; - -static const int indic_syllable_machine_start = 39; -static const int indic_syllable_machine_first_final = 39; -static const int indic_syllable_machine_error = -1; - -static const int indic_syllable_machine_en_main = 39; - - -#line 46 "hb-ot-shape-complex-indic-machine.rl" - - - -#line 102 "hb-ot-shape-complex-indic-machine.rl" - - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_indic (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts, te, act; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 440 "hb-ot-shape-complex-indic-machine.hh" - { - cs = indic_syllable_machine_start; - ts = 0; - te = 0; - act = 0; - } - -#line 122 "hb-ot-shape-complex-indic-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 456 "hb-ot-shape-complex-indic-machine.hh" - { - int _slen; - int _trans; - const unsigned char *_keys; - const unsigned char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _indic_syllable_machine_from_state_actions[cs] ) { - case 10: -#line 1 "NONE" - {ts = p;} - break; -#line 470 "hb-ot-shape-complex-indic-machine.hh" - } - - _keys = _indic_syllable_machine_trans_keys + (cs<<1); - _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs]; - - _slen = _indic_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) && - ( info[p].indic_category()) <= _keys[1] ? - ( info[p].indic_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _indic_syllable_machine_trans_targs[_trans]; - - if ( _indic_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _indic_syllable_machine_trans_actions[_trans] ) { - case 2: -#line 1 "NONE" - {te = p+1;} - break; - case 11: -#line 98 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (indic_non_indic_cluster); }} - break; - case 13: -#line 93 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (indic_consonant_syllable); }} - break; - case 14: -#line 94 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (indic_vowel_syllable); }} - break; - case 17: -#line 95 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (indic_standalone_cluster); }} - break; - case 19: -#line 96 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (indic_symbol_cluster); }} - break; - case 15: -#line 97 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (indic_broken_cluster); }} - break; - case 16: -#line 98 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (indic_non_indic_cluster); }} - break; - case 1: -#line 93 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} - break; - case 3: -#line 94 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} - break; - case 7: -#line 95 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} - break; - case 8: -#line 96 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} - break; - case 4: -#line 97 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); }} - break; - case 6: -#line 1 "NONE" - { switch( act ) { - case 1: - {{p = ((te))-1;} found_syllable (indic_consonant_syllable); } - break; - case 5: - {{p = ((te))-1;} found_syllable (indic_broken_cluster); } - break; - case 6: - {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } - break; - } - } - break; - case 18: -#line 1 "NONE" - {te = p+1;} -#line 93 "hb-ot-shape-complex-indic-machine.rl" - {act = 1;} - break; - case 5: -#line 1 "NONE" - {te = p+1;} -#line 97 "hb-ot-shape-complex-indic-machine.rl" - {act = 5;} - break; - case 12: -#line 1 "NONE" - {te = p+1;} -#line 98 "hb-ot-shape-complex-indic-machine.rl" - {act = 6;} - break; -#line 573 "hb-ot-shape-complex-indic-machine.hh" - } - -_again: - switch ( _indic_syllable_machine_to_state_actions[cs] ) { - case 9: -#line 1 "NONE" - {ts = 0;} - break; -#line 582 "hb-ot-shape-complex-indic-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _indic_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _indic_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 130 "hb-ot-shape-complex-indic-machine.rl" - -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-table.cc deleted file mode 100644 index 326aa9f96e1..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-table.cc +++ /dev/null @@ -1,501 +0,0 @@ -/* == Start of generated table == */ -/* - * The following table is generated by running: - * - * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt - * - * on files with these headers: - * - * # IndicSyllabicCategory-14.0.0.txt - * # Date: 2021-05-22, 01:01:00 GMT [KW, RP] - * # IndicPositionalCategory-14.0.0.txt - * # Date: 2021-05-22, 01:01:00 GMT [KW, RP] - * # Blocks-14.0.0.txt - * # Date: 2021-01-22, 23:29:00 GMT [KW] - */ - -#include "hb.hh" - -#ifndef HB_NO_OT_SHAPE - -#include "hb-ot-shape-complex-indic.hh" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-macros" - -#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 17 chars; Avagraha */ -#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 91 chars; Bindu */ -#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */ -#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 59 chars; Cantillation_Mark */ -#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2206 chars; Consonant */ -#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 14 chars; Consonant_Dead */ -#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 70 chars; Consonant_Final */ -#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */ -#define ISC_CIP INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED /* 1 chars; Consonant_Initial_Postfixed */ -#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */ -#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 31 chars; Consonant_Medial */ -#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 22 chars; Consonant_Placeholder */ -#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 3 chars; Consonant_Preceding_Repha */ -#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 10 chars; Consonant_Prefixed */ -#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 94 chars; Consonant_Subjoined */ -#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 1 chars; Consonant_Succeeding_Repha */ -#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 8 chars; Consonant_With_Stacker */ -#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */ -#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 12 chars; Invisible_Stacker */ -#define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */ -#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */ -#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */ -#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 32 chars; Nukta */ -#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 491 chars; Number */ -#define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */ -#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */ -#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 25 chars; Pure_Killer */ -#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */ -#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 25 chars; Syllable_Modifier */ -#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */ -#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */ -#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 27 chars; Virama */ -#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 35 chars; Visarga */ -#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */ -#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 686 chars; Vowel_Dependent */ -#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 486 chars; Vowel_Independent */ - -#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 352 chars; Bottom */ -#define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */ -#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 4 chars; Bottom_And_Right */ -#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 64 chars; Left */ -#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 22 chars; Left_And_Right */ -#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */ -#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */ -#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 290 chars; Right */ -#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 418 chars; Top */ -#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */ -#define IMC_TBL INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_LEFT /* 2 chars; Top_And_Bottom_And_Left */ -#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */ -#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */ -#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */ -#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */ -#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */ - -#pragma GCC diagnostic pop - -#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M) - - -static const uint16_t indic_table[] = { - - -#define indic_offset_0x0028u 0 - - - /* Basic Latin */ - - /* 0028 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), _(x,x), _(x,x), - /* 0030 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0038 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x00b0u 24 - - - /* Latin-1 Supplement */ - - /* 00B0 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(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), - /* 00D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), - -#define indic_offset_0x0900u 64 - - - /* Devanagari */ - - /* 0900 */ _(Bi,T), _(Bi,T), _(Bi,T), _(Vs,R), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 0918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0920 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0928 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,B), _(A,x), _(M,R), _(M,L), - /* 0940 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), - /* 0948 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(M,L), _(M,R), - /* 0950 */ _(x,x), _(Ca,T), _(Ca,B), _(x,T), _(x,T), _(M,T), _(M,B), _(M,B), - /* 0958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0960 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0968 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 0978 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - - /* Bengali */ - - /* 0980 */ _(CP,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), - /* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 09A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 09A8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 09B0 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), - /* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L), - /* 09C0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L), - /* 09C8 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,B), _(CD,x), _(x,x), - /* 09D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), - /* 09D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), - /* 09E0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 09F0 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(Bi,x), _(x,x), _(SM,T), _(x,x), - - /* Gurmukhi */ - - /* 0A00 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 0A08 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x), - /* 0A10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 0A18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0A28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0A30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), - /* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(x,x), _(M,R), _(M,L), - /* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), - /* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x), - /* 0A50 */ _(x,x), _(Ca,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), - /* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0A70 */ _(Bi,T), _(GM,T), _(CP,x), _(CP,x), _(x,x), _(CM,B), _(x,x), _(x,x), - /* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Gujarati */ - - /* 0A80 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), - /* 0A90 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 0A98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0AA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0AA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0AB0 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L), - /* 0AC0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(x,x), _(M,T), - /* 0AC8 */ _(M,T), _(M,TR), _(x,x), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x), - /* 0AD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0AD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0AF8 */ _(x,x), _(C,x), _(Ca,T), _(Ca,T), _(Ca,T), _(N,T), _(N,T), _(N,T), - - /* Oriya */ - - /* 0B00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), - /* 0B10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 0B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0B28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0B30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T), - /* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L), - /* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x), - /* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,T), _(M,TR), - /* 0B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), - /* 0B60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0B68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0B70 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Tamil */ - - /* 0B80 */ _(x,x), _(x,x), _(Bi,T), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 0B88 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(VI,x), - /* 0B90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(x,x), _(x,x), - /* 0B98 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), _(C,x), - /* 0BA0 */ _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), - /* 0BA8 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), - /* 0BB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0BB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), - /* 0BC0 */ _(M,T), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L), - /* 0BC8 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(x,x), _(x,x), - /* 0BD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), - /* 0BD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0BE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0BE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0BF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Telugu */ - - /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(Bi,T), _(VI,x), _(VI,x), _(VI,x), - /* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), - /* 0C10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 0C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0C28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0C30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,T), _(M,T), - /* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T), - /* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x), - /* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x), - /* 0C58 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(CD,x), _(x,x), _(x,x), - /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0C78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Kannada */ - - /* 0C80 */ _(Bi,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), - /* 0C90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 0C98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0CA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0CA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0CB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T), - /* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR), - /* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x), - /* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), - /* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(C,x), _(x,x), - /* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0CF0 */ _(x,x),_(CWS,x),_(CWS,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Malayalam */ - - /* 0D00 */ _(Bi,T), _(Bi,T), _(Bi,R), _(Vs,R), _(Bi,x), _(VI,x), _(VI,x), _(VI,x), - /* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), - /* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0D20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0D28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0D38 */ _(C,x), _(C,x), _(C,x), _(PK,T), _(PK,T), _(A,x), _(M,R), _(M,R), - /* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L), - /* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T),_(CPR,T), _(x,x), - /* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(M,R), - /* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x), - /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0D70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0D78 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), - - /* Sinhala */ - - /* 0D80 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), - /* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0DA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0DA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0DB0 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0DB8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), - /* 0DC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), - /* 0DC8 */ _(x,x), _(x,x), _(V,T), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), - /* 0DD0 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(x,x), _(M,B), _(x,x), - /* 0DD8 */ _(M,R), _(M,L), _(M,TL), _(M,L), _(M,LR),_(M,TLR), _(M,LR), _(M,R), - /* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0DE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x1000u 1336 - - - /* Myanmar */ - - /* 1000 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1008 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1010 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), - /* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,T), _(TM,B), - /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R),_(CM,TBL), _(CM,B), _(CM,B), _(C,x), - /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(CP,x), _(x,x), _(x,x), _(CP,x), _(x,x), - /* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), - /* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,B), _(CM,B), - /* 1060 */ _(CM,B), _(C,x), _(M,R), _(TM,R), _(TM,R), _(C,x), _(C,x), _(M,R), - /* 1068 */ _(M,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(C,x), _(C,x), - /* 1070 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(C,x), _(C,x), _(C,x), - /* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1080 */ _(C,x), _(C,x), _(CM,B), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,R), - /* 1088 */ _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,B), _(C,x), _(TM,R), - /* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1098 */ _(Nd,x), _(Nd,x), _(TM,R), _(TM,R), _(M,R), _(M,T), _(x,x), _(x,x), - -#define indic_offset_0x1780u 1496 - - - /* Khmer */ - - /* 1780 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1788 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1790 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1798 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 17A0 */ _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(M,R), _(M,T), - /* 17B8 */ _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,TL),_(M,TLR), - /* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,T), _(Vs,R), - /* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(SM,T),_(CSR,T), _(CK,T), _(SM,T), _(SM,T), - /* 17D0 */ _(SM,T), _(PK,T), _(IS,x), _(SM,T), _(x,x), _(x,x), _(x,x), _(x,x), - /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(SM,T), _(x,x), _(x,x), - /* 17E0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 17E8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x1cd0u 1608 - - - /* Vedic Extensions */ - - /* 1CD0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(Ca,O), _(Ca,B), _(Ca,B), _(Ca,B), - /* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B), - /* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), - /* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x), - /* 1CF0 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(Ca,T),_(CWS,x),_(CWS,x), _(Ca,R), - /* 1CF8 */ _(Ca,x), _(Ca,x), _(CP,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x2008u 1656 - - - /* General Punctuation */ - - /* 2008 */ _(x,x), _(x,x), _(x,x), _(x,x),_(ZWNJ,x),_(ZWJ,x), _(x,x), _(x,x), - /* 2010 */ _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x2070u 1672 - - - /* Superscripts and Subscripts */ - - /* 2070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(SM,x), _(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,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0xa8e0u 1696 - - - /* Devanagari Extended */ - - /* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), - /* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), - /* A8F0 */ _(Ca,T), _(Ca,T), _(Bi,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A8F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(M,T), - -#define indic_offset_0xa9e0u 1728 - - - /* Myanmar Extended-B */ - - /* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), _(x,x), _(C,x), - /* A9E8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* A9F8 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), - -#define indic_offset_0xaa60u 1760 - - - /* Myanmar Extended-A */ - - /* AA60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), - /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,R), _(TM,T), _(TM,R), _(C,x), _(C,x), - -}; /* Table items: 1792; occupancy: 71% */ - -uint16_t -hb_indic_get_categories (hb_codepoint_t u) -{ - switch (u >> 12) - { - case 0x0u: - if (unlikely (u == 0x00A0u)) return _(CP,x); - if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u]; - if (hb_in_range<hb_codepoint_t> (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u]; - break; - - case 0x1u: - if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u]; - break; - - case 0x2u: - if (unlikely (u == 0x25CCu)) return _(CP,x); - if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u]; - if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u]; - break; - - case 0xAu: - if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8FFu)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u]; - if (hb_in_range<hb_codepoint_t> (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u]; - if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u]; - break; - - default: - break; - } - return _(x,x); -} - -#undef _ - -#undef ISC_A -#undef ISC_Bi -#undef ISC_BJN -#undef ISC_Ca -#undef ISC_C -#undef ISC_CD -#undef ISC_CF -#undef ISC_CHL -#undef ISC_CIP -#undef ISC_CK -#undef ISC_CM -#undef ISC_CP -#undef ISC_CPR -#undef ISC_CPrf -#undef ISC_CS -#undef ISC_CSR -#undef ISC_CWS -#undef ISC_GM -#undef ISC_IS -#undef ISC_ZWJ -#undef ISC_ML -#undef ISC_ZWNJ -#undef ISC_N -#undef ISC_Nd -#undef ISC_NJ -#undef ISC_x -#undef ISC_PK -#undef ISC_RS -#undef ISC_SM -#undef ISC_TL -#undef ISC_TM -#undef ISC_V -#undef ISC_Vs -#undef ISC_Vo -#undef ISC_M -#undef ISC_VI - -#undef IMC_B -#undef IMC_BL -#undef IMC_BR -#undef IMC_L -#undef IMC_LR -#undef IMC_x -#undef IMC_O -#undef IMC_R -#undef IMC_T -#undef IMC_TB -#undef IMC_TBL -#undef IMC_TBR -#undef IMC_TL -#undef IMC_TLR -#undef IMC_TR -#undef IMC_VOL - -#endif - -/* == End of generated table == */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh deleted file mode 100644 index da77a2887c4..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright © 2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_INDIC_HH -#define HB_OT_SHAPE_COMPLEX_INDIC_HH - -#include "hb.hh" - -#include "hb-ot-shape-complex-syllabic.hh" - - -/* buffer var allocations */ -#define indic_category() complex_var_u8_category() /* indic_category_t */ -#define indic_position() complex_var_u8_auxiliary() /* indic_position_t */ - - -/* Cateories used in the OpenType spec: - * https://docs.microsoft.com/en-us/typography/script-development/devanagari - */ -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum indic_category_t { - OT_X = 0, - OT_C = 1, - OT_V = 2, - OT_N = 3, - OT_H = 4, - OT_ZWNJ = 5, - OT_ZWJ = 6, - OT_M = 7, - OT_SM = 8, - /* OT_VD = 9, UNUSED; we use OT_A instead. */ - OT_A = 10, - OT_PLACEHOLDER = 11, - OT_DOTTEDCIRCLE = 12, - OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */ - OT_Coeng = 14, /* Khmer-style Virama. */ - OT_Repha = 15, /* Atomically-encoded logical or visual repha. */ - OT_Ra = 16, - OT_CM = 17, /* Consonant-Medial. */ - OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */ - OT_CS = 19, - - /* The following are used by Khmer & Myanmar shapers. Defined - * here for them to share. */ - OT_VAbv = 26, - OT_VBlw = 27, - OT_VPre = 28, - OT_VPst = 29, -}; - -#define MEDIAL_FLAGS (FLAG (OT_CM)) - -/* Note: - * - * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels - * cannot happen in a consonant syllable. The plus side however is, we can call the - * consonant syllable logic from the vowel syllable function and get it all right! */ -#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE)) -#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ)) - - -/* Visual positions in a syllable from left to right. */ -enum indic_position_t { - POS_START = 0, - - POS_RA_TO_BECOME_REPH = 1, - POS_PRE_M = 2, - POS_PRE_C = 3, - - POS_BASE_C = 4, - POS_AFTER_MAIN = 5, - - POS_ABOVE_C = 6, - - POS_BEFORE_SUB = 7, - POS_BELOW_C = 8, - POS_AFTER_SUB = 9, - - POS_BEFORE_POST = 10, - POS_POST_C = 11, - POS_AFTER_POST = 12, - - POS_FINAL_C = 13, - POS_SMVD = 14, - - POS_END = 15 -}; - -/* Categories used in IndicSyllabicCategory.txt from UCD. */ -enum indic_syllabic_category_t { - INDIC_SYLLABIC_CATEGORY_OTHER = OT_X, - - INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Symbol, - INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM, - INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER = OT_PLACEHOLDER, /* Don't care. */ - INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK = OT_A, - INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C, - INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C, - INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM, - INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C, - INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER = OT_M, /* U+17CD only. */ - INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM, - INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_PLACEHOLDER, - INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA = OT_Repha, - INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED = OT_X, /* Don't care. */ - INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM, - INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_CM, - INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_CS, - INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, /* https://github.com/harfbuzz/harfbuzz/issues/552 */ - INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_Coeng, - INDIC_SYLLABIC_CATEGORY_JOINER = OT_ZWJ, - INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X, - INDIC_SYLLABIC_CATEGORY_NON_JOINER = OT_ZWNJ, - INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N, - INDIC_SYLLABIC_CATEGORY_NUMBER = OT_PLACEHOLDER, - INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER = OT_PLACEHOLDER, /* Don't care. */ - INDIC_SYLLABIC_CATEGORY_PURE_KILLER = OT_M, /* Is like a vowel matra. */ - INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS, - INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER = OT_SM, - INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X, - INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N, - INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H, - INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM, - INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V, - INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M, - INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V -}; - -/* Categories used in IndicSMatraCategory.txt from UCD */ -enum indic_matra_category_t { - INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_END, - - INDIC_MATRA_CATEGORY_LEFT = POS_PRE_C, - INDIC_MATRA_CATEGORY_TOP = POS_ABOVE_C, - INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW_C, - INDIC_MATRA_CATEGORY_RIGHT = POS_POST_C, - - /* These should resolve to the position of the last part of the split sequence. */ - INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, - INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, - INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM, - INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_LEFT = INDIC_MATRA_CATEGORY_BOTTOM, - INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, - INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP, - INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, - INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT, - - INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN, - INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M -}; - -#define INDIC_COMBINE_CATEGORIES(S,M) \ - ( \ - static_assert_expr (S < 255 && M < 255) + \ - ( S | \ - ( \ - ( \ - S == INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL || \ - S == INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK || \ - S == INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER || \ - S == INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA || \ - S == INDIC_SYLLABIC_CATEGORY_VIRAMA || \ - S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT || \ - false \ - ? M : INDIC_MATRA_CATEGORY_NOT_APPLICABLE \ - ) << 8 \ - ) \ - ) \ - ) - -HB_INTERNAL uint16_t -hb_indic_get_categories (hb_codepoint_t u); - - -static inline bool -is_one_of (const hb_glyph_info_t &info, unsigned int flags) -{ - /* If it ligated, all bets are off. */ - if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG_UNSAFE (info.indic_category()) & flags); -} - -static inline bool -is_joiner (const hb_glyph_info_t &info) -{ - return is_one_of (info, JOINER_FLAGS); -} - -static inline bool -is_consonant (const hb_glyph_info_t &info) -{ - return is_one_of (info, CONSONANT_FLAGS); -} - -static inline bool -is_halant (const hb_glyph_info_t &info) -{ - return is_one_of (info, FLAG (OT_H)); -} - -#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base)) - -#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u)) -#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u)) -#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u)) -#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u)) -#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u)) -#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u)) -#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u)) -#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u)) -#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u)) -#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u)) - - -#define MATRA_POS_LEFT(u) POS_PRE_M -#define MATRA_POS_RIGHT(u) ( \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_BENG(u) ? POS_AFTER_POST : \ - IS_GURU(u) ? POS_AFTER_POST : \ - IS_GUJR(u) ? POS_AFTER_POST : \ - IS_ORYA(u) ? POS_AFTER_POST : \ - IS_TAML(u) ? POS_AFTER_POST : \ - IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ - IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ - IS_MLYM(u) ? POS_AFTER_POST : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - /*default*/ POS_AFTER_SUB \ - ) -#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \ - IS_GUJR(u) ? POS_AFTER_SUB : \ - IS_ORYA(u) ? POS_AFTER_MAIN : \ - IS_TAML(u) ? POS_AFTER_SUB : \ - IS_TELU(u) ? POS_BEFORE_SUB : \ - IS_KNDA(u) ? POS_BEFORE_SUB : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - /*default*/ POS_AFTER_SUB \ - ) -#define MATRA_POS_BOTTOM(u) ( \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_BENG(u) ? POS_AFTER_SUB : \ - IS_GURU(u) ? POS_AFTER_POST : \ - IS_GUJR(u) ? POS_AFTER_POST : \ - IS_ORYA(u) ? POS_AFTER_SUB : \ - IS_TAML(u) ? POS_AFTER_POST : \ - IS_TELU(u) ? POS_BEFORE_SUB : \ - IS_KNDA(u) ? POS_BEFORE_SUB : \ - IS_MLYM(u) ? POS_AFTER_POST : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - /*default*/ POS_AFTER_SUB \ - ) - -static inline indic_position_t -matra_position_indic (hb_codepoint_t u, indic_position_t side) -{ - switch ((int) side) - { - case POS_PRE_C: return MATRA_POS_LEFT (u); - case POS_POST_C: return MATRA_POS_RIGHT (u); - case POS_ABOVE_C: return MATRA_POS_TOP (u); - case POS_BELOW_C: return MATRA_POS_BOTTOM (u); - } - return side; -} - -/* XXX - * This is a hack for now. We should move this data into the main Indic table. - * Or completely remove it and just check in the tables. - */ -static const hb_codepoint_t ra_chars[] = { - 0x0930u, /* Devanagari */ - 0x09B0u, /* Bengali */ - 0x09F0u, /* Bengali */ - 0x0A30u, /* Gurmukhi */ /* No Reph */ - 0x0AB0u, /* Gujarati */ - 0x0B30u, /* Oriya */ - 0x0BB0u, /* Tamil */ /* No Reph */ - 0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */ - 0x0CB0u, /* Kannada */ - 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ - - 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ -}; - -static inline bool -is_ra (hb_codepoint_t u) -{ - return hb_array (ra_chars).lfind (u); -} - -static inline void -set_indic_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0xFFu); - indic_position_t pos = (indic_position_t) (type >> 8); - - - /* - * Re-assign category - */ - - /* The following act more like the Bindus. */ - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0953u, 0x0954u))) - cat = OT_SM; - /* The following act like consonants. */ - else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x0A72u, 0x0A73u, - 0x1CF5u, 0x1CF6u))) - cat = OT_C; - /* TODO: The following should only be allowed after a Visarga. - * For now, just treat them like regular tone marks. */ - else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1CE2u, 0x1CE8u))) - cat = OT_A; - /* TODO: The following should only be allowed after some of - * the nasalization marks, maybe only for U+1CE9..U+1CF1. - * For now, just treat them like tone marks. */ - else if (unlikely (u == 0x1CEDu)) - cat = OT_A; - /* The following take marks in standalone clusters, similar to Avagraha. */ - else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0xA8F2u, 0xA8F7u, - 0x1CE9u, 0x1CECu, - 0x1CEEu, 0x1CF1u))) - { - cat = OT_Symbol; - static_assert (((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol), ""); - } - else if (unlikely (u == 0x0A51u)) - { - /* https://github.com/harfbuzz/harfbuzz/issues/524 */ - cat = OT_M; - pos = POS_BELOW_C; - } - - /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil, - * so the Indic shaper needs to know their categories. */ - else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM; - else if (unlikely (u == 0x1133Bu || u == 0x1133Cu)) cat = OT_N; - - else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */ - else if (unlikely (u == 0x0B55u)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/2849 */ - - else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */ - else if (unlikely (u == 0x09FCu)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/1613 */ - else if (unlikely (u == 0x0C80u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/623 */ - else if (unlikely (u == 0x0D04u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/3511 */ - else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u))) - cat = OT_PLACEHOLDER; - else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; - - - /* - * Re-assign position. - */ - - if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) - { - pos = POS_BASE_C; - if (is_ra (u)) - cat = OT_Ra; - } - else if (cat == OT_M) - { - pos = matra_position_indic (u, pos); - } - else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) /* | FLAG (OT_VD) */ | FLAG (OT_A) | FLAG (OT_Symbol)))) - { - pos = POS_SMVD; - } - - if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */ - - - - info.indic_category() = cat; - info.indic_position() = pos; -} - -struct hb_indic_would_substitute_feature_t -{ - void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_) - { - zero_context = zero_context_; - map->get_stage_lookups (0/*GSUB*/, - map->get_feature_stage (0/*GSUB*/, feature_tag), - &lookups, &count); - } - - bool would_substitute (const hb_codepoint_t *glyphs, - unsigned int glyphs_count, - hb_face_t *face) const - { - for (unsigned int i = 0; i < count; i++) - if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context)) - return true; - return false; - } - - private: - const hb_ot_map_t::lookup_map_t *lookups; - unsigned int count; - bool zero_context; -}; - - -#endif /* HB_OT_SHAPE_COMPLEX_INDIC_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh deleted file mode 100644 index c52f72f394e..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh +++ /dev/null @@ -1,396 +0,0 @@ - -#line 1 "hb-ot-shape-complex-khmer-machine.rl" -/* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH - -#include "hb.hh" - -enum khmer_syllable_type_t { - khmer_consonant_syllable, - khmer_broken_cluster, - khmer_non_khmer_cluster, -}; - - -#line 42 "hb-ot-shape-complex-khmer-machine.hh" -#define khmer_syllable_machine_ex_C 1u -#define khmer_syllable_machine_ex_Coeng 14u -#define khmer_syllable_machine_ex_DOTTEDCIRCLE 12u -#define khmer_syllable_machine_ex_PLACEHOLDER 11u -#define khmer_syllable_machine_ex_Ra 16u -#define khmer_syllable_machine_ex_Robatic 20u -#define khmer_syllable_machine_ex_V 2u -#define khmer_syllable_machine_ex_VAbv 26u -#define khmer_syllable_machine_ex_VBlw 27u -#define khmer_syllable_machine_ex_VPre 28u -#define khmer_syllable_machine_ex_VPst 29u -#define khmer_syllable_machine_ex_Xgroup 21u -#define khmer_syllable_machine_ex_Ygroup 22u -#define khmer_syllable_machine_ex_ZWJ 6u -#define khmer_syllable_machine_ex_ZWNJ 5u - - -#line 60 "hb-ot-shape-complex-khmer-machine.hh" -static const unsigned char _khmer_syllable_machine_trans_keys[] = { - 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, - 5u, 26u, 5u, 21u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, - 5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 29u, 5u, 29u, 5u, 29u, 5u, 29u, - 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 26u, 5u, 29u, - 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, 5u, 29u, - 0 -}; - -static const char _khmer_syllable_machine_key_spans[] = { - 22, 17, 22, 17, 16, 17, 22, 17, - 22, 17, 17, 22, 17, 16, 17, 22, - 17, 22, 17, 22, 29, 25, 25, 25, - 1, 18, 25, 25, 25, 16, 22, 25, - 25, 1, 18, 25, 25, 16, 25, 25 -}; - -static const short _khmer_syllable_machine_index_offsets[] = { - 0, 23, 41, 64, 82, 99, 117, 140, - 158, 181, 199, 217, 240, 258, 275, 293, - 316, 334, 357, 375, 398, 428, 454, 480, - 506, 508, 527, 553, 579, 605, 622, 645, - 671, 697, 699, 718, 744, 770, 787, 813 -}; - -static const char _khmer_syllable_machine_indicies[] = { - 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 3, 0, 0, 0, 0, 4, 0, 1, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, - 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 0, 0, 0, 0, 4, 0, - 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 6, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 0, 7, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 10, 0, 0, - 0, 0, 4, 0, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10, 0, 11, 11, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 0, - 0, 0, 0, 4, 0, 11, 11, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 0, 14, - 14, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 15, - 13, 14, 14, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 15, 16, 16, 16, 16, 17, 16, - 18, 18, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 17, 16, 19, 19, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 19, 16, 20, 20, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 21, 16, 22, 22, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 23, 16, 16, - 16, 16, 17, 16, 22, 22, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 23, 16, 24, 24, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 25, 16, - 16, 16, 16, 17, 16, 24, 24, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 25, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 26, 15, - 16, 16, 16, 16, 17, 16, 28, 28, - 27, 27, 29, 29, 27, 27, 27, 27, - 2, 2, 27, 30, 27, 28, 27, 27, - 27, 27, 15, 19, 27, 27, 27, 17, - 23, 25, 21, 27, 32, 32, 31, 31, - 31, 31, 31, 31, 31, 33, 31, 31, - 31, 31, 31, 2, 3, 6, 31, 31, - 31, 4, 10, 12, 8, 31, 34, 34, - 31, 31, 31, 31, 31, 31, 31, 35, - 31, 31, 31, 31, 31, 31, 3, 6, - 31, 31, 31, 4, 10, 12, 8, 31, - 5, 5, 31, 31, 31, 31, 31, 31, - 31, 35, 31, 31, 31, 31, 31, 31, - 4, 6, 31, 31, 31, 31, 31, 31, - 8, 31, 6, 31, 7, 7, 31, 31, - 31, 31, 31, 31, 31, 35, 31, 31, - 31, 31, 31, 31, 8, 6, 31, 36, - 36, 31, 31, 31, 31, 31, 31, 31, - 35, 31, 31, 31, 31, 31, 31, 10, - 6, 31, 31, 31, 4, 31, 31, 8, - 31, 37, 37, 31, 31, 31, 31, 31, - 31, 31, 35, 31, 31, 31, 31, 31, - 31, 12, 6, 31, 31, 31, 4, 10, - 31, 8, 31, 34, 34, 31, 31, 31, - 31, 31, 31, 31, 33, 31, 31, 31, - 31, 31, 31, 3, 6, 31, 31, 31, - 4, 10, 12, 8, 31, 28, 28, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 28, 31, 14, 14, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 15, 38, - 38, 38, 38, 17, 38, 40, 40, 39, - 39, 39, 39, 39, 39, 39, 41, 39, - 39, 39, 39, 39, 39, 15, 19, 39, - 39, 39, 17, 23, 25, 21, 39, 18, - 18, 39, 39, 39, 39, 39, 39, 39, - 41, 39, 39, 39, 39, 39, 39, 17, - 19, 39, 39, 39, 39, 39, 39, 21, - 39, 19, 39, 20, 20, 39, 39, 39, - 39, 39, 39, 39, 41, 39, 39, 39, - 39, 39, 39, 21, 19, 39, 42, 42, - 39, 39, 39, 39, 39, 39, 39, 41, - 39, 39, 39, 39, 39, 39, 23, 19, - 39, 39, 39, 17, 39, 39, 21, 39, - 43, 43, 39, 39, 39, 39, 39, 39, - 39, 41, 39, 39, 39, 39, 39, 39, - 25, 19, 39, 39, 39, 17, 23, 39, - 21, 39, 44, 44, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 44, 39, 45, 45, 39, 39, 39, - 39, 39, 39, 39, 30, 39, 39, 39, - 39, 39, 26, 15, 19, 39, 39, 39, - 17, 23, 25, 21, 39, 40, 40, 39, - 39, 39, 39, 39, 39, 39, 30, 39, - 39, 39, 39, 39, 39, 15, 19, 39, - 39, 39, 17, 23, 25, 21, 39, 0 -}; - -static const char _khmer_syllable_machine_trans_targs[] = { - 20, 1, 28, 22, 23, 3, 24, 5, - 25, 7, 26, 9, 27, 20, 10, 31, - 20, 32, 12, 33, 14, 34, 16, 35, - 18, 36, 39, 20, 21, 30, 37, 20, - 0, 29, 2, 4, 6, 8, 20, 20, - 11, 13, 15, 17, 38, 19 -}; - -static const char _khmer_syllable_machine_trans_actions[] = { - 1, 0, 2, 2, 2, 0, 0, 0, - 2, 0, 2, 0, 2, 3, 0, 4, - 5, 2, 0, 0, 0, 2, 0, 2, - 0, 2, 4, 8, 2, 9, 0, 10, - 0, 0, 0, 0, 0, 0, 11, 12, - 0, 0, 0, 0, 4, 0 -}; - -static const char _khmer_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, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static const char _khmer_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, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static const unsigned char _khmer_syllable_machine_eof_trans[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 14, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 39, 40, - 40, 40, 40, 40, 40, 40, 40, 40 -}; - -static const int khmer_syllable_machine_start = 20; -static const int khmer_syllable_machine_first_final = 20; -static const int khmer_syllable_machine_error = -1; - -static const int khmer_syllable_machine_en_main = 20; - - -#line 43 "hb-ot-shape-complex-khmer-machine.rl" - - - -#line 86 "hb-ot-shape-complex-khmer-machine.rl" - - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_khmer (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 266 "hb-ot-shape-complex-khmer-machine.hh" - { - cs = khmer_syllable_machine_start; - ts = 0; - te = 0; - act = 0; - } - -#line 106 "hb-ot-shape-complex-khmer-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 282 "hb-ot-shape-complex-khmer-machine.hh" - { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _khmer_syllable_machine_from_state_actions[cs] ) { - case 7: -#line 1 "NONE" - {ts = p;} - break; -#line 296 "hb-ot-shape-complex-khmer-machine.hh" - } - - _keys = _khmer_syllable_machine_trans_keys + (cs<<1); - _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs]; - - _slen = _khmer_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) && - ( info[p].khmer_category()) <= _keys[1] ? - ( info[p].khmer_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _khmer_syllable_machine_trans_targs[_trans]; - - if ( _khmer_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _khmer_syllable_machine_trans_actions[_trans] ) { - case 2: -#line 1 "NONE" - {te = p+1;} - break; - case 8: -#line 82 "hb-ot-shape-complex-khmer-machine.rl" - {te = p+1;{ found_syllable (khmer_non_khmer_cluster); }} - break; - case 10: -#line 80 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (khmer_consonant_syllable); }} - break; - case 12: -#line 81 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (khmer_broken_cluster); }} - break; - case 11: -#line 82 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (khmer_non_khmer_cluster); }} - break; - case 1: -#line 80 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (khmer_consonant_syllable); }} - break; - case 5: -#line 81 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (khmer_broken_cluster); }} - break; - case 3: -#line 1 "NONE" - { switch( act ) { - case 2: - {{p = ((te))-1;} found_syllable (khmer_broken_cluster); } - break; - case 3: - {{p = ((te))-1;} found_syllable (khmer_non_khmer_cluster); } - break; - } - } - break; - case 4: -#line 1 "NONE" - {te = p+1;} -#line 81 "hb-ot-shape-complex-khmer-machine.rl" - {act = 2;} - break; - case 9: -#line 1 "NONE" - {te = p+1;} -#line 82 "hb-ot-shape-complex-khmer-machine.rl" - {act = 3;} - break; -#line 366 "hb-ot-shape-complex-khmer-machine.hh" - } - -_again: - switch ( _khmer_syllable_machine_to_state_actions[cs] ) { - case 6: -#line 1 "NONE" - {ts = 0;} - break; -#line 375 "hb-ot-shape-complex-khmer-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _khmer_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 114 "hb-ot-shape-complex-khmer-machine.rl" - -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh deleted file mode 100644 index 35bfbb64d51..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright © 2018 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_SHAPE_COMPLEX_KHMER_HH -#define HB_OT_SHAPE_COMPLEX_KHMER_HH - -#include "hb.hh" - -#include "hb-ot-shape-complex-indic.hh" - - -/* buffer var allocations */ -#define khmer_category() indic_category() /* khmer_category_t */ - - -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum khmer_category_t -{ - OT_Robatic = 20, - OT_Xgroup = 21, - OT_Ygroup = 22, - //OT_VAbv = 26, - //OT_VBlw = 27, - //OT_VPre = 28, - //OT_VPst = 29, -}; - -using khmer_position_t = indic_position_t; - -static inline void -set_khmer_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - khmer_category_t cat = (khmer_category_t) (type & 0xFFu); - khmer_position_t pos = (khmer_position_t) (type >> 8); - - - /* - * Re-assign category - * - * These categories are experimentally extracted from what Uniscribe allows. - */ - switch (u) - { - case 0x179Au: - cat = (khmer_category_t) OT_Ra; - break; - - case 0x17CCu: - case 0x17C9u: - case 0x17CAu: - cat = OT_Robatic; - break; - - case 0x17C6u: - case 0x17CBu: - case 0x17CDu: - case 0x17CEu: - case 0x17CFu: - case 0x17D0u: - case 0x17D1u: - cat = OT_Xgroup; - break; - - case 0x17C7u: - case 0x17C8u: - case 0x17DDu: - case 0x17D3u: /* Just guessing. Uniscribe doesn't categorize it. */ - cat = OT_Ygroup; - break; - } - - /* - * Re-assign position. - */ - if (cat == (khmer_category_t) OT_M) - switch ((int) pos) - { - case POS_PRE_C: cat = (khmer_category_t) OT_VPre; break; - case POS_BELOW_C: cat = (khmer_category_t) OT_VBlw; break; - case POS_ABOVE_C: cat = (khmer_category_t) OT_VAbv; break; - case POS_POST_C: cat = (khmer_category_t) OT_VPst; break; - default: assert (0); - } - - info.khmer_category() = cat; -} - - -#endif /* HB_OT_SHAPE_COMPLEX_KHMER_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh deleted file mode 100644 index f4ef33004d2..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh +++ /dev/null @@ -1,492 +0,0 @@ - -#line 1 "hb-ot-shape-complex-myanmar-machine.rl" -/* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH - -#include "hb.hh" - -enum myanmar_syllable_type_t { - myanmar_consonant_syllable, - myanmar_punctuation_cluster, - myanmar_broken_cluster, - myanmar_non_myanmar_cluster, -}; - - -#line 43 "hb-ot-shape-complex-myanmar-machine.hh" -#define myanmar_syllable_machine_ex_A 10u -#define myanmar_syllable_machine_ex_As 18u -#define myanmar_syllable_machine_ex_C 1u -#define myanmar_syllable_machine_ex_CS 19u -#define myanmar_syllable_machine_ex_D 32u -#define myanmar_syllable_machine_ex_D0 20u -#define myanmar_syllable_machine_ex_DB 3u -#define myanmar_syllable_machine_ex_GB 11u -#define myanmar_syllable_machine_ex_H 4u -#define myanmar_syllable_machine_ex_IV 2u -#define myanmar_syllable_machine_ex_MH 21u -#define myanmar_syllable_machine_ex_ML 33u -#define myanmar_syllable_machine_ex_MR 22u -#define myanmar_syllable_machine_ex_MW 23u -#define myanmar_syllable_machine_ex_MY 24u -#define myanmar_syllable_machine_ex_P 31u -#define myanmar_syllable_machine_ex_PT 25u -#define myanmar_syllable_machine_ex_Ra 16u -#define myanmar_syllable_machine_ex_V 8u -#define myanmar_syllable_machine_ex_VAbv 26u -#define myanmar_syllable_machine_ex_VBlw 27u -#define myanmar_syllable_machine_ex_VPre 28u -#define myanmar_syllable_machine_ex_VPst 29u -#define myanmar_syllable_machine_ex_VS 30u -#define myanmar_syllable_machine_ex_ZWJ 6u -#define myanmar_syllable_machine_ex_ZWNJ 5u - - -#line 72 "hb-ot-shape-complex-myanmar-machine.hh" -static const unsigned char _myanmar_syllable_machine_trans_keys[] = { - 1u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, - 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u, - 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u, 3u, 33u, - 3u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, - 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u, - 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u, - 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 1u, 33u, 1u, 32u, 8u, 8u, - 0 -}; - -static const char _myanmar_syllable_machine_key_spans[] = { - 33, 31, 25, 4, 25, 23, 21, 21, - 31, 27, 27, 27, 31, 16, 31, 31, - 27, 27, 27, 28, 27, 31, 31, 31, - 31, 31, 25, 4, 25, 23, 21, 21, - 31, 27, 27, 27, 31, 16, 31, 31, - 31, 27, 27, 27, 28, 27, 31, 31, - 31, 31, 31, 31, 31, 33, 32, 1 -}; - -static const short _myanmar_syllable_machine_index_offsets[] = { - 0, 34, 66, 92, 97, 123, 147, 169, - 191, 223, 251, 279, 307, 339, 356, 388, - 420, 448, 476, 504, 533, 561, 593, 625, - 657, 689, 721, 747, 752, 778, 802, 824, - 846, 878, 906, 934, 962, 994, 1011, 1043, - 1075, 1107, 1135, 1163, 1191, 1220, 1248, 1280, - 1312, 1344, 1376, 1408, 1440, 1472, 1506, 1539 -}; - -static const char _myanmar_syllable_machine_indicies[] = { - 1, 1, 2, 3, 4, 4, 0, 5, - 0, 6, 1, 0, 0, 0, 0, 7, - 0, 8, 9, 0, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 1, - 21, 0, 23, 24, 25, 25, 22, 26, - 22, 27, 22, 22, 22, 22, 22, 22, - 22, 28, 22, 22, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 22, 22, - 39, 22, 25, 25, 22, 26, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 40, - 22, 22, 22, 22, 22, 22, 33, 22, - 22, 22, 37, 22, 25, 25, 22, 26, - 22, 25, 25, 22, 26, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 33, 22, 22, - 22, 37, 22, 41, 22, 25, 25, 22, - 26, 22, 33, 22, 22, 22, 22, 22, - 22, 22, 42, 22, 22, 22, 22, 22, - 22, 33, 22, 25, 25, 22, 26, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 42, 22, 22, 22, 22, 22, 22, 33, - 22, 25, 25, 22, 26, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 33, 22, 23, - 22, 25, 25, 22, 26, 22, 27, 22, - 22, 22, 22, 22, 22, 22, 43, 22, - 22, 44, 22, 22, 22, 33, 45, 22, - 22, 37, 22, 22, 22, 43, 22, 23, - 22, 25, 25, 22, 26, 22, 27, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 33, 22, 22, - 22, 37, 22, 23, 22, 25, 25, 22, - 26, 22, 27, 22, 22, 22, 22, 22, - 22, 22, 43, 22, 22, 22, 22, 22, - 22, 33, 45, 22, 22, 37, 22, 23, - 22, 25, 25, 22, 26, 22, 27, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 33, 45, 22, - 22, 37, 22, 23, 22, 25, 25, 22, - 26, 22, 27, 22, 22, 22, 22, 22, - 22, 22, 43, 22, 22, 22, 22, 22, - 22, 33, 45, 22, 22, 37, 22, 22, - 22, 43, 22, 1, 1, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 1, 22, 23, 22, 25, 25, - 22, 26, 22, 27, 22, 22, 22, 22, - 22, 22, 22, 28, 22, 22, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 22, - 22, 22, 39, 22, 23, 22, 25, 25, - 22, 26, 22, 27, 22, 22, 22, 22, - 22, 22, 22, 46, 22, 22, 22, 22, - 22, 22, 33, 34, 35, 36, 37, 22, - 22, 22, 39, 22, 23, 22, 25, 25, - 22, 26, 22, 27, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 33, 34, 35, 36, 37, 22, - 23, 22, 25, 25, 22, 26, 22, 27, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 33, 34, - 35, 22, 37, 22, 23, 22, 25, 25, - 22, 26, 22, 27, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 33, 22, 35, 22, 37, 22, - 23, 22, 25, 25, 22, 26, 22, 27, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 33, 34, - 35, 36, 37, 46, 22, 23, 22, 25, - 25, 22, 26, 22, 27, 22, 22, 22, - 22, 22, 22, 22, 46, 22, 22, 22, - 22, 22, 22, 33, 34, 35, 36, 37, - 22, 23, 22, 25, 25, 22, 26, 22, - 27, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 29, 22, 31, 22, 33, - 34, 35, 36, 37, 22, 22, 22, 39, - 22, 23, 22, 25, 25, 22, 26, 22, - 27, 22, 22, 22, 22, 22, 22, 22, - 46, 22, 22, 29, 22, 22, 22, 33, - 34, 35, 36, 37, 22, 22, 22, 39, - 22, 23, 22, 25, 25, 22, 26, 22, - 27, 22, 22, 22, 22, 22, 22, 22, - 47, 22, 22, 29, 30, 31, 22, 33, - 34, 35, 36, 37, 22, 22, 22, 39, - 22, 23, 22, 25, 25, 22, 26, 22, - 27, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 29, 30, 31, 22, 33, - 34, 35, 36, 37, 22, 22, 22, 39, - 22, 23, 24, 25, 25, 22, 26, 22, - 27, 22, 22, 22, 22, 22, 22, 22, - 28, 22, 22, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 22, 22, 22, 39, - 22, 49, 49, 48, 5, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 50, 48, - 48, 48, 48, 48, 48, 14, 48, 48, - 48, 18, 48, 49, 49, 48, 5, 48, - 49, 49, 48, 5, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 14, 48, 48, 48, - 18, 48, 51, 48, 49, 49, 48, 5, - 48, 14, 48, 48, 48, 48, 48, 48, - 48, 52, 48, 48, 48, 48, 48, 48, - 14, 48, 49, 49, 48, 5, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 52, - 48, 48, 48, 48, 48, 48, 14, 48, - 49, 49, 48, 5, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 14, 48, 2, 48, - 49, 49, 48, 5, 48, 6, 48, 48, - 48, 48, 48, 48, 48, 53, 48, 48, - 54, 48, 48, 48, 14, 55, 48, 48, - 18, 48, 48, 48, 53, 48, 2, 48, - 49, 49, 48, 5, 48, 6, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 14, 48, 48, 48, - 18, 48, 2, 48, 49, 49, 48, 5, - 48, 6, 48, 48, 48, 48, 48, 48, - 48, 53, 48, 48, 48, 48, 48, 48, - 14, 55, 48, 48, 18, 48, 2, 48, - 49, 49, 48, 5, 48, 6, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 14, 55, 48, 48, - 18, 48, 2, 48, 49, 49, 48, 5, - 48, 6, 48, 48, 48, 48, 48, 48, - 48, 53, 48, 48, 48, 48, 48, 48, - 14, 55, 48, 48, 18, 48, 48, 48, - 53, 48, 56, 56, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 56, 48, 2, 3, 49, 49, 48, - 5, 48, 6, 48, 48, 48, 48, 48, - 48, 48, 8, 48, 48, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 48, - 48, 21, 48, 2, 48, 49, 49, 48, - 5, 48, 6, 48, 48, 48, 48, 48, - 48, 48, 8, 48, 48, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 48, 48, - 48, 21, 48, 2, 48, 49, 49, 48, - 5, 48, 6, 48, 48, 48, 48, 48, - 48, 48, 57, 48, 48, 48, 48, 48, - 48, 14, 15, 16, 17, 18, 48, 48, - 48, 21, 48, 2, 48, 49, 49, 48, - 5, 48, 6, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 14, 15, 16, 17, 18, 48, 2, - 48, 49, 49, 48, 5, 48, 6, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 14, 15, 16, - 48, 18, 48, 2, 48, 49, 49, 48, - 5, 48, 6, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 14, 48, 16, 48, 18, 48, 2, - 48, 49, 49, 48, 5, 48, 6, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 14, 15, 16, - 17, 18, 57, 48, 2, 48, 49, 49, - 48, 5, 48, 6, 48, 48, 48, 48, - 48, 48, 48, 57, 48, 48, 48, 48, - 48, 48, 14, 15, 16, 17, 18, 48, - 2, 48, 49, 49, 48, 5, 48, 6, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 10, 48, 12, 48, 14, 15, - 16, 17, 18, 48, 48, 48, 21, 48, - 2, 48, 49, 49, 48, 5, 48, 6, - 48, 48, 48, 48, 48, 48, 48, 57, - 48, 48, 10, 48, 48, 48, 14, 15, - 16, 17, 18, 48, 48, 48, 21, 48, - 2, 48, 49, 49, 48, 5, 48, 6, - 48, 48, 48, 48, 48, 48, 48, 58, - 48, 48, 10, 11, 12, 48, 14, 15, - 16, 17, 18, 48, 48, 48, 21, 48, - 2, 48, 49, 49, 48, 5, 48, 6, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 10, 11, 12, 48, 14, 15, - 16, 17, 18, 48, 48, 48, 21, 48, - 2, 3, 49, 49, 48, 5, 48, 6, - 48, 48, 48, 48, 48, 48, 48, 8, - 48, 48, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 48, 48, 48, 21, 48, - 23, 24, 25, 25, 22, 26, 22, 27, - 22, 22, 22, 22, 22, 22, 22, 59, - 22, 22, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 22, 22, 39, 22, - 23, 60, 25, 25, 22, 26, 22, 27, - 22, 22, 22, 22, 22, 22, 22, 28, - 22, 22, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 22, 22, 22, 39, 22, - 1, 1, 2, 3, 49, 49, 48, 5, - 48, 6, 1, 48, 48, 48, 48, 1, - 48, 8, 48, 48, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 48, 1, - 21, 48, 1, 1, 61, 61, 61, 61, - 61, 61, 61, 61, 1, 61, 61, 61, - 61, 1, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 1, 61, 62, 61, 0 -}; - -static const char _myanmar_syllable_machine_trans_targs[] = { - 0, 1, 26, 37, 0, 27, 33, 51, - 39, 54, 40, 46, 47, 48, 29, 42, - 43, 44, 32, 50, 55, 45, 0, 2, - 13, 0, 3, 9, 14, 15, 21, 22, - 23, 5, 17, 18, 19, 8, 25, 20, - 4, 6, 7, 10, 12, 11, 16, 24, - 0, 0, 28, 30, 31, 34, 36, 35, - 38, 41, 49, 52, 53, 0, 0 -}; - -static const char _myanmar_syllable_machine_trans_actions[] = { - 3, 0, 0, 0, 4, 0, 0, 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, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 7, 8, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 10 -}; - -static const char _myanmar_syllable_machine_to_state_actions[] = { - 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, 0, 0, 0, 0, 0, 0, 0 -}; - -static const char _myanmar_syllable_machine_from_state_actions[] = { - 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 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, 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, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 23, 23, 49, 62, 62 -}; - -static const int myanmar_syllable_machine_start = 0; -static const int myanmar_syllable_machine_first_final = 0; -static const int myanmar_syllable_machine_error = -1; - -static const int myanmar_syllable_machine_en_main = 0; - - -#line 44 "hb-ot-shape-complex-myanmar-machine.rl" - - - -#line 102 "hb-ot-shape-complex-myanmar-machine.rl" - - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_myanmar (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 382 "hb-ot-shape-complex-myanmar-machine.hh" - { - cs = myanmar_syllable_machine_start; - ts = 0; - te = 0; - act = 0; - } - -#line 122 "hb-ot-shape-complex-myanmar-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 398 "hb-ot-shape-complex-myanmar-machine.hh" - { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _myanmar_syllable_machine_from_state_actions[cs] ) { - case 2: -#line 1 "NONE" - {ts = p;} - break; -#line 412 "hb-ot-shape-complex-myanmar-machine.hh" - } - - _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); - _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs]; - - _slen = _myanmar_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) && - ( info[p].myanmar_category()) <= _keys[1] ? - ( info[p].myanmar_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _myanmar_syllable_machine_trans_targs[_trans]; - - if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { - case 6: -#line 94 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (myanmar_consonant_syllable); }} - break; - case 4: -#line 95 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} - break; - case 10: -#line 96 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (myanmar_punctuation_cluster); }} - break; - case 8: -#line 97 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (myanmar_broken_cluster); }} - break; - case 3: -#line 98 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} - break; - case 5: -#line 94 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} - break; - case 7: -#line 97 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_broken_cluster); }} - break; - case 9: -#line 98 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} - break; -#line 462 "hb-ot-shape-complex-myanmar-machine.hh" - } - -_again: - switch ( _myanmar_syllable_machine_to_state_actions[cs] ) { - case 1: -#line 1 "NONE" - {ts = 0;} - break; -#line 471 "hb-ot-shape-complex-myanmar-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _myanmar_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 130 "hb-ot-shape-complex-myanmar-machine.rl" - -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh deleted file mode 100644 index 7fbca3878f2..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright © 2018 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_SHAPE_COMPLEX_MYANMAR_HH -#define HB_OT_SHAPE_COMPLEX_MYANMAR_HH - -#include "hb.hh" - -#include "hb-ot-shape-complex-indic.hh" - - -/* buffer var allocations */ -#define myanmar_category() indic_category() /* myanmar_category_t */ -#define myanmar_position() indic_position() /* myanmar_position_t */ - - -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum myanmar_category_t { - OT_As = 18, /* Asat */ - OT_D0 = 20, /* Digit zero */ - OT_DB = OT_N, /* Dot below */ - OT_GB = OT_PLACEHOLDER, - OT_MH = 21, /* Various consonant medial types */ - OT_MR = 22, /* Various consonant medial types */ - OT_MW = 23, /* Various consonant medial types */ - OT_MY = 24, /* Various consonant medial types */ - OT_PT = 25, /* Pwo and other tones */ - //OT_VAbv = 26, - //OT_VBlw = 27, - //OT_VPre = 28, - //OT_VPst = 29, - OT_VS = 30, /* Variation selectors */ - OT_P = 31, /* Punctuation */ - OT_D = 32, /* Digits except zero */ - OT_ML = 33, /* Various consonant medial types */ -}; - -using myanmar_position_t = indic_position_t; - -static inline void -set_myanmar_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - unsigned int cat = type & 0xFFu; - myanmar_position_t pos = (myanmar_position_t) (type >> 8); - - /* Myanmar - * https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze - */ - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu))) - cat = OT_VS; - - switch (u) - { - case 0x104Eu: - cat = OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */ - break; - - case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u: - case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u: - case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu: - case 0x25FEu: - cat = OT_GB; - break; - - case 0x1004u: case 0x101Bu: case 0x105Au: - cat = OT_Ra; - break; - - case 0x1032u: case 0x1036u: - cat = OT_A; - break; - - case 0x1039u: - cat = OT_H; - break; - - case 0x103Au: - cat = OT_As; - break; - - case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u: - case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u: - case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u: - case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u: - case 0x1097u: case 0x1098u: case 0x1099u: - cat = OT_D; - break; - - case 0x1040u: - cat = OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ - break; - - case 0x103Eu: - cat = OT_MH; - break; - - case 0x1060u: - cat = OT_ML; - break; - - case 0x103Cu: - cat = OT_MR; - break; - - case 0x103Du: case 0x1082u: - cat = OT_MW; - break; - - case 0x103Bu: case 0x105Eu: case 0x105Fu: - cat = OT_MY; - break; - - case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au: - case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu: - cat = OT_PT; - break; - - case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u: - case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du: - case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu: - cat = OT_SM; - break; - - case 0x104Au: case 0x104Bu: - cat = OT_P; - break; - - case 0xAA74u: case 0xAA75u: case 0xAA76u: - /* https://github.com/harfbuzz/harfbuzz/issues/218 */ - cat = OT_C; - break; - } - - if (cat == OT_M) - { - switch ((int) pos) - { - case POS_PRE_C: cat = (myanmar_category_t) OT_VPre; - pos = POS_PRE_M; break; - case POS_ABOVE_C: cat = (myanmar_category_t) OT_VAbv; break; - case POS_BELOW_C: cat = (myanmar_category_t) OT_VBlw; break; - case POS_POST_C: cat = (myanmar_category_t) OT_VPst; break; - } - } - - info.myanmar_category() = cat; - info.myanmar_position() = pos; -} - - -#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh deleted file mode 100644 index 468bd95c3fe..00000000000 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh +++ /dev/null @@ -1,849 +0,0 @@ - -#line 1 "hb-ot-shape-complex-use-machine.rl" -/* - * Copyright © 2015 Mozilla Foundation. - * Copyright © 2015 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. - * - * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH - -#include "hb.hh" - -#include "hb-ot-shape-complex-syllabic.hh" - -/* buffer var allocations */ -#define use_category() complex_var_u8_category() - -#define USE(Cat) use_syllable_machine_ex_##Cat - -enum use_syllable_type_t { - use_virama_terminated_cluster, - use_sakot_terminated_cluster, - use_standard_cluster, - use_number_joiner_terminated_cluster, - use_numeral_cluster, - use_symbol_cluster, - use_hieroglyph_cluster, - use_broken_cluster, - use_non_cluster, -}; - - -#line 57 "hb-ot-shape-complex-use-machine.hh" -#define use_syllable_machine_ex_B 1u -#define use_syllable_machine_ex_CGJ 6u -#define use_syllable_machine_ex_CMAbv 31u -#define use_syllable_machine_ex_CMBlw 32u -#define use_syllable_machine_ex_CS 43u -#define use_syllable_machine_ex_FAbv 24u -#define use_syllable_machine_ex_FBlw 25u -#define use_syllable_machine_ex_FMAbv 45u -#define use_syllable_machine_ex_FMBlw 46u -#define use_syllable_machine_ex_FMPst 47u -#define use_syllable_machine_ex_FPst 26u -#define use_syllable_machine_ex_G 49u -#define use_syllable_machine_ex_GB 5u -#define use_syllable_machine_ex_H 12u -#define use_syllable_machine_ex_HN 13u -#define use_syllable_machine_ex_IS 44u -#define use_syllable_machine_ex_J 50u -#define use_syllable_machine_ex_MAbv 27u -#define use_syllable_machine_ex_MBlw 28u -#define use_syllable_machine_ex_MPre 30u -#define use_syllable_machine_ex_MPst 29u -#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_SB 51u -#define use_syllable_machine_ex_SE 52u -#define use_syllable_machine_ex_SMAbv 41u -#define use_syllable_machine_ex_SMBlw 42u -#define use_syllable_machine_ex_SUB 11u -#define use_syllable_machine_ex_Sk 48u -#define use_syllable_machine_ex_VAbv 33u -#define use_syllable_machine_ex_VBlw 34u -#define use_syllable_machine_ex_VMAbv 37u -#define use_syllable_machine_ex_VMBlw 38u -#define use_syllable_machine_ex_VMPre 23u -#define use_syllable_machine_ex_VMPst 39u -#define use_syllable_machine_ex_VPre 22u -#define use_syllable_machine_ex_VPst 35u -#define use_syllable_machine_ex_WJ 16u -#define use_syllable_machine_ex_ZWNJ 14u - - -#line 100 "hb-ot-shape-complex-use-machine.hh" -static const unsigned char _use_syllable_machine_trans_keys[] = { - 0u, 51u, 11u, 48u, 11u, 48u, 1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, - 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, - 23u, 48u, 23u, 48u, 23u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, - 1u, 1u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 48u, 23u, 48u, - 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, - 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 12u, 48u, 12u, 48u, - 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 13u, 13u, 4u, 4u, 11u, 48u, 11u, 48u, - 1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, - 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, - 12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 11u, 48u, 11u, 48u, - 1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, - 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, - 12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 4u, 4u, 13u, 13u, - 1u, 48u, 11u, 48u, 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, - 0 -}; - -static const char _use_syllable_machine_key_spans[] = { - 52, 38, 38, 48, 26, 24, 23, 22, - 2, 1, 25, 25, 25, 1, 25, 27, - 26, 26, 26, 37, 37, 37, 37, 38, - 1, 38, 2, 1, 38, 38, 48, 26, - 24, 23, 22, 2, 1, 25, 25, 25, - 1, 25, 27, 26, 26, 26, 37, 37, - 37, 37, 38, 1, 1, 1, 38, 38, - 48, 26, 24, 23, 22, 2, 1, 25, - 25, 25, 1, 25, 27, 26, 26, 26, - 37, 37, 37, 37, 38, 1, 38, 38, - 48, 26, 24, 23, 22, 2, 1, 25, - 25, 25, 1, 25, 27, 26, 26, 26, - 37, 37, 37, 37, 38, 1, 1, 1, - 48, 38, 2, 1, 5, 3, 4, 3 -}; - -static const short _use_syllable_machine_index_offsets[] = { - 0, 53, 92, 131, 180, 207, 232, 256, - 279, 282, 284, 310, 336, 362, 364, 390, - 418, 445, 472, 499, 537, 575, 613, 651, - 690, 692, 731, 734, 736, 775, 814, 863, - 890, 915, 939, 962, 965, 967, 993, 1019, - 1045, 1047, 1073, 1101, 1128, 1155, 1182, 1220, - 1258, 1296, 1334, 1373, 1375, 1377, 1379, 1418, - 1457, 1506, 1533, 1558, 1582, 1605, 1608, 1610, - 1636, 1662, 1688, 1690, 1716, 1744, 1771, 1798, - 1825, 1863, 1901, 1939, 1977, 2016, 2018, 2057, - 2096, 2145, 2172, 2197, 2221, 2244, 2247, 2249, - 2275, 2301, 2327, 2329, 2355, 2383, 2410, 2437, - 2464, 2502, 2540, 2578, 2616, 2655, 2657, 2659, - 2661, 2710, 2749, 2752, 2754, 2760, 2764, 2769 -}; - -static const char _use_syllable_machine_indicies[] = { - 0, 1, 2, 2, 3, 4, 2, 2, - 2, 2, 2, 5, 6, 7, 2, 2, - 2, 2, 8, 2, 2, 2, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 2, 23, 24, 25, - 2, 26, 27, 28, 29, 30, 31, 32, - 29, 33, 2, 34, 2, 36, 37, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 35, 52, - 53, 54, 35, 55, 56, 35, 57, 58, - 59, 60, 57, 35, 36, 37, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 48, 48, 49, 50, 51, 35, 52, 53, - 54, 35, 35, 35, 35, 57, 58, 59, - 60, 57, 35, 36, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 39, 40, 41, 42, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 52, - 53, 54, 35, 35, 35, 35, 35, 58, - 59, 60, 61, 35, 39, 40, 41, 42, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 52, 53, 54, 35, 35, 35, - 35, 35, 58, 59, 60, 61, 35, 40, - 41, 42, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 58, 59, 60, 35, - 41, 42, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 58, 59, 60, 35, - 42, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 58, 59, 60, 35, 58, - 59, 35, 59, 35, 40, 41, 42, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 52, 53, 54, 35, 35, 35, 35, - 35, 58, 59, 60, 61, 35, 40, 41, - 42, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 53, 54, 35, 35, - 35, 35, 35, 58, 59, 60, 61, 35, - 40, 41, 42, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 54, - 35, 35, 35, 35, 35, 58, 59, 60, - 61, 35, 62, 35, 40, 41, 42, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 58, 59, 60, 61, 35, 38, 39, - 40, 41, 42, 35, 35, 35, 35, 35, - 35, 49, 50, 51, 35, 52, 53, 54, - 35, 35, 35, 35, 35, 58, 59, 60, - 61, 35, 39, 40, 41, 42, 35, 35, - 35, 35, 35, 35, 49, 50, 51, 35, - 52, 53, 54, 35, 35, 35, 35, 35, - 58, 59, 60, 61, 35, 39, 40, 41, - 42, 35, 35, 35, 35, 35, 35, 35, - 50, 51, 35, 52, 53, 54, 35, 35, - 35, 35, 35, 58, 59, 60, 61, 35, - 39, 40, 41, 42, 35, 35, 35, 35, - 35, 35, 35, 35, 51, 35, 52, 53, - 54, 35, 35, 35, 35, 35, 58, 59, - 60, 61, 35, 39, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 38, 39, 40, - 41, 42, 35, 44, 45, 35, 35, 35, - 49, 50, 51, 35, 52, 53, 54, 35, - 35, 35, 35, 35, 58, 59, 60, 61, - 35, 39, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 38, 39, 40, 41, 42, - 35, 35, 45, 35, 35, 35, 49, 50, - 51, 35, 52, 53, 54, 35, 35, 35, - 35, 35, 58, 59, 60, 61, 35, 39, - 35, 35, 35, 35, 35, 35, 35, 35, - 35, 38, 39, 40, 41, 42, 35, 35, - 35, 35, 35, 35, 49, 50, 51, 35, - 52, 53, 54, 35, 35, 35, 35, 35, - 58, 59, 60, 61, 35, 39, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 38, - 39, 40, 41, 42, 43, 44, 45, 35, - 35, 35, 49, 50, 51, 35, 52, 53, - 54, 35, 35, 35, 35, 35, 58, 59, - 60, 61, 35, 36, 37, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 35, - 48, 49, 50, 51, 35, 52, 53, 54, - 35, 35, 35, 35, 57, 58, 59, 60, - 57, 35, 36, 35, 36, 37, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 38, - 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 35, 52, 53, - 54, 35, 35, 35, 35, 57, 58, 59, - 60, 57, 35, 55, 56, 35, 56, 35, - 64, 65, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 1, 75, 76, 77, - 78, 63, 79, 80, 81, 63, 63, 63, - 63, 82, 83, 84, 85, 86, 63, 64, - 65, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 75, 76, 77, 78, - 63, 79, 80, 81, 63, 63, 63, 63, - 82, 83, 84, 85, 86, 63, 64, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 67, 68, 69, 70, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 79, 80, 81, 63, 63, 63, - 63, 63, 83, 84, 85, 87, 63, 67, - 68, 69, 70, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 79, 80, 81, - 63, 63, 63, 63, 63, 83, 84, 85, - 87, 63, 68, 69, 70, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 83, - 84, 85, 63, 69, 70, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 83, - 84, 85, 63, 70, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 83, 84, - 85, 63, 83, 84, 63, 84, 63, 68, - 69, 70, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 79, 80, 81, 63, - 63, 63, 63, 63, 83, 84, 85, 87, - 63, 68, 69, 70, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 80, - 81, 63, 63, 63, 63, 63, 83, 84, - 85, 87, 63, 68, 69, 70, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 81, 63, 63, 63, 63, 63, - 83, 84, 85, 87, 63, 89, 88, 68, - 69, 70, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 83, 84, 85, 87, - 63, 66, 67, 68, 69, 70, 63, 63, - 63, 63, 63, 63, 76, 77, 78, 63, - 79, 80, 81, 63, 63, 63, 63, 63, - 83, 84, 85, 87, 63, 67, 68, 69, - 70, 63, 63, 63, 63, 63, 63, 76, - 77, 78, 63, 79, 80, 81, 63, 63, - 63, 63, 63, 83, 84, 85, 87, 63, - 67, 68, 69, 70, 63, 63, 63, 63, - 63, 63, 63, 77, 78, 63, 79, 80, - 81, 63, 63, 63, 63, 63, 83, 84, - 85, 87, 63, 67, 68, 69, 70, 63, - 63, 63, 63, 63, 63, 63, 63, 78, - 63, 79, 80, 81, 63, 63, 63, 63, - 63, 83, 84, 85, 87, 63, 67, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 66, 67, 68, 69, 70, 63, 72, 73, - 63, 63, 63, 76, 77, 78, 63, 79, - 80, 81, 63, 63, 63, 63, 63, 83, - 84, 85, 87, 63, 67, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 66, 67, - 68, 69, 70, 63, 63, 73, 63, 63, - 63, 76, 77, 78, 63, 79, 80, 81, - 63, 63, 63, 63, 63, 83, 84, 85, - 87, 63, 67, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 66, 67, 68, 69, - 70, 63, 63, 63, 63, 63, 63, 76, - 77, 78, 63, 79, 80, 81, 63, 63, - 63, 63, 63, 83, 84, 85, 87, 63, - 67, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 66, 67, 68, 69, 70, 71, - 72, 73, 63, 63, 63, 76, 77, 78, - 63, 79, 80, 81, 63, 63, 63, 63, - 63, 83, 84, 85, 87, 63, 64, 65, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 63, 75, 76, 77, 78, 63, - 79, 80, 81, 63, 63, 63, 63, 82, - 83, 84, 85, 86, 63, 64, 90, 92, - 91, 3, 93, 94, 95, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 63, 110, 111, 112, - 63, 55, 56, 63, 113, 114, 115, 85, - 116, 63, 94, 95, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 106, 106, - 107, 108, 109, 63, 110, 111, 112, 63, - 63, 63, 63, 113, 114, 115, 85, 116, - 63, 94, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 97, - 98, 99, 100, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 110, 111, 112, - 63, 63, 63, 63, 63, 114, 115, 85, - 117, 63, 97, 98, 99, 100, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 110, 111, 112, 63, 63, 63, 63, 63, - 114, 115, 85, 117, 63, 98, 99, 100, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 114, 115, 85, 63, 99, 100, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 114, 115, 85, 63, 100, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 114, 115, 85, 63, 114, 115, 63, - 115, 63, 98, 99, 100, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 110, - 111, 112, 63, 63, 63, 63, 63, 114, - 115, 85, 117, 63, 98, 99, 100, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 111, 112, 63, 63, 63, 63, - 63, 114, 115, 85, 117, 63, 98, 99, - 100, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 112, 63, 63, - 63, 63, 63, 114, 115, 85, 117, 63, - 118, 88, 98, 99, 100, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 114, - 115, 85, 117, 63, 96, 97, 98, 99, - 100, 63, 63, 63, 63, 63, 63, 107, - 108, 109, 63, 110, 111, 112, 63, 63, - 63, 63, 63, 114, 115, 85, 117, 63, - 97, 98, 99, 100, 63, 63, 63, 63, - 63, 63, 107, 108, 109, 63, 110, 111, - 112, 63, 63, 63, 63, 63, 114, 115, - 85, 117, 63, 97, 98, 99, 100, 63, - 63, 63, 63, 63, 63, 63, 108, 109, - 63, 110, 111, 112, 63, 63, 63, 63, - 63, 114, 115, 85, 117, 63, 97, 98, - 99, 100, 63, 63, 63, 63, 63, 63, - 63, 63, 109, 63, 110, 111, 112, 63, - 63, 63, 63, 63, 114, 115, 85, 117, - 63, 97, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 96, 97, 98, 99, 100, - 63, 102, 103, 63, 63, 63, 107, 108, - 109, 63, 110, 111, 112, 63, 63, 63, - 63, 63, 114, 115, 85, 117, 63, 97, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 96, 97, 98, 99, 100, 63, 63, - 103, 63, 63, 63, 107, 108, 109, 63, - 110, 111, 112, 63, 63, 63, 63, 63, - 114, 115, 85, 117, 63, 97, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 96, - 97, 98, 99, 100, 63, 63, 63, 63, - 63, 63, 107, 108, 109, 63, 110, 111, - 112, 63, 63, 63, 63, 63, 114, 115, - 85, 117, 63, 97, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 96, 97, 98, - 99, 100, 101, 102, 103, 63, 63, 63, - 107, 108, 109, 63, 110, 111, 112, 63, - 63, 63, 63, 63, 114, 115, 85, 117, - 63, 94, 95, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 63, 106, 107, - 108, 109, 63, 110, 111, 112, 63, 63, - 63, 63, 113, 114, 115, 85, 116, 63, - 94, 90, 94, 95, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 63, 110, 111, 112, 63, - 63, 63, 63, 113, 114, 115, 85, 116, - 63, 5, 6, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 19, 19, 20, - 21, 22, 119, 23, 24, 25, 119, 119, - 119, 119, 29, 30, 31, 32, 29, 119, - 5, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 10, 11, - 12, 13, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 23, 24, 25, 119, - 119, 119, 119, 119, 30, 31, 32, 120, - 119, 10, 11, 12, 13, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 23, - 24, 25, 119, 119, 119, 119, 119, 30, - 31, 32, 120, 119, 11, 12, 13, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 30, 31, 32, 119, 12, 13, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 30, 31, 32, 119, 13, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 30, 31, 32, 119, 30, 31, 119, 31, - 119, 11, 12, 13, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 23, 24, - 25, 119, 119, 119, 119, 119, 30, 31, - 32, 120, 119, 11, 12, 13, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 24, 25, 119, 119, 119, 119, 119, - 30, 31, 32, 120, 119, 11, 12, 13, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 25, 119, 119, 119, - 119, 119, 30, 31, 32, 120, 119, 121, - 119, 11, 12, 13, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 30, 31, - 32, 120, 119, 9, 10, 11, 12, 13, - 119, 119, 119, 119, 119, 119, 20, 21, - 22, 119, 23, 24, 25, 119, 119, 119, - 119, 119, 30, 31, 32, 120, 119, 10, - 11, 12, 13, 119, 119, 119, 119, 119, - 119, 20, 21, 22, 119, 23, 24, 25, - 119, 119, 119, 119, 119, 30, 31, 32, - 120, 119, 10, 11, 12, 13, 119, 119, - 119, 119, 119, 119, 119, 21, 22, 119, - 23, 24, 25, 119, 119, 119, 119, 119, - 30, 31, 32, 120, 119, 10, 11, 12, - 13, 119, 119, 119, 119, 119, 119, 119, - 119, 22, 119, 23, 24, 25, 119, 119, - 119, 119, 119, 30, 31, 32, 120, 119, - 10, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 9, 10, 11, 12, 13, 119, - 15, 16, 119, 119, 119, 20, 21, 22, - 119, 23, 24, 25, 119, 119, 119, 119, - 119, 30, 31, 32, 120, 119, 10, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 9, 10, 11, 12, 13, 119, 119, 16, - 119, 119, 119, 20, 21, 22, 119, 23, - 24, 25, 119, 119, 119, 119, 119, 30, - 31, 32, 120, 119, 10, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 9, 10, - 11, 12, 13, 119, 119, 119, 119, 119, - 119, 20, 21, 22, 119, 23, 24, 25, - 119, 119, 119, 119, 119, 30, 31, 32, - 120, 119, 10, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 9, 10, 11, 12, - 13, 14, 15, 16, 119, 119, 119, 20, - 21, 22, 119, 23, 24, 25, 119, 119, - 119, 119, 119, 30, 31, 32, 120, 119, - 5, 6, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 119, 19, 20, 21, - 22, 119, 23, 24, 25, 119, 119, 119, - 119, 29, 30, 31, 32, 29, 119, 5, - 119, 122, 119, 7, 119, 1, 119, 119, - 119, 1, 119, 119, 119, 119, 119, 5, - 6, 7, 119, 119, 119, 119, 119, 119, - 119, 119, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 119, 23, 24, 25, 119, 26, 27, 119, - 29, 30, 31, 32, 29, 119, 5, 6, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 119, - 23, 24, 25, 119, 119, 119, 119, 29, - 30, 31, 32, 29, 119, 26, 27, 119, - 27, 119, 1, 123, 123, 123, 1, 123, - 125, 124, 33, 124, 33, 125, 124, 125, - 124, 33, 124, 34, 124, 0 -}; - -static const char _use_syllable_machine_trans_targs[] = { - 1, 28, 0, 52, 54, 79, 80, 102, - 104, 92, 81, 82, 83, 84, 96, 97, - 98, 99, 105, 100, 93, 94, 95, 87, - 88, 89, 106, 107, 108, 101, 85, 86, - 0, 109, 111, 0, 2, 3, 15, 4, - 5, 6, 7, 19, 20, 21, 22, 25, - 23, 16, 17, 18, 10, 11, 12, 26, - 27, 24, 8, 9, 0, 13, 14, 0, - 29, 30, 42, 31, 32, 33, 34, 46, - 47, 48, 49, 50, 43, 44, 45, 37, - 38, 39, 51, 35, 36, 0, 51, 40, - 0, 41, 0, 0, 53, 0, 55, 56, - 68, 57, 58, 59, 60, 72, 73, 74, - 75, 78, 76, 69, 70, 71, 63, 64, - 65, 77, 61, 62, 77, 66, 67, 0, - 90, 91, 103, 0, 0, 110 -}; - -static const char _use_syllable_machine_trans_actions[] = { - 0, 0, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 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, 0, 7, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 8, 0, 0, 9, 10, 0, - 11, 0, 12, 13, 0, 14, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 0, 0, 10, 0, 0, 15, - 0, 0, 0, 16, 17, 0 -}; - -static const char _use_syllable_machine_to_state_actions[] = { - 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, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 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[] = { - 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 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[] = { - 0, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 89, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 91, 92, 94, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 89, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 91, 64, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 124, 125, 125, 125 -}; - -static const int use_syllable_machine_start = 0; -static const int use_syllable_machine_first_final = 0; -static const int use_syllable_machine_error = -1; - -static const int use_syllable_machine_en_main = 0; - - -#line 58 "hb-ot-shape-complex-use-machine.rl" - - - -#line 181 "hb-ot-shape-complex-use-machine.rl" - - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \ - for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - - -template <typename Iter> -struct machine_index_t : - hb_iter_with_fallback_t<machine_index_t<Iter>, - typename Iter::item_t> -{ - machine_index_t (const Iter& it) : it (it) {} - machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>, - typename Iter::item_t> (), - it (o.it), is_null (o.is_null) {} - - static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; - static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; - - typename Iter::item_t __item__ () const { return *it; } - typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; } - unsigned __len__ () const { return it.len (); } - void __next__ () { ++it; } - void __forward__ (unsigned n) { it += n; } - void __prev__ () { --it; } - void __rewind__ (unsigned n) { it -= n; } - - void operator = (unsigned n) - { - assert (n == 0); - is_null = true; - } - explicit operator bool () { return !is_null; } - - void operator = (const machine_index_t& o) - { - is_null = o.is_null; - unsigned index = (*it).first; - unsigned n = (*o.it).first; - if (index < n) it += n - index; else if (index > n) it -= index - n; - } - bool operator == (const machine_index_t& o) const - { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; } - bool operator != (const machine_index_t& o) const { return !(*this == o); } - - private: - Iter it; - bool is_null = false; -}; -struct -{ - template <typename Iter, - hb_requires (hb_is_iterable (Iter))> - machine_index_t<hb_iter_type<Iter>> - operator () (Iter&& it) const - { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); } -} -HB_FUNCOBJ (machine_index); - - - -static bool -not_ccs_default_ignorable (const hb_glyph_info_t &i) -{ return i.use_category() != USE(CGJ); } - -static inline void -find_syllables_use (hb_buffer_t *buffer) -{ - hb_glyph_info_t *info = buffer->info; - auto p = - + hb_iter (info, buffer->len) - | hb_enumerate - | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); }, - hb_second) - | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) - { - if (p.second.use_category() == USE(ZWNJ)) - for (unsigned i = p.first + 1; i < buffer->len; ++i) - if (not_ccs_default_ignorable (info[i])) - return !_hb_glyph_info_is_unicode_mark (&info[i]); - return true; - }) - | hb_enumerate - | machine_index - ; - auto pe = p + p.len (); - auto eof = +pe; - auto ts = +p; - auto te = +p; - unsigned int act HB_UNUSED; - int cs; - -#line 702 "hb-ot-shape-complex-use-machine.hh" - { - cs = use_syllable_machine_start; - ts = 0; - te = 0; - act = 0; - } - -#line 281 "hb-ot-shape-complex-use-machine.rl" - - - unsigned int syllable_serial = 1; - -#line 715 "hb-ot-shape-complex-use-machine.hh" - { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _use_syllable_machine_from_state_actions[cs] ) { - case 2: -#line 1 "NONE" - {ts = p;} - break; -#line 729 "hb-ot-shape-complex-use-machine.hh" - } - - _keys = _use_syllable_machine_trans_keys + (cs<<1); - _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs]; - - _slen = _use_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) && - ( (*p).second.second.use_category()) <= _keys[1] ? - ( (*p).second.second.use_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _use_syllable_machine_trans_targs[_trans]; - - if ( _use_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 9: -#line 171 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (use_standard_cluster); }} - break; - case 6: -#line 174 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (use_symbol_cluster); }} - break; - case 4: -#line 176 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (use_broken_cluster); }} - break; - case 3: -#line 177 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (use_non_cluster); }} - break; - case 11: -#line 170 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} - break; - case 7: -#line 171 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (use_standard_cluster); }} - break; - case 14: -#line 172 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} - break; - case 13: -#line 173 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (use_numeral_cluster); }} - break; - case 5: -#line 174 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (use_symbol_cluster); }} - break; - case 17: -#line 175 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} - break; - case 15: -#line 176 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (use_broken_cluster); }} - break; - case 16: -#line 177 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (use_non_cluster); }} - break; - case 12: -#line 1 "NONE" - { switch( act ) { - case 1: - {{p = ((te))-1;} found_syllable (use_virama_terminated_cluster); } - break; - case 2: - {{p = ((te))-1;} found_syllable (use_sakot_terminated_cluster); } - break; - } - } - break; - case 8: -#line 1 "NONE" - {te = p+1;} -#line 169 "hb-ot-shape-complex-use-machine.rl" - {act = 1;} - break; - case 10: -#line 1 "NONE" - {te = p+1;} -#line 170 "hb-ot-shape-complex-use-machine.rl" - {act = 2;} - break; -#line 819 "hb-ot-shape-complex-use-machine.hh" - } - -_again: - switch ( _use_syllable_machine_to_state_actions[cs] ) { - case 1: -#line 1 "NONE" - {ts = 0;} - break; -#line 828 "hb-ot-shape-complex-use-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _use_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _use_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 286 "hb-ot-shape-complex-use-machine.rl" - -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc index aa5a8eeaa3d..7db0b25b731 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc @@ -29,7 +29,7 @@ #ifndef HB_NO_OT_SHAPE #include "hb-ot-shape-normalize.hh" -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" #include "hb-ot-shape.hh" @@ -69,7 +69,7 @@ * - When a font does not support a character but supports its canonical * decomposition, well, use the decomposition. * - * - The complex shapers can customize the compose and decompose functions to + * - The shapers can customize the compose and decompose functions to * offload some of their requirements to the normalizer. For example, the * Indic shaper may want to disallow recomposing of two matras. */ @@ -143,8 +143,7 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint return 1; } - unsigned int ret; - if ((ret = decompose (c, shortest, a))) { + if (unsigned ret = decompose (c, shortest, a)) { if (b) { output_char (buffer, b, b_glyph); return ret + 1; @@ -223,7 +222,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit HB_UNUSED) { - /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */ + /* Currently if there's a variation-selector we give-up on normalization, it's just too hard. */ hb_buffer_t * const buffer = c->buffer; hb_font_t * const font = c->font; for (; buffer->idx < end - 1 && buffer->successful;) { @@ -395,7 +394,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, break; /* We are going to do a O(n^2). Only do this if the sequence is short. */ - if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) { + if (end - i > HB_OT_SHAPE_MAX_COMBINING_MARKS) { i = end; continue; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index 99aadab3f03..0806abb7dd3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc @@ -37,7 +37,7 @@ #include "hb-shaper-impl.hh" #include "hb-ot-shape.hh" -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" #include "hb-ot-shape-fallback.hh" #include "hb-ot-shape-normalize.hh" @@ -86,14 +86,14 @@ 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_shape_complex_categorize (this); + shaper = hb_ot_shaper_categorize (this); script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; script_fallback_mark_positioning = shaper->fallback_position; /* https://github.com/harfbuzz/harfbuzz/issues/1528 */ - if (apply_morx && shaper != &_hb_ot_complex_shaper_default) - shaper = &_hb_ot_complex_shaper_dumber; + if (apply_morx && shaper != &_hb_ot_shaper_default) + shaper = &_hb_ot_shaper_dumber; } void @@ -927,7 +927,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) } static inline void -hb_ot_substitute_complex (const hb_ot_shape_context_t *c) +hb_ot_substitute_plan (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; @@ -946,7 +946,7 @@ hb_ot_substitute_pre (const hb_ot_shape_context_t *c) _hb_buffer_allocate_gsubgpos_vars (c->buffer); - hb_ot_substitute_complex (c); + hb_ot_substitute_plan (c); #ifndef HB_NO_AAT_SHAPE if (c->plan->apply_morx && c->plan->apply_gpos) @@ -1039,7 +1039,7 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) } static inline void -hb_ot_position_complex (const hb_ot_shape_context_t *c) +hb_ot_position_plan (const hb_ot_shape_context_t *c) { unsigned int count = c->buffer->len; hb_glyph_info_t *info = c->buffer->info; @@ -1124,7 +1124,7 @@ hb_ot_position (const hb_ot_shape_context_t *c) hb_ot_position_default (c); - hb_ot_position_complex (c); + hb_ot_position_plan (c); if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) hb_buffer_reverse (c->buffer); @@ -1159,8 +1159,6 @@ hb_propagate_flags (hb_buffer_t *buffer) static void hb_ot_shape_internal (hb_ot_shape_context_t *c) { - c->buffer->enter (); - /* Save the original direction, we use it later. */ c->target_direction = c->buffer->props.direction; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh index e8c81015c79..17fa58b3377 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh @@ -61,7 +61,7 @@ struct hb_shape_plan_key_t; struct hb_ot_shape_plan_t { hb_segment_properties_t props; - const struct hb_ot_complex_shaper_t *shaper; + const struct hb_ot_shaper_t *shaper; hb_ot_map_t map; hb_aat_map_t aat_map; const void *data; @@ -158,7 +158,7 @@ struct hb_ot_shape_planner_t #endif bool script_zero_marks : 1; bool script_fallback_mark_positioning : 1; - const struct hb_ot_complex_shaper_t *shaper; + const struct hb_ot_shaper_t *shaper; HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, const hb_segment_properties_t *props); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh index 78f46c1cac1..b9f92f72d67 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh @@ -24,8 +24,8 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH -#define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH +#ifndef HB_OT_SHAPER_ARABIC_FALLBACK_HH +#define HB_OT_SHAPER_ARABIC_FALLBACK_HH #include "hb.hh" @@ -34,7 +34,11 @@ /* Features ordered the same as the entries in shaping_table rows, - * followed by rlig. Don't change. */ + * followed by rlig. Don't change. + * + * We currently support one subtable per lookup, and one lookup + * per feature. But we allow duplicate features, so we use that! + */ static const hb_tag_t arabic_fallback_features[] = { HB_TAG('i','n','i','t'), @@ -42,6 +46,8 @@ static const hb_tag_t arabic_fallback_features[] = HB_TAG('f','i','n','a'), HB_TAG('i','s','o','l'), HB_TAG('r','l','i','g'), + HB_TAG('r','l','i','g'), + HB_TAG('r','l','i','g'), }; static OT::SubstLookup * @@ -95,20 +101,25 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS return ret && !c.in_error () ? c.copy<OT::SubstLookup> () : nullptr; } +template <typename T> static OT::SubstLookup * arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font) + hb_font_t *font, + const T &ligature_table, + unsigned lookup_flags) { OT::HBGlyphID16 first_glyphs[ARRAY_LENGTH_CONST (ligature_table)]; unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)]; unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)]; unsigned int num_first_glyphs = 0; - /* We know that all our ligatures are 2-component */ + /* We know that all our ligatures have the same number of components. */ OT::HBGlyphID16 ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)]; unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)]; - OT::HBGlyphID16 component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */]; + OT::HBGlyphID16 component_list[ARRAY_LENGTH_CONST (ligature_list) * + ARRAY_LENGTH_CONST (ligature_table[0].ligatures[0].components)]; unsigned int num_ligatures = 0; + unsigned int num_components = 0; /* Populate arrays */ @@ -133,21 +144,32 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN { unsigned int first_glyph_idx = first_glyphs_indirection[i]; - for (unsigned int second_glyph_idx = 0; second_glyph_idx < ARRAY_LENGTH (ligature_table[0].ligatures); second_glyph_idx++) + for (unsigned int ligature_idx = 0; ligature_idx < ARRAY_LENGTH (ligature_table[0].ligatures); ligature_idx++) { - hb_codepoint_t second_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].second; - hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].ligature; - hb_codepoint_t second_glyph, ligature_glyph; - if (!second_u || - !hb_font_get_glyph (font, second_u, 0, &second_glyph) || - !hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph)) + hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[ligature_idx].ligature; + hb_codepoint_t ligature_glyph; + if (!hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph)) continue; - ligature_per_first_glyph_count_list[i]++; + const auto &components = ligature_table[first_glyph_idx].ligatures[ligature_idx].components; + unsigned component_count = ARRAY_LENGTH_CONST (components); + + for (unsigned i = 0; i < component_count; i++) + { + hb_codepoint_t component_u = ligature_table[first_glyph_idx].ligatures[ligature_idx].components[i]; + hb_codepoint_t component_glyph; + if (!component_u || + !hb_font_get_glyph (font, component_u, 0, &component_glyph)) + continue; + component_list[num_components++] = component_glyph; + } + + component_count_list[num_ligatures] = 1 + component_count; ligature_list[num_ligatures] = ligature_glyph; - component_count_list[num_ligatures] = 2; - component_list[num_ligatures] = second_glyph; + + ligature_per_first_glyph_count_list[i]++; + num_ligatures++; } } @@ -161,14 +183,13 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN hb_serialize_context_t c (buf, sizeof (buf)); OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> (); bool ret = lookup->serialize_ligature (&c, - OT::LookupFlag::IgnoreMarks, + lookup_flags, hb_sorted_array (first_glyphs, num_first_glyphs), hb_array (ligature_per_first_glyph_count_list, num_first_glyphs), hb_array (ligature_list, num_ligatures), hb_array (component_count_list, num_ligatures), - hb_array (component_list, num_ligatures)); + hb_array (component_list, num_components)); c.end_serialize (); - /* TODO sanitize the results? */ return ret && !c.in_error () ? c.copy<OT::SubstLookup> () : nullptr; } @@ -181,10 +202,18 @@ arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan, if (feature_index < 4) return arabic_fallback_synthesize_lookup_single (plan, font, feature_index); else - return arabic_fallback_synthesize_lookup_ligature (plan, font); + { + switch (feature_index) { + case 4: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_3_table, OT::LookupFlag::IgnoreMarks); + case 5: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_table, OT::LookupFlag::IgnoreMarks); + case 6: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_mark_table, 0); + } + } + assert (false); + return nullptr; } -#define ARABIC_FALLBACK_MAX_LOOKUPS 5 +#define ARABIC_FALLBACK_MAX_LOOKUPS ARRAY_LENGTH_CONST (arabic_fallback_features) struct arabic_fallback_plan_t { @@ -201,7 +230,7 @@ struct arabic_fallback_plan_t #endif #ifdef HB_WITH_WIN1256 -#include "hb-ot-shape-complex-arabic-win1256.hh" +#include "hb-ot-shaper-arabic-win1256.hh" #endif struct ManifestLookup @@ -230,9 +259,8 @@ arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUS return false; const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest); - static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) == + static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) <= ARABIC_FALLBACK_MAX_LOOKUPS * sizeof (ManifestLookup), ""); - /* TODO sanitize the table? */ unsigned j = 0; unsigned int count = manifest.len; @@ -264,7 +292,7 @@ arabic_fallback_plan_init_unicode (arabic_fallback_plan_t *fallback_plan, const hb_ot_shape_plan_t *plan, hb_font_t *font) { - static_assert ((ARRAY_LENGTH_CONST(arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS), ""); + static_assert ((ARRAY_LENGTH_CONST (arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS), ""); unsigned int j = 0; for (unsigned int i = 0; i < ARRAY_LENGTH(arabic_fallback_features) ; i++) { @@ -345,4 +373,4 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan, } -#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */ +#endif /* HB_OT_SHAPER_ARABIC_FALLBACK_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-joining-list.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-joining-list.hh index e6339ee72bc..a5ce3a6c93b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-joining-list.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-joining-list.hh @@ -12,8 +12,8 @@ * # Date: 2021-07-10, 00:35:31 GMT */ -#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH -#define HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH +#ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH +#define HB_OT_SHAPER_ARABIC_JOINING_LIST_HH static bool has_arabic_joining (hb_script_t script) @@ -42,6 +42,6 @@ has_arabic_joining (hb_script_t script) } -#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH */ +#endif /* HB_OT_SHAPER_ARABIC_JOINING_LIST_HH */ /* == End of generated function == */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-pua.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-pua.hh new file mode 100644 index 00000000000..ba86772f849 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-pua.hh @@ -0,0 +1,118 @@ +/* == Start of generated table == */ +/* + * The following table is generated by running: + * + * ./gen-arabic-pua.py + * + */ + +#ifndef HB_OT_SHAPER_ARABIC_PUA_HH +#define HB_OT_SHAPER_ARABIC_PUA_HH + +static const uint8_t +_hb_arabic_u8[464] = +{ + 84, 86, 85, 85, 85, 85, 85,213, 16, 34, 34, 34, 34, 34, 35, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 36, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 82, 16, 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, + 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 0, 0, 0, 22, 0, 23, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 16, 34, 34, 34, 35, 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, 66, 16, 50, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68,101, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 71, 68, 68, 68, 68, 68, 68, 68,152,186, 76, 77, 68,254, 16, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 5, 6, + 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 23, 23, 29, 30, 31, 32, 33, 0, 0, 0, 0, + 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 36, 37, 38, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 40, + 41, 42, 0, 43, 44, 0, 0, 45, 46, 0, 47, 48, 49, 0, 0, 0, + 0, 50, 0, 0, 51, 52, 0, 53, 54, 55, 56, 57, 58, 0, 0, 0, + 0, 0, 59, 60, 61, 62, 63, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 66, + 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, +}; +static const uint16_t +_hb_arabic_u16[720] = +{ + 0, 0, 0, 0, 0, 0, 0, 0,61728,61729,61730, 0, 0,61733, 0, 0, + 61736,61737,61738,61739,61790,61741,61742,61743,61872,61873,61874,61875,61876,61877,61878,61879, + 61880,61881,61754,61755, 0,61757, 0,61759, 0, 0, 0,61787,61788,61789, 0, 0, + 0, 0, 0,61731, 0, 0, 0, 0, 0, 0, 0,61732, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,61734, 0, 0, 0, 0, 0, 0, 0,61735, + 0, 0, 0, 0,61740, 0, 0, 0, 0, 0, 0,61755, 0, 0, 0,61759, + 0,61869,61765,61763,61883,61767,61882,61761,61770,61865,61772,61774,61777,61780,61783,61784, + 61785,61786,61792,61794,61796,61798,61800,61801,61802,61806,61810,61696,61696,61696,61696,61696, + 61791,61813,61816,61818,61820,61822,61921,61860,61861,61868,61864,61895,61896,61899,61892,61893, + 61898,61897,61894,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696, 0, + 61744,61745,61746,61747,61748,61749,61750,61751,61752,61753, 0,61790,61790, 0, 0, 0, + 0, 0, 0, 0,61708,61709,61710,61711,61756,61758, 0, 0, 0, 0, 0, 0, + 0,61765,61766,61763,61764,61883,61883,61767,61768,61882,61871,61870,61870,61761,61762,61770, + 61770,61769,61769,61865,61866,61772,61772,61771,61771,61774,61774,61773,61773,61777,61776,61775, + 61775,61780,61779,61778,61778,61783,61782,61781,61781,61784,61784,61785,61785,61786,61786,61792, + 61792,61794,61794,61793,61793,61796,61796,61795,61795,61798,61798,61797,61797,61800,61800,61799, + 61799,61801,61801,61801,61801,61802,61802,61802,61802,61806,61805,61803,61804,61810,61809,61807, + 61808,61813,61813,61811,61812,61816,61816,61814,61815,61818,61818,61817,61817,61820,61820,61819, + 61819,61822,61822,61821,61821,61921,61921,61823,61823,61860,61859,61857,61858,61861,61861,61868, + 61867,61864,61863,61862,61862,61888,61889,61886,61887,61890,61891,61885,61884, 0, 0, 0, + 0, 0, 0, 0,61984,61985,61986, 0, 0,61989, 0, 0,61992,61993,61994,61995, + 62046,61997,61998,61999, 0, 0,62010,62011, 0,62013, 0,62015, 0, 0, 0,62043, + 0,62045, 0, 0, 0, 0, 0,61987, 0, 0, 0,61988, 0, 0, 0,61990, + 0, 0, 0,61991,61996, 0, 0, 0, 0, 0, 0,62011, 0, 0, 0,62015, + 0,62165,62021,62019,62170,62023,62169,62017,62028,62161,62032,62036,62040,62048,62052,62053, + 62055,62057,62059,62064,62068,62072,62078,62114,62115,62122,62126,61952,61952,61952,61952,61952, + 62047,62130,62134,62138,62142,62146,62150,62154,62155,62164,62160,62183,62184,62187,62180,62181, + 62186,62185,62182,61952,61952,61952,61952, 0,62000,62001,62002,62003,62004,62005,62006,62007, + 62008,62009, 0,62046,62046, 0, 0, 0,61964,61965,61966,61967,62012,62014, 0, 0, + 61954, 0,61981, 0, 0, 0,61955, 0,61982, 0,61956, 0, 0, 0,62111, 0, + 0, 0, 0,61970,61971,61972,61957, 0,61980, 0, 0, 0, 0, 0,61958, 0, + 61983, 0, 0, 0, 0, 0,62191, 0,62188,62189,62192, 0, 0, 0,61973, 0, + 0,62098, 0, 0,61974, 0, 0,62099, 0, 0,62101, 0, 0,61975, 0, 0, + 62100, 0, 0, 0,62080,62081,62082,62102, 0,62083,62084,62085,62103, 0, 0, 0, + 62106, 0,62107, 0,62108, 0, 0, 0,61976, 0, 0, 0, 0,62086,62087,62088, + 62109,61978,62089,62090,62091,62110,62093,62094, 0,62104, 0, 0, 0, 0,62095,62096, + 62097,62105, 0, 0,61977, 0, 0, 0, 0, 0,62075,62077,61968, 0, 0, 0, + 0,62021,62022,62019,62020,62170,62171,62023,62024,62169,62168,62166,62167,62017,62018,62028, + 62027,62025,62026,62161,62162,62032,62031,62029,62030,62036,62035,62033,62034,62040,62039,62037, + 62038,62048,62044,62041,62042,62052,62051,62049,62050,62053,62054,62055,62056,62057,62058,62059, + 62060,62064,62063,62061,62062,62068,62067,62065,62066,62072,62071,62069,62070,62078,62076,62073, + 62074,62114,62113,62079,62193,62118,62117,62115,62116,62122,62121,62119,62120,62126,62125,62123, + 62124,62130,62129,62127,62128,62134,62133,62131,62132,62138,62137,62135,62136,62142,62141,62139, + 62140,62146,62145,62143,62144,62150,62149,62147,62148,62154,62153,62151,62152,62155,62156,62164, + 62163,62160,62159,62157,62158,62176,62177,62174,62175,62178,62179,62172,62173, 0, 0, 0, +}; + +static inline unsigned +_hb_arabic_b2 (const uint8_t* a, unsigned i) +{ + return (a[i>>2]>>((i&3u)<<1))&3u; +} +static inline unsigned +_hb_arabic_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1u)<<2))&15u; +} +static inline uint_fast16_t +_hb_arabic_pua_simp_map (unsigned u) +{ + return u<65277u?_hb_arabic_u16[((_hb_arabic_u8[40+(((_hb_arabic_b4(8+_hb_arabic_u8,((_hb_arabic_b2(_hb_arabic_u8,u>>3>>4>>4))<<4)+((u>>3>>4)&15u)))<<4)+((u>>3)&15u))])<<3)+((u)&7u)]:0; +} +static inline uint_fast16_t +_hb_arabic_pua_trad_map (unsigned u) +{ + return u<65277u?_hb_arabic_u16[320+(((_hb_arabic_u8[208+(((_hb_arabic_b4(168+_hb_arabic_u8,((_hb_arabic_b4(136+_hb_arabic_u8,u>>2>>4>>4))<<4)+((u>>2>>4)&15u)))<<4)+((u>>2)&15u))])<<2)+((u)&3u))]:0; +} + +#endif /* HB_OT_SHAPER_ARABIC_PUA_HH */ + +/* == End of generated table == */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-table.hh index c158964f2cd..fd3d8645d1d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-table.hh @@ -13,8 +13,8 @@ * UnicodeData.txt does not have a header. */ -#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH -#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH +#ifndef HB_OT_SHAPER_ARABIC_TABLE_HH +#define HB_OT_SHAPER_ARABIC_TABLE_HH #define A JOINING_GROUP_ALAPH @@ -416,26 +416,141 @@ static const uint16_t shaping_table[][4] = static const struct ligature_set_t { uint16_t first; struct ligature_pairs_t { - uint16_t second; + uint16_t components[1]; uint16_t ligature; - } ligatures[4]; + } ligatures[14]; } ligature_table[] = { + { 0xFE91u, { + { {0xFEE2u}, 0xFC08u }, /* ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM */ + { {0xFEE4u}, 0xFC9Fu }, /* ARABIC LIGATURE BEH WITH MEEM INITIAL FORM */ + { {0xFEA0u}, 0xFC9Cu }, /* ARABIC LIGATURE BEH WITH JEEM INITIAL FORM */ + { {0xFEA4u}, 0xFC9Du }, /* ARABIC LIGATURE BEH WITH HAH INITIAL FORM */ + { {0xFEA8u}, 0xFC9Eu }, /* ARABIC LIGATURE BEH WITH KHAH INITIAL FORM */ + }}, + { 0xFE92u, { + { {0xFEAEu}, 0xFC6Au }, /* ARABIC LIGATURE BEH WITH REH FINAL FORM */ + { {0xFEE6u}, 0xFC6Du }, /* ARABIC LIGATURE BEH WITH NOON FINAL FORM */ + { {0xFEF2u}, 0xFC6Fu }, /* ARABIC LIGATURE BEH WITH YEH FINAL FORM */ + }}, + { 0xFE97u, { + { {0xFEE2u}, 0xFC0Eu }, /* ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM */ + { {0xFEE4u}, 0xFCA4u }, /* ARABIC LIGATURE TEH WITH MEEM INITIAL FORM */ + { {0xFEA0u}, 0xFCA1u }, /* ARABIC LIGATURE TEH WITH JEEM INITIAL FORM */ + { {0xFEA4u}, 0xFCA2u }, /* ARABIC LIGATURE TEH WITH HAH INITIAL FORM */ + { {0xFEA8u}, 0xFCA3u }, /* ARABIC LIGATURE TEH WITH KHAH INITIAL FORM */ + }}, + { 0xFE98u, { + { {0xFEAEu}, 0xFC70u }, /* ARABIC LIGATURE TEH WITH REH FINAL FORM */ + { {0xFEE6u}, 0xFC73u }, /* ARABIC LIGATURE TEH WITH NOON FINAL FORM */ + { {0xFEF2u}, 0xFC75u }, /* ARABIC LIGATURE TEH WITH YEH FINAL FORM */ + }}, + { 0xFE9Bu, { + { {0xFEE2u}, 0xFC12u }, /* ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM */ + }}, + { 0xFE9Fu, { + { {0xFEE4u}, 0xFCA8u }, /* ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM */ + }}, + { 0xFEA3u, { + { {0xFEE4u}, 0xFCAAu }, /* ARABIC LIGATURE HAH WITH MEEM INITIAL FORM */ + }}, + { 0xFEA7u, { + { {0xFEE4u}, 0xFCACu }, /* ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM */ + }}, + { 0xFEB3u, { + { {0xFEE4u}, 0xFCB0u }, /* ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM */ + }}, + { 0xFEB7u, { + { {0xFEE4u}, 0xFD30u }, /* ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM */ + }}, + { 0xFED3u, { + { {0xFEF2u}, 0xFC32u }, /* ARABIC LIGATURE FEH WITH YEH ISOLATED FORM */ + }}, { 0xFEDFu, { - { 0xFE82u, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */ - { 0xFE84u, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */ - { 0xFE88u, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */ - { 0xFE8Eu, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */ + { {0xFE9Eu}, 0xFC3Fu }, /* ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM */ + { {0xFEA0u}, 0xFCC9u }, /* ARABIC LIGATURE LAM WITH JEEM INITIAL FORM */ + { {0xFEA2u}, 0xFC40u }, /* ARABIC LIGATURE LAM WITH HAH ISOLATED FORM */ + { {0xFEA4u}, 0xFCCAu }, /* ARABIC LIGATURE LAM WITH HAH INITIAL FORM */ + { {0xFEA6u}, 0xFC41u }, /* ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM */ + { {0xFEA8u}, 0xFCCBu }, /* ARABIC LIGATURE LAM WITH KHAH INITIAL FORM */ + { {0xFEE2u}, 0xFC42u }, /* ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM */ + { {0xFEE4u}, 0xFCCCu }, /* ARABIC LIGATURE LAM WITH MEEM INITIAL FORM */ + { {0xFEF2u}, 0xFC44u }, /* ARABIC LIGATURE LAM WITH YEH ISOLATED FORM */ + { {0xFEECu}, 0xFCCDu }, /* ARABIC LIGATURE LAM WITH HEH INITIAL FORM */ + { {0xFE82u}, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */ + { {0xFE84u}, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */ + { {0xFE88u}, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */ + { {0xFE8Eu}, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */ }}, { 0xFEE0u, { - { 0xFE82u, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */ - { 0xFE84u, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */ - { 0xFE88u, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */ - { 0xFE8Eu, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */ + { {0xFEF0u}, 0xFC86u }, /* ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM */ + { {0xFE82u}, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */ + { {0xFE84u}, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */ + { {0xFE88u}, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */ + { {0xFE8Eu}, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */ + }}, + { 0xFEE3u, { + { {0xFEA0u}, 0xFCCEu }, /* ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM */ + { {0xFEA4u}, 0xFCCFu }, /* ARABIC LIGATURE MEEM WITH HAH INITIAL FORM */ + { {0xFEA8u}, 0xFCD0u }, /* ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM */ + { {0xFEE4u}, 0xFCD1u }, /* ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM */ + }}, + { 0xFEE7u, { + { {0xFEE2u}, 0xFC4Eu }, /* ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM */ + { {0xFEE4u}, 0xFCD5u }, /* ARABIC LIGATURE NOON WITH MEEM INITIAL FORM */ + { {0xFEA0u}, 0xFCD2u }, /* ARABIC LIGATURE NOON WITH JEEM INITIAL FORM */ + { {0xFEA4u}, 0xFCD3u }, /* ARABIC LIGATURE NOON WITH HAH INITIAL FORM */ + }}, + { 0xFEE8u, { + { {0xFEF2u}, 0xFC8Fu }, /* ARABIC LIGATURE NOON WITH YEH FINAL FORM */ + }}, + { 0xFEF3u, { + { {0xFEA0u}, 0xFCDAu }, /* ARABIC LIGATURE YEH WITH JEEM INITIAL FORM */ + { {0xFEA4u}, 0xFCDBu }, /* ARABIC LIGATURE YEH WITH HAH INITIAL FORM */ + { {0xFEA8u}, 0xFCDCu }, /* ARABIC LIGATURE YEH WITH KHAH INITIAL FORM */ + { {0xFEE4u}, 0xFCDDu }, /* ARABIC LIGATURE YEH WITH MEEM INITIAL FORM */ + }}, + { 0xFEF4u, { + { {0xFEAEu}, 0xFC91u }, /* ARABIC LIGATURE YEH WITH REH FINAL FORM */ + { {0xFEE6u}, 0xFC94u }, /* ARABIC LIGATURE YEH WITH NOON FINAL FORM */ + }}, +}; + + +static const struct ligature_mark_set_t { + uint16_t first; + struct ligature_pairs_t { + uint16_t components[1]; + uint16_t ligature; + } ligatures[5]; +} ligature_mark_table[] = +{ + { 0x0651u, { + { {0x064Cu}, 0xFC5Eu }, /* ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM */ + { {0x064Eu}, 0xFC60u }, /* ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM */ + { {0x064Fu}, 0xFC61u }, /* ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM */ + { {0x0650u}, 0xFC62u }, /* ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM */ + { {0x064Bu}, 0xF2EEu }, /* PUA ARABIC LIGATURE SHADDA WITH FATHATAN ISOLATED FORM */ + }}, +}; + + +static const struct ligature_3_set_t { + uint16_t first; + struct ligature_triplets_t { + uint16_t components[2]; + uint16_t ligature; + } ligatures[3]; +} ligature_3_table[] = +{ + { 0xFEDFu, { + { {0xFEE4u, 0xFEA4u}, 0xFD88u}, /* ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM */ + { {0xFEE0u, 0xFEEAu}, 0xF201u}, /* PUA ARABIC LIGATURE LELLAH ISOLATED FORM */ + { {0xFEE4u, 0xFEA0u}, 0xF211u}, /* PUA ARABIC LIGATURE LAM WITH MEEM WITH JEEM INITIAL FORM */ }}, }; -#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */ +#endif /* HB_OT_SHAPER_ARABIC_TABLE_HH */ /* == End of generated table == */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-win1256.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-win1256.hh index 429974d05b4..b8d481c8134 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-win1256.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-win1256.hh @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH +#ifndef HB_OT_SHAPER_ARABIC_WIN1256_HH /* @@ -342,8 +342,8 @@ OT_TABLE_END #include "hb.hh" /* Make check-includes.sh happy. */ #endif #ifdef OT_MEASURE -#include "hb-ot-shape-complex-arabic-win1256.hh" +#include "hb-ot-shaper-arabic-win1256.hh" #endif -#define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH -#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */ +#define HB_OT_SHAPER_ARABIC_WIN1256_HH +#endif /* HB_OT_SHAPER_ARABIC_WIN1256_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc index 224f8b842eb..e869d78509a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc @@ -28,14 +28,14 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-arabic.hh" +#include "hb-ot-shaper-arabic.hh" #include "hb-ot-shape.hh" /* buffer var allocations */ -#define arabic_shaping_action() complex_var_u8_auxiliary() /* arabic shaping action */ +#define arabic_shaping_action() ot_shaper_var_u8_auxiliary() /* arabic shaping action */ -#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0 +#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_SHAPER0 /* See: * https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */ @@ -81,7 +81,7 @@ enum hb_arabic_joining_type_t { JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */ }; -#include "hb-ot-shape-complex-arabic-table.hh" +#include "hb-ot-shaper-arabic-table.hh" static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat) { @@ -172,6 +172,14 @@ record_stch (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer); static void +deallocate_buffer_var (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); +} + +static void collect_features_arabic (hb_ot_shape_planner_t *plan) { hb_ot_map_builder_t *map = &plan->map; @@ -213,6 +221,7 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) map->add_feature (arabic_features[i], has_fallback ? F_HAS_FALLBACK : F_NONE); map->add_gsub_pause (nullptr); } + map->add_gsub_pause (deallocate_buffer_var); /* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script * however, it says a ZWJ should also mean "don't ligate". So we run @@ -240,7 +249,7 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) map->enable_feature (HB_TAG('m','s','e','t')); } -#include "hb-ot-shape-complex-arabic-fallback.hh" +#include "hb-ot-shaper-arabic-fallback.hh" struct arabic_shape_plan_t { @@ -405,7 +414,7 @@ arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { -#ifdef HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK +#ifdef HB_NO_OT_SHAPER_ARABIC_FALLBACK return; #endif @@ -619,8 +628,6 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, hb_font_t *font) { apply_stch (plan, buffer, font); - - HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); } /* https://www.unicode.org/reports/tr53/ */ @@ -689,7 +696,7 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan HB_UNUSED, /* Shift it! */ DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d", cc, i, j); - hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS]; + hb_glyph_info_t temp[HB_OT_SHAPE_MAX_COMBINING_MARKS]; assert (j - i <= ARRAY_LENGTH (temp)); buffer->merge_clusters (start, j); memmove (temp, &info[i], (j - i) * sizeof (hb_glyph_info_t)); @@ -720,7 +727,7 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan HB_UNUSED, } } -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = +const hb_ot_shaper_t _hb_ot_shaper_arabic = { collect_features_arabic, nullptr, /* override_features */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.hh index 5bf6ff6338a..a025b1a399c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.hh @@ -26,12 +26,12 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_HH -#define HB_OT_SHAPE_COMPLEX_ARABIC_HH +#ifndef HB_OT_SHAPER_ARABIC_HH +#define HB_OT_SHAPER_ARABIC_HH #include "hb.hh" -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" struct arabic_shape_plan_t; @@ -47,4 +47,4 @@ setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, hb_buffer_t *buffer, hb_script_t script); -#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_HH */ +#endif /* HB_OT_SHAPER_ARABIC_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-default.cc index a755aea098b..25716aa81f5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-default.cc @@ -28,10 +28,10 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = +const hb_ot_shaper_t _hb_ot_shaper_default = { nullptr, /* collect_features */ nullptr, /* override_features */ @@ -51,7 +51,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = /* Same as default but no mark advance zeroing / fallback positioning. * Dumbest shaper ever, basically. */ -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_dumber = +const hb_ot_shaper_t _hb_ot_shaper_dumber = { nullptr, /* collect_features */ nullptr, /* override_features */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-hangul.cc index 3bc9e9b961c..aa507c75caa 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-hangul.cc @@ -28,7 +28,7 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" /* Hangul shaper */ @@ -119,7 +119,7 @@ data_destroy_hangul (void *data) #define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302Eu, 0x302Fu)) /* buffer var allocations */ -#define hangul_shaping_feature() complex_var_u8_auxiliary() /* hangul jamo shaping feature */ +#define hangul_shaping_feature() ot_shaper_var_u8_auxiliary() /* hangul jamo shaping feature */ static bool is_zero_width_char (hb_font_t *font, @@ -414,7 +414,7 @@ setup_masks_hangul (const hb_ot_shape_plan_t *plan, } -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul = +const hb_ot_shaper_t _hb_ot_shaper_hangul = { collect_features_hangul, override_features_hangul, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-hebrew.cc index 334d3ded82f..f3b6cde1796 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-hebrew.cc @@ -28,7 +28,7 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" static bool @@ -74,7 +74,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, bool found = (bool) c->unicode->compose (a, b, ab); -#ifdef HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK +#ifdef HB_NO_OT_SHAPER_HEBREW_FALLBACK return found; #endif @@ -163,7 +163,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, } -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = +const hb_ot_shaper_t _hb_ot_shaper_hebrew = { nullptr, /* collect_features */ nullptr, /* override_features */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh new file mode 100644 index 00000000000..d52b13f6161 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh @@ -0,0 +1,589 @@ + +#line 1 "hb-ot-shaper-indic-machine.rl" +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPER_INDIC_MACHINE_HH +#define HB_OT_SHAPER_INDIC_MACHINE_HH + +#include "hb.hh" + +#include "hb-ot-layout.hh" +#include "hb-ot-shaper-indic.hh" + +/* buffer var allocations */ +#define indic_category() ot_shaper_var_u8_category() /* indic_category_t */ +#define indic_position() ot_shaper_var_u8_auxiliary() /* indic_position_t */ + +using indic_category_t = unsigned; +using indic_position_t = ot_position_t; + +#define I_Cat(Cat) indic_syllable_machine_ex_##Cat + +enum indic_syllable_type_t { + indic_consonant_syllable, + indic_vowel_syllable, + indic_standalone_cluster, + indic_symbol_cluster, + indic_broken_cluster, + indic_non_indic_cluster, +}; + + +#line 57 "hb-ot-shaper-indic-machine.hh" +#define indic_syllable_machine_ex_A 9u +#define indic_syllable_machine_ex_C 1u +#define indic_syllable_machine_ex_CM 16u +#define indic_syllable_machine_ex_CS 18u +#define indic_syllable_machine_ex_DOTTEDCIRCLE 11u +#define indic_syllable_machine_ex_H 4u +#define indic_syllable_machine_ex_M 7u +#define indic_syllable_machine_ex_N 3u +#define indic_syllable_machine_ex_PLACEHOLDER 10u +#define indic_syllable_machine_ex_RS 12u +#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_Symbol 17u +#define indic_syllable_machine_ex_V 2u +#define indic_syllable_machine_ex_VD 9u +#define indic_syllable_machine_ex_X 0u +#define indic_syllable_machine_ex_ZWJ 6u +#define indic_syllable_machine_ex_ZWNJ 5u + + +#line 79 "hb-ot-shaper-indic-machine.hh" +static const unsigned char _indic_syllable_machine_trans_keys[] = { + 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 8u, 8u, 8u, + 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 12u, 4u, 12u, 8u, 8u, 5u, 7u, + 5u, 8u, 4u, 8u, 4u, 8u, 4u, 12u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, + 4u, 8u, 5u, 8u, 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, 9u, + 4u, 9u, 5u, 9u, 4u, 9u, 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, 9u, 4u, 9u, 5u, 9u, + 4u, 9u, 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 8u, + 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, + 5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u, + 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 12u, 4u, 8u, 3u, 16u, + 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, + 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u, 5u, 9u, + 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 12u, 5u, 9u, + 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, + 1u, 15u, 0 +}; + +static const char _indic_syllable_machine_key_spans[] = { + 1, 5, 3, 4, 5, 9, 5, 1, + 3, 4, 5, 9, 9, 9, 1, 3, + 4, 5, 5, 9, 1, 3, 4, 5, + 5, 4, 1, 18, 14, 14, 13, 15, + 5, 5, 1, 5, 15, 15, 15, 7, + 6, 5, 6, 5, 7, 5, 14, 14, + 14, 14, 13, 15, 14, 14, 13, 15, + 5, 1, 5, 15, 15, 7, 6, 5, + 6, 5, 5, 7, 5, 14, 14, 5, + 14, 14, 13, 15, 14, 15, 5, 1, + 5, 15, 15, 7, 6, 5, 14, 6, + 5, 5, 7, 5, 14, 9, 5, 14, + 14, 13, 15, 14, 15, 5, 1, 5, + 15, 15, 7, 6, 5, 14, 6, 5, + 5, 7, 5, 16, 14, 16, 9, 5, + 1, 5, 15, 7, 5, 5, 1, 5, + 15 +}; + +static const short _indic_syllable_machine_index_offsets[] = { + 0, 2, 8, 12, 17, 23, 33, 39, + 41, 45, 50, 56, 66, 76, 86, 88, + 92, 97, 103, 109, 119, 121, 125, 130, + 136, 142, 147, 149, 168, 183, 198, 212, + 228, 234, 240, 242, 248, 264, 280, 296, + 304, 311, 317, 324, 330, 338, 344, 359, + 374, 389, 404, 418, 434, 449, 464, 478, + 494, 500, 502, 508, 524, 540, 548, 555, + 561, 568, 574, 580, 588, 594, 609, 624, + 630, 645, 660, 674, 690, 705, 721, 727, + 729, 735, 751, 767, 775, 782, 788, 803, + 810, 816, 822, 830, 836, 851, 861, 867, + 882, 897, 911, 927, 942, 958, 964, 966, + 972, 988, 1004, 1012, 1019, 1025, 1040, 1047, + 1053, 1059, 1067, 1073, 1090, 1105, 1122, 1132, + 1138, 1140, 1146, 1162, 1170, 1176, 1182, 1184, + 1190 +}; + +static const unsigned char _indic_syllable_machine_indicies[] = { + 1, 0, 2, 3, 3, 4, 1, 0, + 3, 3, 4, 0, 3, 3, 4, 1, + 0, 5, 3, 3, 4, 1, 0, 2, + 3, 3, 4, 1, 0, 0, 0, 6, + 0, 8, 9, 9, 10, 11, 7, 11, + 7, 9, 9, 10, 7, 9, 9, 10, + 11, 7, 12, 9, 9, 10, 11, 7, + 8, 9, 9, 10, 11, 7, 7, 7, + 13, 7, 8, 9, 9, 10, 11, 7, + 7, 7, 14, 7, 16, 17, 17, 18, + 19, 15, 15, 15, 20, 15, 19, 15, + 17, 17, 18, 21, 17, 17, 18, 19, + 15, 16, 17, 17, 18, 19, 15, 22, + 17, 17, 18, 19, 15, 24, 25, 25, + 26, 27, 23, 23, 23, 28, 23, 27, + 23, 25, 25, 26, 23, 25, 25, 26, + 27, 23, 24, 25, 25, 26, 27, 23, + 29, 25, 25, 26, 27, 23, 17, 17, + 18, 1, 0, 31, 30, 33, 34, 35, + 36, 37, 38, 18, 19, 39, 40, 40, + 20, 32, 41, 42, 43, 44, 45, 32, + 47, 48, 49, 50, 4, 1, 51, 46, + 46, 6, 46, 46, 46, 52, 46, 53, + 48, 54, 54, 4, 1, 51, 46, 46, + 46, 46, 46, 46, 52, 46, 48, 54, + 54, 4, 1, 51, 46, 46, 46, 46, + 46, 46, 52, 46, 33, 46, 46, 46, + 55, 56, 46, 1, 51, 46, 46, 46, + 46, 46, 33, 46, 57, 57, 46, 1, + 51, 46, 51, 46, 46, 58, 51, 46, + 51, 46, 51, 46, 46, 46, 51, 46, + 33, 46, 59, 46, 57, 57, 46, 1, + 51, 46, 46, 46, 46, 46, 33, 46, + 33, 46, 46, 46, 57, 57, 46, 1, + 51, 46, 46, 46, 46, 46, 33, 46, + 33, 46, 46, 46, 57, 56, 46, 1, + 51, 46, 46, 46, 46, 46, 33, 46, + 60, 61, 62, 62, 4, 1, 51, 46, + 61, 62, 62, 4, 1, 51, 46, 62, + 62, 4, 1, 51, 46, 63, 64, 64, + 4, 1, 51, 46, 55, 65, 46, 1, + 51, 46, 55, 46, 57, 57, 46, 1, + 51, 46, 57, 65, 46, 1, 51, 46, + 47, 48, 54, 54, 4, 1, 51, 46, + 46, 46, 46, 46, 46, 52, 46, 47, + 48, 49, 54, 4, 1, 51, 46, 46, + 6, 46, 46, 46, 52, 46, 67, 68, + 69, 70, 10, 11, 71, 66, 66, 14, + 66, 66, 66, 72, 66, 73, 68, 74, + 70, 10, 11, 71, 66, 66, 66, 66, + 66, 66, 72, 66, 68, 74, 70, 10, + 11, 71, 66, 66, 66, 66, 66, 66, + 72, 66, 75, 66, 66, 66, 76, 77, + 66, 11, 71, 66, 66, 66, 66, 66, + 75, 66, 78, 68, 79, 80, 10, 11, + 71, 66, 66, 13, 66, 66, 66, 72, + 66, 81, 68, 74, 74, 10, 11, 71, + 66, 66, 66, 66, 66, 66, 72, 66, + 68, 74, 74, 10, 11, 71, 66, 66, + 66, 66, 66, 66, 72, 66, 75, 66, + 66, 66, 82, 77, 66, 11, 71, 66, + 66, 66, 66, 66, 75, 66, 71, 66, + 66, 83, 71, 66, 71, 66, 71, 66, + 66, 66, 71, 66, 75, 66, 84, 66, + 82, 82, 66, 11, 71, 66, 66, 66, + 66, 66, 75, 66, 75, 66, 66, 66, + 82, 82, 66, 11, 71, 66, 66, 66, + 66, 66, 75, 66, 85, 86, 87, 87, + 10, 11, 71, 66, 86, 87, 87, 10, + 11, 71, 66, 87, 87, 10, 11, 71, + 66, 88, 89, 89, 10, 11, 71, 66, + 76, 90, 66, 11, 71, 66, 82, 82, + 66, 11, 71, 66, 76, 66, 82, 82, + 66, 11, 71, 66, 82, 90, 66, 11, + 71, 66, 78, 68, 74, 74, 10, 11, + 71, 66, 66, 66, 66, 66, 66, 72, + 66, 78, 68, 79, 74, 10, 11, 71, + 66, 66, 13, 66, 66, 66, 72, 66, + 8, 9, 9, 10, 11, 66, 67, 68, + 74, 70, 10, 11, 71, 66, 66, 66, + 66, 66, 66, 72, 66, 92, 36, 93, + 93, 18, 19, 39, 91, 91, 91, 91, + 91, 91, 43, 91, 36, 93, 93, 18, + 19, 39, 91, 91, 91, 91, 91, 91, + 43, 91, 94, 91, 91, 91, 95, 96, + 91, 19, 39, 91, 91, 91, 91, 91, + 94, 91, 35, 36, 97, 98, 18, 19, + 39, 91, 91, 20, 91, 91, 91, 43, + 91, 94, 91, 91, 91, 99, 96, 91, + 19, 39, 91, 91, 91, 91, 91, 94, + 91, 39, 91, 91, 100, 39, 91, 39, + 91, 39, 91, 91, 91, 39, 91, 94, + 91, 101, 91, 99, 99, 91, 19, 39, + 91, 91, 91, 91, 91, 94, 91, 94, + 91, 91, 91, 99, 99, 91, 19, 39, + 91, 91, 91, 91, 91, 94, 91, 102, + 103, 104, 104, 18, 19, 39, 91, 103, + 104, 104, 18, 19, 39, 91, 104, 104, + 18, 19, 39, 91, 35, 36, 93, 93, + 18, 19, 39, 91, 91, 91, 91, 91, + 91, 43, 91, 105, 106, 106, 18, 19, + 39, 91, 95, 107, 91, 19, 39, 91, + 99, 99, 91, 19, 39, 91, 95, 91, + 99, 99, 91, 19, 39, 91, 99, 107, + 91, 19, 39, 91, 35, 36, 97, 93, + 18, 19, 39, 91, 91, 20, 91, 91, + 91, 43, 91, 16, 17, 17, 18, 19, + 108, 108, 108, 20, 108, 16, 17, 17, + 18, 19, 108, 110, 111, 112, 113, 26, + 27, 114, 109, 109, 28, 109, 109, 109, + 115, 109, 116, 111, 113, 113, 26, 27, + 114, 109, 109, 109, 109, 109, 109, 115, + 109, 111, 113, 113, 26, 27, 114, 109, + 109, 109, 109, 109, 109, 115, 109, 117, + 109, 109, 109, 118, 119, 109, 27, 114, + 109, 109, 109, 109, 109, 117, 109, 110, + 111, 112, 40, 26, 27, 114, 109, 109, + 28, 109, 109, 109, 115, 109, 117, 109, + 109, 109, 120, 119, 109, 27, 114, 109, + 109, 109, 109, 109, 117, 109, 114, 109, + 109, 121, 114, 109, 114, 109, 114, 109, + 109, 109, 114, 109, 117, 109, 122, 109, + 120, 120, 109, 27, 114, 109, 109, 109, + 109, 109, 117, 109, 117, 109, 109, 109, + 120, 120, 109, 27, 114, 109, 109, 109, + 109, 109, 117, 109, 123, 124, 125, 125, + 26, 27, 114, 109, 124, 125, 125, 26, + 27, 114, 109, 125, 125, 26, 27, 114, + 109, 110, 111, 113, 113, 26, 27, 114, + 109, 109, 109, 109, 109, 109, 115, 109, + 126, 127, 127, 26, 27, 114, 109, 118, + 128, 109, 27, 114, 109, 120, 120, 109, + 27, 114, 109, 118, 109, 120, 120, 109, + 27, 114, 109, 120, 128, 109, 27, 114, + 109, 33, 34, 35, 36, 97, 93, 18, + 19, 39, 40, 40, 20, 91, 91, 33, + 43, 91, 47, 129, 49, 50, 4, 1, + 51, 46, 46, 6, 46, 46, 46, 52, + 46, 33, 34, 35, 36, 130, 131, 18, + 132, 133, 46, 40, 20, 46, 46, 33, + 43, 46, 16, 134, 134, 18, 132, 51, + 46, 46, 20, 46, 133, 46, 46, 135, + 133, 46, 133, 46, 133, 46, 46, 46, + 133, 46, 33, 46, 59, 16, 134, 134, + 18, 132, 51, 46, 46, 46, 46, 46, + 33, 46, 137, 136, 138, 138, 136, 31, + 139, 136, 138, 138, 136, 31, 139, 136, + 139, 136, 136, 140, 139, 136, 139, 136, + 139, 136, 136, 136, 139, 136, 33, 108, + 108, 108, 108, 108, 108, 108, 108, 40, + 108, 108, 108, 108, 33, 108, 0 +}; + +static const unsigned char _indic_syllable_machine_trans_targs[] = { + 27, 33, 38, 2, 39, 45, 46, 27, + 55, 8, 61, 56, 68, 69, 72, 27, + 77, 15, 83, 78, 86, 27, 91, 27, + 100, 21, 106, 101, 109, 114, 27, 125, + 27, 28, 48, 73, 75, 93, 94, 79, + 95, 115, 116, 87, 123, 128, 27, 29, + 31, 5, 47, 34, 42, 30, 1, 32, + 36, 0, 35, 37, 40, 41, 3, 43, + 4, 44, 27, 49, 51, 12, 71, 57, + 64, 50, 6, 52, 66, 59, 53, 11, + 70, 54, 7, 58, 60, 62, 63, 9, + 65, 10, 67, 27, 74, 17, 76, 89, + 81, 13, 92, 14, 80, 82, 84, 85, + 16, 88, 18, 90, 27, 27, 96, 98, + 19, 23, 102, 110, 97, 99, 112, 104, + 20, 103, 105, 107, 108, 22, 111, 24, + 113, 117, 118, 122, 119, 120, 25, 121, + 27, 124, 26, 126, 127 +}; + +static const char _indic_syllable_machine_trans_actions[] = { + 1, 0, 2, 0, 2, 2, 2, 3, + 2, 0, 2, 0, 2, 2, 2, 4, + 2, 0, 5, 0, 5, 6, 2, 7, + 2, 0, 2, 0, 2, 2, 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, 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 +}; + +static const char _indic_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, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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 _indic_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, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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 _indic_syllable_machine_eof_trans[] = { + 1, 1, 1, 1, 1, 1, 8, 8, + 8, 8, 8, 8, 8, 16, 16, 22, + 16, 16, 16, 24, 24, 24, 24, 24, + 24, 1, 31, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 109, 109, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 92, 47, 47, 47, 47, + 47, 47, 47, 137, 137, 137, 137, 137, + 109 +}; + +static const int indic_syllable_machine_start = 27; +static const int indic_syllable_machine_first_final = 27; +static const int indic_syllable_machine_error = -1; + +static const int indic_syllable_machine_en_main = 27; + + +#line 58 "hb-ot-shaper-indic-machine.rl" + + + +#line 117 "hb-ot-shaper-indic-machine.rl" + + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +inline void +find_syllables_indic (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts, te, act; + int cs; + hb_glyph_info_t *info = buffer->info; + +#line 426 "hb-ot-shaper-indic-machine.hh" + { + cs = indic_syllable_machine_start; + ts = 0; + te = 0; + act = 0; + } + +#line 137 "hb-ot-shaper-indic-machine.rl" + + + p = 0; + pe = eof = buffer->len; + + unsigned int syllable_serial = 1; + +#line 442 "hb-ot-shaper-indic-machine.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const unsigned char *_inds; + if ( p == pe ) + goto _test_eof; +_resume: + switch ( _indic_syllable_machine_from_state_actions[cs] ) { + case 10: +#line 1 "NONE" + {ts = p;} + break; +#line 456 "hb-ot-shaper-indic-machine.hh" + } + + _keys = _indic_syllable_machine_trans_keys + (cs<<1); + _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs]; + + _slen = _indic_syllable_machine_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) && + ( info[p].indic_category()) <= _keys[1] ? + ( info[p].indic_category()) - _keys[0] : _slen ]; + +_eof_trans: + cs = _indic_syllable_machine_trans_targs[_trans]; + + if ( _indic_syllable_machine_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _indic_syllable_machine_trans_actions[_trans] ) { + case 2: +#line 1 "NONE" + {te = p+1;} + break; + case 11: +#line 113 "hb-ot-shaper-indic-machine.rl" + {te = p+1;{ found_syllable (indic_non_indic_cluster); }} + break; + case 13: +#line 108 "hb-ot-shaper-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_consonant_syllable); }} + break; + case 14: +#line 109 "hb-ot-shaper-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_vowel_syllable); }} + break; + case 17: +#line 110 "hb-ot-shaper-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_standalone_cluster); }} + break; + case 19: +#line 111 "hb-ot-shaper-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_symbol_cluster); }} + break; + case 15: +#line 112 "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 113 "hb-ot-shaper-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_non_indic_cluster); }} + break; + case 1: +#line 108 "hb-ot-shaper-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} + break; + case 3: +#line 109 "hb-ot-shaper-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} + break; + case 7: +#line 110 "hb-ot-shaper-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} + break; + case 8: +#line 111 "hb-ot-shaper-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} + break; + case 4: +#line 112 "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: +#line 1 "NONE" + { switch( act ) { + case 1: + {{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; } + break; + case 6: + {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } + break; + } + } + break; + case 18: +#line 1 "NONE" + {te = p+1;} +#line 108 "hb-ot-shaper-indic-machine.rl" + {act = 1;} + break; + case 5: +#line 1 "NONE" + {te = p+1;} +#line 112 "hb-ot-shaper-indic-machine.rl" + {act = 5;} + break; + case 12: +#line 1 "NONE" + {te = p+1;} +#line 113 "hb-ot-shaper-indic-machine.rl" + {act = 6;} + break; +#line 559 "hb-ot-shaper-indic-machine.hh" + } + +_again: + switch ( _indic_syllable_machine_to_state_actions[cs] ) { + case 9: +#line 1 "NONE" + {ts = 0;} + break; +#line 568 "hb-ot-shaper-indic-machine.hh" + } + + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _indic_syllable_machine_eof_trans[cs] > 0 ) { + _trans = _indic_syllable_machine_eof_trans[cs] - 1; + goto _eof_trans; + } + } + + } + +#line 145 "hb-ot-shaper-indic-machine.rl" + +} + +#undef found_syllable + +#endif /* HB_OT_SHAPER_INDIC_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl index df9583f32d4..3274a776af0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl @@ -24,11 +24,23 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH +#ifndef HB_OT_SHAPER_INDIC_MACHINE_HH +#define HB_OT_SHAPER_INDIC_MACHINE_HH #include "hb.hh" +#include "hb-ot-layout.hh" +#include "hb-ot-shaper-indic.hh" + +/* buffer var allocations */ +#define indic_category() ot_shaper_var_u8_category() /* indic_category_t */ +#define indic_position() ot_shaper_var_u8_auxiliary() /* indic_position_t */ + +using indic_category_t = unsigned; +using indic_position_t = ot_position_t; + +#define I_Cat(Cat) indic_syllable_machine_ex_##Cat + enum indic_syllable_type_t { indic_consonant_syllable, indic_vowel_syllable, @@ -47,6 +59,8 @@ enum indic_syllable_type_t { %%{ + +export X = 0; export C = 1; export V = 2; export N = 3; @@ -55,15 +69,17 @@ export ZWNJ = 5; export ZWJ = 6; export M = 7; export SM = 8; -export A = 10; -export PLACEHOLDER = 11; -export DOTTEDCIRCLE = 12; -export RS = 13; -export Repha = 15; -export Ra = 16; -export CM = 17; -export Symbol= 18; -export CS = 19; +export A = 9; +export VD = 9; +export PLACEHOLDER = 10; +export DOTTEDCIRCLE = 11; +export RS = 12; +export Repha = 14; +export Ra = 15; +export CM = 16; +export Symbol= 17; +export CS = 18; + c = (C | Ra); # is_consonant n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier @@ -71,10 +87,9 @@ z = ZWJ|ZWNJ; # is_joiner reph = (Ra H | Repha); # possible reph cn = c.ZWJ?.n?; -forced_rakar = ZWJ H ZWJ Ra; symbol = Symbol.N?; -matra_group = z*.M.N?.(H | forced_rakar)?; -syllable_tail = (z?.SM.SM?.ZWNJ?)? A*; +matra_group = z*.M.N?.H?; +syllable_tail = (z?.SM.SM?.ZWNJ?)? (A | VD)*; halant_group = (z?.H.(ZWJ.N?)?); final_halant_group = halant_group | H.ZWNJ; medial_group = CM?; @@ -94,7 +109,7 @@ main := |* vowel_syllable => { found_syllable (indic_vowel_syllable); }; standalone_cluster => { found_syllable (indic_standalone_cluster); }; symbol_cluster => { found_syllable (indic_symbol_cluster); }; - broken_cluster => { found_syllable (indic_broken_cluster); }; + broken_cluster => { found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }; other => { found_syllable (indic_non_indic_cluster); }; *|; @@ -110,7 +125,7 @@ main := |* if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END -static void +inline void find_syllables_indic (hb_buffer_t *buffer) { unsigned int p, pe, eof, ts, te, act; @@ -132,4 +147,4 @@ find_syllables_indic (hb_buffer_t *buffer) #undef found_syllable -#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */ +#endif /* HB_OT_SHAPER_INDIC_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-table.cc new file mode 100644 index 00000000000..3d3698d7397 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-table.cc @@ -0,0 +1,560 @@ +/* == Start of generated table == */ +/* + * The following table is generated by running: + * + * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt + * + * on files with these headers: + * + * # IndicSyllabicCategory-14.0.0.txt + * # Date: 2021-05-22, 01:01:00 GMT [KW, RP] + * # IndicPositionalCategory-14.0.0.txt + * # Date: 2021-05-22, 01:01:00 GMT [KW, RP] + * # Blocks-14.0.0.txt + * # Date: 2021-01-22, 23:29:00 GMT [KW] + */ + +#include "hb.hh" + +#ifndef HB_NO_OT_SHAPE + +#include "hb-ot-shaper-indic.hh" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-macros" + +#include "hb-ot-shaper-indic-machine.hh" +#include "hb-ot-shaper-khmer-machine.hh" +#include "hb-ot-shaper-myanmar-machine.hh" + +/* indic */ +#define OT_X I_Cat(X) +#define OT_C I_Cat(C) +#define OT_V I_Cat(V) +#define OT_N I_Cat(N) +#define OT_H I_Cat(H) +#define OT_ZWNJ I_Cat(ZWNJ) +#define OT_ZWJ I_Cat(ZWJ) +#define OT_M I_Cat(M) +#define OT_SM I_Cat(SM) +#define OT_A I_Cat(A) +#define OT_VD I_Cat(VD) +#define OT_PLACEHOLDER I_Cat(PLACEHOLDER) +#define OT_DOTTEDCIRCLE I_Cat(DOTTEDCIRCLE) +#define OT_RS I_Cat(RS) +#define OT_Repha I_Cat(Repha) +#define OT_Ra I_Cat(Ra) +#define OT_CM I_Cat(CM) +#define OT_Symbol I_Cat(Symbol) +#define OT_CS I_Cat(CS) +/* khmer */ +#define OT_VAbv K_Cat(VAbv) +#define OT_VBlw K_Cat(VBlw) +#define OT_VPre K_Cat(VPre) +#define OT_VPst K_Cat(VPst) +#define OT_Robatic K_Cat(Robatic) +#define OT_Xgroup K_Cat(Xgroup) +#define OT_Ygroup K_Cat(Ygroup) +/* myanmar */ +static_assert (OT_VAbv == M_Cat(VAbv), ""); +static_assert (OT_VBlw == M_Cat(VBlw), ""); +static_assert (OT_VPre == M_Cat(VPre), ""); +static_assert (OT_VPst == M_Cat(VPst), ""); +#define OT_IV M_Cat(IV) +#define OT_As M_Cat(As) +#define OT_DB M_Cat(DB) +#define OT_GB M_Cat(GB) +#define OT_MH M_Cat(MH) +#define OT_MR M_Cat(MR) +#define OT_MW M_Cat(MW) +#define OT_MY M_Cat(MY) +#define OT_PT M_Cat(PT) +#define OT_VS M_Cat(VS) +#define OT_ML M_Cat(ML) + + +#define _OT_A OT_A /* 53 chars; A */ +#define _OT_As OT_As /* 1 chars; As */ +#define _OT_C OT_C /* 478 chars; C */ +#define _OT_CM OT_CM /* 1 chars; CM */ +#define _OT_CS OT_CS /* 2 chars; CS */ +#define _OT_DC OT_DOTTEDCIRCLE /* 1 chars; DOTTEDCIRCLE */ +#define _OT_H OT_H /* 11 chars; H */ +#define _OT_M OT_M /* 143 chars; M */ +#define _OT_MH OT_MH /* 1 chars; MH */ +#define _OT_ML OT_ML /* 1 chars; ML */ +#define _OT_MR OT_MR /* 1 chars; MR */ +#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_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 /* 55 chars; SM */ +#define _OT_S OT_Symbol /* 22 chars; Symbol */ +#define _OT_V OT_V /* 172 chars; V */ +#define _OT_VA OT_VAbv /* 18 chars; VAbv */ +#define _OT_VB OT_VBlw /* 7 chars; VBlw */ +#define _OT_VL OT_VPre /* 5 chars; VPre */ +#define _OT_VR OT_VPst /* 13 chars; VPst */ +#define _OT_VS OT_VS /* 16 chars; VS */ +#define _OT_X OT_X /* 2 chars; X */ +#define _OT_Xg OT_Xgroup /* 7 chars; Xgroup */ +#define _OT_Yg OT_Ygroup /* 4 chars; Ygroup */ +#define _OT_ZWJ OT_ZWJ /* 1 chars; ZWJ */ +#define _OT_ZWNJ OT_ZWNJ /* 1 chars; ZWNJ */ + +#define _POS_T POS_ABOVE_C /* 22 chars; ABOVE_C */ +#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 /* 45 chars; AFTER_SUB */ +#define _POS_C POS_BASE_C /* 833 chars; BASE_C */ +#define _POS_BS POS_BEFORE_SUB /* 31 chars; BEFORE_SUB */ +#define _POS_B POS_BELOW_C /* 13 chars; BELOW_C */ +#define _POS_X POS_END /* 71 chars; END */ +#define _POS_R POS_POST_C /* 13 chars; POST_C */ +#define _POS_L POS_PRE_C /* 5 chars; PRE_C */ +#define _POS_LM POS_PRE_M /* 14 chars; PRE_M */ +#define _POS_SM POS_SMVD /* 129 chars; SMVD */ + +#pragma GCC diagnostic pop + +#define INDIC_COMBINE_CATEGORIES(S,M) ((S) | ((M) << 8)) + +#define _(S,M) INDIC_COMBINE_CATEGORIES (_OT_##S, _POS_##M) + + +static const uint16_t indic_table[] = { + + +#define indic_offset_0x0028u 0 + + + /* Basic Latin */ + + /* 0028 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(X,X), _(X,X), + /* 0030 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0038 */ _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + +#define indic_offset_0x00b0u 24 + + + /* Latin-1 Supplement */ + + /* 00B0 */ _(X,X), _(X,X),_(SM,SM),_(SM,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), + /* 00D0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), + +#define indic_offset_0x0900u 64 + + + /* Devanagari */ + + /* 0900 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(V,C), _(V,C), _(V,C), _(V,C), + /* 0908 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), + /* 0910 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), + /* 0918 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0920 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0928 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0930 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0938 */ _(C,C), _(C,C), _(M,AS), _(M,AS), _(N,X), _(S,SM), _(M,AS), _(M,LM), + /* 0940 */ _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), + /* 0948 */ _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(H,B), _(M,LM), _(M,AS), + /* 0950 */ _(X,X), _(A,SM), _(A,SM),_(SM,SM),_(SM,SM), _(M,AS), _(M,AS), _(M,AS), + /* 0958 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0960 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 0968 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0970 */ _(X,X), _(X,X), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), + /* 0978 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + + /* Bengali */ + + /* 0980 */ _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), + /* 0988 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(V,C), + /* 0990 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), + /* 0998 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 09A0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 09A8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 09B0 */ _(R,C), _(X,X), _(C,C), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), + /* 09B8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,LM), + /* 09C0 */ _(M,AP), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(X,X), _(M,LM), + /* 09C8 */ _(M,LM), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(C,C), _(X,X), + /* 09D0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), + /* 09D8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), + /* 09E0 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 09E8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 09F0 */ _(R,C), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 09F8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(X,X),_(SM,SM), _(X,X), + + /* Gurmukhi */ + + /* 0A00 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), + /* 0A08 */ _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C), + /* 0A10 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), + /* 0A18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0A20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0A28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0A30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(X,X), + /* 0A38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(X,X), _(M,AP), _(M,LM), + /* 0A40 */ _(M,AP), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), + /* 0A48 */ _(M,AP), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X), + /* 0A50 */ _(X,X), _(M,B), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0A58 */ _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X), + /* 0A60 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 0A68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0A70 */_(SM,SM),_(SM,SM), _(C,C), _(C,C), _(X,X), _(CM,C), _(X,X), _(X,X), + /* 0A78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + + /* Gujarati */ + + /* 0A80 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), + /* 0A88 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), + /* 0A90 */ _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), + /* 0A98 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0AA0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0AA8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0AB0 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), + /* 0AB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,LM), + /* 0AC0 */ _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AS), _(X,X), _(M,AS), + /* 0AC8 */ _(M,AS), _(M,AP), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X), + /* 0AD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0AD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0AE0 */ _(V,C), _(V,C), _(M,AP), _(M,AP), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 0AE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0AF0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0AF8 */ _(X,X), _(C,C), _(A,SM), _(N,X), _(A,SM), _(N,X), _(N,X), _(N,X), + + /* Oriya */ + + /* 0B00 */ _(X,X),_(SM,BS),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), + /* 0B08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(V,C), + /* 0B10 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), + /* 0B18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0B20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0B28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0B30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), + /* 0B38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,A), + /* 0B40 */ _(M,AP), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(X,X), _(M,LM), + /* 0B48 */ _(M,A), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X), + /* 0B50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(N,X), _(M,A), _(M,AP), + /* 0B58 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), + /* 0B60 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 0B68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0B70 */ _(X,X), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0B78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + + /* Tamil */ + + /* 0B80 */ _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(V,C), _(V,C), _(V,C), + /* 0B88 */ _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(X,X), _(V,C), _(V,C), + /* 0B90 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(X,X), _(X,X), + /* 0B98 */ _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X), _(C,C), _(C,C), + /* 0BA0 */ _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), + /* 0BA8 */ _(C,C), _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), + /* 0BB0 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0BB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), _(M,AP), + /* 0BC0 */ _(M,AS), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(M,LM), _(M,LM), + /* 0BC8 */ _(M,LM), _(X,X), _(M,AP), _(M,AP), _(M,AP), _(H,T), _(X,X), _(X,X), + /* 0BD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), + /* 0BD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0BE0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 0BE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0BF0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0BF8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + + /* Telugu */ + + /* 0C00 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(V,C), _(V,C), _(V,C), + /* 0C08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), + /* 0C10 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), + /* 0C18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0C20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0C28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0C30 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0C38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,BS), _(M,BS), + /* 0C40 */ _(M,BS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(M,BS), _(M,BS), + /* 0C48 */ _(M,BS), _(X,X), _(M,BS), _(M,BS), _(M,BS), _(H,T), _(X,X), _(X,X), + /* 0C50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,BS), _(M,BS), _(X,X), + /* 0C58 */ _(C,C), _(C,C), _(C,C), _(X,X), _(X,X), _(C,C), _(X,X), _(X,X), + /* 0C60 */ _(V,C), _(V,C), _(M,BS), _(M,BS), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 0C68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0C70 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0C78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + + /* Kannada */ + + /* 0C80 */ _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), + /* 0C88 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), + /* 0C90 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), + /* 0C98 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0CA0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0CA8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0CB0 */ _(R,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), + /* 0CB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,BS), _(M,BS), + /* 0CC0 */ _(M,BS), _(M,BS), _(M,BS), _(M,BS), _(M,BS), _(X,X), _(M,BS), _(M,BS), + /* 0CC8 */ _(M,BS), _(X,X), _(M,BS), _(M,BS), _(M,BS), _(H,T), _(X,X), _(X,X), + /* 0CD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,BS), _(M,BS), _(X,X), + /* 0CD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), + /* 0CE0 */ _(V,C), _(V,C), _(M,BS), _(M,BS), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 0CE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0CF0 */ _(X,X), _(CS,C), _(CS,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0CF8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + + /* Malayalam */ + + /* 0D00 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(GB,C), _(V,C), _(V,C), _(V,C), + /* 0D08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), + /* 0D10 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), + /* 0D18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0D20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0D28 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0D30 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 0D38 */ _(C,C), _(C,C), _(C,C), _(M,AS), _(M,AS), _(S,SM), _(M,AP), _(M,AP), + /* 0D40 */ _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(X,X), _(M,LM), _(M,LM), + /* 0D48 */ _(M,LM), _(X,X), _(M,AP), _(M,AP), _(M,AP), _(H,T), _(Rf,X), _(X,X), + /* 0D50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(C,C), _(M,AP), + /* 0D58 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C), + /* 0D60 */ _(V,C), _(V,C), _(M,AP), _(M,AP), _(X,X), _(X,X), _(GB,C), _(GB,C), + /* 0D68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 0D70 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 0D78 */ _(X,X), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + +#define indic_offset_0x1000u 1216 + + + /* Myanmar */ + + /* 1000 */ _(C,C), _(C,C), _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), + /* 1008 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 1010 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 1018 */ _(C,C), _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 1020 */ _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), + /* 1028 */ _(V,C), _(V,C), _(V,C), _(VR,R), _(VR,R), _(VA,T), _(VA,T), _(VB,B), + /* 1030 */ _(VB,B), _(VL,L), _(A,SM), _(VA,T), _(VA,T), _(VA,T), _(A,SM), _(N,X), + /* 1038 */_(SM,SM), _(H,X), _(As,X), _(MY,X), _(MR,X), _(MW,X), _(MH,X), _(C,C), + /* 1040 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 1048 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), _(C,C), _(X,X), + /* 1050 */ _(C,C), _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(VR,R), _(VR,R), + /* 1058 */ _(VB,B), _(VB,B), _(R,C), _(C,C), _(C,C), _(C,C), _(MY,X), _(MY,X), + /* 1060 */ _(ML,X), _(C,C), _(VR,R), _(PT,X), _(PT,X), _(C,C), _(C,C), _(VR,R), + /* 1068 */ _(VR,R), _(PT,X), _(PT,X), _(PT,X), _(PT,X), _(PT,X), _(C,C), _(C,C), + /* 1070 */ _(C,C), _(VA,T), _(VA,T), _(VA,T), _(VA,T), _(C,C), _(C,C), _(C,C), + /* 1078 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 1080 */ _(C,C), _(C,C), _(MW,X), _(VR,R), _(VL,L), _(VA,T), _(VA,T),_(SM,SM), + /* 1088 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(C,C),_(SM,SM), + /* 1090 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 1098 */ _(GB,C), _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(VA,T), _(X,X), _(X,X), + +#define indic_offset_0x1780u 1376 + + + /* Khmer */ + + /* 1780 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 1788 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 1790 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 1798 */ _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* 17A0 */ _(C,C), _(C,C), _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), + /* 17A8 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), + /* 17B0 */ _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(VR,R), _(VA,T), + /* 17B8 */ _(VA,T), _(VA,T), _(VA,T), _(VB,B), _(VB,B), _(VB,B), _(VA,T), _(VR,R), + /* 17C0 */ _(VR,R), _(VL,L), _(VL,L), _(VL,L), _(VR,R), _(VR,R), _(Xg,X), _(Yg,X), + /* 17C8 */ _(Yg,X), _(Rt,X), _(Rt,X), _(Xg,X), _(Rt,X), _(Xg,X), _(Xg,X), _(Xg,X), + /* 17D0 */ _(Xg,X), _(Xg,X), _(H,X), _(Yg,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 17D8 */ _(X,X), _(GB,C), _(X,X), _(X,X), _(S,SM), _(Yg,X), _(X,X), _(X,X), + /* 17E0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* 17E8 */ _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + +#define indic_offset_0x1cd0u 1488 + + + /* Vedic Extensions */ + + /* 1CD0 */ _(A,SM), _(A,SM), _(A,SM), _(X,X), _(A,SM), _(A,SM), _(A,SM), _(A,SM), + /* 1CD8 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), + /* 1CE0 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), + /* 1CE8 */ _(A,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(A,SM), _(S,SM), _(S,SM), + /* 1CF0 */ _(S,SM), _(S,SM), _(C,C), _(C,C), _(A,SM), _(C,C), _(C,C), _(A,SM), + /* 1CF8 */ _(A,SM), _(A,SM), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + +#define indic_offset_0x2008u 1536 + + + /* General Punctuation */ + + /* 2008 */ _(X,X), _(X,X), _(X,X), _(X,X),_(ZWNJ,X),_(ZWJ,X), _(X,X), _(X,X), + /* 2010 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), + /* 2018 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 2020 */ _(X,X), _(X,X), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + +#define indic_offset_0x2070u 1568 + + + /* Superscripts and Subscripts */ + + /* 2070 */ _(X,X), _(X,X), _(X,X), _(X,X),_(SM,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), + +#define indic_offset_0x25f8u 1592 + + + /* Geometric Shapes */ + + /* 25F8 */ _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), + +#define indic_offset_0xa8e0u 1600 + + + /* Devanagari Extended */ + + /* A8E0 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), + /* A8E8 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), + /* A8F0 */ _(A,SM), _(A,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), + /* A8F8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C), _(M,AS), + +#define indic_offset_0xa9e0u 1632 + + + /* Myanmar Extended-B */ + + /* A9E0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(VA,T), _(X,X), _(C,C), + /* A9E8 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* A9F0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), + /* A9F8 */ _(GB,C), _(GB,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X), + +#define indic_offset_0xaa60u 1664 + + + /* Myanmar Extended-A */ + + /* AA60 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* AA68 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), + /* AA70 */ _(X,X), _(C,C), _(C,C), _(C,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), + /* AA78 */ _(X,X), _(X,X), _(C,C), _(PT,X), _(N,X), _(N,X), _(C,C), _(C,C), + +#define indic_offset_0xfe00u 1696 + + + /* Variation Selectors */ + + /* FE00 */ _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), + /* FE08 */ _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), + +#define indic_offset_0x11300u 1712 + + + /* Grantha */ + + /* 11300 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X), + /* 11308 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 11310 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 11318 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 11320 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 11328 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 11330 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), + /* 11338 */ _(X,X), _(X,X), _(X,X), _(N,X), _(N,X), _(X,X), _(X,X), _(X,X), + +}; /* Table items: 1776; occupancy: 69% */ + +uint16_t +hb_indic_get_categories (hb_codepoint_t u) +{ + switch (u >> 12) + { + case 0x0u: + if (unlikely (u == 0x00A0u)) return _(GB,C); + if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u]; + if (hb_in_range<hb_codepoint_t> (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0D7Fu)) return indic_table[u - 0x0900u + indic_offset_0x0900u]; + break; + + case 0x1u: + if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u]; + if (hb_in_range<hb_codepoint_t> (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u]; + if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u]; + break; + + case 0x2u: + if (unlikely (u == 0x25CCu)) return _(DC,C); + if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2027u)) return indic_table[u - 0x2008u + indic_offset_0x2008u]; + if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u]; + if (hb_in_range<hb_codepoint_t> (u, 0x25F8u, 0x25FFu)) return indic_table[u - 0x25F8u + indic_offset_0x25f8u]; + break; + + case 0xAu: + if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8FFu)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u]; + if (hb_in_range<hb_codepoint_t> (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u]; + if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u]; + break; + + case 0xFu: + if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return indic_table[u - 0xFE00u + indic_offset_0xfe00u]; + break; + + case 0x11u: + if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x1133Fu)) return indic_table[u - 0x11300u + indic_offset_0x11300u]; + break; + + default: + break; + } + return _(X,X); +} + +#undef _ +#undef INDIC_COMBINE_CATEGORIES + +#undef _OT_A +#undef _OT_As +#undef _OT_C +#undef _OT_CM +#undef _OT_CS +#undef _OT_DC +#undef _OT_H +#undef _OT_M +#undef _OT_MH +#undef _OT_ML +#undef _OT_MR +#undef _OT_MW +#undef _OT_MY +#undef _OT_N +#undef _OT_GB +#undef _OT_PT +#undef _OT_R +#undef _OT_Rf +#undef _OT_Rt +#undef _OT_SM +#undef _OT_S +#undef _OT_V +#undef _OT_VA +#undef _OT_VB +#undef _OT_VL +#undef _OT_VR +#undef _OT_VS +#undef _OT_X +#undef _OT_Xg +#undef _OT_Yg +#undef _OT_ZWJ +#undef _OT_ZWNJ + +#undef _POS_T +#undef _POS_A +#undef _POS_AP +#undef _POS_AS +#undef _POS_C +#undef _POS_BS +#undef _POS_B +#undef _POS_X +#undef _POS_R +#undef _POS_L +#undef _POS_LM +#undef _POS_SM + +#endif + +/* == End of generated table == */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc index c80f7df6a9c..48a3c744630 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc @@ -28,9 +28,9 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-indic.hh" -#include "hb-ot-shape-complex-indic-machine.hh" -#include "hb-ot-shape-complex-vowel-constraints.hh" +#include "hb-ot-shaper-indic.hh" +#include "hb-ot-shaper-indic-machine.hh" +#include "hb-ot-shaper-vowel-constraints.hh" #include "hb-ot-layout.hh" @@ -39,6 +39,81 @@ */ +static inline void +set_indic_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + + info.indic_category() = (indic_category_t) (type & 0xFFu); + info.indic_position() = (indic_position_t) (type >> 8); +} + + +static inline bool +is_one_of (const hb_glyph_info_t &info, unsigned int flags) +{ + /* If it ligated, all bets are off. */ + if (_hb_glyph_info_ligated (&info)) return false; + return !!(FLAG_UNSAFE (info.indic_category()) & flags); +} + +/* Note: + * + * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels + * cannot happen in a consonant syllable. The plus side however is, we can call the + * consonant syllable logic from the vowel syllable function and get it all right! + * + * Keep in sync with consonant_categories in the generator. */ +#define CONSONANT_FLAGS_INDIC (FLAG (I_Cat(C)) | FLAG (I_Cat(CS)) | FLAG (I_Cat(Ra)) | FLAG (I_Cat(CM)) | FLAG (I_Cat(V)) | FLAG (I_Cat(PLACEHOLDER)) | FLAG (I_Cat(DOTTEDCIRCLE))) + +static inline bool +is_consonant (const hb_glyph_info_t &info) +{ + return is_one_of (info, CONSONANT_FLAGS_INDIC); +} + +#define JOINER_FLAGS (FLAG (I_Cat(ZWJ)) | FLAG (I_Cat(ZWNJ))) + +static inline bool +is_joiner (const hb_glyph_info_t &info) +{ + return is_one_of (info, JOINER_FLAGS); +} + +static inline bool +is_halant (const hb_glyph_info_t &info) +{ + return is_one_of (info, FLAG (I_Cat(H))); +} + +struct hb_indic_would_substitute_feature_t +{ + void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_) + { + zero_context = zero_context_; + map->get_stage_lookups (0/*GSUB*/, + map->get_feature_stage (0/*GSUB*/, feature_tag), + &lookups, &count); + } + + bool would_substitute (const hb_codepoint_t *glyphs, + unsigned int glyphs_count, + hb_face_t *face) const + { + for (unsigned int i = 0; i < count; i++) + if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context)) + return true; + return false; + } + + private: + const hb_ot_map_t::lookup_map_t *lookups; + unsigned int count; + bool zero_context; +}; + + /* * Indic configurations. Note that we do not want to keep every single script-specific * behavior in these tables necessarily. This should mainly be used for per-script @@ -47,10 +122,6 @@ * instead of adding a new flag in these structs. */ -enum base_position_t { - BASE_POS_LAST_SINHALA, - BASE_POS_LAST -}; enum reph_position_t { REPH_POS_AFTER_MAIN = POS_AFTER_MAIN, REPH_POS_BEFORE_SUB = POS_BEFORE_SUB, @@ -72,7 +143,6 @@ struct indic_config_t hb_script_t script; bool has_old_spec; hb_codepoint_t virama; - base_position_t base_pos; reph_position_t reph_pos; reph_mode_t reph_mode; blwf_mode_t blwf_mode; @@ -81,26 +151,19 @@ struct indic_config_t static const indic_config_t indic_configs[] = { /* Default. Should be first. */ - {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, - {HB_SCRIPT_DEVANAGARI,true, 0x094Du,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, - {HB_SCRIPT_BENGALI, true, 0x09CDu,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, - {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, - {HB_SCRIPT_GUJARATI, true, 0x0ACDu,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, - {HB_SCRIPT_ORIYA, true, 0x0B4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, - {HB_SCRIPT_TAMIL, true, 0x0BCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, - {HB_SCRIPT_TELUGU, true, 0x0C4Du,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY}, - {HB_SCRIPT_KANNADA, true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY}, - {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST}, - {HB_SCRIPT_SINHALA, false,0x0DCAu,BASE_POS_LAST_SINHALA, - REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_INVALID, false, 0,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_DEVANAGARI,true, 0x094Du,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_BENGALI, true, 0x09CDu,REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_GUJARATI, true, 0x0ACDu,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_ORIYA, true, 0x0B4Du,REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_TAMIL, true, 0x0BCDu,REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_TELUGU, true, 0x0C4Du,REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY}, + {HB_SCRIPT_KANNADA, true, 0x0CCDu,REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY}, + {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST}, }; - -/* - * Indic shaper. - */ - static const hb_ot_map_feature_t indic_features[] = { @@ -207,6 +270,7 @@ static void override_features_indic (hb_ot_shape_planner_t *plan) { plan->map.disable_feature (HB_TAG('l','i','g','a')); + plan->map.add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var } @@ -356,6 +420,7 @@ setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { + HB_BUFFER_ALLOCATE_VAR (buffer, syllable); find_syllables_indic (buffer); foreach_syllable (buffer, start, end) buffer->unsafe_to_break (start, end); @@ -367,7 +432,7 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) int a = pa->indic_position(); int b = pb->indic_position(); - return a < b ? -1 : a == b ? 0 : +1; + return (int) a - (int) b; } @@ -379,9 +444,6 @@ update_consonant_positions_indic (const hb_ot_shape_plan_t *plan, { const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; - if (indic_plan->config->base_pos != BASE_POS_LAST) - return; - hb_codepoint_t virama; if (indic_plan->load_virama_glyph (font, &virama)) { @@ -416,9 +478,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, */ if (buffer->props.script == HB_SCRIPT_KANNADA && start + 3 <= end && - is_one_of (info[start ], FLAG (OT_Ra)) && - is_one_of (info[start+1], FLAG (OT_H)) && - is_one_of (info[start+2], FLAG (OT_ZWJ))) + is_one_of (info[start ], FLAG (I_Cat(Ra))) && + is_one_of (info[start+1], FLAG (I_Cat(H))) && + is_one_of (info[start+2], FLAG (I_Cat(ZWJ)))) { buffer->merge_clusters (start+1, start+3); hb_glyph_info_t tmp = info[start+1]; @@ -452,7 +514,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, start + 3 <= end && ( (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) || - (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ) + (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == I_Cat(ZWJ)) )) { /* See if it matches the 'rphf' feature. */ @@ -470,7 +532,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, base = start; has_reph = true; } - } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == OT_Repha) + } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == I_Cat(Repha)) { limit += 1; while (limit < end && is_joiner (info[limit])) @@ -479,84 +541,51 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, has_reph = true; } - switch (indic_plan->config->base_pos) { - case BASE_POS_LAST: - { - /* -> starting from the end of the syllable, move backwards */ - unsigned int i = end; - bool seen_below = false; - do { - i--; - /* -> until a consonant is found */ - if (is_consonant (info[i])) + /* -> starting from the end of the syllable, move backwards */ + unsigned int i = end; + bool seen_below = false; + do { + i--; + /* -> until a consonant is found */ + if (is_consonant (info[i])) + { + /* -> that does not have a below-base or post-base form + * (post-base forms have to follow below-base forms), */ + if (info[i].indic_position() != POS_BELOW_C && + (info[i].indic_position() != POS_POST_C || seen_below)) { - /* -> that does not have a below-base or post-base form - * (post-base forms have to follow below-base forms), */ - if (info[i].indic_position() != POS_BELOW_C && - (info[i].indic_position() != POS_POST_C || seen_below)) - { - base = i; - break; - } - if (info[i].indic_position() == POS_BELOW_C) - seen_below = true; - - /* -> or that is not a pre-base-reordering Ra, - * - * IMPLEMENTATION NOTES: - * - * Our pre-base-reordering Ra's are marked POS_POST_C, so will be skipped - * by the logic above already. - */ - - /* -> or arrive at the first consonant. The consonant stopped at will - * be the base. */ base = i; + break; } - else - { - /* A ZWJ after a Halant stops the base search, and requests an explicit - * half form. - * A ZWJ before a Halant, requests a subjoined form instead, and hence - * search continues. This is particularly important for Bengali - * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */ - if (start < i && - info[i].indic_category() == OT_ZWJ && - info[i - 1].indic_category() == OT_H) - break; - } - } while (i > limit); - } - break; - - case BASE_POS_LAST_SINHALA: - { - /* Sinhala base positioning is slightly different from main Indic, in that: - * 1. Its ZWJ behavior is different, - * 2. We don't need to look into the font for consonant positions. - */ - - if (!has_reph) - base = limit; + if (info[i].indic_position() == POS_BELOW_C) + seen_below = true; - /* Find the last base consonant that is not blocked by ZWJ. If there is - * a ZWJ right before a base consonant, that would request a subjoined form. */ - for (unsigned int i = limit; i < end; i++) - if (is_consonant (info[i])) - { - if (limit < i && info[i - 1].indic_category() == OT_ZWJ) - break; - else - base = i; - } + /* -> or that is not a pre-base-reordering Ra, + * + * IMPLEMENTATION NOTES: + * + * Our pre-base-reordering Ra's are marked POS_POST_C, so will be skipped + * by the logic above already. + */ - /* Mark all subsequent consonants as below. */ - for (unsigned int i = base + 1; i < end; i++) - if (is_consonant (info[i])) - info[i].indic_position() = POS_BELOW_C; - } - break; + /* -> or arrive at the first consonant. The consonant stopped at will + * be the base. */ + base = i; + } + else + { + /* A ZWJ after a Halant stops the base search, and requests an explicit + * half form. + * A ZWJ before a Halant, requests a subjoined form instead, and hence + * search continues. This is particularly important for Bengali + * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */ + if (start < i && + info[i].indic_category() == I_Cat(ZWJ) && + info[i - 1].indic_category() == I_Cat(H)) + break; + } + } while (i > limit); } /* -> If the syllable starts with Ra + Halant (in a script that has Reph) @@ -611,18 +640,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, if (base < end) info[base].indic_position() = POS_BASE_C; - /* Mark final consonants. A final consonant is one appearing after a matra. - * Happens in Sinhala. */ - for (unsigned int i = base + 1; i < end; i++) - if (info[i].indic_category() == OT_M) { - for (unsigned int j = i + 1; j < end; j++) - if (is_consonant (info[j])) { - info[j].indic_position() = POS_FINAL_C; - break; - } - break; - } - /* Handle beginning Ra */ if (has_reph) info[start].indic_position() = POS_RA_TO_BECOME_REPH; @@ -659,14 +676,14 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, { bool disallow_double_halants = buffer->props.script == HB_SCRIPT_KANNADA; for (unsigned int i = base + 1; i < end; i++) - if (info[i].indic_category() == OT_H) + if (info[i].indic_category() == I_Cat(H)) { unsigned int j; for (j = end - 1; j > i; j--) if (is_consonant (info[j]) || - (disallow_double_halants && info[j].indic_category() == OT_H)) + (disallow_double_halants && info[j].indic_category() == I_Cat(H))) break; - if (info[j].indic_category() != OT_H && j > i) { + if (info[j].indic_category() != I_Cat(H) && j > i) { /* Move Halant to after last consonant. */ hb_glyph_info_t t = info[i]; memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0])); @@ -681,20 +698,16 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, indic_position_t last_pos = POS_START; for (unsigned int i = start; i < end; i++) { - if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_H)))) + if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (I_Cat(N)) | FLAG (I_Cat(RS)) | FLAG (I_Cat(CM)) | FLAG (I_Cat(H))))) { info[i].indic_position() = last_pos; - if (unlikely (info[i].indic_category() == OT_H && + if (unlikely (info[i].indic_category() == I_Cat(H) && info[i].indic_position() == POS_PRE_M)) { /* * Uniscribe doesn't move the Halant with Left Matra. - * TEST: U+092B,U+093F,U+094DE - * We follow. This is important for the Sinhala - * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA - * where U+0DD9 is a left matra and U+0DCA is the virama. - * We don't want to move the virama with the left matra. - * TEST: U+0D9A,U+0DDA + * TEST: U+092B,U+093F,U+094D + * We follow. */ for (unsigned int j = i; j > start; j--) if (info[j - 1].indic_position() != POS_PRE_M) { @@ -718,7 +731,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, if (info[j].indic_position() < POS_SMVD) info[j].indic_position() = info[i].indic_position(); last = i; - } else if (info[i].indic_category() == OT_M) + } else if (info[i].indic_category() == I_Cat(M)) last = i; } @@ -849,10 +862,10 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915 */ for (unsigned int i = start; i + 1 < base; i++) - if (info[i ].indic_category() == OT_Ra && - info[i+1].indic_category() == OT_H && + if (info[i ].indic_category() == I_Cat(Ra) && + info[i+1].indic_category() == I_Cat(H) && (i + 2 == base || - info[i+2].indic_category() != OT_ZWJ)) + info[i+2].indic_category() != I_Cat(ZWJ))) { info[i ].mask |= indic_plan->mask_array[INDIC_BLWF]; info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF]; @@ -879,7 +892,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, /* Apply ZWJ/ZWNJ effects */ for (unsigned int i = start + 1; i < end; i++) if (is_joiner (info[i])) { - bool non_joiner = info[i].indic_category() == OT_ZWNJ; + bool non_joiner = info[i].indic_category() == I_Cat(ZWNJ); unsigned int j = i; do { @@ -912,7 +925,7 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, /* For dotted-circle, this is what Uniscribe does: * If dotted-circle is the last glyph, it just does nothing. * Ie. It doesn't form Reph. */ - if (buffer->info[end - 1].indic_category() == OT_DOTTEDCIRCLE) + if (buffer->info[end - 1].indic_category() == I_Cat(DOTTEDCIRCLE)) return; } @@ -955,8 +968,8 @@ initial_reordering_indic (const hb_ot_shape_plan_t *plan, update_consonant_positions_indic (plan, font, buffer); hb_syllabic_insert_dotted_circles (font, buffer, indic_broken_cluster, - OT_DOTTEDCIRCLE, - OT_Repha, + I_Cat(DOTTEDCIRCLE), + I_Cat(Repha), POS_END); foreach_syllable (buffer, start, end) @@ -978,7 +991,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, * and possibly multiple substitutions happened prior to this * phase, and that might have messed up our properties. Recover * from a particular case of that where we're fairly sure that a - * class of OT_H is desired but has been lost. */ + * class of I_Cat(H) is desired but has been lost. */ /* We don't call load_virama_glyph(), since we know it's already * loaded. */ hb_codepoint_t virama_glyph = indic_plan->virama_glyph.get_relaxed (); @@ -990,7 +1003,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, _hb_glyph_info_multiplied (&info[i])) { /* This will make sure that this glyph passes is_halant() test. */ - info[i].indic_category() = OT_H; + info[i].indic_category() = I_Cat(H); _hb_glyph_info_clear_ligated_and_multiplied (&info[i]); } } @@ -1056,11 +1069,11 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, break; } if (base == end && start < base && - is_one_of (info[base - 1], FLAG (OT_ZWJ))) + is_one_of (info[base - 1], FLAG (I_Cat(ZWJ)))) base--; if (base < end) while (start < base && - is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_H)))) + is_one_of (info[base], (FLAG (I_Cat(N)) | FLAG (I_Cat(H))))) base--; @@ -1105,7 +1118,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, { search: while (new_pos > start && - !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H))))) + !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(H)))))) new_pos--; /* If we found no Halant we are done. @@ -1122,7 +1135,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, if (new_pos + 1 < end) { /* -> If ZWJ follows this halant, matra is NOT repositioned after this halant. */ - if (info[new_pos + 1].indic_category() == OT_ZWJ) + if (info[new_pos + 1].indic_category() == I_Cat(ZWJ)) { /* Keep searching. */ if (new_pos > start) @@ -1195,7 +1208,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, */ if (start + 1 < end && info[start].indic_position() == POS_RA_TO_BECOME_REPH && - ((info[start].indic_category() == OT_Repha) ^ + ((info[start].indic_category() == I_Cat(Repha)) ^ _hb_glyph_info_ligated_and_didnt_multiply (&info[start]))) { unsigned int new_reph_pos; @@ -1305,7 +1318,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, unlikely (is_halant (info[new_reph_pos]))) { for (unsigned int i = base + 1; i < new_reph_pos; i++) - if (info[i].indic_category() == OT_M) { + if (info[i].indic_category() == I_Cat(M)) { /* Ok, got it. */ new_reph_pos--; } @@ -1365,7 +1378,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL) { while (new_pos > start && - !(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_H)))) + !(is_one_of (info[new_pos - 1], FLAG(I_Cat(M)) | FLAG (I_Cat(H))))) new_pos--; } @@ -1414,11 +1427,10 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, switch ((hb_tag_t) plan->props.script) { case HB_SCRIPT_TAMIL: - case HB_SCRIPT_SINHALA: break; default: - /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala. + /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil. * This means, half forms are submerged into the main consonant's cluster. * This is unnecessary, and makes cursor positioning harder, but that's what * Uniscribe does. */ @@ -1453,7 +1465,9 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font) { - _hb_preprocess_text_vowel_constraints (plan, buffer, font); + const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; + if (!indic_plan->uniscribe_bug_compatible) + _hb_preprocess_text_vowel_constraints (plan, buffer, font); } static bool @@ -1486,48 +1500,6 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, #endif } - if ((ab == 0x0DDAu || hb_in_range<hb_codepoint_t> (ab, 0x0DDCu, 0x0DDEu))) - { - /* - * Sinhala split matras... Let the fun begin. - * - * These four characters have Unicode decompositions. However, Uniscribe - * decomposes them "Khmer-style", that is, it uses the character itself to - * get the second half. The first half of all four decompositions is always - * U+0DD9. - * - * Now, there are buggy fonts, namely, the widely used lklug.ttf, that are - * broken with Uniscribe. But we need to support them. As such, we only - * do the Uniscribe-style decomposition if the character is transformed into - * its "sec.half" form by the 'pstf' feature. Otherwise, we fall back to - * Unicode decomposition. - * - * Note that we can't unconditionally use Unicode decomposition. That would - * break some other fonts, that are designed to work with Uniscribe, and - * don't have positioning features for the Unicode-style decomposition. - * - * Argh... - * - * The Uniscribe behavior is now documented in the newly published Sinhala - * spec in 2012: - * - * https://docs.microsoft.com/en-us/typography/script-development/sinhala#shaping - */ - - - const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data; - hb_codepoint_t glyph; - if (indic_plan->uniscribe_bug_compatible || - (c->font->get_nominal_glyph (ab, &glyph) && - indic_plan->pstf.would_substitute (&glyph, 1, c->font->face))) - { - /* Ok, safe to use Uniscribe-style decomposition. */ - *a = 0x0DD9u; - *b = ab; - return true; - } - } - return (bool) c->unicode->decompose (ab, a, b); } @@ -1548,7 +1520,7 @@ compose_indic (const hb_ot_shape_normalize_context_t *c, } -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic = +const hb_ot_shaper_t _hb_ot_shaper_indic = { collect_features_indic, override_features_indic, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.hh new file mode 100644 index 00000000000..4f822c26e9f --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.hh @@ -0,0 +1,66 @@ +/* + * Copyright © 2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPER_INDIC_HH +#define HB_OT_SHAPER_INDIC_HH + +#include "hb.hh" + +#include "hb-ot-shaper-syllabic.hh" + + +/* Visual positions in a syllable from left to right. */ +enum ot_position_t { + POS_START = 0, + + POS_RA_TO_BECOME_REPH = 1, + POS_PRE_M = 2, + POS_PRE_C = 3, + + POS_BASE_C = 4, + POS_AFTER_MAIN = 5, + + POS_ABOVE_C = 6, + + POS_BEFORE_SUB = 7, + POS_BELOW_C = 8, + POS_AFTER_SUB = 9, + + POS_BEFORE_POST = 10, + POS_POST_C = 11, + POS_AFTER_POST = 12, + + POS_SMVD = 13, + + POS_END = 14 +}; + + +HB_INTERNAL uint16_t +hb_indic_get_categories (hb_codepoint_t u); + + +#endif /* HB_OT_SHAPER_INDIC_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh new file mode 100644 index 00000000000..e18bd75ef1f --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh @@ -0,0 +1,428 @@ + +#line 1 "hb-ot-shaper-khmer-machine.rl" +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPER_KHMER_MACHINE_HH +#define HB_OT_SHAPER_KHMER_MACHINE_HH + +#include "hb.hh" + +#include "hb-ot-layout.hh" +#include "hb-ot-shaper-indic.hh" + +/* buffer var allocations */ +#define khmer_category() ot_shaper_var_u8_category() /* khmer_category_t */ + +using khmer_category_t = unsigned; + +#define K_Cat(Cat) khmer_syllable_machine_ex_##Cat + +enum khmer_syllable_type_t { + khmer_consonant_syllable, + khmer_broken_cluster, + khmer_non_khmer_cluster, +}; + + +#line 52 "hb-ot-shaper-khmer-machine.hh" +#define khmer_syllable_machine_ex_C 1u +#define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u +#define khmer_syllable_machine_ex_H 4u +#define khmer_syllable_machine_ex_PLACEHOLDER 10u +#define khmer_syllable_machine_ex_Ra 15u +#define khmer_syllable_machine_ex_Robatic 25u +#define khmer_syllable_machine_ex_V 2u +#define khmer_syllable_machine_ex_VAbv 20u +#define khmer_syllable_machine_ex_VBlw 21u +#define khmer_syllable_machine_ex_VPre 22u +#define khmer_syllable_machine_ex_VPst 23u +#define khmer_syllable_machine_ex_Xgroup 26u +#define khmer_syllable_machine_ex_Ygroup 27u +#define khmer_syllable_machine_ex_ZWJ 6u +#define khmer_syllable_machine_ex_ZWNJ 5u + + +#line 70 "hb-ot-shaper-khmer-machine.hh" +static const unsigned char _khmer_syllable_machine_trans_keys[] = { + 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, + 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, + 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 27u, 4u, 27u, 1u, 15u, + 4u, 27u, 4u, 27u, 27u, 27u, 4u, 27u, 4u, 27u, 4u, 27u, 4u, 27u, 4u, 27u, + 4u, 27u, 1u, 15u, 4u, 27u, 4u, 27u, 27u, 27u, 4u, 27u, 4u, 27u, 4u, 27u, + 4u, 27u, 4u, 27u, 5u, 26u, 0 +}; + +static const char _khmer_syllable_machine_key_spans[] = { + 22, 22, 15, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 15, 22, 22, + 22, 22, 22, 22, 22, 27, 24, 15, + 24, 24, 1, 24, 24, 24, 24, 24, + 24, 15, 24, 24, 1, 24, 24, 24, + 24, 24, 22 +}; + +static const short _khmer_syllable_machine_index_offsets[] = { + 0, 23, 46, 62, 85, 108, 131, 154, + 177, 200, 223, 246, 269, 292, 308, 331, + 354, 377, 400, 423, 446, 469, 497, 522, + 538, 563, 588, 590, 615, 640, 665, 690, + 715, 740, 756, 781, 806, 808, 833, 858, + 883, 908, 933 +}; + +static const char _khmer_syllable_machine_indicies[] = { + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 3, 4, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 4, 0, 6, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 0, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, + 10, 0, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, + 0, 11, 11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 12, 0, + 11, 11, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 13, 4, 0, 15, 15, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 16, 14, 14, + 14, 14, 17, 18, 14, 15, 15, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 18, 19, 20, 20, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 20, 14, 15, 15, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 16, 14, 14, 14, 14, + 14, 18, 14, 21, 21, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 16, 14, 22, 22, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 23, + 14, 24, 24, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 16, 14, 14, 14, 14, 14, 25, 14, + 24, 24, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 25, 14, 26, + 26, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 16, 14, + 14, 14, 14, 14, 27, 14, 26, 26, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 27, 14, 29, 29, 28, + 30, 31, 31, 28, 28, 28, 13, 13, + 28, 28, 28, 29, 28, 28, 28, 28, + 16, 25, 27, 23, 28, 17, 18, 20, + 28, 33, 34, 34, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 2, 10, 12, 8, 32, 13, 4, + 5, 32, 35, 35, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 35, 32, 33, 36, 36, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 2, 10, 12, 8, 32, 3, + 4, 5, 32, 37, 38, 38, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 2, 10, 12, 8, 32, + 32, 4, 5, 32, 5, 32, 37, 6, + 6, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 8, 32, 32, 2, 5, 32, 37, + 7, 7, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 8, 5, 32, + 37, 39, 39, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 2, 32, 32, 8, 32, 32, 10, 5, + 32, 37, 40, 40, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 2, 10, 32, 8, 32, 32, 12, + 5, 32, 33, 38, 38, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 2, 10, 12, 8, 32, 32, + 4, 5, 32, 33, 38, 38, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 2, 10, 12, 8, 32, + 3, 4, 5, 32, 42, 42, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 42, 41, 30, 43, 43, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 16, 25, 27, 23, + 41, 17, 18, 20, 41, 44, 45, 45, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 16, 25, 27, + 23, 41, 41, 18, 20, 41, 20, 41, + 44, 21, 21, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 23, 41, 41, 16, 20, + 41, 44, 22, 22, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 23, + 20, 41, 44, 46, 46, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 16, 41, 41, 23, 41, 41, + 25, 20, 41, 44, 47, 47, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 16, 25, 41, 23, 41, + 41, 27, 20, 41, 30, 45, 45, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 16, 25, 27, 23, + 41, 41, 18, 20, 41, 15, 15, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 16, 48, 48, 48, + 48, 48, 18, 48, 0 +}; + +static const char _khmer_syllable_machine_trans_targs[] = { + 21, 1, 27, 31, 25, 26, 4, 5, + 28, 7, 29, 9, 30, 32, 21, 12, + 37, 41, 35, 21, 36, 15, 16, 38, + 18, 39, 20, 40, 21, 22, 33, 42, + 21, 23, 10, 24, 0, 2, 3, 6, + 8, 21, 34, 11, 13, 14, 17, 19, + 21 +}; + +static const char _khmer_syllable_machine_trans_actions[] = { + 1, 0, 2, 2, 2, 0, 0, 0, + 2, 0, 2, 0, 2, 2, 3, 0, + 2, 4, 4, 5, 0, 0, 0, 2, + 0, 2, 0, 2, 8, 2, 0, 9, + 10, 0, 0, 2, 0, 0, 0, 0, + 0, 11, 4, 0, 0, 0, 0, 0, + 12 +}; + +static const char _khmer_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, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +static const char _khmer_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, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +static const short _khmer_syllable_machine_eof_trans[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 15, 20, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 49 +}; + +static const int khmer_syllable_machine_start = 21; +static const int khmer_syllable_machine_first_final = 21; +static const int khmer_syllable_machine_error = -1; + +static const int khmer_syllable_machine_en_main = 21; + + +#line 53 "hb-ot-shaper-khmer-machine.rl" + + + +#line 102 "hb-ot-shaper-khmer-machine.rl" + + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +inline void +find_syllables_khmer (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts, te, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + +#line 298 "hb-ot-shaper-khmer-machine.hh" + { + cs = khmer_syllable_machine_start; + ts = 0; + te = 0; + act = 0; + } + +#line 122 "hb-ot-shaper-khmer-machine.rl" + + + p = 0; + pe = eof = buffer->len; + + unsigned int syllable_serial = 1; + +#line 314 "hb-ot-shaper-khmer-machine.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; +_resume: + switch ( _khmer_syllable_machine_from_state_actions[cs] ) { + case 7: +#line 1 "NONE" + {ts = p;} + break; +#line 328 "hb-ot-shaper-khmer-machine.hh" + } + + _keys = _khmer_syllable_machine_trans_keys + (cs<<1); + _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs]; + + _slen = _khmer_syllable_machine_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) && + ( info[p].khmer_category()) <= _keys[1] ? + ( info[p].khmer_category()) - _keys[0] : _slen ]; + +_eof_trans: + cs = _khmer_syllable_machine_trans_targs[_trans]; + + if ( _khmer_syllable_machine_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _khmer_syllable_machine_trans_actions[_trans] ) { + case 2: +#line 1 "NONE" + {te = p+1;} + break; + case 8: +#line 98 "hb-ot-shaper-khmer-machine.rl" + {te = p+1;{ found_syllable (khmer_non_khmer_cluster); }} + break; + case 10: +#line 96 "hb-ot-shaper-khmer-machine.rl" + {te = p;p--;{ found_syllable (khmer_consonant_syllable); }} + break; + case 11: +#line 97 "hb-ot-shaper-khmer-machine.rl" + {te = p;p--;{ found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} + break; + case 12: +#line 98 "hb-ot-shaper-khmer-machine.rl" + {te = p;p--;{ found_syllable (khmer_non_khmer_cluster); }} + break; + case 1: +#line 96 "hb-ot-shaper-khmer-machine.rl" + {{p = ((te))-1;}{ found_syllable (khmer_consonant_syllable); }} + break; + case 3: +#line 97 "hb-ot-shaper-khmer-machine.rl" + {{p = ((te))-1;}{ found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} + break; + case 5: +#line 1 "NONE" + { switch( act ) { + case 2: + {{p = ((te))-1;} found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + case 3: + {{p = ((te))-1;} found_syllable (khmer_non_khmer_cluster); } + break; + } + } + break; + case 4: +#line 1 "NONE" + {te = p+1;} +#line 97 "hb-ot-shaper-khmer-machine.rl" + {act = 2;} + break; + case 9: +#line 1 "NONE" + {te = p+1;} +#line 98 "hb-ot-shaper-khmer-machine.rl" + {act = 3;} + break; +#line 398 "hb-ot-shaper-khmer-machine.hh" + } + +_again: + switch ( _khmer_syllable_machine_to_state_actions[cs] ) { + case 6: +#line 1 "NONE" + {ts = 0;} + break; +#line 407 "hb-ot-shaper-khmer-machine.hh" + } + + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { + _trans = _khmer_syllable_machine_eof_trans[cs] - 1; + goto _eof_trans; + } + } + + } + +#line 130 "hb-ot-shaper-khmer-machine.rl" + +} + +#undef found_syllable + +#endif /* HB_OT_SHAPER_KHMER_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl index c9cf33f41da..f180471bb5a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl @@ -24,11 +24,21 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH +#ifndef HB_OT_SHAPER_KHMER_MACHINE_HH +#define HB_OT_SHAPER_KHMER_MACHINE_HH #include "hb.hh" +#include "hb-ot-layout.hh" +#include "hb-ot-shaper-indic.hh" + +/* buffer var allocations */ +#define khmer_category() ot_shaper_var_u8_category() /* khmer_category_t */ + +using khmer_category_t = unsigned; + +#define K_Cat(Cat) khmer_syllable_machine_ex_##Cat + enum khmer_syllable_type_t { khmer_consonant_syllable, khmer_broken_cluster, @@ -44,21 +54,27 @@ enum khmer_syllable_type_t { %%{ + +# We use category H for spec category Coeng + export C = 1; export V = 2; +export H = 4; export ZWNJ = 5; export ZWJ = 6; -export PLACEHOLDER = 11; -export DOTTEDCIRCLE = 12; -export Coeng= 14; -export Ra = 16; -export Robatic = 20; -export Xgroup = 21; -export Ygroup = 22; -export VAbv = 26; -export VBlw = 27; -export VPre = 28; -export VPst = 29; +export PLACEHOLDER = 10; +export DOTTEDCIRCLE = 11; +export Ra = 15; + +export VAbv = 20; +export VBlw = 21; +export VPre = 22; +export VPst = 23; + +export Robatic = 25; +export Xgroup = 26; +export Ygroup = 27; + c = (C | Ra | V); cn = c.((ZWJ|ZWNJ)?.Robatic)?; @@ -69,16 +85,16 @@ ygroup = Ygroup*; # This grammar was experimentally extracted from what Uniscribe allows. matra_group = VPre? xgroup VBlw? xgroup (joiner?.VAbv)? xgroup VPst?; -syllable_tail = xgroup matra_group xgroup (Coeng.c)? ygroup; +syllable_tail = xgroup matra_group xgroup (H.c)? ygroup; -broken_cluster = (Coeng.cn)* (Coeng | syllable_tail); +broken_cluster = Robatic? (H.cn)* (H | syllable_tail); consonant_syllable = (cn|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster; other = any; main := |* consonant_syllable => { found_syllable (khmer_consonant_syllable); }; - broken_cluster => { found_syllable (khmer_broken_cluster); }; + broken_cluster => { found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }; other => { found_syllable (khmer_non_khmer_cluster); }; *|; @@ -94,7 +110,7 @@ main := |* if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END -static void +inline void find_syllables_khmer (hb_buffer_t *buffer) { unsigned int p, pe, eof, ts, te, act HB_UNUSED; @@ -116,4 +132,4 @@ find_syllables_khmer (hb_buffer_t *buffer) #undef found_syllable -#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */ +#endif /* HB_OT_SHAPER_KHMER_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer.cc index a7d5bf574b6..e04d6331958 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer.cc @@ -28,8 +28,8 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-khmer.hh" -#include "hb-ot-shape-complex-khmer-machine.hh" +#include "hb-ot-shaper-khmer-machine.hh" +#include "hb-ot-shaper-indic.hh" #include "hb-ot-layout.hh" @@ -37,6 +37,7 @@ * Khmer shaper. */ + static const hb_ot_map_feature_t khmer_features[] = { @@ -79,6 +80,15 @@ enum { KHMER_BASIC_FEATURES = _KHMER_PRES, /* Don't forget to update this! */ }; +static inline void +set_khmer_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + + info.khmer_category() = (khmer_category_t) (type & 0xFFu); +} + static void setup_syllables_khmer (const hb_ot_shape_plan_t *plan, hb_font_t *font, @@ -115,7 +125,7 @@ collect_features_khmer (hb_ot_shape_planner_t *plan) map->add_feature (khmer_features[i]); /* https://github.com/harfbuzz/harfbuzz/issues/3531 */ - map->add_gsub_pause (nullptr); + map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var for (; i < KHMER_NUM_FEATURES; i++) map->add_feature (khmer_features[i]); @@ -187,6 +197,7 @@ setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { + HB_BUFFER_ALLOCATE_VAR (buffer, syllable); find_syllables_khmer (buffer); foreach_syllable (buffer, start, end) buffer->unsafe_to_break (start, end); @@ -230,11 +241,11 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan, * the 'pref' OpenType feature applied to them. * """ */ - if (info[i].khmer_category() == OT_Coeng && num_coengs <= 2 && i + 1 < end) + if (info[i].khmer_category() == K_Cat(H) && num_coengs <= 2 && i + 1 < end) { num_coengs++; - if (info[i + 1].khmer_category() == OT_Ra) + if (info[i + 1].khmer_category() == K_Cat(Ra)) { for (unsigned int j = 0; j < 2; j++) info[i + j].mask |= khmer_plan->mask_array[KHMER_PREF]; @@ -262,7 +273,7 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan, } /* Reorder left matra piece. */ - else if (info[i].khmer_category() == OT_VPre) + else if (info[i].khmer_category() == K_Cat(VPre)) { /* Move to the start. */ buffer->merge_clusters (start, i + 1); @@ -301,8 +312,8 @@ reorder_khmer (const hb_ot_shape_plan_t *plan, { hb_syllabic_insert_dotted_circles (font, buffer, khmer_broken_cluster, - OT_DOTTEDCIRCLE, - OT_Repha); + K_Cat(DOTTEDCIRCLE), + (unsigned) -1); foreach_syllable (buffer, start, end) reorder_syllable_khmer (plan, font->face, buffer, start, end); @@ -349,7 +360,7 @@ compose_khmer (const hb_ot_shape_normalize_context_t *c, } -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_khmer = +const hb_ot_shaper_t _hb_ot_shaper_khmer = { collect_features_khmer, override_features_khmer, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh new file mode 100644 index 00000000000..b109708937b --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh @@ -0,0 +1,553 @@ + +#line 1 "hb-ot-shaper-myanmar-machine.rl" +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPER_MYANMAR_MACHINE_HH +#define HB_OT_SHAPER_MYANMAR_MACHINE_HH + +#include "hb.hh" + +#include "hb-ot-layout.hh" +#include "hb-ot-shaper-indic.hh" + +/* buffer var allocations */ +#define myanmar_category() ot_shaper_var_u8_category() /* myanmar_category_t */ +#define myanmar_position() ot_shaper_var_u8_auxiliary() /* myanmar_position_t */ + +using myanmar_category_t = unsigned; +using myanmar_position_t = ot_position_t; + +#define M_Cat(Cat) myanmar_syllable_machine_ex_##Cat + +enum myanmar_syllable_type_t { + myanmar_consonant_syllable, + myanmar_broken_cluster, + myanmar_non_myanmar_cluster, +}; + + +#line 54 "hb-ot-shaper-myanmar-machine.hh" +#define myanmar_syllable_machine_ex_A 9u +#define myanmar_syllable_machine_ex_As 32u +#define myanmar_syllable_machine_ex_C 1u +#define myanmar_syllable_machine_ex_CS 18u +#define myanmar_syllable_machine_ex_DB 3u +#define myanmar_syllable_machine_ex_DOTTEDCIRCLE 11u +#define myanmar_syllable_machine_ex_GB 10u +#define myanmar_syllable_machine_ex_H 4u +#define myanmar_syllable_machine_ex_IV 2u +#define myanmar_syllable_machine_ex_MH 35u +#define myanmar_syllable_machine_ex_ML 41u +#define myanmar_syllable_machine_ex_MR 36u +#define myanmar_syllable_machine_ex_MW 37u +#define myanmar_syllable_machine_ex_MY 38u +#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_VAbv 20u +#define myanmar_syllable_machine_ex_VBlw 21u +#define myanmar_syllable_machine_ex_VPre 22u +#define myanmar_syllable_machine_ex_VPst 23u +#define myanmar_syllable_machine_ex_VS 40u +#define myanmar_syllable_machine_ex_ZWJ 6u +#define myanmar_syllable_machine_ex_ZWNJ 5u + + +#line 81 "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 +}; + +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 +}; + +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 +}; + +static const char _myanmar_syllable_machine_indicies[] = { + 1, 1, 2, 3, 4, 4, 0, 5, + 6, 1, 1, 0, 0, 0, 7, 0, + 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, + 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, 48, 48, 47, 5, 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, 52, + 47, 47, 47, 18, 47, 51, 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, 53, 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, 54, 47, 47, 47, 47, 47, + 47, 18, 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, 54, 47, + 47, 47, 47, 47, 47, 18, 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, 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, + 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, 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, + 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, 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, 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, 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, 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, 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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 +}; + +static const char _myanmar_syllable_machine_trans_actions[] = { + 3, 0, 0, 0, 4, 0, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9 +}; + +static const char _myanmar_syllable_machine_to_state_actions[] = { + 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, 0, 0, 0, 0, 0, 0 +}; + +static const char _myanmar_syllable_machine_from_state_actions[] = { + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 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, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 22, 22, 48, 61 +}; + +static const int myanmar_syllable_machine_start = 0; +static const int myanmar_syllable_machine_first_final = 0; +static const int myanmar_syllable_machine_error = -1; + +static const int myanmar_syllable_machine_en_main = 0; + + +#line 55 "hb-ot-shaper-myanmar-machine.rl" + + + +#line 117 "hb-ot-shaper-myanmar-machine.rl" + + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +inline void +find_syllables_myanmar (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts, te, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + +#line 447 "hb-ot-shaper-myanmar-machine.hh" + { + cs = myanmar_syllable_machine_start; + ts = 0; + te = 0; + act = 0; + } + +#line 137 "hb-ot-shaper-myanmar-machine.rl" + + + p = 0; + pe = eof = buffer->len; + + unsigned int syllable_serial = 1; + +#line 463 "hb-ot-shaper-myanmar-machine.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; +_resume: + switch ( _myanmar_syllable_machine_from_state_actions[cs] ) { + case 2: +#line 1 "NONE" + {ts = p;} + break; +#line 477 "hb-ot-shaper-myanmar-machine.hh" + } + + _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); + _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs]; + + _slen = _myanmar_syllable_machine_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) && + ( info[p].myanmar_category()) <= _keys[1] ? + ( info[p].myanmar_category()) - _keys[0] : _slen ]; + +_eof_trans: + cs = _myanmar_syllable_machine_trans_targs[_trans]; + + if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { + case 6: +#line 110 "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" + {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} + break; + case 8: +#line 112 "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" + {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; }} + break; + case 9: +#line 113 "hb-ot-shaper-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} + break; +#line 523 "hb-ot-shaper-myanmar-machine.hh" + } + +_again: + switch ( _myanmar_syllable_machine_to_state_actions[cs] ) { + case 1: +#line 1 "NONE" + {ts = 0;} + break; +#line 532 "hb-ot-shaper-myanmar-machine.hh" + } + + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) { + _trans = _myanmar_syllable_machine_eof_trans[cs] - 1; + goto _eof_trans; + } + } + + } + +#line 145 "hb-ot-shaper-myanmar-machine.rl" + +} + +#undef found_syllable + +#endif /* HB_OT_SHAPER_MYANMAR_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl index 2e6ac783f6a..2cb6e4e7720 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl @@ -24,14 +24,25 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH +#ifndef HB_OT_SHAPER_MYANMAR_MACHINE_HH +#define HB_OT_SHAPER_MYANMAR_MACHINE_HH #include "hb.hh" +#include "hb-ot-layout.hh" +#include "hb-ot-shaper-indic.hh" + +/* buffer var allocations */ +#define myanmar_category() ot_shaper_var_u8_category() /* myanmar_category_t */ +#define myanmar_position() ot_shaper_var_u8_auxiliary() /* myanmar_position_t */ + +using myanmar_category_t = unsigned; +using myanmar_position_t = ot_position_t; + +#define M_Cat(Cat) myanmar_syllable_machine_ex_##Cat + enum myanmar_syllable_type_t { myanmar_consonant_syllable, - myanmar_punctuation_cluster, myanmar_broken_cluster, myanmar_non_myanmar_cluster, }; @@ -45,32 +56,38 @@ enum myanmar_syllable_type_t { %%{ -export A = 10; -export As = 18; + +# Spec category D is folded into GB; D0 is not implemented by Uniscribe and as such folded into D +# Spec category P is folded into GB + export C = 1; -export D = 32; -export D0 = 20; -export DB = 3; -export GB = 11; -export H = 4; export IV = 2; -export MH = 21; -export ML = 33; -export MR = 22; -export MW = 23; -export MY = 24; -export PT = 25; -export V = 8; -export VAbv = 26; -export VBlw = 27; -export VPre = 28; -export VPst = 29; -export VS = 30; -export ZWJ = 6; +export DB = 3; # Dot below = OT_N +export H = 4; export ZWNJ = 5; -export Ra = 16; -export P = 31; -export CS = 19; +export ZWJ = 6; +export SM = 8; # Visarga and Shan tones +export GB = 10; # = OT_PLACEHOLDER +export DOTTEDCIRCLE = 11; +export A = 9; +export Ra = 15; +export CS = 18; + +export VAbv = 20; +export VBlw = 21; +export VPre = 22; +export VPst = 23; + +# 32+ are for Myanmar-specific values +export As = 32; # Asat +export MH = 35; # Medial Ha +export MR = 36; # Medial Ra +export MW = 37; # Medial Wa, Shan Wa +export MY = 38; # Medial Ya, Mon Na, Mon Ma +export PT = 39; # Pwo and other tones +export VS = 40; # Variation selectors +export ML = 41; # Medial Mon La + j = ZWJ|ZWNJ; # Joiners k = (Ra As H); # Kinzi @@ -82,19 +99,17 @@ main_vowel_group = (VPre.VS?)* VAbv* VBlw* A* (DB As?)?; post_vowel_group = VPst MH? ML? As* VAbv* A* (DB As?)?; pwo_tone_group = PT A* DB? As?; -complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?; +complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* SM* j?; syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail); -consonant_syllable = (k|CS)? (c|IV|D|GB).VS? syllable_tail; -punctuation_cluster = P V; +consonant_syllable = (k|CS)? (c|IV|GB|DOTTEDCIRCLE).VS? syllable_tail; broken_cluster = k? VS? syllable_tail; other = any; main := |* consonant_syllable => { found_syllable (myanmar_consonant_syllable); }; j => { found_syllable (myanmar_non_myanmar_cluster); }; - punctuation_cluster => { found_syllable (myanmar_punctuation_cluster); }; - broken_cluster => { found_syllable (myanmar_broken_cluster); }; + broken_cluster => { found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }; other => { found_syllable (myanmar_non_myanmar_cluster); }; *|; @@ -110,7 +125,7 @@ main := |* if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END -static void +inline void find_syllables_myanmar (hb_buffer_t *buffer) { unsigned int p, pe, eof, ts, te, act HB_UNUSED; @@ -132,4 +147,4 @@ find_syllables_myanmar (hb_buffer_t *buffer) #undef found_syllable -#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */ +#endif /* HB_OT_SHAPER_MYANMAR_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar.cc index 13beaf4d4ce..1ccafbca7e7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar.cc @@ -28,14 +28,16 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-myanmar.hh" -#include "hb-ot-shape-complex-myanmar-machine.hh" +#include "hb-ot-shaper-myanmar-machine.hh" +#include "hb-ot-shaper-indic.hh" +#include "hb-ot-layout.hh" /* * Myanmar shaper. */ + static const hb_tag_t myanmar_basic_features[] = { @@ -62,6 +64,40 @@ myanmar_other_features[] = HB_TAG('p','s','t','s'), }; +static inline void +set_myanmar_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + + info.myanmar_category() = (myanmar_category_t) (type & 0xFFu); +} + + +static inline bool +is_one_of_myanmar (const hb_glyph_info_t &info, unsigned int flags) +{ + /* If it ligated, all bets are off. */ + if (_hb_glyph_info_ligated (&info)) return false; + return !!(FLAG_UNSAFE (info.myanmar_category()) & flags); +} + +/* Note: + * + * We treat Vowels and placeholders as if they were consonants. This is safe because Vowels + * cannot happen in a consonant syllable. The plus side however is, we can call the + * consonant syllable logic from the vowel syllable function and get it all right! + * + * Keep in sync with consonant_categories in the generator. */ +#define CONSONANT_FLAGS_MYANMAR (FLAG (M_Cat(C)) | FLAG (M_Cat(CS)) | FLAG (M_Cat(Ra)) | /* FLAG (M_Cat(CM)) | */ FLAG (M_Cat(IV)) | FLAG (M_Cat(GB)) | FLAG (M_Cat(DOTTEDCIRCLE))) + +static inline bool +is_consonant_myanmar (const hb_glyph_info_t &info) +{ + return is_one_of_myanmar (info, CONSONANT_FLAGS_MYANMAR); +} + + static void setup_syllables_myanmar (const hb_ot_shape_plan_t *plan, hb_font_t *font, @@ -92,6 +128,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan) map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE); map->add_gsub_pause (nullptr); } + map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_other_features); i++) map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ); @@ -118,6 +155,7 @@ setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { + HB_BUFFER_ALLOCATE_VAR (buffer, syllable); find_syllables_myanmar (buffer); foreach_syllable (buffer, start, end) buffer->unsafe_to_break (start, end); @@ -129,7 +167,7 @@ compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) int a = pa->myanmar_position(); int b = pb->myanmar_position(); - return a < b ? -1 : a == b ? 0 : +1; + return (int) a - (int) b; } @@ -148,9 +186,9 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer, { unsigned int limit = start; if (start + 3 <= end && - info[start ].myanmar_category() == OT_Ra && - info[start+1].myanmar_category() == OT_As && - info[start+2].myanmar_category() == OT_H) + info[start ].myanmar_category() == M_Cat(Ra) && + info[start+1].myanmar_category() == M_Cat(As) && + info[start+2].myanmar_category() == M_Cat(H)) { limit += 3; base = start; @@ -162,7 +200,7 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer, base = limit; for (unsigned int i = limit; i < end; i++) - if (is_consonant (info[i])) + if (is_consonant_myanmar (info[i])) { base = i; break; @@ -187,39 +225,40 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer, * Myanmar reordering! */ for (; i < end; i++) { - if (info[i].myanmar_category() == OT_MR) /* Pre-base reordering */ + if (info[i].myanmar_category() == M_Cat(MR)) /* Pre-base reordering */ { info[i].myanmar_position() = POS_PRE_C; continue; } - if (info[i].myanmar_position() < POS_BASE_C) /* Left matra */ + if (info[i].myanmar_category() == M_Cat(VPre)) /* Left matra */ { + info[i].myanmar_position() = POS_PRE_M; continue; } - if (info[i].myanmar_category() == OT_VS) + if (info[i].myanmar_category() == M_Cat(VS)) { info[i].myanmar_position() = info[i - 1].myanmar_position(); continue; } - if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == OT_VBlw) + if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == M_Cat(VBlw)) { pos = POS_BELOW_C; info[i].myanmar_position() = pos; continue; } - if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_A) + if (pos == POS_BELOW_C && info[i].myanmar_category() == M_Cat(A)) { info[i].myanmar_position() = POS_BEFORE_SUB; continue; } - if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_VBlw) + if (pos == POS_BELOW_C && info[i].myanmar_category() == M_Cat(VBlw)) { info[i].myanmar_position() = pos; continue; } - if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A) + if (pos == POS_BELOW_C && info[i].myanmar_category() != M_Cat(A)) { pos = POS_AFTER_SUB; info[i].myanmar_position() = pos; @@ -247,7 +286,6 @@ reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, initial_reordering_consonant_syllable (buffer, start, end); break; - case myanmar_punctuation_cluster: case myanmar_non_myanmar_cluster: break; } @@ -262,7 +300,7 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan, { hb_syllabic_insert_dotted_circles (font, buffer, myanmar_broken_cluster, - OT_GB); + M_Cat(DOTTEDCIRCLE)); foreach_syllable (buffer, start, end) reorder_syllable_myanmar (plan, font->face, buffer, start, end); @@ -274,7 +312,7 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan, } -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = +const hb_ot_shaper_t _hb_ot_shaper_myanmar = { collect_features_myanmar, nullptr, /* override_features */ @@ -296,7 +334,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = /* Ugly Zawgyi encoding. * Disable all auto processing. * https://github.com/harfbuzz/harfbuzz/issues/1162 */ -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_zawgyi = +const hb_ot_shaper_t _hb_ot_shaper_myanmar_zawgyi = { nullptr, /* collect_features */ nullptr, /* override_features */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-syllabic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.cc index 76092c7f38e..a8e0d8e8c1e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-syllabic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.cc @@ -26,7 +26,7 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-syllabic.hh" +#include "hb-ot-shaper-syllabic.hh" void @@ -39,31 +39,18 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, { if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == broken_syllable_type) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) + if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE))) return; - hb_codepoint_t dottedcircle_glyph; if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) return; hb_glyph_info_t dottedcircle = {0}; dottedcircle.codepoint = 0x25CCu; - dottedcircle.complex_var_u8_category() = dottedcircle_category; + dottedcircle.ot_shaper_var_u8_category() = dottedcircle_category; if (dottedcircle_position != -1) - dottedcircle.complex_var_u8_auxiliary() = dottedcircle_position; + dottedcircle.ot_shaper_var_u8_auxiliary() = dottedcircle_position; dottedcircle.codepoint = dottedcircle_glyph; buffer->clear_output (); @@ -87,7 +74,7 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, { while (buffer->idx < buffer->len && buffer->successful && last_syllable == buffer->cur().syllable() && - buffer->cur().complex_var_u8_category() == (unsigned) repha_category) + buffer->cur().ot_shaper_var_u8_category() == (unsigned) repha_category) (void) buffer->next_glyph (); } @@ -99,5 +86,13 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, buffer->sync (); } +HB_INTERNAL void +hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); +} + #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-syllabic.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.hh index b901a660d36..e8a15bb48ac 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-syllabic.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.hh @@ -22,12 +22,12 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_OT_SHAPE_COMPLEX_SYLLABIC_HH -#define HB_OT_SHAPE_COMPLEX_SYLLABIC_HH +#ifndef HB_OT_SHAPER_SYLLABIC_HH +#define HB_OT_SHAPER_SYLLABIC_HH #include "hb.hh" -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" HB_INTERNAL void @@ -38,5 +38,10 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font, int repha_category = -1, int dottedcircle_position = -1); +HB_INTERNAL void +hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + -#endif /* HB_OT_SHAPE_COMPLEX_SYLLABIC_HH */ +#endif /* HB_OT_SHAPER_SYLLABIC_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc index a1e27a83be9..1280e7ed17b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc @@ -28,7 +28,7 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" /* Thai / Lao shaper */ @@ -222,7 +222,7 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, hb_font_t *font) { -#ifdef HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK +#ifdef HB_NO_OT_SHAPER_THAI_FALLBACK return; #endif @@ -279,7 +279,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, * to be what Uniscribe and other engines implement. According to Eric Muller: * * When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the - * NIKHAHIT backwards over any tone mark (0E48-0E4B). + * NIKHAHIT backwards over any above-base marks. * * <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32> * @@ -308,8 +308,8 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, * Nikhahit: U+0E4D U+0ECD * * Testing shows that Uniscribe reorder the following marks: - * Thai: <0E31,0E34..0E37,0E47..0E4E> - * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE> + * Thai: <0E31,0E34..0E37, 0E47..0E4E> + * Lao: <0EB1,0EB4..0EB7,0EBB,0EC8..0ECD> * * Note how the Lao versions are the same as Thai + 0x80. */ @@ -319,7 +319,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, #define IS_SARA_AM(x) (((x) & ~0x0080u) == 0x0E33u) #define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0x0E33u + 0x0E4Du) #define SARA_AA_FROM_SARA_AM(x) ((x) - 1) -#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u)) +#define IS_ABOVE_BASE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u, 0x0E3Bu, 0x0E3Bu)) buffer->clear_output (); unsigned int count = buffer->len; @@ -343,7 +343,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, /* Ok, let's see... */ unsigned int start = end - 2; - while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint)) + while (start > 0 && IS_ABOVE_BASE_MARK (buffer->out_info[start - 1].codepoint)) start--; if (start + 2 < end) @@ -371,7 +371,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, do_thai_pua_shaping (plan, buffer, font); } -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai = +const hb_ot_shaper_t _hb_ot_shaper_thai = { nullptr, /* collect_features */ nullptr, /* override_features */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh new file mode 100644 index 00000000000..65e65ff39d0 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh @@ -0,0 +1,931 @@ + +#line 1 "hb-ot-shaper-use-machine.rl" +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPER_USE_MACHINE_HH +#define HB_OT_SHAPER_USE_MACHINE_HH + +#include "hb.hh" + +#include "hb-ot-shaper-syllabic.hh" + +/* buffer var allocations */ +#define use_category() ot_shaper_var_u8_category() + +#define USE(Cat) use_syllable_machine_ex_##Cat + +enum use_syllable_type_t { + use_virama_terminated_cluster, + use_sakot_terminated_cluster, + use_standard_cluster, + use_number_joiner_terminated_cluster, + use_numeral_cluster, + use_symbol_cluster, + use_hieroglyph_cluster, + use_broken_cluster, + use_non_cluster, +}; + + +#line 57 "hb-ot-shaper-use-machine.hh" +#define use_syllable_machine_ex_B 1u +#define use_syllable_machine_ex_CGJ 6u +#define use_syllable_machine_ex_CMAbv 31u +#define use_syllable_machine_ex_CMBlw 32u +#define use_syllable_machine_ex_CS 43u +#define use_syllable_machine_ex_FAbv 24u +#define use_syllable_machine_ex_FBlw 25u +#define use_syllable_machine_ex_FMAbv 45u +#define use_syllable_machine_ex_FMBlw 46u +#define use_syllable_machine_ex_FMPst 47u +#define use_syllable_machine_ex_FPst 26u +#define use_syllable_machine_ex_G 49u +#define use_syllable_machine_ex_GB 5u +#define use_syllable_machine_ex_H 12u +#define use_syllable_machine_ex_HN 13u +#define use_syllable_machine_ex_HVM 53u +#define use_syllable_machine_ex_IS 44u +#define use_syllable_machine_ex_J 50u +#define use_syllable_machine_ex_MAbv 27u +#define use_syllable_machine_ex_MBlw 28u +#define use_syllable_machine_ex_MPre 30u +#define use_syllable_machine_ex_MPst 29u +#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_SB 51u +#define use_syllable_machine_ex_SE 52u +#define use_syllable_machine_ex_SMAbv 41u +#define use_syllable_machine_ex_SMBlw 42u +#define use_syllable_machine_ex_SUB 11u +#define use_syllable_machine_ex_Sk 48u +#define use_syllable_machine_ex_VAbv 33u +#define use_syllable_machine_ex_VBlw 34u +#define use_syllable_machine_ex_VMAbv 37u +#define use_syllable_machine_ex_VMBlw 38u +#define use_syllable_machine_ex_VMPre 23u +#define use_syllable_machine_ex_VMPst 39u +#define use_syllable_machine_ex_VPre 22u +#define use_syllable_machine_ex_VPst 35u +#define use_syllable_machine_ex_WJ 16u +#define use_syllable_machine_ex_ZWNJ 14u + + +#line 101 "hb-ot-shaper-use-machine.hh" +static const unsigned char _use_syllable_machine_trans_keys[] = { + 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, + 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 53u, + 23u, 53u, 23u, 53u, 23u, 53u, 12u, 53u, 23u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, + 11u, 53u, 1u, 1u, 1u, 48u, 11u, 53u, 41u, 42u, 42u, 42u, 11u, 53u, 11u, 53u, + 1u, 53u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, + 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 53u, 23u, 53u, 23u, 53u, 23u, 53u, + 12u, 53u, 23u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 1u, 1u, 48u, + 13u, 13u, 4u, 4u, 11u, 53u, 11u, 53u, 1u, 53u, 23u, 48u, 24u, 47u, 25u, 47u, + 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, + 22u, 53u, 23u, 53u, 23u, 53u, 23u, 53u, 12u, 53u, 23u, 53u, 12u, 53u, 12u, 53u, + 12u, 53u, 11u, 53u, 1u, 1u, 1u, 48u, 11u, 53u, 11u, 53u, 1u, 53u, 23u, 48u, + 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, + 1u, 1u, 24u, 48u, 22u, 53u, 23u, 53u, 23u, 53u, 23u, 53u, 12u, 53u, 23u, 53u, + 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 1u, 1u, 48u, 4u, 4u, 13u, 13u, + 1u, 53u, 11u, 53u, 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, + 0 +}; + +static const char _use_syllable_machine_key_spans[] = { + 54, 43, 43, 53, 26, 24, 23, 22, + 2, 1, 25, 25, 25, 1, 25, 32, + 31, 31, 31, 42, 31, 42, 42, 42, + 43, 1, 48, 43, 2, 1, 43, 43, + 53, 26, 24, 23, 22, 2, 1, 25, + 25, 25, 1, 25, 32, 31, 31, 31, + 42, 31, 42, 42, 42, 43, 1, 48, + 1, 1, 43, 43, 53, 26, 24, 23, + 22, 2, 1, 25, 25, 25, 1, 25, + 32, 31, 31, 31, 42, 31, 42, 42, + 42, 43, 1, 48, 43, 43, 53, 26, + 24, 23, 22, 2, 1, 25, 25, 25, + 1, 25, 32, 31, 31, 31, 42, 31, + 42, 42, 42, 43, 1, 48, 1, 1, + 53, 43, 2, 1, 5, 3, 4, 3 +}; + +static const short _use_syllable_machine_index_offsets[] = { + 0, 55, 99, 143, 197, 224, 249, 273, + 296, 299, 301, 327, 353, 379, 381, 407, + 440, 472, 504, 536, 579, 611, 654, 697, + 740, 784, 786, 835, 879, 882, 884, 928, + 972, 1026, 1053, 1078, 1102, 1125, 1128, 1130, + 1156, 1182, 1208, 1210, 1236, 1269, 1301, 1333, + 1365, 1408, 1440, 1483, 1526, 1569, 1613, 1615, + 1664, 1666, 1668, 1712, 1756, 1810, 1837, 1862, + 1886, 1909, 1912, 1914, 1940, 1966, 1992, 1994, + 2020, 2053, 2085, 2117, 2149, 2192, 2224, 2267, + 2310, 2353, 2397, 2399, 2448, 2492, 2536, 2590, + 2617, 2642, 2666, 2689, 2692, 2694, 2720, 2746, + 2772, 2774, 2800, 2833, 2865, 2897, 2929, 2972, + 3004, 3047, 3090, 3133, 3177, 3179, 3228, 3230, + 3232, 3286, 3330, 3333, 3335, 3341, 3345, 3350 +}; + +static const unsigned char _use_syllable_machine_indicies[] = { + 0, 1, 2, 2, 3, 4, 2, 2, + 2, 2, 2, 5, 6, 7, 2, 2, + 2, 2, 8, 2, 2, 2, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 2, 23, 24, 25, + 2, 26, 27, 28, 29, 30, 31, 32, + 29, 33, 2, 34, 2, 35, 2, 37, + 38, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, + 36, 53, 54, 55, 36, 56, 57, 36, + 58, 59, 60, 61, 58, 36, 36, 36, + 36, 62, 36, 37, 38, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 49, + 49, 50, 51, 52, 36, 53, 54, 55, + 36, 36, 36, 36, 58, 59, 60, 61, + 58, 36, 36, 36, 36, 62, 36, 37, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 40, 41, 42, + 43, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 53, 54, 55, 36, 36, + 36, 36, 36, 59, 60, 61, 63, 36, + 36, 36, 36, 40, 36, 40, 41, 42, + 43, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 53, 54, 55, 36, 36, + 36, 36, 36, 59, 60, 61, 63, 36, + 41, 42, 43, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 59, 60, 61, + 36, 42, 43, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 59, 60, 61, + 36, 43, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 59, 60, 61, 36, + 59, 60, 36, 60, 36, 41, 42, 43, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 53, 54, 55, 36, 36, 36, + 36, 36, 59, 60, 61, 63, 36, 41, + 42, 43, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 54, 55, 36, + 36, 36, 36, 36, 59, 60, 61, 63, + 36, 41, 42, 43, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 55, 36, 36, 36, 36, 36, 59, 60, + 61, 63, 36, 64, 36, 41, 42, 43, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 59, 60, 61, 63, 36, 39, + 40, 41, 42, 43, 36, 36, 36, 36, + 36, 36, 50, 51, 52, 36, 53, 54, + 55, 36, 36, 36, 36, 36, 59, 60, + 61, 63, 36, 36, 36, 36, 40, 36, + 40, 41, 42, 43, 36, 36, 36, 36, + 36, 36, 50, 51, 52, 36, 53, 54, + 55, 36, 36, 36, 36, 36, 59, 60, + 61, 63, 36, 36, 36, 36, 40, 36, + 40, 41, 42, 43, 36, 36, 36, 36, + 36, 36, 36, 51, 52, 36, 53, 54, + 55, 36, 36, 36, 36, 36, 59, 60, + 61, 63, 36, 36, 36, 36, 40, 36, + 40, 41, 42, 43, 36, 36, 36, 36, + 36, 36, 36, 36, 52, 36, 53, 54, + 55, 36, 36, 36, 36, 36, 59, 60, + 61, 63, 36, 36, 36, 36, 40, 36, + 65, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 39, 40, 41, 42, 43, 36, + 45, 46, 36, 36, 36, 50, 51, 52, + 36, 53, 54, 55, 36, 36, 36, 36, + 36, 59, 60, 61, 63, 36, 36, 36, + 36, 40, 36, 40, 41, 42, 43, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 53, 54, 55, 36, 36, 36, 36, + 36, 59, 60, 61, 63, 36, 36, 36, + 36, 40, 36, 65, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 39, 40, 41, + 42, 43, 36, 36, 46, 36, 36, 36, + 50, 51, 52, 36, 53, 54, 55, 36, + 36, 36, 36, 36, 59, 60, 61, 63, + 36, 36, 36, 36, 40, 36, 65, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 39, 40, 41, 42, 43, 36, 36, 36, + 36, 36, 36, 50, 51, 52, 36, 53, + 54, 55, 36, 36, 36, 36, 36, 59, + 60, 61, 63, 36, 36, 36, 36, 40, + 36, 65, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 39, 40, 41, 42, 43, + 44, 45, 46, 36, 36, 36, 50, 51, + 52, 36, 53, 54, 55, 36, 36, 36, + 36, 36, 59, 60, 61, 63, 36, 36, + 36, 36, 40, 36, 37, 38, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 36, 49, 50, 51, 52, 36, 53, 54, + 55, 36, 36, 36, 36, 58, 59, 60, + 61, 58, 36, 36, 36, 36, 62, 36, + 37, 36, 37, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 40, 41, 42, 43, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 53, 54, + 55, 36, 36, 36, 36, 36, 59, 60, + 61, 63, 36, 37, 38, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 36, 53, 54, 55, + 36, 36, 36, 36, 58, 59, 60, 61, + 58, 36, 36, 36, 36, 62, 36, 56, + 57, 36, 57, 36, 67, 68, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 69, + 70, 71, 72, 73, 74, 75, 76, 77, + 1, 78, 79, 80, 81, 66, 82, 83, + 84, 66, 66, 66, 66, 85, 86, 87, + 88, 89, 66, 66, 66, 66, 90, 66, + 67, 68, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 78, 79, 80, + 81, 66, 82, 83, 84, 66, 66, 66, + 66, 85, 86, 87, 88, 89, 66, 66, + 66, 66, 90, 66, 67, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 70, 71, 72, 73, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 82, 83, 84, 66, 66, 66, 66, 66, + 86, 87, 88, 91, 66, 66, 66, 66, + 70, 66, 70, 71, 72, 73, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 82, 83, 84, 66, 66, 66, 66, 66, + 86, 87, 88, 91, 66, 71, 72, 73, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 86, 87, 88, 66, 72, 73, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 86, 87, 88, 66, 73, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 86, 87, 88, 66, 86, 87, 66, + 87, 66, 71, 72, 73, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 82, + 83, 84, 66, 66, 66, 66, 66, 86, + 87, 88, 91, 66, 71, 72, 73, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 83, 84, 66, 66, 66, 66, + 66, 86, 87, 88, 91, 66, 71, 72, + 73, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 84, 66, 66, + 66, 66, 66, 86, 87, 88, 91, 66, + 93, 92, 71, 72, 73, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 86, + 87, 88, 91, 66, 69, 70, 71, 72, + 73, 66, 66, 66, 66, 66, 66, 79, + 80, 81, 66, 82, 83, 84, 66, 66, + 66, 66, 66, 86, 87, 88, 91, 66, + 66, 66, 66, 70, 66, 70, 71, 72, + 73, 66, 66, 66, 66, 66, 66, 79, + 80, 81, 66, 82, 83, 84, 66, 66, + 66, 66, 66, 86, 87, 88, 91, 66, + 66, 66, 66, 70, 66, 70, 71, 72, + 73, 66, 66, 66, 66, 66, 66, 66, + 80, 81, 66, 82, 83, 84, 66, 66, + 66, 66, 66, 86, 87, 88, 91, 66, + 66, 66, 66, 70, 66, 70, 71, 72, + 73, 66, 66, 66, 66, 66, 66, 66, + 66, 81, 66, 82, 83, 84, 66, 66, + 66, 66, 66, 86, 87, 88, 91, 66, + 66, 66, 66, 70, 66, 94, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 69, + 70, 71, 72, 73, 66, 75, 76, 66, + 66, 66, 79, 80, 81, 66, 82, 83, + 84, 66, 66, 66, 66, 66, 86, 87, + 88, 91, 66, 66, 66, 66, 70, 66, + 70, 71, 72, 73, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 82, 83, + 84, 66, 66, 66, 66, 66, 86, 87, + 88, 91, 66, 66, 66, 66, 70, 66, + 94, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 69, 70, 71, 72, 73, 66, + 66, 76, 66, 66, 66, 79, 80, 81, + 66, 82, 83, 84, 66, 66, 66, 66, + 66, 86, 87, 88, 91, 66, 66, 66, + 66, 70, 66, 94, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 69, 70, 71, + 72, 73, 66, 66, 66, 66, 66, 66, + 79, 80, 81, 66, 82, 83, 84, 66, + 66, 66, 66, 66, 86, 87, 88, 91, + 66, 66, 66, 66, 70, 66, 94, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 69, 70, 71, 72, 73, 74, 75, 76, + 66, 66, 66, 79, 80, 81, 66, 82, + 83, 84, 66, 66, 66, 66, 66, 86, + 87, 88, 91, 66, 66, 66, 66, 70, + 66, 67, 68, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 66, 78, 79, + 80, 81, 66, 82, 83, 84, 66, 66, + 66, 66, 85, 86, 87, 88, 89, 66, + 66, 66, 66, 90, 66, 67, 95, 67, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 70, 71, 72, + 73, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 82, 83, 84, 66, 66, + 66, 66, 66, 86, 87, 88, 91, 66, + 97, 96, 3, 98, 99, 100, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 101, + 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 66, 115, 116, + 117, 66, 56, 57, 66, 118, 119, 120, + 88, 121, 66, 66, 66, 66, 122, 66, + 99, 100, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 111, 111, 112, 113, + 114, 66, 115, 116, 117, 66, 66, 66, + 66, 118, 119, 120, 88, 121, 66, 66, + 66, 66, 122, 66, 99, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 102, 103, 104, 105, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 115, 116, 117, 66, 66, 66, 66, 66, + 119, 120, 88, 123, 66, 66, 66, 66, + 102, 66, 102, 103, 104, 105, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 115, 116, 117, 66, 66, 66, 66, 66, + 119, 120, 88, 123, 66, 103, 104, 105, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 119, 120, 88, 66, 104, 105, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 119, 120, 88, 66, 105, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 119, 120, 88, 66, 119, 120, 66, + 120, 66, 103, 104, 105, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 115, + 116, 117, 66, 66, 66, 66, 66, 119, + 120, 88, 123, 66, 103, 104, 105, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 116, 117, 66, 66, 66, 66, + 66, 119, 120, 88, 123, 66, 103, 104, + 105, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 117, 66, 66, + 66, 66, 66, 119, 120, 88, 123, 66, + 124, 92, 103, 104, 105, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 119, + 120, 88, 123, 66, 101, 102, 103, 104, + 105, 66, 66, 66, 66, 66, 66, 112, + 113, 114, 66, 115, 116, 117, 66, 66, + 66, 66, 66, 119, 120, 88, 123, 66, + 66, 66, 66, 102, 66, 102, 103, 104, + 105, 66, 66, 66, 66, 66, 66, 112, + 113, 114, 66, 115, 116, 117, 66, 66, + 66, 66, 66, 119, 120, 88, 123, 66, + 66, 66, 66, 102, 66, 102, 103, 104, + 105, 66, 66, 66, 66, 66, 66, 66, + 113, 114, 66, 115, 116, 117, 66, 66, + 66, 66, 66, 119, 120, 88, 123, 66, + 66, 66, 66, 102, 66, 102, 103, 104, + 105, 66, 66, 66, 66, 66, 66, 66, + 66, 114, 66, 115, 116, 117, 66, 66, + 66, 66, 66, 119, 120, 88, 123, 66, + 66, 66, 66, 102, 66, 125, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 101, + 102, 103, 104, 105, 66, 107, 108, 66, + 66, 66, 112, 113, 114, 66, 115, 116, + 117, 66, 66, 66, 66, 66, 119, 120, + 88, 123, 66, 66, 66, 66, 102, 66, + 102, 103, 104, 105, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 115, 116, + 117, 66, 66, 66, 66, 66, 119, 120, + 88, 123, 66, 66, 66, 66, 102, 66, + 125, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 101, 102, 103, 104, 105, 66, + 66, 108, 66, 66, 66, 112, 113, 114, + 66, 115, 116, 117, 66, 66, 66, 66, + 66, 119, 120, 88, 123, 66, 66, 66, + 66, 102, 66, 125, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 101, 102, 103, + 104, 105, 66, 66, 66, 66, 66, 66, + 112, 113, 114, 66, 115, 116, 117, 66, + 66, 66, 66, 66, 119, 120, 88, 123, + 66, 66, 66, 66, 102, 66, 125, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 101, 102, 103, 104, 105, 106, 107, 108, + 66, 66, 66, 112, 113, 114, 66, 115, + 116, 117, 66, 66, 66, 66, 66, 119, + 120, 88, 123, 66, 66, 66, 66, 102, + 66, 99, 100, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 66, 111, 112, + 113, 114, 66, 115, 116, 117, 66, 66, + 66, 66, 118, 119, 120, 88, 121, 66, + 66, 66, 66, 122, 66, 99, 95, 99, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 102, 103, 104, + 105, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 115, 116, 117, 66, 66, + 66, 66, 66, 119, 120, 88, 123, 66, + 99, 100, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, + 114, 66, 115, 116, 117, 66, 66, 66, + 66, 118, 119, 120, 88, 121, 66, 66, + 66, 66, 122, 66, 5, 6, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 9, + 10, 11, 12, 13, 14, 15, 16, 17, + 19, 19, 20, 21, 22, 126, 23, 24, + 25, 126, 126, 126, 126, 29, 30, 31, + 32, 29, 126, 126, 126, 126, 35, 126, + 5, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 10, 11, + 12, 13, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 23, 24, 25, 126, + 126, 126, 126, 126, 30, 31, 32, 127, + 126, 126, 126, 126, 10, 126, 10, 11, + 12, 13, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 23, 24, 25, 126, + 126, 126, 126, 126, 30, 31, 32, 127, + 126, 11, 12, 13, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 30, 31, + 32, 126, 12, 13, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 30, 31, + 32, 126, 13, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 30, 31, 32, + 126, 30, 31, 126, 31, 126, 11, 12, + 13, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 23, 24, 25, 126, 126, + 126, 126, 126, 30, 31, 32, 127, 126, + 11, 12, 13, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 24, 25, + 126, 126, 126, 126, 126, 30, 31, 32, + 127, 126, 11, 12, 13, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 25, 126, 126, 126, 126, 126, 30, + 31, 32, 127, 126, 128, 126, 11, 12, + 13, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 30, 31, 32, 127, 126, + 9, 10, 11, 12, 13, 126, 126, 126, + 126, 126, 126, 20, 21, 22, 126, 23, + 24, 25, 126, 126, 126, 126, 126, 30, + 31, 32, 127, 126, 126, 126, 126, 10, + 126, 10, 11, 12, 13, 126, 126, 126, + 126, 126, 126, 20, 21, 22, 126, 23, + 24, 25, 126, 126, 126, 126, 126, 30, + 31, 32, 127, 126, 126, 126, 126, 10, + 126, 10, 11, 12, 13, 126, 126, 126, + 126, 126, 126, 126, 21, 22, 126, 23, + 24, 25, 126, 126, 126, 126, 126, 30, + 31, 32, 127, 126, 126, 126, 126, 10, + 126, 10, 11, 12, 13, 126, 126, 126, + 126, 126, 126, 126, 126, 22, 126, 23, + 24, 25, 126, 126, 126, 126, 126, 30, + 31, 32, 127, 126, 126, 126, 126, 10, + 126, 129, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 9, 10, 11, 12, 13, + 126, 15, 16, 126, 126, 126, 20, 21, + 22, 126, 23, 24, 25, 126, 126, 126, + 126, 126, 30, 31, 32, 127, 126, 126, + 126, 126, 10, 126, 10, 11, 12, 13, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 23, 24, 25, 126, 126, 126, + 126, 126, 30, 31, 32, 127, 126, 126, + 126, 126, 10, 126, 129, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 9, 10, + 11, 12, 13, 126, 126, 16, 126, 126, + 126, 20, 21, 22, 126, 23, 24, 25, + 126, 126, 126, 126, 126, 30, 31, 32, + 127, 126, 126, 126, 126, 10, 126, 129, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 9, 10, 11, 12, 13, 126, 126, + 126, 126, 126, 126, 20, 21, 22, 126, + 23, 24, 25, 126, 126, 126, 126, 126, + 30, 31, 32, 127, 126, 126, 126, 126, + 10, 126, 129, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 9, 10, 11, 12, + 13, 14, 15, 16, 126, 126, 126, 20, + 21, 22, 126, 23, 24, 25, 126, 126, + 126, 126, 126, 30, 31, 32, 127, 126, + 126, 126, 126, 10, 126, 5, 6, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 126, 19, 20, 21, 22, 126, 23, + 24, 25, 126, 126, 126, 126, 29, 30, + 31, 32, 29, 126, 126, 126, 126, 35, + 126, 5, 126, 5, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 10, 11, 12, 13, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 23, + 24, 25, 126, 126, 126, 126, 126, 30, + 31, 32, 127, 126, 130, 126, 7, 126, + 1, 126, 126, 126, 1, 126, 126, 126, + 126, 126, 5, 6, 7, 126, 126, 126, + 126, 126, 126, 126, 126, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 126, 23, 24, 25, 126, + 26, 27, 126, 29, 30, 31, 32, 29, + 126, 126, 126, 126, 35, 126, 5, 6, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 126, + 23, 24, 25, 126, 126, 126, 126, 29, + 30, 31, 32, 29, 126, 126, 126, 126, + 35, 126, 26, 27, 126, 27, 126, 1, + 131, 131, 131, 1, 131, 133, 132, 33, + 132, 33, 133, 132, 133, 132, 33, 132, + 34, 132, 0 +}; + +static const char _use_syllable_machine_trans_targs[] = { + 1, 30, 0, 56, 58, 85, 86, 110, + 112, 98, 87, 88, 89, 90, 102, 104, + 105, 106, 113, 107, 99, 100, 101, 93, + 94, 95, 114, 115, 116, 108, 91, 92, + 0, 117, 119, 109, 0, 2, 3, 15, + 4, 5, 6, 7, 19, 21, 22, 23, + 27, 24, 16, 17, 18, 10, 11, 12, + 28, 29, 25, 8, 9, 0, 26, 13, + 14, 20, 0, 31, 32, 44, 33, 34, + 35, 36, 48, 50, 51, 52, 53, 45, + 46, 47, 39, 40, 41, 54, 37, 38, + 0, 54, 55, 42, 0, 43, 49, 0, + 0, 57, 0, 59, 60, 72, 61, 62, + 63, 64, 76, 78, 79, 80, 84, 81, + 73, 74, 75, 67, 68, 69, 82, 65, + 66, 82, 83, 70, 71, 77, 0, 96, + 97, 103, 111, 0, 0, 118 +}; + +static const char _use_syllable_machine_trans_actions[] = { + 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 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, 0, + 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, + 9, 10, 0, 0, 11, 0, 0, 12, + 13, 0, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8, 0, + 0, 10, 0, 0, 0, 0, 15, 0, + 0, 0, 0, 16, 17, 0 +}; + +static const char _use_syllable_machine_to_state_actions[] = { + 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 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[] = { + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 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[] = { + 0, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 93, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 96, 67, + 97, 99, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 93, 67, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 96, 67, 67, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 132, 133, 133, 133 +}; + +static const int use_syllable_machine_start = 0; +static const int use_syllable_machine_first_final = 0; +static const int use_syllable_machine_error = -1; + +static const int use_syllable_machine_en_main = 0; + + +#line 58 "hb-ot-shaper-use-machine.rl" + + + +#line 182 "hb-ot-shaper-use-machine.rl" + + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \ + for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + + +template <typename Iter> +struct machine_index_t : + hb_iter_with_fallback_t<machine_index_t<Iter>, + typename Iter::item_t> +{ + machine_index_t (const Iter& it) : it (it) {} + machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>, + typename Iter::item_t> (), + it (o.it), is_null (o.is_null) {} + + static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; + static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; + + typename Iter::item_t __item__ () const { return *it; } + typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; } + unsigned __len__ () const { return it.len (); } + void __next__ () { ++it; } + void __forward__ (unsigned n) { it += n; } + void __prev__ () { --it; } + void __rewind__ (unsigned n) { it -= n; } + + void operator = (unsigned n) + { + assert (n == 0); + is_null = true; + } + explicit operator bool () { return !is_null; } + + void operator = (const machine_index_t& o) + { + is_null = o.is_null; + unsigned index = (*it).first; + unsigned n = (*o.it).first; + if (index < n) it += n - index; else if (index > n) it -= index - n; + } + bool operator == (const machine_index_t& o) const + { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; } + bool operator != (const machine_index_t& o) const { return !(*this == o); } + + private: + Iter it; + bool is_null = false; +}; +struct +{ + template <typename Iter, + hb_requires (hb_is_iterable (Iter))> + machine_index_t<hb_iter_type<Iter>> + operator () (Iter&& it) const + { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); } +} +HB_FUNCOBJ (machine_index); + + + +static bool +not_ccs_default_ignorable (const hb_glyph_info_t &i) +{ return i.use_category() != USE(CGJ); } + +static inline void +find_syllables_use (hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; + auto p = + + hb_iter (info, buffer->len) + | hb_enumerate + | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); }, + hb_second) + | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) + { + if (p.second.use_category() == USE(ZWNJ)) + for (unsigned i = p.first + 1; i < buffer->len; ++i) + if (not_ccs_default_ignorable (info[i])) + return !_hb_glyph_info_is_unicode_mark (&info[i]); + return true; + }) + | hb_enumerate + | machine_index + ; + auto pe = p + p.len (); + auto eof = +pe; + auto ts = +p; + auto te = +p; + unsigned int act HB_UNUSED; + int cs; + +#line 784 "hb-ot-shaper-use-machine.hh" + { + cs = use_syllable_machine_start; + ts = 0; + te = 0; + act = 0; + } + +#line 282 "hb-ot-shaper-use-machine.rl" + + + unsigned int syllable_serial = 1; + +#line 797 "hb-ot-shaper-use-machine.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const unsigned char *_inds; + if ( p == pe ) + goto _test_eof; +_resume: + switch ( _use_syllable_machine_from_state_actions[cs] ) { + case 2: +#line 1 "NONE" + {ts = p;} + break; +#line 811 "hb-ot-shaper-use-machine.hh" + } + + _keys = _use_syllable_machine_trans_keys + (cs<<1); + _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs]; + + _slen = _use_syllable_machine_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) && + ( (*p).second.second.use_category()) <= _keys[1] ? + ( (*p).second.second.use_category()) - _keys[0] : _slen ]; + +_eof_trans: + cs = _use_syllable_machine_trans_targs[_trans]; + + if ( _use_syllable_machine_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _use_syllable_machine_trans_actions[_trans] ) { + case 9: +#line 172 "hb-ot-shaper-use-machine.rl" + {te = p+1;{ found_syllable (use_standard_cluster); }} + break; + case 6: +#line 175 "hb-ot-shaper-use-machine.rl" + {te = p+1;{ found_syllable (use_symbol_cluster); }} + break; + case 4: +#line 177 "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 3: +#line 178 "hb-ot-shaper-use-machine.rl" + {te = p+1;{ found_syllable (use_non_cluster); }} + break; + case 11: +#line 171 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} + break; + case 7: +#line 172 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_standard_cluster); }} + break; + case 14: +#line 173 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} + break; + case 13: +#line 174 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_numeral_cluster); }} + break; + case 5: +#line 175 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_symbol_cluster); }} + break; + case 17: +#line 176 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} + break; + case 15: +#line 177 "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 16: +#line 178 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_non_cluster); }} + break; + case 12: +#line 1 "NONE" + { switch( act ) { + case 1: + {{p = ((te))-1;} found_syllable (use_virama_terminated_cluster); } + break; + case 2: + {{p = ((te))-1;} found_syllable (use_sakot_terminated_cluster); } + break; + } + } + break; + case 8: +#line 1 "NONE" + {te = p+1;} +#line 170 "hb-ot-shaper-use-machine.rl" + {act = 1;} + break; + case 10: +#line 1 "NONE" + {te = p+1;} +#line 171 "hb-ot-shaper-use-machine.rl" + {act = 2;} + break; +#line 901 "hb-ot-shaper-use-machine.hh" + } + +_again: + switch ( _use_syllable_machine_to_state_actions[cs] ) { + case 1: +#line 1 "NONE" + {ts = 0;} + break; +#line 910 "hb-ot-shaper-use-machine.hh" + } + + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _use_syllable_machine_eof_trans[cs] > 0 ) { + _trans = _use_syllable_machine_eof_trans[cs] - 1; + goto _eof_trans; + } + } + + } + +#line 287 "hb-ot-shaper-use-machine.rl" + +} + +#undef found_syllable + +#endif /* HB_OT_SHAPER_USE_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl index 3f2d5bfba71..4bb37845273 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl @@ -26,15 +26,15 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH +#ifndef HB_OT_SHAPER_USE_MACHINE_HH +#define HB_OT_SHAPER_USE_MACHINE_HH #include "hb.hh" -#include "hb-ot-shape-complex-syllabic.hh" +#include "hb-ot-shaper-syllabic.hh" /* buffer var allocations */ -#define use_category() complex_var_u8_category() +#define use_category() ot_shaper_var_u8_category() #define USE(Cat) use_syllable_machine_ex_##Cat @@ -82,6 +82,7 @@ export G = 49; # HIEROGLYPH export J = 50; # HIEROGLYPH_JOINER export SB = 51; # HIEROGLYPH_SEGMENT_BEGIN export SE = 52; # HIEROGLYPH_SEGMENT_END +export HVM = 53; # HALANT_OR_VOWEL_MODIFIER export FAbv = 24; # CONS_FINAL_ABOVE export FBlw = 25; # CONS_FINAL_BELOW @@ -107,12 +108,12 @@ export FMBlw = 46; # CONS_FINAL_MOD UIPC = Bottom export FMPst = 47; # CONS_FINAL_MOD UIPC = Not_Applicable -h = H | IS | Sk; +h = H | HVM | IS | Sk; consonant_modifiers = CMAbv* CMBlw* ((h B | SUB) CMAbv? CMBlw*)*; medial_consonants = MPre? MAbv? MBlw? MPst?; dependent_vowels = VPre* VAbv* VBlw* VPst* | H; -vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*; +vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*; final_consonants = FAbv* FBlw* FPst*; final_modifiers = FMAbv* FMBlw* | FMPst?; @@ -173,7 +174,7 @@ main := |* numeral_cluster => { found_syllable (use_numeral_cluster); }; symbol_cluster => { found_syllable (use_symbol_cluster); }; hieroglyph_cluster => { found_syllable (use_hieroglyph_cluster); }; - broken_cluster => { found_syllable (use_broken_cluster); }; + broken_cluster => { found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }; other => { found_syllable (use_non_cluster); }; *|; @@ -288,4 +289,4 @@ find_syllables_use (hb_buffer_t *buffer) #undef found_syllable -#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */ +#endif /* HB_OT_SHAPER_USE_MACHINE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh index c8e51516949..5aa025fb4c6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh @@ -37,12 +37,12 @@ * UnicodeData.txt does not have a header. */ -#ifndef HB_OT_SHAPE_COMPLEX_USE_TABLE_HH -#define HB_OT_SHAPE_COMPLEX_USE_TABLE_HH +#ifndef HB_OT_SHAPER_USE_TABLE_HH +#define HB_OT_SHAPER_USE_TABLE_HH #include "hb.hh" -#include "hb-ot-shape-complex-use-machine.hh" +#include "hb-ot-shaper-use-machine.hh" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-macros" @@ -53,6 +53,7 @@ #define GB USE(GB) /* BASE_OTHER */ #define H USE(H) /* HALANT */ #define HN USE(HN) /* HALANT_NUM */ +#define HVM USE(HVM) /* HALANT_OR_VOWEL_MODIFIER */ #define IS USE(IS) /* INVISIBLE_STACKER */ #define J USE(J) /* HIEROGLYPH_JOINER */ #define N USE(N) /* BASE_NUM */ @@ -246,7 +247,7 @@ static const uint8_t use_table[] = { /* 0D90 */ B, B, B, B, B, B, B, WJ, WJ, WJ, B, B, B, B, B, B, /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0DB0 */ B, B, WJ, B, B, B, B, B, B, B, B, B, WJ, B, WJ, WJ, - /* 0DC0 */ B, B, B, B, B, B, B, WJ, WJ, WJ, H, WJ, WJ, WJ, WJ, VPst, + /* 0DC0 */ B, B, B, B, B, B, B, WJ, WJ, WJ, HVM, WJ, WJ, WJ, WJ, VPst, /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, WJ, VBlw, WJ, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, /* 0DE0 */ WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, B, B, B, B, /* 0DF0 */ WJ, WJ, VPst, VPst, O, WJ, WJ, WJ, @@ -1531,6 +1532,7 @@ hb_use_get_category (hb_glyph_info_t info) #undef GB #undef H #undef HN +#undef HVM #undef IS #undef J #undef N @@ -1566,5 +1568,5 @@ hb_use_get_category (hb_glyph_info_t info) #undef VMPre -#endif /* HB_OT_SHAPE_COMPLEX_USE_TABLE_HH */ +#endif /* HB_OT_SHAPER_USE_TABLE_HH */ /* == End of generated table == */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use.cc index 1d13c8a126b..60394ed4d8a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use.cc @@ -30,11 +30,11 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-use-machine.hh" -#include "hb-ot-shape-complex-use-table.hh" -#include "hb-ot-shape-complex-arabic.hh" -#include "hb-ot-shape-complex-arabic-joining-list.hh" -#include "hb-ot-shape-complex-vowel-constraints.hh" +#include "hb-ot-shaper-use-machine.hh" +#include "hb-ot-shaper-use-table.hh" +#include "hb-ot-shaper-arabic.hh" +#include "hb-ot-shaper-arabic-joining-list.hh" +#include "hb-ot-shaper-vowel-constraints.hh" /* @@ -133,6 +133,7 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->enable_feature (use_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE); map->add_gsub_pause (reorder_use); + map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var /* "Topographical features" */ for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++) @@ -297,6 +298,7 @@ setup_syllables_use (const hb_ot_shape_plan_t *plan, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { + HB_BUFFER_ALLOCATE_VAR (buffer, syllable); find_syllables_use (buffer); foreach_syllable (buffer, start, end) buffer->unsafe_to_break (start, end); @@ -349,7 +351,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED, static inline bool is_halant_use (const hb_glyph_info_t &info) { - return (info.use_category() == USE(H) || info.use_category() == USE(IS)) && + return (info.use_category() == USE(H) || info.use_category() == USE(HVM) || info.use_category() == USE(IS)) && !_hb_glyph_info_ligated (&info); } @@ -480,7 +482,7 @@ compose_use (const hb_ot_shape_normalize_context_t *c, } -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = +const hb_ot_shaper_t _hb_ot_shaper_use = { collect_features_use, nullptr, /* override_features */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-vowel-constraints.cc index d2cca105a49..be4ac813b13 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-vowel-constraints.cc @@ -18,7 +18,7 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-vowel-constraints.hh" +#include "hb-ot-shaper-vowel-constraints.hh" static void _output_dotted_circle (hb_buffer_t *buffer) @@ -39,7 +39,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, hb_font_t *font HB_UNUSED) { -#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS +#ifdef HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS return; #endif if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-vowel-constraints.hh index d9082d4eadb..5a7ee1b0f27 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-vowel-constraints.hh @@ -24,16 +24,16 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS_HH -#define HB_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS_HH +#ifndef HB_OT_SHAPER_VOWEL_CONSTRAINTS_HH +#define HB_OT_SHAPER_VOWEL_CONSTRAINTS_HH #include "hb.hh" -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shaper.hh" HB_INTERNAL void _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font); -#endif /* HB_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS_HH */ +#endif /* HB_OT_SHAPER_VOWEL_CONSTRAINTS_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper.hh index 8012a9ae946..b823bf003c5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper.hh @@ -24,8 +24,8 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_SHAPE_COMPLEX_HH -#define HB_OT_SHAPE_COMPLEX_HH +#ifndef HB_OT_SHAPER_HH +#define HB_OT_SHAPER_HH #include "hb.hh" @@ -34,12 +34,12 @@ #include "hb-ot-shape-normalize.hh" -/* buffer var allocations, used by complex shapers */ -#define complex_var_u8_category() var2.u8[2] -#define complex_var_u8_auxiliary() var2.u8[3] +/* buffer var allocations, used by all OT shapers */ +#define ot_shaper_var_u8_category() var2.u8[2] +#define ot_shaper_var_u8_auxiliary() var2.u8[3] -#define HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS 32 +#define HB_OT_SHAPE_MAX_COMBINING_MARKS 32 enum hb_ot_shape_zero_width_marks_type_t { HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, @@ -49,22 +49,22 @@ enum hb_ot_shape_zero_width_marks_type_t { /* Master OT shaper list */ -#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \ - HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \ - HB_COMPLEX_SHAPER_IMPLEMENT (default) \ - HB_COMPLEX_SHAPER_IMPLEMENT (dumber) \ - HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \ - HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \ - HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ - HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \ - HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ - HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \ - HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ - HB_COMPLEX_SHAPER_IMPLEMENT (use) \ +#define HB_OT_SHAPERS_IMPLEMENT_SHAPERS \ + HB_OT_SHAPER_IMPLEMENT (arabic) \ + HB_OT_SHAPER_IMPLEMENT (default) \ + HB_OT_SHAPER_IMPLEMENT (dumber) \ + HB_OT_SHAPER_IMPLEMENT (hangul) \ + HB_OT_SHAPER_IMPLEMENT (hebrew) \ + HB_OT_SHAPER_IMPLEMENT (indic) \ + HB_OT_SHAPER_IMPLEMENT (khmer) \ + HB_OT_SHAPER_IMPLEMENT (myanmar) \ + HB_OT_SHAPER_IMPLEMENT (myanmar_zawgyi) \ + HB_OT_SHAPER_IMPLEMENT (thai) \ + HB_OT_SHAPER_IMPLEMENT (use) \ /* ^--- Add new shapers here; keep sorted. */ -struct hb_ot_complex_shaper_t +struct hb_ot_shaper_t { /* collect_features() * Called during shape_plan(). @@ -168,18 +168,18 @@ struct hb_ot_complex_shaper_t bool fallback_position; }; -#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name; -HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS -#undef HB_COMPLEX_SHAPER_IMPLEMENT +#define HB_OT_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_shaper_t _hb_ot_shaper_##name; +HB_OT_SHAPERS_IMPLEMENT_SHAPERS +#undef HB_OT_SHAPER_IMPLEMENT -static inline const hb_ot_complex_shaper_t * -hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) +static inline const hb_ot_shaper_t * +hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner) { switch ((hb_tag_t) planner->props.script) { default: - return &_hb_ot_complex_shaper_default; + return &_hb_ot_shaper_default; /* Unicode-1.1 additions */ @@ -195,28 +195,28 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || planner->props.script == HB_SCRIPT_ARABIC) && HB_DIRECTION_IS_HORIZONTAL(planner->props.direction)) - return &_hb_ot_complex_shaper_arabic; + return &_hb_ot_shaper_arabic; else - return &_hb_ot_complex_shaper_default; + return &_hb_ot_shaper_default; /* Unicode-1.1 additions */ case HB_SCRIPT_THAI: case HB_SCRIPT_LAO: - return &_hb_ot_complex_shaper_thai; + return &_hb_ot_shaper_thai; /* Unicode-1.1 additions */ case HB_SCRIPT_HANGUL: - return &_hb_ot_complex_shaper_hangul; + return &_hb_ot_shaper_hangul; /* Unicode-1.1 additions */ case HB_SCRIPT_HEBREW: - return &_hb_ot_complex_shaper_hebrew; + return &_hb_ot_shaper_hebrew; /* Unicode-1.1 additions */ @@ -230,9 +230,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_TAMIL: case HB_SCRIPT_TELUGU: - /* Unicode-3.0 additions */ - case HB_SCRIPT_SINHALA: - /* 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. @@ -240,14 +237,14 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) * 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')) - return &_hb_ot_complex_shaper_default; + return &_hb_ot_shaper_default; else if ((planner->map.chosen_script[0] & 0x000000FF) == '3') - return &_hb_ot_complex_shaper_use; + return &_hb_ot_shaper_use; else - return &_hb_ot_complex_shaper_indic; + return &_hb_ot_shaper_indic; case HB_SCRIPT_KHMER: - return &_hb_ot_complex_shaper_khmer; + return &_hb_ot_shaper_khmer; case HB_SCRIPT_MYANMAR: /* If the designer designed the font for the 'DFLT' script, @@ -260,16 +257,16 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) 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')) - return &_hb_ot_complex_shaper_default; + return &_hb_ot_shaper_default; else - return &_hb_ot_complex_shaper_myanmar; + return &_hb_ot_shaper_myanmar; #define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) case HB_SCRIPT_MYANMAR_ZAWGYI: /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ - return &_hb_ot_complex_shaper_myanmar_zawgyi; + return &_hb_ot_shaper_myanmar_zawgyi; /* Unicode-2.0 additions */ @@ -277,7 +274,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-3.0 additions */ case HB_SCRIPT_MONGOLIAN: - //case HB_SCRIPT_SINHALA: + case HB_SCRIPT_SINHALA: /* Unicode-3.2 additions */ case HB_SCRIPT_BUHID: @@ -390,11 +387,11 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) * 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')) - return &_hb_ot_complex_shaper_default; + return &_hb_ot_shaper_default; else - return &_hb_ot_complex_shaper_use; + return &_hb_ot_shaper_use; } } -#endif /* HB_OT_SHAPE_COMPLEX_HH */ +#endif /* HB_OT_SHAPER_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh index b242fba2d87..9394b90ee61 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh @@ -219,6 +219,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('z','u',' ',' '), HB_TAG('Z','U','L',' ')}, /* Zulu */ }; +#ifndef HB_NO_LANGUAGE_LONG 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 */ @@ -1621,6 +1622,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('z','z','a',' '), HB_TAG('Z','Z','A',' ')},*/ /* Zazaki [macrolanguage] */ {HB_TAG('z','z','j',' '), HB_TAG('Z','H','A',' ')}, /* Zuojiang Zhuang -> Zhuang */ }; +#endif /** * hb_ot_tags_from_complex_language: @@ -1636,7 +1638,7 @@ static const LangTag ot_languages3[] = { * * Return value: Whether any language systems were retrieved. **/ -static bool +static inline bool hb_ot_tags_from_complex_language (const char *lang_str, const char *limit, unsigned int *count /* IN/OUT */, @@ -2818,7 +2820,7 @@ out: * Return value: The #hb_language_t corresponding to the BCP 47 language tag, * or #HB_LANGUAGE_INVALID if @tag is not ambiguous. **/ -static hb_language_t +static inline hb_language_t hb_ot_ambiguous_tag_to_language (hb_tag_t tag) { switch (tag) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc index a4a9515362a..ce5cdce98bd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc @@ -263,15 +263,19 @@ hb_ot_tags_from_language (const char *lang_str, unsigned int *count, hb_tag_t *tags) { - const char *s; +#ifndef HB_NO_LANGUAGE_LONG /* Check for matches of multiple subtags. */ if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags)) return; +#endif /* Find a language matching in the first component. */ - s = strchr (lang_str, '-'); +#ifndef HB_NO_LANGUAGE_LONG + const char *s; s = strchr (lang_str, '-'); +#endif { +#ifndef HB_NO_LANGUAGE_LONG if (s && limit - lang_str >= 6) { const char *extlang_end = strchr (s + 1, '-'); @@ -280,6 +284,7 @@ hb_ot_tags_from_language (const char *lang_str, ISALPHA (s[1])) lang_str = s + 1; } +#endif const LangTag *ot_languages = nullptr; unsigned ot_languages_len = 0; const char *dash = strchr (lang_str, '-'); @@ -289,21 +294,23 @@ hb_ot_tags_from_language (const char *lang_str, ot_languages = ot_languages2; ot_languages_len = ARRAY_LENGTH (ot_languages2); } +#ifndef HB_NO_LANGUAGE_LONG else if (first_len == 3) { ot_languages = ot_languages3; ot_languages_len = ARRAY_LENGTH (ot_languages3); } +#endif hb_tag_t lang_tag = hb_tag_from_string (lang_str, first_len); - static unsigned last_tag_idx; /* Poor man's cache. */ - unsigned tag_idx = last_tag_idx; + static hb_atomic_int_t last_tag_idx; /* Poor man's cache. */ + unsigned tag_idx = last_tag_idx.get_relaxed (); if (likely (tag_idx < ot_languages_len && ot_languages[tag_idx].language == lang_tag) || hb_sorted_array (ot_languages, ot_languages_len).bfind (lang_tag, &tag_idx)) { - last_tag_idx = tag_idx; + last_tag_idx.set_relaxed (tag_idx); unsigned int i; while (tag_idx != 0 && ot_languages[tag_idx].language == ot_languages[tag_idx - 1].language) @@ -320,6 +327,7 @@ hb_ot_tags_from_language (const char *lang_str, } } +#ifndef HB_NO_LANGUAGE_LONG if (!s) s = lang_str + strlen (lang_str); if (s - lang_str == 3) { @@ -328,6 +336,7 @@ hb_ot_tags_from_language (const char *lang_str, *count = 1; return; } +#endif *count = 0; } @@ -472,11 +481,13 @@ hb_ot_tag_to_language (hb_tag_t tag) if (tag == HB_OT_TAG_DEFAULT_LANGUAGE) return nullptr; +#ifndef HB_NO_LANGUAGE_LONG { hb_language_t disambiguated_tag = hb_ot_ambiguous_tag_to_language (tag); if (disambiguated_tag != HB_LANGUAGE_INVALID) return disambiguated_tag; } +#endif char buf[4]; for (i = 0; i < ARRAY_LENGTH (ot_languages2); i++) @@ -485,12 +496,14 @@ hb_ot_tag_to_language (hb_tag_t tag) hb_tag_to_string (ot_languages2[i].language, buf); return hb_language_from_string (buf, 2); } +#ifndef HB_NO_LANGUAGE_LONG for (i = 0; i < ARRAY_LENGTH (ot_languages3); i++) if (ot_languages3[i].tag == tag) { hb_tag_to_string (ot_languages3[i].language, buf); return hb_language_from_string (buf, 3); } +#endif /* Return a custom language in the form of "x-hbot-AABBCCDD". * If it's three letters long, also guess it's ISO 639-3 and lower-case and @@ -596,6 +609,7 @@ test_langs_sorted () abort(); } } +#ifndef HB_NO_LANGUAGE_LONG for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages3); i++) { int c = ot_languages3[i].cmp (&ot_languages3[i - 1]); @@ -606,6 +620,7 @@ test_langs_sorted () abort(); } } +#endif } int diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh index e0665586837..c5c476bc0e0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh @@ -213,7 +213,7 @@ struct fvar if (!axis_index) axis_index = &i; *axis_index = HB_OT_VAR_NO_AXIS_INDEX; auto axes = get_axes (); - return axes.lfind (tag, axis_index) && (axes[*axis_index].get_axis_deprecated (info), true); + return axes.lfind (tag, axis_index) && ((void) axes[*axis_index].get_axis_deprecated (info), true); } #endif bool @@ -221,7 +221,7 @@ struct fvar { unsigned i; auto axes = get_axes (); - return axes.lfind (tag, &i) && (axes[i].get_axis_info (i, info), true); + return axes.lfind (tag, &i) && ((void) axes[i].get_axis_info (i, info), true); } int normalize_axis_value (unsigned int axis_index, float v) const diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh index 3b2a38b9a61..6b254b30ce9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh @@ -45,9 +45,10 @@ struct contour_point_t void translate (const contour_point_t &p) { x += p.x; y += p.y; } - uint8_t flag; - float x, y; - bool is_end_point; + float x = 0.f; + float y = 0.f; + uint8_t flag = 0; + bool is_end_point = false; }; struct contour_point_vector_t : hb_vector_t<contour_point_t> @@ -55,16 +56,24 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t> void extend (const hb_array_t<contour_point_t> &a) { unsigned int old_len = length; - resize (old_len + a.length); - for (unsigned int i = 0; i < a.length; i++) - (*this)[old_len + i] = a[i]; + if (unlikely (!resize (old_len + a.length))) + return; + auto arrayZ = this->arrayZ + old_len; + unsigned count = a.length; + for (unsigned int i = 0; i < count; i++) + arrayZ[i] = a.arrayZ[i]; } void transform (const float (&matrix)[4]) { - for (unsigned int i = 0; i < length; i++) + if (matrix[0] == 1.f && matrix[1] == 0.f && + matrix[2] == 0.f && matrix[3] == 1.f) + return; + auto arrayZ = this->arrayZ; + unsigned count = length; + for (unsigned i = 0; i < count; i++) { - contour_point_t &p = (*this)[i]; + contour_point_t &p = arrayZ[i]; float x_ = p.x * matrix[0] + p.y * matrix[2]; p.y = p.x * matrix[1] + p.y * matrix[3]; p.x = x_; @@ -73,8 +82,12 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t> void translate (const contour_point_t& delta) { - for (unsigned int i = 0; i < length; i++) - (*this)[i].translate (delta); + if (delta.x == 0.f && delta.y == 0.f) + return; + auto arrayZ = this->arrayZ; + unsigned count = length; + for (unsigned i = 0; i < count; i++) + arrayZ[i].translate (delta); } }; @@ -89,7 +102,7 @@ struct TupleVariationHeader const TupleVariationHeader &get_next (unsigned axis_count) const { return StructAtOffset<TupleVariationHeader> (this, get_size (axis_count)); } - float calculate_scalar (const int *coords, unsigned int coord_count, + float calculate_scalar (hb_array_t<int> coords, unsigned int coord_count, const hb_array_t<const F2DOT14> shared_tuples) const { hb_array_t<const F2DOT14> peak_tuple; @@ -538,8 +551,7 @@ struct gvar bool apply_deltas_to_points (hb_codepoint_t glyph, hb_font_t *font, const hb_array_t<contour_point_t> points) const { - /* num_coords should exactly match gvar's axisCount due to how GlyphVariationData tuples are aligned */ - if (!font->num_coords || font->num_coords != table->axisCount) return true; + if (!font->num_coords) return true; if (unlikely (glyph >= table->glyphCount)) return true; @@ -565,8 +577,8 @@ struct gvar if (points[i].is_end_point) end_points.push (i); - int *coords = font->coords; - unsigned num_coords = font->num_coords; + auto coords = hb_array (font->coords, font->num_coords); + unsigned num_coords = table->axisCount; hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); do { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh index e9d90352f01..56efcdbee9e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh @@ -319,10 +319,15 @@ struct HVARVVAR hvar_plan.index_map_plans.as_array ())); } - float get_advance_var (hb_codepoint_t glyph, hb_font_t *font) const + float get_advance_var (hb_codepoint_t glyph, + hb_font_t *font, + VariationStore::cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); - return (this+varStore).get_delta (varidx, font->coords, font->num_coords); + return (this+varStore).get_delta (varidx, + font->coords, + font->num_coords, + store_cache); } float get_side_bearing_var (hb_codepoint_t glyph, @@ -335,7 +340,7 @@ struct HVARVVAR bool has_side_bearing_deltas () const { return lsbMap && rsbMap; } - protected: + public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ Offset32To<VariationStore> diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh index ce9ff90bb4f..683a441ec36 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh @@ -32,1033 +32,18 @@ #include "hb-priority-queue.hh" #include "hb-serialize.hh" #include "hb-vector.hh" +#include "graph/graph.hh" +#include "graph/serialize.hh" + +using graph::graph_t; /* * For a detailed writeup on the overflow resolution algorithm see: * docs/repacker.md */ -struct graph_t -{ - struct vertex_t - { - hb_serialize_context_t::object_t obj; - int64_t distance = 0 ; - int64_t space = 0 ; - hb_vector_t<unsigned> parents; - unsigned start = 0; - unsigned end = 0; - unsigned priority = 0; - - friend void swap (vertex_t& a, vertex_t& b) - { - hb_swap (a.obj, b.obj); - hb_swap (a.distance, b.distance); - hb_swap (a.space, b.space); - hb_swap (a.parents, b.parents); - hb_swap (a.start, b.start); - hb_swap (a.end, b.end); - hb_swap (a.priority, b.priority); - } - - bool is_shared () const - { - return parents.length > 1; - } - - unsigned incoming_edges () const - { - return parents.length; - } - - void remove_parent (unsigned parent_index) - { - for (unsigned i = 0; i < parents.length; i++) - { - if (parents[i] != parent_index) continue; - parents.remove (i); - break; - } - } - - void remap_parents (const hb_vector_t<unsigned>& id_map) - { - for (unsigned i = 0; i < parents.length; i++) - parents[i] = id_map[parents[i]]; - } - - void remap_parent (unsigned old_index, unsigned new_index) - { - for (unsigned i = 0; i < parents.length; i++) - { - if (parents[i] == old_index) - parents[i] = new_index; - } - } - - bool is_leaf () const - { - return !obj.real_links.length && !obj.virtual_links.length; - } - - bool raise_priority () - { - if (has_max_priority ()) return false; - priority++; - return true; - } - - bool has_max_priority () const { - return priority >= 3; - } - - int64_t modified_distance (unsigned order) const - { - // TODO(garretrieger): once priority is high enough, should try - // setting distance = 0 which will force to sort immediately after - // it's parent where possible. - - int64_t modified_distance = - hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF); - if (has_max_priority ()) { - modified_distance = 0; - } - return (modified_distance << 18) | (0x003FFFF & order); - } - - int64_t distance_modifier () const - { - if (!priority) return 0; - int64_t table_size = obj.tail - obj.head; - - if (priority == 1) - return -table_size / 2; - - return -table_size; - } - }; - - struct overflow_record_t - { - unsigned parent; - unsigned child; - }; - - /* - * A topological sorting of an object graph. Ordered - * in reverse serialization order (first object in the - * serialization is at the end of the list). This matches - * the 'packed' object stack used internally in the - * serializer - */ - template<typename T> - graph_t (const T& objects) - : parents_invalid (true), - distance_invalid (true), - positions_invalid (true), - successful (true) - { - num_roots_for_space_.push (1); - bool removed_nil = false; - vertices_.alloc (objects.length); - vertices_scratch_.alloc (objects.length); - for (unsigned i = 0; i < objects.length; i++) - { - // TODO(grieger): check all links point to valid objects. - - // If this graph came from a serialization buffer object 0 is the - // nil object. We don't need it for our purposes here so drop it. - if (i == 0 && !objects[i]) - { - removed_nil = true; - continue; - } - - vertex_t* v = vertices_.push (); - if (check_success (!vertices_.in_error ())) - v->obj = *objects[i]; - if (!removed_nil) continue; - // Fix indices to account for removed nil object. - for (auto& l : v->obj.all_links_writer ()) { - l.objidx--; - } - } - } - - ~graph_t () - { - vertices_.fini (); - } - - bool in_error () const - { - return !successful || - vertices_.in_error () || - num_roots_for_space_.in_error (); - } - - const vertex_t& root () const - { - return vertices_[root_idx ()]; - } - - unsigned root_idx () const - { - // Object graphs are in reverse order, the first object is at the end - // of the vector. Since the graph is topologically sorted it's safe to - // assume the first object has no incoming edges. - return vertices_.length - 1; - } - - const hb_serialize_context_t::object_t& object(unsigned i) const - { - return vertices_[i].obj; - } - - /* - * serialize graph into the provided serialization buffer. - */ - hb_blob_t* serialize () const - { - hb_vector_t<char> buffer; - size_t size = serialized_length (); - if (!buffer.alloc (size)) { - DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer."); - return nullptr; - } - hb_serialize_context_t c((void *) buffer, size); - - c.start_serialize<void> (); - for (unsigned i = 0; i < vertices_.length; i++) { - c.push (); - - size_t size = vertices_[i].obj.tail - vertices_[i].obj.head; - char* start = c.allocate_size <char> (size); - if (!start) { - DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space."); - return nullptr; - } - - memcpy (start, vertices_[i].obj.head, size); - - // Only real links needs to be serialized. - for (const auto& link : vertices_[i].obj.real_links) - serialize_link (link, start, &c); - - // All duplications are already encoded in the graph, so don't - // enable sharing during packing. - c.pop_pack (false); - } - c.end_serialize (); - - if (c.in_error ()) { - DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d", - c.errors); - return nullptr; - } - - return c.copy_blob (); - } - - /* - * Generates a new topological sorting of graph ordered by the shortest - * distance to each node. - */ - void sort_shortest_distance () - { - positions_invalid = true; - - if (vertices_.length <= 1) { - // Graph of 1 or less doesn't need sorting. - return; - } - - update_distances (); - - hb_priority_queue_t queue; - hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_; - if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; - hb_vector_t<unsigned> id_map; - if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; - - hb_vector_t<unsigned> removed_edges; - if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return; - update_parents (); - - queue.insert (root ().modified_distance (0), root_idx ()); - int new_id = root_idx (); - unsigned order = 1; - while (!queue.in_error () && !queue.is_empty ()) - { - unsigned next_id = queue.pop_minimum().second; - - hb_swap (sorted_graph[new_id], vertices_[next_id]); - const vertex_t& next = sorted_graph[new_id]; - - id_map[next_id] = new_id--; - - for (const auto& link : next.obj.all_links ()) { - removed_edges[link.objidx]++; - if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) - // Add the order that the links were encountered to the priority. - // This ensures that ties between priorities objects are broken in a consistent - // way. More specifically this is set up so that if a set of objects have the same - // distance they'll be added to the topological order in the order that they are - // referenced from the parent object. - queue.insert (vertices_[link.objidx].modified_distance (order++), - link.objidx); - } - } - - check_success (!queue.in_error ()); - check_success (!sorted_graph.in_error ()); - if (!check_success (new_id == -1)) - print_orphaned_nodes (); - - remap_all_obj_indices (id_map, &sorted_graph); - - hb_swap (vertices_, sorted_graph); - } - - /* - * Assign unique space numbers to each connected subgraph of 32 bit offset(s). - */ - bool assign_32bit_spaces () - { - unsigned root_index = root_idx (); - hb_set_t visited; - hb_set_t roots; - for (unsigned i = 0; i <= root_index; i++) - { - // Only real links can form 32 bit spaces - for (auto& l : vertices_[i].obj.real_links) - { - if (l.width == 4 && !l.is_signed) - { - roots.add (l.objidx); - find_subgraph (l.objidx, visited); - } - } - } - - // Mark everything not in the subgraphs of 32 bit roots as visited. - // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs. - visited.invert (); - - if (!roots) return false; - - while (roots) - { - unsigned next = HB_SET_VALUE_INVALID; - if (unlikely (!check_success (!roots.in_error ()))) break; - if (!roots.next (&next)) break; - - hb_set_t connected_roots; - find_connected_nodes (next, roots, visited, connected_roots); - if (unlikely (!check_success (!connected_roots.in_error ()))) break; - - isolate_subgraph (connected_roots); - if (unlikely (!check_success (!connected_roots.in_error ()))) break; - - unsigned next_space = this->next_space (); - num_roots_for_space_.push (0); - for (unsigned root : connected_roots) - { - DEBUG_MSG (SUBSET_REPACK, nullptr, "Subgraph %u gets space %u", root, next_space); - vertices_[root].space = next_space; - num_roots_for_space_[next_space] = num_roots_for_space_[next_space] + 1; - distance_invalid = true; - positions_invalid = true; - } - - // TODO(grieger): special case for GSUB/GPOS use extension promotions to move 16 bit space - // into the 32 bit space as needed, instead of using isolation. - } - - - - return true; - } - - /* - * Isolates the subgraph of nodes reachable from root. Any links to nodes in the subgraph - * that originate from outside of the subgraph will be removed by duplicating the linked to - * object. - * - * Indices stored in roots will be updated if any of the roots are duplicated to new indices. - */ - bool isolate_subgraph (hb_set_t& roots) - { - update_parents (); - hb_hashmap_t<unsigned, unsigned> subgraph; - - // incoming edges to root_idx should be all 32 bit in length so we don't need to de-dup these - // set the subgraph incoming edge count to match all of root_idx's incoming edges - hb_set_t parents; - for (unsigned root_idx : roots) - { - subgraph.set (root_idx, wide_parents (root_idx, parents)); - find_subgraph (root_idx, subgraph); - } - - unsigned original_root_idx = root_idx (); - hb_hashmap_t<unsigned, unsigned> index_map; - bool made_changes = false; - for (auto entry : subgraph.iter ()) - { - const auto& node = vertices_[entry.first]; - unsigned subgraph_incoming_edges = entry.second; - - if (subgraph_incoming_edges < node.incoming_edges ()) - { - // Only de-dup objects with incoming links from outside the subgraph. - made_changes = true; - duplicate_subgraph (entry.first, index_map); - } - } - - if (!made_changes) - return false; - - if (original_root_idx != root_idx () - && parents.has (original_root_idx)) - { - // If the root idx has changed since parents was determined, update root idx in parents - parents.add (root_idx ()); - parents.del (original_root_idx); - } - - auto new_subgraph = - + subgraph.keys () - | hb_map([&] (unsigned node_idx) { - if (index_map.has (node_idx)) return index_map[node_idx]; - return node_idx; - }) - ; - - remap_obj_indices (index_map, new_subgraph); - remap_obj_indices (index_map, parents.iter (), true); - - // Update roots set with new indices as needed. - unsigned next = HB_SET_VALUE_INVALID; - while (roots.next (&next)) - { - if (index_map.has (next)) - { - roots.del (next); - roots.add (index_map[next]); - } - } - - return true; - } - - void find_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& subgraph) - { - for (const auto& link : vertices_[node_idx].obj.all_links ()) - { - if (subgraph.has (link.objidx)) - { - subgraph.set (link.objidx, subgraph[link.objidx] + 1); - continue; - } - subgraph.set (link.objidx, 1); - find_subgraph (link.objidx, subgraph); - } - } - - void find_subgraph (unsigned node_idx, hb_set_t& subgraph) - { - if (subgraph.has (node_idx)) return; - subgraph.add (node_idx); - for (const auto& link : vertices_[node_idx].obj.all_links ()) - find_subgraph (link.objidx, subgraph); - } - - /* - * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign - * links. index_map is updated with mappings from old id to new id. If a duplication has already - * been performed for a given index, then it will be skipped. - */ - void duplicate_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& index_map) - { - if (index_map.has (node_idx)) - return; - - index_map.set (node_idx, duplicate (node_idx)); - for (const auto& l : object (node_idx).all_links ()) { - duplicate_subgraph (l.objidx, index_map); - } - } - - /* - * Creates a copy of node_idx and returns it's new index. - */ - unsigned duplicate (unsigned node_idx) - { - positions_invalid = true; - distance_invalid = true; - - auto* clone = vertices_.push (); - auto& child = vertices_[node_idx]; - if (vertices_.in_error ()) { - return -1; - } - - clone->obj.head = child.obj.head; - clone->obj.tail = child.obj.tail; - clone->distance = child.distance; - clone->space = child.space; - clone->parents.reset (); - - unsigned clone_idx = vertices_.length - 2; - for (const auto& l : child.obj.real_links) - { - clone->obj.real_links.push (l); - vertices_[l.objidx].parents.push (clone_idx); - } - for (const auto& l : child.obj.virtual_links) - { - clone->obj.virtual_links.push (l); - vertices_[l.objidx].parents.push (clone_idx); - } - - check_success (!clone->obj.real_links.in_error ()); - check_success (!clone->obj.virtual_links.in_error ()); - - // The last object is the root of the graph, so swap back the root to the end. - // The root's obj idx does change, however since it's root nothing else refers to it. - // all other obj idx's will be unaffected. - hb_swap (vertices_[vertices_.length - 2], *clone); - - // Since the root moved, update the parents arrays of all children on the root. - for (const auto& l : root ().obj.all_links ()) - vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); - - return clone_idx; - } - - /* - * 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. - */ - bool 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++; - } - - if (vertices_[child_idx].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 %d => %d", - parent_idx, child_idx); - return false; - } - - DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d", - parent_idx, child_idx); - - unsigned clone_idx = duplicate (child_idx); - if (clone_idx == (unsigned) -1) return false; - // 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 true; - } - - /* - * Raises the sorting priority of all children. - */ - bool raise_childrens_priority (unsigned parent_idx) - { - DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d", - parent_idx); - // This operation doesn't change ordering until a sort is run, so no need - // to invalidate positions. It does not change graph structure so no need - // to update distances or edge counts. - auto& parent = vertices_[parent_idx].obj; - bool made_change = false; - for (auto& l : parent.all_links_writer ()) - made_change |= vertices_[l.objidx].raise_priority (); - return made_change; - } - - /* - * Will any offsets overflow on graph when it's serialized? - */ - bool will_overflow (hb_vector_t<overflow_record_t>* overflows = nullptr) - { - if (overflows) overflows->resize (0); - update_positions (); - - for (int parent_idx = vertices_.length - 1; parent_idx >= 0; parent_idx--) - { - // Don't need to check virtual links for overflow - for (const auto& link : vertices_[parent_idx].obj.real_links) - { - int64_t offset = compute_offset (parent_idx, link); - if (is_valid_offset (offset, link)) - continue; - - if (!overflows) return true; - - overflow_record_t r; - r.parent = parent_idx; - r.child = link.objidx; - overflows->push (r); - } - } - - if (!overflows) return false; - return overflows->length; - } - - void print_orphaned_nodes () - { - if (!DEBUG_ENABLED(SUBSET_REPACK)) return; - - DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); - parents_invalid = true; - update_parents(); - - for (unsigned i = 0; i < root_idx (); i++) - { - const auto& v = vertices_[i]; - if (!v.parents) - DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i); - } - } - - void print_overflows (const hb_vector_t<overflow_record_t>& overflows) - { - if (!DEBUG_ENABLED(SUBSET_REPACK)) return; - - update_parents (); - int limit = 10; - for (const auto& o : overflows) - { - if (!limit--) break; - const auto& parent = vertices_[o.parent]; - const auto& child = vertices_[o.child]; - DEBUG_MSG (SUBSET_REPACK, nullptr, - " overflow from " - "%4d (%4d in, %4d out, space %2d) => " - "%4d (%4d in, %4d out, space %2d)", - o.parent, - parent.incoming_edges (), - parent.obj.real_links.length + parent.obj.virtual_links.length, - space_for (o.parent), - o.child, - child.incoming_edges (), - child.obj.real_links.length + child.obj.virtual_links.length, - space_for (o.child)); - } - if (overflows.length > 10) { - DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %d more overflows.", overflows.length - 10); - } - } - - unsigned num_roots_for_space (unsigned space) const - { - return num_roots_for_space_[space]; - } - - unsigned next_space () const - { - return num_roots_for_space_.length; - } - - void move_to_new_space (const hb_set_t& indices) - { - num_roots_for_space_.push (0); - unsigned new_space = num_roots_for_space_.length - 1; - - for (unsigned index : indices) { - auto& node = vertices_[index]; - num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1; - num_roots_for_space_[new_space] = num_roots_for_space_[new_space] + 1; - node.space = new_space; - distance_invalid = true; - positions_invalid = true; - } - } - - unsigned space_for (unsigned index, unsigned* root = nullptr) const - { - const auto& node = vertices_[index]; - if (node.space) - { - if (root != nullptr) - *root = index; - return node.space; - } - - if (!node.parents) - { - if (root) - *root = index; - return 0; - } - - return space_for (node.parents[0], root); - } - - void err_other_error () { this->successful = false; } - - private: - - size_t serialized_length () const { - size_t total_size = 0; - for (unsigned i = 0; i < vertices_.length; i++) { - size_t size = vertices_[i].obj.tail - vertices_[i].obj.head; - total_size += size; - } - return total_size; - } - - /* - * Returns the numbers of incoming edges that are 32bits wide. - */ - unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const - { - unsigned count = 0; - hb_set_t visited; - for (unsigned p : vertices_[node_idx].parents) - { - if (visited.has (p)) continue; - visited.add (p); - - // Only real links can be wide - for (const auto& l : vertices_[p].obj.real_links) - { - if (l.objidx == node_idx && l.width == 4 && !l.is_signed) - { - count++; - parents.add (p); - } - } - } - return count; - } - - bool check_success (bool success) - { return this->successful && (success || (err_other_error (), false)); } - - /* - * Creates a map from objid to # of incoming edges. - */ - void update_parents () - { - if (!parents_invalid) return; - - for (unsigned i = 0; i < vertices_.length; i++) - vertices_[i].parents.reset (); - - for (unsigned p = 0; p < vertices_.length; p++) - { - for (auto& l : vertices_[p].obj.all_links ()) - { - vertices_[l.objidx].parents.push (p); - } - } - - parents_invalid = false; - } - - /* - * compute the serialized start and end positions for each vertex. - */ - void update_positions () - { - if (!positions_invalid) return; - - unsigned current_pos = 0; - for (int i = root_idx (); i >= 0; i--) - { - auto& v = vertices_[i]; - v.start = current_pos; - current_pos += v.obj.tail - v.obj.head; - v.end = current_pos; - } - - positions_invalid = false; - } - - /* - * Finds the distance to each object in the graph - * from the initial node. - */ - void update_distances () - { - if (!distance_invalid) return; - - // Uses Dijkstra's algorithm to find all of the shortest distances. - // https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm - // - // Implementation Note: - // Since our priority queue doesn't support fast priority decreases - // we instead just add new entries into the queue when a priority changes. - // Redundant ones are filtered out later on by the visited set. - // According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf - // for practical performance this is faster then using a more advanced queue - // (such as a fibonacci queue) with a fast decrease priority. - for (unsigned i = 0; i < vertices_.length; i++) - { - if (i == vertices_.length - 1) - vertices_[i].distance = 0; - else - vertices_[i].distance = hb_int_max (int64_t); - } - - hb_priority_queue_t queue; - queue.insert (0, vertices_.length - 1); - - hb_vector_t<bool> visited; - visited.resize (vertices_.length); - - while (!queue.in_error () && !queue.is_empty ()) - { - unsigned next_idx = queue.pop_minimum ().second; - if (visited[next_idx]) continue; - const auto& next = vertices_[next_idx]; - int64_t next_distance = vertices_[next_idx].distance; - visited[next_idx] = true; - - for (const auto& link : next.obj.all_links ()) - { - if (visited[link.objidx]) continue; - - const auto& child = vertices_[link.objidx].obj; - unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide - int64_t child_weight = (child.tail - child.head) + - ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1); - int64_t child_distance = next_distance + child_weight; - - if (child_distance < vertices_[link.objidx].distance) - { - vertices_[link.objidx].distance = child_distance; - queue.insert (child_distance, link.objidx); - } - } - } - - check_success (!queue.in_error ()); - if (!check_success (queue.is_empty ())) - { - print_orphaned_nodes (); - return; - } - - distance_invalid = false; - } - - int64_t compute_offset ( - unsigned parent_idx, - const hb_serialize_context_t::object_t::link_t& link) const - { - const auto& parent = vertices_[parent_idx]; - const auto& child = vertices_[link.objidx]; - int64_t offset = 0; - switch ((hb_serialize_context_t::whence_t) link.whence) { - case hb_serialize_context_t::whence_t::Head: - offset = child.start - parent.start; break; - case hb_serialize_context_t::whence_t::Tail: - offset = child.start - parent.end; break; - case hb_serialize_context_t::whence_t::Absolute: - offset = child.start; break; - } - - assert (offset >= link.bias); - offset -= link.bias; - return offset; - } - - bool is_valid_offset (int64_t offset, - const hb_serialize_context_t::object_t::link_t& link) const - { - if (unlikely (!link.width)) - // Virtual links can't overflow. - return link.is_signed || offset >= 0; - - if (link.is_signed) - { - if (link.width == 4) - return offset >= -((int64_t) 1 << 31) && offset < ((int64_t) 1 << 31); - else - return offset >= -(1 << 15) && offset < (1 << 15); - } - else - { - if (link.width == 4) - return offset >= 0 && offset < ((int64_t) 1 << 32); - else if (link.width == 3) - return offset >= 0 && offset < ((int32_t) 1 << 24); - else - return offset >= 0 && offset < (1 << 16); - } - } - - /* - * Updates a link in the graph to point to a different object. Corrects the - * parents vector on the previous and new child nodes. - */ - void reassign_link (hb_serialize_context_t::object_t::link_t& link, - unsigned parent_idx, - unsigned new_idx) - { - unsigned old_idx = link.objidx; - link.objidx = new_idx; - vertices_[old_idx].remove_parent (parent_idx); - vertices_[new_idx].parents.push (parent_idx); - } - - /* - * Updates all objidx's in all links using the provided mapping. Corrects incoming edge counts. - */ - template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> - void remap_obj_indices (const hb_hashmap_t<unsigned, unsigned>& id_map, - Iterator subgraph, - bool only_wide = false) - { - if (!id_map) return; - for (unsigned i : subgraph) - { - for (auto& link : vertices_[i].obj.all_links_writer ()) - { - if (!id_map.has (link.objidx)) continue; - if (only_wide && !(link.width == 4 && !link.is_signed)) continue; - - reassign_link (link, i, id_map[link.objidx]); - } - } - } - - /* - * Updates all objidx's in all links using the provided mapping. - */ - void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map, - hb_vector_t<vertex_t>* sorted_graph) const - { - for (unsigned i = 0; i < sorted_graph->length; i++) - { - (*sorted_graph)[i].remap_parents (id_map); - for (auto& link : (*sorted_graph)[i].obj.all_links_writer ()) - { - link.objidx = id_map[link.objidx]; - } - } - } - - template <typename O> void - serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, - char* head, - hb_serialize_context_t* c) const - { - OT::Offset<O>* offset = reinterpret_cast<OT::Offset<O>*> (head + link.position); - *offset = 0; - c->add_link (*offset, - // serializer has an extra nil object at the start of the - // object array. So all id's are +1 of what our id's are. - link.objidx + 1, - (hb_serialize_context_t::whence_t) link.whence, - link.bias); - } - - void serialize_link (const hb_serialize_context_t::object_t::link_t& link, - char* head, - hb_serialize_context_t* c) const - { - switch (link.width) - { - case 0: - // Virtual links aren't serialized. - return; - case 4: - if (link.is_signed) - { - serialize_link_of_type<OT::HBINT32> (link, head, c); - } else { - serialize_link_of_type<OT::HBUINT32> (link, head, c); - } - return; - case 2: - if (link.is_signed) - { - serialize_link_of_type<OT::HBINT16> (link, head, c); - } else { - serialize_link_of_type<OT::HBUINT16> (link, head, c); - } - return; - case 3: - serialize_link_of_type<OT::HBUINT24> (link, head, c); - return; - default: - // Unexpected link width. - assert (0); - } - } - - /* - * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped. - * For this search the graph is treated as being undirected. - * - * Connected targets will be added to connected and removed from targets. All visited nodes - * will be added to visited. - */ - void find_connected_nodes (unsigned start_idx, - hb_set_t& targets, - hb_set_t& visited, - hb_set_t& connected) - { - if (unlikely (!check_success (!visited.in_error ()))) return; - if (visited.has (start_idx)) return; - visited.add (start_idx); - - if (targets.has (start_idx)) - { - targets.del (start_idx); - connected.add (start_idx); - } - - const auto& v = vertices_[start_idx]; - - // Graph is treated as undirected so search children and parents of start_idx - for (const auto& l : v.obj.all_links ()) - find_connected_nodes (l.objidx, targets, visited, connected); - - for (unsigned p : v.parents) - find_connected_nodes (p, targets, visited, connected); - } - - public: - // TODO(garretrieger): make private, will need to move most of offset overflow code into graph. - hb_vector_t<vertex_t> vertices_; - hb_vector_t<vertex_t> vertices_scratch_; - private: - bool parents_invalid; - bool distance_invalid; - bool positions_invalid; - bool successful; - hb_vector_t<unsigned> num_roots_for_space_; -}; static inline -bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows, +bool _try_isolating_subgraphs (const hb_vector_t<graph::overflow_record_t>& overflows, graph_t& sorted_graph) { unsigned space = 0; @@ -1066,7 +51,7 @@ bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& ov for (int i = overflows.length - 1; i >= 0; i--) { - const graph_t::overflow_record_t& r = overflows[i]; + const graph::overflow_record_t& r = overflows[i]; unsigned root; unsigned overflow_space = sorted_graph.space_for (r.parent, &root); @@ -1108,7 +93,7 @@ bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& ov } static inline -bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows, +bool _process_overflows (const hb_vector_t<graph::overflow_record_t>& overflows, hb_set_t& priority_bumped_parents, graph_t& sorted_graph) { @@ -1117,7 +102,7 @@ bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflow // Try resolving the furthest overflows first. for (int i = overflows.length - 1; i >= 0; i--) { - const graph_t::overflow_record_t& r = overflows[i]; + const graph::overflow_record_t& r = overflows[i]; const auto& child = sorted_graph.vertices_[r.child]; if (child.is_shared ()) { @@ -1173,19 +158,18 @@ inline hb_blob_t* hb_resolve_overflows (const T& packed, hb_tag_t table_tag, unsigned max_rounds = 20) { - // Kahn sort is ~twice as fast as shortest distance sort and works for many fonts - // so try it first to save time. graph_t sorted_graph (packed); - if (!sorted_graph.will_overflow ()) + sorted_graph.sort_shortest_distance (); + + bool will_overflow = graph::will_overflow (sorted_graph); + if (!will_overflow) { - return sorted_graph.serialize (); + return graph::serialize (sorted_graph); } - sorted_graph.sort_shortest_distance (); - if ((table_tag == HB_OT_TAG_GPOS || table_tag == HB_OT_TAG_GSUB) - && sorted_graph.will_overflow ()) + && will_overflow) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs."); if (sorted_graph.assign_32bit_spaces ()) @@ -1193,13 +177,13 @@ hb_resolve_overflows (const T& packed, } unsigned round = 0; - hb_vector_t<graph_t::overflow_record_t> overflows; + hb_vector_t<graph::overflow_record_t> overflows; // TODO(garretrieger): select a good limit for max rounds. while (!sorted_graph.in_error () - && sorted_graph.will_overflow (&overflows) + && graph::will_overflow (sorted_graph, &overflows) && round++ < max_rounds) { DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Overflow resolution round %d ===", round); - sorted_graph.print_overflows (overflows); + print_overflows (sorted_graph, overflows); hb_set_t priority_bumped_parents; @@ -1221,13 +205,13 @@ hb_resolve_overflows (const T& packed, return nullptr; } - if (sorted_graph.will_overflow ()) + if (graph::will_overflow (sorted_graph)) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed."); return nullptr; } - return sorted_graph.serialize (); + return graph::serialize (sorted_graph); } #endif /* HB_REPACKER_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh index 5663b290c3b..cecdcdeb748 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh @@ -695,7 +695,7 @@ struct hb_serialize_context_t check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW); } - public: /* TODO Make private. */ + public: char *start, *head, *tail, *end; unsigned int debug_depth; hb_serialize_error_t errors; @@ -719,9 +719,7 @@ struct hb_serialize_context_t hb_vector_t<object_t *> packed; /* Map view of packed objects. */ - hb_hashmap_t<const object_t *, objidx_t, - const object_t *, objidx_t, - nullptr, 0> packed_map; + hb_hashmap_t<const object_t *, objidx_t> packed_map; }; #endif /* HB_SERIALIZE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh index 7d4979b73bd..fab36216e40 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh @@ -30,7 +30,7 @@ #include "hb.hh" /* - * The set digests here implement various "filters" that support + * The set-digests here implement various "filters" that support * "approximate member query". Conceptually these are like Bloom * Filter and Quotient Filter, however, much smaller, faster, and * designed to fit the requirements of our uses for glyph coverage @@ -40,13 +40,25 @@ * set of glyphs, but fully flooded and ineffective if coverage is * all over the place. * - * The frozen-set can be used instead of a digest, to trade more - * memory for 100% accuracy, but in practice, that doesn't look like - * an attractive trade-off. + * The way these are used is that the filter is first populated by + * a lookup's or subtable's Coverage table(s), and then when we + * want to apply the lookup or subtable to a glyph, before trying + * to apply, we ask the filter if the glyph may be covered. If it's + * not, we return early. + * + * We use these filters both at the lookup-level, and then again, + * at the subtable-level. Both have performance win. + * + * The main filter we use is a combination of three 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. + * The accepted patterns are represented as a "long" integer. The + * check is done using four bitwise operations only. */ template <typename mask_t, unsigned int shift> -struct hb_set_digest_lowest_bits_t +struct hb_set_digest_bits_pattern_t { static constexpr unsigned mask_bytes = sizeof (mask_t); static constexpr unsigned mask_bits = sizeof (mask_t) * 8; @@ -102,7 +114,7 @@ struct hb_set_digest_lowest_bits_t bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } bool may_have (hb_codepoint_t g) const - { return !!(mask & mask_for (g)); } + { return mask & mask_for (g); } private: @@ -171,11 +183,11 @@ struct hb_set_digest_combiner_t using hb_set_digest_t = hb_set_digest_combiner_t < - hb_set_digest_lowest_bits_t<unsigned long, 4>, + hb_set_digest_bits_pattern_t<unsigned long, 4>, hb_set_digest_combiner_t < - hb_set_digest_lowest_bits_t<unsigned long, 0>, - hb_set_digest_lowest_bits_t<unsigned long, 9> + hb_set_digest_bits_pattern_t<unsigned long, 0>, + hb_set_digest_bits_pattern_t<unsigned long, 9> > > ; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc index 0e2c1f77efe..2d458294f8a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc @@ -40,7 +40,7 @@ /** - * hb_set_create: (Xconstructor) + * hb_set_create: * * Creates a new, initially empty set. * @@ -186,6 +186,7 @@ hb_set_t * hb_set_copy (const hb_set_t *set) { hb_set_t *copy = hb_set_create (); + if (unlikely (!copy)) return nullptr; copy->set (*set); return copy; } @@ -359,6 +360,23 @@ hb_set_is_equal (const hb_set_t *set, } /** + * hb_set_hash: + * @set: A set + * + * Creates a hash representing @set. + * + * Return value: + * A hash of @set. + * + * Since: 4.4.0 + **/ +HB_EXTERN unsigned int +hb_set_hash (const hb_set_t *set) +{ + return set->hash (); +} + +/** * hb_set_is_subset: * @set: A set * @larger_set: Another set diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h index 10ce7c10d41..56902c267ec 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h @@ -128,6 +128,9 @@ HB_EXTERN hb_bool_t hb_set_is_equal (const hb_set_t *set, const hb_set_t *other); +HB_EXTERN unsigned int +hb_set_hash (const hb_set_t *set); + HB_EXTERN hb_bool_t hb_set_is_subset (const hb_set_t *set, const hb_set_t *larger_set); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh index 60256263637..7eb5e19a2a6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh @@ -166,7 +166,6 @@ struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t> ~hb_set_t () = default; hb_set_t () : sparseset () {}; - hb_set_t (std::nullptr_t) : hb_set_t () {}; 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& operator = (const hb_set_t&) = default; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc index 66332165c37..0af07825fc9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc @@ -170,7 +170,7 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other) /** - * hb_shape_plan_create: (Xconstructor) + * hb_shape_plan_create: * @face: #hb_face_t to use * @props: The #hb_segment_properties_t of the segment * @user_features: (array length=num_user_features): The list of user-selected features @@ -198,7 +198,7 @@ hb_shape_plan_create (hb_face_t *face, } /** - * hb_shape_plan_create2: (Xconstructor) + * hb_shape_plan_create2: * @face: #hb_face_t to use * @props: The #hb_segment_properties_t of the segment * @user_features: (array length=num_user_features): The list of user-selected features @@ -231,7 +231,8 @@ hb_shape_plan_create2 (hb_face_t *face, num_coords, shaper_list); - assert (props->direction != HB_DIRECTION_INVALID); + if (unlikely (props->direction == HB_DIRECTION_INVALID)) + return hb_shape_plan_get_empty (); hb_shape_plan_t *shape_plan; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc index 3407e1af42d..14ec92828fc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc @@ -50,7 +50,7 @@ static inline void free_static_shaper_list (); -static const char *nil_shaper_list[] = {nullptr}; +static const char * const nil_shaper_list[] = {nullptr}; static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, hb_shaper_list_lazy_loader_t> @@ -73,7 +73,7 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, } static void destroy (const char **l) { hb_free (l); } - static const char ** get_null () + static const char * const * get_null () { return nil_shaper_list; } } static_shaper_list; @@ -126,6 +126,11 @@ hb_shape_full (hb_font_t *font, unsigned int num_features, const char * const *shaper_list) { + if (unlikely (!buffer->len)) + return true; + + buffer->enter (); + hb_buffer_t *text_buffer = nullptr; if (buffer->flags & HB_BUFFER_FLAG_VERIFY) { @@ -137,12 +142,19 @@ hb_shape_full (hb_font_t *font, features, num_features, font->coords, font->num_coords, shaper_list); + hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); + + if (buffer->max_ops <= 0) + buffer->shaping_failed = true; + hb_shape_plan_destroy (shape_plan); if (text_buffer) { - if (res && !buffer->verify (text_buffer, + if (res && buffer->successful && !buffer->shaping_failed + && text_buffer->successful + && !buffer->verify (text_buffer, font, features, num_features, @@ -151,6 +163,8 @@ hb_shape_full (hb_font_t *font, hb_buffer_destroy (text_buffer); } + buffer->leave (); + return res; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc index a11ed83afd3..da4253ed649 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc @@ -29,18 +29,18 @@ #include "hb-machinery.hh" -static const hb_shaper_entry_t all_shapers[] = { +static const hb_shaper_entry_t _hb_all_shapers[] = { #define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape}, #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT }; #ifndef HB_NO_SHAPER -static_assert (0 != ARRAY_LENGTH_CONST (all_shapers), "No shaper enabled."); +static_assert (0 != ARRAY_LENGTH_CONST (_hb_all_shapers), "No shaper enabled."); #endif static inline void free_static_shapers (); -static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_t, +static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<hb_shaper_entry_t, hb_shapers_lazy_loader_t> { static hb_shaper_entry_t *create () @@ -49,11 +49,11 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_ if (!env || !*env) return nullptr; - hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) hb_calloc (1, sizeof (all_shapers)); + hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) hb_calloc (1, sizeof (_hb_all_shapers)); if (unlikely (!shapers)) return nullptr; - memcpy (shapers, all_shapers, sizeof (all_shapers)); + memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers)); /* Reorder shaper list to prefer requested shapers. */ unsigned int i = 0; @@ -64,7 +64,7 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_ if (!end) end = p + strlen (p); - for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++) + for (unsigned int j = i; j < ARRAY_LENGTH (_hb_all_shapers); j++) if (end - p == (int) strlen (shapers[j].name) && 0 == strncmp (shapers[j].name, p, end - p)) { @@ -85,8 +85,8 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_ return shapers; } - static void destroy (const hb_shaper_entry_t *p) { hb_free ((void *) p); } - static const hb_shaper_entry_t *get_null () { return all_shapers; } + static void destroy (hb_shaper_entry_t *p) { hb_free (p); } + static const hb_shaper_entry_t *get_null () { return _hb_all_shapers; } } static_shapers; static inline diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh index ae155b4e3c8..bb9f27eec12 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh @@ -44,7 +44,8 @@ struct str_encoder_t void encode_byte (unsigned char b) { - if (unlikely (buff.push (b) == &Crap (unsigned char))) + buff.push (b); + if (unlikely (buff.in_error ())) set_error (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc index 48852809967..028ddf9035e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc @@ -140,7 +140,20 @@ hb_subset_input_create_or_fail (void) HB_TAG ('r', 't', 'l', 'a'), HB_TAG ('r', 't', 'l', 'm'), - //Complex shapers + //random + HB_TAG ('r', 'a', 'n', 'd'), + + //justify + HB_TAG ('j', 'a', 'l', 't'), // HarfBuzz doesn't use; others might + + //private + HB_TAG ('H', 'a', 'r', 'f'), + HB_TAG ('H', 'A', 'R', 'F'), + HB_TAG ('B', 'u', 'z', 'z'), + HB_TAG ('B', 'U', 'Z', 'Z'), + + //shapers + //arabic HB_TAG ('i', 'n', 'i', 't'), HB_TAG ('m', 'e', 'd', 'i'), diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc index a62ae8e0245..7a0baecabf7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc @@ -43,7 +43,7 @@ using OT::Layout::GSUB::GSUB; -typedef hb_hashmap_t<unsigned, hb_set_t *> script_langsys_map; +typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline void _add_cff_seac_components (const OT::cff1::accelerator_t &cff, @@ -347,13 +347,42 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, } } +#ifndef HB_COMPOSITE_OPERATIONS_PER_GLYPH +#define HB_COMPOSITE_OPERATIONS_PER_GLYPH 64 +#endif + +static unsigned +_glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, + hb_codepoint_t gid, + hb_set_t *gids_to_retain, + int operation_count, + unsigned depth = 0) +{ + if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count; + if (unlikely (--operation_count < 0)) return operation_count; + /* Check if is already visited */ + if (gids_to_retain->has (gid)) return operation_count; + + gids_to_retain->add (gid); + + for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ()) + operation_count = + _glyf_add_gid_and_children (glyf, + item.glyphIndex, + gids_to_retain, + operation_count, + depth); + + return operation_count; +} + static void _populate_gids_to_retain (hb_subset_plan_t* plan, bool close_over_gsub, bool close_over_gpos, bool close_over_gdef) { - OT::glyf::accelerator_t glyf (plan->source); + OT::glyf_accelerator_t glyf (plan->source); #ifndef HB_NO_SUBSET_CFF OT::cff1::accelerator_t cff (plan->source); #endif @@ -398,7 +427,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, * composite glyphs. */ if (glyf.has_data ()) for (hb_codepoint_t gid : cur_glyphset) - glyf.add_gid_and_children (gid, plan->_glyphset); + _glyf_add_gid_and_children (glyf, gid, plan->_glyphset, + cur_glyphset.get_population () * HB_COMPOSITE_OPERATIONS_PER_GLYPH); else plan->_glyphset->union_ (cur_glyphset); #ifndef HB_NO_SUBSET_CFF @@ -630,9 +660,6 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) if (plan->gsub_langsys) { - for (auto _ : plan->gsub_langsys->iter ()) - hb_set_destroy (_.second); - hb_object_destroy (plan->gsub_langsys); plan->gsub_langsys->fini_shallow (); hb_free (plan->gsub_langsys); @@ -640,9 +667,6 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) if (plan->gpos_langsys) { - for (auto _ : plan->gpos_langsys->iter ()) - hb_set_destroy (_.second); - hb_object_destroy (plan->gpos_langsys); plan->gpos_langsys->fini_shallow (); hb_free (plan->gpos_langsys); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh index cb567b769ea..2aaf19c61de 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh @@ -87,8 +87,8 @@ struct hb_subset_plan_t hb_map_t *gpos_lookups; //active langsys we'd like to retain - hb_hashmap_t<unsigned, hb_set_t *> *gsub_langsys; - hb_hashmap_t<unsigned, hb_set_t *> *gpos_langsys; + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *gsub_langsys; + hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *gpos_langsys; //active features after removing redundant langsys and prune_features hb_map_t *gsub_features; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index 31ddb4f8940..428a9dd1286 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -78,6 +78,108 @@ using OT::Layout::GSUB::GSUB; * retain glyph ids option and configure the subset to pass through the layout tables untouched. */ +/* + * The list of tables in the open type spec. Used to check for tables that may need handling + * if we are unable to list the tables in a face. + */ +static hb_tag_t known_tables[] { + HB_TAG ('a', 'v', 'a', 'r'), + HB_OT_TAG_BASE, + HB_OT_TAG_CBDT, + HB_OT_TAG_CBLC, + HB_OT_TAG_cff1, + HB_OT_TAG_cff2, + HB_OT_TAG_cmap, + HB_OT_TAG_COLR, + HB_OT_TAG_CPAL, + HB_TAG ('c', 'v', 'a', 'r'), + HB_TAG ('c', 'v', 't', ' '), + HB_TAG ('D', 'S', 'I', 'G'), + HB_TAG ('E', 'B', 'D', 'T'), + HB_TAG ('E', 'B', 'L', 'C'), + HB_TAG ('E', 'B', 'S', 'C'), + HB_TAG ('f', 'p', 'g', 'm'), + HB_TAG ('f', 'v', 'a', 'r'), + HB_TAG ('g', 'a', 's', 'p'), + HB_OT_TAG_GDEF, + HB_OT_TAG_glyf, + HB_OT_TAG_GPOS, + HB_OT_TAG_GSUB, + HB_OT_TAG_gvar, + HB_OT_TAG_hdmx, + HB_OT_TAG_head, + HB_OT_TAG_hhea, + HB_OT_TAG_hmtx, + HB_OT_TAG_HVAR, + HB_OT_TAG_JSTF, + HB_TAG ('k', 'e', 'r', 'n'), + HB_OT_TAG_loca, + HB_TAG ('L', 'T', 'S', 'H'), + HB_OT_TAG_MATH, + HB_OT_TAG_maxp, + HB_TAG ('M', 'E', 'R', 'G'), + HB_TAG ('m', 'e', 't', 'a'), + HB_TAG ('M', 'V', 'A', 'R'), + HB_TAG ('P', 'C', 'L', 'T'), + HB_OT_TAG_post, + HB_TAG ('p', 'r', 'e', 'p'), + HB_OT_TAG_sbix, + HB_TAG ('S', 'T', 'A', 'T'), + HB_TAG ('S', 'V', 'G', ' '), + HB_TAG ('V', 'D', 'M', 'X'), + HB_OT_TAG_vhea, + HB_OT_TAG_vmtx, + HB_OT_TAG_VORG, + HB_OT_TAG_VVAR, + HB_OT_TAG_name, + HB_OT_TAG_OS2 +}; + +static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag) +{ + hb_blob_t* blob = hb_face_reference_table (face, tag); + bool result = (blob == hb_blob_get_empty ()); + hb_blob_destroy (blob); + return result; +} + +static unsigned int +_get_table_tags (const hb_subset_plan_t* plan, + unsigned int start_offset, + unsigned int *table_count, /* IN/OUT */ + hb_tag_t *table_tags /* OUT */) +{ + unsigned num_tables = hb_face_get_table_tags (plan->source, 0, nullptr, nullptr); + if (num_tables) + return hb_face_get_table_tags (plan->source, start_offset, table_count, table_tags); + + // If face has 0 tables associated with it, assume that it was built from + // hb_face_create_tables and thus is unable to list its tables. Fallback to + // checking each table type we can handle for existence instead. + auto it = + hb_concat ( + + hb_array (known_tables) + | hb_filter ([&] (hb_tag_t tag) { + return !_table_is_empty (plan->source, tag) && !plan->no_subset_tables->has (tag); + }) + | hb_map ([] (hb_tag_t tag) -> hb_tag_t { return tag; }), + + plan->no_subset_tables->iter () + | hb_filter([&] (hb_tag_t tag) { + return !_table_is_empty (plan->source, tag); + })); + + it += start_offset; + + unsigned num_written = 0; + while (bool (it) && num_written < *table_count) + table_tags[num_written++] = *it++; + + *table_count = num_written; + return num_written; +} + + static unsigned _plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned table_len, @@ -224,9 +326,17 @@ _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf) static bool _is_table_present (hb_face_t *source, hb_tag_t tag) { + + if (!hb_face_get_table_tags (source, 0, nullptr, nullptr)) { + // If face has 0 tables associated with it, assume that it was built from + // hb_face_create_tables and thus is unable to list its tables. Fallback to + // checking if the blob associated with tag is empty. + return !_table_is_empty (source, tag); + } + hb_tag_t table_tags[32]; unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags); - while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables)) + while (((void) hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables)) { for (unsigned i = 0; i < num_tables; ++i) if (table_tags[i] == tag) @@ -388,7 +498,8 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags); hb_vector_t<char> buf; buf.alloc (4096 - 16); - while ((hb_face_get_table_tags (plan->source, offset, &num_tables, table_tags), num_tables)) + + while (((void) _get_table_tags (plan, offset, &num_tables, table_tags), num_tables)) { for (unsigned i = 0; i < num_tables; ++i) { @@ -400,7 +511,7 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) } offset += num_tables; } -end: +end: return success ? hb_face_reference (plan->dest) : nullptr; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh index 1a4c89c17fc..9e76ca460b2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh @@ -13,7 +13,7 @@ #include "hb.hh" static const hb_script_t -_hb_ucd_sc_map[162] = +_hb_ucd_sc_map[163] = { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -96,6 +96,7 @@ _hb_ucd_sc_map[162] = HB_SCRIPT_YEZIDI, HB_SCRIPT_CYPRO_MINOAN, HB_SCRIPT_OLD_UYGHUR, HB_SCRIPT_TANGSA, HB_SCRIPT_TOTO, HB_SCRIPT_VITHKUQI, + HB_SCRIPT_MATH, }; static const uint16_t _hb_ucd_dm1_p0_map[825] = diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc index 83ead6398b3..05f74b92377 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc @@ -169,7 +169,7 @@ hb_unicode_funcs_get_default () #endif /** - * hb_unicode_funcs_create: (Xconstructor) + * hb_unicode_funcs_create: * @parent: (nullable): Parent Unicode-functions structure * * Creates a new #hb_unicode_funcs_t structure of Unicode functions. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh index 4c28bb0cdfa..39aaee5baa7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh @@ -105,12 +105,9 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE unsigned int modified_combining_class (hb_codepoint_t u) { - /* XXX This hack belongs to the USE shaper (for Tai Tham): - * Reorder SAKOT to ensure it comes after any tone marks. */ + /* Reorder SAKOT to ensure it comes after any tone marks. */ if (unlikely (u == 0x1A60u)) return 254; - - /* XXX This hack belongs to the Tibetan shaper: - * Reorder PADMA to ensure it comes after any vowel marks. */ + /* Reorder PADMA to ensure it comes after any vowel marks. */ if (unlikely (u == 0x0FC6u)) return 254; /* Reorder TSA -PHRU to reorder before U+0F74 */ if (unlikely (u == 0x0F39u)) return 127; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh index b9f5f71415e..8ec638a2b43 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh @@ -29,7 +29,6 @@ #ifndef HB_HH #define HB_HH - #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC #ifdef _MSC_VER #pragma warning( disable: 4068 ) /* Unknown pragma */ @@ -65,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 "-Wcomma" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" #pragma GCC diagnostic error "-Wembedded-directive" #pragma GCC diagnostic error "-Wextra-semi-stmt" @@ -183,7 +183,7 @@ #include <cassert> #include <cfloat> #include <climits> -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) # define _USE_MATH_DEFINES #endif #include <cmath> @@ -470,6 +470,7 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); /* Headers we include for everyone. Keep topologically sorted by dependency. * They express dependency amongst themselves, but no other file should include * them directly.*/ +#include "hb-cplusplus.hh" #include "hb-meta.hh" #include "hb-mutex.hh" #include "hb-number.hh" diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build b/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build index affb40fdf41..6d7666fd77c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build @@ -92,6 +92,15 @@ hb_base_sources = files( 'hb-ot-layout-gdef-table.hh', 'hb-ot-layout-gpos-table.hh', 'hb-ot-layout-gsub-table.hh', + 'OT/glyf/glyf.hh', + 'OT/glyf/glyf-helpers.hh', + 'OT/glyf/loca.hh', + 'OT/glyf/path-builder.hh', + 'OT/glyf/Glyph.hh', + 'OT/glyf/GlyphHeader.hh', + 'OT/glyf/SimpleGlyph.hh', + 'OT/glyf/CompositeGlyph.hh', + 'OT/glyf/SubsetGlyph.hh', 'OT/Layout/GSUB/Common.hh', 'OT/Layout/GSUB/Sequence.hh', 'OT/Layout/GSUB/SingleSubstFormat1.hh', @@ -135,30 +144,29 @@ hb_base_sources = files( 'hb-ot-os2-unicode-ranges.hh', 'hb-ot-post-macroman.hh', 'hb-ot-post-table.hh', - 'hb-ot-shape-complex-arabic-fallback.hh', - 'hb-ot-shape-complex-arabic-joining-list.hh', - 'hb-ot-shape-complex-arabic-table.hh', - 'hb-ot-shape-complex-arabic-win1256.hh', - 'hb-ot-shape-complex-arabic.cc', - 'hb-ot-shape-complex-arabic.hh', - 'hb-ot-shape-complex-default.cc', - 'hb-ot-shape-complex-hangul.cc', - 'hb-ot-shape-complex-hebrew.cc', - 'hb-ot-shape-complex-indic-table.cc', - 'hb-ot-shape-complex-indic.cc', - 'hb-ot-shape-complex-indic.hh', - 'hb-ot-shape-complex-khmer.cc', - 'hb-ot-shape-complex-khmer.hh', - 'hb-ot-shape-complex-myanmar.cc', - 'hb-ot-shape-complex-myanmar.hh', - 'hb-ot-shape-complex-syllabic.cc', - 'hb-ot-shape-complex-syllabic.hh', - 'hb-ot-shape-complex-thai.cc', - 'hb-ot-shape-complex-use-table.hh', - 'hb-ot-shape-complex-use.cc', - 'hb-ot-shape-complex-vowel-constraints.cc', - 'hb-ot-shape-complex-vowel-constraints.hh', - 'hb-ot-shape-complex.hh', + 'hb-ot-shaper-arabic-fallback.hh', + 'hb-ot-shaper-arabic-joining-list.hh', + 'hb-ot-shaper-arabic-pua.hh', + 'hb-ot-shaper-arabic-table.hh', + 'hb-ot-shaper-arabic-win1256.hh', + 'hb-ot-shaper-arabic.cc', + 'hb-ot-shaper-arabic.hh', + 'hb-ot-shaper-default.cc', + 'hb-ot-shaper-hangul.cc', + 'hb-ot-shaper-hebrew.cc', + 'hb-ot-shaper-indic-table.cc', + 'hb-ot-shaper-indic.cc', + 'hb-ot-shaper-indic.hh', + 'hb-ot-shaper-khmer.cc', + 'hb-ot-shaper-myanmar.cc', + 'hb-ot-shaper-syllabic.cc', + 'hb-ot-shaper-syllabic.hh', + 'hb-ot-shaper-thai.cc', + 'hb-ot-shaper-use-table.hh', + 'hb-ot-shaper-use.cc', + 'hb-ot-shaper-vowel-constraints.cc', + 'hb-ot-shaper-vowel-constraints.hh', + 'hb-ot-shaper.hh', 'hb-ot-shape-fallback.cc', 'hb-ot-shape-fallback.hh', 'hb-ot-shape-normalize.cc', @@ -206,19 +214,19 @@ hb_base_ragel_generated_sources = files( 'hb-buffer-deserialize-json.hh', 'hb-buffer-deserialize-text.hh', 'hb-number-parser.hh', - 'hb-ot-shape-complex-indic-machine.hh', - 'hb-ot-shape-complex-khmer-machine.hh', - 'hb-ot-shape-complex-myanmar-machine.hh', - 'hb-ot-shape-complex-use-machine.hh', + 'hb-ot-shaper-indic-machine.hh', + 'hb-ot-shaper-khmer-machine.hh', + 'hb-ot-shaper-myanmar-machine.hh', + 'hb-ot-shaper-use-machine.hh', ) hb_base_ragel_sources = [ 'hb-buffer-deserialize-json.rl', 'hb-buffer-deserialize-text.rl', 'hb-number-parser.rl', - 'hb-ot-shape-complex-indic-machine.rl', - 'hb-ot-shape-complex-khmer-machine.rl', - 'hb-ot-shape-complex-myanmar-machine.rl', - 'hb-ot-shape-complex-use-machine.rl', + 'hb-ot-shaper-indic-machine.rl', + 'hb-ot-shaper-khmer-machine.rl', + 'hb-ot-shaper-myanmar-machine.rl', + 'hb-ot-shaper-use-machine.rl', ] hb_base_headers = files( @@ -227,6 +235,7 @@ hb_base_headers = files( 'hb-blob.h', 'hb-buffer.h', 'hb-common.h', + 'hb-cplusplus.hh', 'hb-deprecated.h', 'hb-draw.h', 'hb-face.h', @@ -324,7 +333,9 @@ if not has_ragel and get_option('ragel_subproject') has_ragel = true endif if not has_ragel - warning('You have to install ragel if you are going to develop HarfBuzz itself') + if not meson.is_subproject() + warning('You have to install ragel if you are going to develop HarfBuzz itself') + endif else ragel_helper = find_program('gen-ragel-artifacts.py') foreach rl : hb_base_ragel_sources @@ -674,7 +685,7 @@ if have_gobject nsversion: '0.0', identifier_prefix: 'hb_', symbol_prefix: ['hb', 'hb_gobject'], - includes: ['GObject-2.0'], + includes: ['GObject-2.0', 'freetype2-2.0'], export_packages: ['harfbuzz-gobject'], header: 'hb-gobject.h', install: true, @@ -715,6 +726,7 @@ if get_option('tests').enabled() env = environment() env.set('srcdir', meson.current_source_dir()) + env.set('base_srcdir', meson.source_root()) env.set('builddir', meson.current_build_dir()) env.set('libs', meson.current_build_dir()) # TODO: Merge this with builddir after autotools removal HBSOURCES = [] diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-algs.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-algs.cc index f8b8ff66682..450a7c439b7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-algs.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-algs.cc @@ -26,6 +26,7 @@ #include "hb.hh" #include "hb-algs.hh" +#include "hb-set.hh" static char * @@ -91,5 +92,19 @@ main (int argc, char **argv) assert (++hb_inc (x) == 3); assert (x == 3); + hb_set_t set1 {1}; + hb_set_t set2 {2}; + + assert (hb_hash (set1) != hb_hash (set2)); + assert (hb_hash (set1) == hb_hash (hb_set_t {1})); + assert (hb_hash (set1) != hb_hash (hb_set_t {})); + assert (hb_hash (set1) != hb_hash (hb_set_t {2})); + assert (hb_hash (set2) == hb_hash (hb_set_t {2})); + + /* hb_hash, unlike std::hash, dereferences pointers. */ + assert (hb_hash (set1) == hb_hash (&set1)); + assert (hb_hash (set1) == hb_hash (hb::shared_ptr<hb_set_t> {hb_set_reference (&set1)})); + assert (hb_hash (set1) == hb_hash (hb::unique_ptr<hb_set_t> {hb_set_reference (&set1)})); + return 0; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc index 721edefe37b..4cb248bd40e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc @@ -20,7 +20,6 @@ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * */ #include "hb.hh" @@ -28,11 +27,6 @@ #include "hb-set.hh" #include <string> -static const std::string invalid{"invalid"}; -static const hb_map_t invalid_map{}; -static const hb_set_t invalid_set{}; -static const hb_vector_t<unsigned> invalid_vector{}; - int main (int argc, char **argv) { @@ -128,19 +122,19 @@ main (int argc, char **argv) /* Test class key / value types. */ { - hb_hashmap_t<hb_bytes_t, int, std::nullptr_t, int, nullptr, 0> m1; - hb_hashmap_t<int, hb_bytes_t, int, std::nullptr_t, 0, nullptr> m2; - hb_hashmap_t<hb_bytes_t, hb_bytes_t, std::nullptr_t, std::nullptr_t, nullptr, nullptr> m3; + hb_hashmap_t<hb_bytes_t, int> m1; + hb_hashmap_t<int, hb_bytes_t> m2; + hb_hashmap_t<hb_bytes_t, hb_bytes_t> m3; assert (m1.get_population () == 0); assert (m2.get_population () == 0); assert (m3.get_population () == 0); } { - hb_hashmap_t<int, int, int, int, 0, 0> m0; - hb_hashmap_t<std::string, int, const std::string*, int, &invalid, 0> m1; - hb_hashmap_t<int, std::string, int, const std::string*, 0, &invalid> m2; - hb_hashmap_t<std::string, std::string, const std::string*, const std::string*, &invalid, &invalid> m3; + hb_hashmap_t<int, int> m0; + hb_hashmap_t<std::string, int> m1; + hb_hashmap_t<int, std::string> m2; + hb_hashmap_t<std::string, std::string> m3; std::string s; for (unsigned i = 1; i < 1000; i++) @@ -157,70 +151,59 @@ main (int argc, char **argv) { using pair = hb_pair_t<hb_codepoint_t, hb_codepoint_t>; - hb_hashmap_t<hb_map_t, hb_map_t, const hb_map_t *, const hb_map_t *, &invalid_map, &invalid_map> m1; - hb_hashmap_t<hb_map_t, hb_map_t, std::nullptr_t, std::nullptr_t, nullptr, nullptr> m2; + hb_hashmap_t<hb_map_t, hb_map_t> m1; m1.set (hb_map_t (), hb_map_t {}); - m2.set (hb_map_t (), hb_map_t {}); - m1.set (hb_map_t (), hb_map_t {pair (1u, 2u)}); - m2.set (hb_map_t (), hb_map_t {pair (1u, 2u)}); - m1.set (hb_map_t {pair (1u, 2u)}, hb_map_t {pair (2u, 3u)}); - m2.set (hb_map_t {pair (1u, 2u)}, hb_map_t {pair (2u, 3u)}); - - /* Cannot override empty map. */ - assert (m1.get (hb_map_t ()) == hb_map_t ()); - assert (m2.get (hb_map_t ()) == hb_map_t ()); - assert (m1.get (hb_map_t {pair (1u, 2u)}) == hb_map_t {pair (2u, 3u)}); - assert (m2.get (hb_map_t {pair (1u, 2u)}) == hb_map_t {pair (2u, 3u)}); + assert (m1.get (hb_map_t ()) == hb_map_t {pair (1u, 2u)}); + assert (m1.get (hb_map_t {pair (1u, 2u)}) == hb_map_t {pair (2u, 3u)}); } /* Test hashing sets. */ { - hb_hashmap_t<hb_set_t, hb_set_t, const hb_set_t *, const hb_set_t *, &invalid_set, &invalid_set> m1; - hb_hashmap_t<hb_set_t, hb_set_t, std::nullptr_t, std::nullptr_t, nullptr, nullptr> m2; + hb_hashmap_t<hb_set_t, hb_set_t> m1; m1.set (hb_set_t (), hb_set_t ()); - m2.set (hb_set_t (), hb_set_t ()); - m1.set (hb_set_t (), hb_set_t {1}); - m2.set (hb_set_t (), hb_set_t {1}); - m1.set (hb_set_t {1, 1000}, hb_set_t {2}); - m2.set (hb_set_t {1, 1000}, hb_set_t {2}); - - /* Cannot override empty set. */ - assert (m1.get (hb_set_t ()) == hb_set_t ()); - assert (m2.get (hb_set_t ()) == hb_set_t ()); + assert (m1.get (hb_set_t ()) == hb_set_t {1}); assert (m1.get (hb_set_t {1000, 1}) == hb_set_t {2}); - assert (m2.get (hb_set_t {1000, 1}) == hb_set_t {2}); } /* Test hashing vectors. */ { using vector_t = hb_vector_t<unsigned>; - hb_hashmap_t<vector_t, vector_t, const vector_t *, const vector_t *, &invalid_vector, &invalid_vector> m1; - hb_hashmap_t<vector_t, vector_t, std::nullptr_t, std::nullptr_t, nullptr, nullptr> m2; + hb_hashmap_t<vector_t, vector_t> m1; m1.set (vector_t (), vector_t ()); - m2.set (vector_t (), vector_t ()); - m1.set (vector_t (), vector_t {1}); - m2.set (vector_t (), vector_t {1}); - m1.set (vector_t {1}, vector_t {2}); - m2.set (vector_t {1}, vector_t {2}); - - /* Cannot override empty vector. */ - assert (m1.get (vector_t ()) == vector_t ()); - assert (m2.get (vector_t ()) == vector_t ()); + assert (m1.get (vector_t ()) == vector_t {1}); assert (m1.get (vector_t {1}) == vector_t {2}); - assert (m2.get (vector_t {1}) == vector_t {2}); + } + + /* Test hb::shared_ptr. */ + hb_hash (hb::shared_ptr<hb_set_t> ()); + { + hb_hashmap_t<hb::shared_ptr<hb_set_t>, hb::shared_ptr<hb_set_t>> m; + + m.get (hb::shared_ptr<hb_set_t> ()); + m.get (hb::shared_ptr<hb_set_t> (hb_set_get_empty ())); + m.iter (); + } + /* Test hb::unique_ptr. */ + hb_hash (hb::unique_ptr<hb_set_t> ()); + { + hb_hashmap_t<hb::unique_ptr<hb_set_t>, hb::unique_ptr<hb_set_t>> m; + + m.get (hb::unique_ptr<hb_set_t> ()); + m.get (hb::unique_ptr<hb_set_t> (hb_set_get_empty ())); + m.iter_ref (); } return 0; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc index 17e0d267ac2..69863b562f2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc @@ -28,6 +28,7 @@ #include "hb-repacker.hh" #include "hb-open-type.hh" +#include "graph/serialize.hh" static void start_object(const char* tag, unsigned len, @@ -931,7 +932,7 @@ test_serialize () hb_bytes_t expected = c1.copy_bytes (); graph_t graph (c1.object_graph ()); - hb_blob_t* out = graph.serialize (); + hb_blob_t* out = graph::serialize (graph); free (buffer_1); hb_bytes_t actual = out->as_bytes (); @@ -948,7 +949,7 @@ static void test_will_overflow_1 () populate_serializer_complex_2 (&c); graph_t graph (c.object_graph ()); - assert (!graph.will_overflow (nullptr)); + assert (!graph::will_overflow (graph, nullptr)); free (buffer); } @@ -961,7 +962,7 @@ static void test_will_overflow_2 () populate_serializer_with_overflow (&c); graph_t graph (c.object_graph ()); - assert (graph.will_overflow (nullptr)); + assert (graph::will_overflow (graph, nullptr)); free (buffer); } @@ -974,7 +975,7 @@ static void test_will_overflow_3 () populate_serializer_with_dedup_overflow (&c); graph_t graph (c.object_graph ()); - assert (graph.will_overflow (nullptr)); + assert (graph::will_overflow (graph, nullptr)); free (buffer); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc index bcff0560437..983a15910df 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc @@ -20,13 +20,11 @@ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * */ #include "hb.hh" #include "hb-set.hh" - int main (int argc, char **argv) { |