texlive[72778] Build/source/libs: harfbuzz 10.1.0

commits+kakuto at tug.org commits+kakuto at tug.org
Wed Nov 6 05:18:34 CET 2024


Revision: 72778
          https://tug.org/svn/texlive?view=revision&revision=72778
Author:   kakuto
Date:     2024-11-06 05:18:33 +0100 (Wed, 06 Nov 2024)
Log Message:
-----------
harfbuzz 10.1.0

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/harfbuzz/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
    trunk/Build/source/libs/harfbuzz/configure
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/ms-use/IndicPositionalCategory-Additional.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/ms-use/IndicSyllabicCategory-Additional.txt
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/README	2024-11-06 04:18:33 UTC (rev 72778)
@@ -28,7 +28,7 @@
   https://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 10.0.1 - checked 25sep24
+harfbuzz 10.1.0 - checked 06nov24
   https://github.com/harfbuzz/harfbuzz/releases/latest
 
 icu 76.1 - checked 27oct24 (requires C++17, e.g., g++13)

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2024-11-06 04:18:33 UTC (rev 72778)
@@ -1,3 +1,8 @@
+2024-11-06  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Import harfbuzz-10.1.0.
+	* version.ac: Adjusted.
+
 2024-09-25  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Import harfbuzz-10.0.1.

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2024-11-06 04:18:33 UTC (rev 72778)
@@ -1,3 +1,8 @@
+2024-11-06  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Imported harfbuzz-10.1.0 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/10.1.0/
+
 2024-09-25  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Imported harfbuzz-10.0.1 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2024-11-06 04:18:33 UTC (rev 72778)
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-10.0.1/ tree as obtained from:
-	https://github.com/harfbuzz/harfbuzz/releases/download/10.0.1/
+Changes applied to the harfbuzz-10.1.0/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/10.1.0/
 
 Removed:
 	.clang-format

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/configure	2024-11-06 04:18:33 UTC (rev 72778)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for harfbuzz (TeX Live) 10.0.1.
+# Generated by GNU Autoconf 2.72 for harfbuzz (TeX Live) 10.1.0.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -604,8 +604,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='10.0.1'
-PACKAGE_STRING='harfbuzz (TeX Live) 10.0.1'
+PACKAGE_VERSION='10.1.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 10.1.0'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1341,7 +1341,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-'configure' configures harfbuzz (TeX Live) 10.0.1 to adapt to many kinds of systems.
+'configure' configures harfbuzz (TeX Live) 10.1.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1413,7 +1413,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 10.0.1:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 10.1.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1518,7 +1518,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 10.0.1
+harfbuzz (TeX Live) configure 10.1.0
 generated by GNU Autoconf 2.72
 
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -2075,7 +2075,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by harfbuzz (TeX Live) $as_me 10.0.1, which was
+It was created by harfbuzz (TeX Live) $as_me 10.1.0, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -5252,7 +5252,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='10.0.1'
+ VERSION='10.1.0'
 
 
 # Some tools Automake needs.
@@ -5441,9 +5441,9 @@
 
 
 HB_VERSION_MAJOR=10
-HB_VERSION_MINOR=0
-HB_VERSION_MICRO=1
-HB_VERSION=10.0.1
+HB_VERSION_MINOR=1
+HB_VERSION_MICRO=0
+HB_VERSION=10.1.0
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -9292,7 +9292,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by harfbuzz (TeX Live) $as_me 10.0.1, which was
+This file was extended by harfbuzz (TeX Live) $as_me 10.1.0, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -9360,7 +9360,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 10.0.1
+harfbuzz (TeX Live) config.status 10.1.0
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2024-11-06 04:18:33 UTC (rev 72778)
@@ -1,5 +1,28 @@
+Overview of changes leading to 10.1.0
+Tuesday, November 5, 2024
+====================================
+- Fix the sign of fallback vertical glyph advance (used when font has no
+  vertical advance data).
+- Increase maximum “CFF” operands limit 20 times to support more complex fonts.
+- Add “--face-loader” option to command line utilities.
+- Support “COLR” v0 table in hb_font_get_glyph_extents().
+- Add support for font functions that use Core Text APIs, similar to FreeType
+  font functions. This allows, for example, using drawing fonts that use the new
+  (and undocumented) “hvgl” table.
+- Update IANA and OT language registries, as well ase USE data files.
+- Fix build with ICU 76.
+- Various compiler warnings and build fixes.
+- Various subsetter fixes.
+
+- New API:
++hb_face_create_or_fail()
++hb_face_create_from_file_or_fail()
++hb_coretext_face_create_from_file_or_fail()
++hb_coretext_font_set_funcs()
++hb_ft_face_create_from_file_or_fail()
+
 Overview of changes leading to 10.0.1
-Tuesday, Sep 24, 2024
+Tuesday, September 24, 2024
 ====================================
 - Relax sanitization checks for “morx” subtables to fix broken AAT shaping of
   macOS 15.0 version of GeezaPro.
@@ -6,7 +29,7 @@
 
 
 Overview of changes leading to 10.0.0
-Monday, Sep 23, 2024
+Monday, September 23, 2024
 ====================================
 - Unicode 16.0.0 support.
 - Various documentation fixes.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2024-11-06 04:18:33 UTC (rev 72778)
@@ -1,6 +1,6 @@
 project('harfbuzz', 'c', 'cpp',
   meson_version: '>= 0.55.0',
-  version: '10.0.1',
+  version: '10.1.0',
   default_options: [
     'cpp_eh=none',          # Just to support msvc, we are passing -fno-exceptions also anyway
     # 'cpp_rtti=false',     # Do NOT enable, wraps inherit it and ICU needs RTTI

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -2058,7 +2058,7 @@
       unsigned outer = (*var_idx) >> 16;
       unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer);
       outer_bit_count = hb_max (bit_count, outer_bit_count);
-      
+
       unsigned inner = (*var_idx) & 0xFFFF;
       bit_count = (inner == 0) ? 1 : hb_bit_storage (inner);
       inner_bit_count = hb_max (bit_count, inner_bit_count);
@@ -2080,7 +2080,7 @@
   bool has_v0_data () const { return numBaseGlyphs; }
   bool has_v1_data () const
   {
-    if (version != 1)
+    if (version < 1)
       return false;
     hb_barrier ();
 
@@ -2180,7 +2180,7 @@
                       hb_set_t *variation_indices,
                       hb_set_t *delta_set_indices) const
   {
-    if (version != 1) return;
+    if (version < 1) return;
     hb_barrier ();
 
     hb_set_t visited_glyphs;
@@ -2222,17 +2222,23 @@
   { return (this+baseGlyphList); }
 
   bool has_var_store () const
-  { return version >= 1 && varStore != 0; }
+  { return version >= 1 && hb_barrier () && varStore != 0; }
 
   bool has_delta_set_index_map () const
-  { return version >= 1 && varIdxMap != 0; }
+  { return version >= 1 && hb_barrier () && varIdxMap != 0; }
 
+  bool has_clip_list () const
+  { return version >= 1 && hb_barrier () && clipList != 0; }
+
   const DeltaSetIndexMap &get_delta_set_index_map () const
-  { return (version == 0 || varIdxMap == 0) ? Null (DeltaSetIndexMap) : this+varIdxMap; }
+  { return has_delta_set_index_map () && hb_barrier () ? this+varIdxMap : Null (DeltaSetIndexMap); }
 
   const ItemVariationStore &get_var_store () const
-  { return (version == 0 || varStore == 0) ? Null (ItemVariationStore) : this+varStore; }
+  { return has_var_store () && hb_barrier () ? this+varStore : Null (ItemVariationStore); }
 
+  const ClipList &get_clip_list () const
+  { return has_clip_list () && hb_barrier () ? this+clipList : Null (ClipList); }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -2242,7 +2248,6 @@
                   (this+layersZ).sanitize (c, numLayers) &&
                   (version == 0 ||
 		   (hb_barrier () &&
-		    version == 1 &&
 		    baseGlyphList.sanitize (c, this) &&
 		    layerList.sanitize (c, this) &&
 		    clipList.sanitize (c, this) &&
@@ -2465,8 +2470,10 @@
     if (unlikely (!c->serializer->extend_min (colr_prime)))  return_trace (false);
 
     if (version == 0 || downgrade_to_V0 (glyphset))
-    return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
+      return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
 
+    hb_barrier ();
+
     //start version 1
     if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
     if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
@@ -2475,8 +2482,8 @@
      * after instancing */
     if (!subset_varstore (c, colr_prime)) return_trace (false);
 
-    ItemVarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr,
-	                         varIdxMap ? &(this+varIdxMap) : nullptr,
+    ItemVarStoreInstancer instancer (&(get_var_store ()),
+	                         &(get_delta_set_index_map ()),
 	                         c->plan->normalized_coords.as_array ());
 
     if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer))
@@ -2505,12 +2512,10 @@
   bool
   get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
   {
-    if (version != 1)
-      return false;
 
-    ItemVarStoreInstancer instancer (&(this+varStore),
-				 &(this+varIdxMap),
-				 hb_array (font->coords, font->num_coords));
+    ItemVarStoreInstancer instancer (&(get_var_store ()),
+                                     &(get_delta_set_index_map ()),
+                                     hb_array (font->coords, font->num_coords));
 
     if (get_clip (glyph, extents, instancer))
     {
@@ -2545,7 +2550,7 @@
   bool
   has_paint_for_glyph (hb_codepoint_t glyph) const
   {
-    if (version == 1)
+    if (version >= 1)
     {
       hb_barrier ();
 
@@ -2561,7 +2566,7 @@
 		 hb_glyph_extents_t *extents,
 		 const ItemVarStoreInstancer instancer) const
   {
-    return (this+clipList).get_extents (glyph,
+    return get_clip_list ().get_extents (glyph,
 					extents,
 					instancer);
   }
@@ -2570,13 +2575,13 @@
   bool
   paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
   {
-    ItemVarStoreInstancer instancer (&(this+varStore),
-	                         &(this+varIdxMap),
+    ItemVarStoreInstancer instancer (&(get_var_store ()),
+	                         &(get_delta_set_index_map ()),
 	                         hb_array (font->coords, font->num_coords));
     hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
     c.current_glyphs.add (glyph);
 
-    if (version == 1)
+    if (version >= 1)
     {
       hb_barrier ();
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	2024-11-06 04:18:33 UTC (rev 72778)
@@ -345,14 +345,18 @@
 		self.from_bcp_47_uninherited = None
 		# Whether the parser is in a <td> element
 		self._td = False
-		# Whether the parser is after a <br> element within the current <tr> element
-		self._br = False
+		# Whether the parser ignores the rest of the current <td> element
+		self._disengaged = False
 		# The text of the <td> elements of the current <tr> element.
 		self._current_tr = []
 
 	def handle_starttag (self, tag, attrs):
-		if tag == 'br':
-			self._br = True
+		if tag == 'a':
+			if self._current_tr and not self._disengaged:
+				self._current_tr[-1] = ''
+				self._disengaged = True
+		elif tag == 'br':
+			self._disengaged = True
 		elif tag == 'meta':
 			for attr, value in attrs:
 				if attr == 'name' and value == 'updated_at':
@@ -362,12 +366,13 @@
 			self._td = True
 			self._current_tr.append ('')
 		elif tag == 'tr':
-			self._br = False
+			self._disengaged = False
 			self._current_tr = []
 
 	def handle_endtag (self, tag):
 		if tag == 'td':
 			self._td = False
+			self._disengaged = False
 		elif tag == 'tr' and self._current_tr:
 			expect (2 <= len (self._current_tr) <= 3)
 			name = self._current_tr[0].strip ()
@@ -387,7 +392,7 @@
 			self.ranks[tag] = rank
 
 	def handle_data (self, data):
-		if self._td and not self._br:
+		if self._td and not self._disengaged:
 			self._current_tr[-1] += data
 
 	def handle_charref (self, name):

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2024-11-06 04:18:33 UTC (rev 72778)
@@ -109,6 +109,7 @@
 	'Nukta',
 	'Virama',
 	'Pure_Killer',
+	'Reordering_Killer',
 	'Invisible_Stacker',
 	'Vowel_Independent',
 	'Vowel_Dependent',
@@ -263,6 +264,8 @@
 		and not is_SYM_MOD(U, UISC, UDI, UGC, AJT)
 		and not is_Word_Joiner(U, UISC, UDI, UGC, AJT)
 	)
+def is_REORDERING_KILLER(U, UISC, UDI, UGC, AJT):
+	return UISC == Reordering_Killer
 def is_REPHA(U, UISC, UDI, UGC, AJT):
 	return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
 def is_SAKOT(U, UISC, UDI, UGC, AJT):
@@ -306,6 +309,7 @@
 	'SE':	is_HIEROGLYPH_SEGMENT_END,
 	'ZWNJ':	is_ZWNJ,
 	'O':	is_OTHER,
+	'RK':	is_REORDERING_KILLER,
 	'R':	is_REPHA,
 	'Sk':	is_SAKOT,
 	'SM':	is_SYM_MOD,
@@ -358,6 +362,7 @@
 		'Pst': [Not_Applicable],
 	},
 	'R': None,
+	'RK': None,
 	'SUB': None,
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -6,7 +6,8 @@
 #include "hb-buffer-verify.cc"
 #include "hb-buffer.cc"
 #include "hb-common.cc"
-#include "hb-coretext.cc"
+#include "hb-coretext-font.cc"
+#include "hb-coretext-shape.cc"
 #include "hb-directwrite.cc"
 #include "hb-draw.cc"
 #include "hb-face-builder.cc"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -617,10 +617,9 @@
 
 /**
  * hb_blob_create_from_file_or_fail:
- * @file_name: A font filename
+ * @file_name: A filename
  *
- * Creates a new blob containing the data from the
- * specified binary font file.
+ * Creates a new blob containing the data from the specified file.
  *
  * The filename is passed directly to the system on all platforms,
  * except on Windows, where the filename is interpreted as UTF-8.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -482,7 +482,7 @@
 								   &hb_cairo_face_user_data_key);
     font = hb_font_create (face);
 
-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,16,0)
+#if !defined(HB_NO_VAR) && CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,16,0)
     cairo_font_options_t *font_options = cairo_font_options_create ();
 
     // Set variations

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -56,7 +56,6 @@
 
 #ifdef HB_LEAN
 #define HB_DISABLE_DEPRECATED
-#define HB_NDEBUG
 #define HB_NO_ATEXIT
 #define HB_NO_BUFFER_MESSAGE
 #define HB_NO_BUFFER_SERIALIZE

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-font.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -0,0 +1,461 @@
+/*
+ * Copyright © 2024  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author(s): Behdad Esfahbod
+ */
+
+#include "hb.hh"
+
+#ifdef HAVE_CORETEXT
+
+#include "hb-coretext.h"
+
+#include "hb-draw.hh"
+#include "hb-font.hh"
+#include "hb-machinery.hh"
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
+#  define kCTFontOrientationDefault kCTFontDefaultOrientation
+#endif
+
+#define MAX_GLYPHS 64u
+
+static void
+_hb_coretext_font_destroy (void *font_data)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  CFRelease (ct_font);
+}
+
+static hb_bool_t
+hb_coretext_get_nominal_glyph (hb_font_t *font HB_UNUSED,
+			       void *font_data,
+			       hb_codepoint_t unicode,
+			       hb_codepoint_t *glyph,
+			       void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+  UniChar ch = unicode;
+  CGGlyph cg_glyph;
+  if (CTFontGetGlyphsForCharacters (ct_font, &ch, &cg_glyph, 1))
+  {
+    *glyph = cg_glyph;
+    return true;
+  }
+  return false;
+}
+
+static unsigned int
+hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
+				void *font_data,
+				unsigned int count,
+				const hb_codepoint_t *first_unicode,
+				unsigned int unicode_stride,
+				hb_codepoint_t *first_glyph,
+				unsigned int glyph_stride,
+				void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  UniChar ch[MAX_GLYPHS];
+  CGGlyph cg_glyph[MAX_GLYPHS];
+  for (unsigned i = 0; i < count; i += MAX_GLYPHS)
+  {
+    unsigned c = (unsigned) hb_min ((int) MAX_GLYPHS, (int) count - (int) i);
+    for (unsigned j = 0; j < c; j++)
+    {
+      ch[j] = *first_unicode;
+      first_unicode = &StructAtOffset<const hb_codepoint_t> (first_unicode, unicode_stride);
+    }
+    CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, c);
+    for (unsigned j = 0; j < c; j++)
+    {
+      *first_glyph = cg_glyph[j];
+      first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
+    }
+  }
+
+  return count;
+}
+
+static hb_bool_t
+hb_coretext_get_variation_glyph (hb_font_t *font HB_UNUSED,
+				 void *font_data,
+				 hb_codepoint_t unicode,
+				 hb_codepoint_t variation_selector,
+				 hb_codepoint_t *glyph,
+				 void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  UniChar ch[2] = { unicode, variation_selector };
+  CGGlyph cg_glyph[2];
+
+  CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, 2);
+
+  if (cg_glyph[1])
+    return false;
+
+  *glyph = cg_glyph[0];
+  return true;
+}
+
+static void
+hb_coretext_get_glyph_h_advances (hb_font_t* font, void* font_data,
+				  unsigned count,
+				  const hb_codepoint_t *first_glyph,
+				  unsigned glyph_stride,
+				  hb_position_t *first_advance,
+				  unsigned advance_stride,
+				  void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  CGFloat ct_font_size = CTFontGetSize (ct_font);
+  CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
+
+  CGGlyph cg_glyph[MAX_GLYPHS];
+  CGSize advances[MAX_GLYPHS];
+  for (unsigned i = 0; i < count; i += MAX_GLYPHS)
+  {
+    unsigned c = (unsigned) hb_min ((int) MAX_GLYPHS, (int) count - (int) i);
+    for (unsigned j = 0; j < c; j++)
+    {
+      cg_glyph[j] = *first_glyph;
+      first_glyph = &StructAtOffset<const hb_codepoint_t> (first_glyph, glyph_stride);
+    }
+    CTFontGetAdvancesForGlyphs (ct_font, kCTFontOrientationHorizontal, cg_glyph, advances, c);
+    for (unsigned j = 0; j < c; j++)
+    {
+      *first_advance = round (advances[j].width * x_mult);
+      first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
+    }
+  }
+}
+
+#ifndef HB_NO_VERTICAL
+static void
+hb_coretext_get_glyph_v_advances (hb_font_t* font, void* font_data,
+				  unsigned count,
+				  const hb_codepoint_t *first_glyph,
+				  unsigned glyph_stride,
+				  hb_position_t *first_advance,
+				  unsigned advance_stride,
+				  void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  CGFloat ct_font_size = CTFontGetSize (ct_font);
+  CGFloat y_mult = (CGFloat) -font->y_scale / ct_font_size;
+
+  CGGlyph cg_glyph[MAX_GLYPHS];
+  CGSize advances[MAX_GLYPHS];
+  for (unsigned i = 0; i < count; i += MAX_GLYPHS)
+  {
+    unsigned c = (unsigned) hb_min ((int) MAX_GLYPHS, (int) count - (int) i);
+    for (unsigned j = 0; j < c; j++)
+    {
+      cg_glyph[j] = *first_glyph;
+      first_glyph = &StructAtOffset<const hb_codepoint_t> (first_glyph, glyph_stride);
+    }
+    CTFontGetAdvancesForGlyphs (ct_font, kCTFontOrientationVertical, cg_glyph, advances, c);
+    for (unsigned j = 0; j < c; j++)
+    {
+      *first_advance = round (advances[j].width * y_mult);
+      first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
+    }
+  }
+}
+#endif
+
+#ifndef HB_NO_VERTICAL
+static hb_bool_t
+hb_coretext_get_glyph_v_origin (hb_font_t *font,
+				void *font_data,
+				hb_codepoint_t glyph,
+				hb_position_t *x,
+				hb_position_t *y,
+				void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  CGFloat ct_font_size = CTFontGetSize (ct_font);
+  CGFloat x_mult = (CGFloat) -font->x_scale / ct_font_size;
+  CGFloat y_mult = (CGFloat) -font->y_scale / ct_font_size;
+
+  const CGGlyph glyphs = glyph;
+  CGSize origin;
+  CTFontGetVerticalTranslationsForGlyphs (ct_font, &glyphs, &origin, 1);
+
+  *x = round (x_mult * origin.width);
+  *y = round (y_mult * origin.height);
+
+  return true;
+}
+#endif
+
+static hb_bool_t
+hb_coretext_get_glyph_extents (hb_font_t *font,
+			       void *font_data,
+			       hb_codepoint_t glyph,
+			       hb_glyph_extents_t *extents,
+			       void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  CGFloat ct_font_size = CTFontGetSize (ct_font);
+  CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
+  CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
+
+  CGGlyph glyphs[1] = { glyph };
+  CGRect bounds = ::CTFontGetBoundingRectsForGlyphs(ct_font,
+						    kCTFontOrientationDefault, glyphs, NULL, 1);
+
+  extents->x_bearing = round (bounds.origin.x * x_mult);
+  extents->y_bearing = round (bounds.origin.y * y_mult);
+  extents->width = round (bounds.size.width * x_mult);
+  extents->height = round (bounds.size.height * y_mult);
+
+  return true;
+}
+
+static hb_bool_t
+hb_coretext_get_font_h_extents (hb_font_t *font,
+				void *font_data,
+				hb_font_extents_t *metrics,
+				void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+  CGFloat ct_font_size = CTFontGetSize (ct_font);
+  CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
+
+  metrics->ascender = round (CTFontGetAscent (ct_font) * y_mult);
+  metrics->descender = -round (CTFontGetDescent (ct_font) * y_mult);
+  metrics->line_gap = round (CTFontGetLeading (ct_font) * y_mult);
+
+  return true;
+}
+
+#ifndef HB_NO_DRAW
+
+static void
+ct_apply_func (void *info, const CGPathElement *element)
+{
+  hb_draw_session_t *draws = (hb_draw_session_t *) info;
+
+  switch (element->type)
+  {
+  case kCGPathElementMoveToPoint:
+    draws->move_to (element->points[0].x, element->points[0].y);
+    break;
+  case kCGPathElementAddLineToPoint:
+    draws->line_to (element->points[0].x, element->points[0].y);
+    break;
+  case kCGPathElementAddQuadCurveToPoint:
+    draws->quadratic_to (element->points[0].x, element->points[0].y,
+			 element->points[1].x, element->points[1].y);
+    break;
+  case kCGPathElementAddCurveToPoint:
+    draws->cubic_to (element->points[0].x, element->points[0].y,
+		     element->points[1].x, element->points[1].y,
+		     element->points[2].x, element->points[2].y);
+    break;
+  case kCGPathElementCloseSubpath:
+    draws->close_path ();
+    break;
+  }
+}
+
+static void
+hb_coretext_draw_glyph (hb_font_t *font,
+			void *font_data HB_UNUSED,
+			hb_codepoint_t glyph,
+			hb_draw_funcs_t *draw_funcs, void *draw_data,
+			void *user_data)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  CGFloat ct_font_size = CTFontGetSize (ct_font);
+  CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
+  CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
+
+  CGAffineTransform transform = CGAffineTransformIdentity;
+  transform = CGAffineTransformScale (transform, x_mult, y_mult);
+
+  CGPathRef path = CTFontCreatePathForGlyph (ct_font, glyph, &transform);
+  if (!path)
+    return;
+
+  hb_draw_session_t drawing = {draw_funcs, draw_data, font->slant};
+
+  CGPathApply (path, &drawing, ct_apply_func);
+
+  CFRelease (path);
+}
+#endif
+
+static hb_bool_t
+hb_coretext_get_glyph_name (hb_font_t *font,
+			    void *font_data HB_UNUSED,
+			    hb_codepoint_t glyph,
+			    char *name, unsigned int size,
+			    void *user_data HB_UNUSED)
+{
+  CGFontRef cg_font = (CGFontRef) (const void *) font->face->data.coretext;
+
+  CGGlyph cg_glyph = glyph;
+  CFStringRef cf_name = CGFontCopyGlyphNameForGlyph (cg_font, cg_glyph);
+  if (!cf_name)
+    return false;
+
+  CFIndex len = CFStringGetLength (cf_name);
+  if (len > size - 1)
+    len = size - 1;
+
+  CFStringGetBytes (cf_name, CFRangeMake (0, len),
+		    kCFStringEncodingUTF8, 0, false,
+		    (UInt8 *) name, size, &len);
+
+  name[len] = '\0';
+  return true;
+}
+
+static hb_bool_t
+hb_coretext_get_glyph_from_name (hb_font_t *font HB_UNUSED,
+				 void *font_data,
+				 const char *name, int len,
+				 hb_codepoint_t *glyph,
+				 void *user_data HB_UNUSED)
+{
+  CTFontRef ct_font = (CTFontRef) font_data;
+
+  if (len == -1)
+    len = strlen (name);
+
+  CFStringRef cf_name = CFStringCreateWithBytes (kCFAllocatorDefault,
+						 (const UInt8 *) name, len,
+						 kCFStringEncodingUTF8, false);
+  CGGlyph cg_glyph = CTFontGetGlyphWithName (ct_font, cf_name);
+  *glyph = cg_glyph;
+
+  CFRelease (cf_name);
+
+  // TODO Return true for .notdef; hb-ft does that.
+
+  return cg_glyph != 0;
+}
+
+
+static inline void free_static_coretext_funcs ();
+
+static struct hb_coretext_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_coretext_font_funcs_lazy_loader_t>
+{
+  static hb_font_funcs_t *create ()
+  {
+    hb_font_funcs_t *funcs = hb_font_funcs_create ();
+
+    hb_font_funcs_set_nominal_glyph_func (funcs, hb_coretext_get_nominal_glyph, nullptr, nullptr);
+    hb_font_funcs_set_nominal_glyphs_func (funcs, hb_coretext_get_nominal_glyphs, nullptr, nullptr);
+    hb_font_funcs_set_variation_glyph_func (funcs, hb_coretext_get_variation_glyph, nullptr, nullptr);
+
+    hb_font_funcs_set_font_h_extents_func (funcs, hb_coretext_get_font_h_extents, nullptr, nullptr);
+    hb_font_funcs_set_glyph_h_advances_func (funcs, hb_coretext_get_glyph_h_advances, nullptr, nullptr);
+    //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_coretext_get_glyph_h_origin, nullptr, nullptr);
+
+#ifndef HB_NO_VERTICAL
+    //hb_font_funcs_set_font_v_extents_func (funcs, hb_coretext_get_font_v_extents, nullptr, nullptr);
+    hb_font_funcs_set_glyph_v_advances_func (funcs, hb_coretext_get_glyph_v_advances, nullptr, nullptr);
+    hb_font_funcs_set_glyph_v_origin_func (funcs, hb_coretext_get_glyph_v_origin, nullptr, nullptr);
+#endif
+
+#ifndef HB_NO_DRAW
+    hb_font_funcs_set_draw_glyph_func (funcs, hb_coretext_draw_glyph, nullptr, nullptr);
+#endif
+
+    hb_font_funcs_set_glyph_extents_func (funcs, hb_coretext_get_glyph_extents, nullptr, nullptr);
+
+#ifndef HB_NO_OT_FONT_GLYPH_NAMES
+    hb_font_funcs_set_glyph_name_func (funcs, hb_coretext_get_glyph_name, nullptr, nullptr);
+    hb_font_funcs_set_glyph_from_name_func (funcs, hb_coretext_get_glyph_from_name, nullptr, nullptr);
+#endif
+
+    hb_font_funcs_make_immutable (funcs);
+
+    hb_atexit (free_static_coretext_funcs);
+
+    return funcs;
+  }
+} static_coretext_funcs;
+
+static inline
+void free_static_coretext_funcs ()
+{
+  static_coretext_funcs.free_instance ();
+}
+
+static hb_font_funcs_t *
+_hb_coretext_get_font_funcs ()
+{
+  return static_coretext_funcs.get_unconst ();
+}
+
+
+/**
+ * hb_coretext_font_set_funcs:
+ * @font: #hb_font_t to work upon
+ *
+ * Configures the font-functions structure of the specified
+ * #hb_font_t font object to use CoreText font functions.
+ *
+ * In particular, you can use this function to configure an
+ * existing #hb_face_t face object for use with CoreText font
+ * functions even if that #hb_face_t face object was initially
+ * created with hb_face_create(), and therefore was not
+ * initially configured to use CoreText font functions.
+ *
+ * An #hb_font_t object created with hb_coretext_font_create()
+ * is preconfigured for CoreText font functions and does not
+ * require this function to be used.
+ *
+ * <note>Note: Internally, this function creates a CTFont.
+* </note>
+ *
+ * Since: 10.1.0
+ **/
+void
+hb_coretext_font_set_funcs (hb_font_t *font)
+{
+  CTFontRef ct_font = hb_coretext_font_get_ct_font (font);
+  if (unlikely (!ct_font))
+    return;
+
+  hb_font_set_funcs (font,
+		     _hb_coretext_get_font_funcs (),
+		     (void *) CFRetain (ct_font),
+		     _hb_coretext_font_destroy);
+}
+
+#undef MAX_GLYPHS
+
+#endif

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext-shape.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -0,0 +1,1314 @@
+/*
+ * Copyright © 2012,2013  Mozilla Foundation.
+ * Copyright © 2012,2013  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
+ */
+
+#include "hb.hh"
+
+#ifdef HAVE_CORETEXT
+
+#include "hb-shaper-impl.hh"
+
+#include "hb-coretext.h"
+#include "hb-aat-layout.hh"
+
+
+/**
+ * SECTION:hb-coretext
+ * @title: hb-coretext
+ * @short_description: CoreText integration
+ * @include: hb-coretext.h
+ *
+ * Functions for using HarfBuzz with the CoreText fonts.
+ **/
+
+/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
+#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
+
+static CTFontRef create_ct_font (CGFontRef cg_font, CGFloat font_size);
+
+static void
+release_table_data (void *user_data)
+{
+  CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data);
+  CFRelease(cf_data);
+}
+
+static hb_blob_t *
+_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+  CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
+  CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
+  if (unlikely (!cf_data))
+    return nullptr;
+
+  const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data));
+  const size_t length = CFDataGetLength (cf_data);
+  if (!data || !length)
+  {
+    CFRelease (cf_data);
+    return nullptr;
+  }
+
+  return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
+			 reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)),
+			 release_table_data);
+}
+
+static unsigned
+_hb_cg_get_table_tags (const hb_face_t *face HB_UNUSED,
+		       unsigned int start_offset,
+		       unsigned int *table_count,
+		       hb_tag_t *table_tags,
+		       void *user_data)
+{
+  CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
+
+  CTFontRef ct_font = create_ct_font (cg_font, (CGFloat) HB_CORETEXT_DEFAULT_FONT_SIZE);
+
+  auto arr = CTFontCopyAvailableTables (ct_font, kCTFontTableOptionNoOptions);
+
+  unsigned population = (unsigned) CFArrayGetCount (arr);
+  unsigned end_offset;
+
+  if (!table_count)
+    goto done;
+
+  if (unlikely (start_offset >= population))
+  {
+    *table_count = 0;
+    goto done;
+  }
+
+  end_offset = start_offset + *table_count;
+  if (unlikely (end_offset < start_offset))
+  {
+    *table_count = 0;
+    goto done;
+  }
+  end_offset= hb_min (end_offset, (unsigned) population);
+
+  *table_count = end_offset - start_offset;
+  for (unsigned i = start_offset; i < end_offset; i++)
+  {
+    CTFontTableTag tag = (CTFontTableTag)(uintptr_t) CFArrayGetValueAtIndex (arr, i);
+    table_tags[i - start_offset] = tag;
+  }
+
+done:
+  CFRelease (arr);
+  CFRelease (ct_font);
+  return population;
+}
+
+static void
+_hb_cg_font_release (void *data)
+{
+  CGFontRelease ((CGFontRef) data);
+}
+
+
+static CTFontDescriptorRef
+get_last_resort_font_desc ()
+{
+  // TODO Handle allocation failures?
+  CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0);
+  CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault,
+					   (const void **) &last_resort,
+					   1,
+					   &kCFTypeArrayCallBacks);
+  CFRelease (last_resort);
+  CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
+						   (const void **) &kCTFontCascadeListAttribute,
+						   (const void **) &cascade_list,
+						   1,
+						   &kCFTypeDictionaryKeyCallBacks,
+						   &kCFTypeDictionaryValueCallBacks);
+  CFRelease (cascade_list);
+
+  CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
+  CFRelease (attributes);
+  return font_desc;
+}
+
+static void
+release_data (void *info, const void *data, size_t size)
+{
+  assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
+	  hb_blob_get_data ((hb_blob_t *) info, nullptr) == data);
+
+  hb_blob_destroy ((hb_blob_t *) info);
+}
+
+static CGFontRef
+create_cg_font (hb_face_t *face)
+{
+  CGFontRef cg_font = nullptr;
+  if (face->destroy == _hb_cg_font_release)
+  {
+    cg_font = CGFontRetain ((CGFontRef) face->user_data);
+  }
+  else
+  {
+    hb_blob_t *blob = hb_face_reference_blob (face);
+    unsigned int blob_length;
+    const char *blob_data = hb_blob_get_data (blob, &blob_length);
+    if (unlikely (!blob_length))
+      DEBUG_MSG (CORETEXT, face, "Face has empty blob");
+
+    CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
+    if (likely (provider))
+    {
+      cg_font = CGFontCreateWithDataProvider (provider);
+      if (unlikely (!cg_font))
+	DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
+      CGDataProviderRelease (provider);
+    }
+  }
+  return cg_font;
+}
+
+static CTFontRef
+create_ct_font (CGFontRef cg_font, CGFloat font_size)
+{
+  CTFontRef ct_font = nullptr;
+
+  /* CoreText does not enable trak table usage / tracking when creating a CTFont
+   * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems
+   * to be through the CTFontCreateUIFontForLanguage call. */
+  CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font);
+  if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) ||
+      CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay")))
+  {
+#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+# define kCTFontUIFontSystem kCTFontSystemFontType
+# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType
+#endif
+    CTFontUIFontType font_type = kCTFontUIFontSystem;
+    if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold")))
+      font_type = kCTFontUIFontEmphasizedSystem;
+
+    ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, nullptr);
+    CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font);
+    if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo)
+    {
+      CFRelease(ct_font);
+      ct_font = nullptr;
+    }
+    CFRelease (ct_result_name);
+  }
+  CFRelease (cg_postscript_name);
+
+  if (!ct_font)
+    ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, nullptr, nullptr);
+
+  if (unlikely (!ct_font)) {
+    DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
+    return nullptr;
+  }
+
+  /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter
+   * bug indicate that the cascade list reconfiguration occasionally causes
+   * crashes in CoreText on OS X 10.9, thus let's skip this step on older
+   * operating system versions. Except for the emoji font, where _not_
+   * reconfiguring the cascade list causes CoreText crashes. For details, see
+   * crbug.com/549610 */
+  // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) {
+#pragma GCC diagnostic pop
+    CFStringRef fontName = CTFontCopyPostScriptName (ct_font);
+    bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo;
+    CFRelease (fontName);
+    if (!isEmojiFont)
+      return ct_font;
+  }
+
+  CFURLRef original_url = nullptr;
+#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+  ATSFontRef atsFont;
+  FSRef fsref;
+  OSStatus status;
+  atsFont = CTFontGetPlatformFont (ct_font, NULL);
+  status = ATSFontGetFileReference (atsFont, &fsref);
+  if (status == noErr)
+    original_url = CFURLCreateFromFSRef (NULL, &fsref);
+#else
+  original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute);
+#endif
+
+  /* Create font copy with cascade list that has LastResort first; this speeds up CoreText
+   * font fallback which we don't need anyway. */
+  {
+    CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc ();
+    CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, last_resort_font_desc);
+    CFRelease (last_resort_font_desc);
+    if (new_ct_font)
+    {
+      /* The CTFontCreateCopyWithAttributes call fails to stay on the same font
+       * when reconfiguring the cascade list and may switch to a different font
+       * when there are fonts that go by the same name, since the descriptor is
+       * just name and size.
+       *
+       * Avoid reconfiguring the cascade lists if the new font is outside the
+       * system locations that we cannot access from the sandboxed renderer
+       * process in Blink. This can be detected by the new file URL location
+       * that the newly found font points to. */
+      CFURLRef new_url = nullptr;
+#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+      atsFont = CTFontGetPlatformFont (new_ct_font, NULL);
+      status = ATSFontGetFileReference (atsFont, &fsref);
+      if (status == noErr)
+	new_url = CFURLCreateFromFSRef (NULL, &fsref);
+#else
+      new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
+#endif
+      // Keep reconfigured font if URL cannot be retrieved (seems to be the case
+      // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606
+      if (!original_url || !new_url || CFEqual (original_url, new_url)) {
+	CFRelease (ct_font);
+	ct_font = new_ct_font;
+      } else {
+	CFRelease (new_ct_font);
+	DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
+      }
+      if (new_url)
+	CFRelease (new_url);
+    }
+    else
+      DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed");
+  }
+
+  if (original_url)
+    CFRelease (original_url);
+  return ct_font;
+}
+
+hb_coretext_face_data_t *
+_hb_coretext_shaper_face_data_create (hb_face_t *face)
+{
+  CGFontRef cg_font = create_cg_font (face);
+
+  if (unlikely (!cg_font))
+  {
+    DEBUG_MSG (CORETEXT, face, "CGFont creation failed..");
+    return nullptr;
+  }
+
+  return (hb_coretext_face_data_t *) cg_font;
+}
+
+void
+_hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data)
+{
+  CFRelease ((CGFontRef) data);
+}
+
+/**
+ * hb_coretext_face_create:
+ * @cg_font: The CGFontRef to work upon
+ *
+ * Creates an #hb_face_t face object from the specified
+ * CGFontRef.
+ *
+ * Return value: (transfer full): The new face object
+ *
+ * Since: 0.9.10
+ */
+hb_face_t *
+hb_coretext_face_create (CGFontRef cg_font)
+{
+  hb_face_t *face = hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
+  hb_face_set_get_table_tags_func (face, _hb_cg_get_table_tags, cg_font, nullptr);
+  return face;
+}
+
+/**
+ * hb_coretext_face_create_from_file_or_fail:
+ * @file_name: A font filename
+ * @index: The index of the face within the file
+ *
+ * Creates an #hb_face_t face object from the specified
+ * font file and face index.
+ *
+ * This is similar in functionality to hb_face_create_from_file_or_fail(),
+ * but uses the CoreText library for loading the font file.
+ *
+ * Return value: (transfer full): The new face object, or `NULL` if
+ * no face is found at the specified index or the file cannot be read.
+ *
+ * Since: 10.1.0
+ */
+hb_face_t *
+hb_coretext_face_create_from_file_or_fail (const char   *file_name,
+					   unsigned int  index)
+{
+  auto url = CFURLCreateFromFileSystemRepresentation (nullptr,
+						      (const UInt8 *) file_name,
+						      strlen (file_name),
+						      false);
+  if (unlikely (!url))
+    return nullptr;
+
+  auto ct_font_desc_array = CTFontManagerCreateFontDescriptorsFromURL (url);
+  if (unlikely (!ct_font_desc_array))
+  {
+    CFRelease (url);
+    return nullptr;
+  }
+  auto ct_font_desc = (CFArrayGetCount (ct_font_desc_array) > index) ?
+		      (CTFontDescriptorRef) CFArrayGetValueAtIndex (ct_font_desc_array, index) : nullptr;
+  if (unlikely (!ct_font_desc))
+  {
+	  CFRelease (ct_font_desc_array);
+	  CFRelease (url);
+	  return nullptr;
+  }
+  CFRelease (url);
+  auto ct_font = ct_font_desc ? CTFontCreateWithFontDescriptor (ct_font_desc, 0, nullptr) : nullptr;
+  CFRelease (ct_font_desc_array);
+  if (unlikely (!ct_font))
+    return nullptr;
+
+  auto cg_font = ct_font ? CTFontCopyGraphicsFont (ct_font, nullptr) : nullptr;
+  CFRelease (ct_font);
+  if (unlikely (!cg_font))
+    return nullptr;
+
+  hb_face_t *face = hb_coretext_face_create (cg_font);
+  if (unlikely (hb_face_is_immutable (face)))
+    return nullptr;
+
+  return face;
+}
+
+/**
+ * hb_coretext_face_get_cg_font:
+ * @face: The #hb_face_t to work upon
+ *
+ * Fetches the CGFontRef associated with an #hb_face_t
+ * face object
+ *
+ * Return value: the CGFontRef found
+ *
+ * Since: 0.9.10
+ */
+CGFontRef
+hb_coretext_face_get_cg_font (hb_face_t *face)
+{
+  return (CGFontRef) (const void *) face->data.coretext;
+}
+
+
+hb_coretext_font_data_t *
+_hb_coretext_shaper_font_data_create (hb_font_t *font)
+{
+  hb_face_t *face = font->face;
+  const hb_coretext_face_data_t *face_data = face->data.coretext;
+  if (unlikely (!face_data)) return nullptr;
+  CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
+
+  CGFloat font_size = (CGFloat) (font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem);
+  CTFontRef ct_font = create_ct_font (cg_font, font_size);
+
+  if (unlikely (!ct_font))
+  {
+    DEBUG_MSG (CORETEXT, font, "CGFont creation failed..");
+    return nullptr;
+  }
+
+  if (font->num_coords)
+  {
+    CFMutableDictionaryRef variations =
+      CFDictionaryCreateMutable (kCFAllocatorDefault,
+				 font->num_coords,
+				 &kCFTypeDictionaryKeyCallBacks,
+				 &kCFTypeDictionaryValueCallBacks);
+
+    for (unsigned i = 0; i < font->num_coords; i++)
+    {
+      if (font->coords[i] == 0.) continue;
+
+      hb_ot_var_axis_info_t info;
+      unsigned int c = 1;
+      hb_ot_var_get_axis_infos (font->face, i, &c, &info);
+      float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value);
+
+      CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag);
+      CFNumberRef value_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &v);
+      CFDictionarySetValue (variations, tag_number, value_number);
+      CFRelease (tag_number);
+      CFRelease (value_number);
+    }
+
+    CFDictionaryRef attributes =
+      CFDictionaryCreate (kCFAllocatorDefault,
+			  (const void **) &kCTFontVariationAttribute,
+			  (const void **) &variations,
+			  1,
+			  &kCFTypeDictionaryKeyCallBacks,
+			  &kCFTypeDictionaryValueCallBacks);
+
+    CTFontDescriptorRef varDesc = CTFontDescriptorCreateWithAttributes (attributes);
+    CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0, nullptr, varDesc);
+
+    CFRelease (ct_font);
+    CFRelease (attributes);
+    CFRelease (variations);
+    ct_font = new_ct_font;
+  }
+
+  return (hb_coretext_font_data_t *) ct_font;
+}
+
+void
+_hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data)
+{
+  CFRelease ((CTFontRef) data);
+}
+
+/**
+ * hb_coretext_font_create:
+ * @ct_font: The CTFontRef to work upon
+ *
+ * Creates an #hb_font_t font object from the specified
+ * CTFontRef.
+ *
+ * The created font uses the default font functions implemented
+ * navitely by HarfBuzz. If you want to use the CoreText font functions
+ * instead (rarely needed), you can do so by calling
+ * by hb_coretext_font_set_funcs().
+ *
+ * Return value: (transfer full): The new font object
+ *
+ * Since: 1.7.2
+ **/
+hb_font_t *
+hb_coretext_font_create (CTFontRef ct_font)
+{
+  CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr);
+  hb_face_t *face = hb_coretext_face_create (cg_font);
+  CFRelease (cg_font);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+
+  if (unlikely (hb_object_is_immutable (font)))
+    return font;
+
+  hb_font_set_ptem (font, CTFontGetSize (ct_font));
+
+  /* Let there be dragons here... */
+  font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font));
+
+  // https://github.com/harfbuzz/harfbuzz/pull/4895#issuecomment-2408471254
+  //hb_coretext_font_set_funcs (font);
+
+  return font;
+}
+
+/**
+ * hb_coretext_font_get_ct_font:
+ * @font: #hb_font_t to work upon
+ *
+ * Fetches the CTFontRef associated with the specified
+ * #hb_font_t font object.
+ *
+ * Return value: the CTFontRef found
+ *
+ * Since: 0.9.10
+ */
+CTFontRef
+hb_coretext_font_get_ct_font (hb_font_t *font)
+{
+  CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
+  return ct_font ? (CTFontRef) ct_font : nullptr;
+}
+
+
+/*
+ * shaper
+ */
+
+struct feature_record_t {
+  unsigned int feature;
+  unsigned int setting;
+};
+
+struct active_feature_t {
+  feature_record_t rec;
+  unsigned int order;
+
+  HB_INTERNAL static int cmp (const void *pa, const void *pb) {
+    const active_feature_t *a = (const active_feature_t *) pa;
+    const active_feature_t *b = (const active_feature_t *) pb;
+    return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
+	   a->order < b->order ? -1 : a->order > b->order ? 1 :
+	   a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
+	   0;
+  }
+  bool operator== (const active_feature_t& f) const {
+    return cmp (this, &f) == 0;
+  }
+};
+
+struct feature_event_t {
+  unsigned int index;
+  bool start;
+  active_feature_t feature;
+
+  HB_INTERNAL static int cmp (const void *pa, const void *pb) {
+    const feature_event_t *a = (const feature_event_t *) pa;
+    const feature_event_t *b = (const feature_event_t *) pb;
+    return a->index < b->index ? -1 : a->index > b->index ? 1 :
+	   a->start < b->start ? -1 : a->start > b->start ? 1 :
+	   active_feature_t::cmp (&a->feature, &b->feature);
+  }
+};
+
+struct range_record_t {
+  CTFontRef font;
+  unsigned int index_first; /* == start */
+  unsigned int index_last;  /* == end - 1 */
+};
+
+
+hb_bool_t
+_hb_coretext_shape (hb_shape_plan_t    *shape_plan,
+		    hb_font_t          *font,
+		    hb_buffer_t        *buffer,
+		    const hb_feature_t *features,
+		    unsigned int        num_features)
+{
+  hb_face_t *face = font->face;
+  CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
+  CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
+
+  CGFloat ct_font_size = CTFontGetSize (ct_font);
+  CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
+  CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
+
+  /* Attach marks to their bases, to match the 'ot' shaper.
+   * Adapted from a very old version of hb-ot-shape:hb_form_clusters().
+   * Note that this only makes us be closer to the 'ot' shaper,
+   * but by no means the same.  For example, if there's
+   * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will
+   * continue pointing to B2 even though B2 was merged into B1's
+   * cluster... */
+  if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
+  {
+    hb_unicode_funcs_t *unicode = buffer->unicode;
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    for (unsigned int i = 1; i < count; i++)
+      if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i].codepoint)))
+	buffer->merge_clusters (i - 1, i + 1);
+  }
+
+  hb_vector_t<range_record_t> range_records;
+
+  /*
+   * Set up features.
+   * (copied + modified from code from hb-uniscribe.cc)
+   */
+  if (num_features)
+  {
+    /* Sort features by start/end events. */
+    hb_vector_t<feature_event_t> feature_events;
+    for (unsigned int i = 0; i < num_features; i++)
+    {
+      active_feature_t feature;
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
+      const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag);
+      if (!mapping)
+	continue;
+
+      feature.rec.feature = mapping->aatFeatureType;
+      feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable;
+#else
+      feature.rec.feature = features[i].tag;
+      feature.rec.setting = features[i].value;
+#endif
+      feature.order = i;
+
+      feature_event_t *event;
+
+      event = feature_events.push ();
+      event->index = features[i].start;
+      event->start = true;
+      event->feature = feature;
+
+      event = feature_events.push ();
+      event->index = features[i].end;
+      event->start = false;
+      event->feature = feature;
+    }
+    feature_events.qsort ();
+    /* Add a strategic final event. */
+    {
+      active_feature_t feature;
+      feature.rec.feature = HB_TAG_NONE;
+      feature.rec.setting = 0;
+      feature.order = num_features + 1;
+
+      feature_event_t *event = feature_events.push ();
+      event->index = 0; /* This value does magic. */
+      event->start = false;
+      event->feature = feature;
+    }
+
+    /* Scan events and save features for each range. */
+    hb_vector_t<active_feature_t> active_features;
+    unsigned int last_index = 0;
+    for (unsigned int i = 0; i < feature_events.length; i++)
+    {
+      feature_event_t *event = &feature_events[i];
+
+      if (event->index != last_index)
+      {
+	/* Save a snapshot of active features and the range. */
+	range_record_t *range = range_records.push ();
+
+	if (active_features.length)
+	{
+	  CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+	  /* TODO sort and resolve conflicting features? */
+	  /* active_features.qsort (); */
+	  for (unsigned int j = 0; j < active_features.length; j++)
+	  {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
+	    CFStringRef keys[] = {
+	      kCTFontFeatureTypeIdentifierKey,
+	      kCTFontFeatureSelectorIdentifierKey
+	    };
+	    CFNumberRef values[] = {
+	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature),
+	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
+	    };
+#else
+	    char tag[5] = {HB_UNTAG (active_features[j].rec.feature)};
+	    CFTypeRef keys[] = {
+	      kCTFontOpenTypeFeatureTag,
+	      kCTFontOpenTypeFeatureValue
+	    };
+	    CFTypeRef values[] = {
+	      CFStringCreateWithCString (kCFAllocatorDefault, tag, kCFStringEncodingASCII),
+	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
+	    };
+#endif
+	    static_assert ((ARRAY_LENGTH_CONST (keys) == ARRAY_LENGTH_CONST (values)), "");
+	    CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault,
+						       (const void **) keys,
+						       (const void **) values,
+						       ARRAY_LENGTH (keys),
+						       &kCFTypeDictionaryKeyCallBacks,
+						       &kCFTypeDictionaryValueCallBacks);
+	    for (unsigned int i = 0; i < ARRAY_LENGTH (values); i++)
+	      CFRelease (values[i]);
+
+	    CFArrayAppendValue (features_array, dict);
+	    CFRelease (dict);
+
+	  }
+
+	  CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
+							   (const void **) &kCTFontFeatureSettingsAttribute,
+							   (const void **) &features_array,
+							   1,
+							   &kCFTypeDictionaryKeyCallBacks,
+							   &kCFTypeDictionaryValueCallBacks);
+	  CFRelease (features_array);
+
+	  CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
+	  CFRelease (attributes);
+
+	  range->font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, font_desc);
+	  CFRelease (font_desc);
+	}
+	else
+	{
+	  range->font = nullptr;
+	}
+
+	range->index_first = last_index;
+	range->index_last  = event->index - 1;
+
+	last_index = event->index;
+      }
+
+      if (event->start)
+      {
+	active_features.push (event->feature);
+      } else {
+	active_feature_t *feature = active_features.lsearch (event->feature);
+	if (feature)
+	  active_features.remove_ordered (feature - active_features.arrayZ);
+      }
+    }
+  }
+
+  unsigned int scratch_size;
+  hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
+
+#define ALLOCATE_ARRAY(Type, name, len, on_no_room) \
+  Type *name = (Type *) scratch; \
+  do { \
+    unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
+    if (unlikely (_consumed > scratch_size)) \
+    { \
+      on_no_room; \
+      assert (0); \
+    } \
+    scratch += _consumed; \
+    scratch_size -= _consumed; \
+  } while (0)
+
+  ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, ((void)nullptr) /*nothing*/);
+  unsigned int chars_len = 0;
+  for (unsigned int i = 0; i < buffer->len; i++) {
+    hb_codepoint_t c = buffer->info[i].codepoint;
+    if (likely (c <= 0xFFFFu))
+      pchars[chars_len++] = c;
+    else if (unlikely (c > 0x10FFFFu))
+      pchars[chars_len++] = 0xFFFDu;
+    else {
+      pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
+      pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
+    }
+  }
+
+  ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, ((void)nullptr) /*nothing*/);
+  chars_len = 0;
+  for (unsigned int i = 0; i < buffer->len; i++)
+  {
+    hb_codepoint_t c = buffer->info[i].codepoint;
+    unsigned int cluster = buffer->info[i].cluster;
+    log_clusters[chars_len++] = cluster;
+    if (hb_in_range (c, 0x10000u, 0x10FFFFu))
+      log_clusters[chars_len++] = cluster; /* Surrogates. */
+  }
+
+#define FAIL(...) \
+  HB_STMT_START { \
+    DEBUG_MSG (CORETEXT, nullptr, __VA_ARGS__); \
+    ret = false; \
+    goto fail; \
+  } HB_STMT_END
+
+  bool ret = true;
+  CFStringRef string_ref = nullptr;
+  CTLineRef line = nullptr;
+
+  if (false)
+  {
+resize_and_retry:
+    DEBUG_MSG (CORETEXT, buffer, "Buffer resize");
+    /* string_ref uses the scratch-buffer for backing store, and line references
+     * string_ref (via attr_string).  We must release those before resizing buffer. */
+    assert (string_ref);
+    assert (line);
+    CFRelease (string_ref);
+    CFRelease (line);
+    string_ref = nullptr;
+    line = nullptr;
+
+    /* Get previous start-of-scratch-area, that we use later for readjusting
+     * our existing scratch arrays. */
+    unsigned int old_scratch_used;
+    hb_buffer_t::scratch_buffer_t *old_scratch;
+    old_scratch = buffer->get_scratch_buffer (&old_scratch_used);
+    old_scratch_used = scratch - old_scratch;
+
+    if (unlikely (!buffer->ensure (buffer->allocated * 2)))
+      FAIL ("Buffer resize failed");
+
+    /* Adjust scratch, pchars, and log_cluster arrays.  This is ugly, but really the
+     * cleanest way to do without completely restructuring the rest of this shaper. */
+    scratch = buffer->get_scratch_buffer (&scratch_size);
+    pchars = reinterpret_cast<UniChar *> (((char *) scratch + ((char *) pchars - (char *) old_scratch)));
+    log_clusters = reinterpret_cast<unsigned int *> (((char *) scratch + ((char *) log_clusters - (char *) old_scratch)));
+    scratch += old_scratch_used;
+    scratch_size -= old_scratch_used;
+  }
+  {
+    string_ref = CFStringCreateWithCharactersNoCopy (nullptr,
+						     pchars, chars_len,
+						     kCFAllocatorNull);
+    if (unlikely (!string_ref))
+      FAIL ("CFStringCreateWithCharactersNoCopy failed");
+
+    /* Create an attributed string, populate it, and create a line from it, then release attributed string. */
+    {
+      CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (kCFAllocatorDefault,
+										  chars_len);
+      if (unlikely (!attr_string))
+	FAIL ("CFAttributedStringCreateMutable failed");
+      CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref);
+      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
+      {
+	CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
+					kCTVerticalFormsAttributeName, kCFBooleanTrue);
+      }
+
+      if (buffer->props.language)
+      {
+/* What's the iOS equivalent of this check?
+ * The symbols was introduced in iOS 7.0.
+ * At any rate, our fallback is safe and works fine. */
+#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+#  define kCTLanguageAttributeName CFSTR ("NSLanguage")
+#endif
+	CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
+							    hb_language_to_string (buffer->props.language),
+							    kCFStringEncodingUTF8,
+							    kCFAllocatorNull);
+	if (unlikely (!lang))
+	{
+	  CFRelease (attr_string);
+	  FAIL ("CFStringCreateWithCStringNoCopy failed");
+	}
+	CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
+					kCTLanguageAttributeName, lang);
+	CFRelease (lang);
+      }
+      CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
+				      kCTFontAttributeName, ct_font);
+
+      if (num_features && range_records.length)
+      {
+	unsigned int start = 0;
+	range_record_t *last_range = &range_records[0];
+	for (unsigned int k = 0; k < chars_len; k++)
+	{
+	  range_record_t *range = last_range;
+	  while (log_clusters[k] < range->index_first)
+	    range--;
+	  while (log_clusters[k] > range->index_last)
+	    range++;
+	  if (range != last_range)
+	  {
+	    if (last_range->font)
+	      CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, k - start),
+					      kCTFontAttributeName, last_range->font);
+
+	    start = k;
+	  }
+
+	  last_range = range;
+	}
+	if (start != chars_len && last_range->font)
+	  CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, chars_len - start),
+					  kCTFontAttributeName, last_range->font);
+      }
+      /* Enable/disable kern if requested.
+       *
+       * Note: once kern is disabled, reenabling it doesn't currently seem to work in CoreText.
+       */
+      if (num_features)
+      {
+	unsigned int zeroint = 0;
+	CFNumberRef zero = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &zeroint);
+	for (unsigned int i = 0; i < num_features; i++)
+	{
+	  const hb_feature_t &feature = features[i];
+	  if (feature.tag == HB_TAG('k','e','r','n') &&
+	      feature.start < chars_len && feature.start < feature.end)
+	  {
+	    CFRange feature_range = CFRangeMake (feature.start,
+						 hb_min (feature.end, chars_len) - feature.start);
+	    if (feature.value)
+	      CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName);
+	    else
+	      CFAttributedStringSetAttribute (attr_string, feature_range, kCTKernAttributeName, zero);
+	  }
+	}
+	CFRelease (zero);
+      }
+
+      int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
+      CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level);
+#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+      extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel;
+#endif
+      CFDictionaryRef options = CFDictionaryCreate (kCFAllocatorDefault,
+						    (const void **) &kCTTypesetterOptionForcedEmbeddingLevel,
+						    (const void **) &level_number,
+						    1,
+						    &kCFTypeDictionaryKeyCallBacks,
+						    &kCFTypeDictionaryValueCallBacks);
+      CFRelease (level_number);
+      if (unlikely (!options))
+      {
+	CFRelease (attr_string);
+	FAIL ("CFDictionaryCreate failed");
+      }
+
+      CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options);
+      CFRelease (options);
+      CFRelease (attr_string);
+      if (unlikely (!typesetter))
+	FAIL ("CTTypesetterCreateWithAttributedStringAndOptions failed");
+
+      line = CTTypesetterCreateLine (typesetter, CFRangeMake(0, 0));
+      CFRelease (typesetter);
+      if (unlikely (!line))
+	FAIL ("CTTypesetterCreateLine failed");
+    }
+
+    CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
+    unsigned int num_runs = CFArrayGetCount (glyph_runs);
+    DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs);
+
+    buffer->len = 0;
+    uint32_t status_or = 0;
+    CGFloat advances_so_far = 0;
+    /* For right-to-left runs, CoreText returns the glyphs positioned such that
+     * any trailing whitespace is to the left of (0,0).  Adjust coordinate system
+     * to fix for that.  Test with any RTL string with trailing spaces.
+     * https://crbug.com/469028
+     */
+    if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+    {
+      advances_so_far -= CTLineGetTrailingWhitespaceWidth (line);
+      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
+	  advances_so_far = -advances_so_far;
+    }
+
+    const CFRange range_all = CFRangeMake (0, 0);
+
+    for (unsigned int i = 0; i < num_runs; i++)
+    {
+      CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i));
+      CTRunStatus run_status = CTRunGetStatus (run);
+      status_or  |= run_status;
+      DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
+      CGFloat run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr);
+      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
+	  run_advance = -run_advance;
+      DEBUG_MSG (CORETEXT, run, "Run advance: %g", (double) run_advance);
+
+      /* CoreText does automatic font fallback (AKA "cascading") for  characters
+       * not supported by the requested font, and provides no way to turn it off,
+       * so we must detect if the returned run uses a font other than the requested
+       * one and fill in the buffer with .notdef glyphs instead of random glyph
+       * indices from a different font.
+       */
+      CFDictionaryRef attributes = CTRunGetAttributes (run);
+      CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
+      if (!CFEqual (run_ct_font, ct_font))
+      {
+	/* The run doesn't use our main font instance.  We have to figure out
+	 * whether font fallback happened, or this is just CoreText giving us
+	 * another CTFont using the same underlying CGFont.  CoreText seems
+	 * to do that in a variety of situations, one of which being vertical
+	 * text, but also perhaps for caching reasons.
+	 *
+	 * First, see if it uses any of our subfonts created to set font features...
+	 *
+	 * Next, compare the CGFont to the one we used to create our fonts.
+	 * Even this doesn't work all the time.
+	 *
+	 * Finally, we compare PS names, which I don't think are unique...
+	 *
+	 * Looks like if we really want to be sure here we have to modify the
+	 * font to change the name table, similar to what we do in the uniscribe
+	 * backend.
+	 *
+	 * However, even that wouldn't work if we were passed in the CGFont to
+	 * construct a hb_face to begin with.
+	 *
+	 * See: https://github.com/harfbuzz/harfbuzz/pull/36
+	 *
+	 * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098
+	 */
+	bool matched = false;
+	for (unsigned int i = 0; i < range_records.length; i++)
+	  if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font))
+	  {
+	    matched = true;
+	    break;
+	  }
+	if (!matched)
+	{
+	  CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, nullptr);
+	  if (run_cg_font)
+	  {
+	    matched = CFEqual (run_cg_font, cg_font);
+	    CFRelease (run_cg_font);
+	  }
+	}
+	if (!matched)
+	{
+	  CFStringRef font_ps_name = CTFontCopyName (ct_font, kCTFontPostScriptNameKey);
+	  CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey);
+	  CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0);
+	  CFRelease (run_ps_name);
+	  CFRelease (font_ps_name);
+	  if (result == kCFCompareEqualTo)
+	    matched = true;
+	}
+	if (!matched)
+	{
+	  CFRange range = CTRunGetStringRange (run);
+	  DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
+		     range.location, range.location + range.length);
+	  if (!buffer->ensure_inplace (buffer->len + range.length))
+	    goto resize_and_retry;
+	  hb_glyph_info_t *info = buffer->info + buffer->len;
+
+	  hb_codepoint_t notdef = 0;
+	  hb_direction_t dir = buffer->props.direction;
+	  hb_position_t x_advance, y_advance, x_offset, y_offset;
+	  hb_font_get_glyph_advance_for_direction (font, notdef, dir, &x_advance, &y_advance);
+	  hb_font_get_glyph_origin_for_direction (font, notdef, dir, &x_offset, &y_offset);
+	  hb_position_t advance = x_advance + y_advance;
+	  x_offset = -x_offset;
+	  y_offset = -y_offset;
+
+	  unsigned int old_len = buffer->len;
+	  for (CFIndex j = range.location; j < range.location + range.length; j++)
+	  {
+	      UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
+	      if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j)
+	      {
+		ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
+		if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu))
+		  /* This is the second of a surrogate pair.  Don't need .notdef
+		   * for this one. */
+		  continue;
+	      }
+	      if (buffer->unicode->is_default_ignorable (ch))
+		continue;
+
+	      info->codepoint = notdef;
+	      info->cluster = log_clusters[j];
+
+	      info->mask = advance;
+	      info->var1.i32 = x_offset;
+	      info->var2.i32 = y_offset;
+
+	      info++;
+	      buffer->len++;
+	  }
+	  if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+	    buffer->reverse_range (old_len, buffer->len);
+	  advances_so_far += run_advance;
+	  continue;
+	}
+      }
+
+      unsigned int num_glyphs = CTRunGetGlyphCount (run);
+      if (num_glyphs == 0)
+	continue;
+
+      if (!buffer->ensure_inplace (buffer->len + num_glyphs))
+	goto resize_and_retry;
+
+      hb_glyph_info_t *run_info = buffer->info + buffer->len;
+
+      /* Testing used to indicate that CTRunGetGlyphsPtr, etc (almost?) always
+       * succeed, and so copying data to our own buffer will be rare.  Reports
+       * have it that this changed in OS X 10.10 Yosemite, and nullptr is returned
+       * frequently.  At any rate, we can test that codepath by setting USE_PTR
+       * to false. */
+
+#define USE_PTR true
+
+#define SCRATCH_SAVE() \
+  unsigned int scratch_size_saved = scratch_size; \
+  hb_buffer_t::scratch_buffer_t *scratch_saved = scratch
+
+#define SCRATCH_RESTORE() \
+  scratch_size = scratch_size_saved; \
+  scratch = scratch_saved
+
+      { /* Setup glyphs */
+	SCRATCH_SAVE();
+	const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : nullptr;
+	if (!glyphs) {
+	  ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry);
+	  CTRunGetGlyphs (run, range_all, glyph_buf);
+	  glyphs = glyph_buf;
+	}
+	const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : nullptr;
+	if (!string_indices) {
+	  ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs, goto resize_and_retry);
+	  CTRunGetStringIndices (run, range_all, index_buf);
+	  string_indices = index_buf;
+	}
+	hb_glyph_info_t *info = run_info;
+	for (unsigned int j = 0; j < num_glyphs; j++)
+	{
+	  info->codepoint = glyphs[j];
+	  info->cluster = log_clusters[string_indices[j]];
+	  info++;
+	}
+	SCRATCH_RESTORE();
+      }
+      {
+	/* Setup positions.
+	 * Note that CoreText does not return advances for glyphs.  As such,
+	 * for all but last glyph, we use the delta position to next glyph as
+	 * advance (in the advance direction only), and for last glyph we set
+	 * whatever is needed to make the whole run's advance add up. */
+	SCRATCH_SAVE();
+	const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : nullptr;
+	if (!positions) {
+	  ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry);
+	  CTRunGetPositions (run, range_all, position_buf);
+	  positions = position_buf;
+	}
+	hb_glyph_info_t *info = run_info;
+	if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+	{
+	  hb_position_t x_offset = round ((positions[0].x - advances_so_far) * x_mult);
+	  for (unsigned int j = 0; j < num_glyphs; j++)
+	  {
+	    CGFloat advance;
+	    if (likely (j + 1 < num_glyphs))
+	      advance = positions[j + 1].x - positions[j].x;
+	    else /* last glyph */
+	      advance = run_advance - (positions[j].x - positions[0].x);
+	    /* int cast necessary to pass through negative values. */
+	    info->mask = (int) round (advance * x_mult);
+	    info->var1.i32 = x_offset;
+	    info->var2.i32 = round (positions[j].y * y_mult);
+	    info++;
+	  }
+	}
+	else
+	{
+	  hb_position_t y_offset = round ((positions[0].y - advances_so_far) * y_mult);
+	  for (unsigned int j = 0; j < num_glyphs; j++)
+	  {
+	    CGFloat advance;
+	    if (likely (j + 1 < num_glyphs))
+	      advance = positions[j + 1].y - positions[j].y;
+	    else /* last glyph */
+	      advance = run_advance - (positions[j].y - positions[0].y);
+	    /* int cast necessary to pass through negative values. */
+	    info->mask = (int) round (advance * y_mult);
+	    info->var1.i32 = round (positions[j].x * x_mult);
+	    info->var2.i32 = y_offset;
+	    info++;
+	  }
+	}
+	SCRATCH_RESTORE();
+	advances_so_far += run_advance;
+      }
+#undef SCRATCH_RESTORE
+#undef SCRATCH_SAVE
+#undef USE_PTR
+#undef ALLOCATE_ARRAY
+
+      buffer->len += num_glyphs;
+    }
+
+    buffer->clear_positions ();
+
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    hb_glyph_position_t *pos = buffer->pos;
+    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+      for (unsigned int i = 0; i < count; i++)
+      {
+	pos->x_advance = info->mask;
+	pos->x_offset = info->var1.i32;
+	pos->y_offset = info->var2.i32;
+
+	info++; pos++;
+      }
+    else
+      for (unsigned int i = 0; i < count; i++)
+      {
+	pos->y_advance = info->mask;
+	pos->x_offset = info->var1.i32;
+	pos->y_offset = info->var2.i32;
+
+	info++; pos++;
+      }
+
+    /* Fix up clusters so that we never return out-of-order indices;
+     * if core text has reordered glyphs, we'll merge them to the
+     * beginning of the reordered cluster.  CoreText is nice enough
+     * to tell us whenever it has produced nonmonotonic results...
+     * Note that we assume the input clusters were nonmonotonic to
+     * begin with.
+     *
+     * This does *not* mean we'll form the same clusters as Uniscribe
+     * or the native OT backend, only that the cluster indices will be
+     * monotonic in the output buffer. */
+    if (count > 1 && (status_or & kCTRunStatusNonMonotonic) &&
+	buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
+    {
+      hb_glyph_info_t *info = buffer->info;
+      if (HB_DIRECTION_IS_FORWARD (buffer->props.direction))
+      {
+	unsigned int cluster = info[count - 1].cluster;
+	for (unsigned int i = count - 1; i > 0; i--)
+	{
+	  cluster = hb_min (cluster, info[i - 1].cluster);
+	  info[i - 1].cluster = cluster;
+	}
+      }
+      else
+      {
+	unsigned int cluster = info[0].cluster;
+	for (unsigned int i = 1; i < count; i++)
+	{
+	  cluster = hb_min (cluster, info[i].cluster);
+	  info[i].cluster = cluster;
+	}
+      }
+    }
+  }
+
+  /* TODO: Sometimes the above positioning code generates negative
+   * advance values. Fix them up. Example, with NotoNastaliqUrdu
+   * font and sequence ابهد. */
+
+  buffer->clear_glyph_flags ();
+  buffer->unsafe_to_break ();
+
+#undef FAIL
+
+fail:
+  if (string_ref)
+    CFRelease (string_ref);
+  if (line)
+    CFRelease (line);
+
+  for (unsigned int i = 0; i < range_records.length; i++)
+    if (range_records[i].font)
+      CFRelease (range_records[i].font);
+
+  return ret;
+}
+
+
+#endif

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -1,1247 +0,0 @@
-/*
- * Copyright © 2012,2013  Mozilla Foundation.
- * Copyright © 2012,2013  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
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_CORETEXT
-
-#include "hb-shaper-impl.hh"
-
-#include "hb-coretext.h"
-#include "hb-aat-layout.hh"
-
-
-/**
- * SECTION:hb-coretext
- * @title: hb-coretext
- * @short_description: CoreText integration
- * @include: hb-coretext.h
- *
- * Functions for using HarfBuzz with the CoreText fonts.
- **/
-
-/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
-#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
-
-static CTFontRef create_ct_font (CGFontRef cg_font, CGFloat font_size);
-
-static void
-release_table_data (void *user_data)
-{
-  CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data);
-  CFRelease(cf_data);
-}
-
-static hb_blob_t *
-_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
-{
-  CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
-  CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
-  if (unlikely (!cf_data))
-    return nullptr;
-
-  const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data));
-  const size_t length = CFDataGetLength (cf_data);
-  if (!data || !length)
-  {
-    CFRelease (cf_data);
-    return nullptr;
-  }
-
-  return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
-			 reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)),
-			 release_table_data);
-}
-
-static unsigned
-_hb_cg_get_table_tags (const hb_face_t *face HB_UNUSED,
-		       unsigned int start_offset,
-		       unsigned int *table_count,
-		       hb_tag_t *table_tags,
-		       void *user_data)
-{
-  CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
-
-  CTFontRef ct_font = create_ct_font (cg_font, (CGFloat) HB_CORETEXT_DEFAULT_FONT_SIZE);
-
-  auto arr = CTFontCopyAvailableTables (ct_font, kCTFontTableOptionNoOptions);
-
-  unsigned population = (unsigned) CFArrayGetCount (arr);
-  unsigned end_offset;
-
-  if (!table_count)
-    goto done;
-
-  if (unlikely (start_offset >= population))
-  {
-    *table_count = 0;
-    goto done;
-  }
-
-  end_offset = start_offset + *table_count;
-  if (unlikely (end_offset < start_offset))
-  {
-    *table_count = 0;
-    goto done;
-  }
-  end_offset= hb_min (end_offset, (unsigned) population);
-
-  *table_count = end_offset - start_offset;
-  for (unsigned i = start_offset; i < end_offset; i++)
-  {
-    CTFontTableTag tag = (CTFontTableTag)(uintptr_t) CFArrayGetValueAtIndex (arr, i);
-    table_tags[i - start_offset] = tag;
-  }
-
-done:
-  CFRelease (arr);
-  CFRelease (ct_font);
-  return population;
-}
-
-static void
-_hb_cg_font_release (void *data)
-{
-  CGFontRelease ((CGFontRef) data);
-}
-
-
-static CTFontDescriptorRef
-get_last_resort_font_desc ()
-{
-  // TODO Handle allocation failures?
-  CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0);
-  CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault,
-					   (const void **) &last_resort,
-					   1,
-					   &kCFTypeArrayCallBacks);
-  CFRelease (last_resort);
-  CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
-						   (const void **) &kCTFontCascadeListAttribute,
-						   (const void **) &cascade_list,
-						   1,
-						   &kCFTypeDictionaryKeyCallBacks,
-						   &kCFTypeDictionaryValueCallBacks);
-  CFRelease (cascade_list);
-
-  CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
-  CFRelease (attributes);
-  return font_desc;
-}
-
-static void
-release_data (void *info, const void *data, size_t size)
-{
-  assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
-	  hb_blob_get_data ((hb_blob_t *) info, nullptr) == data);
-
-  hb_blob_destroy ((hb_blob_t *) info);
-}
-
-static CGFontRef
-create_cg_font (hb_face_t *face)
-{
-  CGFontRef cg_font = nullptr;
-  if (face->destroy == _hb_cg_font_release)
-  {
-    cg_font = CGFontRetain ((CGFontRef) face->user_data);
-  }
-  else
-  {
-    hb_blob_t *blob = hb_face_reference_blob (face);
-    unsigned int blob_length;
-    const char *blob_data = hb_blob_get_data (blob, &blob_length);
-    if (unlikely (!blob_length))
-      DEBUG_MSG (CORETEXT, face, "Face has empty blob");
-
-    CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
-    if (likely (provider))
-    {
-      cg_font = CGFontCreateWithDataProvider (provider);
-      if (unlikely (!cg_font))
-	DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
-      CGDataProviderRelease (provider);
-    }
-  }
-  return cg_font;
-}
-
-static CTFontRef
-create_ct_font (CGFontRef cg_font, CGFloat font_size)
-{
-  CTFontRef ct_font = nullptr;
-
-  /* CoreText does not enable trak table usage / tracking when creating a CTFont
-   * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems
-   * to be through the CTFontCreateUIFontForLanguage call. */
-  CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font);
-  if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) ||
-      CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay")))
-  {
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1080
-# define kCTFontUIFontSystem kCTFontSystemFontType
-# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType
-#endif
-    CTFontUIFontType font_type = kCTFontUIFontSystem;
-    if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold")))
-      font_type = kCTFontUIFontEmphasizedSystem;
-
-    ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, nullptr);
-    CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font);
-    if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo)
-    {
-      CFRelease(ct_font);
-      ct_font = nullptr;
-    }
-    CFRelease (ct_result_name);
-  }
-  CFRelease (cg_postscript_name);
-
-  if (!ct_font)
-    ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, nullptr, nullptr);
-
-  if (unlikely (!ct_font)) {
-    DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
-    return nullptr;
-  }
-
-  /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter
-   * bug indicate that the cascade list reconfiguration occasionally causes
-   * crashes in CoreText on OS X 10.9, thus let's skip this step on older
-   * operating system versions. Except for the emoji font, where _not_
-   * reconfiguring the cascade list causes CoreText crashes. For details, see
-   * crbug.com/549610 */
-  // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-  if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) {
-#pragma GCC diagnostic pop
-    CFStringRef fontName = CTFontCopyPostScriptName (ct_font);
-    bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo;
-    CFRelease (fontName);
-    if (!isEmojiFont)
-      return ct_font;
-  }
-
-  CFURLRef original_url = nullptr;
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-  ATSFontRef atsFont;
-  FSRef fsref;
-  OSStatus status;
-  atsFont = CTFontGetPlatformFont (ct_font, NULL);
-  status = ATSFontGetFileReference (atsFont, &fsref);
-  if (status == noErr)
-    original_url = CFURLCreateFromFSRef (NULL, &fsref);
-#else
-  original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute);
-#endif
-
-  /* Create font copy with cascade list that has LastResort first; this speeds up CoreText
-   * font fallback which we don't need anyway. */
-  {
-    CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc ();
-    CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, last_resort_font_desc);
-    CFRelease (last_resort_font_desc);
-    if (new_ct_font)
-    {
-      /* The CTFontCreateCopyWithAttributes call fails to stay on the same font
-       * when reconfiguring the cascade list and may switch to a different font
-       * when there are fonts that go by the same name, since the descriptor is
-       * just name and size.
-       *
-       * Avoid reconfiguring the cascade lists if the new font is outside the
-       * system locations that we cannot access from the sandboxed renderer
-       * process in Blink. This can be detected by the new file URL location
-       * that the newly found font points to. */
-      CFURLRef new_url = nullptr;
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-      atsFont = CTFontGetPlatformFont (new_ct_font, NULL);
-      status = ATSFontGetFileReference (atsFont, &fsref);
-      if (status == noErr)
-	new_url = CFURLCreateFromFSRef (NULL, &fsref);
-#else
-      new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
-#endif
-      // Keep reconfigured font if URL cannot be retrieved (seems to be the case
-      // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606
-      if (!original_url || !new_url || CFEqual (original_url, new_url)) {
-	CFRelease (ct_font);
-	ct_font = new_ct_font;
-      } else {
-	CFRelease (new_ct_font);
-	DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
-      }
-      if (new_url)
-	CFRelease (new_url);
-    }
-    else
-      DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed");
-  }
-
-  if (original_url)
-    CFRelease (original_url);
-  return ct_font;
-}
-
-hb_coretext_face_data_t *
-_hb_coretext_shaper_face_data_create (hb_face_t *face)
-{
-  CGFontRef cg_font = create_cg_font (face);
-
-  if (unlikely (!cg_font))
-  {
-    DEBUG_MSG (CORETEXT, face, "CGFont creation failed..");
-    return nullptr;
-  }
-
-  return (hb_coretext_face_data_t *) cg_font;
-}
-
-void
-_hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data)
-{
-  CFRelease ((CGFontRef) data);
-}
-
-/**
- * hb_coretext_face_create:
- * @cg_font: The CGFontRef to work upon
- *
- * Creates an #hb_face_t face object from the specified
- * CGFontRef.
- *
- * Return value: the new #hb_face_t face object
- *
- * Since: 0.9.10
- */
-hb_face_t *
-hb_coretext_face_create (CGFontRef cg_font)
-{
-  hb_face_t *face = hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
-  hb_face_set_get_table_tags_func (face, _hb_cg_get_table_tags, cg_font, nullptr);
-  return face;
-}
-
-/**
- * hb_coretext_face_get_cg_font:
- * @face: The #hb_face_t to work upon
- *
- * Fetches the CGFontRef associated with an #hb_face_t
- * face object
- *
- * Return value: the CGFontRef found
- *
- * Since: 0.9.10
- */
-CGFontRef
-hb_coretext_face_get_cg_font (hb_face_t *face)
-{
-  return (CGFontRef) (const void *) face->data.coretext;
-}
-
-
-hb_coretext_font_data_t *
-_hb_coretext_shaper_font_data_create (hb_font_t *font)
-{
-  hb_face_t *face = font->face;
-  const hb_coretext_face_data_t *face_data = face->data.coretext;
-  if (unlikely (!face_data)) return nullptr;
-  CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
-
-  CGFloat font_size = (CGFloat) (font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem);
-  CTFontRef ct_font = create_ct_font (cg_font, font_size);
-
-  if (unlikely (!ct_font))
-  {
-    DEBUG_MSG (CORETEXT, font, "CGFont creation failed..");
-    return nullptr;
-  }
-
-  if (font->num_coords)
-  {
-    CFMutableDictionaryRef variations =
-      CFDictionaryCreateMutable (kCFAllocatorDefault,
-				 font->num_coords,
-				 &kCFTypeDictionaryKeyCallBacks,
-				 &kCFTypeDictionaryValueCallBacks);
-
-    for (unsigned i = 0; i < font->num_coords; i++)
-    {
-      if (font->coords[i] == 0.) continue;
-
-      hb_ot_var_axis_info_t info;
-      unsigned int c = 1;
-      hb_ot_var_get_axis_infos (font->face, i, &c, &info);
-      float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value);
-
-      CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag);
-      CFNumberRef value_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &v);
-      CFDictionarySetValue (variations, tag_number, value_number);
-      CFRelease (tag_number);
-      CFRelease (value_number);
-    }
-
-    CFDictionaryRef attributes =
-      CFDictionaryCreate (kCFAllocatorDefault,
-			  (const void **) &kCTFontVariationAttribute,
-			  (const void **) &variations,
-			  1,
-			  &kCFTypeDictionaryKeyCallBacks,
-			  &kCFTypeDictionaryValueCallBacks);
-
-    CTFontDescriptorRef varDesc = CTFontDescriptorCreateWithAttributes (attributes);
-    CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0, nullptr, varDesc);
-
-    CFRelease (ct_font);
-    CFRelease (attributes);
-    CFRelease (variations);
-    ct_font = new_ct_font;
-  }
-
-  return (hb_coretext_font_data_t *) ct_font;
-}
-
-void
-_hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data)
-{
-  CFRelease ((CTFontRef) data);
-}
-
-/**
- * hb_coretext_font_create:
- * @ct_font: The CTFontRef to work upon
- *
- * Creates an #hb_font_t font object from the specified
- * CTFontRef.
- *
- * Return value: the new #hb_font_t font object
- *
- * Since: 1.7.2
- **/
-hb_font_t *
-hb_coretext_font_create (CTFontRef ct_font)
-{
-  CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr);
-  hb_face_t *face = hb_coretext_face_create (cg_font);
-  CFRelease (cg_font);
-  hb_font_t *font = hb_font_create (face);
-  hb_face_destroy (face);
-
-  if (unlikely (hb_object_is_immutable (font)))
-    return font;
-
-  hb_font_set_ptem (font, CTFontGetSize (ct_font));
-
-  /* Let there be dragons here... */
-  font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font));
-
-  return font;
-}
-
-/**
- * hb_coretext_font_get_ct_font:
- * @font: #hb_font_t to work upon
- *
- * Fetches the CTFontRef associated with the specified
- * #hb_font_t font object.
- *
- * Return value: the CTFontRef found
- *
- * Since: 0.9.10
- */
-CTFontRef
-hb_coretext_font_get_ct_font (hb_font_t *font)
-{
-  CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
-  return ct_font ? (CTFontRef) ct_font : nullptr;
-}
-
-
-/*
- * shaper
- */
-
-struct feature_record_t {
-  unsigned int feature;
-  unsigned int setting;
-};
-
-struct active_feature_t {
-  feature_record_t rec;
-  unsigned int order;
-
-  HB_INTERNAL static int cmp (const void *pa, const void *pb) {
-    const active_feature_t *a = (const active_feature_t *) pa;
-    const active_feature_t *b = (const active_feature_t *) pb;
-    return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
-	   a->order < b->order ? -1 : a->order > b->order ? 1 :
-	   a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
-	   0;
-  }
-  bool operator== (const active_feature_t& f) const {
-    return cmp (this, &f) == 0;
-  }
-};
-
-struct feature_event_t {
-  unsigned int index;
-  bool start;
-  active_feature_t feature;
-
-  HB_INTERNAL static int cmp (const void *pa, const void *pb) {
-    const feature_event_t *a = (const feature_event_t *) pa;
-    const feature_event_t *b = (const feature_event_t *) pb;
-    return a->index < b->index ? -1 : a->index > b->index ? 1 :
-	   a->start < b->start ? -1 : a->start > b->start ? 1 :
-	   active_feature_t::cmp (&a->feature, &b->feature);
-  }
-};
-
-struct range_record_t {
-  CTFontRef font;
-  unsigned int index_first; /* == start */
-  unsigned int index_last;  /* == end - 1 */
-};
-
-
-hb_bool_t
-_hb_coretext_shape (hb_shape_plan_t    *shape_plan,
-		    hb_font_t          *font,
-		    hb_buffer_t        *buffer,
-		    const hb_feature_t *features,
-		    unsigned int        num_features)
-{
-  hb_face_t *face = font->face;
-  CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
-  CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
-
-  CGFloat ct_font_size = CTFontGetSize (ct_font);
-  CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
-  CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
-
-  /* Attach marks to their bases, to match the 'ot' shaper.
-   * Adapted from a very old version of hb-ot-shape:hb_form_clusters().
-   * Note that this only makes us be closer to the 'ot' shaper,
-   * but by no means the same.  For example, if there's
-   * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will
-   * continue pointing to B2 even though B2 was merged into B1's
-   * cluster... */
-  if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
-  {
-    hb_unicode_funcs_t *unicode = buffer->unicode;
-    unsigned int count = buffer->len;
-    hb_glyph_info_t *info = buffer->info;
-    for (unsigned int i = 1; i < count; i++)
-      if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i].codepoint)))
-	buffer->merge_clusters (i - 1, i + 1);
-  }
-
-  hb_vector_t<range_record_t> range_records;
-
-  /*
-   * Set up features.
-   * (copied + modified from code from hb-uniscribe.cc)
-   */
-  if (num_features)
-  {
-    /* Sort features by start/end events. */
-    hb_vector_t<feature_event_t> feature_events;
-    for (unsigned int i = 0; i < num_features; i++)
-    {
-      active_feature_t feature;
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
-      const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag);
-      if (!mapping)
-	continue;
-
-      feature.rec.feature = mapping->aatFeatureType;
-      feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable;
-#else
-      feature.rec.feature = features[i].tag;
-      feature.rec.setting = features[i].value;
-#endif
-      feature.order = i;
-
-      feature_event_t *event;
-
-      event = feature_events.push ();
-      event->index = features[i].start;
-      event->start = true;
-      event->feature = feature;
-
-      event = feature_events.push ();
-      event->index = features[i].end;
-      event->start = false;
-      event->feature = feature;
-    }
-    feature_events.qsort ();
-    /* Add a strategic final event. */
-    {
-      active_feature_t feature;
-      feature.rec.feature = HB_TAG_NONE;
-      feature.rec.setting = 0;
-      feature.order = num_features + 1;
-
-      feature_event_t *event = feature_events.push ();
-      event->index = 0; /* This value does magic. */
-      event->start = false;
-      event->feature = feature;
-    }
-
-    /* Scan events and save features for each range. */
-    hb_vector_t<active_feature_t> active_features;
-    unsigned int last_index = 0;
-    for (unsigned int i = 0; i < feature_events.length; i++)
-    {
-      feature_event_t *event = &feature_events[i];
-
-      if (event->index != last_index)
-      {
-	/* Save a snapshot of active features and the range. */
-	range_record_t *range = range_records.push ();
-
-	if (active_features.length)
-	{
-	  CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-
-	  /* TODO sort and resolve conflicting features? */
-	  /* active_features.qsort (); */
-	  for (unsigned int j = 0; j < active_features.length; j++)
-	  {
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
-	    CFStringRef keys[] = {
-	      kCTFontFeatureTypeIdentifierKey,
-	      kCTFontFeatureSelectorIdentifierKey
-	    };
-	    CFNumberRef values[] = {
-	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature),
-	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
-	    };
-#else
-	    char tag[5] = {HB_UNTAG (active_features[j].rec.feature)};
-	    CFTypeRef keys[] = {
-	      kCTFontOpenTypeFeatureTag,
-	      kCTFontOpenTypeFeatureValue
-	    };
-	    CFTypeRef values[] = {
-	      CFStringCreateWithCString (kCFAllocatorDefault, tag, kCFStringEncodingASCII),
-	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
-	    };
-#endif
-	    static_assert ((ARRAY_LENGTH_CONST (keys) == ARRAY_LENGTH_CONST (values)), "");
-	    CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault,
-						       (const void **) keys,
-						       (const void **) values,
-						       ARRAY_LENGTH (keys),
-						       &kCFTypeDictionaryKeyCallBacks,
-						       &kCFTypeDictionaryValueCallBacks);
-	    for (unsigned int i = 0; i < ARRAY_LENGTH (values); i++)
-	      CFRelease (values[i]);
-
-	    CFArrayAppendValue (features_array, dict);
-	    CFRelease (dict);
-
-	  }
-
-	  CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
-							   (const void **) &kCTFontFeatureSettingsAttribute,
-							   (const void **) &features_array,
-							   1,
-							   &kCFTypeDictionaryKeyCallBacks,
-							   &kCFTypeDictionaryValueCallBacks);
-	  CFRelease (features_array);
-
-	  CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
-	  CFRelease (attributes);
-
-	  range->font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, font_desc);
-	  CFRelease (font_desc);
-	}
-	else
-	{
-	  range->font = nullptr;
-	}
-
-	range->index_first = last_index;
-	range->index_last  = event->index - 1;
-
-	last_index = event->index;
-      }
-
-      if (event->start)
-      {
-	active_features.push (event->feature);
-      } else {
-	active_feature_t *feature = active_features.lsearch (event->feature);
-	if (feature)
-	  active_features.remove_ordered (feature - active_features.arrayZ);
-      }
-    }
-  }
-
-  unsigned int scratch_size;
-  hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
-
-#define ALLOCATE_ARRAY(Type, name, len, on_no_room) \
-  Type *name = (Type *) scratch; \
-  do { \
-    unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
-    if (unlikely (_consumed > scratch_size)) \
-    { \
-      on_no_room; \
-      assert (0); \
-    } \
-    scratch += _consumed; \
-    scratch_size -= _consumed; \
-  } while (0)
-
-  ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, ((void)nullptr) /*nothing*/);
-  unsigned int chars_len = 0;
-  for (unsigned int i = 0; i < buffer->len; i++) {
-    hb_codepoint_t c = buffer->info[i].codepoint;
-    if (likely (c <= 0xFFFFu))
-      pchars[chars_len++] = c;
-    else if (unlikely (c > 0x10FFFFu))
-      pchars[chars_len++] = 0xFFFDu;
-    else {
-      pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
-      pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
-    }
-  }
-
-  ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, ((void)nullptr) /*nothing*/);
-  chars_len = 0;
-  for (unsigned int i = 0; i < buffer->len; i++)
-  {
-    hb_codepoint_t c = buffer->info[i].codepoint;
-    unsigned int cluster = buffer->info[i].cluster;
-    log_clusters[chars_len++] = cluster;
-    if (hb_in_range (c, 0x10000u, 0x10FFFFu))
-      log_clusters[chars_len++] = cluster; /* Surrogates. */
-  }
-
-#define FAIL(...) \
-  HB_STMT_START { \
-    DEBUG_MSG (CORETEXT, nullptr, __VA_ARGS__); \
-    ret = false; \
-    goto fail; \
-  } HB_STMT_END
-
-  bool ret = true;
-  CFStringRef string_ref = nullptr;
-  CTLineRef line = nullptr;
-
-  if (false)
-  {
-resize_and_retry:
-    DEBUG_MSG (CORETEXT, buffer, "Buffer resize");
-    /* string_ref uses the scratch-buffer for backing store, and line references
-     * string_ref (via attr_string).  We must release those before resizing buffer. */
-    assert (string_ref);
-    assert (line);
-    CFRelease (string_ref);
-    CFRelease (line);
-    string_ref = nullptr;
-    line = nullptr;
-
-    /* Get previous start-of-scratch-area, that we use later for readjusting
-     * our existing scratch arrays. */
-    unsigned int old_scratch_used;
-    hb_buffer_t::scratch_buffer_t *old_scratch;
-    old_scratch = buffer->get_scratch_buffer (&old_scratch_used);
-    old_scratch_used = scratch - old_scratch;
-
-    if (unlikely (!buffer->ensure (buffer->allocated * 2)))
-      FAIL ("Buffer resize failed");
-
-    /* Adjust scratch, pchars, and log_cluster arrays.  This is ugly, but really the
-     * cleanest way to do without completely restructuring the rest of this shaper. */
-    scratch = buffer->get_scratch_buffer (&scratch_size);
-    pchars = reinterpret_cast<UniChar *> (((char *) scratch + ((char *) pchars - (char *) old_scratch)));
-    log_clusters = reinterpret_cast<unsigned int *> (((char *) scratch + ((char *) log_clusters - (char *) old_scratch)));
-    scratch += old_scratch_used;
-    scratch_size -= old_scratch_used;
-  }
-  {
-    string_ref = CFStringCreateWithCharactersNoCopy (nullptr,
-						     pchars, chars_len,
-						     kCFAllocatorNull);
-    if (unlikely (!string_ref))
-      FAIL ("CFStringCreateWithCharactersNoCopy failed");
-
-    /* Create an attributed string, populate it, and create a line from it, then release attributed string. */
-    {
-      CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (kCFAllocatorDefault,
-										  chars_len);
-      if (unlikely (!attr_string))
-	FAIL ("CFAttributedStringCreateMutable failed");
-      CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref);
-      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
-      {
-	CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
-					kCTVerticalFormsAttributeName, kCFBooleanTrue);
-      }
-
-      if (buffer->props.language)
-      {
-/* What's the iOS equivalent of this check?
- * The symbols was introduced in iOS 7.0.
- * At any rate, our fallback is safe and works fine. */
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1090
-#  define kCTLanguageAttributeName CFSTR ("NSLanguage")
-#endif
-	CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
-							    hb_language_to_string (buffer->props.language),
-							    kCFStringEncodingUTF8,
-							    kCFAllocatorNull);
-	if (unlikely (!lang))
-	{
-	  CFRelease (attr_string);
-	  FAIL ("CFStringCreateWithCStringNoCopy failed");
-	}
-	CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
-					kCTLanguageAttributeName, lang);
-	CFRelease (lang);
-      }
-      CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
-				      kCTFontAttributeName, ct_font);
-
-      if (num_features && range_records.length)
-      {
-	unsigned int start = 0;
-	range_record_t *last_range = &range_records[0];
-	for (unsigned int k = 0; k < chars_len; k++)
-	{
-	  range_record_t *range = last_range;
-	  while (log_clusters[k] < range->index_first)
-	    range--;
-	  while (log_clusters[k] > range->index_last)
-	    range++;
-	  if (range != last_range)
-	  {
-	    if (last_range->font)
-	      CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, k - start),
-					      kCTFontAttributeName, last_range->font);
-
-	    start = k;
-	  }
-
-	  last_range = range;
-	}
-	if (start != chars_len && last_range->font)
-	  CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, chars_len - start),
-					  kCTFontAttributeName, last_range->font);
-      }
-      /* Enable/disable kern if requested.
-       *
-       * Note: once kern is disabled, reenabling it doesn't currently seem to work in CoreText.
-       */
-      if (num_features)
-      {
-	unsigned int zeroint = 0;
-	CFNumberRef zero = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &zeroint);
-	for (unsigned int i = 0; i < num_features; i++)
-	{
-	  const hb_feature_t &feature = features[i];
-	  if (feature.tag == HB_TAG('k','e','r','n') &&
-	      feature.start < chars_len && feature.start < feature.end)
-	  {
-	    CFRange feature_range = CFRangeMake (feature.start,
-						 hb_min (feature.end, chars_len) - feature.start);
-	    if (feature.value)
-	      CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName);
-	    else
-	      CFAttributedStringSetAttribute (attr_string, feature_range, kCTKernAttributeName, zero);
-	  }
-	}
-	CFRelease (zero);
-      }
-
-      int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
-      CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level);
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-      extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel;
-#endif
-      CFDictionaryRef options = CFDictionaryCreate (kCFAllocatorDefault,
-						    (const void **) &kCTTypesetterOptionForcedEmbeddingLevel,
-						    (const void **) &level_number,
-						    1,
-						    &kCFTypeDictionaryKeyCallBacks,
-						    &kCFTypeDictionaryValueCallBacks);
-      CFRelease (level_number);
-      if (unlikely (!options))
-      {
-	CFRelease (attr_string);
-	FAIL ("CFDictionaryCreate failed");
-      }
-
-      CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options);
-      CFRelease (options);
-      CFRelease (attr_string);
-      if (unlikely (!typesetter))
-	FAIL ("CTTypesetterCreateWithAttributedStringAndOptions failed");
-
-      line = CTTypesetterCreateLine (typesetter, CFRangeMake(0, 0));
-      CFRelease (typesetter);
-      if (unlikely (!line))
-	FAIL ("CTTypesetterCreateLine failed");
-    }
-
-    CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
-    unsigned int num_runs = CFArrayGetCount (glyph_runs);
-    DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs);
-
-    buffer->len = 0;
-    uint32_t status_or = 0;
-    CGFloat advances_so_far = 0;
-    /* For right-to-left runs, CoreText returns the glyphs positioned such that
-     * any trailing whitespace is to the left of (0,0).  Adjust coordinate system
-     * to fix for that.  Test with any RTL string with trailing spaces.
-     * https://crbug.com/469028
-     */
-    if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
-    {
-      advances_so_far -= CTLineGetTrailingWhitespaceWidth (line);
-      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
-	  advances_so_far = -advances_so_far;
-    }
-
-    const CFRange range_all = CFRangeMake (0, 0);
-
-    for (unsigned int i = 0; i < num_runs; i++)
-    {
-      CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i));
-      CTRunStatus run_status = CTRunGetStatus (run);
-      status_or  |= run_status;
-      DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
-      CGFloat run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr);
-      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
-	  run_advance = -run_advance;
-      DEBUG_MSG (CORETEXT, run, "Run advance: %g", (double) run_advance);
-
-      /* CoreText does automatic font fallback (AKA "cascading") for  characters
-       * not supported by the requested font, and provides no way to turn it off,
-       * so we must detect if the returned run uses a font other than the requested
-       * one and fill in the buffer with .notdef glyphs instead of random glyph
-       * indices from a different font.
-       */
-      CFDictionaryRef attributes = CTRunGetAttributes (run);
-      CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
-      if (!CFEqual (run_ct_font, ct_font))
-      {
-	/* The run doesn't use our main font instance.  We have to figure out
-	 * whether font fallback happened, or this is just CoreText giving us
-	 * another CTFont using the same underlying CGFont.  CoreText seems
-	 * to do that in a variety of situations, one of which being vertical
-	 * text, but also perhaps for caching reasons.
-	 *
-	 * First, see if it uses any of our subfonts created to set font features...
-	 *
-	 * Next, compare the CGFont to the one we used to create our fonts.
-	 * Even this doesn't work all the time.
-	 *
-	 * Finally, we compare PS names, which I don't think are unique...
-	 *
-	 * Looks like if we really want to be sure here we have to modify the
-	 * font to change the name table, similar to what we do in the uniscribe
-	 * backend.
-	 *
-	 * However, even that wouldn't work if we were passed in the CGFont to
-	 * construct a hb_face to begin with.
-	 *
-	 * See: https://github.com/harfbuzz/harfbuzz/pull/36
-	 *
-	 * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098
-	 */
-	bool matched = false;
-	for (unsigned int i = 0; i < range_records.length; i++)
-	  if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font))
-	  {
-	    matched = true;
-	    break;
-	  }
-	if (!matched)
-	{
-	  CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, nullptr);
-	  if (run_cg_font)
-	  {
-	    matched = CFEqual (run_cg_font, cg_font);
-	    CFRelease (run_cg_font);
-	  }
-	}
-	if (!matched)
-	{
-	  CFStringRef font_ps_name = CTFontCopyName (ct_font, kCTFontPostScriptNameKey);
-	  CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey);
-	  CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0);
-	  CFRelease (run_ps_name);
-	  CFRelease (font_ps_name);
-	  if (result == kCFCompareEqualTo)
-	    matched = true;
-	}
-	if (!matched)
-	{
-	  CFRange range = CTRunGetStringRange (run);
-	  DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
-		     range.location, range.location + range.length);
-	  if (!buffer->ensure_inplace (buffer->len + range.length))
-	    goto resize_and_retry;
-	  hb_glyph_info_t *info = buffer->info + buffer->len;
-
-	  hb_codepoint_t notdef = 0;
-	  hb_direction_t dir = buffer->props.direction;
-	  hb_position_t x_advance, y_advance, x_offset, y_offset;
-	  hb_font_get_glyph_advance_for_direction (font, notdef, dir, &x_advance, &y_advance);
-	  hb_font_get_glyph_origin_for_direction (font, notdef, dir, &x_offset, &y_offset);
-	  hb_position_t advance = x_advance + y_advance;
-	  x_offset = -x_offset;
-	  y_offset = -y_offset;
-
-	  unsigned int old_len = buffer->len;
-	  for (CFIndex j = range.location; j < range.location + range.length; j++)
-	  {
-	      UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
-	      if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j)
-	      {
-		ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
-		if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu))
-		  /* This is the second of a surrogate pair.  Don't need .notdef
-		   * for this one. */
-		  continue;
-	      }
-	      if (buffer->unicode->is_default_ignorable (ch))
-		continue;
-
-	      info->codepoint = notdef;
-	      info->cluster = log_clusters[j];
-
-	      info->mask = advance;
-	      info->var1.i32 = x_offset;
-	      info->var2.i32 = y_offset;
-
-	      info++;
-	      buffer->len++;
-	  }
-	  if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
-	    buffer->reverse_range (old_len, buffer->len);
-	  advances_so_far += run_advance;
-	  continue;
-	}
-      }
-
-      unsigned int num_glyphs = CTRunGetGlyphCount (run);
-      if (num_glyphs == 0)
-	continue;
-
-      if (!buffer->ensure_inplace (buffer->len + num_glyphs))
-	goto resize_and_retry;
-
-      hb_glyph_info_t *run_info = buffer->info + buffer->len;
-
-      /* Testing used to indicate that CTRunGetGlyphsPtr, etc (almost?) always
-       * succeed, and so copying data to our own buffer will be rare.  Reports
-       * have it that this changed in OS X 10.10 Yosemite, and nullptr is returned
-       * frequently.  At any rate, we can test that codepath by setting USE_PTR
-       * to false. */
-
-#define USE_PTR true
-
-#define SCRATCH_SAVE() \
-  unsigned int scratch_size_saved = scratch_size; \
-  hb_buffer_t::scratch_buffer_t *scratch_saved = scratch
-
-#define SCRATCH_RESTORE() \
-  scratch_size = scratch_size_saved; \
-  scratch = scratch_saved
-
-      { /* Setup glyphs */
-	SCRATCH_SAVE();
-	const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : nullptr;
-	if (!glyphs) {
-	  ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry);
-	  CTRunGetGlyphs (run, range_all, glyph_buf);
-	  glyphs = glyph_buf;
-	}
-	const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : nullptr;
-	if (!string_indices) {
-	  ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs, goto resize_and_retry);
-	  CTRunGetStringIndices (run, range_all, index_buf);
-	  string_indices = index_buf;
-	}
-	hb_glyph_info_t *info = run_info;
-	for (unsigned int j = 0; j < num_glyphs; j++)
-	{
-	  info->codepoint = glyphs[j];
-	  info->cluster = log_clusters[string_indices[j]];
-	  info++;
-	}
-	SCRATCH_RESTORE();
-      }
-      {
-	/* Setup positions.
-	 * Note that CoreText does not return advances for glyphs.  As such,
-	 * for all but last glyph, we use the delta position to next glyph as
-	 * advance (in the advance direction only), and for last glyph we set
-	 * whatever is needed to make the whole run's advance add up. */
-	SCRATCH_SAVE();
-	const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : nullptr;
-	if (!positions) {
-	  ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry);
-	  CTRunGetPositions (run, range_all, position_buf);
-	  positions = position_buf;
-	}
-	hb_glyph_info_t *info = run_info;
-	if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
-	{
-	  hb_position_t x_offset = round ((positions[0].x - advances_so_far) * x_mult);
-	  for (unsigned int j = 0; j < num_glyphs; j++)
-	  {
-	    CGFloat advance;
-	    if (likely (j + 1 < num_glyphs))
-	      advance = positions[j + 1].x - positions[j].x;
-	    else /* last glyph */
-	      advance = run_advance - (positions[j].x - positions[0].x);
-	    /* int cast necessary to pass through negative values. */
-	    info->mask = (int) round (advance * x_mult);
-	    info->var1.i32 = x_offset;
-	    info->var2.i32 = round (positions[j].y * y_mult);
-	    info++;
-	  }
-	}
-	else
-	{
-	  hb_position_t y_offset = round ((positions[0].y - advances_so_far) * y_mult);
-	  for (unsigned int j = 0; j < num_glyphs; j++)
-	  {
-	    CGFloat advance;
-	    if (likely (j + 1 < num_glyphs))
-	      advance = positions[j + 1].y - positions[j].y;
-	    else /* last glyph */
-	      advance = run_advance - (positions[j].y - positions[0].y);
-	    /* int cast necessary to pass through negative values. */
-	    info->mask = (int) round (advance * y_mult);
-	    info->var1.i32 = round (positions[j].x * x_mult);
-	    info->var2.i32 = y_offset;
-	    info++;
-	  }
-	}
-	SCRATCH_RESTORE();
-	advances_so_far += run_advance;
-      }
-#undef SCRATCH_RESTORE
-#undef SCRATCH_SAVE
-#undef USE_PTR
-#undef ALLOCATE_ARRAY
-
-      buffer->len += num_glyphs;
-    }
-
-    buffer->clear_positions ();
-
-    unsigned int count = buffer->len;
-    hb_glyph_info_t *info = buffer->info;
-    hb_glyph_position_t *pos = buffer->pos;
-    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
-      for (unsigned int i = 0; i < count; i++)
-      {
-	pos->x_advance = info->mask;
-	pos->x_offset = info->var1.i32;
-	pos->y_offset = info->var2.i32;
-
-	info++; pos++;
-      }
-    else
-      for (unsigned int i = 0; i < count; i++)
-      {
-	pos->y_advance = info->mask;
-	pos->x_offset = info->var1.i32;
-	pos->y_offset = info->var2.i32;
-
-	info++; pos++;
-      }
-
-    /* Fix up clusters so that we never return out-of-order indices;
-     * if core text has reordered glyphs, we'll merge them to the
-     * beginning of the reordered cluster.  CoreText is nice enough
-     * to tell us whenever it has produced nonmonotonic results...
-     * Note that we assume the input clusters were nonmonotonic to
-     * begin with.
-     *
-     * This does *not* mean we'll form the same clusters as Uniscribe
-     * or the native OT backend, only that the cluster indices will be
-     * monotonic in the output buffer. */
-    if (count > 1 && (status_or & kCTRunStatusNonMonotonic) &&
-	buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
-    {
-      hb_glyph_info_t *info = buffer->info;
-      if (HB_DIRECTION_IS_FORWARD (buffer->props.direction))
-      {
-	unsigned int cluster = info[count - 1].cluster;
-	for (unsigned int i = count - 1; i > 0; i--)
-	{
-	  cluster = hb_min (cluster, info[i - 1].cluster);
-	  info[i - 1].cluster = cluster;
-	}
-      }
-      else
-      {
-	unsigned int cluster = info[0].cluster;
-	for (unsigned int i = 1; i < count; i++)
-	{
-	  cluster = hb_min (cluster, info[i].cluster);
-	  info[i].cluster = cluster;
-	}
-      }
-    }
-  }
-
-  /* TODO: Sometimes the above positioning code generates negative
-   * advance values. Fix them up. Example, with NotoNastaliqUrdu
-   * font and sequence ابهد. */
-
-  buffer->clear_glyph_flags ();
-  buffer->unsafe_to_break ();
-
-#undef FAIL
-
-fail:
-  if (string_ref)
-    CFRelease (string_ref);
-  if (line)
-    CFRelease (line);
-
-  for (unsigned int i = 0; i < range_records.length; i++)
-    if (range_records[i].font)
-      CFRelease (range_records[i].font);
-
-  return ret;
-}
-
-
-#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h	2024-11-06 04:18:33 UTC (rev 72778)
@@ -44,9 +44,9 @@
  * HB_CORETEXT_TAG_MORT:
  *
  * The #hb_tag_t tag for the `mort` (glyph metamorphosis) table,
- * which holds AAT features. 
+ * which holds AAT features.
  *
- * For more information, see 
+ * For more information, see
  * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html
  *
  **/
@@ -56,7 +56,7 @@
  * HB_CORETEXT_TAG_MORX:
  *
  * The #hb_tag_t tag for the `morx` (extended glyph metamorphosis)
- * table, which holds AAT features. 
+ * table, which holds AAT features.
  *
  * For more information, see
  * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html
@@ -68,9 +68,9 @@
  * HB_CORETEXT_TAG_KERX:
  *
  * The #hb_tag_t tag for the `kerx` (extended kerning) table, which
- * holds AAT kerning information. 
+ * holds AAT kerning information.
  *
- * For more information, see 
+ * For more information, see
  * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html
  *
  **/
@@ -80,6 +80,10 @@
 HB_EXTERN hb_face_t *
 hb_coretext_face_create (CGFontRef cg_font);
 
+HB_EXTERN hb_face_t *
+hb_coretext_face_create_from_file_or_fail (const char   *file_name,
+					   unsigned int  index);
+
 HB_EXTERN hb_font_t *
 hb_coretext_font_create (CTFontRef ct_font);
 
@@ -90,7 +94,10 @@
 HB_EXTERN CTFontRef
 hb_coretext_font_get_ct_font (hb_font_t *font);
 
+HB_EXTERN void
+hb_coretext_font_set_funcs (hb_font_t *font);
 
+
 HB_END_DECLS
 
 #endif /* HB_CORETEXT_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2024-11-06 04:18:33 UTC (rev 72778)
@@ -70,7 +70,7 @@
  *
  * The default #hb_draw_state_t at the start of glyph drawing.
  */
-#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}}
+#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}}
 
 
 /**

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -264,6 +264,61 @@
 }
 
 /**
+ * hb_face_create_or_fail:
+ * @blob: #hb_blob_t to work upon
+ * @index: The index of the face within @blob
+ *
+ * Like hb_face_create(), but returns `NULL` if the blob data
+ * contains no usable font face at the specified index.
+ *
+ * Return value: (transfer full): The new face object, or `NULL` if
+ * no face is found at the specified index.
+ *
+ * Since: 10.1.0
+ **/
+hb_face_t *
+hb_face_create_or_fail (hb_blob_t    *blob,
+			unsigned int  index)
+{
+  unsigned num_faces = hb_face_count (blob);
+  if (index >= num_faces)
+    return nullptr;
+
+  hb_face_t *face = hb_face_create (blob, index);
+  if (hb_object_is_immutable (face))
+    return nullptr;
+
+  return face;
+}
+
+/**
+ * hb_face_create_from_file_or_fail:
+ * @file_name: A font filename
+ * @index: The index of the face within the file
+ *
+ * A thin wrapper around hb_blob_create_from_file_or_fail()
+ * followed by hb_face_create_or_fail().
+ *
+ * Return value: (transfer full): The new face object, or `NULL` if
+ * no face is found at the specified index or the file cannot be read.
+ *
+ * Since: 10.1.0
+ **/
+HB_EXTERN hb_face_t *
+hb_face_create_from_file_or_fail (const char   *file_name,
+				  unsigned int  index)
+{
+  hb_blob_t *blob = hb_blob_create_from_file_or_fail (file_name);
+  if (unlikely (!blob))
+    return nullptr;
+
+  hb_face_t *face = hb_face_create_or_fail (blob, index);
+  hb_blob_destroy (blob);
+
+  return face;
+}
+
+/**
  * hb_face_get_empty:
  *
  * Fetches the singleton empty face object.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h	2024-11-06 04:18:33 UTC (rev 72778)
@@ -59,6 +59,14 @@
 hb_face_create (hb_blob_t    *blob,
 		unsigned int  index);
 
+HB_EXTERN hb_face_t *
+hb_face_create_or_fail (hb_blob_t    *blob,
+			unsigned int  index);
+
+HB_EXTERN hb_face_t *
+hb_face_create_from_file_or_fail (const char   *file_name,
+				  unsigned int  index);
+
 /**
  * hb_reference_table_func_t:
  * @face: an #hb_face_t to reference table for

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -231,7 +231,7 @@
 				 void           *user_data HB_UNUSED)
 {
   /* TODO use font_extents.ascender+descender */
-  return font->y_scale;
+  return -font->y_scale;
 }
 
 static hb_position_t

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -41,6 +41,7 @@
 #include "hb-ot-shaper-arabic-pua.hh"
 #include "hb-paint.hh"
 
+#include FT_MODULE_H
 #include FT_ADVANCES_H
 #include FT_MULTIPLE_MASTERS_H
 #include FT_OUTLINE_H
@@ -1432,6 +1433,24 @@
   return hb_ft_font_create (ft_face, _hb_ft_face_destroy);
 }
 
+
+static void * _hb_ft_alloc (FT_Memory memory, long size)
+{ return hb_malloc (size); }
+
+static void _hb_ft_free (FT_Memory memory, void *block)
+{ hb_free (block); }
+
+static void * _hb_ft_realloc (FT_Memory memory, long cur_size, long new_size, void *block)
+{ return hb_realloc (block, new_size); }
+
+static FT_MemoryRec_ m =
+{
+  nullptr,
+  _hb_ft_alloc,
+  _hb_ft_free,
+  _hb_ft_realloc
+};
+
 static inline void free_static_ft_library ();
 
 static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<FT_Library>,
@@ -1440,9 +1459,12 @@
   static FT_Library create ()
   {
     FT_Library l;
-    if (FT_Init_FreeType (&l))
+    if (FT_New_Library (&m, &l))
       return nullptr;
 
+    FT_Add_Default_Modules (l);
+    FT_Set_Default_Properties (l);
+
     hb_atexit (free_static_ft_library);
 
     return l;
@@ -1449,7 +1471,7 @@
   }
   static void destroy (FT_Library l)
   {
-    FT_Done_FreeType (l);
+    FT_Done_Library (l);
   }
   static FT_Library get_null ()
   {
@@ -1464,12 +1486,79 @@
 }
 
 static FT_Library
-get_ft_library ()
+reference_ft_library ()
 {
-  return static_ft_library.get_unconst ();
+  FT_Library l = static_ft_library.get_unconst ();
+  if (unlikely (FT_Reference_Library (l)))
+  {
+    DEBUG_MSG (FT, l, "FT_Reference_Library() failed");
+    return nullptr;
+  }
+  return l;
 }
 
+static hb_user_data_key_t ft_library_key = {0};
+
 static void
+finalize_ft_library (void *arg)
+{
+  FT_Face ft_face = (FT_Face) arg;
+  FT_Done_Library ((FT_Library) ft_face->generic.data);
+}
+
+static void
+destroy_ft_library (void *arg)
+{
+  FT_Done_Library ((FT_Library) arg);
+}
+
+/**
+ * hb_ft_face_create_from_file_or_fail:
+ * @file_name: A font filename
+ * @index: The index of the face within the file
+ *
+ * Creates an #hb_face_t face object from the specified
+ * font file and face index.
+ *
+ * This is similar in functionality to hb_face_create_from_file_or_fail(),
+ * but uses the FreeType library for loading the font file.
+ *
+ * Return value: (transfer full): The new face object, or `NULL` if
+ * no face is found at the specified index or the file cannot be read.
+ *
+ * Since: 10.1.0
+ */
+hb_face_t *
+hb_ft_face_create_from_file_or_fail (const char   *file_name,
+				     unsigned int  index)
+{
+  FT_Library ft_library = reference_ft_library ();
+  if (unlikely (!ft_library))
+  {
+    DEBUG_MSG (FT, ft_library, "reference_ft_library failed");
+    return nullptr;
+  }
+
+  FT_Face ft_face;
+  if (unlikely (FT_New_Face (ft_library,
+			     file_name,
+			     index,
+			     &ft_face)))
+    return nullptr;
+
+  hb_face_t *face = hb_ft_face_create_referenced (ft_face);
+  FT_Done_Face (ft_face);
+
+  ft_face->generic.data = ft_library;
+  ft_face->generic.finalizer = finalize_ft_library;
+
+  if (hb_face_is_immutable (face))
+    return nullptr;
+
+  return face;
+}
+
+static void
 _release_blob (void *arg)
 {
   FT_Face ft_face = (FT_Face) arg;
@@ -1511,16 +1600,23 @@
   if (unlikely (!blob_length))
     DEBUG_MSG (FT, font, "Font face has empty blob");
 
+  FT_Library ft_library = reference_ft_library ();
+  if (unlikely (!ft_library))
+  {
+    hb_blob_destroy (blob);
+    DEBUG_MSG (FT, font, "reference_ft_library failed");
+    return;
+  }
+
   FT_Face ft_face = nullptr;
-  FT_Error err = FT_New_Memory_Face (get_ft_library (),
-				     (const FT_Byte *) blob_data,
-				     blob_length,
-				     hb_face_get_index (font->face),
-				     &ft_face);
-
-  if (unlikely (err)) {
+  if (unlikely (FT_New_Memory_Face (ft_library,
+				    (const FT_Byte *) blob_data,
+				    blob_length,
+				    hb_face_get_index (font->face),
+				    &ft_face)))
+  {
     hb_blob_destroy (blob);
-    DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed");
+    DEBUG_MSG (FT, font, "FT_New_Memory_Face() failed");
     return;
   }
 
@@ -1527,10 +1623,13 @@
   if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL))
     FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
 
-
+  // Hook the blob to the FT_Face
   ft_face->generic.data = blob;
   ft_face->generic.finalizer = _release_blob;
 
+  // And the FT_Library to the blob
+  hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true);
+
   _hb_ft_font_set_funcs (font, ft_face, true);
   hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h	2024-11-06 04:18:33 UTC (rev 72778)
@@ -84,6 +84,9 @@
 HB_EXTERN hb_face_t *
 hb_ft_face_create_referenced (FT_Face ft_face);
 
+HB_EXTERN hb_face_t *
+hb_ft_face_create_from_file_or_fail (const char   *file_name,
+				     unsigned int  index);
 
 /*
  * hb-font from ft-face.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -31,6 +31,11 @@
 
 #ifdef HAVE_ICU
 
+#pragma GCC diagnostic push
+
+// https://github.com/harfbuzz/harfbuzz/issues/4915
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+
 #include "hb-icu.h"
 
 #include "hb-machinery.hh"
@@ -44,7 +49,6 @@
 /* ICU extra semicolon, fixed since 65, https://github.com/unicode-org/icu/commit/480bec3 */
 #if U_ICU_VERSION_MAJOR_NUM < 65 && (defined(__GNUC__) || defined(__clang__))
 #define HB_ICU_EXTRA_SEMI_IGNORED
-#pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wextra-semi-stmt"
 #endif
 
@@ -284,8 +288,6 @@
   return static_icu_funcs.get_unconst ();
 }
 
-#ifdef HB_ICU_EXTRA_SEMI_IGNORED
 #pragma GCC diagnostic pop
-#endif
 
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -101,7 +101,7 @@
 #endif
 
 #ifndef HB_CFF_MAX_OPS
-#define HB_CFF_MAX_OPS 10000
+#define HB_CFF_MAX_OPS 200000
 #endif
 
 #ifndef HB_MAX_COMPOSITE_OPERATIONS_PER_GLYPH

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -307,7 +307,7 @@
   const V& get_with_hash (const K &key, uint32_t hash) const
   {
     if (!items) return item_t::default_value ();
-    auto *item = fetch_item (key, hb_hash (key));
+    auto *item = fetch_item (key, hash);
     if (item)
       return item->value;
     return item_t::default_value ();

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -30,7 +30,7 @@
 
 #include "hb.hh"
 
-/* Variations of this code exist in hb-coretext.cc as well
+/* Variations of this code exist in hb-coretext-shape.cc as well
  * as hb-aat-map.cc... */
 
 typedef struct hb_ms_feature_t {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -642,7 +642,9 @@
  * hb_ot_font_set_funcs:
  * @font: #hb_font_t to work upon
  *
- * Sets the font functions to use when working with @font. 
+ * Sets the font functions to use when working with @font to
+ * the HarfBuzz's native implementation. This is the default
+ * for fonts newly created.
  *
  * Since: 0.9.28
  **/

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -3714,11 +3714,11 @@
 
 struct ItemVarStoreInstancer
 {
-  ItemVarStoreInstancer (const ItemVariationStore *varStore,
+  ItemVarStoreInstancer (const ItemVariationStore *varStore_,
 			 const DeltaSetIndexMap *varIdxMap,
 			 hb_array_t<const int> coords,
 			 VarRegionList::cache_t *cache = nullptr) :
-    varStore (varStore), varIdxMap (varIdxMap), coords (coords), cache (cache)
+    varStore (varStore_), varIdxMap (varIdxMap), coords (coords), cache (cache)
   {
     if (!varStore)
       varStore = &Null(ItemVariationStore);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -173,7 +173,7 @@
 
 /* Design:
  * unicode_props() is a two-byte number.  The low byte includes:
- * - Extended General_Category: 5 bits.
+ * - Modified General_Category: 5 bits.
  * - A bit each for:
  *   * Is it Default_Ignorable(); we have a modified Default_Ignorable().
  *   * Whether it's one of the four Mongolian Free Variation Selectors,
@@ -186,17 +186,23 @@
  * - For Cf: whether it's ZWJ, ZWNJ, or something else.
  * - For Ws: index of which space character this is, if space fallback
  *   is needed, ie. we don't set this by default, only if asked to.
+ *
+ * Above I said "modified" General_Category. This is because we need to
+ * remember Variation Selectors, and we don't have bits left. So we
+ * change their Gen_Cat from Mn to Cf, and use a bit of the high byte to
+ * remember them.
  */
 
 enum hb_unicode_props_flags_t {
   UPROPS_MASK_GEN_CAT	= 0x001Fu,
   UPROPS_MASK_IGNORABLE	= 0x0020u,
-  UPROPS_MASK_HIDDEN	= 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters */
+  UPROPS_MASK_HIDDEN	= 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters, or CGJ sometimes */
   UPROPS_MASK_CONTINUATION=0x0080u,
 
   /* If GEN_CAT=FORMAT, top byte masks: */
   UPROPS_MASK_Cf_ZWJ	= 0x0100u,
-  UPROPS_MASK_Cf_ZWNJ	= 0x0200u
+  UPROPS_MASK_Cf_ZWNJ	= 0x0200u,
+  UPROPS_MASK_Cf_VS	= 0x0400u
 };
 HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t);
 
@@ -229,7 +235,7 @@
       /* TAG characters need similar treatment. Fixes:
        * https://github.com/harfbuzz/harfbuzz/issues/463 */
       else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN;
-      /* COMBINING GRAPHEME JOINER should not be skipped; at least some times.
+      /* COMBINING GRAPHEME JOINER should not be skipped during GSUB either.
        * https://github.com/harfbuzz/harfbuzz/issues/554 */
       else if (unlikely (u == 0x034Fu))
       {
@@ -302,6 +308,27 @@
 	 (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) :
 	 hb_unicode_funcs_t::NOT_SPACE;
 }
+static inline bool
+_hb_glyph_info_is_variation_selector (const hb_glyph_info_t *info)
+{
+  return _hb_glyph_info_get_general_category (info) ==
+	 HB_UNICODE_GENERAL_CATEGORY_FORMAT &&
+	 (info->unicode_props() & UPROPS_MASK_Cf_VS);
+}
+static inline void
+_hb_glyph_info_set_variation_selector (hb_glyph_info_t *info, bool customize)
+{
+  if (customize)
+  {
+    _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_FORMAT);
+    info->unicode_props() |= UPROPS_MASK_Cf_VS;
+  }
+  else
+  {
+    // Reset to their original condition
+    _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK);
+  }
+}
 
 static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -222,8 +222,7 @@
 	(void) buffer->next_glyph ();
 
         buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK;
-	_hb_glyph_info_set_general_category (&buffer->cur(),
-					     _HB_UNICODE_GENERAL_CATEGORY_VARIATION_SELECTOR);
+	_hb_glyph_info_set_variation_selector (&buffer->cur(), true);
 	if (buffer->not_found_variation_selector != HB_CODEPOINT_INVALID)
 	  _hb_glyph_info_clear_default_ignorable (&buffer->cur());
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -850,12 +850,11 @@
 
   for (unsigned int i = 0; i < count; i++)
   {
-    if (_hb_glyph_info_get_general_category (&info[i]) ==
-	_HB_UNICODE_GENERAL_CATEGORY_VARIATION_SELECTOR)
+    if (_hb_glyph_info_is_variation_selector (&info[i]))
     {
       info[i].codepoint = buffer->not_found_variation_selector;
       pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0;
-      _hb_glyph_info_set_general_category (&info[i], HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK);
+      _hb_glyph_info_set_variation_selector (&info[i], false);
     }
   }
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -81,6 +81,7 @@
 #define use_syllable_machine_ex_N 4u
 #define use_syllable_machine_ex_O 0u
 #define use_syllable_machine_ex_R 18u
+#define use_syllable_machine_ex_RK 56u
 #define use_syllable_machine_ex_SB 51u
 #define use_syllable_machine_ex_SE 52u
 #define use_syllable_machine_ex_SMAbv 41u
@@ -99,62 +100,62 @@
 #define use_syllable_machine_ex_ZWNJ 14u
 
 
-#line 103 "hb-ot-shaper-use-machine.hh"
+#line 104 "hb-ot-shaper-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-	49u, 51u, 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 
+	49u, 51u, 0u, 56u, 11u, 56u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 
 	14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 
 	14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 
-	12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 53u, 
+	12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 56u, 
 	1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 
 	14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 
-	14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 
-	1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 
-	14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 
-	14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 
-	14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u, 1u, 48u, 
-	11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 
-	14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 
-	14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 
-	1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 14u, 42u, 14u, 42u, 1u, 5u, 
-	14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 53u, 0
+	14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, 
+	1u, 14u, 1u, 48u, 14u, 14u, 13u, 14u, 4u, 14u, 11u, 56u, 11u, 56u, 1u, 53u, 
+	14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 
+	14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 
+	12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 56u, 1u, 14u, 1u, 14u, 
+	1u, 48u, 14u, 14u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 
+	14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 
+	14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 
+	12u, 53u, 11u, 56u, 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 56u, 14u, 42u, 
+	14u, 42u, 1u, 5u, 14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 56u, 0
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-	3, 54, 43, 43, 53, 35, 34, 34, 
+	3, 57, 46, 46, 53, 35, 34, 34, 
 	34, 33, 33, 1, 35, 35, 35, 14, 
 	35, 40, 40, 40, 40, 42, 40, 42, 
-	42, 42, 43, 14, 48, 29, 29, 43, 
+	42, 42, 46, 14, 48, 29, 29, 46, 
 	53, 35, 34, 34, 34, 33, 33, 1, 
 	35, 35, 35, 14, 35, 40, 40, 40, 
-	40, 42, 40, 42, 42, 42, 43, 14, 
-	14, 48, 2, 11, 43, 43, 53, 35, 
-	34, 34, 34, 33, 33, 1, 35, 35, 
-	35, 14, 35, 40, 40, 40, 40, 42, 
-	40, 42, 42, 42, 43, 14, 14, 48, 
-	43, 53, 35, 34, 34, 34, 33, 33, 
-	1, 35, 35, 35, 14, 35, 40, 40, 
-	40, 40, 42, 40, 42, 42, 42, 43, 
-	14, 48, 11, 2, 53, 29, 29, 5, 
-	42, 38, 39, 41, 43
+	40, 42, 40, 42, 42, 42, 46, 14, 
+	14, 48, 1, 2, 11, 46, 46, 53, 
+	35, 34, 34, 34, 33, 33, 1, 35, 
+	35, 35, 14, 35, 40, 40, 40, 40, 
+	42, 40, 42, 42, 42, 46, 14, 14, 
+	48, 1, 46, 53, 35, 34, 34, 34, 
+	33, 33, 1, 35, 35, 35, 14, 35, 
+	40, 40, 40, 40, 42, 40, 42, 42, 
+	42, 46, 14, 48, 11, 2, 56, 29, 
+	29, 5, 42, 38, 39, 41, 46
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-	0, 4, 59, 103, 147, 201, 237, 272, 
-	307, 342, 376, 410, 412, 448, 484, 520, 
-	535, 571, 612, 653, 694, 735, 778, 819, 
-	862, 905, 948, 992, 1007, 1056, 1086, 1116, 
-	1160, 1214, 1250, 1285, 1320, 1355, 1389, 1423, 
-	1425, 1461, 1497, 1533, 1548, 1584, 1625, 1666, 
-	1707, 1748, 1791, 1832, 1875, 1918, 1961, 2005, 
-	2020, 2035, 2084, 2087, 2099, 2143, 2187, 2241, 
-	2277, 2312, 2347, 2382, 2416, 2450, 2452, 2488, 
-	2524, 2560, 2575, 2611, 2652, 2693, 2734, 2775, 
-	2818, 2859, 2902, 2945, 2988, 3032, 3047, 3062, 
-	3111, 3155, 3209, 3245, 3280, 3315, 3350, 3384, 
-	3418, 3420, 3456, 3492, 3528, 3543, 3579, 3620, 
-	3661, 3702, 3743, 3786, 3827, 3870, 3913, 3956, 
-	4000, 4015, 4064, 4076, 4079, 4133, 4163, 4193, 
-	4199, 4242, 4281, 4321, 4363
+	0, 4, 62, 109, 156, 210, 246, 281, 
+	316, 351, 385, 419, 421, 457, 493, 529, 
+	544, 580, 621, 662, 703, 744, 787, 828, 
+	871, 914, 957, 1004, 1019, 1068, 1098, 1128, 
+	1175, 1229, 1265, 1300, 1335, 1370, 1404, 1438, 
+	1440, 1476, 1512, 1548, 1563, 1599, 1640, 1681, 
+	1722, 1763, 1806, 1847, 1890, 1933, 1976, 2023, 
+	2038, 2053, 2102, 2104, 2107, 2119, 2166, 2213, 
+	2267, 2303, 2338, 2373, 2408, 2442, 2476, 2478, 
+	2514, 2550, 2586, 2601, 2637, 2678, 2719, 2760, 
+	2801, 2844, 2885, 2928, 2971, 3014, 3061, 3076, 
+	3091, 3140, 3142, 3189, 3243, 3279, 3314, 3349, 
+	3384, 3418, 3452, 3454, 3490, 3526, 3562, 3577, 
+	3613, 3654, 3695, 3736, 3777, 3820, 3861, 3904, 
+	3947, 3990, 4037, 4052, 4101, 4113, 4116, 4173, 
+	4203, 4233, 4239, 4282, 4321, 4361, 4403
 };
 
 static const unsigned char _use_syllable_machine_indicies[] = {
@@ -165,77 +166,73 @@
 	19, 20, 21, 8, 22, 23, 24, 25, 
 	5, 26, 27, 28, 5, 29, 30, 31, 
 	32, 33, 34, 35, 32, 1, 5, 36, 
-	5, 37, 5, 39, 40, 38, 41, 38, 
-	38, 38, 38, 38, 38, 38, 42, 43, 
-	44, 45, 46, 47, 48, 49, 50, 39, 
-	51, 52, 53, 54, 38, 55, 56, 57, 
-	38, 58, 59, 38, 60, 61, 62, 63, 
-	60, 38, 38, 38, 38, 64, 38, 39, 
-	40, 38, 41, 38, 38, 38, 38, 38, 
-	38, 38, 42, 43, 44, 45, 46, 47, 
-	48, 49, 50, 39, 51, 52, 53, 54, 
-	38, 55, 56, 57, 38, 38, 38, 38, 
-	60, 61, 62, 63, 60, 38, 38, 38, 
-	38, 64, 38, 39, 38, 38, 38, 38, 
+	5, 37, 5, 5, 35, 5, 39, 40, 
+	38, 41, 38, 38, 38, 38, 38, 38, 
+	38, 42, 43, 44, 45, 46, 47, 48, 
+	49, 50, 39, 51, 52, 53, 54, 38, 
+	55, 56, 57, 38, 58, 59, 38, 60, 
+	61, 62, 63, 60, 38, 38, 38, 38, 
+	64, 38, 38, 63, 38, 39, 40, 38, 
+	41, 38, 38, 38, 38, 38, 38, 38, 
+	42, 43, 44, 45, 46, 47, 48, 49, 
+	50, 39, 51, 52, 53, 54, 38, 55, 
+	56, 57, 38, 38, 38, 38, 60, 61, 
+	62, 63, 60, 38, 38, 38, 38, 64, 
+	38, 38, 63, 38, 39, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	41, 38, 38, 38, 38, 38, 38, 38, 
-	38, 43, 44, 45, 46, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 38, 55, 
-	56, 57, 38, 38, 38, 38, 38, 61, 
-	62, 63, 65, 38, 38, 38, 38, 43, 
 	38, 41, 38, 38, 38, 38, 38, 38, 
 	38, 38, 43, 44, 45, 46, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
 	55, 56, 57, 38, 38, 38, 38, 38, 
-	61, 62, 63, 65, 38, 41, 38, 38, 
-	38, 38, 38, 38, 38, 38, 38, 44, 
-	45, 46, 38, 38, 38, 38, 38, 38, 
+	61, 62, 63, 65, 38, 38, 38, 38, 
+	43, 38, 41, 38, 38, 38, 38, 38, 
+	38, 38, 38, 43, 44, 45, 46, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 61, 62, 63, 38, 
-	41, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 45, 46, 38, 38, 38, 
+	38, 55, 56, 57, 38, 38, 38, 38, 
+	38, 61, 62, 63, 65, 38, 41, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 38, 61, 
-	62, 63, 38, 41, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 38, 46, 
+	44, 45, 46, 38, 38, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 38, 61, 62, 63, 
+	38, 41, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 45, 46, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 61, 62, 63, 38, 41, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
+	61, 62, 63, 38, 41, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
+	46, 38, 38, 38, 38, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 61, 62, 38, 
-	41, 38, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 61, 62, 63, 38, 41, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	62, 38, 41, 38, 41, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 44, 45, 
-	46, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 55, 56, 57, 38, 38, 
-	38, 38, 38, 61, 62, 63, 65, 38, 
+	38, 38, 38, 38, 38, 38, 61, 62, 
+	38, 41, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 38, 
+	38, 62, 38, 41, 38, 41, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 44, 
+	45, 46, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 55, 56, 57, 38, 
+	38, 38, 38, 38, 61, 62, 63, 65, 
+	38, 41, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 44, 45, 46, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 38, 
+	38, 56, 57, 38, 38, 38, 38, 38, 
+	61, 62, 63, 65, 38, 41, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 44, 
+	45, 46, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 38, 38, 57, 38, 
+	38, 38, 38, 38, 61, 62, 63, 65, 
+	38, 66, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 38, 38, 41, 38, 
 	41, 38, 38, 38, 38, 38, 38, 38, 
 	38, 38, 44, 45, 46, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	56, 57, 38, 38, 38, 38, 38, 61, 
+	38, 38, 38, 38, 38, 38, 38, 61, 
 	62, 63, 65, 38, 41, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 44, 45, 
-	46, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 57, 38, 38, 
-	38, 38, 38, 61, 62, 63, 65, 38, 
-	66, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 41, 38, 41, 
-	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 44, 45, 46, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 61, 62, 
-	63, 65, 38, 41, 38, 38, 38, 38, 
-	38, 38, 38, 42, 43, 44, 45, 46, 
-	38, 38, 38, 38, 38, 38, 52, 53, 
-	54, 38, 55, 56, 57, 38, 38, 38, 
-	38, 38, 61, 62, 63, 65, 38, 38, 
-	38, 38, 43, 38, 41, 38, 38, 38, 
-	38, 38, 38, 38, 38, 43, 44, 45, 
+	38, 38, 38, 38, 42, 43, 44, 45, 
 	46, 38, 38, 38, 38, 38, 38, 52, 
 	53, 54, 38, 55, 56, 57, 38, 38, 
 	38, 38, 38, 61, 62, 63, 65, 38, 
@@ -242,481 +239,491 @@
 	38, 38, 38, 43, 38, 41, 38, 38, 
 	38, 38, 38, 38, 38, 38, 43, 44, 
 	45, 46, 38, 38, 38, 38, 38, 38, 
-	38, 53, 54, 38, 55, 56, 57, 38, 
+	52, 53, 54, 38, 55, 56, 57, 38, 
 	38, 38, 38, 38, 61, 62, 63, 65, 
 	38, 38, 38, 38, 43, 38, 41, 38, 
 	38, 38, 38, 38, 38, 38, 38, 43, 
 	44, 45, 46, 38, 38, 38, 38, 38, 
-	38, 38, 38, 54, 38, 55, 56, 57, 
+	38, 38, 53, 54, 38, 55, 56, 57, 
 	38, 38, 38, 38, 38, 61, 62, 63, 
+	65, 38, 38, 38, 38, 43, 38, 41, 
+	38, 38, 38, 38, 38, 38, 38, 38, 
+	43, 44, 45, 46, 38, 38, 38, 38, 
+	38, 38, 38, 38, 54, 38, 55, 56, 
+	57, 38, 38, 38, 38, 38, 61, 62, 
+	63, 65, 38, 38, 38, 38, 43, 38, 
+	67, 38, 41, 38, 38, 38, 38, 38, 
+	38, 38, 42, 43, 44, 45, 46, 38, 
+	48, 49, 38, 38, 38, 52, 53, 54, 
+	38, 55, 56, 57, 38, 38, 38, 38, 
+	38, 61, 62, 63, 65, 38, 38, 38, 
+	38, 43, 38, 41, 38, 38, 38, 38, 
+	38, 38, 38, 38, 43, 44, 45, 46, 
+	38, 38, 38, 38, 38, 38, 38, 38, 
+	38, 38, 55, 56, 57, 38, 38, 38, 
+	38, 38, 61, 62, 63, 65, 38, 38, 
+	38, 38, 43, 38, 67, 38, 41, 38, 
+	38, 38, 38, 38, 38, 38, 42, 43, 
+	44, 45, 46, 38, 38, 49, 38, 38, 
+	38, 52, 53, 54, 38, 55, 56, 57, 
+	38, 38, 38, 38, 38, 61, 62, 63, 
 	65, 38, 38, 38, 38, 43, 38, 67, 
 	38, 41, 38, 38, 38, 38, 38, 38, 
-	38, 42, 43, 44, 45, 46, 38, 48, 
-	49, 38, 38, 38, 52, 53, 54, 38, 
+	38, 42, 43, 44, 45, 46, 38, 38, 
+	38, 38, 38, 38, 52, 53, 54, 38, 
 	55, 56, 57, 38, 38, 38, 38, 38, 
 	61, 62, 63, 65, 38, 38, 38, 38, 
-	43, 38, 41, 38, 38, 38, 38, 38, 
-	38, 38, 38, 43, 44, 45, 46, 38, 
+	43, 38, 67, 38, 41, 38, 38, 38, 
+	38, 38, 38, 38, 42, 43, 44, 45, 
+	46, 47, 48, 49, 38, 38, 38, 52, 
+	53, 54, 38, 55, 56, 57, 38, 38, 
+	38, 38, 38, 61, 62, 63, 65, 38, 
+	38, 38, 38, 43, 38, 39, 40, 38, 
+	41, 38, 38, 38, 38, 38, 38, 38, 
+	42, 43, 44, 45, 46, 47, 48, 49, 
+	50, 38, 51, 52, 53, 54, 38, 55, 
+	56, 57, 38, 38, 38, 38, 60, 61, 
+	62, 63, 60, 38, 38, 38, 38, 64, 
+	38, 38, 63, 38, 39, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 55, 56, 57, 38, 38, 38, 38, 
-	38, 61, 62, 63, 65, 38, 38, 38, 
-	38, 43, 38, 67, 38, 41, 38, 38, 
-	38, 38, 38, 38, 38, 42, 43, 44, 
-	45, 46, 38, 38, 49, 38, 38, 38, 
-	52, 53, 54, 38, 55, 56, 57, 38, 
-	38, 38, 38, 38, 61, 62, 63, 65, 
-	38, 38, 38, 38, 43, 38, 67, 38, 
+	38, 41, 38, 39, 38, 38, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 38, 
 	41, 38, 38, 38, 38, 38, 38, 38, 
-	42, 43, 44, 45, 46, 38, 38, 38, 
-	38, 38, 38, 52, 53, 54, 38, 55, 
+	38, 43, 44, 45, 46, 38, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 55, 
 	56, 57, 38, 38, 38, 38, 38, 61, 
-	62, 63, 65, 38, 38, 38, 38, 43, 
-	38, 67, 38, 41, 38, 38, 38, 38, 
-	38, 38, 38, 42, 43, 44, 45, 46, 
-	47, 48, 49, 38, 38, 38, 52, 53, 
-	54, 38, 55, 56, 57, 38, 38, 38, 
-	38, 38, 61, 62, 63, 65, 38, 38, 
-	38, 38, 43, 38, 39, 40, 38, 41, 
-	38, 38, 38, 38, 38, 38, 38, 42, 
-	43, 44, 45, 46, 47, 48, 49, 50, 
-	38, 51, 52, 53, 54, 38, 55, 56, 
-	57, 38, 38, 38, 38, 60, 61, 62, 
-	63, 60, 38, 38, 38, 38, 64, 38, 
-	39, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 41, 38, 39, 
+	62, 63, 65, 38, 41, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 41, 38, 38, 38, 
-	38, 38, 38, 38, 38, 43, 44, 45, 
-	46, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 55, 56, 57, 38, 38, 
-	38, 38, 38, 61, 62, 63, 65, 38, 
-	41, 38, 38, 38, 38, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
+	38, 38, 38, 38, 38, 38, 38, 58, 
+	59, 38, 41, 38, 38, 38, 38, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 58, 59, 38, 41, 38, 
 	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 38, 38, 38, 38, 38, 38, 
-	38, 38, 59, 38, 4, 69, 68, 70, 
-	68, 68, 68, 68, 68, 68, 68, 71, 
-	72, 73, 74, 75, 76, 77, 78, 79, 
-	4, 80, 81, 82, 83, 68, 84, 85, 
-	86, 68, 68, 68, 68, 87, 88, 89, 
-	90, 91, 68, 68, 68, 68, 92, 68, 
-	4, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 70, 68, 68, 
+	38, 38, 38, 38, 38, 38, 59, 38, 
+	4, 69, 68, 70, 68, 68, 68, 68, 
+	68, 68, 68, 71, 72, 73, 74, 75, 
+	76, 77, 78, 79, 4, 80, 81, 82, 
+	83, 68, 84, 85, 86, 68, 68, 68, 
+	68, 87, 88, 89, 90, 91, 68, 68, 
+	68, 68, 92, 68, 68, 93, 68, 4, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 70, 68, 68, 68, 
+	68, 68, 68, 68, 68, 72, 73, 74, 
+	75, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 84, 85, 86, 68, 68, 
+	68, 68, 68, 88, 89, 90, 94, 68, 
+	68, 68, 68, 72, 68, 70, 68, 68, 
 	68, 68, 68, 68, 68, 68, 72, 73, 
 	74, 75, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 84, 85, 86, 68, 
-	68, 68, 68, 68, 88, 89, 90, 93, 
-	68, 68, 68, 68, 72, 68, 70, 68, 
-	68, 68, 68, 68, 68, 68, 68, 72, 
-	73, 74, 75, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 84, 85, 86, 
-	68, 68, 68, 68, 68, 88, 89, 90, 
-	93, 68, 70, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 73, 74, 75, 68, 
+	68, 68, 68, 68, 88, 89, 90, 94, 
+	68, 70, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 73, 74, 75, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 88, 89, 90, 68, 70, 68, 68, 
+	88, 89, 90, 68, 70, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 74, 
+	75, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	74, 75, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 88, 89, 90, 68, 70, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 88, 89, 90, 68, 
-	70, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 75, 68, 68, 68, 
+	68, 68, 68, 75, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 88, 
-	89, 90, 68, 70, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 88, 89, 
+	90, 68, 70, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 88, 89, 68, 70, 68, 68, 
+	68, 88, 89, 68, 70, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 89, 68, 70, 
-	68, 70, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 73, 74, 75, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	84, 85, 86, 68, 68, 68, 68, 68, 
-	88, 89, 90, 93, 68, 70, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 73, 
-	74, 75, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 85, 86, 68, 
-	68, 68, 68, 68, 88, 89, 90, 93, 
-	68, 70, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 73, 74, 75, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 86, 68, 68, 68, 68, 68, 
-	88, 89, 90, 93, 68, 95, 94, 94, 
-	94, 94, 94, 94, 94, 94, 94, 94, 
-	94, 94, 96, 94, 70, 68, 68, 68, 
+	68, 68, 68, 68, 89, 68, 70, 68, 
+	70, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 73, 74, 75, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 84, 
+	85, 86, 68, 68, 68, 68, 68, 88, 
+	89, 90, 94, 68, 70, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 73, 74, 
 	75, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 85, 86, 68, 68, 
+	68, 68, 68, 88, 89, 90, 94, 68, 
+	70, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 73, 74, 75, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 88, 89, 90, 93, 68, 
+	68, 86, 68, 68, 68, 68, 68, 88, 
+	89, 90, 94, 68, 96, 95, 95, 95, 
+	95, 95, 95, 95, 95, 95, 95, 95, 
+	95, 97, 95, 70, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 73, 74, 75, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 88, 89, 90, 94, 68, 70, 
+	68, 68, 68, 68, 68, 68, 68, 71, 
+	72, 73, 74, 75, 68, 68, 68, 68, 
+	68, 68, 81, 82, 83, 68, 84, 85, 
+	86, 68, 68, 68, 68, 68, 88, 89, 
+	90, 94, 68, 68, 68, 68, 72, 68, 
 	70, 68, 68, 68, 68, 68, 68, 68, 
-	71, 72, 73, 74, 75, 68, 68, 68, 
+	68, 72, 73, 74, 75, 68, 68, 68, 
 	68, 68, 68, 81, 82, 83, 68, 84, 
 	85, 86, 68, 68, 68, 68, 68, 88, 
-	89, 90, 93, 68, 68, 68, 68, 72, 
+	89, 90, 94, 68, 68, 68, 68, 72, 
 	68, 70, 68, 68, 68, 68, 68, 68, 
 	68, 68, 72, 73, 74, 75, 68, 68, 
-	68, 68, 68, 68, 81, 82, 83, 68, 
+	68, 68, 68, 68, 68, 82, 83, 68, 
 	84, 85, 86, 68, 68, 68, 68, 68, 
-	88, 89, 90, 93, 68, 68, 68, 68, 
+	88, 89, 90, 94, 68, 68, 68, 68, 
 	72, 68, 70, 68, 68, 68, 68, 68, 
 	68, 68, 68, 72, 73, 74, 75, 68, 
-	68, 68, 68, 68, 68, 68, 82, 83, 
+	68, 68, 68, 68, 68, 68, 68, 83, 
 	68, 84, 85, 86, 68, 68, 68, 68, 
-	68, 88, 89, 90, 93, 68, 68, 68, 
-	68, 72, 68, 70, 68, 68, 68, 68, 
-	68, 68, 68, 68, 72, 73, 74, 75, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	83, 68, 84, 85, 86, 68, 68, 68, 
-	68, 68, 88, 89, 90, 93, 68, 68, 
-	68, 68, 72, 68, 97, 68, 70, 68, 
-	68, 68, 68, 68, 68, 68, 71, 72, 
-	73, 74, 75, 68, 77, 78, 68, 68, 
-	68, 81, 82, 83, 68, 84, 85, 86, 
-	68, 68, 68, 68, 68, 88, 89, 90, 
-	93, 68, 68, 68, 68, 72, 68, 70, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	72, 73, 74, 75, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 84, 85, 
-	86, 68, 68, 68, 68, 68, 88, 89, 
-	90, 93, 68, 68, 68, 68, 72, 68, 
-	97, 68, 70, 68, 68, 68, 68, 68, 
-	68, 68, 71, 72, 73, 74, 75, 68, 
-	68, 78, 68, 68, 68, 81, 82, 83, 
-	68, 84, 85, 86, 68, 68, 68, 68, 
-	68, 88, 89, 90, 93, 68, 68, 68, 
-	68, 72, 68, 97, 68, 70, 68, 68, 
+	68, 88, 89, 90, 94, 68, 68, 68, 
+	68, 72, 68, 98, 68, 70, 68, 68, 
 	68, 68, 68, 68, 68, 71, 72, 73, 
-	74, 75, 68, 68, 68, 68, 68, 68, 
+	74, 75, 68, 77, 78, 68, 68, 68, 
 	81, 82, 83, 68, 84, 85, 86, 68, 
-	68, 68, 68, 68, 88, 89, 90, 93, 
-	68, 68, 68, 68, 72, 68, 97, 68, 
-	70, 68, 68, 68, 68, 68, 68, 68, 
-	71, 72, 73, 74, 75, 76, 77, 78, 
-	68, 68, 68, 81, 82, 83, 68, 84, 
-	85, 86, 68, 68, 68, 68, 68, 88, 
-	89, 90, 93, 68, 68, 68, 68, 72, 
-	68, 4, 69, 68, 70, 68, 68, 68, 
+	68, 68, 68, 68, 88, 89, 90, 94, 
+	68, 68, 68, 68, 72, 68, 70, 68, 
+	68, 68, 68, 68, 68, 68, 68, 72, 
+	73, 74, 75, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 84, 85, 86, 
+	68, 68, 68, 68, 68, 88, 89, 90, 
+	94, 68, 68, 68, 68, 72, 68, 98, 
+	68, 70, 68, 68, 68, 68, 68, 68, 
+	68, 71, 72, 73, 74, 75, 68, 68, 
+	78, 68, 68, 68, 81, 82, 83, 68, 
+	84, 85, 86, 68, 68, 68, 68, 68, 
+	88, 89, 90, 94, 68, 68, 68, 68, 
+	72, 68, 98, 68, 70, 68, 68, 68, 
 	68, 68, 68, 68, 71, 72, 73, 74, 
-	75, 76, 77, 78, 79, 68, 80, 81, 
+	75, 68, 68, 68, 68, 68, 68, 81, 
 	82, 83, 68, 84, 85, 86, 68, 68, 
-	68, 68, 87, 88, 89, 90, 91, 68, 
-	68, 68, 68, 92, 68, 4, 98, 98, 
-	98, 98, 98, 98, 98, 98, 98, 98, 
-	98, 98, 99, 98, 4, 94, 94, 94, 
-	94, 94, 94, 94, 94, 94, 94, 94, 
-	94, 96, 94, 4, 68, 68, 68, 68, 
+	68, 68, 68, 88, 89, 90, 94, 68, 
+	68, 68, 68, 72, 68, 98, 68, 70, 
+	68, 68, 68, 68, 68, 68, 68, 71, 
+	72, 73, 74, 75, 76, 77, 78, 68, 
+	68, 68, 81, 82, 83, 68, 84, 85, 
+	86, 68, 68, 68, 68, 68, 88, 89, 
+	90, 94, 68, 68, 68, 68, 72, 68, 
+	4, 69, 68, 70, 68, 68, 68, 68, 
+	68, 68, 68, 71, 72, 73, 74, 75, 
+	76, 77, 78, 79, 68, 80, 81, 82, 
+	83, 68, 84, 85, 86, 68, 68, 68, 
+	68, 87, 88, 89, 90, 91, 68, 68, 
+	68, 68, 92, 68, 68, 93, 68, 4, 
+	99, 99, 99, 99, 99, 99, 99, 99, 
+	99, 99, 99, 99, 100, 99, 4, 95, 
+	95, 95, 95, 95, 95, 95, 95, 95, 
+	95, 95, 95, 97, 95, 4, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	70, 68, 68, 68, 68, 68, 68, 68, 
-	68, 72, 73, 74, 75, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 84, 
-	85, 86, 68, 68, 68, 68, 68, 88, 
-	89, 90, 93, 68, 101, 102, 100, 6, 
-	103, 103, 103, 103, 103, 103, 103, 103, 
-	103, 104, 103, 105, 106, 68, 70, 68, 
-	68, 68, 68, 68, 68, 68, 107, 108, 
-	109, 110, 111, 112, 113, 114, 115, 105, 
-	116, 117, 118, 119, 68, 120, 121, 122, 
-	68, 58, 59, 68, 123, 124, 125, 126, 
-	127, 68, 68, 68, 68, 128, 68, 105, 
-	106, 68, 70, 68, 68, 68, 68, 68, 
-	68, 68, 107, 108, 109, 110, 111, 112, 
-	113, 114, 115, 105, 116, 117, 118, 119, 
-	68, 120, 121, 122, 68, 68, 68, 68, 
-	123, 124, 125, 126, 127, 68, 68, 68, 
-	68, 128, 68, 105, 68, 68, 68, 68, 
+	68, 68, 70, 68, 68, 68, 68, 68, 
+	68, 68, 68, 72, 73, 74, 75, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	70, 68, 68, 68, 68, 68, 68, 68, 
-	68, 108, 109, 110, 111, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 120, 
-	121, 122, 68, 68, 68, 68, 68, 124, 
-	125, 126, 129, 68, 68, 68, 68, 108, 
+	68, 84, 85, 86, 68, 68, 68, 68, 
+	68, 88, 89, 90, 94, 68, 100, 99, 
+	102, 103, 101, 6, 104, 104, 104, 104, 
+	104, 104, 104, 104, 104, 105, 104, 106, 
+	107, 68, 70, 68, 68, 68, 68, 68, 
+	68, 68, 108, 109, 110, 111, 112, 113, 
+	114, 115, 116, 106, 117, 118, 119, 120, 
+	68, 121, 122, 123, 68, 58, 59, 68, 
+	124, 125, 126, 127, 128, 68, 68, 68, 
+	68, 129, 68, 68, 130, 68, 106, 107, 
 	68, 70, 68, 68, 68, 68, 68, 68, 
-	68, 68, 108, 109, 110, 111, 68, 68, 
+	68, 108, 109, 110, 111, 112, 113, 114, 
+	115, 116, 106, 117, 118, 119, 120, 68, 
+	121, 122, 123, 68, 68, 68, 68, 124, 
+	125, 126, 127, 128, 68, 68, 68, 68, 
+	129, 68, 68, 130, 68, 106, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	120, 121, 122, 68, 68, 68, 68, 68, 
-	124, 125, 126, 129, 68, 70, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 109, 
-	110, 111, 68, 68, 68, 68, 68, 68, 
+	68, 68, 70, 68, 68, 68, 68, 68, 
+	68, 68, 68, 109, 110, 111, 112, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 124, 125, 126, 68, 
-	70, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 110, 111, 68, 68, 68, 
+	68, 121, 122, 123, 68, 68, 68, 68, 
+	68, 125, 126, 127, 131, 68, 68, 68, 
+	68, 109, 68, 70, 68, 68, 68, 68, 
+	68, 68, 68, 68, 109, 110, 111, 112, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 124, 
-	125, 126, 68, 70, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 111, 
+	68, 68, 121, 122, 123, 68, 68, 68, 
+	68, 68, 125, 126, 127, 131, 68, 70, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 110, 111, 112, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 124, 125, 126, 68, 70, 68, 
+	68, 68, 68, 68, 68, 68, 125, 126, 
+	127, 68, 70, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 111, 112, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 125, 126, 127, 68, 70, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 124, 125, 68, 
+	68, 112, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 125, 126, 127, 68, 
 	70, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 125, 
+	126, 68, 70, 68, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	125, 68, 70, 68, 70, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 109, 110, 
-	111, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 120, 121, 122, 68, 68, 
-	68, 68, 68, 124, 125, 126, 129, 68, 
-	70, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 109, 110, 111, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	121, 122, 68, 68, 68, 68, 68, 124, 
-	125, 126, 129, 68, 70, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 109, 110, 
-	111, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 122, 68, 68, 
-	68, 68, 68, 124, 125, 126, 129, 68, 
-	130, 94, 94, 94, 94, 94, 94, 94, 
-	94, 94, 94, 94, 94, 96, 94, 70, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 109, 110, 111, 68, 68, 68, 68, 
+	68, 68, 126, 68, 70, 68, 70, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 124, 125, 
-	126, 129, 68, 70, 68, 68, 68, 68, 
-	68, 68, 68, 107, 108, 109, 110, 111, 
-	68, 68, 68, 68, 68, 68, 117, 118, 
-	119, 68, 120, 121, 122, 68, 68, 68, 
-	68, 68, 124, 125, 126, 129, 68, 68, 
-	68, 68, 108, 68, 70, 68, 68, 68, 
+	110, 111, 112, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 121, 122, 123, 
+	68, 68, 68, 68, 68, 125, 126, 127, 
+	131, 68, 70, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 110, 111, 112, 68, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 122, 123, 68, 68, 68, 68, 
+	68, 125, 126, 127, 131, 68, 70, 68, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	110, 111, 112, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 123, 
+	68, 68, 68, 68, 68, 125, 126, 127, 
+	131, 68, 132, 95, 95, 95, 95, 95, 
+	95, 95, 95, 95, 95, 95, 95, 97, 
+	95, 70, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 110, 111, 112, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	125, 126, 127, 131, 68, 70, 68, 68, 
 	68, 68, 68, 68, 68, 108, 109, 110, 
-	111, 68, 68, 68, 68, 68, 68, 117, 
-	118, 119, 68, 120, 121, 122, 68, 68, 
-	68, 68, 68, 124, 125, 126, 129, 68, 
-	68, 68, 68, 108, 68, 70, 68, 68, 
-	68, 68, 68, 68, 68, 68, 108, 109, 
-	110, 111, 68, 68, 68, 68, 68, 68, 
-	68, 118, 119, 68, 120, 121, 122, 68, 
-	68, 68, 68, 68, 124, 125, 126, 129, 
-	68, 68, 68, 68, 108, 68, 70, 68, 
+	111, 112, 68, 68, 68, 68, 68, 68, 
+	118, 119, 120, 68, 121, 122, 123, 68, 
+	68, 68, 68, 68, 125, 126, 127, 131, 
+	68, 68, 68, 68, 109, 68, 70, 68, 
+	68, 68, 68, 68, 68, 68, 68, 109, 
+	110, 111, 112, 68, 68, 68, 68, 68, 
+	68, 118, 119, 120, 68, 121, 122, 123, 
+	68, 68, 68, 68, 68, 125, 126, 127, 
+	131, 68, 68, 68, 68, 109, 68, 70, 
+	68, 68, 68, 68, 68, 68, 68, 68, 
+	109, 110, 111, 112, 68, 68, 68, 68, 
+	68, 68, 68, 119, 120, 68, 121, 122, 
+	123, 68, 68, 68, 68, 68, 125, 126, 
+	127, 131, 68, 68, 68, 68, 109, 68, 
+	70, 68, 68, 68, 68, 68, 68, 68, 
+	68, 109, 110, 111, 112, 68, 68, 68, 
+	68, 68, 68, 68, 68, 120, 68, 121, 
+	122, 123, 68, 68, 68, 68, 68, 125, 
+	126, 127, 131, 68, 68, 68, 68, 109, 
+	68, 133, 68, 70, 68, 68, 68, 68, 
+	68, 68, 68, 108, 109, 110, 111, 112, 
+	68, 114, 115, 68, 68, 68, 118, 119, 
+	120, 68, 121, 122, 123, 68, 68, 68, 
+	68, 68, 125, 126, 127, 131, 68, 68, 
+	68, 68, 109, 68, 70, 68, 68, 68, 
+	68, 68, 68, 68, 68, 109, 110, 111, 
+	112, 68, 68, 68, 68, 68, 68, 68, 
+	68, 68, 68, 121, 122, 123, 68, 68, 
+	68, 68, 68, 125, 126, 127, 131, 68, 
+	68, 68, 68, 109, 68, 133, 68, 70, 
 	68, 68, 68, 68, 68, 68, 68, 108, 
-	109, 110, 111, 68, 68, 68, 68, 68, 
-	68, 68, 68, 119, 68, 120, 121, 122, 
-	68, 68, 68, 68, 68, 124, 125, 126, 
-	129, 68, 68, 68, 68, 108, 68, 131, 
+	109, 110, 111, 112, 68, 68, 115, 68, 
+	68, 68, 118, 119, 120, 68, 121, 122, 
+	123, 68, 68, 68, 68, 68, 125, 126, 
+	127, 131, 68, 68, 68, 68, 109, 68, 
+	133, 68, 70, 68, 68, 68, 68, 68, 
+	68, 68, 108, 109, 110, 111, 112, 68, 
+	68, 68, 68, 68, 68, 118, 119, 120, 
+	68, 121, 122, 123, 68, 68, 68, 68, 
+	68, 125, 126, 127, 131, 68, 68, 68, 
+	68, 109, 68, 133, 68, 70, 68, 68, 
+	68, 68, 68, 68, 68, 108, 109, 110, 
+	111, 112, 113, 114, 115, 68, 68, 68, 
+	118, 119, 120, 68, 121, 122, 123, 68, 
+	68, 68, 68, 68, 125, 126, 127, 131, 
+	68, 68, 68, 68, 109, 68, 106, 107, 
 	68, 70, 68, 68, 68, 68, 68, 68, 
-	68, 107, 108, 109, 110, 111, 68, 113, 
-	114, 68, 68, 68, 117, 118, 119, 68, 
-	120, 121, 122, 68, 68, 68, 68, 68, 
-	124, 125, 126, 129, 68, 68, 68, 68, 
-	108, 68, 70, 68, 68, 68, 68, 68, 
-	68, 68, 68, 108, 109, 110, 111, 68, 
+	68, 108, 109, 110, 111, 112, 113, 114, 
+	115, 116, 68, 117, 118, 119, 120, 68, 
+	121, 122, 123, 68, 68, 68, 68, 124, 
+	125, 126, 127, 128, 68, 68, 68, 68, 
+	129, 68, 68, 130, 68, 106, 99, 99, 
+	99, 99, 99, 99, 99, 99, 99, 99, 
+	99, 99, 100, 99, 106, 95, 95, 95, 
+	95, 95, 95, 95, 95, 95, 95, 95, 
+	95, 97, 95, 106, 68, 68, 68, 68, 
 	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 120, 121, 122, 68, 68, 68, 68, 
-	68, 124, 125, 126, 129, 68, 68, 68, 
-	68, 108, 68, 131, 68, 70, 68, 68, 
-	68, 68, 68, 68, 68, 107, 108, 109, 
-	110, 111, 68, 68, 114, 68, 68, 68, 
-	117, 118, 119, 68, 120, 121, 122, 68, 
-	68, 68, 68, 68, 124, 125, 126, 129, 
-	68, 68, 68, 68, 108, 68, 131, 68, 
 	70, 68, 68, 68, 68, 68, 68, 68, 
-	107, 108, 109, 110, 111, 68, 68, 68, 
-	68, 68, 68, 117, 118, 119, 68, 120, 
-	121, 122, 68, 68, 68, 68, 68, 124, 
-	125, 126, 129, 68, 68, 68, 68, 108, 
-	68, 131, 68, 70, 68, 68, 68, 68, 
-	68, 68, 68, 107, 108, 109, 110, 111, 
-	112, 113, 114, 68, 68, 68, 117, 118, 
-	119, 68, 120, 121, 122, 68, 68, 68, 
-	68, 68, 124, 125, 126, 129, 68, 68, 
-	68, 68, 108, 68, 105, 106, 68, 70, 
-	68, 68, 68, 68, 68, 68, 68, 107, 
-	108, 109, 110, 111, 112, 113, 114, 115, 
-	68, 116, 117, 118, 119, 68, 120, 121, 
-	122, 68, 68, 68, 68, 123, 124, 125, 
-	126, 127, 68, 68, 68, 68, 128, 68, 
-	105, 98, 98, 98, 98, 98, 98, 98, 
-	98, 98, 98, 98, 98, 99, 98, 105, 
-	94, 94, 94, 94, 94, 94, 94, 94, 
-	94, 94, 94, 94, 96, 94, 105, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 70, 68, 68, 68, 68, 
-	68, 68, 68, 68, 108, 109, 110, 111, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 120, 121, 122, 68, 68, 68, 
-	68, 68, 124, 125, 126, 129, 68, 8, 
-	9, 132, 11, 132, 132, 132, 132, 132, 
-	132, 132, 13, 14, 15, 16, 17, 18, 
-	19, 20, 21, 8, 22, 23, 24, 25, 
-	132, 26, 27, 28, 132, 132, 132, 132, 
-	32, 33, 34, 35, 32, 132, 132, 132, 
-	132, 37, 132, 8, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	11, 132, 132, 132, 132, 132, 132, 132, 
-	132, 14, 15, 16, 17, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 26, 
-	27, 28, 132, 132, 132, 132, 132, 33, 
-	34, 35, 133, 132, 132, 132, 132, 14, 
-	132, 11, 132, 132, 132, 132, 132, 132, 
-	132, 132, 14, 15, 16, 17, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	26, 27, 28, 132, 132, 132, 132, 132, 
-	33, 34, 35, 133, 132, 11, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 15, 
-	16, 17, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 33, 34, 35, 132, 
-	11, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 16, 17, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 33, 
-	34, 35, 132, 11, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 17, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 33, 34, 35, 132, 11, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 33, 34, 132, 
-	11, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	34, 132, 11, 132, 11, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 15, 16, 
-	17, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 26, 27, 28, 132, 132, 
-	132, 132, 132, 33, 34, 35, 133, 132, 
-	11, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 15, 16, 17, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	27, 28, 132, 132, 132, 132, 132, 33, 
-	34, 35, 133, 132, 11, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 15, 16, 
-	17, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 28, 132, 132, 
-	132, 132, 132, 33, 34, 35, 133, 132, 
-	134, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 11, 132, 11, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 15, 16, 17, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 33, 34, 
-	35, 133, 132, 11, 132, 132, 132, 132, 
-	132, 132, 132, 13, 14, 15, 16, 17, 
-	132, 132, 132, 132, 132, 132, 23, 24, 
-	25, 132, 26, 27, 28, 132, 132, 132, 
-	132, 132, 33, 34, 35, 133, 132, 132, 
-	132, 132, 14, 132, 11, 132, 132, 132, 
-	132, 132, 132, 132, 132, 14, 15, 16, 
-	17, 132, 132, 132, 132, 132, 132, 23, 
-	24, 25, 132, 26, 27, 28, 132, 132, 
-	132, 132, 132, 33, 34, 35, 133, 132, 
-	132, 132, 132, 14, 132, 11, 132, 132, 
-	132, 132, 132, 132, 132, 132, 14, 15, 
-	16, 17, 132, 132, 132, 132, 132, 132, 
-	132, 24, 25, 132, 26, 27, 28, 132, 
-	132, 132, 132, 132, 33, 34, 35, 133, 
-	132, 132, 132, 132, 14, 132, 11, 132, 
-	132, 132, 132, 132, 132, 132, 132, 14, 
-	15, 16, 17, 132, 132, 132, 132, 132, 
-	132, 132, 132, 25, 132, 26, 27, 28, 
-	132, 132, 132, 132, 132, 33, 34, 35, 
-	133, 132, 132, 132, 132, 14, 132, 135, 
-	132, 11, 132, 132, 132, 132, 132, 132, 
-	132, 13, 14, 15, 16, 17, 132, 19, 
-	20, 132, 132, 132, 23, 24, 25, 132, 
-	26, 27, 28, 132, 132, 132, 132, 132, 
-	33, 34, 35, 133, 132, 132, 132, 132, 
-	14, 132, 11, 132, 132, 132, 132, 132, 
-	132, 132, 132, 14, 15, 16, 17, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 26, 27, 28, 132, 132, 132, 132, 
-	132, 33, 34, 35, 133, 132, 132, 132, 
-	132, 14, 132, 135, 132, 11, 132, 132, 
-	132, 132, 132, 132, 132, 13, 14, 15, 
-	16, 17, 132, 132, 20, 132, 132, 132, 
-	23, 24, 25, 132, 26, 27, 28, 132, 
-	132, 132, 132, 132, 33, 34, 35, 133, 
-	132, 132, 132, 132, 14, 132, 135, 132, 
-	11, 132, 132, 132, 132, 132, 132, 132, 
-	13, 14, 15, 16, 17, 132, 132, 132, 
-	132, 132, 132, 23, 24, 25, 132, 26, 
-	27, 28, 132, 132, 132, 132, 132, 33, 
-	34, 35, 133, 132, 132, 132, 132, 14, 
-	132, 135, 132, 11, 132, 132, 132, 132, 
-	132, 132, 132, 13, 14, 15, 16, 17, 
-	18, 19, 20, 132, 132, 132, 23, 24, 
-	25, 132, 26, 27, 28, 132, 132, 132, 
-	132, 132, 33, 34, 35, 133, 132, 132, 
-	132, 132, 14, 132, 8, 9, 132, 11, 
-	132, 132, 132, 132, 132, 132, 132, 13, 
-	14, 15, 16, 17, 18, 19, 20, 21, 
-	132, 22, 23, 24, 25, 132, 26, 27, 
-	28, 132, 132, 132, 132, 32, 33, 34, 
-	35, 32, 132, 132, 132, 132, 37, 132, 
-	8, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 11, 132, 8, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 11, 132, 132, 132, 
-	132, 132, 132, 132, 132, 14, 15, 16, 
-	17, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 26, 27, 28, 132, 132, 
-	132, 132, 132, 33, 34, 35, 133, 132, 
-	136, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 11, 132, 10, 11, 132, 4, 
-	132, 132, 132, 4, 132, 132, 132, 132, 
-	132, 8, 9, 10, 11, 132, 132, 132, 
-	132, 132, 132, 132, 13, 14, 15, 16, 
-	17, 18, 19, 20, 21, 8, 22, 23, 
-	24, 25, 132, 26, 27, 28, 132, 29, 
-	30, 132, 32, 33, 34, 35, 32, 132, 
-	132, 132, 132, 37, 132, 11, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	29, 30, 132, 11, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 132, 
-	132, 132, 132, 132, 132, 132, 132, 30, 
-	132, 4, 137, 137, 137, 4, 137, 139, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 140, 138, 141, 138, 141, 
-	142, 138, 139, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 1, 140, 140, 
-	138, 139, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 140, 138, 141, 
-	138, 139, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 138, 138, 138, 
-	138, 138, 138, 138, 138, 140, 138, 141, 
-	138, 141, 138, 39, 40, 38, 41, 38, 
+	68, 109, 110, 111, 112, 68, 68, 68, 
+	68, 68, 68, 68, 68, 68, 68, 121, 
+	122, 123, 68, 68, 68, 68, 68, 125, 
+	126, 127, 131, 68, 100, 99, 8, 9, 
+	134, 11, 134, 134, 134, 134, 134, 134, 
+	134, 13, 14, 15, 16, 17, 18, 19, 
+	20, 21, 8, 22, 23, 24, 25, 134, 
+	26, 27, 28, 134, 134, 134, 134, 32, 
+	33, 34, 35, 32, 134, 134, 134, 134, 
+	37, 134, 134, 35, 134, 8, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 11, 134, 134, 134, 134, 134, 
+	134, 134, 134, 14, 15, 16, 17, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 26, 27, 28, 134, 134, 134, 134, 
+	134, 33, 34, 35, 135, 134, 134, 134, 
+	134, 14, 134, 11, 134, 134, 134, 134, 
+	134, 134, 134, 134, 14, 15, 16, 17, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 26, 27, 28, 134, 134, 134, 
+	134, 134, 33, 34, 35, 135, 134, 11, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 15, 16, 17, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 33, 34, 
+	35, 134, 11, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 16, 17, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 33, 34, 35, 134, 11, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 17, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 33, 34, 35, 134, 
+	11, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 33, 
+	34, 134, 11, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 34, 134, 11, 134, 11, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	15, 16, 17, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 26, 27, 28, 
+	134, 134, 134, 134, 134, 33, 34, 35, 
+	135, 134, 11, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 15, 16, 17, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 27, 28, 134, 134, 134, 134, 
+	134, 33, 34, 35, 135, 134, 11, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	15, 16, 17, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 28, 
+	134, 134, 134, 134, 134, 33, 34, 35, 
+	135, 134, 136, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 11, 
+	134, 11, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 15, 16, 17, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	33, 34, 35, 135, 134, 11, 134, 134, 
+	134, 134, 134, 134, 134, 13, 14, 15, 
+	16, 17, 134, 134, 134, 134, 134, 134, 
+	23, 24, 25, 134, 26, 27, 28, 134, 
+	134, 134, 134, 134, 33, 34, 35, 135, 
+	134, 134, 134, 134, 14, 134, 11, 134, 
+	134, 134, 134, 134, 134, 134, 134, 14, 
+	15, 16, 17, 134, 134, 134, 134, 134, 
+	134, 23, 24, 25, 134, 26, 27, 28, 
+	134, 134, 134, 134, 134, 33, 34, 35, 
+	135, 134, 134, 134, 134, 14, 134, 11, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	14, 15, 16, 17, 134, 134, 134, 134, 
+	134, 134, 134, 24, 25, 134, 26, 27, 
+	28, 134, 134, 134, 134, 134, 33, 34, 
+	35, 135, 134, 134, 134, 134, 14, 134, 
+	11, 134, 134, 134, 134, 134, 134, 134, 
+	134, 14, 15, 16, 17, 134, 134, 134, 
+	134, 134, 134, 134, 134, 25, 134, 26, 
+	27, 28, 134, 134, 134, 134, 134, 33, 
+	34, 35, 135, 134, 134, 134, 134, 14, 
+	134, 137, 134, 11, 134, 134, 134, 134, 
+	134, 134, 134, 13, 14, 15, 16, 17, 
+	134, 19, 20, 134, 134, 134, 23, 24, 
+	25, 134, 26, 27, 28, 134, 134, 134, 
+	134, 134, 33, 34, 35, 135, 134, 134, 
+	134, 134, 14, 134, 11, 134, 134, 134, 
+	134, 134, 134, 134, 134, 14, 15, 16, 
+	17, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 26, 27, 28, 134, 134, 
+	134, 134, 134, 33, 34, 35, 135, 134, 
+	134, 134, 134, 14, 134, 137, 134, 11, 
+	134, 134, 134, 134, 134, 134, 134, 13, 
+	14, 15, 16, 17, 134, 134, 20, 134, 
+	134, 134, 23, 24, 25, 134, 26, 27, 
+	28, 134, 134, 134, 134, 134, 33, 34, 
+	35, 135, 134, 134, 134, 134, 14, 134, 
+	137, 134, 11, 134, 134, 134, 134, 134, 
+	134, 134, 13, 14, 15, 16, 17, 134, 
+	134, 134, 134, 134, 134, 23, 24, 25, 
+	134, 26, 27, 28, 134, 134, 134, 134, 
+	134, 33, 34, 35, 135, 134, 134, 134, 
+	134, 14, 134, 137, 134, 11, 134, 134, 
+	134, 134, 134, 134, 134, 13, 14, 15, 
+	16, 17, 18, 19, 20, 134, 134, 134, 
+	23, 24, 25, 134, 26, 27, 28, 134, 
+	134, 134, 134, 134, 33, 34, 35, 135, 
+	134, 134, 134, 134, 14, 134, 8, 9, 
+	134, 11, 134, 134, 134, 134, 134, 134, 
+	134, 13, 14, 15, 16, 17, 18, 19, 
+	20, 21, 134, 22, 23, 24, 25, 134, 
+	26, 27, 28, 134, 134, 134, 134, 32, 
+	33, 34, 35, 32, 134, 134, 134, 134, 
+	37, 134, 134, 35, 134, 8, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 11, 134, 8, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 11, 134, 134, 134, 134, 134, 134, 
+	134, 134, 14, 15, 16, 17, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	26, 27, 28, 134, 134, 134, 134, 134, 
+	33, 34, 35, 135, 134, 138, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 11, 
+	134, 10, 11, 134, 4, 134, 134, 134, 
+	4, 134, 134, 134, 134, 134, 8, 9, 
+	10, 11, 134, 134, 134, 134, 134, 134, 
+	134, 13, 14, 15, 16, 17, 18, 19, 
+	20, 21, 8, 22, 23, 24, 25, 134, 
+	26, 27, 28, 134, 29, 30, 134, 32, 
+	33, 34, 35, 32, 134, 134, 134, 134, 
+	37, 134, 134, 35, 134, 11, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	29, 30, 134, 11, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 134, 
+	134, 134, 134, 134, 134, 134, 134, 30, 
+	134, 4, 139, 139, 139, 4, 139, 141, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 142, 140, 143, 140, 143, 
+	144, 140, 141, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 1, 142, 142, 
+	140, 141, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 142, 140, 143, 
+	140, 141, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 140, 140, 140, 
+	140, 140, 140, 140, 140, 142, 140, 143, 
+	140, 143, 140, 39, 40, 38, 41, 38, 
 	38, 38, 38, 38, 38, 38, 42, 43, 
 	44, 45, 46, 47, 48, 49, 50, 39, 
 	51, 52, 53, 54, 38, 55, 56, 57, 
 	38, 58, 59, 38, 60, 61, 62, 63, 
-	60, 1, 38, 2, 38, 64, 38, 0
+	60, 1, 38, 2, 38, 64, 38, 38, 
+	63, 38, 0
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
-	1, 120, 0, 2, 31, 1, 58, 60, 
-	88, 89, 114, 1, 116, 102, 90, 91, 
-	92, 93, 106, 108, 109, 110, 111, 103, 
-	104, 105, 97, 98, 99, 117, 118, 119, 
-	112, 94, 95, 96, 124, 113, 1, 3, 
+	1, 122, 0, 2, 31, 1, 59, 61, 
+	90, 91, 116, 1, 118, 104, 92, 93, 
+	94, 95, 108, 110, 111, 112, 113, 105, 
+	106, 107, 99, 100, 101, 119, 120, 121, 
+	114, 96, 97, 98, 126, 115, 1, 3, 
 	4, 1, 17, 5, 6, 7, 8, 21, 
 	23, 24, 25, 26, 18, 19, 20, 12, 
 	13, 14, 29, 30, 27, 9, 10, 11, 
@@ -723,13 +730,14 @@
 	28, 15, 16, 22, 1, 32, 1, 45, 
 	33, 34, 35, 36, 49, 51, 52, 53, 
 	54, 46, 47, 48, 40, 41, 42, 55, 
-	37, 38, 39, 56, 57, 43, 1, 44, 
-	1, 50, 1, 1, 1, 59, 1, 1, 
-	1, 61, 62, 75, 63, 64, 65, 66, 
-	79, 81, 82, 83, 84, 76, 77, 78, 
-	70, 71, 72, 85, 67, 68, 69, 86, 
-	87, 73, 74, 80, 1, 100, 101, 107, 
-	115, 1, 1, 1, 121, 122, 123
+	37, 38, 39, 56, 57, 58, 43, 1, 
+	44, 1, 50, 1, 1, 1, 60, 1, 
+	1, 1, 62, 63, 76, 64, 65, 66, 
+	67, 80, 82, 83, 84, 85, 77, 78, 
+	79, 71, 72, 73, 86, 68, 69, 70, 
+	87, 88, 89, 74, 75, 81, 1, 102, 
+	103, 109, 117, 1, 1, 1, 123, 124, 
+	125
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
@@ -744,13 +752,14 @@
 	0, 0, 0, 0, 9, 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, 11, 0, 
-	12, 0, 13, 14, 15, 0, 16, 17, 
-	18, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 11, 
+	0, 12, 0, 13, 14, 15, 0, 16, 
+	17, 18, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 19, 0, 0, 0, 
-	0, 20, 21, 22, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 19, 0, 
+	0, 0, 0, 20, 21, 22, 0, 0, 
+	0
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
@@ -769,7 +778,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0
 };
 
 static const char _use_syllable_machine_from_state_actions[] = {
@@ -788,7 +797,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 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[] = {
@@ -797,17 +806,17 @@
 	39, 39, 39, 39, 39, 39, 39, 39, 
 	39, 39, 39, 39, 39, 39, 39, 69, 
 	69, 69, 69, 69, 69, 69, 69, 69, 
-	69, 69, 69, 95, 69, 69, 69, 69, 
-	69, 69, 69, 69, 69, 69, 69, 99, 
-	95, 69, 101, 104, 69, 69, 69, 69, 
+	69, 69, 69, 96, 69, 69, 69, 69, 
+	69, 69, 69, 69, 69, 69, 69, 100, 
+	96, 69, 100, 102, 105, 69, 69, 69, 
 	69, 69, 69, 69, 69, 69, 69, 69, 
-	69, 95, 69, 69, 69, 69, 69, 69, 
-	69, 69, 69, 69, 69, 99, 95, 69, 
-	133, 133, 133, 133, 133, 133, 133, 133, 
-	133, 133, 133, 133, 133, 133, 133, 133, 
-	133, 133, 133, 133, 133, 133, 133, 133, 
-	133, 133, 133, 133, 133, 133, 133, 138, 
-	139, 139, 139, 139, 39
+	69, 69, 96, 69, 69, 69, 69, 69, 
+	69, 69, 69, 69, 69, 69, 100, 96, 
+	69, 100, 135, 135, 135, 135, 135, 135, 
+	135, 135, 135, 135, 135, 135, 135, 135, 
+	135, 135, 135, 135, 135, 135, 135, 135, 
+	135, 135, 135, 135, 135, 135, 135, 135, 
+	135, 140, 141, 141, 141, 141, 39
 };
 
 static const int use_syllable_machine_start = 1;
@@ -821,7 +830,7 @@
 
 
 
-#line 184 "hb-ot-shaper-use-machine.rl"
+#line 185 "hb-ot-shaper-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
@@ -920,7 +929,7 @@
   unsigned int act HB_UNUSED;
   int cs;
   
-#line 924 "hb-ot-shaper-use-machine.hh"
+#line 933 "hb-ot-shaper-use-machine.hh"
 	{
 	cs = use_syllable_machine_start;
 	ts = 0;
@@ -928,12 +937,12 @@
 	act = 0;
 	}
 
-#line 284 "hb-ot-shaper-use-machine.rl"
+#line 285 "hb-ot-shaper-use-machine.rl"
 
 
   unsigned int syllable_serial = 1;
   
-#line 937 "hb-ot-shaper-use-machine.hh"
+#line 946 "hb-ot-shaper-use-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -947,7 +956,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 951 "hb-ot-shaper-use-machine.hh"
+#line 960 "hb-ot-shaper-use-machine.hh"
 	}
 
 	_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -970,82 +979,82 @@
 	{te = p+1;}
 	break;
 	case 14:
-#line 172 "hb-ot-shaper-use-machine.rl"
+#line 173 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_virama_terminated_cluster); }}
 	break;
 	case 12:
-#line 173 "hb-ot-shaper-use-machine.rl"
+#line 174 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_sakot_terminated_cluster); }}
 	break;
 	case 10:
-#line 174 "hb-ot-shaper-use-machine.rl"
+#line 175 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_standard_cluster); }}
 	break;
 	case 18:
-#line 175 "hb-ot-shaper-use-machine.rl"
+#line 176 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }}
 	break;
 	case 16:
-#line 176 "hb-ot-shaper-use-machine.rl"
+#line 177 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_numeral_cluster); }}
 	break;
 	case 8:
-#line 177 "hb-ot-shaper-use-machine.rl"
+#line 178 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_symbol_cluster); }}
 	break;
 	case 22:
-#line 178 "hb-ot-shaper-use-machine.rl"
+#line 179 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_hieroglyph_cluster); }}
 	break;
 	case 5:
-#line 179 "hb-ot-shaper-use-machine.rl"
+#line 180 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
 	break;
 	case 4:
-#line 180 "hb-ot-shaper-use-machine.rl"
+#line 181 "hb-ot-shaper-use-machine.rl"
 	{te = p+1;{ found_syllable (use_non_cluster); }}
 	break;
 	case 13:
-#line 172 "hb-ot-shaper-use-machine.rl"
+#line 173 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
 	break;
 	case 11:
-#line 173 "hb-ot-shaper-use-machine.rl"
+#line 174 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
 	break;
 	case 9:
-#line 174 "hb-ot-shaper-use-machine.rl"
+#line 175 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_standard_cluster); }}
 	break;
 	case 17:
-#line 175 "hb-ot-shaper-use-machine.rl"
+#line 176 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
 	break;
 	case 15:
-#line 176 "hb-ot-shaper-use-machine.rl"
+#line 177 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_numeral_cluster); }}
 	break;
 	case 7:
-#line 177 "hb-ot-shaper-use-machine.rl"
+#line 178 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_symbol_cluster); }}
 	break;
 	case 21:
-#line 178 "hb-ot-shaper-use-machine.rl"
+#line 179 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
 	break;
 	case 19:
-#line 179 "hb-ot-shaper-use-machine.rl"
+#line 180 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
 	break;
 	case 20:
-#line 180 "hb-ot-shaper-use-machine.rl"
+#line 181 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_non_cluster); }}
 	break;
 	case 1:
-#line 177 "hb-ot-shaper-use-machine.rl"
+#line 178 "hb-ot-shaper-use-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (use_symbol_cluster); }}
 	break;
-#line 1049 "hb-ot-shaper-use-machine.hh"
+#line 1058 "hb-ot-shaper-use-machine.hh"
 	}
 
 _again:
@@ -1054,7 +1063,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 1058 "hb-ot-shaper-use-machine.hh"
+#line 1067 "hb-ot-shaper-use-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -1070,7 +1079,7 @@
 
 	}
 
-#line 289 "hb-ot-shaper-use-machine.rl"
+#line 290 "hb-ot-shaper-use-machine.rl"
 
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl	2024-11-06 04:18:33 UTC (rev 72778)
@@ -85,6 +85,7 @@
 export HVM	= 53; # HALANT_OR_VOWEL_MODIFIER
 export HM	= 54; # HIEROGLYPH_MOD
 export HR	= 55; # HIEROGLYPH_MIRROR
+export RK	= 56; # REORDERING_KILLER
 
 export FAbv	= 24; # CONS_FINAL_ABOVE
 export FBlw	= 25; # CONS_FINAL_BELOW
@@ -138,7 +139,7 @@
 
 virama_terminated_cluster_tail =
 	consonant_modifiers
-	IS
+	(IS | RK)
 ;
 virama_terminated_cluster =
 	complex_syllable_start

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -67,6 +67,7 @@
 #define N	USE(N)	/* BASE_NUM */
 #define O	USE(O)	/* OTHER */
 #define R	USE(R)	/* REPHA */
+#define RK	USE(RK)	/* REORDERING_KILLER */
 #define SB	USE(SB)	/* HIEROGLYPH_SEGMENT_BEGIN */
 #define SE	USE(SE)	/* HIEROGLYPH_SEGMENT_END */
 #define SUB	USE(SUB)	/* CONS_SUB */
@@ -101,7 +102,7 @@
 #ifndef HB_OPTIMIZE_SIZE
 
 static const uint8_t
-hb_use_u8[3343] =
+hb_use_u8[3345] =
 {
      16,   50,   51,   51,   51,   52,   51,   83,  118,  131,   57,   58,   59,  195,  211,   62,
      51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
@@ -201,89 +202,89 @@
       2,    2,    2,  107,   22,   20,   20,   22,   48,   48,   22,  108,    2,    2,    2,    9,
       0,    0,    0,    0,    0,    0,  109,  110,  110,  110,  110,    0,    0,    0,    0,    0,
       0,  106,   74,    2,    2,    2,    2,    2,    2,   60,   61,   59,   25,   22,  111,   61,
-      2,    2,    2,    2,  107,   22,   23,   45,   45,  102,   14,    0,    0,    0,    0,    0,
-      0,    2,    2,   61,   18,   48,   23,  112,  102,  102,  102,  113,  114,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    0,   30,    2,   11,   46,  115,  115,  115,   11,  115,
-    115,   15,  115,  115,  115,   26,    0,   40,    0,    0,    0,  116,   51,   11,    5,    0,
-      0,    0,    0,    0,    0,    0,  117,    0,    0,    0,    0,    0,    0,    0,    6,  118,
-    119,   42,   42,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  119,  119,
-    120,  119,  119,  119,  119,  119,  119,  119,  119,    0,    0,  121,    0,    0,    0,    0,
-      0,    0,    7,  121,    0,    0,    0,    0,    0,   46,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,  122,  122,    0,    0,
+      2,    2,    2,    2,  107,   22,   23,   45,   45,  102,  112,    0,    0,    0,    0,    0,
+      0,    2,    2,   61,   18,   48,   23,  113,  102,  102,  102,  114,  115,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    0,   30,    2,   11,   46,  116,  116,  116,   11,  116,
+    116,   15,  116,  116,  116,   26,    0,   40,    0,    0,    0,  117,   51,   11,    5,    0,
+      0,    0,    0,    0,    0,    0,  118,    0,    0,    0,    0,    0,    0,    0,    6,  119,
+    120,   42,   42,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  120,  120,
+    121,  120,  120,  120,  120,  120,  120,  120,  120,    0,    0,  122,    0,    0,    0,    0,
+      0,    0,    7,  122,    0,    0,    0,    0,    0,   46,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,  123,  123,    0,    0,
       0,    2,    2,    2,    2,    0,    0,    0,   30,    0,    0,    0,    0,    0,    0,    0,
-    123,    0,  122,  122,    0,    0,    0,    0,    0,    2,   53,    2,  108,    2,   10,    2,
+    124,    0,  123,  123,    0,    0,    0,    0,    0,    2,   53,    2,  108,    2,   10,    2,
       2,    2,   65,   19,   16,    0,    0,   31,    0,    2,    2,    0,    0,    0,    0,    0,
-      0,   29,    2,    2,    2,    2,    2,    2,    2,    2,    2,  124,   23,   23,   23,   23,
-     23,   23,   23,  125,    0,    0,    0,    0,    0,   11,   11,   11,   11,   11,   11,   11,
-     11,   11,    2,    0,    0,    0,    0,    0,   52,    2,    2,    2,   22,   22,  126,  115,
-      0,    2,    2,    2,  127,   20,   59,   20,  112,  102,  128,    0,    0,    0,    0,    0,
-      0,   11,  129,    2,    2,    2,    2,    2,    2,    2,  130,   23,   22,   20,   48,  131,
-    132,  133,    0,    0,    0,    0,    0,    0,    0,    2,    2,   52,   30,    2,    2,    2,
-      2,    2,    2,    2,    2,   10,   22,   59,   99,   76,  134,  135,  136,    0,    0,    0,
-      0,    2,  137,    2,    2,    2,    2,  138,    0,   30,    2,   42,    5,    0,   79,   15,
-      2,   53,   22,  139,   52,   53,    2,    2,  105,   10,    9,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,  140,   21,   25,    0,    0,  141,  142,    0,    0,    0,
-      0,    2,   65,   45,   23,   80,   47,  143,    0,   81,   81,   81,   81,   81,   81,   81,
-     81,    0,    0,    0,    0,    0,    0,    0,    6,  119,  119,  119,  119,  120,    0,    0,
+      0,   29,    2,    2,    2,    2,    2,    2,    2,    2,    2,  125,   23,   23,   23,   23,
+     23,   23,   23,  126,    0,    0,    0,    0,    0,   11,   11,   11,   11,   11,   11,   11,
+     11,   11,    2,    0,    0,    0,    0,    0,   52,    2,    2,    2,   22,   22,  127,  116,
+      0,    2,    2,    2,  128,   20,   59,   20,  113,  102,  129,    0,    0,    0,    0,    0,
+      0,   11,  130,    2,    2,    2,    2,    2,    2,    2,  131,   23,   22,   20,   48,  132,
+    133,  134,    0,    0,    0,    0,    0,    0,    0,    2,    2,   52,   30,    2,    2,    2,
+      2,    2,    2,    2,    2,   10,   22,   59,   99,   76,  135,  136,  137,    0,    0,    0,
+      0,    2,  138,    2,    2,    2,    2,  139,    0,   30,    2,   42,    5,    0,   79,   15,
+      2,   53,   22,  140,   52,   53,    2,    2,  105,   10,    9,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,  141,   21,   25,    0,    0,  142,  143,    0,    0,    0,
+      0,    2,   65,   45,   23,   80,   47,  144,    0,   81,   81,   81,   81,   81,   81,   81,
+     81,    0,    0,    0,    0,    0,    0,    0,    6,  120,  120,  120,  120,  121,    0,    0,
       0,    2,    2,    2,    2,    2,    9,    2,    2,    2,    9,    2,   30,    2,    2,    2,
-      2,    2,   30,    2,    2,    2,   30,    9,    0,  127,   20,   27,   31,    0,    0,  144,
-    145,    2,    2,   30,    2,   30,    2,    2,    2,    2,    2,    2,    0,   14,   37,    0,
-    146,    2,    2,   13,   37,    0,   30,    2,    2,    2,    0,    0,    0,    0,    0,    0,
+      2,    2,   30,    2,    2,    2,   30,    9,    0,  128,   20,   27,   31,    0,    0,  145,
+    146,    2,    2,   30,    2,   30,    2,    2,    2,    2,    2,    2,    0,   14,   37,    0,
+    147,    2,    2,   13,   37,    0,   30,    2,    2,    2,    0,    0,    0,    0,    0,    0,
       0,    0,    0,    0,    0,   30,    2,    2,    9,    2,    2,   11,   41,    0,    0,    0,
       0,    2,    2,    2,    0,   27,   22,   22,   30,    2,    2,    2,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,   27,   38,    0,    2,    2,    2,  115,  115,  115,  115,
-    115,  147,    2,    9,    0,    0,    0,    0,    0,    2,   14,   14,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,   27,   38,    0,    2,    2,    2,  116,  116,  116,  116,
+    116,  148,    2,    9,    0,    0,    0,    0,    0,    2,   14,   14,    0,    0,    0,    0,
       0,    9,    2,    2,    9,    2,    2,    2,    2,   30,    2,    9,    0,   30,    2,    0,
-      0,  148,  149,  150,    2,    2,    2,    2,    2,    2,    2,    2,    2,   22,   22,   20,
-     20,   20,   22,   22,  133,    0,    0,    0,    0,    0,  151,  151,  151,  151,  151,  151,
-    151,  151,  151,  151,    2,    2,    2,    2,    2,   53,   52,   53,    0,    0,    0,    0,
-    152,   11,   74,    2,    2,    2,    2,    2,    2,   18,   19,   21,   16,   24,   37,    0,
+      0,  149,  150,  151,    2,    2,    2,    2,    2,    2,    2,    2,    2,   22,   22,   20,
+     20,   20,   22,   22,  134,    0,    0,    0,    0,    0,  152,  152,  152,  152,  152,  152,
+    152,  152,  152,  152,    2,    2,    2,    2,    2,   53,   52,   53,    0,    0,    0,    0,
+    153,   11,   74,    2,    2,    2,    2,    2,    2,   18,   19,   21,   16,   24,   37,    0,
       0,    0,   31,    0,    0,    0,    0,    0,    0,   11,   49,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,  127,   20,   22,  153,   22,   21,  154,  155,    2,    2,    2,    2,
-      2,    0,    0,   65,  156,    0,    0,    0,    0,    2,   13,    0,    0,    0,    0,    0,
-      0,    2,   65,   25,   20,   20,   20,   22,   22,  108,  157,    0,    0,   56,  158,   31,
-    159,   30,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   23,
-     19,   22,   22,  160,   44,    0,    0,    0,   49,  127,    0,    0,    0,    0,    0,    0,
+      2,    2,    2,    2,  128,   20,   22,  154,   22,   21,  155,  156,    2,    2,    2,    2,
+      2,    0,    0,   65,  157,    0,    0,    0,    0,    2,   13,    0,    0,    0,    0,    0,
+      0,    2,   65,   25,   20,   20,   20,   22,   22,  108,  158,    0,    0,   56,  159,   31,
+    160,   30,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   23,
+     19,   22,   22,  161,   44,    0,    0,    0,   49,  128,    0,    0,    0,    0,    0,    0,
       0,    2,    2,    2,    9,    9,    2,    2,   30,    2,    2,    2,    2,    2,    2,    2,
-     30,    2,    2,    2,    2,    2,    2,    2,   10,   18,   19,   21,   22,  161,   31,    0,
+     30,    2,    2,    2,    2,    2,    2,    2,   10,   18,   19,   21,   22,  162,   31,    0,
       0,   11,   11,   30,    2,    2,    2,    9,   30,    9,    2,   30,    2,    2,   58,   17,
      23,   16,   23,   47,   32,   33,   32,   34,    0,    0,    0,    0,   35,    0,    0,    0,
       2,    2,   23,    0,   11,   11,   11,   46,    0,   11,   11,   46,    0,    0,    0,    0,
       0,    2,    2,    2,    2,    2,   30,    0,    9,    2,    2,    2,   30,   45,   59,   20,
-     20,   31,   33,   32,   32,   25,  162,   29,  163,  164,   37,    0,    0,    0,    0,    0,
+     20,   31,   33,   32,   32,   25,  163,   29,  164,  165,   37,    0,    0,    0,    0,    0,
       0,   12,   26,    0,    0,    0,    0,    0,    0,    2,    2,   65,   25,   20,   20,   20,
-     22,   23,  125,   15,   17,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
-    165,  166,    0,    0,    0,    0,    0,    0,    0,   18,   19,   20,   20,   66,   99,   25,
-    159,   11,  167,    9,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-     65,   25,   20,   20,    0,   48,   48,   11,  168,   37,    0,    0,    0,    0,    0,    0,
+     22,   23,  126,   15,   17,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
+    166,  167,    0,    0,    0,    0,    0,    0,    0,   18,   19,   20,   20,   66,   99,   25,
+    160,   11,  168,    9,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
+     65,   25,   20,   20,    0,   48,   48,   11,  169,   37,    0,    0,    0,    0,    0,    0,
       0,    0,    0,    0,    0,    2,    2,   20,    0,   23,   19,   20,   20,   21,   16,   82,
-    168,   38,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,   10,  169,
-     25,   20,   22,   22,  167,    9,    0,    0,    0,    2,    2,    2,    2,    2,    9,   43,
-    135,   23,   22,   20,   76,   21,   22,    0,    0,    2,    2,    2,    9,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,   18,   19,   20,   21,   22,  105,  168,   37,    0,
+    169,   38,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,   10,  170,
+     25,   20,   22,   22,  168,    9,    0,    0,    0,    2,    2,    2,    2,    2,    9,   43,
+    136,   23,   22,   20,   76,   21,   22,    0,    0,    2,    2,    2,    9,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,   18,   19,   20,   21,   22,  105,  169,   37,    0,
       0,    2,    2,    2,    9,   30,    0,    2,    2,    2,    2,   30,    9,    2,    2,    2,
-      2,   23,   23,   18,   32,   33,   12,  170,  164,  171,  172,    0,    0,    0,    0,    0,
+      2,   23,   23,   18,   32,   33,   12,  171,  165,  172,  173,    0,    0,    0,    0,    0,
       0,    2,    2,    2,    2,    0,    2,    2,    2,   65,   25,   20,   20,    0,   22,   23,
-     29,  108,    0,   33,    0,    0,    0,    0,    0,   52,   20,   22,   22,   22,  139,    2,
-      2,    2,  173,  174,   11,   15,  175,   61,  176,    0,    0,    1,  146,    0,    0,    0,
-      0,   52,   20,   22,   16,   19,   20,    2,    2,    2,    2,  157,  157,  157,  177,  177,
-    177,  177,  177,  177,   15,  178,    0,   30,    0,   22,   20,   20,   31,   22,   22,   11,
-    168,    0,   61,   61,   61,   61,   61,   61,   61,   66,   21,   82,   46,    0,    0,    0,
+     29,  108,    0,   33,    0,    0,    0,    0,    0,   52,   20,   22,   22,   22,  140,    2,
+      2,    2,  174,  175,   11,   15,  176,   61,  177,    0,    0,    1,  147,    0,    0,    0,
+      0,   52,   20,   22,   16,   19,   20,    2,    2,    2,    2,  158,  158,  158,  178,  178,
+    178,  178,  178,  178,   15,  179,    0,   30,    0,   22,   20,   20,   31,   22,   22,   11,
+    169,    0,   61,   61,   61,   61,   61,   61,   61,   66,   21,   82,   46,    0,    0,    0,
       0,    2,    2,    2,    9,    2,   30,    2,    2,   52,   22,   22,   31,    0,   38,   22,
-     27,   11,  158,  179,  180,    0,    0,    0,    0,    2,    2,    2,   30,    9,    2,    2,
+     27,   11,  159,  180,  181,    0,    0,    0,    0,    2,    2,    2,   30,    9,    2,    2,
       2,    2,    2,    2,    2,    2,   23,   23,   47,   22,   35,   82,   68,    0,    0,    0,
-      0,    2,  181,   66,   47,    0,    0,    0,    0,   11,  182,    2,    2,    2,    2,    2,
-      2,    2,    2,   23,   22,   20,   31,    0,   48,   16,  142,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,  155,    0,    0,  183,  183,  183,  183,  183,  183,  183,
-    183,  184,  184,  184,  185,  186,  184,  183,  183,  187,  183,  183,  188,  189,  189,  189,
-    189,  189,  189,  189,    0,    0,    0,    0,    0,  183,  183,  183,  183,  183,  190,    0,
-      0,    2,    2,    2,    2,    2,    2,    2,   22,   22,   22,   22,   22,   22,  191,  192,
-    193,   11,   11,   11,   46,    0,    0,    0,    0,   29,   74,    2,    2,    2,    2,    2,
+      0,    2,  182,   66,   47,    0,    0,    0,    0,   11,  183,    2,    2,    2,    2,    2,
+      2,    2,    2,   23,   22,   20,   31,    0,   48,   16,  143,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,  156,    0,    0,  184,  184,  184,  184,  184,  184,  184,
+    184,  185,  185,  185,  186,  187,  185,  184,  184,  188,  184,  184,  189,  190,  190,  190,
+    190,  190,  190,  190,    0,    0,    0,    0,    0,  184,  184,  184,  184,  184,  191,    0,
+      0,    2,    2,    2,    2,    2,    2,    2,   22,   22,   22,   22,   22,   22,  192,  193,
+    194,   11,   11,   11,   46,    0,    0,    0,    0,   29,   74,    2,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,   65,   47,    0,    2,    2,    2,    2,    2,    9,    0,
-     58,  194,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-     20,   20,   20,   20,   20,    0,    0,    0,   40,  115,   26,    0,    0,    0,    0,    0,
+     58,  195,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+     20,   20,   20,   20,   20,    0,    0,    0,   40,  116,   26,    0,    0,    0,    0,    0,
       0,    0,    0,    9,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-     30,    2,    2,    2,    2,    2,    0,   58,   37,    0,    6,  119,  119,  119,  120,    0,
+     30,    2,    2,    2,    2,    2,    0,   58,   37,    0,    6,  120,  120,  120,  121,    0,
       0,   11,   11,   11,   49,    2,    2,    2,    0,    2,    2,    2,    2,    2,    0,    0,
       2,    2,    2,    2,    2,    2,    2,    2,   46,    2,    2,    2,    2,    2,    2,   11,
      11,    2,    2,    2,    2,    2,    2,   22,   22,    2,    2,    2,    2,    2,    2,    2,
@@ -301,17 +302,18 @@
   FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv,   IS,FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,
   CMAbv,CMAbv,    B,   GB,    B, VAbv,  SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv,
    VPre,    B, MPre, MBlw,  SUB, FAbv, FAbv, MAbv,  SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv,
-   VPst,    H,    B,    O,SMAbv,SMAbv,SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,
-  VMBlw,VMAbv,   CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,   SB,   SE,    O,
-      H, MPst, VPst,    H,VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv,
-   MBlw, MPst, MBlw,    H,    O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,
-      B,    B, VPre,    O,VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,
-      B,VMPst,VMAbv,VMPst,   CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,
-      O, VPst,    B,    R,    R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,VMPst,    O,VMAbv,
-  CMBlw,   IS,    R,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,    H,VMPst, VAbv,VMAbv, VPst, MPst,
-      R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,   CS,  SUB,  SUB,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,
-     IS,    R, MBlw,   GB, VAbv,    R,VMPst,    G,    G,    J,    J,    J,   SB,   SE,    J,   HR,
-      G,    G,   HM,   HM,   HM,    G,    O, MPre, MPre, MPst,VMAbv, MBlw, VBlw,    O, VBlw,
+   VPst,    H,    B,    O,SMAbv,SMAbv,SMAbv, VPst,   IS,   RK,   RK, VBlw, FAbv,VMPre,VMPre,FMAbv,
+  CMBlw,VMBlw,VMBlw,VMAbv,   CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,   SB,
+     SE,    O,    H, MPst, VPst,    H,VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,
+  CMAbv, VAbv, MBlw, MPst, MBlw,    H,    O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv,
+   FPst, VBlw,    B,    B, VPre,    O,VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,
+     IS,VMBlw,    B,VMPst,VMAbv,VMPst,   CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,
+     IS,CMAbv,    O, VPst,    B,    R,    R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,VMPst,
+      O,VMAbv,CMBlw,   IS,    R,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,    H,VMPst, VAbv,VMAbv,
+   VPst, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,   CS,  SUB,  SUB,   GB, FBlw, FBlw,CMAbv,
+     IS, VBlw,   IS,    R, MBlw,   GB, VAbv,    R,VMPst,    G,    G,    J,    J,    J,   SB,   SE,
+      J,   HR,    G,    G,   HM,   HM,   HM,    G,    O, MPre, MPre, MPst,VMAbv, MBlw, VBlw,    O,
+   VBlw,
 };
 static const uint16_t
 hb_use_u16[856] =
@@ -387,7 +389,7 @@
 #else
 
 static const uint8_t
-hb_use_u8[3655] =
+hb_use_u8[3657] =
 {
      16,   50,   51,   51,   51,   52,   51,   83,  118,  131,   57,   58,   59,  195,  211,   62,
      51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
@@ -507,89 +509,89 @@
      48,   48,   22,  108,    2,    2,    2,    9,    0,    0,    0,    0,    0,    0,  109,  110,
     110,  110,  110,    0,    0,    0,    0,    0,    0,  106,   74,    2,    2,    2,    2,    2,
       2,   60,   61,   59,   25,   22,  111,   61,    2,    2,    2,    2,  107,   22,   23,   45,
-     45,  102,   14,    0,    0,    0,    0,    0,    0,    2,    2,   61,   18,   48,   23,  112,
-    102,  102,  102,  113,  114,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   30,
-      2,   11,   46,  115,  115,  115,   11,  115,  115,   15,  115,  115,  115,   26,    0,   40,
-      0,    0,    0,  116,   51,   11,    5,    0,    0,    0,    0,    0,    0,    0,  117,    0,
-      0,    0,    0,    0,    0,    0,    6,  118,  119,   42,   42,    5,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,  119,  119,  120,  119,  119,  119,  119,  119,  119,  119,
-    119,    0,    0,  121,    0,    0,    0,    0,    0,    0,    7,  121,    0,    0,    0,    0,
+     45,  102,  112,    0,    0,    0,    0,    0,    0,    2,    2,   61,   18,   48,   23,  113,
+    102,  102,  102,  114,  115,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   30,
+      2,   11,   46,  116,  116,  116,   11,  116,  116,   15,  116,  116,  116,   26,    0,   40,
+      0,    0,    0,  117,   51,   11,    5,    0,    0,    0,    0,    0,    0,    0,  118,    0,
+      0,    0,    0,    0,    0,    0,    6,  119,  120,   42,   42,    5,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,  120,  120,  121,  120,  120,  120,  120,  120,  120,  120,
+    120,    0,    0,  122,    0,    0,    0,    0,    0,    0,    7,  122,    0,    0,    0,    0,
       0,   46,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    9,
-      0,    0,    0,    0,  122,  122,    0,    0,    0,    2,    2,    2,    2,    0,    0,    0,
-     30,    0,    0,    0,    0,    0,    0,    0,  123,    0,  122,  122,    0,    0,    0,    0,
+      0,    0,    0,    0,  123,  123,    0,    0,    0,    2,    2,    2,    2,    0,    0,    0,
+     30,    0,    0,    0,    0,    0,    0,    0,  124,    0,  123,  123,    0,    0,    0,    0,
       0,    2,   53,    2,  108,    2,   10,    2,    2,    2,   65,   19,   16,    0,    0,   31,
       0,    2,    2,    0,    0,    0,    0,    0,    0,   29,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,  124,   23,   23,   23,   23,   23,   23,   23,  125,    0,    0,    0,    0,
+      2,    2,    2,  125,   23,   23,   23,   23,   23,   23,   23,  126,    0,    0,    0,    0,
       0,   11,   11,   11,   11,   11,   11,   11,   11,   11,    2,    0,    0,    0,    0,    0,
-     52,    2,    2,    2,   22,   22,  126,  115,    0,    2,    2,    2,  127,   20,   59,   20,
-    112,  102,  128,    0,    0,    0,    0,    0,    0,   11,  129,    2,    2,    2,    2,    2,
-      2,    2,  130,   23,   22,   20,   48,  131,  132,  133,    0,    0,    0,    0,    0,    0,
+     52,    2,    2,    2,   22,   22,  127,  116,    0,    2,    2,    2,  128,   20,   59,   20,
+    113,  102,  129,    0,    0,    0,    0,    0,    0,   11,  130,    2,    2,    2,    2,    2,
+      2,    2,  131,   23,   22,   20,   48,  132,  133,  134,    0,    0,    0,    0,    0,    0,
       0,    2,    2,   52,   30,    2,    2,    2,    2,    2,    2,    2,    2,   10,   22,   59,
-     99,   76,  134,  135,  136,    0,    0,    0,    0,    2,  137,    2,    2,    2,    2,  138,
-      0,   30,    2,   42,    5,    0,   79,   15,    2,   53,   22,  139,   52,   53,    2,    2,
-    105,   10,    9,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  140,   21,
-     25,    0,    0,  141,  142,    0,    0,    0,    0,    2,   65,   45,   23,   80,   47,  143,
+     99,   76,  135,  136,  137,    0,    0,    0,    0,    2,  138,    2,    2,    2,    2,  139,
+      0,   30,    2,   42,    5,    0,   79,   15,    2,   53,   22,  140,   52,   53,    2,    2,
+    105,   10,    9,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  141,   21,
+     25,    0,    0,  142,  143,    0,    0,    0,    0,    2,   65,   45,   23,   80,   47,  144,
       0,   81,   81,   81,   81,   81,   81,   81,   81,    0,    0,    0,    0,    0,    0,    0,
-      6,  119,  119,  119,  119,  120,    0,    0,    0,    2,    2,    2,    2,    2,    9,    2,
+      6,  120,  120,  120,  120,  121,    0,    0,    0,    2,    2,    2,    2,    2,    9,    2,
       2,    2,    9,    2,   30,    2,    2,    2,    2,    2,   30,    2,    2,    2,   30,    9,
-      0,  127,   20,   27,   31,    0,    0,  144,  145,    2,    2,   30,    2,   30,    2,    2,
-      2,    2,    2,    2,    0,   14,   37,    0,  146,    2,    2,   13,   37,    0,   30,    2,
+      0,  128,   20,   27,   31,    0,    0,  145,  146,    2,    2,   30,    2,   30,    2,    2,
+      2,    2,    2,    2,    0,   14,   37,    0,  147,    2,    2,   13,   37,    0,   30,    2,
       2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   30,    2,    2,
       9,    2,    2,   11,   41,    0,    0,    0,    0,    2,    2,    2,    0,   27,   22,   22,
      30,    2,    2,    2,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,   27,   38,
-      0,    2,    2,    2,  115,  115,  115,  115,  115,  147,    2,    9,    0,    0,    0,    0,
+      0,    2,    2,    2,  116,  116,  116,  116,  116,  148,    2,    9,    0,    0,    0,    0,
       0,    2,   14,   14,    0,    0,    0,    0,    0,    9,    2,    2,    9,    2,    2,    2,
-      2,   30,    2,    9,    0,   30,    2,    0,    0,  148,  149,  150,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,   22,   22,   20,   20,   20,   22,   22,  133,    0,    0,    0,
-      0,    0,  151,  151,  151,  151,  151,  151,  151,  151,  151,  151,    2,    2,    2,    2,
-      2,   53,   52,   53,    0,    0,    0,    0,  152,   11,   74,    2,    2,    2,    2,    2,
+      2,   30,    2,    9,    0,   30,    2,    0,    0,  149,  150,  151,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,   22,   22,   20,   20,   20,   22,   22,  134,    0,    0,    0,
+      0,    0,  152,  152,  152,  152,  152,  152,  152,  152,  152,  152,    2,    2,    2,    2,
+      2,   53,   52,   53,    0,    0,    0,    0,  153,   11,   74,    2,    2,    2,    2,    2,
       2,   18,   19,   21,   16,   24,   37,    0,    0,    0,   31,    0,    0,    0,    0,    0,
-      0,   11,   49,    2,    2,    2,    2,    2,    2,    2,    2,    2,  127,   20,   22,  153,
-     22,   21,  154,  155,    2,    2,    2,    2,    2,    0,    0,   65,  156,    0,    0,    0,
+      0,   11,   49,    2,    2,    2,    2,    2,    2,    2,    2,    2,  128,   20,   22,  154,
+     22,   21,  155,  156,    2,    2,    2,    2,    2,    0,    0,   65,  157,    0,    0,    0,
       0,    2,   13,    0,    0,    0,    0,    0,    0,    2,   65,   25,   20,   20,   20,   22,
-     22,  108,  157,    0,    0,   56,  158,   31,  159,   30,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,   23,   19,   22,   22,  160,   44,    0,    0,    0,
-     49,  127,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    9,    9,    2,    2,
+     22,  108,  158,    0,    0,   56,  159,   31,  160,   30,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,   23,   19,   22,   22,  161,   44,    0,    0,    0,
+     49,  128,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    9,    9,    2,    2,
      30,    2,    2,    2,    2,    2,    2,    2,   30,    2,    2,    2,    2,    2,    2,    2,
-     10,   18,   19,   21,   22,  161,   31,    0,    0,   11,   11,   30,    2,    2,    2,    9,
+     10,   18,   19,   21,   22,  162,   31,    0,    0,   11,   11,   30,    2,    2,    2,    9,
      30,    9,    2,   30,    2,    2,   58,   17,   23,   16,   23,   47,   32,   33,   32,   34,
       0,    0,    0,    0,   35,    0,    0,    0,    2,    2,   23,    0,   11,   11,   11,   46,
       0,   11,   11,   46,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,   30,    0,
-      9,    2,    2,    2,   30,   45,   59,   20,   20,   31,   33,   32,   32,   25,  162,   29,
-    163,  164,   37,    0,    0,    0,    0,    0,    0,   12,   26,    0,    0,    0,    0,    0,
-      0,    2,    2,   65,   25,   20,   20,   20,   22,   23,  125,   15,   17,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    0,    0,  165,  166,    0,    0,    0,    0,    0,    0,
-      0,   18,   19,   20,   20,   66,   99,   25,  159,   11,  167,    9,    0,    0,    0,    0,
+      9,    2,    2,    2,   30,   45,   59,   20,   20,   31,   33,   32,   32,   25,  163,   29,
+    164,  165,   37,    0,    0,    0,    0,    0,    0,   12,   26,    0,    0,    0,    0,    0,
+      0,    2,    2,   65,   25,   20,   20,   20,   22,   23,  126,   15,   17,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    0,    0,  166,  167,    0,    0,    0,    0,    0,    0,
+      0,   18,   19,   20,   20,   66,   99,   25,  160,   11,  168,    9,    0,    0,    0,    0,
       0,    2,    2,    2,    2,    2,    2,    2,   65,   25,   20,   20,    0,   48,   48,   11,
-    168,   37,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,    2,   20,
-      0,   23,   19,   20,   20,   21,   16,   82,  168,   38,    0,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,   10,  169,   25,   20,   22,   22,  167,    9,    0,    0,
-      0,    2,    2,    2,    2,    2,    9,   43,  135,   23,   22,   20,   76,   21,   22,    0,
+    169,   37,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,    2,   20,
+      0,   23,   19,   20,   20,   21,   16,   82,  169,   38,    0,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,   10,  170,   25,   20,   22,   22,  168,    9,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,   43,  136,   23,   22,   20,   76,   21,   22,    0,
       0,    2,    2,    2,    9,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,   18,
-     19,   20,   21,   22,  105,  168,   37,    0,    0,    2,    2,    2,    9,   30,    0,    2,
-      2,    2,    2,   30,    9,    2,    2,    2,    2,   23,   23,   18,   32,   33,   12,  170,
-    164,  171,  172,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    0,    2,    2,
+     19,   20,   21,   22,  105,  169,   37,    0,    0,    2,    2,    2,    9,   30,    0,    2,
+      2,    2,    2,   30,    9,    2,    2,    2,    2,   23,   23,   18,   32,   33,   12,  171,
+    165,  172,  173,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    0,    2,    2,
       2,   65,   25,   20,   20,    0,   22,   23,   29,  108,    0,   33,    0,    0,    0,    0,
-      0,   52,   20,   22,   22,   22,  139,    2,    2,    2,  173,  174,   11,   15,  175,   61,
-    176,    0,    0,    1,  146,    0,    0,    0,    0,   52,   20,   22,   16,   19,   20,    2,
-      2,    2,    2,  157,  157,  157,  177,  177,  177,  177,  177,  177,   15,  178,    0,   30,
-      0,   22,   20,   20,   31,   22,   22,   11,  168,    0,   61,   61,   61,   61,   61,   61,
+      0,   52,   20,   22,   22,   22,  140,    2,    2,    2,  174,  175,   11,   15,  176,   61,
+    177,    0,    0,    1,  147,    0,    0,    0,    0,   52,   20,   22,   16,   19,   20,    2,
+      2,    2,    2,  158,  158,  158,  178,  178,  178,  178,  178,  178,   15,  179,    0,   30,
+      0,   22,   20,   20,   31,   22,   22,   11,  169,    0,   61,   61,   61,   61,   61,   61,
      61,   66,   21,   82,   46,    0,    0,    0,    0,    2,    2,    2,    9,    2,   30,    2,
-      2,   52,   22,   22,   31,    0,   38,   22,   27,   11,  158,  179,  180,    0,    0,    0,
+      2,   52,   22,   22,   31,    0,   38,   22,   27,   11,  159,  180,  181,    0,    0,    0,
       0,    2,    2,    2,   30,    9,    2,    2,    2,    2,    2,    2,    2,    2,   23,   23,
-     47,   22,   35,   82,   68,    0,    0,    0,    0,    2,  181,   66,   47,    0,    0,    0,
-      0,   11,  182,    2,    2,    2,    2,    2,    2,    2,    2,   23,   22,   20,   31,    0,
-     48,   16,  142,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  155,    0,
-      0,  183,  183,  183,  183,  183,  183,  183,  183,  184,  184,  184,  185,  186,  184,  183,
-    183,  187,  183,  183,  188,  189,  189,  189,  189,  189,  189,  189,    0,    0,    0,    0,
-      0,  183,  183,  183,  183,  183,  190,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-     22,   22,   22,   22,   22,   22,  191,  192,  193,   11,   11,   11,   46,    0,    0,    0,
+     47,   22,   35,   82,   68,    0,    0,    0,    0,    2,  182,   66,   47,    0,    0,    0,
+      0,   11,  183,    2,    2,    2,    2,    2,    2,    2,    2,   23,   22,   20,   31,    0,
+     48,   16,  143,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  156,    0,
+      0,  184,  184,  184,  184,  184,  184,  184,  184,  185,  185,  185,  186,  187,  185,  184,
+    184,  188,  184,  184,  189,  190,  190,  190,  190,  190,  190,  190,    0,    0,    0,    0,
+      0,  184,  184,  184,  184,  184,  191,    0,    0,    2,    2,    2,    2,    2,    2,    2,
+     22,   22,   22,   22,   22,   22,  192,  193,  194,   11,   11,   11,   46,    0,    0,    0,
       0,   29,   74,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   65,   47,
-      0,    2,    2,    2,    2,    2,    9,    0,   58,  194,   20,   20,   20,   20,   20,   20,
+      0,    2,    2,    2,    2,    2,    9,    0,   58,  195,   20,   20,   20,   20,   20,   20,
      20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,    0,    0,    0,
-     40,  115,   26,    0,    0,    0,    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,
+     40,  116,   26,    0,    0,    0,    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,
       0,    0,    0,    0,    0,    0,    0,    0,   30,    2,    2,    2,    2,    2,    0,   58,
-     37,    0,    6,  119,  119,  119,  120,    0,    0,   11,   11,   11,   49,    2,    2,    2,
+     37,    0,    6,  120,  120,  120,  121,    0,    0,   11,   11,   11,   49,    2,    2,    2,
       0,    2,    2,    2,    2,    2,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,
      46,    2,    2,    2,    2,    2,    2,   11,   11,    2,    2,    2,    2,    2,    2,   22,
      22,    2,    2,    2,    2,    2,    2,    2,   20,    2,    2,   44,   44,   44,   92,    0,
@@ -607,17 +609,17 @@
   FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,CMAbv,CMAbv,    B,   GB,    B, VAbv,  SUB, FPst,
    FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre,    B, MPre, MBlw,  SUB, FAbv, FAbv, MAbv,
     SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst,    H,    B,    O,SMAbv,SMAbv,SMAbv, VPst,
-     IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,   CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,
-     WJ,   WJ,    O,FMPst,    O,   SB,   SE,    O,    H, MPst, VPst,    H,VMAbv, VAbv,VMBlw,    B,
-   VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,    O, VBlw, MPst, MPre,
-   MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,VMPst,   IS,    O,VMPst,
-   VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,   CS,   CS,    B,    N,
-      N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,    R,CMBlw, VAbv, VPre,
-  VMAbv,VMAbv,    H, VAbv,CMBlw,VMPst,    O,VMAbv,CMBlw,   IS,    R,FMAbv,    B,   CS,   CS,    H,
-  CMBlw,VMPst,    H,VMPst, VAbv,VMAbv, VPst, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,   CS,
-    SUB,  SUB,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,    R, MBlw,   GB, VAbv,    R,VMPst,    G,
-      G,    J,    J,    J,   SB,   SE,    J,   HR,    G,    G,   HM,   HM,   HM,    G,    O, MPre,
-   MPre, MPst,VMAbv, MBlw, VBlw,    O, VBlw,
+     IS,   RK,   RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,   CS,    O,FMAbv, ZWNJ,
+    CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,   SB,   SE,    O,    H, MPst, VPst,    H,VMAbv, VAbv,
+  VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,    O, VBlw,
+   MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,VMPst,   IS,
+      O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,   CS,   CS,
+      B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,    R,CMBlw,
+   VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,VMPst,    O,VMAbv,CMBlw,   IS,    R,FMAbv,    B,   CS,
+     CS,    H,CMBlw,VMPst,    H,VMPst, VAbv,VMAbv, VPst, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,
+  VMAbv,   CS,  SUB,  SUB,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,    R, MBlw,   GB, VAbv,    R,
+  VMPst,    G,    G,    J,    J,    J,   SB,   SE,    J,   HR,    G,    G,   HM,   HM,   HM,    G,
+      O, MPre, MPre, MPst,VMAbv, MBlw, VBlw,    O, VBlw,
 };
 static const uint16_t
 hb_use_u16[486] =
@@ -683,6 +685,7 @@
 #undef N
 #undef O
 #undef R
+#undef RK
 #undef SB
 #undef SE
 #undef SUB

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -6,8 +6,8 @@
  *
  * on files with these headers:
  *
- * <meta name="updated_at" content="2024-05-31 05:41 PM" />
- * File-Date: 2024-05-16
+ * <meta name="updated_at" content="2024-07-07 12:57 AM" />
+ * File-Date: 2024-06-14
  */
 
 #ifndef HB_OT_TAG_TABLE_HH

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh	2024-11-06 04:18:33 UTC (rev 72778)
@@ -34,9 +34,6 @@
 #include "hb.hh"
 
 
-// Hack. See: https://github.com/harfbuzz/harfbuzz/pull/4529#discussion_r1769638033
-#define _HB_UNICODE_GENERAL_CATEGORY_VARIATION_SELECTOR ((hb_unicode_general_category_t) 30)
-
 extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256];
 
 /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2024-11-06 04:18:33 UTC (rev 72778)
@@ -217,7 +217,7 @@
       {
 	hb_font_extents_t font_extents;
 	hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
-	hb_glyph_extents_t extents = {0};
+	hb_glyph_extents_t extents = {0, 0, 0, 0};
 	if (!hb_font_get_glyph_extents (font, gid, &extents))
 	{
 	  printf ("Skip gid: %u\n", gid);
@@ -267,7 +267,7 @@
   {
     hb_font_extents_t font_extents;
     hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
-    hb_glyph_extents_t extents = {0};
+    hb_glyph_extents_t extents = {0, 0, 0, 0};
     if (!hb_font_get_glyph_extents (font, gid, &extents))
     {
       printf ("Skip gid: %u\n", gid);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2024-11-06 04:18:33 UTC (rev 72778)
@@ -346,7 +346,7 @@
 
 # System-dependent sources and headers
 
-hb_coretext_sources = files('hb-coretext.cc')
+hb_coretext_sources = files('hb-coretext-shape.cc', 'hb-coretext-font.cc')
 hb_coretext_headers = files('hb-coretext.h')
 
 hb_directwrite_sources = files('hb-directwrite.cc')

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/ms-use/IndicPositionalCategory-Additional.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/ms-use/IndicPositionalCategory-Additional.txt	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/ms-use/IndicPositionalCategory-Additional.txt	2024-11-06 04:18:33 UTC (rev 72778)
@@ -77,11 +77,12 @@
 10F83         ; Bottom # Mn       OLD UYGHUR COMBINING DOT BELOW
 10F84         ; Bottom # Mn       OLD UYGHUR COMBINING TWO DOTS ABOVE # Overriden, ccc controls order
 10F85         ; Bottom # Mn       OLD UYGHUR COMBINING TWO DOTS BELOW
+113CF         ; Bottom # Mc       TULU-TIGALARI SIGN LOOPED VIRAMA    # Issue #17
 16F4F         ; Bottom # Mn       MIAO SIGN CONSONANT MODIFIER BAR
 16F51..16F87  ; Bottom # Mc  [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI
 16F8F..16F92  ; Bottom # Mn   [4] MIAO TONE RIGHT..MIAO TONE BELOW
-1E5EE         ; Bottom  # Mn       OL ONAL SIGN MU # Not really below, but need to override to fit into Universal model
-1E5EF         ; Bottom  # Mn       OL ONAL SIGN IKIR
+1E5EE         ; Bottom # Mn       OL ONAL SIGN MU # Not really below, but need to override to fit into Universal model
+1E5EF         ; Bottom # Mn       OL ONAL SIGN IKIR
 
 # ================================================
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/ms-use/IndicSyllabicCategory-Additional.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/ms-use/IndicSyllabicCategory-Additional.txt	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/ms-use/IndicSyllabicCategory-Additional.txt	2024-11-06 04:18:33 UTC (rev 72778)
@@ -54,7 +54,6 @@
 
 # Indic_Syllabic_Category=Nukta   
 0F71          ; Nukta            # Mn       TIBETAN VOWEL SIGN AA # Reassigned to get this before an above vowel, but see #22
-1BF2..1BF3    ; Nukta            # Mc   [2] BATAK PANGOLAT..BATAK PANONGONAN # see USE issue #20
 113CF         ; Nukta            # Mc       TULU-TIGALARI SIGN LOOPED VIRAMA
 
 # ================================================

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2024-11-06 00:41:48 UTC (rev 72777)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2024-11-06 04:18:33 UTC (rev 72778)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [10.0.1])
+m4_define([harfbuzz_version], [10.1.0])



More information about the tex-live-commits mailing list.