texlive[60943] Build/source/libs: harfbuzz 3.1.0

commits+kakuto at tug.org commits+kakuto at tug.org
Thu Nov 4 01:51:18 CET 2021


Revision: 60943
          http://tug.org/svn/texlive?view=revision&revision=60943
Author:   kakuto
Date:     2021-11-04 01:51:18 +0100 (Thu, 04 Nov 2021)
Log Message:
-----------
harfbuzz 3.1.0

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/harfbuzz/ChangeLog
    trunk/Build/source/libs/harfbuzz/Makefile.am
    trunk/Build/source/libs/harfbuzz/Makefile.in
    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/CMakeLists.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-hb-version.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-bsln-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dispatch.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc
    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.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/README	2021-11-04 00:51:18 UTC (rev 60943)
@@ -26,8 +26,8 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 3.0.0 - checked 18sep21
-  https://github.com/harfbuzz/harfbuzz/releases/download/3.0.0/
+harfbuzz 3.1.0 - checked 04nov21
+  https://github.com/harfbuzz/harfbuzz/releases/download/3.1.0/
 
 icu 68.2 - checked 13feb21
   http://download.icu-project.org/files/icu4c/

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,3 +1,8 @@
+2021-11-04  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Import harfbuzz-3.1.0.
+	* Makefile.am, version.ac: Adjusted.
+
 2021-09-18  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Import harfbuzz-3.0.0.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2021-11-04 00:51:18 UTC (rev 60943)
@@ -110,6 +110,7 @@
 	@HARFBUZZ_TREE@/src/hb-ot-post-table-v2subset.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-tag.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-tag-table.hh \
+	@HARFBUZZ_TREE@/src/hb-ot-var-common.hh \
 	@HARFBUZZ_TREE@/src/hb-sanitize.hh \
 	@HARFBUZZ_TREE@/src/hb-serialize.hh \
 	@HARFBUZZ_TREE@/src/hb-set-digest.hh \

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2021-11-04 00:51:18 UTC (rev 60943)
@@ -785,6 +785,7 @@
 	@HARFBUZZ_TREE@/src/hb-ot-post-table-v2subset.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-tag.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-tag-table.hh \
+	@HARFBUZZ_TREE@/src/hb-ot-var-common.hh \
 	@HARFBUZZ_TREE@/src/hb-sanitize.hh \
 	@HARFBUZZ_TREE@/src/hb-serialize.hh \
 	@HARFBUZZ_TREE@/src/hb-set-digest.hh \

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,3 +1,8 @@
+2021-11-04  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Imported harfbuzz-3.1.0 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/3.1.0/
+
 2021-09-18  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Imported harfbuzz-3.0.0 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-3.0.0/ tree as obtained from:
-	https://github.com/harfbuzz/harfbuzz/releases/download/3.0.0/
+Changes applied to the harfbuzz-3.1.0/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/3.1.0/
 
 Removed:
 	COPYING

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/configure	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 3.0.0.
+# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 3.1.0.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -611,8 +611,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='3.0.0'
-PACKAGE_STRING='harfbuzz (TeX Live) 3.0.0'
+PACKAGE_VERSION='3.1.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 3.1.0'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1346,7 +1346,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) 3.0.0 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 3.1.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1418,7 +1418,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 3.0.0:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 3.1.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1523,7 +1523,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 3.0.0
+harfbuzz (TeX Live) configure 3.1.0
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2064,7 +2064,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 3.0.0, which was
+It was created by harfbuzz (TeX Live) $as_me 3.1.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4823,7 +4823,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='3.0.0'
+ VERSION='3.1.0'
 
 
 # Some tools Automake needs.
@@ -5034,9 +5034,9 @@
 
 
 HB_VERSION_MAJOR=3
-HB_VERSION_MINOR=0
+HB_VERSION_MINOR=1
 HB_VERSION_MICRO=0
-HB_VERSION=3.0.0
+HB_VERSION=3.1.0
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8818,7 +8818,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 3.0.0, which was
+This file was extended by harfbuzz (TeX Live) $as_me 3.1.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8886,7 +8886,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 3.0.0
+harfbuzz (TeX Live) config.status 3.1.0
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2021-11-04 00:51:18 UTC (rev 60943)
@@ -437,6 +437,7 @@
 ## Define harfbuzz-subset library
 if (HB_BUILD_SUBSET)
   add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-subset.h)
   add_dependencies(harfbuzz-subset harfbuzz)
   target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
 
@@ -702,6 +703,11 @@
       FRAMEWORK DESTINATION Library/Frameworks
     )
   endif ()
+  if (HB_BUILD_SUBSET)
+    install(TARGETS harfbuzz-subset
+      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+  endif ()
   if (HB_BUILD_UTILS)
     if (WIN32 AND BUILD_SHARED_LIBS)
       install(TARGETS harfbuzz-subset

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,3 +1,1795 @@
+commit 77eeec53a917554a2766a7cb1687607841282777
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Nov 3 23:31:03 2021 +0200
+
+    3.1.0
+
+ NEWS                   | 21 +++++++++++++++++++++
+ configure.ac           |  2 +-
+ docs/harfbuzz-docs.xml |  1 +
+ meson.build            |  2 +-
+ src/hb-buffer.cc       |  4 ++--
+ src/hb-version.h       |  4 ++--
+ 6 files changed, 28 insertions(+), 6 deletions(-)
+
+commit 54e7d6267b485f252cf3f266a4577c72d79b286b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 3 14:43:34 2021 -0600
+
+    [array] Remove defaulted destructor
+
+ src/hb-array.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit f51b48c8e780ca918535c7af670818f2166ccf64
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Nov 2 16:16:52 2021 -0700
+
+    [subset] Fix fuzzer found memory leak.
+    
+    Happens because an insert into a map with an invalid key reports successful, but this causes the set being inserted to be lost.
+
+ src/hb-ot-layout-gsubgpos.hh                           |  17 +++++++++--------
+ .../leak-34f1798a142fd0dfdd71a96fb6aa7de19a62865e      | Bin 0 -> 134 bytes
+ 2 files changed, 9 insertions(+), 8 deletions(-)
+
+commit b1cd0dce8ed2fff2b781dfb432777db7de5f3f80
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 17:56:11 2021 -0600
+
+    [map] Add INVALID_KEY and INVALID_VALUE
+
+ src/hb-map.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 540f19b6fe0de39312bc3f881be16e76dd902c33
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Oct 29 17:11:53 2021 -0700
+
+    [subset] fix bug in (Chain)ContextFormat2
+    
+    Only keep rulesets for glyphs class numbers that survived in coverage
+
+ src/hb-ot-layout-common.hh                         |  53 ++++++++++++++++++++-
+ src/hb-ot-layout-gsubgpos.hh                       |  46 ++++++++++++++----
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ ...lar.layout-test-retain-gids.268,301,302,324.ttf | Bin 0 -> 6312 bytes
+ ...ayout-test-retain-gids.retain-all-codepoint.ttf | Bin 0 -> 60976 bytes
+ ...Molengo-Regular.layout-test.268,301,302,324.ttf | Bin 0 -> 4124 bytes
+ ...go-Regular.layout-test.retain-all-codepoint.ttf | Bin 0 -> 60972 bytes
+ test/subset/data/fonts/Molengo-Regular.ttf         | Bin 0 -> 65464 bytes
+ test/subset/data/tests/layout.gsub5_format2.tests  |  10 ++++
+ test/subset/meson.build                            |   1 +
+ 11 files changed, 103 insertions(+), 9 deletions(-)
+
+commit e260eeb9be0402d645917cadc8634ddf8c0e2743
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Nov 2 15:31:32 2021 -0700
+
+    [subset] Update test goldens for gdef.glyphset.
+
+ ...Howrah-Regular.default.retain-all-codepoint.ttf | Bin 174040 -> 174308 bytes
+ ...rah-Regular.drop-hints.retain-all-codepoint.ttf | Bin 99020 -> 99288 bytes
+ ...ah-Regular.retain-gids.retain-all-codepoint.ttf | Bin 174340 -> 174608 bytes
+ 3 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 60e203644b7aa2098bce9ddae7741ba037500d2c
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Nov 2 15:02:36 2021 -0700
+
+    [subset] use glyphset_gsub instead of glyphset for GDEF
+
+ src/hb-ot-layout-gdef-table.hh                         |   4 ++--
+ test/subset/data/Makefile.am                           |   1 +
+ test/subset/data/Makefile.sources                      |   1 +
+ .../IndicTestHowrah-Regular.default.9dd.ttf            | Bin 0 -> 4152 bytes
+ ...TestHowrah-Regular.default.retain-all-codepoint.ttf | Bin 0 -> 174040 bytes
+ .../IndicTestHowrah-Regular.drop-hints.9dd.ttf         | Bin 0 -> 1128 bytes
+ ...tHowrah-Regular.drop-hints.retain-all-codepoint.ttf | Bin 0 -> 99020 bytes
+ .../IndicTestHowrah-Regular.retain-gids.9dd.ttf        | Bin 0 -> 4540 bytes
+ ...Howrah-Regular.retain-gids.retain-all-codepoint.ttf | Bin 0 -> 174340 bytes
+ test/subset/data/fonts/IndicTestHowrah-Regular.ttf     | Bin 0 -> 186128 bytes
+ test/subset/data/tests/layout.gdef.glyphset.tests      |  11 +++++++++++
+ test/subset/meson.build                                |   1 +
+ 12 files changed, 16 insertions(+), 2 deletions(-)
+
+commit e39647c0f14102928ed787c2d38213f5b6cf576d
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Nov 2 15:25:05 2021 -0700
+
+    [subset] update subset goldens to fix tests.
+
+ ...wLatin-Regular.default.retain-all-codepoint.ttf | Bin 131672 -> 131672 bytes
+ ...in-Regular.layout-test.retain-all-codepoint.ttf | Bin 153648 -> 153648 bytes
+ ...in-Regular.retain-gids.retain-all-codepoint.ttf | Bin 134776 -> 134776 bytes
+ 3 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 0a7563a53ffedd735cb41c03f697269ef48f0ec2
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Nov 1 14:56:14 2021 -0700
+
+    [subset] fuzzer fix: https://oss-fuzz.com/testcase?key=6254792024915968
+    
+    Make sure input is valid, each gid has a corresponding offset value in
+    the map
+
+ src/hb-ot-color-colr-table.hh                           |   5 ++++-
+ ...testcase-minimized-hb-subset-fuzzer-6254792024915968 | Bin 0 -> 20851 bytes
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit 364b6b3989e9df6335711e282e3250534d88299a
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Sun Oct 31 14:38:20 2021 -0700
+
+    [subset] Don't assume FeatureList is sorted
+    
+    Though the spec said FeatureRecords are sorted alphabetically by feature
+    tag, there're font files with unsorted FeatureList. And harfbuzz is not
+    able to subset these files correctly because we use binary search in
+    finding featureRecords when collecting lookups. Also
+    find_duplicate_features needs to be updated to handle this.
+
+ src/hb-ot-layout-gsubgpos.hh                       |  28 +++++++++++++++------
+ src/hb-ot-layout.cc                                |  21 +++++-----------
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ ...HebrewLatin-Regular.default.392,3a7,3b2,3c7.ttf | Bin 0 -> 2464 bytes
+ ...wLatin-Regular.default.retain-all-codepoint.ttf | Bin 0 -> 131672 bytes
+ ...ewLatin-Regular.layout-test.392,3a7,3b2,3c7.ttf | Bin 0 -> 2588 bytes
+ ...in-Regular.layout-test.retain-all-codepoint.ttf | Bin 0 -> 153648 bytes
+ ...ewLatin-Regular.retain-gids.392,3a7,3b2,3c7.ttf | Bin 0 -> 13484 bytes
+ ...in-Regular.retain-gids.retain-all-codepoint.ttf | Bin 0 -> 134776 bytes
+ .../data/fonts/NotoIKEAHebrewLatin-Regular.ttf     | Bin 0 -> 212524 bytes
+ .../data/tests/layout.unsorted_featurelist.tests   |  11 ++++++++
+ test/subset/meson.build                            |   1 +
+ 13 files changed, 40 insertions(+), 23 deletions(-)
+
+commit 49c9392412ccf31cf948310acda057b96eb6afc6
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Sep 24 09:28:10 2021 -0700
+
+    [subset] During LigatureSubstFormat1 subsetting always place Coverage last.
+    
+    In Windows 7 on Chrome if the coverage table comes before any of the LigatureSet or Ligature subtables the font won't load. This changes the packing order to always place the Coverage table last. Virtual links are used to ensure the repacker maintains the desired ordering.
+    
+    Coincidentally fontTools also does the same thing (https://github.com/fonttools/fonttools/blob/a3f988fbf621142d7d9b3e68a69725b88f358869/Lib/fontTools/ttLib/tables/otTables.py#L1137) to reduce overflows during packing.
+
+ src/hb-ot-layout-gsub-table.hh                     |  48 +++++++++++++++++----
+ ...aa-Regular-new.default.retain-all-codepoint.ttf | Bin 222756 -> 222756 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 191632 -> 191632 bytes
+ ...Regular-new.drop-hints.retain-all-codepoint.ttf | Bin 191584 -> 191584 bytes
+ ...ortaa-Regular-new.gids.retain-all-codepoint.ttf | Bin 222756 -> 222756 bytes
+ ...egular-new.glyph-names.retain-all-codepoint.ttf | Bin 229748 -> 229748 bytes
+ ...ep-all-layout-features.retain-all-codepoint.ttf | Bin 223452 -> 223452 bytes
+ ...ar-new.layout-features.retain-all-codepoint.ttf | Bin 220948 -> 220948 bytes
+ ...a-Regular-new.name-ids.retain-all-codepoint.ttf | Bin 222496 -> 222496 bytes
+ ...lar-new.name-languages.retain-all-codepoint.ttf | Bin 222756 -> 222756 bytes
+ ...egular-new.name-legacy.retain-all-codepoint.ttf | Bin 222756 -> 222756 bytes
+ ...o-prune-unicode-ranges.retain-all-codepoint.ttf | Bin 222756 -> 222756 bytes
+ ...lar-new.notdef-outline.retain-all-codepoint.ttf | Bin 223352 -> 223352 bytes
+ ...egular-new.retain-gids.retain-all-codepoint.ttf | Bin 222804 -> 222804 bytes
+ ...tu-Regular.glyph-names.retain-all-codepoint.ttf | Bin 281092 -> 281092 bytes
+ ...ns-BlackItalic.default.retain-all-codepoint.ttf | Bin 120236 -> 120236 bytes
+ ...lackItalic.glyph-names.retain-all-codepoint.ttf | Bin 132480 -> 132480 bytes
+ ...kItalic.notdef-outline.retain-all-codepoint.ttf | Bin 120236 -> 120236 bytes
+ ...andhar-Regular.default.retain-all-codepoint.ttf | Bin 49248 -> 49248 bytes
+ ...har-Regular.drop-hints.retain-all-codepoint.ttf | Bin 29468 -> 29468 bytes
+ ...dhar-Regular.keep-gdef.retain-all-codepoint.ttf | Bin 49248 -> 49248 bytes
+ ...ayout-test-retain-gids.retain-all-codepoint.otf | Bin 4064 -> 4064 bytes
+ ...pos5_font1.layout-test.retain-all-codepoint.otf | Bin 4064 -> 4064 bytes
+ ...ayout-test-retain-gids.retain-all-codepoint.otf | Bin 4008 -> 4008 bytes
+ ...cessive_f1.layout-test.retain-all-codepoint.otf | Bin 4008 -> 4008 bytes
+ ...Bold.default.627,644,623,62D,644,627,645,2E.ttf | Bin 11372 -> 11372 bytes
+ ...toNastaliqUrdu-Bold.default.627,644,62D,628.ttf | Bin 17640 -> 17732 bytes
+ .../NotoNastaliqUrdu-Bold.default.627,644.ttf      | Bin 3512 -> 3512 bytes
+ ...rdu-Bold.default.633,645,627,621,20,644,627.ttf | Bin 12360 -> 12360 bytes
+ .../NotoNastaliqUrdu-Bold.default.63A,64A,631.ttf  | Bin 19340 -> 19432 bytes
+ ....retain-gids.627,644,623,62D,644,627,645,2E.ttf | Bin 18208 -> 18208 bytes
+ ...staliqUrdu-Bold.retain-gids.627,644,62D,628.ttf | Bin 23704 -> 23792 bytes
+ .../NotoNastaliqUrdu-Bold.retain-gids.627,644.ttf  | Bin 9160 -> 9160 bytes
+ ...Bold.retain-gids.633,645,627,621,20,644,627.ttf | Bin 18164 -> 18164 bytes
+ ...toNastaliqUrdu-Bold.retain-gids.63A,64A,631.ttf | Bin 25392 -> 25484 bytes
+ .../Tinos-Italic.default.retain-all-codepoint.ttf  | Bin 412764 -> 412764 bytes
+ ...nos-Italic.glyph-names.retain-all-codepoint.ttf | Bin 437592 -> 437592 bytes
+ ...-Italic.notdef-outline.retain-all-codepoint.ttf | Bin 412764 -> 412764 bytes
+ ...nos-Italic.retain-gids.retain-all-codepoint.ttf | Bin 415140 -> 415140 bytes
+ ...woMath-Regular.default.retain-all-codepoint.ttf | Bin 1038580 -> 1038580 bytes
+ ...th-Regular.glyph-names.retain-all-codepoint.ttf | Bin 1091356 -> 1091356 bytes
+ ...Regular.notdef-outline.retain-all-codepoint.ttf | Bin 1038828 -> 1038828 bytes
+ ...th-Regular.retain-gids.retain-all-codepoint.ttf | Bin 1053656 -> 1053656 bytes
+ .../variable/Fraunces.default.26,66,69,124,125.ttf | Bin 15856 -> 15856 bytes
+ 44 files changed, 39 insertions(+), 9 deletions(-)
+
+commit 9643d77086b1d0896cb4703f48b71743044880bf
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Sep 24 11:39:59 2021 -0700
+
+    [repacker] add more detailed comment about virtual links.
+
+ src/hb-serialize.hh | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+commit 5bfc7d101562a188fb283fd679a7ba55acc4042c
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 23 14:45:20 2021 -0700
+
+    [repacker] remove VirtualOffset struct.
+    
+    Make and add_virtual_link () specialization of add_link() instead.
+
+ src/hb-serialize.hh  | 9 +--------
+ src/test-repacker.cc | 3 +--
+ 2 files changed, 2 insertions(+), 10 deletions(-)
+
+commit bc4c5341d6e5725a6ad231eba3a7a6f2ba606ce9
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 23 14:41:42 2021 -0700
+
+    [repacker] Add test for virtual links in the repacker.
+
+ src/hb-serialize.hh  | 24 +++++++++++++++++++++
+ src/test-repacker.cc | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 84 insertions(+)
+
+commit 7615b94ecf483aa275220409d3c385089a74a09d
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 23 14:14:06 2021 -0700
+
+    [repacker] add 'virtual links' to the serializer.
+    
+    These aren't associated with an offset field, but instead exist solely to add an ordering constraint to the object graph.
+
+ src/hb-repacker.hh  | 10 +++++++++-
+ src/hb-serialize.hh | 21 ++++++++++++++++++++-
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+
+commit 59d8f6c8173a9054b2594f38c06d9aa635da04c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 10:33:53 2021 -0600
+
+    [map] Fix copy assignment operator
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit bbda020cbc99d6a956f21a7fb05bf721fa0f2faf
+Merge: 8dc86d070 459e485ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 08:40:59 2021 -0700
+
+    Merge pull request #3278 from harfbuzz/more-std
+    
+    More standard idioms
+
+commit 459e485babea657e47930e74bd56280658811af2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 09:36:12 2021 -0600
+
+    [meta] Remove otherwise-empty test-meta
+
+ src/Makefile.am  |  5 ----
+ src/meson.build  |  1 -
+ src/test-meta.cc | 87 --------------------------------------------------------
+ 3 files changed, 93 deletions(-)
+
+commit b8724c60232a97d1e1785c3c618a340089be9c8a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 00:49:40 2021 -0600
+
+    [meta] Add in-house impl of hb_is_convertible()
+
+ src/hb-meta.hh   | 26 +-------------------------
+ src/test-meta.cc | 14 --------------
+ 2 files changed, 1 insertion(+), 39 deletions(-)
+
+commit 7a078c395a57097a2ae204c0089f47a9ac97d849
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 00:44:51 2021 -0600
+
+    [meta] Use std::conditional instead of hb_conditional()
+
+ src/hb-meta.hh      | 13 ++-----------
+ src/hb-open-type.hh |  2 +-
+ 2 files changed, 3 insertions(+), 12 deletions(-)
+
+commit 943921cf0caefa564601f7b18eed2168be77cfda
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 00:26:46 2021 -0600
+
+    [meta] Use more std type_traits
+
+ src/hb-algs.hh      |  6 +++---
+ src/hb-map.hh       |  8 ++++----
+ src/hb-meta.hh      | 44 --------------------------------------------
+ src/hb-open-type.hh |  4 ++--
+ src/hb-serialize.hh |  2 +-
+ src/test-meta.cc    |  3 ---
+ 6 files changed, 10 insertions(+), 57 deletions(-)
+
+commit 6d555ce82e50bdd54896a89d9d547493b466b116
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 00:18:22 2021 -0600
+
+    [meta] Use std::forward instead of hb_forward()
+
+ src/hb-aat-layout-common.hh     |  2 +-
+ src/hb-aat-layout-kerx-table.hh | 10 +++---
+ src/hb-aat-layout-morx-table.hh | 10 +++---
+ src/hb-algs.hh                  | 80 ++++++++++++++++++++---------------------
+ src/hb-debug.hh                 |  8 ++---
+ src/hb-dispatch.hh              |  2 +-
+ src/hb-iter.hh                  | 14 ++++----
+ src/hb-meta.hh                  | 10 ++----
+ src/hb-open-type.hh             | 22 ++++++------
+ src/hb-ot-cff-common.hh         |  2 +-
+ src/hb-ot-color-colr-table.hh   | 68 +++++++++++++++++------------------
+ src/hb-ot-kern-table.hh         |  8 ++---
+ src/hb-ot-layout-common.hh      |  4 +--
+ src/hb-ot-layout-gdef-table.hh  |  6 ++--
+ src/hb-ot-layout-gpos-table.hh  | 36 +++++++++----------
+ src/hb-ot-layout-gsub-table.hh  | 30 ++++++++--------
+ src/hb-ot-layout-gsubgpos.hh    | 16 ++++-----
+ src/hb-ot-layout.cc             |  4 +--
+ src/hb-sanitize.hh              |  6 ++--
+ src/hb-serialize.hh             | 16 ++++-----
+ src/hb-subset.hh                |  6 ++--
+ src/hb-vector.hh                |  4 +--
+ 22 files changed, 179 insertions(+), 185 deletions(-)
+
+commit 811f80a701a7e40d8ef2e01b927da74015aa6113
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 00:14:34 2021 -0600
+
+    [algs] Use std::move instead of hb_move()
+
+ src/hb-map.hh    | 4 ++--
+ src/hb-meta.hh   | 6 ++----
+ src/hb-set.hh    | 2 +-
+ src/hb-vector.hh | 2 +-
+ 4 files changed, 6 insertions(+), 8 deletions(-)
+
+commit 896e0c74a82eb65f80d284a5d4f6557960de2620
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 00:06:30 2021 -0600
+
+    [meta] Remove unused traits
+
+ src/hb-meta.hh   | 46 ----------------------------------------------
+ src/test-meta.cc | 13 -------------
+ 2 files changed, 59 deletions(-)
+
+commit be42800fc6d90340f843fa03be1bb06b0453e519
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 2 00:04:18 2021 -0600
+
+    [meta] Use std::is_trivially_... instead of internal copies
+
+ src/hb-meta.hh      | 58 ++---------------------------------------------------
+ src/hb-open-type.hh | 10 ++++-----
+ src/test-meta.cc    | 16 ---------------
+ 3 files changed, 7 insertions(+), 77 deletions(-)
+
+commit 30c05e8b55c36200735446f237f1d7003cb70450
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 23:57:00 2021 -0600
+
+    [algs] include <new>
+
+ src/hb-algs.hh  | 1 +
+ src/hb-mutex.hh | 1 -
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c6fd7cdb2f2ab60de83d9a1e0fd189510b771a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 23:13:34 2021 -0600
+
+    [map] Try moving items when resizing
+
+ src/hb-map.hh | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit a28ea8d7f35a89cda49a9552a5ab6dc14d208c84
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 22:50:54 2021 -0600
+
+    Simplify swap()
+
+ src/hb-bit-set.hh | 1 -
+ src/hb-map.hh     | 1 -
+ 2 files changed, 2 deletions(-)
+
+commit 94158316d9ba69315497a200ec63d13cb6959363
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 22:47:26 2021 -0600
+
+    [map] Add iterable constructor
+
+ src/hb-map.hh   |  6 ++++++
+ src/test-map.cc | 24 ++++++++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+commit a03b9b14c988aa04ba3ee1e5d187b65e7b24015a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 22:45:11 2021 -0600
+
+    [map] Add initializer_list and swap()
+
+ src/hb-map.hh   | 25 +++++++++++++++++++++++--
+ src/test-map.cc | 10 ++++++++++
+ src/test-set.cc |  6 +++---
+ 3 files changed, 36 insertions(+), 5 deletions(-)
+
+commit 3604f5f2484b47c0693896f8a8e48dfe46dddef1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 22:37:42 2021 -0600
+
+    [algs] Include <initializer_list>
+
+ src/hb-algs.hh   | 1 +
+ src/hb-set.hh    | 2 --
+ src/hb-vector.hh | 2 --
+ 3 files changed, 1 insertion(+), 4 deletions(-)
+
+commit c30f6834d0ad0adbe0f16bb79555fd161de2303e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 22:29:14 2021 -0600
+
+    [map] Add 5 methods
+
+ src/Makefile.am    |  5 ++++
+ src/hb-map.hh      | 17 +++++++++++++-
+ src/meson.build    |  1 +
+ src/test-map.cc    | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/test-set.cc    |  1 +
+ src/test-vector.cc |  1 +
+ 6 files changed, 92 insertions(+), 1 deletion(-)
+
+commit 38debbab7e287e513968c80a10e69ab054acad4d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 22:17:35 2021 -0600
+
+    [set] Add successful check in swap()
+
+ src/hb-bit-set-invertible.hh | 2 ++
+ src/hb-bit-set.hh            | 2 ++
+ 2 files changed, 4 insertions(+)
+
+commit b860b44229dbde49e8a1ed34257b1a70bb2401ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 22:00:18 2021 -0600
+
+    [bimap] Simplify initialization
+
+ src/hb-bimap.hh | 15 +++------------
+ 1 file changed, 3 insertions(+), 12 deletions(-)
+
+commit d2c364f6e7edbd295132f792d711ac37ff551d37
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 21:55:14 2021 -0600
+
+    [array] Use default methods
+
+ src/hb-array.hh | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+commit 6f74d80ed1f20a31744f78ee5a290b76b1dfb102
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 21:49:32 2021 -0600
+
+    [vector] Complete sorted_vector 5-methods
+
+ src/hb-vector.hh   | 11 +++++++++--
+ src/test-vector.cc | 19 ++++++++++++++++---
+ 2 files changed, 25 insertions(+), 5 deletions(-)
+
+commit a28b5d03b5c86d2ffc352ef35463718aa4a00a9f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 21:43:44 2021 -0600
+
+    [vector] Add swap() friend to hb_sorted_vector_t
+
+ src/hb-vector.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit e97e79967e6ed0dd5719c2b88cf72f8860790245
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 21:34:46 2021 -0600
+
+    Verbiage
+
+ src/hb-set.hh    |  8 ++++----
+ src/hb-vector.hh | 10 +++++-----
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 34fa5e290146b14ee6bdb261811d219fd7711574
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 21:25:03 2021 -0600
+
+    [set] More default operators
+
+ src/hb-set.hh | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit b6c0b40fc2a66893c70f02dc20f2c99b0a996b6a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 21:15:38 2021 -0600
+
+    [vector] Use default constructor
+
+ src/hb-vector.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 1e3f57c07904578079a58e37baf3a6bb01c0be0c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 21:14:12 2021 -0600
+
+    [bit-set] Implement standard-5 methods plus swap
+
+ src/hb-bit-set.hh | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+commit 11eadb5d2886c8d2a6eef26866f080bde9ff65ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 21:07:09 2021 -0600
+
+    [bit-set-invertible] Implement standard-5 methods & swap
+
+ src/hb-bit-set-invertible.hh | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+commit dcd18da611436455733e3a80075d07685a6f96f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 20:55:30 2021 -0600
+
+    [set] Add standard the 5 standard methods & tests
+
+ src/Makefile.am |  9 ++++++
+ src/hb-set.hh   | 33 +++++++++++++++++---
+ src/meson.build |  1 +
+ src/test-set.cc | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 135 insertions(+), 4 deletions(-)
+
+commit 628a0f3796992fe858b368c8b6358ef9d83a21e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 20:36:55 2021 -0600
+
+    [vector] Add more tests
+
+ src/test-vector.cc | 41 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+commit f15858be5f09a9fdfbec9ccc68490e23e5db35ad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 20:26:07 2021 -0600
+
+    [vector] Pre-allocate if iterator has random-access length
+
+ src/hb-vector.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 11135150a7e9955aefbf9ac943367a618b513981
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 20:23:12 2021 -0600
+
+    [vector] Move test code into separate file
+
+ src/Makefile.am    | 14 ++++++++-
+ src/meson.build    |  1 +
+ src/test-algs.cc   | 51 --------------------------------
+ src/test-vector.cc | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 99 insertions(+), 52 deletions(-)
+
+commit ee75e716c1fec110e9ee2d30be9db14b75515404
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 20:18:49 2021 -0600
+
+    [vector] Add initializer from iterable
+
+ src/hb-vector.hh |  6 ++++++
+ src/test-algs.cc | 31 +++++++++++++++++++++++++++++++
+ 2 files changed, 37 insertions(+)
+
+commit 18a078f968072990cc50f96d4b6e47b32a6001c5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 20:06:58 2021 -0600
+
+    [vector] Implement move assignment using swap
+
+ src/hb-vector.hh | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+commit 8dc86d07036e0d251ab6817230651f8943693db8
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Nov 1 19:57:11 2021 -0400
+
+    Add a test font scale rounding behavior
+    
+    This test verifies the fix for
+    https://github.com/harfbuzz/harfbuzz/issues/3274
+
+ test/api/Makefile.am           |   1 +
+ test/api/fonts/Cantarell.A.otf | Bin 0 -> 1956 bytes
+ test/api/meson.build           |   1 +
+ test/api/test-font-scale.c     |  57 +++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 59 insertions(+)
+
+commit eeda2c549ddd103ebf8f9d1e20ae30137f5ed532
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 18:36:57 2021 -0600
+
+    [vector] Add initializer_list constructor & tests
+
+ src/hb-vector.hh | 15 +++++++++++++--
+ src/test-algs.cc | 20 ++++++++++++++++++++
+ 2 files changed, 33 insertions(+), 2 deletions(-)
+
+commit c484641304daff090111171d2dc3404735e14ed6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 18:48:24 2021 -0600
+
+    Revert "[vector] Add initializer_list constructor & tests"
+    
+    This reverts commit aa6182453b29b2d1cc974756fe0ae4220a846bf4.
+
+ src/hb-vector.hh | 15 ++-------------
+ src/test-algs.cc | 20 --------------------
+ 2 files changed, 2 insertions(+), 33 deletions(-)
+
+commit aa6182453b29b2d1cc974756fe0ae4220a846bf4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 18:36:57 2021 -0600
+
+    [vector] Add initializer_list constructor & tests
+
+ src/hb-vector.hh | 15 +++++++++++++--
+ src/test-algs.cc | 20 ++++++++++++++++++++
+ 2 files changed, 33 insertions(+), 2 deletions(-)
+
+commit 8c05569930b3ba8901baae7ffb9ae2a6fc6ce4b1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 17:59:17 2021 -0600
+
+    [algs] Add hb_swap() ala, and using, std::swap()
+    
+    Use it in vector.
+    
+    Use ADL idiom.
+
+ src/hb-algs.hh     | 11 +++++++++++
+ src/hb-repacker.hh |  4 ++--
+ src/hb-vector.hh   | 16 ++++------------
+ 3 files changed, 17 insertions(+), 14 deletions(-)
+
+commit bbaccf23d9e231370fb3ca3398ebfc132c7555bc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 1 16:45:36 2021 -0600
+
+    Better round positions during scaling
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3274
+
+ src/hb-font.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 52ccdc78e67b57645a83c6a55268dc19bf562e04
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Oct 28 14:56:13 2021 -0400
+
+    docs: Add a link to the OpenType spec
+    
+    Link to the name table specification in the
+    hb_ot_name_id_t docs.
+
+ src/hb-ot-name.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 8cb2f969d9632804a546e7e1157b64f85f21f512
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Oct 28 07:42:07 2021 -0400
+
+    Document hb_ot_name_t values
+    
+    Add a short blurb for each value and refer
+    to the OpenType spec for more information.
+    
+    Fixes: #3181
+
+ src/hb-ot-name.h | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+commit 85deddb16ee6b00b0c921998e1d93c84002f5a42
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Oct 27 14:36:02 2021 -0700
+
+    [subset] fuzzer fix: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=40406
+
+ src/hb-ot-color-colr-table.hh                           |   1 +
+ ...testcase-minimized-hb-subset-fuzzer-6315334756335616 | Bin 0 -> 20377 bytes
+ 2 files changed, 1 insertion(+)
+
+commit de9424172d79ee45c1913b2a5020c228a19e7ac8
+Author: David Korczynski <david at adalogics.com>
+Date:   Wed Oct 27 15:24:57 2021 +0100
+
+    [ci] Add CIFuzz integration
+    
+    Add CIFuzz integration, which will run the fuzzers for a short amount
+    of time when a PR is submitted on Github.
+    
+    Signed-off-by: David Korczynski <david at adalogics.com>
+
+ .github/workflows/cifuzz.yml | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+commit da500568dee503fd3fc9042d95668e3371f93d75
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 26 08:02:29 2021 -0600
+
+    [API] Add hb_buffer_[sg]et_not_found_glyph() and --not-found-glyph
+    
+    Instead of using gid=0 when a character is not found in the font,
+    client can now set a custom value.  This is useful for shaper-driven
+    font fallback and to differentiate that from .notdef glyph.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1360
+
+ docs/harfbuzz-sections.txt   |  2 ++
+ src/hb-buffer.cc             | 42 ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-buffer.h              |  7 +++++++
+ src/hb-buffer.hh             |  1 +
+ src/hb-font.hh               | 10 ++++++----
+ src/hb-ot-shape-normalize.cc |  5 +++--
+ src/hb-ot-shape-normalize.hh |  1 +
+ util/shape-options.hh        |  3 +++
+ 8 files changed, 65 insertions(+), 6 deletions(-)
+
+commit 6ea6c581edb3cecf1b4b42854e37b40d6d067cd3
+Author: Cameron Cawley <ccawley2011 at gmail.com>
+Date:   Fri Sep 24 22:05:29 2021 +0100
+
+    Remove direct link to dwrite from meson scripts
+
+ meson.build     | 7 +------
+ src/meson.build | 1 -
+ 2 files changed, 1 insertion(+), 7 deletions(-)
+
+commit ecbe224743c205c99aa459b27e7fb241cc4b1dc5
+Author: Cameron Cawley <ccawley2011 at gmail.com>
+Date:   Fri Sep 24 21:32:12 2021 +0100
+
+    Revert "[hb-directwrite] Don't load dwrit.dll dynamically"
+    
+    This reverts commit 6119ff9d806db7de3ceef73de67fe589507800bb.
+
+ src/hb-directwrite.cc | 36 ++++++++++++++++++++++++++++++++++--
+ 1 file changed, 34 insertions(+), 2 deletions(-)
+
+commit 4262636926123df42eaba5374dc54bb9776a5af2
+Merge: f55d83473 d17155f5d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 23 13:18:22 2021 -0700
+
+    Merge pull request #3248 from googlefonts/connected_components
+    
+    [repacker] Keep connected subgraphs in the same space.
+
+commit f55d834736b58ac15cff09c20f5c5cd3ca52ef1e
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Oct 14 13:39:45 2021 -0700
+
+    [subset] Move struct DeltaSetIndexMap into hb-ot-var-common.hh
+    
+    Also fix naming issues in review comments
+
+ src/Makefile.sources          |   1 +
+ src/hb-ot-color-colr-table.hh | 131 +--------------------
+ src/hb-ot-var-common.hh       | 264 ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-var-hvar-table.hh   |  88 +-------------
+ src/meson.build               |   1 +
+ 5 files changed, 273 insertions(+), 212 deletions(-)
+
+commit 8c583db9b5c63dc790f6553044b8915e1f5906bb
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Sat Oct 2 20:32:30 2021 -0700
+
+    [subset] COLRv1: update subset() method for new strutc ClipList and VarIdxMap
+    
+    Also fix issues in struct PaintTransform definition
+
+ src/hb-ot-color-colr-table.hh                      | 193 ++++++++++++++++++---
+ src/hb-subset-plan.cc                              |  60 ++++---
+ .../TwemojiMozilla.subset.default.32,3299.ttf      | Bin 1576 -> 1520 bytes
+ .../api/fonts/TwemojiMozilla.subset.default.32.ttf | Bin 932 -> 888 bytes
+ .../fonts/TwemojiMozilla.subset.default.3297.ttf   | Bin 1376 -> 1332 bytes
+ test/api/fonts/TwemojiMozilla.subset.ttf           | Bin 1936 -> 1868 bytes
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ .../TwemojiMozilla.subset.default.32,3297,3299.ttf | Bin 1868 -> 1868 bytes
+ .../colr/TwemojiMozilla.subset.default.32,3297.ttf | Bin 1344 -> 1344 bytes
+ .../colr/TwemojiMozilla.subset.default.32,3299.ttf | Bin 1520 -> 1520 bytes
+ .../TwemojiMozilla.subset.default.3297,3299.ttf    | Bin 1860 -> 1860 bytes
+ .../colr/TwemojiMozilla.subset.default.3297.ttf    | Bin 1332 -> 1332 bytes
+ .../colr/TwemojiMozilla.subset.default.3299.ttf    | Bin 1508 -> 1508 bytes
+ ....subset.drop-hints-retain-gids.32,3297,3299.ttf | Bin 1848 -> 1848 bytes
+ ...zilla.subset.drop-hints-retain-gids.32,3297.ttf | Bin 1340 -> 1340 bytes
+ ...zilla.subset.drop-hints-retain-gids.32,3299.ttf | Bin 1520 -> 1520 bytes
+ ...lla.subset.drop-hints-retain-gids.3297,3299.ttf | Bin 1844 -> 1844 bytes
+ ...iMozilla.subset.drop-hints-retain-gids.3297.ttf | Bin 1328 -> 1328 bytes
+ ...iMozilla.subset.drop-hints-retain-gids.3299.ttf | Bin 1508 -> 1508 bytes
+ ...emojiMozilla.subset.drop-hints.32,3297,3299.ttf | Bin 1848 -> 1848 bytes
+ .../TwemojiMozilla.subset.drop-hints.32,3297.ttf   | Bin 1324 -> 1324 bytes
+ .../TwemojiMozilla.subset.drop-hints.32,3299.ttf   | Bin 1500 -> 1500 bytes
+ .../TwemojiMozilla.subset.drop-hints.3297,3299.ttf | Bin 1840 -> 1840 bytes
+ .../colr/TwemojiMozilla.subset.drop-hints.3297.ttf | Bin 1312 -> 1312 bytes
+ .../colr/TwemojiMozilla.subset.drop-hints.3299.ttf | Bin 1488 -> 1488 bytes
+ ...mojiMozilla.subset.retain-gids.32,3297,3299.ttf | Bin 1868 -> 1868 bytes
+ .../TwemojiMozilla.subset.retain-gids.32,3297.ttf  | Bin 1360 -> 1360 bytes
+ .../TwemojiMozilla.subset.retain-gids.32,3299.ttf  | Bin 1540 -> 1540 bytes
+ ...TwemojiMozilla.subset.retain-gids.3297,3299.ttf | Bin 1864 -> 1864 bytes
+ .../TwemojiMozilla.subset.retain-gids.3297.ttf     | Bin 1348 -> 1348 bytes
+ .../TwemojiMozilla.subset.retain-gids.3299.ttf     | Bin 1528 -> 1528 bytes
+ .../colr_with_components/colr-table.default.6B.ttf | Bin 4260 -> 4260 bytes
+ .../colr-table.drop-hints-retain-gids.6B.ttf       | Bin 4984 -> 4984 bytes
+ .../colr-table.drop-hints.6B.ttf                   | Bin 4260 -> 4260 bytes
+ .../colr-table.retain-gids.6B.ttf                  | Bin 4984 -> 4984 bytes
+ .../TestCOLRv1.default.E000,E001,E002,E003.ttf     | Bin 0 -> 1260 bytes
+ .../colrv1/TestCOLRv1.default.E000,E001,E002.ttf   | Bin 0 -> 1200 bytes
+ .../colrv1/TestCOLRv1.default.E000,E001.ttf        | Bin 0 -> 996 bytes
+ .../colrv1/TestCOLRv1.default.E000,E004.ttf        | Bin 0 -> 940 bytes
+ .../expected/colrv1/TestCOLRv1.default.E000.ttf    | Bin 0 -> 800 bytes
+ .../expected/colrv1/TestCOLRv1.default.E001.ttf    | Bin 0 -> 856 bytes
+ .../colrv1/TestCOLRv1.default.E002,E003,E004.ttf   | Bin 0 -> 1248 bytes
+ .../colrv1/TestCOLRv1.default.E002,E003.ttf        | Bin 0 -> 1116 bytes
+ .../expected/colrv1/TestCOLRv1.default.E002.ttf    | Bin 0 -> 856 bytes
+ .../colrv1/TestCOLRv1.default.E003,E004.ttf        | Bin 0 -> 1044 bytes
+ .../expected/colrv1/TestCOLRv1.default.E003.ttf    | Bin 0 -> 916 bytes
+ .../expected/colrv1/TestCOLRv1.default.E004.ttf    | Bin 0 -> 748 bytes
+ .../TestCOLRv1.default.retain-all-codepoint.ttf    | Bin 0 -> 1532 bytes
+ ....drop-hints-retain-gids.E000,E001,E002,E003.ttf | Bin 0 -> 1308 bytes
+ ...OLRv1.drop-hints-retain-gids.E000,E001,E002.ttf | Bin 0 -> 1248 bytes
+ ...TestCOLRv1.drop-hints-retain-gids.E000,E001.ttf | Bin 0 -> 1052 bytes
+ ...TestCOLRv1.drop-hints-retain-gids.E000,E004.ttf | Bin 0 -> 1020 bytes
+ .../TestCOLRv1.drop-hints-retain-gids.E000.ttf     | Bin 0 -> 856 bytes
+ .../TestCOLRv1.drop-hints-retain-gids.E001.ttf     | Bin 0 -> 924 bytes
+ ...OLRv1.drop-hints-retain-gids.E002,E003,E004.ttf | Bin 0 -> 1304 bytes
+ ...TestCOLRv1.drop-hints-retain-gids.E002,E003.ttf | Bin 0 -> 1176 bytes
+ .../TestCOLRv1.drop-hints-retain-gids.E002.ttf     | Bin 0 -> 936 bytes
+ ...TestCOLRv1.drop-hints-retain-gids.E003,E004.ttf | Bin 0 -> 1124 bytes
+ .../TestCOLRv1.drop-hints-retain-gids.E003.ttf     | Bin 0 -> 984 bytes
+ .../TestCOLRv1.drop-hints-retain-gids.E004.ttf     | Bin 0 -> 844 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 0 -> 1532 bytes
+ .../TestCOLRv1.drop-hints.E000,E001,E002,E003.ttf  | Bin 0 -> 1260 bytes
+ .../TestCOLRv1.drop-hints.E000,E001,E002.ttf       | Bin 0 -> 1200 bytes
+ .../colrv1/TestCOLRv1.drop-hints.E000,E001.ttf     | Bin 0 -> 996 bytes
+ .../colrv1/TestCOLRv1.drop-hints.E000,E004.ttf     | Bin 0 -> 940 bytes
+ .../expected/colrv1/TestCOLRv1.drop-hints.E000.ttf | Bin 0 -> 800 bytes
+ .../expected/colrv1/TestCOLRv1.drop-hints.E001.ttf | Bin 0 -> 856 bytes
+ .../TestCOLRv1.drop-hints.E002,E003,E004.ttf       | Bin 0 -> 1248 bytes
+ .../colrv1/TestCOLRv1.drop-hints.E002,E003.ttf     | Bin 0 -> 1116 bytes
+ .../expected/colrv1/TestCOLRv1.drop-hints.E002.ttf | Bin 0 -> 856 bytes
+ .../colrv1/TestCOLRv1.drop-hints.E003,E004.ttf     | Bin 0 -> 1044 bytes
+ .../expected/colrv1/TestCOLRv1.drop-hints.E003.ttf | Bin 0 -> 916 bytes
+ .../expected/colrv1/TestCOLRv1.drop-hints.E004.ttf | Bin 0 -> 748 bytes
+ .../TestCOLRv1.drop-hints.retain-all-codepoint.ttf | Bin 0 -> 1532 bytes
+ .../TestCOLRv1.retain-gids.E000,E001,E002,E003.ttf | Bin 0 -> 1308 bytes
+ .../TestCOLRv1.retain-gids.E000,E001,E002.ttf      | Bin 0 -> 1248 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E000,E001.ttf    | Bin 0 -> 1052 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E000,E004.ttf    | Bin 0 -> 1020 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E000.ttf         | Bin 0 -> 856 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E001.ttf         | Bin 0 -> 924 bytes
+ .../TestCOLRv1.retain-gids.E002,E003,E004.ttf      | Bin 0 -> 1304 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E002,E003.ttf    | Bin 0 -> 1176 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E002.ttf         | Bin 0 -> 936 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E003,E004.ttf    | Bin 0 -> 1124 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E003.ttf         | Bin 0 -> 984 bytes
+ .../colrv1/TestCOLRv1.retain-gids.E004.ttf         | Bin 0 -> 844 bytes
+ ...TestCOLRv1.retain-gids.retain-all-codepoint.ttf | Bin 0 -> 1532 bytes
+ test/subset/data/fonts/TestCOLRv1.ttf              | Bin 1780 -> 1860 bytes
+ test/subset/data/tests/colrv1.tests                |  16 +-
+ test/subset/meson.build                            |   2 +-
+ 91 files changed, 222 insertions(+), 51 deletions(-)
+
+commit e51c7f8e79867b790bfb282ca112b922cc7a2022
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Sep 30 10:42:17 2021 -0700
+
+    [subset] COLRv1: add ClipList/ClipRecord/ClipBox struct definition
+
+ src/hb-ot-color-colr-table.hh | 76 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 76 insertions(+)
+
+commit 2e5636eeaf5da1623c9a14d60163449c44ffacd1
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Aug 4 14:51:52 2021 -0700
+
+    [subset] add DeltasetIndexMap struct definition
+
+ src/hb-ot-color-colr-table.hh | 86 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 84 insertions(+), 2 deletions(-)
+
+commit d2e986feadfb8bbd7b7109795187780290e28f3b
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Aug 3 16:31:42 2021 -0700
+
+    [subset] update COLRv1 table struct definitions
+
+ src/hb-ot-color-colr-table.hh     | 471 ++++++++++++++++++++++++++------------
+ src/hb-ot-color-colrv1-closure.hh |  53 +++--
+ 2 files changed, 357 insertions(+), 167 deletions(-)
+
+commit 792ca307b0cfe916e65879403861a583bb12c378
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Oct 5 19:00:29 2021 +0200
+
+    [meson] Add graphite2 option and deprecate graphite
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3241
+    
+    Should be better handled when we can use https://github.com/mesonbuild/meson/pull/9184
+
+ meson.build       | 5 +++--
+ meson_options.txt | 2 ++
+ src/meson.build   | 2 +-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+commit c6557747ef2d5b5effeaa4c6ff97a0d274e0ca6c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 21 09:56:47 2021 -0600
+
+    [style] Use head->macStyle.isExtended in style fallback
+    
+    https://github.com/harfbuzz/harfbuzz/issues/3263
+
+ src/hb-style.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit f3f848b5066f3e6680ae5f68a1047085e7b8d59f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 21 09:54:02 2021 -0600
+
+    [head] Add is_expanded() internally
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3263
+
+ src/hb-ot-head-table.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit d17155f5d26f7ecb75d24d190c28a46f179c5d37
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Oct 13 14:40:00 2021 -0700
+
+    [repacker] use possibly updated root idx after isolate_subgraph.
+    
+    isolate_subgraph can change the root indices in some cases. So operations after the isolation need to use the roots from the output of isolate_subgraph.
+
+ src/hb-repacker.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit a7a36085538f218678c635a595025b7235c0e8cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 12 16:11:25 2021 -0700
+
+    [docs] Rename overflow_resolution to repacker
+
+ docs/{overflow_resolution.md => repacker.md} | 0
+ src/hb-repacker.hh                           | 4 ++--
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 9bd7ba5019381bb8584811ee63a0ba0cee7dca99
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 12 08:44:01 2021 -0700
+
+    Err on -Wbitwise-instead-of-logical
+    
+    Part of https://github.com/harfbuzz/harfbuzz/pull/3256
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 6bc64317ca0b1784a2826f980393d8cad3cf9de3
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 12 13:13:32 2021 -0700
+
+    Add a writeup of the overflow resolution algorithm in harfbuzz.
+
+ docs/overflow_resolution.md | 265 ++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-repacker.hh          |   7 ++
+ 2 files changed, 272 insertions(+)
+
+commit 96299d70edba60e5eb88a1efca384bc82392d977
+Author: Nico Weber <thakis at chromium.org>
+Date:   Tue Oct 12 10:42:43 2021 -0400
+
+    Fix Wbitwise-instead-of-logical warnings
+    
+    `a || b` only evaluates b if a is false. `a | b` always evaluates
+    both a and b. If a and b are of type bool, || is usually what you
+    want, so clang now warns on `|` where both arguments are of type bool.
+    
+    This warning fires twice in harfbuzz. In both cases, `|` is used
+    intentionally, with a comment explaining this.
+    
+    Slightly reorder the code a bit to make the compiler happy, and to
+    make it obvious even without a comment that both calls should be evaluated.
+    
+    No intended behavior change.
+
+ src/hb-ot-layout-gpos-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit b621c4fc29162c69098dce29fed887eac903d516
+Author: faywong <philip584521 at gmail.com>
+Date:   Mon Oct 11 21:04:47 2021 +0800
+
+    [subset] Refine the coding style
+
+ CMakeLists.txt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f8538d3117b3f1715ffcfaf1775635c3d867839c
+Author: faywong <philip584521 at gmail.com>
+Date:   Mon Oct 11 21:01:21 2021 +0800
+
+    [subset] Export header & archive when HB_BUILD_SUBSET
+    
+    Ease the adopt of hb-subset feature for 3rd party developers
+
+ CMakeLists.txt | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 36ed56b6e81b613b95b551527f6091c9fdbdc7ba
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Sep 23 10:51:21 2021 -0700
+
+    [subset] code cleanup
+    
+    - rename copy() method if it takes extra parameter
+    - get rid of same code blocks
+
+ src/hb-ot-layout-gsubgpos.hh | 110 ++++++++++++++++++-------------------------
+ 1 file changed, 45 insertions(+), 65 deletions(-)
+
+commit 3e635cf5e26e33d6210d3092256a49291752deec
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Oct 8 17:13:22 2021 -0400
+
+    [USE] Categorize characters that only have AJT
+
+ src/gen-use-table.py                 | 69 +++++++++++++-----------------------
+ src/hb-ot-shape-complex-use-table.hh | 66 +++++++++++++++++-----------------
+ src/update-unicode-tables.make       |  2 +-
+ 3 files changed, 59 insertions(+), 78 deletions(-)
+
+commit ae193cd18239e662308a4a189a0241cbf7b92244
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Oct 8 21:58:07 2021 -0400
+
+    [USE] Insert dotted circles before lone viramas
+
+ src/hb-ot-shape-complex-use-machine.hh | 520 ++++++++++++++++-----------------
+ src/hb-ot-shape-complex-use-machine.rl |  14 +-
+ 2 files changed, 265 insertions(+), 269 deletions(-)
+
+commit 641296b5ebb17875550705f1cea45ab6e6a8e562
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Oct 8 21:39:30 2021 -0400
+
+    [USE] Categorize U+11046 BRAHMI VIRAMA as HALANT
+
+ src/gen-use-table.py                 | 3 +--
+ src/hb-ot-shape-complex-use-table.hh | 2 +-
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+commit cca42cda460491fb8d9ee89cb0b37fe1d59ac04a
+Merge: 8eaee2f88 bb50aae9b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 8 13:10:21 2021 -0600
+
+    Merge pull request #3249 from harfbuzz/use-merge-s-o
+    
+    [USE] Merge the categories S and O
+
+commit bb50aae9b42e20e4b7aff0f7ac67a18ff2d65460
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Oct 8 13:25:46 2021 -0400
+
+    [USE] Document customizations of USE categories
+
+ src/gen-use-table.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 7287125c586994bf2ea5d3117b15731475ce3192
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Tue Oct 5 08:52:11 2021 -0400
+
+    [USE] Merge the categories S and O
+
+ src/gen-use-table.py                   |   5 -
+ src/hb-ot-shape-complex-use-machine.hh | 470 ++++++++++++++++-----------------
+ src/hb-ot-shape-complex-use-machine.rl |   6 +-
+ src/hb-ot-shape-complex-use-table.hh   |   4 +-
+ src/hb-ot-shape-complex-use.cc         |   1 -
+ 5 files changed, 234 insertions(+), 252 deletions(-)
+
+commit 8eaee2f887fffb1130b41668a54cd98866f0bfb5
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Thu Oct 7 20:10:31 2021 -0400
+
+    [USE] Only skip default ignorables within CCSes
+
+ src/gen-use-table.py                              | 106 ++++++++--------
+ src/hb-ot-shape-complex-use-machine.hh            |  55 ++++----
+ src/hb-ot-shape-complex-use-machine.rl            |   9 +-
+ src/hb-ot-shape-complex-use-table.hh              | 145 ++++++++++++++--------
+ src/update-unicode-tables.make                    |  16 +--
+ test/shape/data/in-house/tests/use-syllable.tests |   2 +-
+ 6 files changed, 189 insertions(+), 144 deletions(-)
+
+commit 4645c3b47c6e7a70f8d55eda543df1109e309347
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Thu Oct 7 08:52:02 2021 -0400
+
+    Update comments for U+180F FVS4
+
+ src/hb-ot-layout.hh | 4 ++--
+ src/hb-unicode.hh   | 3 ++-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit 5b882c420adc8f0556a0d966a641aef4c812079e
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Oct 6 11:12:32 2021 -0700
+
+    [repacker] performance optimizations for topological sorting.
+    
+    - Presize the output sorted graph and write it once in the correct order to avoid needing to reverse.
+    - Swap the old/new graph vectors instead of copying.
+    - Use a boolean vector for tracking visited instead of a set.
+
+ src/hb-repacker.hh | 25 +++++++++++--------------
+ src/hb-vector.hh   | 15 +++++++++++++++
+ 2 files changed, 26 insertions(+), 14 deletions(-)
+
+commit ff7a86e9b06f7c9b4c82fb931d681b08be1e0b27
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Oct 6 10:51:45 2021 -0700
+
+    [repacker] remove clone buffer, they are unnessecary.
+    
+    When nodes are duplicated it's fine to just reuse head, tail from the node being cloned since we don't modify the contents.
+
+ src/hb-repacker.hh | 39 +++------------------------------------
+ 1 file changed, 3 insertions(+), 36 deletions(-)
+
+commit 8cae8b653ddae37b1a5410a5997a14e44bf934a0
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 5 14:03:02 2021 -0700
+
+    [repacker] add missing fini for parents vector.
+
+ src/hb-repacker.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 7f0ede4f04f3f3eeb985bf40907e127952c7390c
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 5 13:10:01 2021 -0700
+
+    [repacker] refactor resolve overflow tests to use a helper.
+
+ src/test-repacker.cc | 165 +++++++++++++++++----------------------------------
+ 1 file changed, 53 insertions(+), 112 deletions(-)
+
+commit 79937d24b75d3039d70feafa2e5ca9836d72689b
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 5 12:53:21 2021 -0700
+
+    [repacker] Add repacker test that requires space splitting.
+
+ test/subset/data/fonts/Harmattan-Regular.ttf        | Bin 0 -> 835156 bytes
+ test/subset/data/repack_tests/Makefile.sources      |   3 ++-
+ test/subset/data/repack_tests/space_splitting.tests |   2 ++
+ test/subset/meson.build                             |   2 ++
+ 4 files changed, 6 insertions(+), 1 deletion(-)
+
+commit 7883b7ed95fcf577e4a5771daeaa01a89058eade
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 5 12:46:59 2021 -0700
+
+    [repacker] Add additional splitting spaces test.
+    
+    Fix issues it uncovered.
+
+ src/hb-repacker.hh   |  11 +++--
+ src/test-repacker.cc | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 133 insertions(+), 3 deletions(-)
+
+commit 6265663de4c77dd504d231f2b8f7fd8e80363b40
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 5 11:30:04 2021 -0700
+
+    [repacker] add test for splitting spaces.
+
+ src/test-repacker.cc | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 105 insertions(+)
+
+commit d97bd4268a8acdbc3628855057743d2b22e85341
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 5 10:53:05 2021 -0700
+
+    [repacker] when assigning spaces use post isolation node indices.
+    
+    isolate_subgraph can result in some of the roots being duplicated and moved to new indices, so do subgraph isolation before assign roots to spaces.
+
+ src/hb-repacker.hh | 69 ++++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 51 insertions(+), 18 deletions(-)
+
+commit bb57df7a4fae6991895388c8b4fab8ae9de80332
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Oct 5 15:40:30 2021 +0200
+
+    [test] Add test for https://github.com/harfbuzz/harfbuzz/issues/2757#issuecomment-933531978
+
+ .../fonts/e6185e88b04432fbf373594d5971686bb7dd698d.ttf  | Bin 0 -> 79552 bytes
+ test/shape/data/in-house/tests/aat-morx.tests           |   1 +
+ 2 files changed, 1 insertion(+)
+
+commit 16245503776b5d5487bb07640b1d75d0429f2143
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Oct 5 15:35:17 2021 +0200
+
+    [test] Add test for https://github.com/harfbuzz/harfbuzz/issues/3244
+
+ .../fonts/e2b17207c4b7ad78d843e1b0c4d00b09398a1137.ttf   | Bin 0 -> 1488 bytes
+ test/shape/data/in-house/tests/indic-syllable.tests      |   1 +
+ 2 files changed, 1 insertion(+)
+
+commit ccfc0481539ca34cba578ebbcef8ac0ea315e2f0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 5 07:00:50 2021 -0600
+
+    [indic] Apply 'calt' and 'clig' across syllable boundaries
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3244
+
+ src/hb-ot-shape-complex-indic.cc | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit d58f1685cee7fef904f4149561a2dcf5ec519ac3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 4 08:40:24 2021 -0600
+
+    [ot-shape] Tweak table order some more; apply GPOS with morx
+    
+    During 5bc05ba155 accidentally GPOS was disabled when morx was
+    enabled. Fix that.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2757#issuecomment-933531978
+
+ src/hb-ot-shape.cc | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit f8ebb8a65778745e43c560270d198c77c9d55220
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Wed Sep 29 19:18:25 2021 -0400
+
+    [USE] Update the data files
+    
+    This uses the data files from
+    <https://github.com/microsoft/font-tools/tree/c355d0419429fca2f1a22d88d0afd35822e4c0b0/USE>.
+
+ src/hb-ot-shape-complex-use-table.hh              | 187 +++++++++++++++++-----
+ src/ms-use/IndicPositionalCategory-Additional.txt |  97 +++++------
+ src/ms-use/IndicSyllabicCategory-Additional.txt   | 164 ++++++++++---------
+ 3 files changed, 284 insertions(+), 164 deletions(-)
+
+commit 564afc425abac78fc2741540cb0d77cf31491f40
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Tue Sep 28 17:33:47 2021 -0400
+
+    [USE] Remove overrides for hieroglyphic categories
+
+ src/gen-use-table.py                 |  8 ---
+ src/hb-ot-shape-complex-use-table.hh | 96 +++++-------------------------------
+ 2 files changed, 13 insertions(+), 91 deletions(-)
+
+commit 8c654420692a3534413334f6d096738a796f4384
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sat Sep 25 16:38:32 2021 -0400
+
+    [Unicode 14] Handle U+180F FVS4
+
+ src/hb-ot-layout.hh               | 2 +-
+ src/hb-ot-shape-complex-arabic.cc | 2 +-
+ src/hb-unicode.hh                 | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 375a6c8f81a894ac15be7542e17571ad3ebdf16a
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 29 18:14:57 2021 -0700
+
+    [repacker] add the ability to move subgraphs from a shared space into their own space.
+    
+    Used to resolve overflows during manual resolution.
+
+ src/hb-repacker.hh | 93 ++++++++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 84 insertions(+), 9 deletions(-)
+
+commit 0dccbf368f1158f474f7ec3c6647932fbdda4e60
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 29 14:28:27 2021 -0700
+
+    [repacker] Handle the case where a subgraph root has an incoming 32 and 16 bit edge.
+    
+    In this case the entire subgraph from that root will be duplicated.
+
+ src/hb-repacker.hh   |  49 ++++++++++++++++++++----
+ src/test-repacker.cc | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 146 insertions(+), 8 deletions(-)
+
+commit 794b00db4b63e8314aee96c23a20ecb878452eef
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Sep 27 17:21:16 2021 -0700
+
+    [subset] fuzzer fix: https://oss-fuzz.com/testcase-detail/6616166961905664
+
+ src/hb-ot-math-table.hh                                   |   8 ++++++--
+ ...z-testcase-minimized-hb-subset-fuzzer-6616166961905664 | Bin 0 -> 919 bytes
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit 816c5302a7f5bfbbac1b89a72f9d50871085ddf3
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Sep 28 16:04:27 2021 -0700
+
+    [repacker] restrict 32 bit subgraph connected component search to only nodes reachable via directed links.
+
+ src/hb-repacker.hh   |  20 ++++++---
+ src/test-repacker.cc | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 136 insertions(+), 6 deletions(-)
+
+commit 67eb222b8eae1a10d0fd485a04254144e4051d46
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Sep 28 13:36:06 2021 -0700
+
+    [repacker] when assigning each connected subgraph a space, also isolate it.
+    
+    This will break any links coming from space 0 (ie. the 16 bit offset only space).
+
+ src/hb-repacker.hh   | 46 ++++++++++++++--------------------------------
+ src/test-repacker.cc | 50 ++++++++++++++++++++++++++++++++++----------------
+ 2 files changed, 48 insertions(+), 48 deletions(-)
+
+commit 307acf7fb0d4c767b4b78ba6c80ab83399d16cb4
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Sep 28 12:08:18 2021 -0700
+
+    [repacker] add space assignment based on connected components.
+    
+    Assign each connected component that is underneath one or more 32 bit offsets into a unique space. This ensures that 32 bit subgraphs which are connected are packed into the same space.
+
+ src/hb-repacker.hh   |  79 ++++++++++++++++++++++++++++++++-
+ src/test-repacker.cc | 122 ++++++++++++++++++++++++++++++++++++++++++++-------
+ 2 files changed, 182 insertions(+), 19 deletions(-)
+
+commit c77bdf1dcf86dcad79e90643a5f4e7d04fbae975
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Sep 24 15:58:57 2021 -0700
+
+    [repacker] begin storing each nodes parents.
+    
+    Will be used for connected component search.
+
+ src/hb-repacker.hh | 132 +++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 87 insertions(+), 45 deletions(-)
+
+commit a52c6df38a38c4e36ff991dfb4b7d92e48a44553
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Sep 27 11:22:05 2021 -0700
+
+    [subset] Fix bug in composite operation counting.
+    
+    Adding the result of add_gid_and_children to operation count over counts the number of operations.
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit efda2f14e104eedfee7da50ba2d22ba9a9ae376b
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Sep 24 16:28:34 2021 -0700
+
+    [repacker] fix bug in subgraph isolation.
+    
+    Prior to this fix id remapping at the end of the isolation operation was fed the old subgraph instead of the new one. Which results in object indices being remapped for the nodes outside of the new subgraph. Adds a test which detects this problem.
+
+ src/hb-repacker.hh   | 11 +++++++--
+ src/test-repacker.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 69 insertions(+), 6 deletions(-)
+
+commit 6f1909439862cc37246aba55a85c0a072b945dff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 23 08:39:29 2021 -0600
+
+    [getn-hb-version.py] Open old output in UTF-8 mode as well
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3227
+
+ src/gen-hb-version.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9247d24d7f41f820d7ea79089b482410b927edc8
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 22 16:00:02 2021 -0700
+
+    [repacker] s/0/HB_TAG_NONE
+
+ src/test-repacker.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit fe155de9895e99d8ae13cb7516e2a70d6e7f8856
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Sep 10 14:55:24 2021 -0700
+
+    [repacker] handle a couple of duplication edge cases.
+    
+    - Detect cases where there are multiple links from a parent to a child. Don't duplicate that child if those are the only remaining links to the child.
+    - Correctly handle isolating a subgraph where the root idx has multiple incoming links.
+
+ src/hb-repacker.hh | 47 ++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 36 insertions(+), 11 deletions(-)
+
+commit c19ec97da722d4a91024328c2d31f5e2f984fe10
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 9 10:53:09 2021 -0700
+
+    [repacker] reduce the bits used by order by 2 to give more bits to distance.
+
+ src/hb-repacker.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit d5beb96e06c34b6f5799f341d4b27e952e739d85
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 9 10:40:08 2021 -0700
+
+    [repacker] add repacker isolation test on real font.
+
+ .../subset/data/fonts/NotoNastaliqUrdu-Regular.ttf | Bin 0 -> 570552 bytes
+ test/subset/data/repack_tests/Makefile.sources     |   1 +
+ test/subset/data/repack_tests/isolation.tests      |  96 +++++++++++++++++++++
+ test/subset/meson.build                            |   1 +
+ 4 files changed, 98 insertions(+)
+
+commit d0daa7a59be05689ac618b6c22f2c112f67d75cb
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 9 10:25:43 2021 -0700
+
+    [repacker] add a couple more complex isolation tests.
+
+ src/hb-repacker.hh   |   5 ++-
+ src/test-repacker.cc | 120 +++++++++++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 119 insertions(+), 6 deletions(-)
+
+commit 62c502cd9dc4637934f846caa9587a2aebca9ee9
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 9 09:57:42 2021 -0700
+
+    [repacker] correctly update incoming_edges in duplicate.
+
+ src/hb-repacker.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit a57ef8df7ebf70f08065233f3ad218c451eff98a
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 8 17:31:39 2021 -0700
+
+    [repacker] default space to 0.
+    
+    Since vector push() init's new objects to all zeros.
+
+ src/hb-repacker.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 58facaade1c85906fec70584abfe13995a9dd07b
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 8 16:08:48 2021 -0700
+
+    [repacker] put each 32 bit subgraph into it's own packing space.
+    
+    Each subgraph pointed to by a 32 bit offset should be packed into it's own space. This adds a space property to vertices which affects the distance calculation. This effectively places the distances for all of the nodes of a 32 bit subgraph into a distinct range. Thus all of the nodes of the subgraph will be packed together.
+
+ src/hb-repacker.hh   | 12 ++++++++++--
+ src/test-repacker.cc |  3 +++
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+commit 543a3f97333a3bdede0cadd19b9a8554df81f1e8
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 8 15:07:02 2021 -0700
+
+    [repacker] Add repacker test for subgraph isolation.
+
+ src/hb-repacker.hh   | 10 +++++++--
+ src/test-repacker.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 65 insertions(+), 2 deletions(-)
+
+commit 7147f169d6cc93f54b7722022829ddb68957d2a5
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 8 13:44:25 2021 -0700
+
+    [repacker] recursively duplicate nodes during isolation.
+    
+    If a node is duplicated during isolation then any children it has will have incoming links from outside the subgraph (from the duplicated node and the original node), so they must be duplicated too.
+
+ src/hb-repacker.hh | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+commit 41bbf2812e9f4f6e704496da5d73ba74d0b4465e
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 8 10:14:00 2021 -0700
+
+    [repacker] do extension subtable isolation before starting resolution attempts.
+
+ src/hb-repacker.hh   | 39 ++++++++++++++++++++++++++++++++-------
+ src/hb-subset.cc     |  2 +-
+ src/test-repacker.cc |  4 ++--
+ 3 files changed, 35 insertions(+), 10 deletions(-)
+
+commit 8d8b7458a4cac9131bd650800ef0e3c0b67adfd4
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Sep 7 16:52:37 2021 -0700
+
+    [repacker] extract overflows processing into its own method.
+
+ src/hb-repacker.hh | 102 ++++++++++++++++++++++++++---------------------------
+ 1 file changed, 51 insertions(+), 51 deletions(-)
+
+commit b14b3f13bae48045c8a8465bdf6f579cb833852c
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Sep 7 16:32:13 2021 -0700
+
+    [repacker] begin implementing the ability to isolate extension subtables.
+    
+    Adds isolate_subgraph operation to the repacker. This severs any links from outside a subgraph by duplicating the affected vertices. This will be used to isolate the subgraphs of a extension subtable from the rest of object graph. Thus allowing the extension subtable to be packed far away from the rest of the objects.
+
+ src/hb-repacker.hh | 122 +++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 105 insertions(+), 17 deletions(-)
+
+commit 02c4a516dbcedc40cf7436105a56c6d913fa3675
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Sep 7 13:22:19 2021 -0700
+
+    Add a debug message when offset overflow resolution fails.
+
+ src/hb-repacker.hh | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+commit cb2d71c648137f1bd7586d3ec05050f0db50865f
+Author: Ben Wagner <bungeman at chromium.org>
+Date:   Fri Jul 30 14:30:20 2021 -0400
+
+    [mutex] Add hb_mutex_t std::mutex implementation
+    
+    Instead of failing...
+
+ src/hb-mutex.hh | 33 ++++++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+commit 67b3962fa5348ac7ee8e6297edcc277f3983e8be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 22 16:21:27 2021 -0600
+
+    [atomic] Cannot fail anymore
+
+ src/hb-atomic.hh | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+commit ca7b9daef06fc515ec84cfb95e7204e9eef3f00e
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Sep 20 14:42:51 2021 -0700
+
+    [subset] subset MATH table
+
+ src/hb-ot-layout-common.hh                         |  37 +++
+ src/hb-ot-math-table.hh                            | 268 +++++++++++++++++++++
+ src/hb-subset-plan.cc                              |  20 +-
+ src/hb-subset-plan.hh                              |   1 +
+ src/hb-subset.cc                                   |   2 +
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ .../math/STIXTwoMath-Regular.default.2f,7c,305.ttf | Bin 0 -> 6388 bytes
+ ...woMath-Regular.default.retain-all-codepoint.ttf | Bin 0 -> 1038580 bytes
+ .../STIXTwoMath-Regular.glyph-names.2f,7c,305.ttf  | Bin 0 -> 6540 bytes
+ ...th-Regular.glyph-names.retain-all-codepoint.ttf | Bin 0 -> 1091356 bytes
+ ...TIXTwoMath-Regular.notdef-outline.2f,7c,305.ttf | Bin 0 -> 6636 bytes
+ ...Regular.notdef-outline.retain-all-codepoint.ttf | Bin 0 -> 1038828 bytes
+ .../STIXTwoMath-Regular.retain-gids.2f,7c,305.ttf  | Bin 0 -> 14916 bytes
+ ...th-Regular.retain-gids.retain-all-codepoint.ttf | Bin 0 -> 1053656 bytes
+ test/subset/data/fonts/STIXTwoMath-Regular.ttf     | Bin 0 -> 1517976 bytes
+ test/subset/data/tests/math.tests                  |  12 +
+ test/subset/meson.build                            |   1 +
+ 18 files changed, 342 insertions(+), 1 deletion(-)
+
+commit c2cc566c9d7f63c024c0a15e93c9ae99717a4b4f
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 22 14:15:55 2021 -0700
+
+    [subset] Fix subset_offset_array adding unused space to serializer.
+    
+    ArrayOf.serialize_append allocates space for the new item, but ArrayOf.pop() does not recover the allocated space. So in the case where the revert path was entered the extra space added by serialize_append gets left in the serialization buffer. This moves the snapshot to before ArrayOf.serialize_append is called so that revert cleans up the buffer extend.
+
+ src/hb-ot-layout-common.hh                         |   4 ++--
+ src/hb-ot-layout-gpos-table.hh                     |   2 +-
+ src/hb-ot-layout-gsubgpos.hh                       |   4 ++--
+ ...ns-BlackItalic.default.retain-all-codepoint.ttf | Bin 120240 -> 120236 bytes
+ ...lackItalic.glyph-names.retain-all-codepoint.ttf | Bin 132484 -> 132480 bytes
+ ...kItalic.notdef-outline.retain-all-codepoint.ttf | Bin 120240 -> 120236 bytes
+ ...s2_1_font7.layout-test-retain-gids.21,23,25.otf | Bin 1728 -> 1728 bytes
+ .../gpos2_1_font7.layout-test.21,23,25.otf         | Bin 1384 -> 1384 bytes
+ ...e_subrules_f2.layout-test-retain-gids.41,42.otf | Bin 2208 -> 2208 bytes
+ ...ext1_multiple_subrules_f2.layout-test.41,42.otf | Bin 1400 -> 1400 bytes
+ ...e_subrules_f2.layout-test-retain-gids.41,42.otf | Bin 2224 -> 2224 bytes
+ ...ext2_multiple_subrules_f2.layout-test.41,42.otf | Bin 1416 -> 1416 bytes
+ ...Bold.default.627,644,623,62D,644,627,645,2E.ttf | Bin 11388 -> 11372 bytes
+ ...toNastaliqUrdu-Bold.default.627,644,62D,628.ttf | Bin 17688 -> 17640 bytes
+ .../NotoNastaliqUrdu-Bold.default.627,644.ttf      | Bin 3520 -> 3512 bytes
+ ...rdu-Bold.default.633,645,627,621,20,644,627.ttf | Bin 12380 -> 12360 bytes
+ .../NotoNastaliqUrdu-Bold.default.63A,64A,631.ttf  | Bin 19380 -> 19340 bytes
+ ....retain-gids.627,644,623,62D,644,627,645,2E.ttf | Bin 18224 -> 18208 bytes
+ ...staliqUrdu-Bold.retain-gids.627,644,62D,628.ttf | Bin 23748 -> 23704 bytes
+ .../NotoNastaliqUrdu-Bold.retain-gids.627,644.ttf  | Bin 9164 -> 9160 bytes
+ ...Bold.retain-gids.633,645,627,621,20,644,627.ttf | Bin 18184 -> 18164 bytes
+ ...toNastaliqUrdu-Bold.retain-gids.63A,64A,631.ttf | Bin 25432 -> 25392 bytes
+ .../variable/Fraunces.default.26,66,69,124,125.ttf | Bin 15856 -> 15856 bytes
+ 23 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 8c5c81746d8d4c5921be50a85d219deea2c95762
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Sun Sep 12 20:16:30 2021 -0700
+
+    [subset] fix find_duplicate_features
+    
+    We should check each feature against all other features with the same
+    tag for duplicates.
+
+ src/hb-ot-layout-gsubgpos.hh                       |  70 +++++++++++----------
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ ...fault.20,2f,38,49,4c,51,53,66,67,6f,b4,2044.ttf | Bin 0 -> 8452 bytes
+ ...ns-BlackItalic.default.retain-all-codepoint.ttf | Bin 0 -> 120240 bytes
+ ...names.20,2f,38,49,4c,51,53,66,67,6f,b4,2044.ttf | Bin 0 -> 8552 bytes
+ ...lackItalic.glyph-names.retain-all-codepoint.ttf | Bin 0 -> 132484 bytes
+ ...tline.20,2f,38,49,4c,51,53,66,67,6f,b4,2044.ttf | Bin 0 -> 8452 bytes
+ ...kItalic.notdef-outline.retain-all-codepoint.ttf | Bin 0 -> 120240 bytes
+ .../subset/data/fonts/AlegreyaSans-BlackItalic.ttf | Bin 0 -> 211948 bytes
+ .../data/tests/layout.duplicate_features.tests     |  11 ++++
+ test/subset/meson.build                            |   1 +
+ 12 files changed, 50 insertions(+), 34 deletions(-)
+
+commit 1afc3874e00992c378977c2feb25f8088c9c5a9a
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Sun Sep 19 20:41:43 2021 -0700
+
+    [subset] add closure_glyphs () method for MATH table
+
+ src/hb-ot-math-table.hh | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 57 insertions(+)
+
+commit 3b2929e8a9da349fbd8437fd0b5cf0c8ce92cf32
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 21 12:21:02 2021 -0600
+
+    [set-digest] Use using instead of typedef
+
+ src/hb-set-digest.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 5694561f75bdea9c7d77d7932598fe4e5f45b33e
+Author: Simon Cozens <simon at simon-cozens.org>
+Date:   Mon Sep 20 15:21:11 2021 +0100
+
+    Add support for Pwo Karen / Ason Chin medial la
+    
+    https://github.com/harfbuzz/harfbuzz/pull/3217
+
+ src/hb-ot-shape-complex-myanmar-machine.hh | 473 +++++++++++++++--------------
+ src/hb-ot-shape-complex-myanmar-machine.rl |   5 +-
+ src/hb-ot-shape-complex-myanmar.hh         |   7 +-
+ 3 files changed, 259 insertions(+), 226 deletions(-)
+
+commit bff56854323f853ed3dbad1105555da5192a7d1b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 20 13:25:58 2021 -0600
+
+    [khmer] Towards separating Khmer from Indic table
+
+ src/hb-ot-shape-complex-khmer.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 5d957ffe74d767f621d7ce4833ce2349206a2391
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 20 11:33:01 2021 -0600
+
+    [myanmar] Towards separating Myanmar from Indic table
+
+ src/hb-ot-shape-complex-myanmar.cc | 2 +-
+ src/hb-ot-shape-complex-myanmar.hh | 3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+commit 6db4b56e05a6fd993b4f3b5f1d21acc12236361e
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Sep 20 19:18:39 2021 +0200
+
+    Make the file UTF-8 again
+    
+    GitHub web interface failed to show the encoding change.
+
+ src/hb-subset-input.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 14a2df7bc237e7e59ff62c710751c7069733a469
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 19 23:06:09 2021 -0400
+
+    Add stub HBUINT15
+
+ src/hb-open-type.hh        | 9 +++++++++
+ src/hb-ot-layout-common.hh | 2 +-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+commit c852b8684154f707a897b6b62338efc48ebcfd9e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 19 16:30:12 2021 -0400
+
+    Rename HBGlyphID to HBGlyphID16
+
+ perf/texts/en-words.txt                    |  2 +-
+ src/hb-aat-layout-bsln-table.hh            |  4 +-
+ src/hb-aat-layout-common.hh                | 16 +++---
+ src/hb-aat-layout-just-table.hh            |  8 +--
+ src/hb-aat-layout-kerx-table.hh            |  4 +-
+ src/hb-aat-layout-morx-table.hh            | 32 ++++++------
+ src/hb-open-type.hh                        |  4 +-
+ src/hb-ot-cmap-table.hh                    |  4 +-
+ src/hb-ot-color-cbdt-table.hh              |  8 +--
+ src/hb-ot-color-colr-table.hh              |  6 +--
+ src/hb-ot-glyf-table.hh                    |  2 +-
+ src/hb-ot-layout-base-table.hh             |  2 +-
+ src/hb-ot-layout-common.hh                 | 18 +++----
+ src/hb-ot-layout-gpos-table.hh             |  2 +-
+ src/hb-ot-layout-gsub-table.hh             | 78 +++++++++++++++---------------
+ src/hb-ot-layout-jstf-table.hh             |  2 +-
+ src/hb-ot-math-table.hh                    |  4 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh | 14 +++---
+ src/hb-ot-vorg-table.hh                    |  2 +-
+ 19 files changed, 106 insertions(+), 106 deletions(-)
+
+commit 74f96d9d4b359fc138d21709c975a09ba933fb3d
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Sep 17 13:46:07 2021 -0700
+
+    [repacker] fix heap use after free in repacker.
+    
+    Don't store a reference to the link in overflow records as the link object may be freed if the sorted graph vector is resized.
+
+ src/hb-repacker.hh                                      |  12 ++++++------
+ ...testcase-minimized-hb-subset-fuzzer-5127321313476608 | Bin 0 -> 60417 bytes
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 7143c8333bae6b0ca238a92d1fdb222d088bf9d1
+Author: ActuallyaDeviloper <ActuallyaDeviloper at users.noreply.github.com>
+Date:   Sat Sep 18 20:59:38 2021 +0200
+
+    Make the code able to compile with MSVC++ from Visual Studio 2015 (Version 14.0.25431.01, Update 3) sucessfully again.
+
+ src/hb-subset-input.hh | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+commit b36f1510ec5180724e7866e2a86570429a435c93
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Sep 18 23:09:07 2021 +0200
+
+    [doc] Add missing version tags
+
+ src/hb-ot-layout.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
 commit 9c387e20d65a7a366ac270d789f6ad266014c9e0
 Author: Khaled Hosny <khaled at aliftype.com>
 Date:   Fri Sep 17 21:32:30 2021 +0200

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,3 +1,24 @@
+Overview of changes leading to 3.1.0
+Wednesday, November 3, 2021
+====================================
+- Better offset-overflow handling in the subsetter library. (Garret Rieger)
+- Improved Unicode 14 properties in the USE shaper, and various other USE
+  shaper fixes. (David Corbett)
+- MATH and COLR v1 tables subsetting support, and various other subsetter fixes.
+  (Qunxin Liu)
+- Support for Pwo Karen / Ason Chin medial la. (Simon Cozens)
+- Apply GPOS positioning when substituting with morx table, if kerx is missing.
+  (Behdad Esfahbod)
+- Apply calt and clig features across syllable boundaries in Indic shaper.
+  (Behdad Esfahbod)
+- meson option for enabling Graphite 2 has been renamed to graphite2.
+- Build and documentation fixes.
+
+- New API:
++hb_buffer_set_not_found_glyph()
++hb_buffer_get_not_found_glyph()
+
+
 Overview of changes leading to 3.0.0
 Friday, September 17, 2021
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [3.0.0],
+        [3.1.0],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,6 +1,6 @@
 project('harfbuzz', 'c', 'cpp',
   meson_version: '>= 0.52.0',
-  version: '3.0.0',
+  version: '3.1.0',
   default_options: [
     'cpp_rtti=false',       # Just to support msvc, we are passing -fno-exceptions also anyway
     'cpp_std=c++11',
@@ -96,7 +96,8 @@
                       fallback: ['glib', 'libglib_dep'])
 gobject_dep = dependency('gobject-2.0', required: get_option('gobject'),
                          fallback: ['glib', 'libgobject_dep'])
-graphite2_dep = dependency('graphite2', required: get_option('graphite'))
+graphite2_dep = dependency('graphite2', required: get_option('graphite2'))
+graphite_dep = dependency('graphite2', required: get_option('graphite'))
 
 icu_dep = null_dep
 if not get_option('icu').disabled()
@@ -188,7 +189,7 @@
   conf.set('HAVE_CHAFA', 1)
 endif
 
-if graphite2_dep.found()
+if graphite2_dep.found() or graphite_dep.found()
   conf.set('HAVE_GRAPHITE2', 1)
 endif
 
@@ -244,17 +245,12 @@
 endif
 
 # DirectWrite (Windows)
-directwrite_dep = null_dep
 if host_machine.system() == 'windows' and not get_option('directwrite').disabled()
   if get_option('directwrite').enabled() and not cpp.has_header('dwrite_1.h')
     error('DirectWrite was enabled explicitly, but required header is missing.')
   endif
 
-  directwrite_dep = cpp.find_library('dwrite', required: get_option('directwrite'))
-
-  if directwrite_dep.found()
-    conf.set('HAVE_DIRECTWRITE', 1)
-  endif
+  conf.set('HAVE_DIRECTWRITE', 1)
 endif
 
 # CoreText (macOS)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt	2021-11-04 00:51:18 UTC (rev 60943)
@@ -10,6 +10,8 @@
 option('icu', type: 'feature', value: 'auto',
   description: 'Enable ICU library unicode functions')
 option('graphite', type: 'feature', value: 'disabled',
+  description: 'Deprecated use graphite2 option instead')
+option('graphite2', type: 'feature', value: 'disabled',
   description: 'Enable Graphite2 complementary shaper')
 option('freetype', type: 'feature', value: 'auto',
   description: 'Enable freetype interop helpers')

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2021-11-04 00:51:18 UTC (rev 60943)
@@ -342,7 +342,20 @@
 test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
 test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
 
-COMPILED_TESTS = test-algs test-array test-iter test-meta test-number test-ot-tag test-priority-queue test-unicode-ranges test-bimap test-repacker
+COMPILED_TESTS = \
+	test-algs \
+	test-array \
+	test-iter \
+	test-map \
+	test-number \
+	test-ot-tag \
+	test-priority-queue \
+	test-set \
+	test-unicode-ranges \
+	test-vector \
+	test-bimap \
+	test-repacker \
+	$(NULL)
 COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
 COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
 check_PROGRAMS += $(COMPILED_TESTS)
@@ -368,9 +381,9 @@
 test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_iter_LDADD = $(COMPILED_TESTS_LDADD)
 
-test_meta_SOURCES = test-meta.cc hb-static.cc
-test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
-test_meta_LDADD = $(COMPILED_TESTS_LDADD)
+test_map_SOURCES = test-map.cc hb-static.cc
+test_map_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_map_LDADD = $(COMPILED_TESTS_LDADD)
 
 test_number_SOURCES = test-number.cc hb-number.cc
 test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
@@ -380,10 +393,18 @@
 test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_set_SOURCES = test-set.cc hb-static.cc
+test_set_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_set_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_unicode_ranges_SOURCES = test-unicode-ranges.cc
 test_unicode_ranges_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_unicode_ranges_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_vector_SOURCES = test-vector.cc hb-static.cc
+test_vector_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_vector_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_bimap_SOURCES = test-bimap.cc hb-static.cc
 test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_bimap_LDADD = $(COMPILED_TESTS_LDADD)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2021-11-04 00:51:18 UTC (rev 60943)
@@ -143,6 +143,7 @@
 	hb-ot-tag-table.hh \
 	hb-ot-tag.cc \
 	hb-ot-var-avar-table.hh \
+	hb-ot-var-common.hh \
 	hb-ot-var-fvar-table.hh \
 	hb-ot-var-gvar-table.hh \
 	hb-ot-var-hvar-table.hh \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-hb-version.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-hb-version.py	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-hb-version.py	2021-11-04 00:51:18 UTC (rev 60943)
@@ -15,7 +15,7 @@
 CURRENT_SOURCE_DIR = os.path.dirname(INPUT)
 
 try:
-	with open (OUTPUT, "r") as old_output:
+	with open (OUTPUT, "r", encoding='utf-8') as old_output:
 		for line in old_output:
 			old_version = re.match (r"#define HB_VERSION_STRING \"(\d.\d.\d)\"", line)
 			if old_version and old_version[1] == version:

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	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,14 +1,16 @@
 #!/usr/bin/env python3
 # flake8: noqa: F821
 
-"""usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt ArabicShaping.txt Blocks.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
+"""usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
 
 Input files:
 * https://unicode.org/Public/UCD/latest/ucd/IndicSyllabicCategory.txt
 * https://unicode.org/Public/UCD/latest/ucd/IndicPositionalCategory.txt
+* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt
+* https://unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
 * https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
-* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt
 * https://unicode.org/Public/UCD/latest/ucd/Blocks.txt
+* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt
 * ms-use/IndicSyllabicCategory-Additional.txt
 * ms-use/IndicPositionalCategory-Additional.txt
 """
@@ -15,19 +17,21 @@
 
 import sys
 
-if len (sys.argv) != 8:
+if len (sys.argv) != 10:
 	sys.exit (__doc__)
 
-DISABLED_BLOCKS = [
+DISABLED_SCRIPTS = {
+	'Arabic',
+	'Lao',
 	'Samaritan',
+	'Syriac',
 	'Thai',
-	'Lao',
-]
+}
 
 files = [open (x, encoding='utf-8') for x in sys.argv[1:]]
 
-headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 2]
-for j in range(5, 7):
+headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 4]
+for j in range(7, 9):
 	for line in files[j]:
 		line = line.rstrip()
 		if not line:
@@ -38,16 +42,8 @@
 data = [{} for _ in files]
 values = [{} for _ in files]
 for i, f in enumerate (files):
-	extended = False
-
 	for line in f:
 
-		# TODO: https://github.com/MicrosoftDocs/typography-issues/issues/522
-		if extended and line.startswith ('# ') and line.find (';'):
-			line = line[2:]
-		elif 'USE_Syllabic_Category' in line:
-			extended = True
-
 		j = line.find ('#')
 		if j >= 0:
 			line = line[:j]
@@ -63,25 +59,26 @@
 		else:
 			end = int (uu[1], 16)
 
-		t = fields[1 if i not in [2, 3] else 2]
+		t = fields[1 if i not in [2, 4] else 2]
 
-		if i == 3:
+		if i == 2:
 			t = 'jt_' + t
-		elif i == 5 and t == 'Consonant_Final_Modifier':
+		elif i == 3 and t != 'Default_Ignorable_Code_Point':
+			continue
+		elif i == 7 and t == 'Consonant_Final_Modifier':
 			# TODO: https://github.com/MicrosoftDocs/typography-issues/issues/336
 			t = 'Syllable_Modifier'
-		elif i == 6 and t == 'NA':
+		elif i == 8 and t == 'NA':
 			t = 'Not_Applicable'
 
-		i0 = i if i < 5 else i - 5
+		i0 = i if i < 7 else i - 7
 		for u in range (start, end + 1):
 			data[i0][u] = t
 		values[i0][t] = values[i0].get (t, 0) + end - start + 1
 
-defaults = ('Other', 'Not_Applicable', 'Cn', 'jt_X', 'No_Block')
+defaults = ('Other', 'Not_Applicable', 'jt_X', '', 'Cn', 'No_Block', 'Unknown')
 
 # TODO Characters that are not in Unicode Indic files, but used in USE
-data[0][0x0640] = defaults[0]
 data[0][0x1B61] = defaults[0]
 data[0][0x1B63] = defaults[0]
 data[0][0x1B64] = defaults[0]
@@ -91,29 +88,6 @@
 data[0][0x1B69] = defaults[0]
 data[0][0x1B6A] = defaults[0]
 data[0][0x2060] = defaults[0]
-for u in range (0x07CA, 0x07EA + 1):
-	data[0][u] = defaults[0]
-data[0][0x07FA] = defaults[0]
-for u in range (0x0840, 0x0858 + 1):
-	data[0][u] = defaults[0]
-for u in range (0x1887, 0x18A8 + 1):
-	data[0][u] = defaults[0]
-data[0][0x18AA] = defaults[0]
-for u in range (0xA840, 0xA872 + 1):
-	data[0][u] = defaults[0]
-for u in range (0x10B80, 0x10B91 + 1):
-	data[0][u] = defaults[0]
-for u in range (0x10BA9, 0x10BAE + 1):
-	data[0][u] = defaults[0]
-data[0][0x10FB0] = defaults[0]
-for u in range (0x10FB2, 0x10FB6 + 1):
-	data[0][u] = defaults[0]
-for u in range (0x10FB8, 0x10FBF + 1):
-	data[0][u] = defaults[0]
-for u in range (0x10FC1, 0x10FC4 + 1):
-	data[0][u] = defaults[0]
-for u in range (0x10FC9, 0x10FCB + 1):
-	data[0][u] = defaults[0]
 # TODO https://github.com/harfbuzz/harfbuzz/pull/1685
 data[0][0x1B5B] = 'Consonant_Placeholder'
 data[0][0x1B5C] = 'Consonant_Placeholder'
@@ -132,12 +106,12 @@
 combined = {}
 for i,d in enumerate (data):
 	for u,v in d.items ():
-		if i >= 2 and not u in combined:
-			continue
 		if not u in combined:
+			if i >= 4:
+				continue
 			combined[u] = list (defaults)
 		combined[u][i] = v
-combined = {k:v for k,v in combined.items() if v[4] not in DISABLED_BLOCKS}
+combined = {k: v for k, v in combined.items() if v[6] not in DISABLED_SCRIPTS}
 data = combined
 del combined
 
@@ -237,7 +211,7 @@
 globals().update(property_values)
 
 
-def is_BASE(U, UISC, UGC, AJT):
+def is_BASE(U, UISC, UDI, UGC, AJT):
 	return (UISC in [Number, Consonant, Consonant_Head_Letter,
 			Tone_Letter,
 			Vowel_Independent,
@@ -246,77 +220,79 @@
 		AJT in [jt_C, jt_D, jt_L, jt_R] and UISC != Joiner or
 		(UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial,
 					Consonant_Subjoined, Vowel, Vowel_Dependent]))
-def is_BASE_NUM(U, UISC, UGC, AJT):
+def is_BASE_NUM(U, UISC, UDI, UGC, AJT):
 	return UISC == Brahmi_Joining_Number
-def is_BASE_OTHER(U, UISC, UGC, AJT):
+def is_BASE_OTHER(U, UISC, UDI, UGC, AJT):
 	if UISC == Consonant_Placeholder: return True
 	return U in [0x2015, 0x2022, 0x25FB, 0x25FC, 0x25FD, 0x25FE]
-def is_CONS_FINAL(U, UISC, UGC, AJT):
+def is_CGJ(U, UISC, UDI, UGC, AJT):
+	# Also includes VARIATION_SELECTOR, WJ, and ZWJ
+	return U == 0x200D or UDI and UGC in [Mc, Me, Mn]
+def is_CONS_FINAL(U, UISC, UDI, UGC, AJT):
 	return ((UISC == Consonant_Final and UGC != Lo) or
 		UISC == Consonant_Succeeding_Repha)
-def is_CONS_FINAL_MOD(U, UISC, UGC, AJT):
+def is_CONS_FINAL_MOD(U, UISC, UDI, UGC, AJT):
 	return UISC == Syllable_Modifier
-def is_CONS_MED(U, UISC, UGC, AJT):
+def is_CONS_MED(U, UISC, UDI, UGC, AJT):
 	# Consonant_Initial_Postfixed is new in Unicode 11; not in the spec.
 	return (UISC == Consonant_Medial and UGC != Lo or
 		UISC == Consonant_Initial_Postfixed)
-def is_CONS_MOD(U, UISC, UGC, AJT):
+def is_CONS_MOD(U, UISC, UDI, UGC, AJT):
 	return (UISC in [Nukta, Gemination_Mark, Consonant_Killer] and
-		not is_SYM_MOD(U, UISC, UGC, AJT))
-def is_CONS_SUB(U, UISC, UGC, AJT):
+		not is_SYM_MOD(U, UISC, UDI, UGC, AJT))
+def is_CONS_SUB(U, UISC, UDI, UGC, AJT):
 	return UISC == Consonant_Subjoined and UGC != Lo
-def is_CONS_WITH_STACKER(U, UISC, UGC, AJT):
+def is_CONS_WITH_STACKER(U, UISC, UDI, UGC, AJT):
 	return UISC == Consonant_With_Stacker
-def is_HALANT(U, UISC, UGC, AJT):
+def is_HALANT(U, UISC, UDI, UGC, AJT):
 	return (UISC in [Virama, Invisible_Stacker]
-		and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC, AJT)
-		and not is_SAKOT(U, UISC, UGC, AJT))
-def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC, AJT):
-	# https://github.com/harfbuzz/harfbuzz/issues/1102
+		and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UDI, UGC, AJT)
+		and not is_SAKOT(U, UISC, UDI, UGC, AJT))
+def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UDI, UGC, AJT):
+	# Split off of HALANT
 	# https://github.com/harfbuzz/harfbuzz/issues/1379
-	return U in [0x11046, 0x1134D]
-def is_HALANT_NUM(U, UISC, UGC, AJT):
+	return U == 0x1134D
+def is_HALANT_NUM(U, UISC, UDI, UGC, AJT):
 	return UISC == Number_Joiner
-def is_HIEROGLYPH(U, UISC, UGC, AJT):
+def is_HIEROGLYPH(U, UISC, UDI, UGC, AJT):
 	return UISC == Hieroglyph
-def is_HIEROGLYPH_JOINER(U, UISC, UGC, AJT):
+def is_HIEROGLYPH_JOINER(U, UISC, UDI, UGC, AJT):
 	return UISC == Hieroglyph_Joiner
-def is_HIEROGLYPH_SEGMENT_BEGIN(U, UISC, UGC, AJT):
+def is_HIEROGLYPH_SEGMENT_BEGIN(U, UISC, UDI, UGC, AJT):
 	return UISC == Hieroglyph_Segment_Begin
-def is_HIEROGLYPH_SEGMENT_END(U, UISC, UGC, AJT):
+def is_HIEROGLYPH_SEGMENT_END(U, UISC, UDI, UGC, AJT):
 	return UISC == Hieroglyph_Segment_End
-def is_ZWNJ(U, UISC, UGC, AJT):
+def is_ZWNJ(U, UISC, UDI, UGC, AJT):
 	return UISC == Non_Joiner
-def is_OTHER(U, UISC, UGC, AJT):
+def is_OTHER(U, UISC, UDI, UGC, AJT):
+	# Also includes BASE_IND, Rsv, and SYM
 	return ((UGC in [Cn, Po] or UISC in [Consonant_Dead, Joiner, Modifying_Letter, Other])
-		and not is_BASE(U, UISC, UGC, AJT)
-		and not is_BASE_OTHER(U, UISC, UGC, AJT)
-		and not is_SYM(U, UISC, UGC, AJT)
-		and not is_SYM_MOD(U, UISC, UGC, AJT)
+		and not is_BASE(U, UISC, UDI, UGC, AJT)
+		and not is_BASE_OTHER(U, UISC, UDI, UGC, AJT)
+		and not is_CGJ(U, UISC, UDI, UGC, AJT)
+		and not is_SYM_MOD(U, UISC, UDI, UGC, AJT)
 	)
-def is_REPHA(U, UISC, UGC, AJT):
+def is_REPHA(U, UISC, UDI, UGC, AJT):
 	return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
-def is_SAKOT(U, UISC, UGC, AJT):
+def is_SAKOT(U, UISC, UDI, UGC, AJT):
+	# Split off of HALANT
 	return U == 0x1A60
-def is_SYM(U, UISC, UGC, AJT):
-	if U in [0x25CC, 0x1E14F]: return False
-	return UGC in [So, Sc] and U not in [0x0F01, 0x1B62, 0x1B68]
-def is_SYM_MOD(U, UISC, UGC, AJT):
+def is_SYM_MOD(U, UISC, UDI, UGC, AJT):
 	return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73]
-def is_VOWEL(U, UISC, UGC, AJT):
+def is_VOWEL(U, UISC, UDI, UGC, AJT):
 	# https://github.com/harfbuzz/harfbuzz/issues/376
 	return (UISC == Pure_Killer or
 		(UGC != Lo and UISC in [Vowel, Vowel_Dependent] and U not in [0xAA29]))
-def is_VOWEL_MOD(U, UISC, UGC, AJT):
+def is_VOWEL_MOD(U, UISC, UDI, UGC, AJT):
 	# https://github.com/harfbuzz/harfbuzz/issues/376
 	return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or
 		(UGC != Lo and (UISC == Bindu or U in [0xAA29])))
 
-# CGJ, VS, WJ, and ZWJ are handled in find_syllables
 use_mapping = {
 	'B':	is_BASE,
 	'N':	is_BASE_NUM,
 	'GB':	is_BASE_OTHER,
+	'CGJ':	is_CGJ,
 	'F':	is_CONS_FINAL,
 	'FM':	is_CONS_FINAL_MOD,
 	'M':	is_CONS_MED,
@@ -333,7 +309,6 @@
 	'ZWNJ':	is_ZWNJ,
 	'O':	is_OTHER,
 	'R':	is_REPHA,
-	'S':	is_SYM,
 	'Sk':	is_SAKOT,
 	'SM':	is_SYM_MOD,
 	'V':	is_VOWEL,
@@ -387,7 +362,7 @@
 def map_to_use(data):
 	out = {}
 	items = use_mapping.items()
-	for U,(UISC,UIPC,UGC,AJT,UBlock) in data.items():
+	for U, (UISC, UIPC, AJT, UDI, UGC, UBlock, _) in data.items():
 
 		# Resolve Indic_Syllabic_Category
 
@@ -408,8 +383,8 @@
 		# TODO: https://github.com/microsoft/font-tools/issues/1
 		if U == 0xA982: UISC = Consonant_Succeeding_Repha
 
-		values = [k for k,v in items if v(U,UISC,UGC,AJT)]
-		assert len(values) == 1, "%s %s %s %s %s" % (hex(U), UISC, UGC, AJT, values)
+		values = [k for k,v in items if v(U, UISC, UDI, UGC, AJT)]
+		assert len(values) == 1, "%s %s %s %s %s %s" % (hex(U), UISC, UDI, UGC, AJT, values)
 		USE = values[0]
 
 		# Resolve Indic_Positional_Category
@@ -430,12 +405,12 @@
 		if 0x11131 <= U <= 0x11132: UIPC = Top
 
 		assert (UIPC in [Not_Applicable, Visual_Order_Left] or U == 0x0F7F or
-			USE in use_positions), "%s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC, AJT)
+			USE in use_positions), "%s %s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UDI, UGC, AJT)
 
 		pos_mapping = use_positions.get(USE, None)
 		if pos_mapping:
 			values = [k for k,v in pos_mapping.items() if v and UIPC in v]
-			assert len(values) == 1, "%s %s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC, AJT, values)
+			assert len(values) == 1, "%s %s %s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UDI, UGC, AJT, values)
 			USE = USE + values[0]
 
 		out[U] = (USE, UBlock)
@@ -448,7 +423,7 @@
 print ("/*")
 print (" * The following table is generated by running:")
 print (" *")
-print (" *   {} IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt ArabicShaping.txt Blocks.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt".format (sys.argv[0]))
+print (" *   {} IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt".format (sys.argv[0]))
 print (" *")
 print (" * on files with these headers:")
 print (" *")

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-bsln-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-bsln-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-bsln-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -82,7 +82,7 @@
   }
 
   protected:
-  HBGlyphID	stdGlyph;	/* The specific glyph index number in this
+  HBGlyphID16	stdGlyph;	/* The specific glyph index number in this
 				 * font that is used to set the baseline values.
 				 * This is the standard glyph.
 				 * This glyph must contain a set of control points
@@ -105,7 +105,7 @@
   }
 
   protected:
-  HBGlyphID	stdGlyph;	/* ditto */
+  HBGlyphID16	stdGlyph;	/* ditto */
   HBUINT16	ctlPoints[32];	/* ditto */
   Lookup<HBUINT16>
 		lookupTable;	/* Lookup table that maps glyphs to their

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -96,8 +96,8 @@
     return_trace (c->check_struct (this) && value.sanitize (c, base));
   }
 
-  HBGlyphID	last;		/* Last GlyphID in this segment */
-  HBGlyphID	first;		/* First GlyphID in this segment */
+  HBGlyphID16	last;		/* Last GlyphID in this segment */
+  HBGlyphID16	first;		/* First GlyphID in this segment */
   T		value;		/* The lookup value (only one) */
   public:
   DEFINE_SIZE_STATIC (4 + T::static_size);
@@ -162,11 +162,11 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
 		  first <= last &&
-		  valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...));
+		  valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...));
   }
 
-  HBGlyphID	last;		/* Last GlyphID in this segment */
-  HBGlyphID	first;		/* First GlyphID in this segment */
+  HBGlyphID16	last;		/* Last GlyphID in this segment */
+  HBGlyphID16	first;		/* First GlyphID in this segment */
   NNOffset16To<UnsizedArrayOf<T>>
 		valuesZ;	/* A 16-bit offset from the start of
 				 * the table to the data. */
@@ -225,7 +225,7 @@
     return_trace (c->check_struct (this) && value.sanitize (c, base));
   }
 
-  HBGlyphID	glyph;		/* Last GlyphID */
+  HBGlyphID16	glyph;		/* Last GlyphID */
   T		value;		/* The lookup value (only one) */
   public:
   DEFINE_SIZE_STATIC (2 + T::static_size);
@@ -287,7 +287,7 @@
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 8 */
-  HBGlyphID	firstGlyph;	/* First glyph index included in the trimmed array. */
+  HBGlyphID16	firstGlyph;	/* First glyph index included in the trimmed array. */
   HBUINT16	glyphCount;	/* Total number of glyphs (equivalent to the last
 				 * glyph minus the value of firstGlyph plus 1). */
   UnsizedArrayOf<T>
@@ -329,7 +329,7 @@
   protected:
   HBUINT16	format;		/* Format identifier--format = 8 */
   HBUINT16	valueSize;	/* Byte size of each value. */
-  HBGlyphID	firstGlyph;	/* First glyph index included in the trimmed array. */
+  HBGlyphID16	firstGlyph;	/* First glyph index included in the trimmed array. */
   HBUINT16	glyphCount;	/* Total number of glyphs (equivalent to the last
 				 * glyph minus the value of firstGlyph plus 1). */
   UnsizedArrayOf<HBUINT8>
@@ -661,7 +661,7 @@
     return_trace (c->check_struct (this) && classArray.sanitize (c));
   }
   protected:
-  HBGlyphID		firstGlyph;	/* First glyph index included in the trimmed array. */
+  HBGlyphID16		firstGlyph;	/* First glyph index included in the trimmed array. */
   Array16Of<HBUCHAR>	classArray;	/* The class codes (indexed by glyph index minus
 					 * firstGlyph). */
   public:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -100,7 +100,7 @@
   protected:
   ActionSubrecordHeader
 		header;
-  HBGlyphID	addGlyph;	/* Glyph that should be added if the distance factor
+  HBGlyphID16	addGlyph;	/* Glyph that should be added if the distance factor
 				 * is growing. */
 
   public:
@@ -121,11 +121,11 @@
   HBFixed	substThreshold; /* Distance growth factor (in ems) at which
 				 * this glyph is replaced and the growth factor
 				 * recalculated. */
-  HBGlyphID	addGlyph;	/* Glyph to be added as kashida. If this value is
+  HBGlyphID16	addGlyph;	/* Glyph to be added as kashida. If this value is
 				 * 0xFFFF, no extra glyph will be added. Note that
 				 * generally when a glyph is added, justification
 				 * will need to be redone. */
-  HBGlyphID	substGlyph;	/* Glyph to be substituted for this glyph if the
+  HBGlyphID16	substGlyph;	/* Glyph to be substituted for this glyph if the
 				 * growth factor equals or exceeds the value of
 				 * substThreshold. */
   public:
@@ -170,7 +170,7 @@
   ActionSubrecordHeader
 		header;
   HBUINT16	flags;		/* Currently unused; set to 0. */
-  HBGlyphID	glyph;		/* Glyph that should be added if the distance factor
+  HBGlyphID16	glyph;		/* Glyph that should be added if the distance factor
 				 * is growing. */
   public:
   DEFINE_SIZE_STATIC (10);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -82,8 +82,8 @@
   }
 
   protected:
-  HBGlyphID	left;
-  HBGlyphID	right;
+  HBGlyphID16	left;
+  HBGlyphID16	right;
   FWORD		value;
   public:
   DEFINE_SIZE_STATIC (6);
@@ -775,11 +775,11 @@
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case 0:	return_trace (c->dispatch (u.format0, hb_forward<Ts> (ds)...));
-    case 1:	return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
-    case 2:	return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
-    case 4:	return_trace (c->dispatch (u.format4, hb_forward<Ts> (ds)...));
-    case 6:	return_trace (c->dispatch (u.format6, hb_forward<Ts> (ds)...));
+    case 0:	return_trace (c->dispatch (u.format0, std::forward<Ts> (ds)...));
+    case 1:	return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2:	return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    case 4:	return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
+    case 6:	return_trace (c->dispatch (u.format6, std::forward<Ts> (ds)...));
     default:	return_trace (c->default_return_value ());
     }
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -243,7 +243,7 @@
       if (buffer->idx == buffer->len && !mark_set)
 	return;
 
-      const HBGlyphID *replacement;
+      const HBGlyphID16 *replacement;
 
       replacement = nullptr;
       if (Types::extended)
@@ -250,7 +250,7 @@
       {
 	if (entry.data.markIndex != 0xFFFF)
 	{
-	  const Lookup<HBGlyphID> &lookup = subs[entry.data.markIndex];
+	  const Lookup<HBGlyphID16> &lookup = subs[entry.data.markIndex];
 	  replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs);
 	}
       }
@@ -257,7 +257,7 @@
       else
       {
 	unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint;
-	const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs;
+	const UnsizedArrayOf<HBGlyphID16> &subs_old = (const UnsizedArrayOf<HBGlyphID16> &) subs;
 	replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
 	if (!replacement->sanitize (&c->sanitizer) || !*replacement)
 	  replacement = nullptr;
@@ -278,7 +278,7 @@
       {
 	if (entry.data.currentIndex != 0xFFFF)
 	{
-	  const Lookup<HBGlyphID> &lookup = subs[entry.data.currentIndex];
+	  const Lookup<HBGlyphID16> &lookup = subs[entry.data.currentIndex];
 	  replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs);
 	}
       }
@@ -285,7 +285,7 @@
       else
       {
 	unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint;
-	const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs;
+	const UnsizedArrayOf<HBGlyphID16> &subs_old = (const UnsizedArrayOf<HBGlyphID16> &) subs;
 	replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
 	if (!replacement->sanitize (&c->sanitizer) || !*replacement)
 	  replacement = nullptr;
@@ -315,7 +315,7 @@
     bool has_glyph_classes;
     unsigned int mark;
     const ContextualSubtable *table;
-    const UnsizedListOfOffset16To<Lookup<HBGlyphID>, HBUINT, false> &subs;
+    const UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, false> &subs;
   };
 
   bool apply (hb_aat_apply_context_t *c) const
@@ -359,7 +359,7 @@
   protected:
   StateTable<Types, EntryData>
 		machine;
-  NNOffsetTo<UnsizedListOfOffset16To<Lookup<HBGlyphID>, HBUINT, false>, HBUINT>
+  NNOffsetTo<UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, false>, HBUINT>
 		substitutionTables;
   public:
   DEFINE_SIZE_STATIC (20);
@@ -531,7 +531,7 @@
 	  if (action & (LigActionStore | LigActionLast))
 	  {
 	    ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ);
-	    const HBGlyphID &ligatureData = ligature[ligature_idx];
+	    const HBGlyphID16 &ligatureData = ligature[ligature_idx];
 	    if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break;
 	    hb_codepoint_t lig = ligatureData;
 
@@ -565,7 +565,7 @@
     const LigatureSubtable *table;
     const UnsizedArrayOf<HBUINT32> &ligAction;
     const UnsizedArrayOf<HBUINT16> &component;
-    const UnsizedArrayOf<HBGlyphID> &ligature;
+    const UnsizedArrayOf<HBGlyphID16> &ligature;
     unsigned int match_length;
     unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
   };
@@ -597,7 +597,7 @@
 		ligAction;	/* Offset to the ligature action table. */
   NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT>
 		component;	/* Offset to the component table. */
-  NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT>
+  NNOffsetTo<UnsizedArrayOf<HBGlyphID16>, HBUINT>
 		ligature;	/* Offset to the actual ligature lists. */
   public:
   DEFINE_SIZE_STATIC (28);
@@ -620,7 +620,7 @@
     unsigned int count = c->buffer->len;
     for (unsigned int i = 0; i < count; i++)
     {
-      const HBGlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
+      const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
       if (replacement)
       {
 	info[i].codepoint = *replacement;
@@ -641,7 +641,7 @@
   }
 
   protected:
-  Lookup<HBGlyphID>	substitute;
+  Lookup<HBGlyphID16>	substitute;
   public:
   DEFINE_SIZE_MIN (2);
 };
@@ -744,7 +744,7 @@
 	unsigned int count = (flags & MarkedInsertCount);
 	if (unlikely ((buffer->max_ops -= count) <= 0)) return;
 	unsigned int start = entry.data.markedInsertIndex;
-	const HBGlyphID *glyphs = &insertionAction[start];
+	const HBGlyphID16 *glyphs = &insertionAction[start];
 	if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
 
 	bool before = flags & MarkedInsertBefore;
@@ -772,7 +772,7 @@
 	unsigned int count = (flags & CurrentInsertCount) >> 5;
 	if (unlikely ((buffer->max_ops -= count) <= 0)) return;
 	unsigned int start = entry.data.currentInsertIndex;
-	const HBGlyphID *glyphs = &insertionAction[start];
+	const HBGlyphID16 *glyphs = &insertionAction[start];
 	if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
 
 	bool before = flags & CurrentInsertBefore;
@@ -810,7 +810,7 @@
     private:
     hb_aat_apply_context_t *c;
     unsigned int mark;
-    const UnsizedArrayOf<HBGlyphID> &insertionAction;
+    const UnsizedArrayOf<HBGlyphID16> &insertionAction;
   };
 
   bool apply (hb_aat_apply_context_t *c) const
@@ -836,7 +836,7 @@
   protected:
   StateTable<Types, EntryData>
 		machine;
-  NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT>
+  NNOffsetTo<UnsizedArrayOf<HBGlyphID16>, HBUINT>
 		insertionAction;	/* Byte offset from stateHeader to the start of
 					 * the insertion glyph table. */
   public:
@@ -906,11 +906,11 @@
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case Rearrangement:		return_trace (c->dispatch (u.rearrangement, hb_forward<Ts> (ds)...));
-    case Contextual:		return_trace (c->dispatch (u.contextual, hb_forward<Ts> (ds)...));
-    case Ligature:		return_trace (c->dispatch (u.ligature, hb_forward<Ts> (ds)...));
-    case Noncontextual:		return_trace (c->dispatch (u.noncontextual, hb_forward<Ts> (ds)...));
-    case Insertion:		return_trace (c->dispatch (u.insertion, hb_forward<Ts> (ds)...));
+    case Rearrangement:		return_trace (c->dispatch (u.rearrangement, std::forward<Ts> (ds)...));
+    case Contextual:		return_trace (c->dispatch (u.contextual, std::forward<Ts> (ds)...));
+    case Ligature:		return_trace (c->dispatch (u.ligature, std::forward<Ts> (ds)...));
+    case Noncontextual:		return_trace (c->dispatch (u.noncontextual, std::forward<Ts> (ds)...));
+    case Insertion:		return_trace (c->dispatch (u.insertion, std::forward<Ts> (ds)...));
     default:			return_trace (c->default_return_value ());
     }
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -34,6 +34,9 @@
 #include "hb-null.hh"
 #include "hb-number.hh"
 
+#include <algorithm>
+#include <initializer_list>
+#include <new>
 
 /*
  * Flags
@@ -125,7 +128,7 @@
 template <typename Type>
 struct BEInt<Type, 3>
 {
-  static_assert (!hb_is_signed (Type), "");
+  static_assert (!std::is_signed<Type>::value, "");
   public:
   BEInt () = default;
   constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF),
@@ -179,7 +182,7 @@
 {
   /* Note.  This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */
   template <typename T> constexpr auto
-  operator () (T&& v) const HB_AUTO_RETURN ( hb_forward<T> (v) )
+  operator () (T&& v) const HB_AUTO_RETURN ( std::forward<T> (v) )
 }
 HB_FUNCOBJ (hb_identity);
 struct
@@ -203,7 +206,7 @@
 struct
 {
   template <typename T> constexpr bool
-  operator () (T&& v) const { return bool (hb_forward<T> (v)); }
+  operator () (T&& v) const { return bool (std::forward<T> (v)); }
 }
 HB_FUNCOBJ (hb_bool);
 
@@ -215,7 +218,7 @@
   impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
 
   template <typename T,
-	    hb_enable_if (hb_is_integral (T))> constexpr auto
+	    hb_enable_if (std::is_integral<T>::value)> constexpr auto
   impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
   (
     /* Knuth's multiplicative method: */
@@ -237,17 +240,17 @@
   /* Pointer-to-member-function. */
   template <typename Appl, typename T, typename ...Ts> auto
   impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN
-  ((hb_deref (hb_forward<T> (v)).*hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...))
+  ((hb_deref (std::forward<T> (v)).*std::forward<Appl> (a)) (std::forward<Ts> (ds)...))
 
   /* Pointer-to-member. */
   template <typename Appl, typename T> auto
   impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN
-  ((hb_deref (hb_forward<T> (v))).*hb_forward<Appl> (a))
+  ((hb_deref (std::forward<T> (v))).*std::forward<Appl> (a))
 
   /* Operator(). */
   template <typename Appl, typename ...Ts> auto
   impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN
-  (hb_deref (hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...))
+  (hb_deref (std::forward<Appl> (a)) (std::forward<Ts> (ds)...))
 
   public:
 
@@ -254,9 +257,9 @@
   template <typename Appl, typename ...Ts> auto
   operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN
   (
-    impl (hb_forward<Appl> (a),
+    impl (std::forward<Appl> (a),
 	  hb_prioritize,
-	  hb_forward<Ts> (ds)...)
+	  std::forward<Ts> (ds)...)
   )
 }
 HB_FUNCOBJ (hb_invoke);
@@ -275,9 +278,9 @@
 						   hb_declval (V),
 						   hb_declval (Ts)...))
   {
-    return hb_invoke (hb_forward<Appl> (a),
-		      hb_forward<V> (v),
-		      hb_forward<Ts> (ds)...);
+    return hb_invoke (std::forward<Appl> (a),
+		      std::forward<V> (v),
+		      std::forward<Ts> (ds)...);
   }
   template <typename T0, typename ...Ts,
 	    unsigned P = Pos,
@@ -287,10 +290,10 @@
 							    hb_declval (V),
 							    hb_declval (Ts)...))
   {
-    return hb_invoke (hb_forward<Appl> (a),
-		      hb_forward<T0> (d0),
-		      hb_forward<V> (v),
-		      hb_forward<Ts> (ds)...);
+    return hb_invoke (std::forward<Appl> (a),
+		      std::forward<T0> (d0),
+		      std::forward<V> (v),
+		      std::forward<Ts> (ds)...);
   }
 
   private:
@@ -324,7 +327,7 @@
 #define HB_PARTIALIZE(Pos) \
   template <typename _T> \
   decltype(auto) operator () (_T&& _v) const \
-  { return hb_partial<Pos> (this, hb_forward<_T> (_v)); } \
+  { return hb_partial<Pos> (this, std::forward<_T> (_v)); } \
   static_assert (true, "")
 #else
 /* https://github.com/harfbuzz/harfbuzz/issues/1724 */
@@ -331,7 +334,7 @@
 #define HB_PARTIALIZE(Pos) \
   template <typename _T> \
   auto operator () (_T&& _v) const HB_AUTO_RETURN \
-  (hb_partial<Pos> (+this, hb_forward<_T> (_v))) \
+  (hb_partial<Pos> (+this, std::forward<_T> (_v))) \
   static_assert (true, "")
 #endif
 
@@ -343,14 +346,14 @@
   template <typename Pred, typename Val> auto
   impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
   (
-    hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v))
+    hb_deref (std::forward<Pred> (p)).has (std::forward<Val> (v))
   )
 
   template <typename Pred, typename Val> auto
   impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
   (
-    hb_invoke (hb_forward<Pred> (p),
-	       hb_forward<Val> (v))
+    hb_invoke (std::forward<Pred> (p),
+	       std::forward<Val> (v))
   )
 
   public:
@@ -357,8 +360,8 @@
 
   template <typename Pred, typename Val> auto
   operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
-    impl (hb_forward<Pred> (p),
-	  hb_forward<Val> (v),
+    impl (std::forward<Pred> (p),
+	  std::forward<Val> (v),
 	  hb_prioritize)
   )
 }
@@ -371,14 +374,14 @@
   template <typename Pred, typename Val> auto
   impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
   (
-    hb_has (hb_forward<Pred> (p),
-	    hb_forward<Val> (v))
+    hb_has (std::forward<Pred> (p),
+	    std::forward<Val> (v))
   )
 
   template <typename Pred, typename Val> auto
   impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
   (
-    hb_forward<Pred> (p) == hb_forward<Val> (v)
+    std::forward<Pred> (p) == std::forward<Val> (v)
   )
 
   public:
@@ -385,8 +388,8 @@
 
   template <typename Pred, typename Val> auto
   operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
-    impl (hb_forward<Pred> (p),
-	  hb_forward<Val> (v),
+    impl (std::forward<Pred> (p),
+	  std::forward<Val> (v),
 	  hb_prioritize)
   )
 }
@@ -399,20 +402,20 @@
   template <typename Proj, typename Val> auto
   impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
   (
-    hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v))
+    hb_deref (std::forward<Proj> (f)).get (std::forward<Val> (v))
   )
 
   template <typename Proj, typename Val> auto
   impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
   (
-    hb_invoke (hb_forward<Proj> (f),
-	       hb_forward<Val> (v))
+    hb_invoke (std::forward<Proj> (f),
+	       std::forward<Val> (v))
   )
 
   template <typename Proj, typename Val> auto
   impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
   (
-    hb_forward<Proj> (f)[hb_forward<Val> (v)]
+    std::forward<Proj> (f)[std::forward<Val> (v)]
   )
 
   public:
@@ -420,8 +423,8 @@
   template <typename Proj, typename Val> auto
   operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN
   (
-    impl (hb_forward<Proj> (f),
-	  hb_forward<Val> (v),
+    impl (std::forward<Proj> (f),
+	  std::forward<Val> (v),
 	  hb_prioritize)
   )
 }
@@ -434,19 +437,19 @@
   template <typename T1, typename T2> auto
   impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
   (
-    hb_forward<T2> (v2).cmp (hb_forward<T1> (v1)) == 0
+    std::forward<T2> (v2).cmp (std::forward<T1> (v1)) == 0
   )
 
   template <typename T1, typename T2> auto
   impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
   (
-    hb_forward<T1> (v1).cmp (hb_forward<T2> (v2)) == 0
+    std::forward<T1> (v1).cmp (std::forward<T2> (v2)) == 0
   )
 
   template <typename T1, typename T2> auto
   impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
   (
-    hb_forward<T1> (v1) == hb_forward<T2> (v2)
+    std::forward<T1> (v1) == std::forward<T2> (v2)
   )
 
   public:
@@ -454,8 +457,8 @@
   template <typename T1, typename T2> auto
   operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN
   (
-    impl (hb_forward<T1> (v1),
-	  hb_forward<T2> (v2),
+    impl (std::forward<T1> (v1),
+	  std::forward<T2> (v2),
 	  hb_prioritize)
   )
 }
@@ -515,7 +518,7 @@
 {
   template <typename T, typename T2> constexpr auto
   operator () (T&& a, T2&& b) const HB_AUTO_RETURN
-  (a <= b ? hb_forward<T> (a) : hb_forward<T2> (b))
+  (a <= b ? std::forward<T> (a) : std::forward<T2> (b))
 }
 HB_FUNCOBJ (hb_min);
 struct
@@ -522,7 +525,7 @@
 {
   template <typename T, typename T2> constexpr auto
   operator () (T&& a, T2&& b) const HB_AUTO_RETURN
-  (a >= b ? hb_forward<T> (a) : hb_forward<T2> (b))
+  (a >= b ? std::forward<T> (a) : std::forward<T2> (b))
 }
 HB_FUNCOBJ (hb_max);
 struct
@@ -529,10 +532,20 @@
 {
   template <typename T, typename T2, typename T3> constexpr auto
   operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN
-  (hb_min (hb_max (hb_forward<T> (x), hb_forward<T2> (min)), hb_forward<T3> (max)))
+  (hb_min (hb_max (std::forward<T> (x), std::forward<T2> (min)), std::forward<T3> (max)))
 }
 HB_FUNCOBJ (hb_clamp);
 
+struct
+{
+  template <typename T> void
+  operator () (T& a, T& b) const
+  {
+    using std::swap; // allow ADL
+    swap (a, b);
+  }
+}
+HB_FUNCOBJ (hb_swap);
 
 /*
  * Bithacks.
@@ -795,7 +808,7 @@
 template <typename T> static inline bool
 hb_in_range (T u, T lo, T hi)
 {
-  static_assert (!hb_is_signed<T>::value, "");
+  static_assert (!std::is_signed<T>::value, "");
 
   /* The casts below are important as if T is smaller than int,
    * the subtract results will become a signed int! */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -50,10 +50,10 @@
   /*
    * Constructors.
    */
-  hb_array_t () : arrayZ (nullptr), length (0), backwards_length (0) {}
-  hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_), backwards_length (0) {}
+  hb_array_t () = default;
+  hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
   template <unsigned int length_>
-  hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {}
+  hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {}
 
   template <typename U,
 	    hb_enable_if (hb_is_cr_convertible(U, Type))>
@@ -281,9 +281,9 @@
    */
 
   public:
-  Type *arrayZ;
-  unsigned int length;
-  unsigned int backwards_length;
+  Type *arrayZ = nullptr;
+  unsigned int length = 0;
+  unsigned int backwards_length = 0;
 };
 template <typename T> inline hb_array_t<T>
 hb_array (T *array, unsigned int length)
@@ -302,7 +302,7 @@
   static constexpr bool is_random_access_iterator = true;
   static constexpr bool is_sorted_iterator = true;
 
-  hb_sorted_array_t () : hb_array_t<Type> () {}
+  hb_sorted_array_t () = default;
   hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
   template <unsigned int length_>
   hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -102,20 +102,12 @@
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)	_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
 
 
-#elif defined(HB_NO_MT)
+#else /* defined(HB_NO_MT) */
 
 #define hb_atomic_int_impl_add(AI, V)		((*(AI) += (V)) - (V))
-
 #define _hb_memory_barrier()			do {} while (0)
-
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)	(* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
 
-
-#else
-
-#error "Could not find any system to define atomic_int macros."
-#error "Check hb-atomic.hh for possible resolutions."
-
 #endif
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -33,9 +33,7 @@
 /* Bi-directional map */
 struct hb_bimap_t
 {
-  hb_bimap_t () { init (); }
-  ~hb_bimap_t () { fini (); }
-
+  /* XXX(remove) */
   void init ()
   {
     forw_map.init ();
@@ -42,6 +40,7 @@
     back_map.init ();
   }
 
+  /* XXX(remove) */
   void fini ()
   {
     forw_map.fini ();
@@ -99,14 +98,6 @@
 /* Inremental bimap: only lhs is given, rhs is incrementally assigned */
 struct hb_inc_bimap_t : hb_bimap_t
 {
-  hb_inc_bimap_t () { init (); }
-
-  void init ()
-  {
-    hb_bimap_t::init ();
-    next_value = 0;
-  }
-
   /* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
    * Return the rhs value as the result.
    */
@@ -165,7 +156,7 @@
   }
 
   protected:
-  unsigned int	next_value;
+  unsigned int next_value = 0;
 };
 
 #endif /* HB_BIMAP_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -35,10 +35,20 @@
 struct hb_bit_set_invertible_t
 {
   hb_bit_set_t s;
-  bool inverted;
+  bool inverted = false;
 
-  hb_bit_set_invertible_t () { init (); }
-  ~hb_bit_set_invertible_t () { fini (); }
+  hb_bit_set_invertible_t () = default;
+  hb_bit_set_invertible_t (hb_bit_set_invertible_t& o) = default;
+  hb_bit_set_invertible_t (hb_bit_set_invertible_t&& o) = default;
+  hb_bit_set_invertible_t& operator= (const hb_bit_set_invertible_t& o) = default;
+  hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& o) = default;
+  friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b)
+  {
+    if (likely (!a.s.successful || !b.s.successful))
+      return;
+    hb_swap (a.inverted, b.inverted);
+    hb_swap (a.s, b.s);
+  }
 
   void init () { s.init (); inverted = false; }
   void fini () { s.fini (); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -35,13 +35,22 @@
 
 struct hb_bit_set_t
 {
-  hb_bit_set_t () { init (); }
-  ~hb_bit_set_t () { fini (); }
+  hb_bit_set_t () = default;
+  ~hb_bit_set_t () = default;
 
   hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other); }
-  void operator= (const hb_bit_set_t& other) { set (other); }
-  // TODO Add move construtor/assign
-  // TODO Add constructor for Iterator; with specialization for (sorted) vector / array?
+  hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); }
+  hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; }
+  hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; }
+  friend void swap (hb_bit_set_t &a, hb_bit_set_t &b)
+  {
+    if (likely (!a.successful || !b.successful))
+      return;
+    hb_swap (a.population, b.population);
+    hb_swap (a.last_page_lookup, b.last_page_lookup);
+    hb_swap (a.page_map, b.page_map);
+    hb_swap (a.pages, b.pages);
+  }
 
   void init ()
   {
@@ -67,9 +76,9 @@
     uint32_t index;
   };
 
-  bool successful; /* Allocations successful */
-  mutable unsigned int population;
-  mutable unsigned int last_page_lookup;
+  bool successful = true; /* Allocations successful */
+  mutable unsigned int population = 0;
+  mutable unsigned int last_page_lookup = 0;
   hb_sorted_vector_t<page_map_t> page_map;
   hb_vector_t<page_t> pages;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -224,6 +224,7 @@
   flags = HB_BUFFER_FLAG_DEFAULT;
   replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
   invisible = 0;
+  not_found = 0;
 
   clear ();
 }
@@ -608,6 +609,7 @@
   HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
   HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
   0, /* invisible */
+  0, /* not_found */
   HB_BUFFER_SCRATCH_FLAG_DEFAULT,
   HB_BUFFER_MAX_LEN_DEFAULT,
   HB_BUFFER_MAX_OPS_DEFAULT,
@@ -1158,8 +1160,48 @@
   return buffer->invisible;
 }
 
+/**
+ * hb_buffer_set_not_found_glyph:
+ * @buffer: An #hb_buffer_t
+ * @not_found: the not-found #hb_codepoint_t
+ *
+ * Sets the #hb_codepoint_t that replaces characters not found in
+ * the font during shaping.
+ *
+ * The not-found glyph defaults to zero, sometimes knows as the
+ * ".notdef" glyph.  This API allows for differentiating the two.
+ *
+ * Since: 3.1.0
+ **/
+void
+hb_buffer_set_not_found_glyph (hb_buffer_t    *buffer,
+			       hb_codepoint_t  not_found)
+{
+  if (unlikely (hb_object_is_immutable (buffer)))
+    return;
 
+  buffer->not_found = not_found;
+}
+
 /**
+ * hb_buffer_get_not_found_glyph:
+ * @buffer: An #hb_buffer_t
+ *
+ * See hb_buffer_set_not_found_glyph().
+ *
+ * Return value:
+ * The @buffer not-found #hb_codepoint_t
+ *
+ * Since: 3.1.0
+ **/
+hb_codepoint_t
+hb_buffer_get_not_found_glyph (hb_buffer_t    *buffer)
+{
+  return buffer->not_found;
+}
+
+
+/**
  * hb_buffer_reset:
  * @buffer: An #hb_buffer_t
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2021-11-04 00:51:18 UTC (rev 60943)
@@ -383,7 +383,14 @@
 HB_EXTERN hb_codepoint_t
 hb_buffer_get_invisible_glyph (hb_buffer_t    *buffer);
 
+HB_EXTERN void
+hb_buffer_set_not_found_glyph (hb_buffer_t    *buffer,
+			       hb_codepoint_t  not_found);
 
+HB_EXTERN hb_codepoint_t
+hb_buffer_get_not_found_glyph (hb_buffer_t    *buffer);
+
+
 HB_EXTERN void
 hb_buffer_reset (hb_buffer_t *buffer);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -93,6 +93,7 @@
   hb_buffer_cluster_level_t cluster_level;
   hb_codepoint_t replacement; /* U+FFFD or something else. */
   hb_codepoint_t invisible; /* 0 or something else. */
+  hb_codepoint_t not_found; /* 0 or something else. */
   hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
   unsigned int max_len; /* Maximum allowed len. */
   int max_ops; /* Maximum allowed operations. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -302,7 +302,7 @@
   {
     if (unlikely (returned)) {
       fprintf (stderr, "OUCH, double calls to return_trace().  This is a bug, please report.\n");
-      return hb_forward<T> (v);
+      return std::forward<T> (v);
     }
 
     _hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1,
@@ -311,7 +311,7 @@
     if (plevel) --*plevel;
     plevel = nullptr;
     returned = true;
-    return hb_forward<T> (v);
+    return std::forward<T> (v);
   }
 
   private:
@@ -333,7 +333,7 @@
   template <typename T>
   T ret (T&& v,
 	 const char *func HB_UNUSED = nullptr,
-	 unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); }
+	 unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); }
 };
 
 /* For disabled tracing; optimize out everything.
@@ -343,7 +343,7 @@
   template <typename T>
   T ret (T&& v,
 	 const char *func HB_UNUSED = nullptr,
-	 unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); }
+	 unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); }
 };
 
 #define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -43,6 +43,14 @@
  * Functions for using HarfBuzz with DirectWrite fonts.
  **/
 
+/* Declare object creator for dynamic support of DWRITE */
+typedef HRESULT (* WINAPI t_DWriteCreateFactory)(
+  DWRITE_FACTORY_TYPE factoryType,
+  REFIID              iid,
+  IUnknown            **factory
+);
+
+
 /*
  * DirectWrite font stream helpers
  */
@@ -137,6 +145,7 @@
 
 struct hb_directwrite_face_data_t
 {
+  HMODULE dwrite_dll;
   IDWriteFactory *dwriteFactory;
   IDWriteFontFile *fontFile;
   DWriteFontFileStream *fontFileStream;
@@ -158,12 +167,33 @@
     return nullptr; \
   } HB_STMT_END
 
+  data->dwrite_dll = LoadLibrary (TEXT ("DWRITE"));
+  if (unlikely (!data->dwrite_dll))
+    FAIL ("Cannot find DWrite.DLL");
+
+  t_DWriteCreateFactory p_DWriteCreateFactory;
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-function-type"
+#endif
+
+  p_DWriteCreateFactory = (t_DWriteCreateFactory)
+			  GetProcAddress (data->dwrite_dll, "DWriteCreateFactory");
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+  if (unlikely (!p_DWriteCreateFactory))
+    FAIL ("Cannot find DWriteCreateFactory().");
+
   HRESULT hr;
 
   // TODO: factory and fontFileLoader should be cached separately
   IDWriteFactory* dwriteFactory;
-  hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
-			    (IUnknown**) &dwriteFactory);
+  hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
+			      (IUnknown**) &dwriteFactory);
 
   if (unlikely (hr != S_OK))
     FAIL ("Failed to run DWriteCreateFactory().");
@@ -227,6 +257,8 @@
     delete data->fontFileStream;
   if (data->faceBlob)
     hb_blob_destroy (data->faceBlob);
+  if (data->dwrite_dll)
+    FreeLibrary (data->dwrite_dll);
   if (data)
     delete data;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dispatch.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dispatch.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dispatch.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -50,7 +50,7 @@
   bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; }
   template <typename T, typename ...Ts>
   return_t dispatch (const T &obj, Ts&&... ds)
-  { return obj.dispatch (thiz (), hb_forward<Ts> (ds)...); }
+  { return obj.dispatch (thiz (), std::forward<Ts> (ds)...); }
   static return_t no_dispatch_return_value () { return Context::default_return_value (); }
   static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; }
   unsigned debug_depth = 0;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -217,9 +217,10 @@
   }
 
   hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
-			       hb_codepoint_t *glyph)
+			       hb_codepoint_t *glyph,
+			       hb_codepoint_t not_found = 0)
   {
-    *glyph = 0;
+    *glyph = not_found;
     return klass->get.f.nominal_glyph (this, user_data,
 				       unicode, glyph,
 				       klass->user_data.nominal_glyph);
@@ -238,9 +239,10 @@
   }
 
   hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
-				 hb_codepoint_t *glyph)
+				 hb_codepoint_t *glyph,
+				 hb_codepoint_t not_found = 0)
   {
-    *glyph = 0;
+    *glyph = not_found;
     return klass->get.f.variation_glyph (this, user_data,
 					 unicode, variation_selector, glyph,
 					 klass->user_data.variation_glyph);
@@ -618,9 +620,7 @@
   }
 
   hb_position_t em_mult (int16_t v, int64_t mult)
-  {
-    return (hb_position_t) ((v * mult) >> 16);
-  }
+  { return (hb_position_t) ((v * mult + 32768) >> 16); }
   hb_position_t em_scalef (float v, int scale)
   { return (hb_position_t) roundf (v * scale / face->get_upem ()); }
   float em_fscale (int16_t v, int scale)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -162,7 +162,7 @@
 {
   template <typename T> hb_iter_type<T>
   operator () (T&& c) const
-  { return hb_deref (hb_forward<T> (c)).iter (); }
+  { return hb_deref (std::forward<T> (c)).iter (); }
 
   /* Specialization for C arrays. */
 
@@ -353,7 +353,7 @@
 template <typename Lhs, typename Rhs,
 	  hb_requires (hb_is_iterator (Lhs))>
 static inline auto
-operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (hb_forward<Rhs> (rhs) (hb_forward<Lhs> (lhs)))
+operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (std::forward<Rhs> (rhs) (std::forward<Lhs> (lhs)))
 
 /* hb_map(), hb_filter(), hb_reduce() */
 
@@ -674,8 +674,8 @@
   template <typename S2 = S>
   auto
   inc (hb_type_identity<S2> s, hb_priority<1>)
-    -> hb_void_t<decltype (hb_invoke (hb_forward<S2> (s), hb_declval<T&> ()))>
-  { v = hb_invoke (hb_forward<S2> (s), v); }
+    -> hb_void_t<decltype (hb_invoke (std::forward<S2> (s), hb_declval<T&> ()))>
+  { v = hb_invoke (std::forward<S2> (s), v); }
 
   void
   inc (S s, hb_priority<0>)
@@ -874,7 +874,7 @@
 		    Proj&& f = hb_identity) const
   {
     for (auto it = hb_iter (c); it; ++it)
-      if (!hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+      if (!hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
 	return false;
     return true;
   }
@@ -891,7 +891,7 @@
 		    Proj&& f = hb_identity) const
   {
     for (auto it = hb_iter (c); it; ++it)
-      if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+      if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
 	return true;
     return false;
   }
@@ -908,7 +908,7 @@
 		    Proj&& f = hb_identity) const
   {
     for (auto it = hb_iter (c); it; ++it)
-      if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+      if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
 	return false;
     return true;
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -35,17 +35,36 @@
  */
 
 template <typename K, typename V,
-	  K kINVALID = hb_is_pointer (K) ? 0 : hb_is_signed (K) ? hb_int_min (K) : (K) -1,
-	  V vINVALID = hb_is_pointer (V) ? 0 : hb_is_signed (V) ? hb_int_min (V) : (V) -1>
+	  K kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
+	  V vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
 struct hb_hashmap_t
 {
-  HB_DELETE_COPY_ASSIGN (hb_hashmap_t);
+  static constexpr K INVALID_KEY   = kINVALID;
+  static constexpr V INVALID_VALUE = vINVALID;
+
   hb_hashmap_t ()  { init (); }
   ~hb_hashmap_t () { fini (); }
 
-  static_assert (hb_is_integral (K) || hb_is_pointer (K), "");
-  static_assert (hb_is_integral (V) || hb_is_pointer (V), "");
+  hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { hb_copy (o, *this); }
+  hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); }
+  hb_hashmap_t& operator= (const hb_hashmap_t& o)  { hb_copy (o, *this); return *this; }
+  hb_hashmap_t& operator= (hb_hashmap_t&& o)  { hb_swap (*this, o); return *this; }
 
+  hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t ()
+  {
+    for (auto&& item : lst)
+      set (item.first, item.second);
+  }
+  template <typename Iterable,
+	    hb_requires (hb_is_iterable (Iterable))>
+  hb_hashmap_t (const Iterable &o) : hb_hashmap_t ()
+  {
+    hb_copy (o, *this);
+  }
+
+  static_assert (std::is_integral<K>::value || hb_is_pointer (K), "");
+  static_assert (std::is_integral<V>::value || hb_is_pointer (V), "");
+
   struct item_t
   {
     K key;
@@ -70,6 +89,16 @@
   unsigned int prime;
   item_t *items;
 
+  friend void swap (hb_hashmap_t& a, hb_hashmap_t& b)
+  {
+    if (unlikely (!a.successful || !b.successful))
+      return;
+    hb_swap (a.population, b.population);
+    hb_swap (a.occupancy, b.occupancy);
+    hb_swap (a.mask, b.mask);
+    hb_swap (a.prime, b.prime);
+    hb_swap (a.items, b.items);
+  }
   void init_shallow ()
   {
     successful = true;
@@ -133,7 +162,7 @@
 	if (old_items[i].is_real ())
 	  set_with_hash (old_items[i].key,
 			 old_items[i].hash,
-			 old_items[i].value);
+			 std::move (old_items[i].value));
 
     hb_free (old_items);
 
@@ -140,10 +169,8 @@
     return true;
   }
 
-  bool set (K key, V value)
-  {
-    return set_with_hash (key, hb_hash (key), value);
-  }
+  bool set (K key, const V& value) { return set_with_hash (key, hb_hash (key), value); }
+  bool set (K key, V&& value) { return set_with_hash (key, hb_hash (key), std::move (value)); }
 
   V get (K key) const
   {
@@ -213,7 +240,8 @@
 
   protected:
 
-  bool set_with_hash (K key, uint32_t hash, V value)
+  template <typename VV>
+  bool set_with_hash (K key, uint32_t hash, VV&& value)
   {
     if (unlikely (!successful)) return false;
     if (unlikely (key == kINVALID)) return true;
@@ -321,7 +349,22 @@
 struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
 			       hb_codepoint_t,
 			       HB_MAP_VALUE_INVALID,
-			       HB_MAP_VALUE_INVALID> {};
+			       HB_MAP_VALUE_INVALID>
+{
+  using hashmap = hb_hashmap_t<hb_codepoint_t,
+			       hb_codepoint_t,
+			       HB_MAP_VALUE_INVALID,
+			       HB_MAP_VALUE_INVALID>;
 
+  hb_map_t () = default;
+  ~hb_map_t () = default;
+  hb_map_t (hb_map_t& o) = default;
+  hb_map_t& operator= (const hb_map_t& other) = default;
+  hb_map_t& operator= (hb_map_t&& other) = default;
+  hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {}
+  template <typename Iterable,
+	    hb_requires (hb_is_iterable (Iterable))>
+  hb_map_t (const Iterable &o) : hashmap (o) {}
+};
 
 #endif /* HB_MAP_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -29,7 +29,10 @@
 
 #include "hb.hh"
 
+#include <type_traits>
+#include <utility>
 
+
 /*
  * C++ template meta-programming & fundamentals used with them.
  */
@@ -129,42 +132,9 @@
 /* TODO Add feature-parity to std::decay. */
 template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
 
+#define hb_is_convertible(From,To) std::is_convertible<From, To>::value
 
-template<bool B, class T, class F>
-struct _hb_conditional { typedef T type; };
-template<class T, class F>
-struct _hb_conditional<false, T, F> { typedef F type; };
-template<bool B, class T, class F>
-using hb_conditional = typename _hb_conditional<B, T, F>::type;
-
-
 template <typename From, typename To>
-struct hb_is_convertible
-{
-  private:
-  static constexpr bool   from_void = hb_is_same (void, hb_decay<From>);
-  static constexpr bool     to_void = hb_is_same (void, hb_decay<To>  );
-  static constexpr bool either_void = from_void || to_void;
-  static constexpr bool   both_void = from_void && to_void;
-
-  static hb_true_type impl2 (hb_conditional<to_void, int, To>);
-
-  template <typename T>
-  static auto impl (hb_priority<1>) -> decltype (impl2 (hb_declval (T)));
-  template <typename T>
-  static hb_false_type impl (hb_priority<0>);
-  public:
-  static constexpr bool value = both_void ||
-		       (!either_void &&
-			decltype (impl<hb_conditional<from_void, int, From>> (hb_prioritize))::value);
-};
-#define hb_is_convertible(From,To) hb_is_convertible<From, To>::value
-
-template <typename Base, typename Derived>
-using hb_is_base_of = hb_is_convertible<hb_decay<Derived> *, hb_decay<Base> *>;
-#define hb_is_base_of(Base,Derived) hb_is_base_of<Base, Derived>::value
-
-template <typename From, typename To>
 using hb_is_cr_convertible = hb_bool_constant<
   hb_is_same (hb_decay<From>, hb_decay<To>) &&
   (!hb_is_const (From) || hb_is_const (To)) &&
@@ -172,20 +142,11 @@
 >;
 #define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
 
-/* std::move and std::forward */
 
-template <typename T>
-static constexpr hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
-
-template <typename T>
-static constexpr T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
-template <typename T>
-static constexpr T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
-
 struct
 {
   template <typename T> constexpr auto
-  operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
+  operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v))
 
   template <typename T> constexpr auto
   operator () (T *v) const HB_AUTO_RETURN (*v)
@@ -195,7 +156,7 @@
 struct
 {
   template <typename T> constexpr auto
-  operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
+  operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v))
 
   template <typename T> constexpr auto
   operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
@@ -226,50 +187,6 @@
 
 /* Type traits */
 
-template <typename T>
-using hb_is_integral = hb_bool_constant<
-  hb_is_same (hb_decay<T>, char) ||
-  hb_is_same (hb_decay<T>, signed char) ||
-  hb_is_same (hb_decay<T>, unsigned char) ||
-  hb_is_same (hb_decay<T>, signed int) ||
-  hb_is_same (hb_decay<T>, unsigned int) ||
-  hb_is_same (hb_decay<T>, signed short) ||
-  hb_is_same (hb_decay<T>, unsigned short) ||
-  hb_is_same (hb_decay<T>, signed long) ||
-  hb_is_same (hb_decay<T>, unsigned long) ||
-  hb_is_same (hb_decay<T>, signed long long) ||
-  hb_is_same (hb_decay<T>, unsigned long long) ||
-  false
->;
-#define hb_is_integral(T) hb_is_integral<T>::value
-template <typename T>
-using hb_is_floating_point = hb_bool_constant<
-  hb_is_same (hb_decay<T>, float) ||
-  hb_is_same (hb_decay<T>, double) ||
-  hb_is_same (hb_decay<T>, long double) ||
-  false
->;
-#define hb_is_floating_point(T) hb_is_floating_point<T>::value
-template <typename T>
-using hb_is_arithmetic = hb_bool_constant<
-  hb_is_integral (T) ||
-  hb_is_floating_point (T) ||
-  false
->;
-#define hb_is_arithmetic(T) hb_is_arithmetic<T>::value
-
-
-template <typename T, bool is_arithmetic> struct hb_is_signed_;
-template <typename T> struct hb_is_signed_<T, false>	: hb_false_type {};
-template <typename T> struct hb_is_signed_<T, true>	: hb_bool_constant<(T) -1 < (T) 0> {};
-template <typename T> struct hb_is_signed : hb_is_signed_<T, hb_is_arithmetic (T)> {};
-#define hb_is_signed(T) hb_is_signed<T>::value
-template <typename T, bool is_arithmetic> struct hb_is_unsigned_;
-template <typename T> struct hb_is_unsigned_<T, false>	: hb_false_type {};
-template <typename T> struct hb_is_unsigned_<T, true>	: hb_bool_constant<(T) 0 < (T) -1> {};
-template <typename T> struct hb_is_unsigned : hb_is_unsigned_<T, hb_is_arithmetic (T)> {};
-#define hb_is_unsigned(T) hb_is_unsigned<T>::value
-
 template <typename T> struct hb_int_min;
 template <> struct hb_int_min<char>			: hb_integral_constant<char,			CHAR_MIN>	{};
 template <> struct hb_int_min<signed char>		: hb_integral_constant<signed char,		SCHAR_MIN>	{};
@@ -309,108 +226,6 @@
   TypeName(const TypeName&) = delete; \
   void operator=(const TypeName&) = delete
 
-template <typename T, typename>
-struct _hb_is_destructible : hb_false_type {};
-template <typename T>
-struct _hb_is_destructible<T, hb_void_t<decltype (hb_declval (T).~T ())>> : hb_true_type {};
-template <typename T>
-using hb_is_destructible = _hb_is_destructible<T, void>;
-#define hb_is_destructible(T) hb_is_destructible<T>::value
-
-template <typename T, typename, typename ...Ts>
-struct _hb_is_constructible : hb_false_type {};
-template <typename T, typename ...Ts>
-struct _hb_is_constructible<T, hb_void_t<decltype (T (hb_declval (Ts)...))>, Ts...> : hb_true_type {};
-template <typename T, typename ...Ts>
-using hb_is_constructible = _hb_is_constructible<T, void, Ts...>;
-#define hb_is_constructible(...) hb_is_constructible<__VA_ARGS__>::value
-
-template <typename T>
-using hb_is_default_constructible = hb_is_constructible<T>;
-#define hb_is_default_constructible(T) hb_is_default_constructible<T>::value
-
-template <typename T>
-using hb_is_copy_constructible = hb_is_constructible<T, hb_add_lvalue_reference<hb_add_const<T>>>;
-#define hb_is_copy_constructible(T) hb_is_copy_constructible<T>::value
-
-template <typename T>
-using hb_is_move_constructible = hb_is_constructible<T, hb_add_rvalue_reference<hb_add_const<T>>>;
-#define hb_is_move_constructible(T) hb_is_move_constructible<T>::value
-
-template <typename T, typename U, typename>
-struct _hb_is_assignable : hb_false_type {};
-template <typename T, typename U>
-struct _hb_is_assignable<T, U, hb_void_t<decltype (hb_declval (T) = hb_declval (U))>> : hb_true_type {};
-template <typename T, typename U>
-using hb_is_assignable = _hb_is_assignable<T, U, void>;
-#define hb_is_assignable(T,U) hb_is_assignable<T, U>::value
-
-template <typename T>
-using hb_is_copy_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
-					       hb_add_lvalue_reference<hb_add_const<T>>>;
-#define hb_is_copy_assignable(T) hb_is_copy_assignable<T>::value
-
-template <typename T>
-using hb_is_move_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
-					       hb_add_rvalue_reference<T>>;
-#define hb_is_move_assignable(T) hb_is_move_assignable<T>::value
-
-/* Trivial versions. */
-
-template <typename T> union hb_trivial { T value; };
-
-template <typename T>
-using hb_is_trivially_destructible= hb_is_destructible<hb_trivial<T>>;
-#define hb_is_trivially_destructible(T) hb_is_trivially_destructible<T>::value
-
-/* Don't know how to do the following. */
-//template <typename T, typename ...Ts>
-//using hb_is_trivially_constructible= hb_is_constructible<hb_trivial<T>, hb_trivial<Ts>...>;
-//#define hb_is_trivially_constructible(...) hb_is_trivially_constructible<__VA_ARGS__>::value
-
-template <typename T>
-using hb_is_trivially_default_constructible= hb_is_default_constructible<hb_trivial<T>>;
-#define hb_is_trivially_default_constructible(T) hb_is_trivially_default_constructible<T>::value
-
-template <typename T>
-using hb_is_trivially_copy_constructible= hb_is_copy_constructible<hb_trivial<T>>;
-#define hb_is_trivially_copy_constructible(T) hb_is_trivially_copy_constructible<T>::value
-
-template <typename T>
-using hb_is_trivially_move_constructible= hb_is_move_constructible<hb_trivial<T>>;
-#define hb_is_trivially_move_constructible(T) hb_is_trivially_move_constructible<T>::value
-
-/* Don't know how to do the following. */
-//template <typename T, typename U>
-//using hb_is_trivially_assignable= hb_is_assignable<hb_trivial<T>, hb_trivial<U>>;
-//#define hb_is_trivially_assignable(T,U) hb_is_trivially_assignable<T, U>::value
-
-template <typename T>
-using hb_is_trivially_copy_assignable= hb_is_copy_assignable<hb_trivial<T>>;
-#define hb_is_trivially_copy_assignable(T) hb_is_trivially_copy_assignable<T>::value
-
-template <typename T>
-using hb_is_trivially_move_assignable= hb_is_move_assignable<hb_trivial<T>>;
-#define hb_is_trivially_move_assignable(T) hb_is_trivially_move_assignable<T>::value
-
-template <typename T>
-using hb_is_trivially_copyable= hb_bool_constant<
-  hb_is_trivially_destructible (T) &&
-  (!hb_is_move_assignable (T) || hb_is_trivially_move_assignable (T)) &&
-  (!hb_is_move_constructible (T) || hb_is_trivially_move_constructible (T)) &&
-  (!hb_is_copy_assignable (T) || hb_is_trivially_copy_assignable (T)) &&
-  (!hb_is_copy_constructible (T) || hb_is_trivially_copy_constructible (T)) &&
-  true
->;
-#define hb_is_trivially_copyable(T) hb_is_trivially_copyable<T>::value
-
-template <typename T>
-using hb_is_trivial= hb_bool_constant<
-  hb_is_trivially_copyable (T) &&
-  hb_is_trivially_default_constructible (T)
->;
-#define hb_is_trivial(T) hb_is_trivial<T>::value
-
 /* hb_unwrap_type (T)
  * If T has no T::type, returns T. Otherwise calls itself on T::type recursively.
  */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -47,7 +47,7 @@
 /* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */
 
 
-#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
+#elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
 
 #include <pthread.h>
 typedef pthread_mutex_t hb_mutex_impl_t;
@@ -57,7 +57,7 @@
 #define hb_mutex_impl_finish(M)	pthread_mutex_destroy (M)
 
 
-#elif !defined(HB_NO_MT) && defined(_WIN32)
+#elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && defined(_WIN32)
 
 typedef CRITICAL_SECTION hb_mutex_impl_t;
 #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
@@ -70,8 +70,18 @@
 #define hb_mutex_impl_finish(M)	DeleteCriticalSection (M)
 
 
-#elif defined(HB_NO_MT)
+#elif !defined(HB_NO_MT)
 
+#include <mutex>
+typedef std::mutex              hb_mutex_impl_t;
+#define hb_mutex_impl_init(M)   HB_STMT_START { new (M) hb_mutex_impl_t; } HB_STMT_END
+#define hb_mutex_impl_lock(M)   (M)->lock ()
+#define hb_mutex_impl_unlock(M) (M)->unlock ()
+#define hb_mutex_impl_finish(M) HB_STMT_START { (M)->~hb_mutex_impl_t(); } HB_STMT_END
+
+
+#else /* defined(HB_NO_MT) */
+
 typedef int hb_mutex_impl_t;
 #define hb_mutex_impl_init(M)	HB_STMT_START {} HB_STMT_END
 #define hb_mutex_impl_lock(M)	HB_STMT_START {} HB_STMT_END
@@ -79,22 +89,18 @@
 #define hb_mutex_impl_finish(M)	HB_STMT_START {} HB_STMT_END
 
 
-#else
-
-#error "Could not find any system to define mutex macros."
-#error "Check hb-mutex.hh for possible resolutions."
-
 #endif
 
 
 struct hb_mutex_t
 {
-  hb_mutex_impl_t m;
+  /* Create space for, but do not initialize m. */
+  alignas(hb_mutex_impl_t) char m[sizeof (hb_mutex_impl_t)];
 
-  void init   () { hb_mutex_impl_init   (&m); }
-  void lock   () { hb_mutex_impl_lock   (&m); }
-  void unlock () { hb_mutex_impl_unlock (&m); }
-  void fini ()   { hb_mutex_impl_finish (&m); }
+  void init   () { hb_mutex_impl_init   ((hb_mutex_impl_t *) m); }
+  void lock   () { hb_mutex_impl_lock   ((hb_mutex_impl_t *) m); }
+  void unlock () { hb_mutex_impl_unlock ((hb_mutex_impl_t *) m); }
+  void fini   () { hb_mutex_impl_finish ((hb_mutex_impl_t *) m); }
 };
 
 struct hb_lock_t

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -64,7 +64,7 @@
   IntType& operator = (Type i) { v = i; return *this; }
   /* For reason we define cast out operator for signed/unsigned, instead of Type, see:
    * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */
-  operator hb_conditional<hb_is_signed (Type), signed, unsigned> () const { return v; }
+  operator typename std::conditional<std::is_signed<Type>::value, signed, unsigned>::type () const { return v; }
 
   bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
   bool operator != (const IntType &o) const { return !(*this == o); }
@@ -86,7 +86,7 @@
     return pb->cmp (*pa);
   }
   template <typename Type2,
-	    hb_enable_if (hb_is_integral (Type2) &&
+	    hb_enable_if (std::is_integral<Type2>::value &&
 			  sizeof (Type2) < sizeof (int) &&
 			  sizeof (Type) < sizeof (int))>
   int cmp (Type2 a) const
@@ -122,6 +122,15 @@
  * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */
 typedef IntType<uint32_t, 3> HBUINT24;	/* 24-bit unsigned integer. */
 
+/* 15-bit unsigned number; top bit used for extension. */
+struct HBUINT15 : HBUINT16
+{
+  /* TODO Flesh out; actually mask top bit. */
+  HBUINT15& operator = (uint16_t i ) { HBUINT16::operator= (i); return *this; }
+  public:
+  DEFINE_SIZE_STATIC (2);
+};
+
 /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
 typedef HBINT16 FWORD;
 
@@ -182,9 +191,9 @@
 };
 
 /* Glyph index number, same as uint16 (length = 16 bits) */
-struct HBGlyphID : HBUINT16
+struct HBGlyphID16 : HBUINT16
 {
-  HBGlyphID& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
+  HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
 };
 
 /* Script/language-system/feature index */
@@ -332,7 +341,7 @@
 
     s->push ();
 
-    bool ret = c->dispatch (src_base+src, hb_forward<Ts> (ds)...);
+    bool ret = c->dispatch (src_base+src, std::forward<Ts> (ds)...);
 
     if (ret || !has_null)
       s->add_link (*this, s->pop_pack ());
@@ -349,7 +358,7 @@
     *this = 0;
 
     Type* obj = c->push<Type> ();
-    bool ret = obj->serialize (c, hb_forward<Ts> (ds)...);
+    bool ret = obj->serialize (c, std::forward<Ts> (ds)...);
 
     if (ret)
       c->add_link (*this, c->pop_pack ());
@@ -375,7 +384,7 @@
 
     c->push ();
 
-    bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...);
+    bool ret = c->copy (src_base+src, std::forward<Ts> (ds)...);
 
     c->add_link (*this, c->pop_pack (), whence, dst_bias);
 
@@ -401,7 +410,7 @@
     TRACE_SANITIZE (this);
     return_trace (sanitize_shallow (c, base) &&
 		  (this->is_null () ||
-		   c->dispatch (StructAtOffset<Type> (base, *this), hb_forward<Ts> (ds)...) ||
+		   c->dispatch (StructAtOffset<Type> (base, *this), std::forward<Ts> (ds)...) ||
 		   neuter (c)));
   }
 
@@ -509,9 +518,9 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
+    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
+      if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }
@@ -556,7 +565,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace ((UnsizedArray16OfOffsetTo<Type, OffsetType, has_null>
-		   ::sanitize (c, count, this, hb_forward<Ts> (ds)...)));
+		   ::sanitize (c, count, this, std::forward<Ts> (ds)...)));
   }
 };
 
@@ -698,10 +707,10 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
+    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
+      if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }
@@ -759,7 +768,7 @@
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
-    return_trace (Array16OfOffset16To<Type>::sanitize (c, this, hb_forward<Ts> (ds)...));
+    return_trace (Array16OfOffset16To<Type>::sanitize (c, this, std::forward<Ts> (ds)...));
   }
 };
 
@@ -826,10 +835,10 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
+    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
     unsigned int count = get_length ();
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
+      if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }
@@ -875,10 +884,10 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
+    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
     unsigned int count = lenM1 + 1;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
+      if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }
@@ -1061,10 +1070,10 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
+    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
     unsigned int count = get_length ();
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(*this)[i].sanitize (c, hb_forward<Ts> (ds)...)))
+      if (unlikely (!(*this)[i].sanitize (c, std::forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -373,7 +373,7 @@
   {
     TRACE_SERIALIZE (this);
     for (unsigned int i = 0; i < dictval.get_count (); i++)
-      if (unlikely (!opszr.serialize (c, dictval[i], hb_forward<Ts> (ds)...)))
+      if (unlikely (!opszr.serialize (c, dictval[i], std::forward<Ts> (ds)...)))
 	return_trace (false);
 
     return_trace (true);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -604,7 +604,7 @@
   UINT		length;		/* Byte length of this subtable. */
   UINT		language;	/* Ignore. */
   UINT		startCharCode;	/* First character code covered. */
-  ArrayOf<HBGlyphID, UINT>
+  ArrayOf<HBGlyphID16, UINT>
 		glyphIdArray;	/* Array of glyph index values for character
 				 * codes in the range. */
   public:
@@ -900,7 +900,7 @@
   }
 
   HBUINT24	unicodeValue;	/* Base Unicode value of the UVS */
-  HBGlyphID	glyphID;	/* Glyph ID of the UVS */
+  HBGlyphID16	glyphID;	/* Glyph ID of the UVS */
   public:
   DEFINE_SIZE_STATIC (5);
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -508,8 +508,8 @@
 						   offset, length, format);
   }
 
-  HBGlyphID			firstGlyphIndex;
-  HBGlyphID			lastGlyphIndex;
+  HBGlyphID16			firstGlyphIndex;
+  HBGlyphID16			lastGlyphIndex;
   Offset32To<IndexSubtable>	offsetToSubtable;
   public:
   DEFINE_SIZE_STATIC (8);
@@ -679,8 +679,8 @@
   HBUINT32		colorRef;
   SBitLineMetrics	horizontal;
   SBitLineMetrics	vertical;
-  HBGlyphID		startGlyphIndex;
-  HBGlyphID		endGlyphIndex;
+  HBGlyphID16		startGlyphIndex;
+  HBGlyphID16		endGlyphIndex;
   HBUINT8		ppemX;
   HBUINT8		ppemY;
   HBUINT8		bitDepth;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -30,6 +30,7 @@
 
 #include "hb-open-type.hh"
 #include "hb-ot-layout-common.hh"
+#include "hb-ot-var-common.hh"
 
 /*
  * COLR -- Color
@@ -42,7 +43,7 @@
 #endif
 
 #ifndef COLRV1_ENABLE_SUBSETTING
-#define COLRV1_ENABLE_SUBSETTING 0
+#define COLRV1_ENABLE_SUBSETTING 1
 #endif
 
 namespace OT {
@@ -121,7 +122,7 @@
   }
 
   public:
-  HBGlyphID	glyphId;	/* Glyph ID of layer glyph */
+  HBGlyphID16	glyphId;	/* Glyph ID of layer glyph */
   Index		colorIdx;	/* Index value to use with a
 				 * selected color palette.
 				 * An index value of 0xFFFF
@@ -148,7 +149,7 @@
   }
 
   public:
-  HBGlyphID	glyphId;	/* Glyph ID of reference glyph */
+  HBGlyphID16	glyphId;	/* Glyph ID of reference glyph */
   HBUINT16	firstLayerIdx;	/* Index (from beginning of
 				 * the Layer Records) to the
 				 * layer record. There will be
@@ -163,15 +164,31 @@
 template <typename T>
 struct Variable
 {
+  Variable<T>* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { value.closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    if (!value.subset (c)) return_trace (false);
+    return_trace (c->serializer->embed (varIdxBase));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (c->check_struct (this) && value.sanitize (c));
   }
 
   protected:
   T      value;
-  VarIdx varIdx;
+  VarIdx varIdxBase;
   public:
   DEFINE_SIZE_STATIC (4 + T::static_size);
 };
@@ -179,51 +196,46 @@
 template <typename T>
 struct NoVariable
 {
-  bool sanitize (hb_sanitize_context_t *c) const
+  NoVariable<T>* copy (hb_serialize_context_t *c) const
   {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
   }
 
-  T      value;
-  public:
-  DEFINE_SIZE_STATIC (T::static_size);
-};
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { value.closurev1 (c); }
 
-// Color structures
-
-template <template<typename> class Var>
-struct ColorIndex
-{
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
-    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
-                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+    return_trace (value.subset (c));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (c->check_struct (this) && value.sanitize (c));
   }
 
-  HBUINT16	paletteIndex;
-  Var<F2DOT14>	alpha;
+  T      value;
   public:
-  DEFINE_SIZE_STATIC (2 + Var<F2DOT14>::static_size);
+  DEFINE_SIZE_STATIC (T::static_size);
 };
 
-template <template<typename> class Var>
+// Color structures
+
 struct ColorStop
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { c->add_palette_index (paletteIndex); }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    if (unlikely (!c->serializer->embed (stopOffset))) return_trace (false);
-    return_trace (color.subset (c));
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -232,10 +244,11 @@
     return_trace (c->check_struct (this));
   }
 
-  Var<F2DOT14>		stopOffset;
-  ColorIndex<Var>		color;
+  F2DOT14	stopOffset;
+  HBUINT16	paletteIndex;
+  F2DOT14	alpha;
   public:
-  DEFINE_SIZE_STATIC (Var<F2DOT14>::static_size + ColorIndex<Var>::static_size);
+  DEFINE_SIZE_STATIC (2 + 2 * F2DOT14::static_size);
 };
 
 struct Extend : HBUINT8
@@ -252,6 +265,12 @@
 template <template<typename> class Var>
 struct ColorLine
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    for (const auto &stop : stops.iter ())
+      stop.closurev1 (c);
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -276,8 +295,8 @@
                   stops.sanitize (c));
   }
 
-  Extend			extend;
-  Array16Of<ColorStop<Var>>	stops;
+  Extend	extend;
+  Array16Of<Var<ColorStop>>	stops;
   public:
   DEFINE_SIZE_ARRAY_SIZED (3, stops);
 };
@@ -331,7 +350,6 @@
   DEFINE_SIZE_STATIC (1);
 };
 
-template <template<typename> class Var>
 struct Affine2x3
 {
   bool sanitize (hb_sanitize_context_t *c) const
@@ -340,14 +358,14 @@
     return_trace (c->check_struct (this));
   }
 
-  Var<HBFixed> xx;
-  Var<HBFixed> yx;
-  Var<HBFixed> xy;
-  Var<HBFixed> yy;
-  Var<HBFixed> dx;
-  Var<HBFixed> dy;
+  HBFixed xx;
+  HBFixed yx;
+  HBFixed xy;
+  HBFixed yy;
+  HBFixed dx;
+  HBFixed dy;
   public:
-  DEFINE_SIZE_STATIC (6 * Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (6 * HBFixed::static_size);
 };
 
 struct PaintColrLayers
@@ -373,22 +391,23 @@
 
   HBUINT8	format; /* format = 1 */
   HBUINT8	numLayers;
-  HBUINT32	firstLayerIndex;  /* index into COLRv1::layersV1 */
+  HBUINT32	firstLayerIndex;  /* index into COLRv1::layerList */
   public:
   DEFINE_SIZE_STATIC (6);
 };
 
-template <template<typename> class Var>
 struct PaintSolid
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const
-  { c->add_palette_index (color.paletteIndex); }
+  { c->add_palette_index (paletteIndex); }
 
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    if (unlikely (!c->serializer->embed (format))) return_trace (false);
-    return_trace (color.subset (c));
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -397,10 +416,11 @@
     return_trace (c->check_struct (this));
   }
 
-  HBUINT8		format; /* format = 2(noVar) or 3(Var)*/
-  ColorIndex<Var>	color;
+  HBUINT8	format; /* format = 2(noVar) or 3(Var)*/
+  HBUINT16	paletteIndex;
+  F2DOT14	alpha;
   public:
-  DEFINE_SIZE_STATIC (1 + ColorIndex<Var>::static_size);
+  DEFINE_SIZE_STATIC (3 + F2DOT14::static_size);
 };
 
 template <template<typename> class Var>
@@ -407,10 +427,7 @@
 struct PaintLinearGradient
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const
-  {
-    for (const auto &stop : (this+colorLine).stops.iter ())
-      c->add_palette_index (stop.color.paletteIndex);
-  }
+  { (this+colorLine).closurev1 (c); }
 
   bool subset (hb_subset_context_t *c) const
   {
@@ -430,19 +447,22 @@
   HBUINT8			format; /* format = 4(noVar) or 5 (Var) */
   Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintLinearGradient
                                             * table) to ColorLine subtable. */
-  Var<FWORD>			x0;
-  Var<FWORD>			y0;
-  Var<FWORD>			x1;
-  Var<FWORD>			y1;
-  Var<FWORD>			x2;
-  Var<FWORD>			y2;
+  FWORD			x0;
+  FWORD			y0;
+  FWORD			x1;
+  FWORD			y1;
+  FWORD			x2;
+  FWORD			y2;
   public:
-  DEFINE_SIZE_STATIC (4 + 6 * Var<FWORD>::static_size);
+  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
 };
 
 template <template<typename> class Var>
 struct PaintRadialGradient
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { (this+colorLine).closurev1 (c); }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -452,12 +472,6 @@
     return_trace (out->colorLine.serialize_subset (c, colorLine, this));
   }
 
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  {
-    for (const auto &stop : (this+colorLine).stops.iter ())
-      c->add_palette_index (stop.color.paletteIndex);
-  }
-
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -467,19 +481,22 @@
   HBUINT8			format; /* format = 6(noVar) or 7 (Var) */
   Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintRadialGradient
                                             * table) to ColorLine subtable. */
-  Var<FWORD>			x0;
-  Var<FWORD>			y0;
-  Var<UFWORD>			radius0;
-  Var<FWORD>			x1;
-  Var<FWORD>			y1;
-  Var<UFWORD>			radius1;
+  FWORD			x0;
+  FWORD			y0;
+  UFWORD		radius0;
+  FWORD			x1;
+  FWORD			y1;
+  UFWORD		radius1;
   public:
-  DEFINE_SIZE_STATIC (4 + 6 * Var<FWORD>::static_size);
+  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
 };
 
 template <template<typename> class Var>
 struct PaintSweepGradient
 {
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { (this+colorLine).closurev1 (c); }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -489,12 +506,6 @@
     return_trace (out->colorLine.serialize_subset (c, colorLine, this));
   }
 
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  {
-    for (const auto &stop : (this+colorLine).stops.iter ())
-      c->add_palette_index (stop.color.paletteIndex);
-  }
-
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -504,12 +515,12 @@
   HBUINT8			format; /* format = 8(noVar) or 9 (Var) */
   Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintSweepGradient
                                             * table) to ColorLine subtable. */
-  Var<FWORD>			centerX;
-  Var<FWORD>			centerY;
-  Var<HBFixed>			startAngle;
-  Var<HBFixed>			endAngle;
+  FWORD			centerX;
+  FWORD			centerY;
+  F2DOT14		startAngle;
+  F2DOT14		endAngle;
   public:
-  DEFINE_SIZE_STATIC (2 * Var<FWORD>::static_size + 2 * Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size);
 };
 
 struct Paint;
@@ -580,7 +591,7 @@
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
-
+    if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false);
     return_trace (out->src.serialize_subset (c, src, this));
   }
 
@@ -587,17 +598,18 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
+    return_trace (c->check_struct (this) &&
+                  src.sanitize (c, this) &&
+                  transform.sanitize (c, this));
   }
 
-  HBUINT8		format; /* format = 12(noVar) or 13 (Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */
-  Affine2x3<Var>	transform;
+  HBUINT8			format; /* format = 12(noVar) or 13 (Var) */
+  Offset24To<Paint>		src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */
+  Offset24To<Var<Affine2x3>>	transform;
   public:
-  DEFINE_SIZE_STATIC (4 + Affine2x3<Var>::static_size);
+  DEFINE_SIZE_STATIC (7);
 };
 
-template <template<typename> class Var>
 struct PaintTranslate
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
@@ -619,13 +631,122 @@
 
   HBUINT8		format; /* format = 14(noVar) or 15 (Var) */
   Offset24To<Paint>	src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */
-  Var<HBFixed>		dx;
-  Var<HBFixed>		dy;
+  FWORD		dx;
+  FWORD		dy;
   public:
-  DEFINE_SIZE_STATIC (4 + Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size);
 };
 
-template <template<typename> class Var>
+struct PaintScale
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 16 (noVar) or 17(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScale table) to Paint subtable. */
+  F2DOT14		scaleX;
+  F2DOT14		scaleY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
+};
+
+struct PaintScaleAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 18 (noVar) or 19(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */
+  F2DOT14	scaleX;
+  F2DOT14	scaleY;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintScaleUniform
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 20 (noVar) or 21(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
+  F2DOT14		scale;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
+};
+
+struct PaintScaleUniformAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 22 (noVar) or 23(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
+  F2DOT14	scale;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
 struct PaintRotate
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
@@ -645,16 +766,41 @@
     return_trace (c->check_struct (this) && src.sanitize (c, this));
   }
 
-  HBUINT8		format; /* format = 16 (noVar) or 17(Var) */
+  HBUINT8		format; /* format = 24 (noVar) or 25(Var) */
   Offset24To<Paint>	src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
-  Var<HBFixed>		angle;
-  Var<HBFixed>		centerX;
-  Var<HBFixed>		centerY;
+  F2DOT14		angle;
   public:
-  DEFINE_SIZE_STATIC (4 + 3 * Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
 };
 
-template <template<typename> class Var>
+struct PaintRotateAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 26 (noVar) or 27(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
+  F2DOT14	angle;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
 struct PaintSkew
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
@@ -674,16 +820,43 @@
     return_trace (c->check_struct (this) && src.sanitize (c, this));
   }
 
-  HBUINT8		format; /* format = 18(noVar) or 19 (Var) */
+  HBUINT8		format; /* format = 28(noVar) or 29 (Var) */
   Offset24To<Paint>	src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
-  Var<HBFixed>		xSkewAngle;
-  Var<HBFixed>		ySkewAngle;
-  Var<HBFixed>		centerX;
-  Var<HBFixed>		centerY;
+  F2DOT14		xSkewAngle;
+  F2DOT14		ySkewAngle;
   public:
-  DEFINE_SIZE_STATIC (4 + 4 * Var<HBFixed>::static_size);
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
 };
 
+struct PaintSkewAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  HBUINT8		format; /* format = 30(noVar) or 31 (Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
+  F2DOT14	xSkewAngle;
+  F2DOT14	ySkewAngle;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
 struct PaintComposite
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const;
@@ -706,7 +879,7 @@
                   backdrop.sanitize (c, this));
   }
 
-  HBUINT8		format; /* format = 20 */
+  HBUINT8		format; /* format = 32 */
   Offset24To<Paint>	src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */
   CompositeMode		mode;   /* If mode is unrecognized use COMPOSITE_CLEAR */
   Offset24To<Paint>	backdrop; /* Offset (from beginning of PaintComposite table) to backdrop Paint subtable. */
@@ -714,6 +887,179 @@
   DEFINE_SIZE_STATIC (8);
 };
 
+struct ClipBoxFormat1
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  HBUINT8	format; /* format = 1(noVar) or 2(Var)*/
+  FWORD		xMin;
+  FWORD		yMin;
+  FWORD		xMax;
+  FWORD		yMax;
+  public:
+  DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size);
+};
+
+struct ClipBoxFormat2 : Variable<ClipBoxFormat1> {};
+
+struct ClipBox
+{
+  ClipBox* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.format) {
+    case 1: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format1)));
+    case 2: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format2)));
+    default:return_trace (nullptr);
+    }
+  }
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  HBUINT8		format;         /* Format identifier */
+  ClipBoxFormat1	format1;
+  ClipBoxFormat2	format2;
+  } u;
+};
+
+struct ClipRecord
+{
+  ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+    if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr);
+    return_trace (out);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && clipBox.sanitize (c, base));
+  }
+
+  public:
+  HBUINT16		startGlyphID;  // first gid clip applies to
+  HBUINT16		endGlyphID;    // last gid clip applies to, inclusive
+  Offset24To<ClipBox>	clipBox;   // Box or VarBox
+  public:
+  DEFINE_SIZE_STATIC (7);
+};
+
+struct ClipList
+{
+  unsigned serialize_clip_records (hb_serialize_context_t *c,
+                                   const hb_set_t& gids,
+                                   const hb_map_t& gid_offset_map) const
+  {
+    TRACE_SERIALIZE (this);
+    if (gids.is_empty () ||
+        gid_offset_map.get_population () != gids.get_population ())
+      return_trace (0);
+
+    unsigned count  = 0;
+
+    hb_codepoint_t start_gid= gids.get_min ();
+    hb_codepoint_t prev_gid = start_gid;
+
+    unsigned offset = gid_offset_map.get (start_gid);
+    unsigned prev_offset = offset;
+    for (const hb_codepoint_t _ : gids.iter ())
+    {
+      if (_ == start_gid) continue;
+      
+      offset = gid_offset_map.get (_);
+      if (_ == prev_gid + 1 &&  offset == prev_offset)
+      {
+        prev_gid = _;
+        continue;
+      }
+
+      ClipRecord record;
+      record.startGlyphID = start_gid;
+      record.endGlyphID = prev_gid;
+      record.clipBox = prev_offset;
+
+      if (!c->copy (record, this)) return_trace (0);
+      count++;
+
+      start_gid = _;
+      prev_gid = _;
+      prev_offset = offset;
+    }
+
+    //last one
+    {
+      ClipRecord record;
+      record.startGlyphID = start_gid;
+      record.endGlyphID = prev_gid;
+      record.clipBox = prev_offset;
+      if (!c->copy (record, this)) return_trace (0);
+      count++;
+    }
+    return_trace (count);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+
+    const hb_set_t& glyphset = *c->plan->_glyphset;
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+    
+    hb_map_t new_gid_offset_map;
+    hb_set_t new_gids;
+    for (const ClipRecord& record : clips.iter ())
+    {
+      unsigned start_gid = record.startGlyphID;
+      unsigned end_gid = record.endGlyphID;
+      for (unsigned gid = start_gid; gid <= end_gid; gid++)
+      {
+        if (!glyphset.has (gid) || !glyph_map.has (gid)) continue;
+        unsigned new_gid = glyph_map.get (gid);
+        new_gid_offset_map.set (new_gid, record.clipBox);
+        new_gids.add (new_gid);
+      }
+    }
+
+    unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map);
+    if (!count) return_trace (false);
+    return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && clips.sanitize (c, this));
+  }
+
+  HBUINT8			format;  // Set to 1.
+  Array32Of<ClipRecord>		clips;  // Clip records, sorted by startGlyphID
+  public:
+  DEFINE_SIZE_ARRAY_SIZED (5, clips);
+};
+
 struct Paint
 {
   template <typename context_t, typename ...Ts>
@@ -722,26 +1068,38 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.paintformat1, hb_forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.paintformat2, hb_forward<Ts> (ds)...));
-    case 3: return_trace (c->dispatch (u.paintformat3, hb_forward<Ts> (ds)...));
-    case 4: return_trace (c->dispatch (u.paintformat4, hb_forward<Ts> (ds)...));
-    case 5: return_trace (c->dispatch (u.paintformat5, hb_forward<Ts> (ds)...));
-    case 6: return_trace (c->dispatch (u.paintformat6, hb_forward<Ts> (ds)...));
-    case 7: return_trace (c->dispatch (u.paintformat7, hb_forward<Ts> (ds)...));
-    case 8: return_trace (c->dispatch (u.paintformat8, hb_forward<Ts> (ds)...));
-    case 9: return_trace (c->dispatch (u.paintformat9, hb_forward<Ts> (ds)...));
-    case 10: return_trace (c->dispatch (u.paintformat10, hb_forward<Ts> (ds)...));
-    case 11: return_trace (c->dispatch (u.paintformat11, hb_forward<Ts> (ds)...));
-    case 12: return_trace (c->dispatch (u.paintformat12, hb_forward<Ts> (ds)...));
-    case 13: return_trace (c->dispatch (u.paintformat13, hb_forward<Ts> (ds)...));
-    case 14: return_trace (c->dispatch (u.paintformat14, hb_forward<Ts> (ds)...));
-    case 15: return_trace (c->dispatch (u.paintformat15, hb_forward<Ts> (ds)...));
-    case 16: return_trace (c->dispatch (u.paintformat16, hb_forward<Ts> (ds)...));
-    case 17: return_trace (c->dispatch (u.paintformat17, hb_forward<Ts> (ds)...));
-    case 18: return_trace (c->dispatch (u.paintformat18, hb_forward<Ts> (ds)...));
-    case 19: return_trace (c->dispatch (u.paintformat19, hb_forward<Ts> (ds)...));
-    case 20: return_trace (c->dispatch (u.paintformat20, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.paintformat1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.paintformat2, std::forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.paintformat3, std::forward<Ts> (ds)...));
+    case 4: return_trace (c->dispatch (u.paintformat4, std::forward<Ts> (ds)...));
+    case 5: return_trace (c->dispatch (u.paintformat5, std::forward<Ts> (ds)...));
+    case 6: return_trace (c->dispatch (u.paintformat6, std::forward<Ts> (ds)...));
+    case 7: return_trace (c->dispatch (u.paintformat7, std::forward<Ts> (ds)...));
+    case 8: return_trace (c->dispatch (u.paintformat8, std::forward<Ts> (ds)...));
+    case 9: return_trace (c->dispatch (u.paintformat9, std::forward<Ts> (ds)...));
+    case 10: return_trace (c->dispatch (u.paintformat10, std::forward<Ts> (ds)...));
+    case 11: return_trace (c->dispatch (u.paintformat11, std::forward<Ts> (ds)...));
+    case 12: return_trace (c->dispatch (u.paintformat12, std::forward<Ts> (ds)...));
+    case 13: return_trace (c->dispatch (u.paintformat13, std::forward<Ts> (ds)...));
+    case 14: return_trace (c->dispatch (u.paintformat14, std::forward<Ts> (ds)...));
+    case 15: return_trace (c->dispatch (u.paintformat15, std::forward<Ts> (ds)...));
+    case 16: return_trace (c->dispatch (u.paintformat16, std::forward<Ts> (ds)...));
+    case 17: return_trace (c->dispatch (u.paintformat17, std::forward<Ts> (ds)...));
+    case 18: return_trace (c->dispatch (u.paintformat18, std::forward<Ts> (ds)...));
+    case 19: return_trace (c->dispatch (u.paintformat19, std::forward<Ts> (ds)...));
+    case 20: return_trace (c->dispatch (u.paintformat20, std::forward<Ts> (ds)...));
+    case 21: return_trace (c->dispatch (u.paintformat21, std::forward<Ts> (ds)...));
+    case 22: return_trace (c->dispatch (u.paintformat22, std::forward<Ts> (ds)...));
+    case 23: return_trace (c->dispatch (u.paintformat23, std::forward<Ts> (ds)...));
+    case 24: return_trace (c->dispatch (u.paintformat24, std::forward<Ts> (ds)...));
+    case 25: return_trace (c->dispatch (u.paintformat25, std::forward<Ts> (ds)...));
+    case 26: return_trace (c->dispatch (u.paintformat26, std::forward<Ts> (ds)...));
+    case 27: return_trace (c->dispatch (u.paintformat27, std::forward<Ts> (ds)...));
+    case 28: return_trace (c->dispatch (u.paintformat28, std::forward<Ts> (ds)...));
+    case 29: return_trace (c->dispatch (u.paintformat29, std::forward<Ts> (ds)...));
+    case 30: return_trace (c->dispatch (u.paintformat30, std::forward<Ts> (ds)...));
+    case 31: return_trace (c->dispatch (u.paintformat31, std::forward<Ts> (ds)...));
+    case 32: return_trace (c->dispatch (u.paintformat32, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -748,31 +1106,43 @@
 
   protected:
   union {
-  HBUINT8				format;
-  PaintColrLayers			paintformat1;
-  PaintSolid<NoVariable>		paintformat2;
-  PaintSolid<Variable>			paintformat3;
-  PaintLinearGradient<NoVariable>	paintformat4;
-  PaintLinearGradient<Variable>		paintformat5;
-  PaintRadialGradient<NoVariable>	paintformat6;
-  PaintRadialGradient<Variable>		paintformat7;
-  PaintSweepGradient<NoVariable>	paintformat8;
-  PaintSweepGradient<Variable>		paintformat9;
-  PaintGlyph				paintformat10;
-  PaintColrGlyph			paintformat11;
-  PaintTransform<NoVariable>		paintformat12;
-  PaintTransform<Variable>		paintformat13;
-  PaintTranslate<NoVariable>		paintformat14;
-  PaintTranslate<Variable>		paintformat15;
-  PaintRotate<NoVariable>		paintformat16;
-  PaintRotate<Variable>			paintformat17;
-  PaintSkew<NoVariable>			paintformat18;
-  PaintSkew<Variable>			paintformat19;
-  PaintComposite			paintformat20;
+  HBUINT8					format;
+  PaintColrLayers				paintformat1;
+  PaintSolid					paintformat2;
+  Variable<PaintSolid>				paintformat3;
+  PaintLinearGradient<NoVariable>		paintformat4;
+  Variable<PaintLinearGradient<Variable>>	paintformat5;
+  PaintRadialGradient<NoVariable>		paintformat6;
+  Variable<PaintRadialGradient<Variable>>	paintformat7;
+  PaintSweepGradient<NoVariable>		paintformat8;
+  Variable<PaintSweepGradient<Variable>>	paintformat9;
+  PaintGlyph					paintformat10;
+  PaintColrGlyph				paintformat11;
+  PaintTransform<NoVariable>			paintformat12;
+  PaintTransform<Variable>			paintformat13;
+  PaintTranslate				paintformat14;
+  Variable<PaintTranslate>			paintformat15;
+  PaintScale					paintformat16;
+  Variable<PaintScale>				paintformat17;
+  PaintScaleAroundCenter			paintformat18;
+  Variable<PaintScaleAroundCenter>		paintformat19;
+  PaintScaleUniform				paintformat20;
+  Variable<PaintScaleUniform>			paintformat21;
+  PaintScaleUniformAroundCenter			paintformat22;
+  Variable<PaintScaleUniformAroundCenter>	paintformat23;
+  PaintRotate					paintformat24;
+  Variable<PaintRotate>				paintformat25;
+  PaintRotateAroundCenter			paintformat26;
+  Variable<PaintRotateAroundCenter>		paintformat27;
+  PaintSkew					paintformat28;
+  Variable<PaintSkew>				paintformat29;
+  PaintSkewAroundCenter				paintformat30;
+  Variable<PaintSkewAroundCenter>		paintformat31;
+  PaintComposite				paintformat32;
   } u;
 };
 
-struct BaseGlyphV1Record
+struct BaseGlyphPaintRecord
 {
   int cmp (hb_codepoint_t g) const
   { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
@@ -797,14 +1167,14 @@
   }
 
   public:
-  HBGlyphID		glyphId;    /* Glyph ID of reference glyph */
-  Offset32To<Paint>	paint;      /* Offset (from beginning of BaseGlyphV1Record array) to Paint,
+  HBGlyphID16		glyphId;    /* Glyph ID of reference glyph */
+  Offset32To<Paint>	paint;      /* Offset (from beginning of BaseGlyphPaintRecord array) to Paint,
                                      * Typically PaintColrLayers */
   public:
   DEFINE_SIZE_STATIC (6);
 };
 
-struct BaseGlyphV1List : SortedArray32Of<BaseGlyphV1Record>
+struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
 {
   bool subset (hb_subset_context_t *c) const
   {
@@ -828,11 +1198,11 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (SortedArray32Of<BaseGlyphV1Record>::sanitize (c, this));
+    return_trace (SortedArray32Of<BaseGlyphPaintRecord>::sanitize (c, this));
   }
 };
 
-struct LayerV1List : Array32OfOffset32To<Paint>
+struct LayerList : Array32OfOffset32To<Paint>
 {
   const Paint& get_paint (unsigned i) const
   { return this+(*this)[i]; }
@@ -952,24 +1322,24 @@
     hb_set_t visited_glyphs;
 
     hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices);
-    const BaseGlyphV1List &baseglyphV1_records = this+baseGlyphsV1List;
+    const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
 
-    for (const BaseGlyphV1Record &baseglyphV1record: baseglyphV1_records.iter ())
+    for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ())
     {
-      unsigned gid = baseglyphV1record.glyphId;
+      unsigned gid = baseglyph_paintrecord.glyphId;
       if (!glyphset->has (gid)) continue;
 
-      const Paint &paint = &baseglyphV1_records+baseglyphV1record.paint;
+      const Paint &paint = &baseglyph_paintrecords+baseglyph_paintrecord.paint;
       paint.dispatch (&c);
     }
     hb_set_union (glyphset, &visited_glyphs);
   }
 
-  const LayerV1List& get_layerV1List () const
-  { return (this+layersV1); }
+  const LayerList& get_layerList () const
+  { return (this+layerList); }
 
-  const BaseGlyphV1List& get_baseglyphV1List () const
-  { return (this+baseGlyphsV1List); }
+  const BaseGlyphList& get_baseglyphList () const
+  { return (this+baseGlyphList); }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -979,8 +1349,10 @@
                   (this+layersZ).sanitize (c, numLayers) &&
                   (version == 0 ||
 		   (COLRV1_ENABLE_SUBSETTING && version == 1 &&
-		    baseGlyphsV1List.sanitize (c, this) &&
-		    layersV1.sanitize (c, this) &&
+		    baseGlyphList.sanitize (c, this) &&
+		    layerList.sanitize (c, this) &&
+		    clipList.sanitize (c, this) &&
+		    varIdxMap.sanitize (c, this) &&
 		    varStore.sanitize (c, this))));
   }
 
@@ -996,19 +1368,17 @@
     if (unlikely (base_it.len () != layer_it.len ()))
       return_trace (false);
 
-    if (unlikely (!c->extend_min (this))) return_trace (false);
     this->version = version;
     numLayers = 0;
     numBaseGlyphs = base_it.len ();
-    if (base_it.len () == 0)
+    if (numBaseGlyphs == 0)
     {
       baseGlyphsZ = 0;
       layersZ = 0;
       return_trace (true);
     }
-    baseGlyphsZ = COLR::min_size;
-    layersZ = COLR::min_size + numBaseGlyphs * BaseGlyphRecord::min_size;
 
+    c->push ();
     for (const hb_item_type<BaseIterator> _ : + base_it.iter ())
     {
       auto* record = c->embed (_);
@@ -1016,10 +1386,14 @@
       record->firstLayerIdx = numLayers;
       numLayers += record->numLayers;
     }
+    c->add_link (baseGlyphsZ, c->pop_pack ());
 
+    c->push ();
     for (const hb_item_type<LayerIterator>& _ : + layer_it.iter ())
       _.as_array ().copy (c);
 
+    c->add_link (layersZ, c->pop_pack ());
+
     return_trace (true);
   }
 
@@ -1033,9 +1407,9 @@
     return record;
   }
 
-  const BaseGlyphV1Record* get_base_glyphV1_record (hb_codepoint_t gid) const
+  const BaseGlyphPaintRecord* get_base_glyph_paintrecord (hb_codepoint_t gid) const
   {
-    const BaseGlyphV1Record* record = &(this+baseGlyphsV1List).bsearch ((unsigned) gid);
+    const BaseGlyphPaintRecord* record = &(this+baseGlyphList).bsearch ((unsigned) gid);
     if ((record && (hb_codepoint_t) record->glyphId != gid))
       record = nullptr;
     return record;
@@ -1101,23 +1475,26 @@
       return_trace (false);
 
     COLR *colr_prime = c->serializer->start_embed<COLR> ();
-    bool ret = colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it);
+    if (unlikely (!c->serializer->extend_min (colr_prime)))  return_trace (false);
 
-    if (version == 0) return_trace (ret);
+    if (version == 0)
+    return_trace (colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it));
+
     auto snap = c->serializer->snapshot ();
-    if (!c->serializer->allocate_size<void> (3 * HBUINT32::static_size)) return_trace (false);
-    if (!colr_prime->baseGlyphsV1List.serialize_subset (c, baseGlyphsV1List, this))
+    if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
+    if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this))
     {
       if (c->serializer->in_error ()) return_trace (false);
       //no more COLRv1 glyphs: downgrade to version 0
       c->serializer->revert (snap);
-      colr_prime->version = 0;
-      return_trace (true);
+      return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
     }
 
-    if (!colr_prime->layersV1.serialize_subset (c, layersV1, this)) return_trace (false);
+    if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
 
-    colr_prime->varStore = 0;
+    colr_prime->layerList.serialize_subset (c, layerList, this);
+    colr_prime->clipList.serialize_subset (c, clipList, this);
+    colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this);
     //TODO: subset varStore once it's implemented in fonttools
     return_trace (true);
   }
@@ -1131,8 +1508,10 @@
 		layersZ;	/* Offset to Layer Records. */
   HBUINT16	numLayers;	/* Number of Layer Records. */
   // Version-1 additions
-  Offset32To<BaseGlyphV1List>		baseGlyphsV1List;
-  Offset32To<LayerV1List>		layersV1;
+  Offset32To<BaseGlyphList>		baseGlyphList;
+  Offset32To<LayerList>			layerList;
+  Offset32To<ClipList>			clipList;   // Offset to ClipList table (may be NULL)
+  Offset32To<DeltaSetIndexMap>		varIdxMap;  // Offset to DeltaSetIndexMap table (may be NULL)
   Offset32To<VariationStore>		varStore;
   public:
   DEFINE_SIZE_MIN (14);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -40,7 +40,7 @@
 HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const
 {
   c->add_layer_indices (firstLayerIndex, numLayers);
-  const LayerV1List &paint_offset_lists = c->get_colr_table ()->get_layerV1List ();
+  const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
   for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
   {
     const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i];
@@ -57,38 +57,45 @@
 HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
 {
   const COLR *colr_table = c->get_colr_table ();
-  const BaseGlyphV1Record* baseglyphV1_record = colr_table->get_base_glyphV1_record (gid);
-  if (!baseglyphV1_record) return;
+  const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid);
+  if (!baseglyph_paintrecord) return;
   c->add_glyph (gid);
 
-  const BaseGlyphV1List &baseglyphV1_list = colr_table->get_baseglyphV1List ();
-  (&baseglyphV1_list+baseglyphV1_record->paint).dispatch (c);
+  const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList ();
+  (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c);
 }
 
 template <template<typename> class Var>
 HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-}
+{ (this+src).dispatch (c); }
 
-template <template<typename> class Var>
-HB_INTERNAL void PaintTranslate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-}
+HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
 
-template <template<typename> class Var>
-HB_INTERNAL void PaintRotate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-}
+HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
 
-template <template<typename> class Var>
-HB_INTERNAL void PaintSkew<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-}
+HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
 
+HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
 HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
 {
   (this+src).dispatch (c);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -388,7 +388,7 @@
 
     protected:
     HBUINT16	flags;
-    HBGlyphID	glyphIndex;
+    HBGlyphID16	glyphIndex;
     public:
     DEFINE_SIZE_MIN (4);
   };
@@ -1118,7 +1118,7 @@
       while (it)
       {
         auto item = *(it++);
-        operation_count +=
+        operation_count =
             add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth, operation_count);
       }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -72,12 +72,14 @@
     UNDERLINE	= 1u<<2,
     OUTLINE	= 1u<<3,
     SHADOW	= 1u<<4,
-    CONDENSED	= 1u<<5
+    CONDENSED	= 1u<<5,
+    EXPANDED	= 1u<<6,
   };
 
   bool is_bold () const      { return macStyle & BOLD; }
   bool is_italic () const    { return macStyle & ITALIC; }
   bool is_condensed () const { return macStyle & CONDENSED; }
+  bool is_expanded () const  { return macStyle & EXPANDED; }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -134,11 +134,11 @@
     switch (subtable_type) {
     case 0:	return_trace (c->dispatch (u.format0));
 #ifndef HB_NO_AAT_SHAPE
-    case 1:	return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ());
+    case 1:	return_trace (u.header.apple ? c->dispatch (u.format1, std::forward<Ts> (ds)...) : c->default_return_value ());
 #endif
     case 2:	return_trace (c->dispatch (u.format2));
 #ifndef HB_NO_AAT_SHAPE
-    case 3:	return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ());
+    case 3:	return_trace (u.header.apple ? c->dispatch (u.format3, std::forward<Ts> (ds)...) : c->default_return_value ());
 #endif
     default:	return_trace (c->default_return_value ());
     }
@@ -325,9 +325,9 @@
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case 0:	return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...));
+    case 0:	return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
 #ifndef HB_NO_AAT_SHAPE
-    case 1:	return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...));
+    case 1:	return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
 #endif
     default:	return_trace (c->default_return_value ());
     }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -73,7 +73,7 @@
   protected:
   HBUINT16	format;		/* Format identifier--format = 2 */
   FWORD		coordinate;	/* X or Y value, in design units */
-  HBGlyphID	referenceGlyph;	/* Glyph ID of control glyph */
+  HBGlyphID16	referenceGlyph;	/* Glyph ID of control glyph */
   HBUINT16	coordPoint;	/* Index of contour point on the
 				 * reference glyph */
   public:

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	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -89,7 +89,7 @@
 
 static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
 					  const hb_map_t &gid_klass_map,
-					  hb_sorted_vector_t<HBGlyphID> &glyphs,
+					  hb_sorted_vector_t<HBGlyphID16> &glyphs,
 					  const hb_set_t &klasses,
 					  bool use_class_zero,
 					  hb_map_t *klass_map /*INOUT*/);
@@ -237,9 +237,9 @@
   template <typename T>
   bool operator () (T&& offset)
   {
+    auto snap = subset_context->serializer->snapshot ();
     auto *o = out.serialize_append (subset_context->serializer);
     if (unlikely (!o)) return false;
-    auto snap = subset_context->serializer->snapshot ();
     bool ret = o->serialize_subset (subset_context, offset, base);
     if (!ret)
     {
@@ -268,9 +268,9 @@
   template <typename T>
   bool operator () (T&& offset)
   {
+    auto snap = subset_context->serializer->snapshot ();
     auto *o = out.serialize_append (subset_context->serializer);
     if (unlikely (!o)) return false;
-    auto snap = subset_context->serializer->snapshot ();
     bool ret = o->serialize_subset (subset_context, offset, base, arg);
     if (!ret)
     {
@@ -346,7 +346,44 @@
 }
 HB_FUNCOBJ (subset_record_array);
 
+
+template<typename OutputArray>
+struct serialize_math_record_array_t
+{
+  serialize_math_record_array_t (hb_serialize_context_t *serialize_context_,
+                         OutputArray& out_,
+                         const void *base_) : serialize_context (serialize_context_),
+                                              out (out_), base (base_) {}
+
+  template <typename T>
+  bool operator () (T&& record)
+  {
+    if (!serialize_context->copy (record, base)) return false;
+    out.len++;
+    return true;
+  }
+
+  private:
+  hb_serialize_context_t *serialize_context;
+  OutputArray &out;
+  const void *base;
+};
+
 /*
+ * Helper to serialize an array of MATH records.
+ */
+struct
+{
+  template<typename OutputArray>
+  serialize_math_record_array_t<OutputArray>
+  operator () (hb_serialize_context_t *serialize_context, OutputArray& out,
+               const void *base) const
+  { return serialize_math_record_array_t<OutputArray> (serialize_context, out, base); }
+
+}
+HB_FUNCOBJ (serialize_math_record_array);
+
+/*
  *
  * OpenType Layout Common Table Formats
  *
@@ -508,8 +545,8 @@
   bool collect_coverage (set_t *glyphs) const
   { return glyphs->add_range (first, last); }
 
-  HBGlyphID	first;		/* First GlyphID in the range */
-  HBGlyphID	last;		/* Last GlyphID in the range */
+  HBGlyphID16	first;		/* First GlyphID in the range */
+  HBGlyphID16	last;		/* Last GlyphID in the range */
   HBUINT16	value;		/* Value */
   public:
   DEFINE_SIZE_STATIC (6);
@@ -1249,7 +1286,7 @@
     TRACE_DISPATCH (this, lookup_type);
     unsigned int count = get_subtable_count ();
     for (unsigned int i = 0; i < count; i++) {
-      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, hb_forward<Ts> (ds)...);
+      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...);
       if (c->stop_sublookup_iteration (r))
 	return_trace (r);
     }
@@ -1299,7 +1336,7 @@
       outMarkFilteringSet = markFilteringSet;
     }
 
-    return_trace (true);
+    return_trace (out->subTable.len);
   }
 
   template <typename TSubTable>
@@ -1454,7 +1491,7 @@
 
   protected:
   HBUINT16	coverageFormat;	/* Format identifier--format = 1 */
-  SortedArray16Of<HBGlyphID>
+  SortedArray16Of<HBGlyphID16>
 		glyphArray;	/* Array of GlyphIDs--in numerical order */
   public:
   DEFINE_SIZE_ARRAY (4, glyphArray);
@@ -1832,7 +1869,7 @@
 
 static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
 					  const hb_map_t &gid_klass_map,
-					  hb_sorted_vector_t<HBGlyphID> &glyphs,
+					  hb_sorted_vector_t<HBGlyphID16> &glyphs,
 					  const hb_set_t &klasses,
                                           bool use_class_zero,
 					  hb_map_t *klass_map /*INOUT*/)
@@ -1859,7 +1896,7 @@
 
   auto it =
   + glyphs.iter ()
-  | hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, unsigned>
+  | hb_map_retains_sorting ([&] (const HBGlyphID16& gid) -> hb_pair_t<hb_codepoint_t, unsigned>
 			    {
 			      unsigned new_klass = klass_map->get (gid_klass_map[gid]);
 			      return hb_pair ((hb_codepoint_t)gid, new_klass);
@@ -1926,7 +1963,7 @@
     const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
-    hb_sorted_vector_t<HBGlyphID> glyphs;
+    hb_sorted_vector_t<HBGlyphID16> glyphs;
     hb_set_t orig_klasses;
     hb_map_t gid_org_klass_map;
 
@@ -2044,9 +2081,25 @@
         intersect_glyphs->add (startGlyph + i);
   }
 
+  void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
+  {
+    if (glyphs->is_empty ()) return;
+    hb_codepoint_t end_glyph = startGlyph + classValue.len - 1;
+    if (glyphs->get_min () < startGlyph ||
+        glyphs->get_max () > end_glyph)
+      intersect_classes->add (0);
+
+    for (const auto& _ : + hb_enumerate (classValue))
+    {
+      hb_codepoint_t g = startGlyph + _.first;
+      if (glyphs->has (g))
+        intersect_classes->add (_.second);
+    }
+  }
+
   protected:
   HBUINT16	classFormat;	/* Format identifier--format = 1 */
-  HBGlyphID	startGlyph;	/* First GlyphID of the classValueArray */
+  HBGlyphID16	startGlyph;	/* First GlyphID of the classValueArray */
   Array16Of<HBUINT16>
 		classValue;	/* Array of Class Values--one per GlyphID */
   public:
@@ -2128,7 +2181,7 @@
     const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
-    hb_sorted_vector_t<HBGlyphID> glyphs;
+    hb_sorted_vector_t<HBGlyphID16> glyphs;
     hb_set_t orig_klasses;
     hb_map_t gid_org_klass_map;
 
@@ -2277,6 +2330,31 @@
     }
   }
 
+  void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
+  {
+    if (glyphs->is_empty ()) return;
+
+    unsigned count = rangeRecord.len;
+    hb_codepoint_t g = HB_SET_VALUE_INVALID;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (!hb_set_next (glyphs, &g))
+        break;
+      if (g < rangeRecord[i].first)
+      {
+        intersect_classes->add (0);
+        break;
+      }
+      g = rangeRecord[i].last;
+    }
+    if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
+      intersect_classes->add (0);
+
+    for (const RangeRecord& record : rangeRecord.iter ())
+      if (record.intersects (glyphs))
+        intersect_classes->add (record.value);
+  }
+
   protected:
   HBUINT16	classFormat;	/* Format identifier--format = 2 */
   SortedArray16Of<RangeRecord>
@@ -2429,6 +2507,16 @@
     }
   }
 
+  void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.intersected_classes (glyphs, intersect_classes);
+    case 2: return u.format2.intersected_classes (glyphs, intersect_classes);
+    default:return;
+    }
+  }
+
+
   protected:
   union {
   HBUINT16		format;		/* Format identifier */
@@ -2543,7 +2631,7 @@
 
   public:
   HBUINT16	axisCount;
-  HBUINT16	regionCount;
+  HBUINT15	regionCount;
   protected:
   UnsizedArrayOf<VarRegionAxis>
 		axesZ;
@@ -2947,7 +3035,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -84,7 +84,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto *out = c->serializer->start_embed (*this);
@@ -248,9 +248,9 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
-    case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -371,7 +371,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto *out = c->serializer->start_embed (*this);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1050,8 +1050,8 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1144,7 +1144,7 @@
   }
 
   protected:
-  HBGlyphID	secondGlyph;		/* GlyphID of second glyph in the
+  HBGlyphID16	secondGlyph;		/* GlyphID of second glyph in the
 					 * pair--first glyph is listed in the
 					 * Coverage table */
   ValueRecord	values;			/* Positioning data for the first glyph
@@ -1220,9 +1220,9 @@
 						record_size);
     if (record)
     {
-      /* Note the intentional use of "|" instead of short-circuit "||". */
-      if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) |
-	  valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]))
+      bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
+      bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+      if (applied_first || applied_second)
 	buffer->unsafe_to_break (buffer->idx, pos + 1);
       if (len2)
 	pos++;
@@ -1386,9 +1386,9 @@
     | hb_filter (glyphset, hb_first)
     | hb_filter ([this, c, out] (const Offset16To<PairSet>& _)
 		 {
+                   auto snap = c->serializer->snapshot ();
 		   auto *o = out->pairSet.serialize_append (c->serializer);
 		   if (unlikely (!o)) return false;
-		   auto snap = c->serializer->snapshot ();
 		   bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat);
 		   if (!ret)
 		   {
@@ -1560,9 +1560,9 @@
     if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
 
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
-    /* Note the intentional use of "|" instead of short-circuit "||". */
-    if (valueFormat1.apply_value (c, this, v, buffer->cur_pos()) |
-	valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]))
+    bool applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
+    bool applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+    if (applied_first || applied_second)
       buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
 
     buffer->idx = skippy_iter.idx;
@@ -1702,8 +1702,8 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1959,7 +1959,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2194,7 +2194,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2434,7 +2434,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2653,7 +2653,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2704,15 +2704,15 @@
   {
     TRACE_DISPATCH (this, lookup_type);
     switch (lookup_type) {
-    case Single:		return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...));
-    case Pair:			return_trace (u.pair.dispatch (c, hb_forward<Ts> (ds)...));
-    case Cursive:		return_trace (u.cursive.dispatch (c, hb_forward<Ts> (ds)...));
-    case MarkBase:		return_trace (u.markBase.dispatch (c, hb_forward<Ts> (ds)...));
-    case MarkLig:		return_trace (u.markLig.dispatch (c, hb_forward<Ts> (ds)...));
-    case MarkMark:		return_trace (u.markMark.dispatch (c, hb_forward<Ts> (ds)...));
-    case Context:		return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...));
-    case ChainContext:		return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...));
-    case Extension:		return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...));
+    case Single:		return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
+    case Pair:			return_trace (u.pair.dispatch (c, std::forward<Ts> (ds)...));
+    case Cursive:		return_trace (u.cursive.dispatch (c, std::forward<Ts> (ds)...));
+    case MarkBase:		return_trace (u.markBase.dispatch (c, std::forward<Ts> (ds)...));
+    case MarkLig:		return_trace (u.markLig.dispatch (c, std::forward<Ts> (ds)...));
+    case MarkMark:		return_trace (u.markMark.dispatch (c, std::forward<Ts> (ds)...));
+    case Context:		return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
+    case ChainContext:		return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
+    case Extension:		return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
     default:			return_trace (c->default_return_value ());
     }
   }
@@ -2800,7 +2800,7 @@
 
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
-  { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
+  { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
 
   bool subset (hb_subset_context_t *c) const
   { return Lookup::subset<SubTable> (c); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -225,7 +225,7 @@
     + hb_zip (this+coverage, substitute)
     | hb_filter (glyphset, hb_first)
     | hb_filter (glyphset, hb_second)
-    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID &> p) -> hb_codepoint_pair_t
+    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t
 			      { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
     ;
 
@@ -245,7 +245,7 @@
   Offset16To<Coverage>
 		coverage;		/* Offset to Coverage table--from
 					 * beginning of Substitution table */
-  Array16Of<HBGlyphID>
+  Array16Of<HBGlyphID16>
 		substitute;		/* Array of substitute
 					 * GlyphIDs--ordered by Coverage Index */
   public:
@@ -290,8 +290,8 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -391,7 +391,7 @@
   }
 
   protected:
-  Array16Of<HBGlyphID>
+  Array16Of<HBGlyphID16>
 		substitute;		/* String of GlyphIDs to substitute */
   public:
   DEFINE_SIZE_ARRAY (2, substitute);
@@ -443,9 +443,9 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID> glyphs,
+		  hb_sorted_array_t<const HBGlyphID16> glyphs,
 		  hb_array_t<const unsigned int> substitute_len_list,
-		  hb_array_t<const HBGlyphID> substitute_glyphs_list)
+		  hb_array_t<const HBGlyphID16> substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
@@ -504,9 +504,9 @@
 struct MultipleSubst
 {
   bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID> glyphs,
+		  hb_sorted_array_t<const HBGlyphID16> glyphs,
 		  hb_array_t<const unsigned int> substitute_len_list,
-		  hb_array_t<const HBGlyphID> substitute_glyphs_list)
+		  hb_array_t<const HBGlyphID16> substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
@@ -524,7 +524,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -624,7 +624,7 @@
   }
 
   protected:
-  Array16Of<HBGlyphID>
+  Array16Of<HBGlyphID16>
 		alternates;		/* Array of alternate GlyphIDs--in
 					 * arbitrary order */
   public:
@@ -686,9 +686,9 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID> glyphs,
+		  hb_sorted_array_t<const HBGlyphID16> glyphs,
 		  hb_array_t<const unsigned int> alternate_len_list,
-		  hb_array_t<const HBGlyphID> alternate_glyphs_list)
+		  hb_array_t<const HBGlyphID16> alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
@@ -747,9 +747,9 @@
 struct AlternateSubst
 {
   bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID> glyphs,
+		  hb_sorted_array_t<const HBGlyphID16> glyphs,
 		  hb_array_t<const unsigned int> alternate_len_list,
-		  hb_array_t<const HBGlyphID> alternate_glyphs_list)
+		  hb_array_t<const HBGlyphID16> alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
@@ -767,7 +767,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -861,7 +861,7 @@
     return_trace (true);
   }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
   {
     TRACE_SUBSET (this);
     const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
@@ -868,6 +868,8 @@
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false);
+    // Ensure Coverage table is always packed after this.
+    c->serializer->add_virtual_link (coverage_idx);
 
     auto it =
       + hb_iter (component)
@@ -888,8 +890,8 @@
   }
 
   protected:
-  HBGlyphID	ligGlyph;		/* GlyphID of ligature to substitute */
-  HeadlessArrayOf<HBGlyphID>
+  HBGlyphID16	ligGlyph;		/* GlyphID of ligature to substitute */
+  HeadlessArrayOf<HBGlyphID16>
 		component;		/* Array of component GlyphIDs--start
 					 * with the second  component--ordered
 					 * in writing direction */
@@ -949,9 +951,9 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const HBGlyphID> ligatures,
+		  hb_array_t<const HBGlyphID16> ligatures,
 		  hb_array_t<const unsigned int> component_count_list,
-		  hb_array_t<const HBGlyphID> &component_list /* Starting from second for each ligature */)
+		  hb_array_t<const HBGlyphID16> &component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
@@ -968,7 +970,7 @@
     return_trace (true);
   }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
@@ -975,9 +977,14 @@
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     + hb_iter (ligature)
-    | hb_filter (subset_offset_array (c, out->ligature, this))
+    | hb_filter (subset_offset_array (c, out->ligature, this, coverage_idx))
     | hb_drain
     ;
+
+    if (bool (out->ligature))
+      // Ensure Coverage table is always packed after this.
+      c->serializer->add_virtual_link (coverage_idx);
+
     return_trace (bool (out->ligature));
   }
 
@@ -1059,11 +1066,11 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID> first_glyphs,
+		  hb_sorted_array_t<const HBGlyphID16> first_glyphs,
 		  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-		  hb_array_t<const HBGlyphID> ligatures_list,
+		  hb_array_t<const HBGlyphID16> ligatures_list,
 		  hb_array_t<const unsigned int> component_count_list,
-		  hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
+		  hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
@@ -1092,15 +1099,38 @@
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
     out->format = format;
 
-    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
-    + hb_zip (this+coverage, ligatureSet)
+    // Due to a bug in some older versions of windows 7 the Coverage table must be
+    // packed after the LigatureSet and Ligature tables, so serialize Coverage first
+    // which places it last in the packed order.
+    hb_set_t new_coverage;
+    + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
     | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->ligatureSet, this), hb_second)
+    | hb_filter ([&] (const LigatureSet& _) {
+      return _.intersects (&glyphset);
+    }, hb_second)
     | hb_map (hb_first)
-    | hb_map (glyph_map)
-    | hb_sink (new_coverage)
+    | hb_sink (new_coverage);
+
+    if (!c->serializer->push<Coverage> ()
+        ->serialize (c->serializer,
+                     + new_coverage.iter () | hb_map_retains_sorting (glyph_map)))
+    {
+      c->serializer->pop_discard ();
+      return_trace (false);
+    }
+
+    unsigned coverage_idx = c->serializer->pop_pack ();
+     c->serializer->add_link (out->coverage, coverage_idx);
+
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_filter (new_coverage, hb_first)
+    | hb_map (hb_second)
+    // to ensure that the repacker always orders the coverage table after the LigatureSet
+    // and LigatureSubtable's they will be linked to the Coverage table via a virtual link
+    // the coverage table object idx is passed down to facilitate this.
+    | hb_apply (subset_offset_array (c, out->ligatureSet, this, coverage_idx))
     ;
-    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
+
     return_trace (bool (new_coverage));
   }
 
@@ -1125,11 +1155,11 @@
 struct LigatureSubst
 {
   bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID> first_glyphs,
+		  hb_sorted_array_t<const HBGlyphID16> first_glyphs,
 		  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-		  hb_array_t<const HBGlyphID> ligatures_list,
+		  hb_array_t<const HBGlyphID16> ligatures_list,
 		  hb_array_t<const unsigned int> component_count_list,
-		  hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
+		  hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
@@ -1152,7 +1182,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1208,7 +1238,7 @@
     if (!intersects (c->glyphs)) return;
 
     const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-    const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead);
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
 
     + hb_zip (this+coverage, substitute)
     | hb_filter (c->parent_active_glyphs (), hb_first)
@@ -1234,7 +1264,7 @@
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return;
 
-    const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead);
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
     count = substitute.len;
     c->output->add_array (substitute.arrayZ, substitute.len);
   }
@@ -1254,7 +1284,7 @@
     if (likely (index == NOT_COVERED)) return_trace (false);
 
     const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-    const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead);
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
 
     if (unlikely (index >= substitute.len)) return_trace (false);
 
@@ -1317,7 +1347,7 @@
     if (!serialize_coverage_offset_array (c, backtrack_iter)) return_trace (false);
     if (!serialize_coverage_offset_array (c, lookahead_iter)) return_trace (false);
 
-    auto *substitute_out = c->serializer->start_embed<Array16Of<HBGlyphID>> ();
+    auto *substitute_out = c->serializer->start_embed<Array16Of<HBGlyphID16>> ();
     auto substitutes =
     + coverage_subst_iter
     | hb_map (hb_second)
@@ -1342,13 +1372,13 @@
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-    const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead);
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
 
     auto it =
     + hb_zip (this+coverage, substitute)
     | hb_filter (glyphset, hb_first)
     | hb_filter (glyphset, hb_second)
-    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID &> p) -> hb_codepoint_pair_t
+    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t
                               { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
     ;
 
@@ -1363,7 +1393,7 @@
     const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
     if (!lookahead.sanitize (c, this))
       return_trace (false);
-    const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead);
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
     return_trace (substitute.sanitize (c));
   }
 
@@ -1380,7 +1410,7 @@
 		lookaheadX;		/* Array of coverage tables
 					 * in lookahead sequence, in glyph
 					 * sequence order */
-  Array16Of<HBGlyphID>
+  Array16Of<HBGlyphID16>
 		substituteX;		/* Array of substitute
 					 * GlyphIDs--ordered by Coverage Index */
   public:
@@ -1395,7 +1425,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1434,14 +1464,14 @@
   {
     TRACE_DISPATCH (this, lookup_type);
     switch (lookup_type) {
-    case Single:		return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...));
-    case Multiple:		return_trace (u.multiple.dispatch (c, hb_forward<Ts> (ds)...));
-    case Alternate:		return_trace (u.alternate.dispatch (c, hb_forward<Ts> (ds)...));
-    case Ligature:		return_trace (u.ligature.dispatch (c, hb_forward<Ts> (ds)...));
-    case Context:		return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...));
-    case ChainContext:		return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...));
-    case Extension:		return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...));
-    case ReverseChainSingle:	return_trace (u.reverseChainContextSingle.dispatch (c, hb_forward<Ts> (ds)...));
+    case Single:		return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
+    case Multiple:		return_trace (u.multiple.dispatch (c, std::forward<Ts> (ds)...));
+    case Alternate:		return_trace (u.alternate.dispatch (c, std::forward<Ts> (ds)...));
+    case Ligature:		return_trace (u.ligature.dispatch (c, std::forward<Ts> (ds)...));
+    case Context:		return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
+    case ChainContext:		return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
+    case Extension:		return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
+    case ReverseChainSingle:	return_trace (u.reverseChainContextSingle.dispatch (c, std::forward<Ts> (ds)...));
     default:			return_trace (c->default_return_value ());
     }
   }
@@ -1561,8 +1591,8 @@
 
   bool serialize_single (hb_serialize_context_t *c,
 			 uint32_t lookup_props,
-			 hb_sorted_array_t<const HBGlyphID> glyphs,
-			 hb_array_t<const HBGlyphID> substitutes)
+			 hb_sorted_array_t<const HBGlyphID16> glyphs,
+			 hb_array_t<const HBGlyphID16> substitutes)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
@@ -1577,9 +1607,9 @@
 
   bool serialize_multiple (hb_serialize_context_t *c,
 			   uint32_t lookup_props,
-			   hb_sorted_array_t<const HBGlyphID> glyphs,
+			   hb_sorted_array_t<const HBGlyphID16> glyphs,
 			   hb_array_t<const unsigned int> substitute_len_list,
-			   hb_array_t<const HBGlyphID> substitute_glyphs_list)
+			   hb_array_t<const HBGlyphID16> substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false);
@@ -1598,9 +1628,9 @@
 
   bool serialize_alternate (hb_serialize_context_t *c,
 			    uint32_t lookup_props,
-			    hb_sorted_array_t<const HBGlyphID> glyphs,
+			    hb_sorted_array_t<const HBGlyphID16> glyphs,
 			    hb_array_t<const unsigned int> alternate_len_list,
-			    hb_array_t<const HBGlyphID> alternate_glyphs_list)
+			    hb_array_t<const HBGlyphID16> alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false);
@@ -1620,11 +1650,11 @@
 
   bool serialize_ligature (hb_serialize_context_t *c,
 			   uint32_t lookup_props,
-			   hb_sorted_array_t<const HBGlyphID> first_glyphs,
+			   hb_sorted_array_t<const HBGlyphID16> first_glyphs,
 			   hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-			   hb_array_t<const HBGlyphID> ligatures_list,
+			   hb_array_t<const HBGlyphID16> ligatures_list,
 			   hb_array_t<const unsigned int> component_count_list,
-			   hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
+			   hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
@@ -1667,7 +1697,7 @@
 
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
-  { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
+  { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
 
   bool subset (hb_subset_context_t *c) const
   { return Lookup::subset<SubTable> (c); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1210,15 +1210,14 @@
 
 struct LookupRecord
 {
-  LookupRecord* copy (hb_serialize_context_t *c,
-		      const hb_map_t         *lookup_map) const
+  bool serialize (hb_serialize_context_t *c,
+		  const hb_map_t         *lookup_map) const
   {
     TRACE_SERIALIZE (this);
     auto *out = c->embed (*this);
-    if (unlikely (!out)) return_trace (nullptr);
+    if (unlikely (!out)) return_trace (false);
 
-    out->lookupListIndex = hb_map_get (lookup_map, lookupListIndex);
-    return_trace (out);
+    return_trace (c->check_assign (out->lookupListIndex, lookup_map->get (lookupListIndex), HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1235,6 +1234,24 @@
   DEFINE_SIZE_STATIC (4);
 };
 
+static unsigned serialize_lookuprecord_array (hb_serialize_context_t *c,
+					      const hb_array_t<const LookupRecord> lookupRecords,
+					      const hb_map_t *lookup_map)
+{
+  unsigned count = 0;
+  for (const LookupRecord& r : lookupRecords)
+  {
+    if (!lookup_map->has (r.lookupListIndex))
+      continue;
+
+    if (!r.serialize (c, lookup_map))
+      return 0;
+
+    count++;
+  }
+  return count;
+}
+
 enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 };
 
 static void context_closure_recurse_lookups (hb_closure_context_t *c,
@@ -1605,8 +1622,6 @@
     if (unlikely (!c->extend_min (out))) return_trace (false);
 
     out->inputCount = inputCount;
-    out->lookupCount = lookupCount;
-
     const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1);
     for (const auto org : input)
     {
@@ -1617,17 +1632,9 @@
 
     const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
 						       (inputZ.as_array ((inputCount ? inputCount - 1 : 0)));
-    for (unsigned i = 0; i < (unsigned) lookupCount; i++)
-    {
-      if (!lookup_map->has (lookupRecord[i].lookupListIndex))
-      {
-        out->lookupCount--;
-        continue;
-      }
-      c->copy (lookupRecord[i], lookup_map);
-    }
 
-    return_trace (true);
+    unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (lookupCount), lookup_map);
+    return_trace (c->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   bool subset (hb_subset_context_t *c,
@@ -1752,10 +1759,10 @@
     for (const Offset16To<Rule>& _ : rule)
     {
       if (!_) continue;
+      auto o_snap = c->serializer->snapshot ();
       auto *o = out->rule.serialize_append (c->serializer);
       if (unlikely (!o)) continue;
 
-      auto o_snap = c->serializer->snapshot ();
       if (!o->serialize_subset (c, _, this, lookup_map, klass_map))
       {
 	out->rule.pop ();
@@ -1943,6 +1950,13 @@
       &class_def
     };
 
+    hb_set_t retained_coverage_glyphs;
+    (this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs);
+
+    hb_set_t coverage_glyph_classes;
+    class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
+
+
     return
     + hb_iter (ruleSet)
     | hb_map (hb_add (this))
@@ -1949,6 +1963,7 @@
     | hb_enumerate
     | hb_map ([&] (const hb_pair_t<unsigned, const RuleSet &> p)
 	      { return class_def.intersects_class (glyphs, p.first) &&
+		       coverage_glyph_classes.has (p.first) &&
 		       p.second.intersects (glyphs, lookup_context); })
     | hb_any
     ;
@@ -2069,9 +2084,16 @@
     hb_map_t klass_map;
     out->classDef.serialize_subset (c, classDef, this, &klass_map);
 
+    const hb_set_t* glyphset = c->plan->glyphset_gsub ();
+    hb_set_t retained_coverage_glyphs;
+    (this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs);
+
+    hb_set_t coverage_glyph_classes;
+    (this+classDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
+
     const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
     bool ret = true;
-    int non_zero_index = 0, index = 0;
+    int non_zero_index = -1, index = 0;
     for (const auto& _ : + hb_enumerate (ruleSet)
 			 | hb_filter (klass_map, hb_first))
     {
@@ -2082,13 +2104,14 @@
 	break;
       }
 
-      if (o->serialize_subset (c, _.second, this, lookup_map, &klass_map))
+      if (coverage_glyph_classes.has (_.first) &&
+	  o->serialize_subset (c, _.second, this, lookup_map, &klass_map))
 	non_zero_index = index;
 
       index++;
     }
 
-    if (!ret) return_trace (ret);
+    if (!ret || non_zero_index == -1) return_trace (false);
 
     //prune empty trailing ruleSets
     --index;
@@ -2226,7 +2249,6 @@
 
     out->format = format;
     out->glyphCount = glyphCount;
-    out->lookupCount = lookupCount;
 
     auto coverages = coverageZ.as_array (glyphCount);
 
@@ -2238,19 +2260,12 @@
       if (!o->serialize_subset (c, offset, this)) return_trace (false);
     }
 
-    const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
+    const UnsizedArrayOf<LookupRecord>& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount));
     const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
-    for (unsigned i = 0; i < (unsigned) lookupCount; i++)
-    {
-      if (!lookup_map->has (lookupRecord[i].lookupListIndex))
-      {
-        out->lookupCount--;
-        continue;
-      }
-      c->serializer->copy (lookupRecord[i], lookup_map);
-    }
 
-    return_trace (true);
+
+    unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (lookupCount), lookup_map);
+    return_trace (c->serializer->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2289,9 +2304,9 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
-    case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2539,15 +2554,15 @@
       c->copy ((HBUINT16) g);
   }
 
-  ChainRule* copy (hb_serialize_context_t *c,
-		   const hb_map_t *lookup_map,
-		   const hb_map_t *backtrack_map,
-		   const hb_map_t *input_map = nullptr,
-		   const hb_map_t *lookahead_map = nullptr) const
+  bool serialize (hb_serialize_context_t *c,
+		  const hb_map_t *lookup_map,
+		  const hb_map_t *backtrack_map,
+		  const hb_map_t *input_map = nullptr,
+		  const hb_map_t *lookahead_map = nullptr) const
   {
     TRACE_SERIALIZE (this);
     auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
+    if (unlikely (!out)) return_trace (false);
 
     const hb_map_t *mapping = backtrack_map;
     serialize_array (c, backtrack.len, + backtrack.iter ()
@@ -2566,19 +2581,10 @@
     const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead);
 
     HBUINT16* lookupCount = c->embed (&(lookupRecord.len));
-    if (!lookupCount) return_trace (nullptr);
+    if (!lookupCount) return_trace (false);
 
-    for (unsigned i = 0; i < lookupRecord.len; i++)
-    {
-      if (!lookup_map->has (lookupRecord[i].lookupListIndex))
-      {
-        (*lookupCount)--;
-        continue;
-      }
-      if (!c->copy (lookupRecord[i], lookup_map)) return_trace (nullptr);
-    }
-
-    return_trace (out);
+    unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (), lookup_map);
+    return_trace (c->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   bool subset (hb_subset_context_t *c,
@@ -2600,7 +2606,7 @@
 	  !hb_all (lookahead, glyphset))
 	return_trace (false);
 
-      copy (c->serializer, lookup_map, c->plan->glyph_map);
+      serialize (c->serializer, lookup_map, c->plan->glyph_map);
     }
     else
     {
@@ -2609,7 +2615,7 @@
 	  !hb_all (lookahead, lookahead_map))
 	return_trace (false);
 
-      copy (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map);
+      serialize (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map);
     }
 
     return_trace (true);
@@ -2724,10 +2730,10 @@
     for (const Offset16To<ChainRule>& _ : rule)
     {
       if (!_) continue;
+      auto o_snap = c->serializer->snapshot ();
       auto *o = out->rule.serialize_append (c->serializer);
       if (unlikely (!o)) continue;
 
-      auto o_snap = c->serializer->snapshot ();
       if (!o->serialize_subset (c, _, this,
 				lookup_map,
 				backtrack_klass_map,
@@ -2920,6 +2926,12 @@
        &lookahead_class_def}
     };
 
+    hb_set_t retained_coverage_glyphs;
+    (this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs);
+
+    hb_set_t coverage_glyph_classes;
+    input_class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
+
     return
     + hb_iter (ruleSet)
     | hb_map (hb_add (this))
@@ -2926,6 +2938,7 @@
     | hb_enumerate
     | hb_map ([&] (const hb_pair_t<unsigned, const ChainRuleSet &> p)
 	      { return input_class_def.intersects_class (glyphs, p.first) &&
+		       coverage_glyph_classes.has (p.first) &&
 		       p.second.intersects (glyphs, lookup_context); })
     | hb_any
     ;
@@ -3080,13 +3093,19 @@
 						   lookahead_klass_map)))
       return_trace (false);
 
+    const hb_set_t* glyphset = c->plan->glyphset_gsub ();
+    hb_set_t retained_coverage_glyphs;
+    (this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs);
+
+    hb_set_t coverage_glyph_classes;
+    (this+inputClassDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
+
     int non_zero_index = -1, index = 0;
     bool ret = true;
     const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
     auto last_non_zero = c->serializer->snapshot ();
-    for (const Offset16To<ChainRuleSet>& _ : + hb_enumerate (ruleSet)
-					   | hb_filter (input_klass_map, hb_first)
-					   | hb_map (hb_second))
+    for (const auto& _ : + hb_enumerate (ruleSet)
+			 | hb_filter (input_klass_map, hb_first))
     {
       auto *o = out->ruleSet.serialize_append (c->serializer);
       if (unlikely (!o))
@@ -3094,7 +3113,8 @@
 	ret = false;
 	break;
       }
-      if (o->serialize_subset (c, _, this,
+      if (coverage_glyph_classes.has (_.first) &&
+          o->serialize_subset (c, _.second, this,
 			       lookup_map,
 			       &backtrack_klass_map,
 			       &input_klass_map,
@@ -3107,7 +3127,7 @@
       index++;
     }
 
-    if (!ret) return_trace (ret);
+    if (!ret || non_zero_index == -1) return_trace (false);
 
     // prune empty trailing ruleSets
     if (index > non_zero_index) {
@@ -3318,22 +3338,12 @@
 
     const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead);
     const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
-    hb_set_t lookup_indices;
-    for (unsigned i = 0; i < (unsigned) lookupRecord.len; i++)
-      if (lookup_map->has (lookupRecord[i].lookupListIndex))
-        lookup_indices.add (i);
 
-    HBUINT16 lookupCount;
-    lookupCount = lookup_indices.get_population ();
-    if (!c->serializer->copy (lookupCount)) return_trace (false);
+    HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookupRecord.len);
+    if (!lookupCount) return_trace (false);
 
-    for (unsigned i : lookup_indices.iter ())
-    {
-      if (!c->serializer->copy (lookupRecord[i], lookup_map))
-        return_trace (false);
-    }
-
-    return_trace (true);
+    unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (), lookup_map);
+    return_trace (c->serializer->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -3378,9 +3388,9 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
-    case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...));
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -3409,7 +3419,7 @@
   {
     TRACE_DISPATCH (this, format);
     if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ());
-    return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), hb_forward<Ts> (ds)...));
+    return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), std::forward<Ts> (ds)...));
   }
 
   void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
@@ -3489,7 +3499,7 @@
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (u.format1.dispatch (c, hb_forward<Ts> (ds)...));
+    case 1: return_trace (u.format1.dispatch (c, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -3678,57 +3688,72 @@
                                 const hb_set_t *feature_indices,
                                 hb_map_t *duplicate_feature_map /* OUT */) const
   {
+    if (feature_indices->is_empty ()) return;
+    hb_hashmap_t<hb_tag_t, hb_set_t *, (unsigned)-1, nullptr> unique_features;
     //find out duplicate features after subset
-    unsigned prev = 0xFFFFu;
     for (unsigned i : feature_indices->iter ())
     {
-      if (prev == 0xFFFFu)
+      hb_tag_t t = get_feature_tag (i);
+      if (t == unique_features.INVALID_KEY) continue;
+      if (!unique_features.has (t))
       {
+        hb_set_t* indices = hb_set_create ();
+        if (unlikely (indices == hb_set_get_empty () ||
+                      !unique_features.set (t, indices)))
+        {
+          hb_set_destroy (indices);
+          for (auto _ : unique_features.iter ())
+            hb_set_destroy (_.second);
+          return;
+        }
+        if (unique_features.get (t))
+          unique_features.get (t)->add (i);
         duplicate_feature_map->set (i, i);
-        prev = i;
         continue;
       }
 
-      hb_tag_t t = get_feature_tag (i);
-      hb_tag_t prev_t = get_feature_tag (prev);
-      if (t != prev_t)
+      bool found = false;
+
+      hb_set_t* same_tag_features = unique_features.get (t);
+      for (unsigned other_f_index : same_tag_features->iter ())
       {
-        duplicate_feature_map->set (i, i);
-        prev = i;
-        continue;
-      }
+        const Feature& f = get_feature (i);
+        const Feature& other_f = get_feature (other_f_index);
 
-      const Feature& f = get_feature (i);
-      const Feature& prev_f = get_feature (prev);
+        auto f_iter =
+        + hb_iter (f.lookupIndex)
+        | hb_filter (lookup_indices)
+        ;
 
-      auto f_iter =
-      + hb_iter (f.lookupIndex)
-      | hb_filter (lookup_indices)
-      ;
+        auto other_f_iter =
+        + hb_iter (other_f.lookupIndex)
+        | hb_filter (lookup_indices)
+        ;
 
-      auto prev_iter =
-      + hb_iter (prev_f.lookupIndex)
-      | hb_filter (lookup_indices)
-      ;
+        bool is_equal = true;
+        for (; f_iter && other_f_iter; f_iter++, other_f_iter++)
+        {
+          unsigned a = *f_iter;
+          unsigned b = *other_f_iter;
+          if (a != b) { is_equal = false; break; }
+        }
 
-      if (f_iter.len () != prev_iter.len ())
-      {
-        duplicate_feature_map->set (i, i);
-        prev = i;
-        continue;
+        if (is_equal == false || f_iter || other_f_iter) continue;
+
+        found = true;
+        duplicate_feature_map->set (i, other_f_index);
+        break;
       }
 
-      bool is_equal = true;
-      for (auto _ : + hb_zip (f_iter, prev_iter))
-        if (_.first != _.second) { is_equal = false; break; }
-
-      if (is_equal == true) duplicate_feature_map->set (i, prev);
-      else
+      if (found == false)
       {
+        same_tag_features->add (i);
         duplicate_feature_map->set (i, i);
-        prev = i;
       }
     }
+
+    for (auto _ : unique_features.iter ())
+      hb_set_destroy (_.second);
   }
 
   void prune_features (const hb_map_t *lookup_indices, /* IN */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -136,7 +136,7 @@
  * ExtenderGlyphs -- Extender Glyph Table
  */
 
-typedef SortedArray16Of<HBGlyphID> ExtenderGlyphs;
+typedef SortedArray16Of<HBGlyphID16> ExtenderGlyphs;
 
 
 /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -688,8 +688,8 @@
  *
  * Return value: %true if the language tag is found, %false otherwise
  *
- * Since: ??
- * Deprecated: ??
+ * Since: 0.6.0
+ * Deprecated: 2.0.0
  **/
 hb_bool_t
 hb_ot_layout_script_find_language (hb_face_t    *face,
@@ -1013,24 +1013,15 @@
     }
 
     has_feature_filter = true;
+    hb_set_t features_set;
     for (; *features; features++)
+      features_set.add (*features);
+    
+    for (unsigned i = 0; i < g.get_feature_count (); i++)
     {
-      hb_tag_t tag = *features;
-      unsigned index;
-      g.find_feature_index (tag, &index);
-      if (index == OT::Index::NOT_FOUND_INDEX) continue;
-
-      feature_indices_filter.add(index);
-      for (int i = (int) index - 1; i >= 0; i--)
-      {
-        if (g.get_feature_tag (i) != tag) break;
+      hb_tag_t tag = g.get_feature_tag (i);
+      if (features_set.has (tag))
         feature_indices_filter.add(i);
-      }
-      for (unsigned i = index + 1; i < g.get_feature_count (); i++)
-      {
-        if (g.get_feature_tag (i) != tag) break;
-        feature_indices_filter.add(i);
-      }
     }
   }
 
@@ -2011,7 +2002,7 @@
   private:
   template <typename T, typename ...Ts> auto
   _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
-  ( obj.get_glyph_alternates (hb_forward<Ts> (ds)...) )
+  ( obj.get_glyph_alternates (std::forward<Ts> (ds)...) )
   template <typename T, typename ...Ts> auto
   _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
   ( default_return_value () )
@@ -2018,7 +2009,7 @@
   public:
   template <typename T, typename ...Ts> auto
   dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
-  ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) )
+  ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
 };
 
 /**

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	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -187,7 +187,7 @@
  * - General_Category: 5 bits.
  * - A bit each for:
  *   * Is it Default_Ignorable(); we have a modified Default_Ignorable().
- *   * Whether it's one of the three Mongolian Free Variation Selectors,
+ *   * Whether it's one of the four Mongolian Free Variation Selectors,
  *     CGJ, or other characters that are hidden but should not be ignored
  *     like most other Default_Ignorable()s do during matching.
  *   * Whether it's a grapheme continuation.
@@ -202,7 +202,7 @@
 enum hb_unicode_props_flags_t {
   UPROPS_MASK_GEN_CAT	= 0x001Fu,
   UPROPS_MASK_IGNORABLE	= 0x0020u,
-  UPROPS_MASK_HIDDEN	= 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3, or TAG characters */
+  UPROPS_MASK_HIDDEN	= 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters */
   UPROPS_MASK_CONTINUATION=0x0080u,
 
   /* If GEN_CAT=FORMAT, top byte masks: */
@@ -236,7 +236,7 @@
        * FVSes are GC=Mn, we have use a separate bit to remember them.
        * Fixes:
        * https://github.com/harfbuzz/harfbuzz/issues/234 */
-      else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_HIDDEN;
+      else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu))) props |= UPROPS_MASK_HIDDEN;
       /* 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;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -41,6 +41,16 @@
   hb_position_t get_y_value (hb_font_t *font, const void *base) const
   { return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); }
 
+  MathValueRecord* copy (hb_serialize_context_t *c, const void *base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+    out->deviceTable.serialize_copy (c, deviceTable, base, 0, hb_serialize_context_t::Head);
+
+    return_trace (out);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -59,6 +69,29 @@
 
 struct MathConstants
 {
+  MathConstants* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2);
+    if (unlikely (!p)) return_trace (nullptr);
+    memcpy (p, percentScaleDown, HBINT16::static_size * 2);
+
+    HBUINT16 *m = c->allocate_size<HBUINT16> (HBUINT16::static_size * 2);
+    if (unlikely (!m)) return_trace (nullptr);
+    memcpy (m, minHeight, HBUINT16::static_size * 2);
+
+    unsigned count = ARRAY_LENGTH (mathValueRecords);
+    for (unsigned i = 0; i < count; i++)
+      if (!c->copy (mathValueRecords[i], this))
+        return_trace (nullptr);
+
+    if (!c->embed (radicalDegreeBottomRaisePercent)) return_trace (nullptr);
+    return_trace (out);
+  }
+
   bool sanitize_math_value_records (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -165,6 +198,28 @@
 
 struct MathItalicsCorrectionInfo
 {
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, italicsCorrection)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (serialize_math_record_array (c->serializer, out->italicsCorrection, this), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -196,6 +251,28 @@
 
 struct MathTopAccentAttachment
 {
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+topAccentCoverage, topAccentAttachment)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (serialize_math_record_array (c->serializer, out->topAccentAttachment, this), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    out->topAccentCoverage.serialize_serialize (c->serializer, new_coverage.iter ());
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -229,6 +306,22 @@
 
 struct MathKern
 {
+  MathKern* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    if (unlikely (!c->embed (heightCount))) return_trace (nullptr);
+
+    unsigned count = 2 * heightCount + 1;
+    for (unsigned i = 0; i < count; i++)
+      if (!c->copy (mathValueRecordsZ.arrayZ[i], this))
+        return_trace (nullptr);
+
+    return_trace (out);
+  }
+
   bool sanitize_math_value_records (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -295,6 +388,19 @@
 
 struct MathKernInfoRecord
 {
+  MathKernInfoRecord* copy (hb_serialize_context_t *c, const void *base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    unsigned count = ARRAY_LENGTH (mathKern);
+    for (unsigned i = 0; i < count; i++)
+      out->mathKern[i].serialize_copy (c, mathKern[i], base, 0, hb_serialize_context_t::Head);
+
+    return_trace (out);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -328,6 +434,28 @@
 
 struct MathKernInfo
 {
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+mathKernCoverage, mathKernInfoRecords)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (serialize_math_record_array (c->serializer, out->mathKernInfoRecords, this), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    out->mathKernCoverage.serialize_serialize (c->serializer, new_coverage.iter ());
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -365,6 +493,30 @@
 
 struct MathGlyphInfo
 {
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    out->mathItalicsCorrectionInfo.serialize_subset (c, mathItalicsCorrectionInfo, this);
+    out->mathTopAccentAttachment.serialize_subset (c, mathTopAccentAttachment, this);
+
+    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto it =
+    + hb_iter (this+extendedShapeCoverage)
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting (glyph_map)
+    ;
+
+    out->extendedShapeCoverage.serialize_serialize (c->serializer, it);
+
+    out->mathKernInfo.serialize_subset (c, mathKernInfo, this);
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -420,6 +572,16 @@
 {
   friend struct MathGlyphConstruction;
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    const hb_map_t& glyph_map = *c->plan->glyph_map;
+    return_trace (c->serializer->check_assign (out->variantGlyph, glyph_map.get (variantGlyph), HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -426,8 +588,11 @@
     return_trace (c->check_struct (this));
   }
 
+  void closure_glyphs (hb_set_t *variant_glyphs) const
+  { variant_glyphs->add (variantGlyph); }
+
   protected:
-  HBGlyphID variantGlyph;       /* Glyph ID for the variant. */
+  HBGlyphID16 variantGlyph;       /* Glyph ID for the variant. */
   HBUINT16  advanceMeasurement; /* Advance width/height, in design units, of the
 				 * variant, in the direction of requested
 				 * glyph extension. */
@@ -450,6 +615,16 @@
 
 struct MathGlyphPartRecord
 {
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    const hb_map_t& glyph_map = *c->plan->glyph_map;
+    return_trace (c->serializer->check_assign (out->glyph, glyph_map.get (glyph), HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -474,8 +649,11 @@
 		(partFlags & PartFlags::Defined);
   }
 
+  void closure_glyphs (hb_set_t *variant_glyphs) const
+  { variant_glyphs->add (glyph); }
+
   protected:
-  HBGlyphID	glyph;		/* Glyph ID for the part. */
+  HBGlyphID16	glyph;		/* Glyph ID for the part. */
   HBUINT16	startConnectorLength;
 				/* Advance width/ height of the straight bar
 				 * connector material, in design units, is at
@@ -497,6 +675,20 @@
 
 struct MathGlyphAssembly
 {
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (!c->serializer->copy (italicsCorrection, this)) return_trace (false);
+    if (!c->serializer->copy<HBUINT16> (partRecords.len)) return_trace (false);
+
+    for (const auto& record : partRecords.iter ())
+      if (!record.subset (c)) return_trace (false);
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -526,6 +718,12 @@
     return partRecords.len;
   }
 
+  void closure_glyphs (hb_set_t *variant_glyphs) const
+  {
+    for (const auto& _ : partRecords.iter ())
+      _.closure_glyphs (variant_glyphs);
+  }
+
   protected:
   MathValueRecord
 		italicsCorrection;
@@ -543,6 +741,22 @@
 
 struct MathGlyphConstruction
 {
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    out->glyphAssembly.serialize_subset (c, glyphAssembly, this);
+
+    if (!c->serializer->check_assign (out->mathGlyphVariantRecord.len, mathGlyphVariantRecord.len, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+    for (const auto& record : mathGlyphVariantRecord.iter ())
+      if (!record.subset (c)) return_trace (false);
+
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -569,6 +783,14 @@
     return mathGlyphVariantRecord.len;
   }
 
+  void closure_glyphs (hb_set_t *variant_glyphs) const
+  {
+    (this+glyphAssembly).closure_glyphs (variant_glyphs);
+
+    for (const auto& _ : mathGlyphVariantRecord.iter ())
+      _.closure_glyphs (variant_glyphs);
+  }
+
   protected:
   /* Offset to MathGlyphAssembly table for this shape - from the beginning of
      MathGlyphConstruction table.  May be NULL. */
@@ -583,6 +805,91 @@
 
 struct MathVariants
 {
+  void closure_glyphs (const hb_set_t *glyph_set,
+                       hb_set_t *variant_glyphs) const
+  {
+    const hb_array_t<const Offset16To<MathGlyphConstruction>> glyph_construction_offsets = glyphConstruction.as_array (vertGlyphCount + horizGlyphCount);
+
+    if (vertGlyphCoverage)
+    {
+      const auto vert_offsets = glyph_construction_offsets.sub_array (0, vertGlyphCount);
+      + hb_zip (this+vertGlyphCoverage, vert_offsets)
+      | hb_filter (glyph_set, hb_first)
+      | hb_map (hb_second)
+      | hb_map (hb_add (this))
+      | hb_apply ([=] (const MathGlyphConstruction &_) { _.closure_glyphs (variant_glyphs); })
+      ;
+    }
+
+    if (horizGlyphCoverage)
+    {
+      const auto hori_offsets = glyph_construction_offsets.sub_array (vertGlyphCount, horizGlyphCount);
+      + hb_zip (this+horizGlyphCoverage, hori_offsets)
+      | hb_filter (glyph_set, hb_first)
+      | hb_map (hb_second)
+      | hb_map (hb_add (this))
+      | hb_apply ([=] (const MathGlyphConstruction &_) { _.closure_glyphs (variant_glyphs); })
+      ;
+    }
+  }
+
+  void collect_coverage_and_indices (hb_sorted_vector_t<hb_codepoint_t>& new_coverage,
+                                     const Offset16To<Coverage>& coverage,
+                                     unsigned i,
+                                     unsigned end_index,
+                                     hb_set_t& indices,
+                                     const hb_set_t& glyphset,
+                                     const hb_map_t& glyph_map) const
+  {
+    if (!coverage) return;
+
+    for (const auto _ : (this+coverage).iter ())
+    {
+      if (i >= end_index) return;
+      if (glyphset.has (_))
+      {
+        unsigned new_gid = glyph_map.get (_);
+        new_coverage.push (new_gid);
+        indices.add (i);
+      }
+      i++;
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    if (!c->serializer->check_assign (out->minConnectorOverlap, minConnectorOverlap, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+    
+    hb_sorted_vector_t<hb_codepoint_t> new_vert_coverage;
+    hb_sorted_vector_t<hb_codepoint_t> new_hori_coverage;
+    hb_set_t indices;
+    collect_coverage_and_indices (new_vert_coverage, vertGlyphCoverage, 0, vertGlyphCount, indices, glyphset, glyph_map);
+    collect_coverage_and_indices (new_hori_coverage, horizGlyphCoverage, vertGlyphCount, vertGlyphCount + horizGlyphCount, indices, glyphset, glyph_map);
+    
+    if (!c->serializer->check_assign (out->vertGlyphCount, new_vert_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+    if (!c->serializer->check_assign (out->horizGlyphCount, new_hori_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+
+    for (unsigned i : indices.iter ())
+    {
+      auto *o = c->serializer->embed (glyphConstruction[i]);
+      if (!o) return_trace (false);
+      o->serialize_subset (c, glyphConstruction[i], this);
+    }
+
+    out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ());
+    out->horizGlyphCoverage.serialize_serialize (c->serializer, new_hori_coverage.iter ());
+    return_trace (true);
+  }
+
   bool sanitize_offsets (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -690,6 +997,28 @@
 
   bool has_data () const { return version.to_int (); }
 
+  void closure_glyphs (hb_set_t *glyph_set) const
+  {
+    if (mathVariants)
+    {
+      hb_set_t variant_glyphs;
+      (this+mathVariants).closure_glyphs (glyph_set, &variant_glyphs);
+      hb_set_union (glyph_set, &variant_glyphs);
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    out->mathConstants.serialize_copy (c->serializer, mathConstants, this, 0, hb_serialize_context_t::Head);
+    out->mathGlyphInfo.serialize_subset (c, mathGlyphInfo, this);
+    out->mathVariants.serialize_subset (c, mathVariants, this);
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h	2021-11-04 00:51:18 UTC (rev 60943)
@@ -36,6 +36,33 @@
 
 /**
  * hb_ot_name_id_t:
+ * @HB_OT_NAME_ID_COPYRIGHT: Copyright notice
+ * @HB_OT_NAME_ID_FONT_FAMILY: Font Family name
+ * @HB_OT_NAME_ID_FONT_SUBFAMILY: Font Subfamily name
+ * @HB_OT_NAME_ID_UNIQUE_ID: Unique font identifier
+ * @HB_OT_NAME_ID_FULL_NAME: Full font name that reflects
+ * all family and relevant subfamily descriptors
+ * @HB_OT_NAME_ID_VERSION_STRING: Version string
+ * @HB_OT_NAME_ID_POSTSCRIPT_NAME: PostScript name for the font
+ * @HB_OT_NAME_ID_TRADEMARK: Trademark
+ * @HB_OT_NAME_ID_MANUFACTURER: Manufacturer Name
+ * @HB_OT_NAME_ID_DESIGNER: Designer
+ * @HB_OT_NAME_ID_DESCRIPTION: Description
+ * @HB_OT_NAME_ID_VENDOR_URL: URL of font vendor
+ * @HB_OT_NAME_ID_DESIGNER_URL: URL of typeface designer
+ * @HB_OT_NAME_ID_LICENSE: License Description
+ * @HB_OT_NAME_ID_LICENSE_URL: URL where additional licensing
+ * information can be found
+ * @HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY: Typographic Family name
+ * @HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY: Typographic Subfamily name
+ * @HB_OT_NAME_ID_MAC_FULL_NAME: Compatible Full Name for MacOS
+ * @HB_OT_NAME_ID_SAMPLE_TEXT: Sample text
+ * @HB_OT_NAME_ID_CID_FINDFONT_NAME: PostScript CID findfont name
+ * @HB_OT_NAME_ID_WWS_FAMILY: WWS Family Name
+ * @HB_OT_NAME_ID_WWS_SUBFAMILY: WWS Subfamily Name
+ * @HB_OT_NAME_ID_LIGHT_BACKGROUND: Light Background Palette
+ * @HB_OT_NAME_ID_DARK_BACKGROUND: Dark Background Palette
+ * @HB_OT_NAME_ID_VARIATIONS_PS_PREFIX: Variations PostScript Name Prefix
  * @HB_OT_NAME_ID_INVALID: Value to represent a nonexistent name ID.
  *
  * An integral type representing an OpenType 'name' table name identifier.
@@ -42,6 +69,9 @@
  * There are predefined name IDs, as well as name IDs return from other
  * API.  These can be used to fetch name strings from a font face.
  *
+ * For more information on these fields, see the
+ * [OpenType spec](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids).
+ *
  * Since: 2.0.0
  **/
 enum

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -49,8 +49,8 @@
 					  hb_font_t *font,
 					  unsigned int feature_index)
 {
-  OT::HBGlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
-  OT::HBGlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+  OT::HBGlyphID16 glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+  OT::HBGlyphID16 substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
   unsigned int num_glyphs = 0;
 
   /* Populate arrays */
@@ -78,7 +78,7 @@
   /* Bubble-sort or something equally good!
    * May not be good-enough for presidential candidate interviews, but good-enough for us... */
   hb_stable_sort (&glyphs[0], num_glyphs,
-		  (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp,
+		  (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID16::cmp,
 		  &substitutes[0]);
 
 
@@ -99,15 +99,15 @@
 arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
 					    hb_font_t *font)
 {
-  OT::HBGlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
+  OT::HBGlyphID16 first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
   unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
   unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
   unsigned int num_first_glyphs = 0;
 
   /* We know that all our ligatures are 2-component */
-  OT::HBGlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
+  OT::HBGlyphID16 ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
   unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
-  OT::HBGlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
+  OT::HBGlyphID16 component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
   unsigned int num_ligatures = 0;
 
   /* Populate arrays */
@@ -125,7 +125,7 @@
     num_first_glyphs++;
   }
   hb_stable_sort (&first_glyphs[0], num_first_glyphs,
-		  (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp,
+		  (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID16::cmp,
 		  &first_glyphs_indirection[0]);
 
   /* Now that the first-glyphs are sorted, walk again, populate ligatures. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -349,7 +349,7 @@
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 1; i < count; i++)
-    if (unlikely (hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du)))
+    if (unlikely (hb_in_ranges<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu)))
       info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action();
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -202,9 +202,6 @@
   for (; i < INDIC_NUM_FEATURES; i++)
     map->add_feature (indic_features[i]);
 
-  map->enable_feature (HB_TAG('c','a','l','t'));
-  map->enable_feature (HB_TAG('c','l','i','g'));
-
   map->add_gsub_pause (_hb_clear_syllables);
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -49,6 +49,8 @@
   //OT_VPst = 29,
 };
 
+using khmer_position_t = indic_position_t;
+
 static inline void
 set_khmer_properties (hb_glyph_info_t &info)
 {
@@ -55,7 +57,7 @@
   hb_codepoint_t u = info.codepoint;
   unsigned int type = hb_indic_get_categories (u);
   khmer_category_t cat = (khmer_category_t) (type & 0xFFu);
-  indic_position_t pos = (indic_position_t) (type >> 8);
+  khmer_position_t pos = (khmer_position_t) (type >> 8);
 
 
   /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -51,6 +51,7 @@
 #define myanmar_syllable_machine_ex_H 4u
 #define myanmar_syllable_machine_ex_IV 2u
 #define myanmar_syllable_machine_ex_MH 21u
+#define myanmar_syllable_machine_ex_ML 33u
 #define myanmar_syllable_machine_ex_MR 22u
 #define myanmar_syllable_machine_ex_MW 23u
 #define myanmar_syllable_machine_ex_MY 24u
@@ -67,35 +68,36 @@
 #define myanmar_syllable_machine_ex_ZWNJ 5u
 
 
-#line 71 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 72 "hb-ot-shape-complex-myanmar-machine.hh"
 static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
-	1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 
-	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, 
-	3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
-	5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 
-	3u, 29u, 3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
-	3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 
-	3u, 29u, 1u, 32u, 1u, 32u, 8u, 8u, 0
+	1u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 
+	3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u, 
+	3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u, 3u, 33u, 
+	3u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 
+	3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u, 
+	3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u, 
+	3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 1u, 33u, 1u, 32u, 8u, 8u, 
+	0
 };
 
 static const char _myanmar_syllable_machine_key_spans[] = {
-	32, 28, 25, 4, 25, 23, 21, 21, 
-	27, 27, 27, 27, 16, 27, 27, 27, 
-	27, 27, 28, 27, 27, 27, 27, 27, 
-	25, 4, 25, 23, 21, 21, 27, 27, 
-	27, 27, 16, 28, 27, 27, 27, 27, 
-	27, 28, 27, 27, 27, 27, 27, 28, 
-	27, 32, 32, 1
+	33, 31, 25, 4, 25, 23, 21, 21, 
+	31, 27, 27, 27, 31, 16, 31, 31, 
+	27, 27, 27, 28, 27, 31, 31, 31, 
+	31, 31, 25, 4, 25, 23, 21, 21, 
+	31, 27, 27, 27, 31, 16, 31, 31, 
+	31, 27, 27, 27, 28, 27, 31, 31, 
+	31, 31, 31, 31, 31, 33, 32, 1
 };
 
 static const short _myanmar_syllable_machine_index_offsets[] = {
-	0, 33, 62, 88, 93, 119, 143, 165, 
-	187, 215, 243, 271, 299, 316, 344, 372, 
-	400, 428, 456, 485, 513, 541, 569, 597, 
-	625, 651, 656, 682, 706, 728, 750, 778, 
-	806, 834, 862, 879, 908, 936, 964, 992, 
-	1020, 1048, 1077, 1105, 1133, 1161, 1189, 1217, 
-	1246, 1274, 1307, 1340
+	0, 34, 66, 92, 97, 123, 147, 169, 
+	191, 223, 251, 279, 307, 339, 356, 388, 
+	420, 448, 476, 504, 533, 561, 593, 625, 
+	657, 689, 721, 747, 752, 778, 802, 824, 
+	846, 878, 906, 934, 962, 994, 1011, 1043, 
+	1075, 1107, 1135, 1163, 1191, 1220, 1248, 1280, 
+	1312, 1344, 1376, 1408, 1440, 1472, 1506, 1539
 };
 
 static const char _myanmar_syllable_machine_indicies[] = {
@@ -103,192 +105,217 @@
 	0, 6, 1, 0, 0, 0, 0, 7, 
 	0, 8, 9, 0, 10, 11, 12, 13, 
 	14, 15, 16, 17, 18, 19, 20, 1, 
-	0, 22, 23, 24, 24, 21, 25, 21, 
-	26, 21, 21, 21, 21, 21, 21, 21, 
-	27, 21, 21, 28, 29, 30, 31, 32, 
-	33, 34, 35, 36, 37, 21, 24, 24, 
-	21, 25, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 38, 21, 21, 21, 21, 
-	21, 21, 32, 21, 21, 21, 36, 21, 
-	24, 24, 21, 25, 21, 24, 24, 21, 
-	25, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 32, 21, 21, 21, 36, 21, 39, 
-	21, 24, 24, 21, 25, 21, 32, 21, 
-	21, 21, 21, 21, 21, 21, 40, 21, 
-	21, 21, 21, 21, 21, 32, 21, 24, 
-	24, 21, 25, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 40, 21, 21, 21, 
-	21, 21, 21, 32, 21, 24, 24, 21, 
-	25, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 32, 21, 22, 21, 24, 24, 21, 
-	25, 21, 26, 21, 21, 21, 21, 21, 
-	21, 21, 41, 21, 21, 41, 21, 21, 
-	21, 32, 42, 21, 21, 36, 21, 22, 
-	21, 24, 24, 21, 25, 21, 26, 21, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 32, 21, 21, 
-	21, 36, 21, 22, 21, 24, 24, 21, 
-	25, 21, 26, 21, 21, 21, 21, 21, 
-	21, 21, 41, 21, 21, 21, 21, 21, 
-	21, 32, 42, 21, 21, 36, 21, 22, 
-	21, 24, 24, 21, 25, 21, 26, 21, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 32, 42, 21, 
-	21, 36, 21, 1, 1, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 1, 21, 22, 21, 24, 24, 
-	21, 25, 21, 26, 21, 21, 21, 21, 
-	21, 21, 21, 27, 21, 21, 28, 29, 
-	30, 31, 32, 33, 34, 35, 36, 21, 
-	22, 21, 24, 24, 21, 25, 21, 26, 
-	21, 21, 21, 21, 21, 21, 21, 43, 
-	21, 21, 21, 21, 21, 21, 32, 33, 
-	34, 35, 36, 21, 22, 21, 24, 24, 
-	21, 25, 21, 26, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 32, 33, 34, 35, 36, 21, 
-	22, 21, 24, 24, 21, 25, 21, 26, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 32, 33, 
-	34, 21, 36, 21, 22, 21, 24, 24, 
-	21, 25, 21, 26, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 32, 21, 34, 21, 36, 21, 
-	22, 21, 24, 24, 21, 25, 21, 26, 
-	21, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 32, 33, 
-	34, 35, 36, 43, 21, 22, 21, 24, 
-	24, 21, 25, 21, 26, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 21, 28, 
-	21, 30, 21, 32, 33, 34, 35, 36, 
-	21, 22, 21, 24, 24, 21, 25, 21, 
-	26, 21, 21, 21, 21, 21, 21, 21, 
-	43, 21, 21, 28, 21, 21, 21, 32, 
-	33, 34, 35, 36, 21, 22, 21, 24, 
-	24, 21, 25, 21, 26, 21, 21, 21, 
-	21, 21, 21, 21, 44, 21, 21, 28, 
-	29, 30, 21, 32, 33, 34, 35, 36, 
-	21, 22, 21, 24, 24, 21, 25, 21, 
-	26, 21, 21, 21, 21, 21, 21, 21, 
-	21, 21, 21, 28, 29, 30, 21, 32, 
-	33, 34, 35, 36, 21, 22, 23, 24, 
-	24, 21, 25, 21, 26, 21, 21, 21, 
-	21, 21, 21, 21, 27, 21, 21, 28, 
-	29, 30, 31, 32, 33, 34, 35, 36, 
-	21, 46, 46, 45, 5, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 47, 45, 
-	45, 45, 45, 45, 45, 14, 45, 45, 
-	45, 18, 45, 46, 46, 45, 5, 45, 
-	46, 46, 45, 5, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	45, 45, 45, 45, 14, 45, 45, 45, 
-	18, 45, 48, 45, 46, 46, 45, 5, 
-	45, 14, 45, 45, 45, 45, 45, 45, 
-	45, 49, 45, 45, 45, 45, 45, 45, 
-	14, 45, 46, 46, 45, 5, 45, 45, 
-	45, 45, 45, 45, 45, 45, 45, 49, 
-	45, 45, 45, 45, 45, 45, 14, 45, 
-	46, 46, 45, 5, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	45, 45, 45, 45, 14, 45, 2, 45, 
-	46, 46, 45, 5, 45, 6, 45, 45, 
-	45, 45, 45, 45, 45, 50, 45, 45, 
-	50, 45, 45, 45, 14, 51, 45, 45, 
-	18, 45, 2, 45, 46, 46, 45, 5, 
-	45, 6, 45, 45, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	14, 45, 45, 45, 18, 45, 2, 45, 
-	46, 46, 45, 5, 45, 6, 45, 45, 
-	45, 45, 45, 45, 45, 50, 45, 45, 
-	45, 45, 45, 45, 14, 51, 45, 45, 
-	18, 45, 2, 45, 46, 46, 45, 5, 
-	45, 6, 45, 45, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	14, 51, 45, 45, 18, 45, 52, 52, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 52, 45, 2, 
-	3, 46, 46, 45, 5, 45, 6, 45, 
-	45, 45, 45, 45, 45, 45, 8, 45, 
-	45, 10, 11, 12, 13, 14, 15, 16, 
-	17, 18, 19, 45, 2, 45, 46, 46, 
-	45, 5, 45, 6, 45, 45, 45, 45, 
-	45, 45, 45, 8, 45, 45, 10, 11, 
-	12, 13, 14, 15, 16, 17, 18, 45, 
-	2, 45, 46, 46, 45, 5, 45, 6, 
-	45, 45, 45, 45, 45, 45, 45, 53, 
-	45, 45, 45, 45, 45, 45, 14, 15, 
-	16, 17, 18, 45, 2, 45, 46, 46, 
-	45, 5, 45, 6, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	45, 45, 14, 15, 16, 17, 18, 45, 
-	2, 45, 46, 46, 45, 5, 45, 6, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 14, 15, 
-	16, 45, 18, 45, 2, 45, 46, 46, 
-	45, 5, 45, 6, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	45, 45, 14, 45, 16, 45, 18, 45, 
-	2, 45, 46, 46, 45, 5, 45, 6, 
-	45, 45, 45, 45, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 14, 15, 
-	16, 17, 18, 53, 45, 2, 45, 46, 
-	46, 45, 5, 45, 6, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 45, 10, 
-	45, 12, 45, 14, 15, 16, 17, 18, 
-	45, 2, 45, 46, 46, 45, 5, 45, 
-	6, 45, 45, 45, 45, 45, 45, 45, 
-	53, 45, 45, 10, 45, 45, 45, 14, 
-	15, 16, 17, 18, 45, 2, 45, 46, 
-	46, 45, 5, 45, 6, 45, 45, 45, 
-	45, 45, 45, 45, 54, 45, 45, 10, 
-	11, 12, 45, 14, 15, 16, 17, 18, 
-	45, 2, 45, 46, 46, 45, 5, 45, 
-	6, 45, 45, 45, 45, 45, 45, 45, 
-	45, 45, 45, 10, 11, 12, 45, 14, 
-	15, 16, 17, 18, 45, 2, 3, 46, 
-	46, 45, 5, 45, 6, 45, 45, 45, 
-	45, 45, 45, 45, 8, 45, 45, 10, 
-	11, 12, 13, 14, 15, 16, 17, 18, 
-	45, 22, 23, 24, 24, 21, 25, 21, 
-	26, 21, 21, 21, 21, 21, 21, 21, 
-	55, 21, 21, 28, 29, 30, 31, 32, 
-	33, 34, 35, 36, 37, 21, 22, 56, 
-	24, 24, 21, 25, 21, 26, 21, 21, 
-	21, 21, 21, 21, 21, 27, 21, 21, 
-	28, 29, 30, 31, 32, 33, 34, 35, 
-	36, 21, 1, 1, 2, 3, 46, 46, 
-	45, 5, 45, 6, 1, 45, 45, 45, 
-	45, 1, 45, 8, 45, 45, 10, 11, 
-	12, 13, 14, 15, 16, 17, 18, 19, 
-	45, 1, 45, 1, 1, 57, 57, 57, 
-	57, 57, 57, 57, 57, 1, 57, 57, 
-	57, 57, 1, 57, 57, 57, 57, 57, 
-	57, 57, 57, 57, 57, 57, 57, 57, 
-	57, 57, 1, 57, 58, 57, 0
+	21, 0, 23, 24, 25, 25, 22, 26, 
+	22, 27, 22, 22, 22, 22, 22, 22, 
+	22, 28, 22, 22, 29, 30, 31, 32, 
+	33, 34, 35, 36, 37, 38, 22, 22, 
+	39, 22, 25, 25, 22, 26, 22, 22, 
+	22, 22, 22, 22, 22, 22, 22, 40, 
+	22, 22, 22, 22, 22, 22, 33, 22, 
+	22, 22, 37, 22, 25, 25, 22, 26, 
+	22, 25, 25, 22, 26, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 33, 22, 22, 
+	22, 37, 22, 41, 22, 25, 25, 22, 
+	26, 22, 33, 22, 22, 22, 22, 22, 
+	22, 22, 42, 22, 22, 22, 22, 22, 
+	22, 33, 22, 25, 25, 22, 26, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	42, 22, 22, 22, 22, 22, 22, 33, 
+	22, 25, 25, 22, 26, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 33, 22, 23, 
+	22, 25, 25, 22, 26, 22, 27, 22, 
+	22, 22, 22, 22, 22, 22, 43, 22, 
+	22, 44, 22, 22, 22, 33, 45, 22, 
+	22, 37, 22, 22, 22, 43, 22, 23, 
+	22, 25, 25, 22, 26, 22, 27, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 33, 22, 22, 
+	22, 37, 22, 23, 22, 25, 25, 22, 
+	26, 22, 27, 22, 22, 22, 22, 22, 
+	22, 22, 43, 22, 22, 22, 22, 22, 
+	22, 33, 45, 22, 22, 37, 22, 23, 
+	22, 25, 25, 22, 26, 22, 27, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 33, 45, 22, 
+	22, 37, 22, 23, 22, 25, 25, 22, 
+	26, 22, 27, 22, 22, 22, 22, 22, 
+	22, 22, 43, 22, 22, 22, 22, 22, 
+	22, 33, 45, 22, 22, 37, 22, 22, 
+	22, 43, 22, 1, 1, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 1, 22, 23, 22, 25, 25, 
+	22, 26, 22, 27, 22, 22, 22, 22, 
+	22, 22, 22, 28, 22, 22, 29, 30, 
+	31, 32, 33, 34, 35, 36, 37, 22, 
+	22, 22, 39, 22, 23, 22, 25, 25, 
+	22, 26, 22, 27, 22, 22, 22, 22, 
+	22, 22, 22, 46, 22, 22, 22, 22, 
+	22, 22, 33, 34, 35, 36, 37, 22, 
+	22, 22, 39, 22, 23, 22, 25, 25, 
+	22, 26, 22, 27, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 33, 34, 35, 36, 37, 22, 
+	23, 22, 25, 25, 22, 26, 22, 27, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 33, 34, 
+	35, 22, 37, 22, 23, 22, 25, 25, 
+	22, 26, 22, 27, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 33, 22, 35, 22, 37, 22, 
+	23, 22, 25, 25, 22, 26, 22, 27, 
+	22, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 22, 22, 22, 33, 34, 
+	35, 36, 37, 46, 22, 23, 22, 25, 
+	25, 22, 26, 22, 27, 22, 22, 22, 
+	22, 22, 22, 22, 46, 22, 22, 22, 
+	22, 22, 22, 33, 34, 35, 36, 37, 
+	22, 23, 22, 25, 25, 22, 26, 22, 
+	27, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 29, 22, 31, 22, 33, 
+	34, 35, 36, 37, 22, 22, 22, 39, 
+	22, 23, 22, 25, 25, 22, 26, 22, 
+	27, 22, 22, 22, 22, 22, 22, 22, 
+	46, 22, 22, 29, 22, 22, 22, 33, 
+	34, 35, 36, 37, 22, 22, 22, 39, 
+	22, 23, 22, 25, 25, 22, 26, 22, 
+	27, 22, 22, 22, 22, 22, 22, 22, 
+	47, 22, 22, 29, 30, 31, 22, 33, 
+	34, 35, 36, 37, 22, 22, 22, 39, 
+	22, 23, 22, 25, 25, 22, 26, 22, 
+	27, 22, 22, 22, 22, 22, 22, 22, 
+	22, 22, 22, 29, 30, 31, 22, 33, 
+	34, 35, 36, 37, 22, 22, 22, 39, 
+	22, 23, 24, 25, 25, 22, 26, 22, 
+	27, 22, 22, 22, 22, 22, 22, 22, 
+	28, 22, 22, 29, 30, 31, 32, 33, 
+	34, 35, 36, 37, 22, 22, 22, 39, 
+	22, 49, 49, 48, 5, 48, 48, 48, 
+	48, 48, 48, 48, 48, 48, 50, 48, 
+	48, 48, 48, 48, 48, 14, 48, 48, 
+	48, 18, 48, 49, 49, 48, 5, 48, 
+	49, 49, 48, 5, 48, 48, 48, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 48, 48, 14, 48, 48, 48, 
+	18, 48, 51, 48, 49, 49, 48, 5, 
+	48, 14, 48, 48, 48, 48, 48, 48, 
+	48, 52, 48, 48, 48, 48, 48, 48, 
+	14, 48, 49, 49, 48, 5, 48, 48, 
+	48, 48, 48, 48, 48, 48, 48, 52, 
+	48, 48, 48, 48, 48, 48, 14, 48, 
+	49, 49, 48, 5, 48, 48, 48, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 48, 48, 14, 48, 2, 48, 
+	49, 49, 48, 5, 48, 6, 48, 48, 
+	48, 48, 48, 48, 48, 53, 48, 48, 
+	54, 48, 48, 48, 14, 55, 48, 48, 
+	18, 48, 48, 48, 53, 48, 2, 48, 
+	49, 49, 48, 5, 48, 6, 48, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 48, 48, 14, 48, 48, 48, 
+	18, 48, 2, 48, 49, 49, 48, 5, 
+	48, 6, 48, 48, 48, 48, 48, 48, 
+	48, 53, 48, 48, 48, 48, 48, 48, 
+	14, 55, 48, 48, 18, 48, 2, 48, 
+	49, 49, 48, 5, 48, 6, 48, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 48, 48, 14, 55, 48, 48, 
+	18, 48, 2, 48, 49, 49, 48, 5, 
+	48, 6, 48, 48, 48, 48, 48, 48, 
+	48, 53, 48, 48, 48, 48, 48, 48, 
+	14, 55, 48, 48, 18, 48, 48, 48, 
+	53, 48, 56, 56, 48, 48, 48, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 56, 48, 2, 3, 49, 49, 48, 
+	5, 48, 6, 48, 48, 48, 48, 48, 
+	48, 48, 8, 48, 48, 10, 11, 12, 
+	13, 14, 15, 16, 17, 18, 19, 48, 
+	48, 21, 48, 2, 48, 49, 49, 48, 
+	5, 48, 6, 48, 48, 48, 48, 48, 
+	48, 48, 8, 48, 48, 10, 11, 12, 
+	13, 14, 15, 16, 17, 18, 48, 48, 
+	48, 21, 48, 2, 48, 49, 49, 48, 
+	5, 48, 6, 48, 48, 48, 48, 48, 
+	48, 48, 57, 48, 48, 48, 48, 48, 
+	48, 14, 15, 16, 17, 18, 48, 48, 
+	48, 21, 48, 2, 48, 49, 49, 48, 
+	5, 48, 6, 48, 48, 48, 48, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 14, 15, 16, 17, 18, 48, 2, 
+	48, 49, 49, 48, 5, 48, 6, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 48, 48, 48, 14, 15, 16, 
+	48, 18, 48, 2, 48, 49, 49, 48, 
+	5, 48, 6, 48, 48, 48, 48, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 14, 48, 16, 48, 18, 48, 2, 
+	48, 49, 49, 48, 5, 48, 6, 48, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 48, 48, 48, 14, 15, 16, 
+	17, 18, 57, 48, 2, 48, 49, 49, 
+	48, 5, 48, 6, 48, 48, 48, 48, 
+	48, 48, 48, 57, 48, 48, 48, 48, 
+	48, 48, 14, 15, 16, 17, 18, 48, 
+	2, 48, 49, 49, 48, 5, 48, 6, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 10, 48, 12, 48, 14, 15, 
+	16, 17, 18, 48, 48, 48, 21, 48, 
+	2, 48, 49, 49, 48, 5, 48, 6, 
+	48, 48, 48, 48, 48, 48, 48, 57, 
+	48, 48, 10, 48, 48, 48, 14, 15, 
+	16, 17, 18, 48, 48, 48, 21, 48, 
+	2, 48, 49, 49, 48, 5, 48, 6, 
+	48, 48, 48, 48, 48, 48, 48, 58, 
+	48, 48, 10, 11, 12, 48, 14, 15, 
+	16, 17, 18, 48, 48, 48, 21, 48, 
+	2, 48, 49, 49, 48, 5, 48, 6, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 10, 11, 12, 48, 14, 15, 
+	16, 17, 18, 48, 48, 48, 21, 48, 
+	2, 3, 49, 49, 48, 5, 48, 6, 
+	48, 48, 48, 48, 48, 48, 48, 8, 
+	48, 48, 10, 11, 12, 13, 14, 15, 
+	16, 17, 18, 48, 48, 48, 21, 48, 
+	23, 24, 25, 25, 22, 26, 22, 27, 
+	22, 22, 22, 22, 22, 22, 22, 59, 
+	22, 22, 29, 30, 31, 32, 33, 34, 
+	35, 36, 37, 38, 22, 22, 39, 22, 
+	23, 60, 25, 25, 22, 26, 22, 27, 
+	22, 22, 22, 22, 22, 22, 22, 28, 
+	22, 22, 29, 30, 31, 32, 33, 34, 
+	35, 36, 37, 22, 22, 22, 39, 22, 
+	1, 1, 2, 3, 49, 49, 48, 5, 
+	48, 6, 1, 48, 48, 48, 48, 1, 
+	48, 8, 48, 48, 10, 11, 12, 13, 
+	14, 15, 16, 17, 18, 19, 48, 1, 
+	21, 48, 1, 1, 61, 61, 61, 61, 
+	61, 61, 61, 61, 1, 61, 61, 61, 
+	61, 1, 61, 61, 61, 61, 61, 61, 
+	61, 61, 61, 61, 61, 61, 61, 61, 
+	61, 1, 61, 62, 61, 0
 };
 
 static const char _myanmar_syllable_machine_trans_targs[] = {
-	0, 1, 24, 34, 0, 25, 31, 47, 
-	36, 50, 37, 42, 43, 44, 27, 39, 
-	40, 41, 30, 46, 51, 0, 2, 12, 
-	0, 3, 9, 13, 14, 19, 20, 21, 
-	5, 16, 17, 18, 8, 23, 4, 6, 
-	7, 10, 11, 15, 22, 0, 0, 26, 
-	28, 29, 32, 33, 35, 38, 45, 48, 
-	49, 0, 0
+	0, 1, 26, 37, 0, 27, 33, 51, 
+	39, 54, 40, 46, 47, 48, 29, 42, 
+	43, 44, 32, 50, 55, 45, 0, 2, 
+	13, 0, 3, 9, 14, 15, 21, 22, 
+	23, 5, 17, 18, 19, 8, 25, 20, 
+	4, 6, 7, 10, 12, 11, 16, 24, 
+	0, 0, 28, 30, 31, 34, 36, 35, 
+	38, 41, 49, 52, 53, 0, 0
 };
 
 static const char _myanmar_syllable_machine_trans_actions[] = {
 	3, 0, 0, 0, 4, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 5, 0, 0, 
-	6, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 5, 0, 
+	0, 6, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 7, 8, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 9, 10
+	7, 8, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 9, 10
 };
 
 static const char _myanmar_syllable_machine_to_state_actions[] = {
@@ -298,7 +325,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 _myanmar_syllable_machine_from_state_actions[] = {
@@ -308,17 +335,17 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0
 };
 
 static const short _myanmar_syllable_machine_eof_trans[] = {
-	0, 22, 22, 22, 22, 22, 22, 22, 
-	22, 22, 22, 22, 22, 22, 22, 22, 
-	22, 22, 22, 22, 22, 22, 22, 22, 
-	46, 46, 46, 46, 46, 46, 46, 46, 
-	46, 46, 46, 46, 46, 46, 46, 46, 
-	46, 46, 46, 46, 46, 46, 46, 22, 
-	22, 46, 58, 58
+	0, 23, 23, 23, 23, 23, 23, 23, 
+	23, 23, 23, 23, 23, 23, 23, 23, 
+	23, 23, 23, 23, 23, 23, 23, 23, 
+	23, 23, 49, 49, 49, 49, 49, 49, 
+	49, 49, 49, 49, 49, 49, 49, 49, 
+	49, 49, 49, 49, 49, 49, 49, 49, 
+	49, 49, 49, 23, 23, 49, 62, 62
 };
 
 static const int myanmar_syllable_machine_start = 0;
@@ -332,7 +359,7 @@
 
 
 
-#line 101 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 102 "hb-ot-shape-complex-myanmar-machine.rl"
 
 
 #define found_syllable(syllable_type) \
@@ -351,7 +378,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 355 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 382 "hb-ot-shape-complex-myanmar-machine.hh"
 	{
 	cs = myanmar_syllable_machine_start;
 	ts = 0;
@@ -359,7 +386,7 @@
 	act = 0;
 	}
 
-#line 121 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 122 "hb-ot-shape-complex-myanmar-machine.rl"
 
 
   p = 0;
@@ -367,7 +394,7 @@
 
   unsigned int syllable_serial = 1;
   
-#line 371 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 398 "hb-ot-shape-complex-myanmar-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -381,7 +408,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 385 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 412 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 	_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -400,38 +427,38 @@
 
 	switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
 	case 6:
-#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (myanmar_consonant_syllable); }}
 	break;
 	case 4:
-#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 95 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
 	break;
 	case 10:
-#line 95 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 96 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (myanmar_punctuation_cluster); }}
 	break;
 	case 8:
-#line 96 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 97 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (myanmar_broken_cluster); }}
 	break;
 	case 3:
-#line 97 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 98 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
 	break;
 	case 5:
-#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (myanmar_consonant_syllable); }}
 	break;
 	case 7:
-#line 96 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 97 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (myanmar_broken_cluster); }}
 	break;
 	case 9:
-#line 97 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 98 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
 	break;
-#line 435 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 462 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 _again:
@@ -440,7 +467,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 444 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 471 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -456,7 +483,7 @@
 
 	}
 
-#line 129 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 130 "hb-ot-shape-complex-myanmar-machine.rl"
 
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl	2021-11-04 00:51:18 UTC (rev 60943)
@@ -55,6 +55,7 @@
 export H    = 4;
 export IV   = 2;
 export MH   = 21;
+export ML   = 33;
 export MR   = 22;
 export MW   = 23;
 export MY   = 24;
@@ -76,9 +77,9 @@
 
 c = C|Ra;			# is_consonant
 
-medial_group = MY? As? MR? ((MW MH? | MH) As?)?;
+medial_group = MY? As? MR? ((MW MH? ML? | MH ML? | ML) As?)?;
 main_vowel_group = (VPre.VS?)* VAbv* VBlw* A* (DB As?)?;
-post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
+post_vowel_group = VPst MH? ML? As* VAbv* A* (DB As?)?;
 pwo_tone_group = PT A* DB? As?;
 
 complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -185,7 +185,7 @@
       info[i].myanmar_position() = POS_BASE_C;
       i++;
     }
-    indic_position_t pos = POS_AFTER_MAIN;
+    myanmar_position_t pos = POS_AFTER_MAIN;
     /* The following loop may be ugly, but it implements all of
      * Myanmar reordering! */
     for (; i < end; i++)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -56,8 +56,10 @@
   OT_VS   = 30, /* Variation selectors */
   OT_P    = 31, /* Punctuation */
   OT_D    = 32, /* Digits except zero */
+  OT_ML   = 33, /* Various consonant medial types */
 };
 
+using myanmar_position_t = indic_position_t;
 
 static inline void
 set_myanmar_properties (hb_glyph_info_t &info)
@@ -65,7 +67,7 @@
   hb_codepoint_t u = info.codepoint;
   unsigned int type = hb_indic_get_categories (u);
   unsigned int cat = type & 0xFFu;
-  indic_position_t pos = (indic_position_t) (type >> 8);
+  myanmar_position_t pos = (myanmar_position_t) (type >> 8);
 
   /* Myanmar
    * https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze
@@ -114,10 +116,14 @@
       cat = OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
       break;
 
-    case 0x103Eu: case 0x1060u:
+    case 0x103Eu:
       cat = OT_MH;
       break;
 
+    case 0x1060u:
+      cat = OT_ML;
+      break;
+
     case 0x103Cu:
       cat = OT_MR;
       break;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -41,7 +41,6 @@
 #define USE(Cat) use_syllable_machine_ex_##Cat
 
 enum use_syllable_type_t {
-  use_independent_cluster,
   use_virama_terminated_cluster,
   use_sakot_terminated_cluster,
   use_standard_cluster,
@@ -54,8 +53,9 @@
 };
 
 
-#line 58 "hb-ot-shape-complex-use-machine.hh"
+#line 57 "hb-ot-shape-complex-use-machine.hh"
 #define use_syllable_machine_ex_B 1u
+#define use_syllable_machine_ex_CGJ 6u
 #define use_syllable_machine_ex_CMAbv 31u
 #define use_syllable_machine_ex_CMBlw 32u
 #define use_syllable_machine_ex_CS 43u
@@ -78,7 +78,6 @@
 #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_S 19u
 #define use_syllable_machine_ex_SB 51u
 #define use_syllable_machine_ex_SE 52u
 #define use_syllable_machine_ex_SMAbv 41u
@@ -96,237 +95,235 @@
 #define use_syllable_machine_ex_ZWNJ 14u
 
 
-#line 100 "hb-ot-shape-complex-use-machine.hh"
+#line 99 "hb-ot-shape-complex-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-	1u, 1u, 1u, 1u, 0u, 51u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u, 
+	0u, 51u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u, 
 	24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 
 	1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 
-	11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, 
-	22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 
-	24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 
-	22u, 48u, 11u, 48u, 1u, 48u, 1u, 1u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u, 
-	41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0
+	11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 
+	23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 
+	24u, 48u, 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 
+	22u, 48u, 11u, 48u, 1u, 48u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u, 41u, 42u, 
+	42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-	1, 1, 52, 38, 38, 1, 27, 26, 
+	52, 2, 1, 38, 38, 1, 27, 26, 
 	24, 23, 22, 2, 1, 25, 25, 25, 
 	1, 25, 26, 26, 26, 27, 27, 27, 
-	38, 48, 1, 1, 38, 2, 1, 38, 
-	27, 26, 24, 23, 22, 2, 1, 25, 
-	25, 25, 25, 26, 26, 26, 27, 27, 
-	27, 38, 48, 1, 1, 1, 48, 38, 
-	2, 1, 5, 3, 4, 3
+	38, 48, 1, 1, 38, 38, 1, 27, 
+	26, 24, 23, 22, 2, 1, 25, 25, 
+	25, 1, 25, 26, 26, 26, 27, 27, 
+	27, 38, 48, 1, 1, 48, 38, 2, 
+	1, 5, 3, 4, 3
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-	0, 2, 4, 57, 96, 135, 137, 165, 
-	192, 217, 241, 264, 267, 269, 295, 321, 
-	347, 349, 375, 402, 429, 456, 484, 512, 
-	540, 579, 628, 630, 632, 671, 674, 676, 
-	715, 743, 770, 795, 819, 842, 845, 847, 
-	873, 899, 925, 951, 978, 1005, 1032, 1060, 
-	1088, 1116, 1155, 1204, 1206, 1208, 1210, 1259, 
-	1298, 1301, 1303, 1309, 1313, 1318
+	0, 53, 56, 58, 97, 136, 138, 166, 
+	193, 218, 242, 265, 268, 270, 296, 322, 
+	348, 350, 376, 403, 430, 457, 485, 513, 
+	541, 580, 629, 631, 633, 672, 711, 713, 
+	741, 768, 793, 817, 840, 843, 845, 871, 
+	897, 923, 925, 951, 978, 1005, 1032, 1060, 
+	1088, 1116, 1155, 1204, 1206, 1208, 1257, 1296, 
+	1299, 1301, 1307, 1311, 1316
 };
 
 static const char _use_syllable_machine_indicies[] = {
-	1, 0, 2, 0, 3, 4, 5, 5, 
-	6, 7, 5, 5, 5, 5, 5, 1, 
-	8, 9, 5, 5, 5, 5, 10, 11, 
-	5, 5, 12, 13, 14, 15, 16, 17, 
-	18, 12, 19, 20, 21, 22, 23, 24, 
-	5, 25, 26, 27, 5, 28, 29, 30, 
-	31, 32, 33, 34, 8, 35, 5, 36, 
-	5, 38, 39, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 40, 41, 42, 43, 
-	44, 45, 46, 40, 47, 4, 48, 49, 
-	50, 51, 37, 52, 53, 54, 37, 37, 
-	37, 37, 55, 56, 57, 58, 39, 37, 
-	38, 39, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 40, 41, 42, 43, 44, 
-	45, 46, 40, 47, 48, 48, 49, 50, 
-	51, 37, 52, 53, 54, 37, 37, 37, 
-	37, 55, 56, 57, 58, 39, 37, 38, 
-	59, 40, 41, 42, 43, 44, 37, 37, 
-	37, 37, 37, 37, 49, 50, 51, 37, 
-	52, 53, 54, 37, 37, 37, 37, 41, 
-	56, 57, 58, 60, 37, 41, 42, 43, 
-	44, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 52, 53, 54, 37, 37, 
-	37, 37, 37, 56, 57, 58, 60, 37, 
-	42, 43, 44, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 56, 57, 58, 
-	37, 43, 44, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 56, 57, 58, 
-	37, 44, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 56, 57, 58, 37, 
-	56, 57, 37, 57, 37, 42, 43, 44, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 52, 53, 54, 37, 37, 37, 
-	37, 37, 56, 57, 58, 60, 37, 42, 
-	43, 44, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 53, 54, 37, 
-	37, 37, 37, 37, 56, 57, 58, 60, 
-	37, 42, 43, 44, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	54, 37, 37, 37, 37, 37, 56, 57, 
-	58, 60, 37, 62, 61, 42, 43, 44, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 56, 57, 58, 60, 37, 41, 
-	42, 43, 44, 37, 37, 37, 37, 37, 
-	37, 49, 50, 51, 37, 52, 53, 54, 
-	37, 37, 37, 37, 41, 56, 57, 58, 
-	60, 37, 41, 42, 43, 44, 37, 37, 
-	37, 37, 37, 37, 37, 50, 51, 37, 
-	52, 53, 54, 37, 37, 37, 37, 41, 
-	56, 57, 58, 60, 37, 41, 42, 43, 
-	44, 37, 37, 37, 37, 37, 37, 37, 
-	37, 51, 37, 52, 53, 54, 37, 37, 
-	37, 37, 41, 56, 57, 58, 60, 37, 
-	40, 41, 42, 43, 44, 37, 46, 40, 
-	37, 37, 37, 49, 50, 51, 37, 52, 
-	53, 54, 37, 37, 37, 37, 41, 56, 
-	57, 58, 60, 37, 40, 41, 42, 43, 
-	44, 37, 37, 40, 37, 37, 37, 49, 
-	50, 51, 37, 52, 53, 54, 37, 37, 
-	37, 37, 41, 56, 57, 58, 60, 37, 
-	40, 41, 42, 43, 44, 45, 46, 40, 
-	37, 37, 37, 49, 50, 51, 37, 52, 
-	53, 54, 37, 37, 37, 37, 41, 56, 
-	57, 58, 60, 37, 38, 39, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 40, 
-	41, 42, 43, 44, 45, 46, 40, 47, 
-	37, 48, 49, 50, 51, 37, 52, 53, 
-	54, 37, 37, 37, 37, 55, 56, 57, 
-	58, 39, 37, 38, 59, 59, 59, 59, 
-	59, 59, 59, 59, 59, 59, 59, 59, 
-	59, 59, 59, 59, 59, 59, 59, 59, 
-	59, 41, 42, 43, 44, 59, 59, 59, 
-	59, 59, 59, 59, 59, 59, 59, 52, 
-	53, 54, 59, 59, 59, 59, 59, 56, 
-	57, 58, 60, 59, 64, 63, 6, 65, 
-	38, 39, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 40, 41, 42, 43, 44, 
-	45, 46, 40, 47, 4, 48, 49, 50, 
-	51, 37, 52, 53, 54, 37, 11, 66, 
-	37, 55, 56, 57, 58, 39, 37, 11, 
-	66, 67, 66, 67, 1, 69, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 12, 
-	13, 14, 15, 16, 17, 18, 12, 19, 
-	21, 21, 22, 23, 24, 68, 25, 26, 
-	27, 68, 68, 68, 68, 31, 32, 33, 
-	34, 69, 68, 12, 13, 14, 15, 16, 
-	68, 68, 68, 68, 68, 68, 22, 23, 
-	24, 68, 25, 26, 27, 68, 68, 68, 
-	68, 13, 32, 33, 34, 70, 68, 13, 
-	14, 15, 16, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 25, 26, 27, 
-	68, 68, 68, 68, 68, 32, 33, 34, 
-	70, 68, 14, 15, 16, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 32, 
-	33, 34, 68, 15, 16, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 32, 
-	33, 34, 68, 16, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 32, 33, 
-	34, 68, 32, 33, 68, 33, 68, 14, 
-	15, 16, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 25, 26, 27, 68, 
-	68, 68, 68, 68, 32, 33, 34, 70, 
-	68, 14, 15, 16, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 26, 
-	27, 68, 68, 68, 68, 68, 32, 33, 
-	34, 70, 68, 14, 15, 16, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 27, 68, 68, 68, 68, 68, 
-	32, 33, 34, 70, 68, 14, 15, 16, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 32, 33, 34, 70, 68, 13, 
-	14, 15, 16, 68, 68, 68, 68, 68, 
-	68, 22, 23, 24, 68, 25, 26, 27, 
-	68, 68, 68, 68, 13, 32, 33, 34, 
-	70, 68, 13, 14, 15, 16, 68, 68, 
-	68, 68, 68, 68, 68, 23, 24, 68, 
-	25, 26, 27, 68, 68, 68, 68, 13, 
-	32, 33, 34, 70, 68, 13, 14, 15, 
-	16, 68, 68, 68, 68, 68, 68, 68, 
-	68, 24, 68, 25, 26, 27, 68, 68, 
-	68, 68, 13, 32, 33, 34, 70, 68, 
-	12, 13, 14, 15, 16, 68, 18, 12, 
-	68, 68, 68, 22, 23, 24, 68, 25, 
-	26, 27, 68, 68, 68, 68, 13, 32, 
-	33, 34, 70, 68, 12, 13, 14, 15, 
-	16, 68, 68, 12, 68, 68, 68, 22, 
-	23, 24, 68, 25, 26, 27, 68, 68, 
-	68, 68, 13, 32, 33, 34, 70, 68, 
-	12, 13, 14, 15, 16, 17, 18, 12, 
-	68, 68, 68, 22, 23, 24, 68, 25, 
-	26, 27, 68, 68, 68, 68, 13, 32, 
-	33, 34, 70, 68, 1, 69, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 12, 
-	13, 14, 15, 16, 17, 18, 12, 19, 
-	68, 21, 22, 23, 24, 68, 25, 26, 
-	27, 68, 68, 68, 68, 31, 32, 33, 
-	34, 69, 68, 1, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 13, 14, 15, 16, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 25, 
-	26, 27, 68, 68, 68, 68, 68, 32, 
-	33, 34, 70, 68, 1, 71, 72, 68, 
-	9, 68, 4, 68, 68, 68, 4, 68, 
-	68, 68, 68, 68, 1, 69, 9, 68, 
-	68, 68, 68, 68, 68, 68, 68, 12, 
-	13, 14, 15, 16, 17, 18, 12, 19, 
-	20, 21, 22, 23, 24, 68, 25, 26, 
-	27, 68, 28, 29, 68, 31, 32, 33, 
-	34, 69, 68, 1, 69, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 12, 13, 
-	14, 15, 16, 17, 18, 12, 19, 20, 
-	21, 22, 23, 24, 68, 25, 26, 27, 
-	68, 68, 68, 68, 31, 32, 33, 34, 
-	69, 68, 28, 29, 68, 29, 68, 4, 
-	71, 71, 71, 4, 71, 74, 73, 35, 
-	73, 35, 74, 73, 74, 73, 35, 73, 
-	36, 73, 0
+	0, 1, 2, 2, 3, 4, 2, 2, 
+	2, 2, 2, 5, 6, 7, 2, 2, 
+	2, 2, 8, 2, 2, 2, 9, 10, 
+	11, 12, 13, 14, 15, 9, 16, 17, 
+	18, 19, 20, 21, 2, 22, 23, 24, 
+	2, 25, 26, 27, 28, 29, 30, 31, 
+	6, 32, 2, 33, 2, 0, 35, 34, 
+	35, 34, 37, 38, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 39, 40, 41, 
+	42, 43, 44, 45, 39, 46, 1, 47, 
+	48, 49, 50, 36, 51, 52, 53, 36, 
+	36, 36, 36, 54, 55, 56, 57, 38, 
+	36, 37, 38, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 39, 40, 41, 42, 
+	43, 44, 45, 39, 46, 47, 47, 48, 
+	49, 50, 36, 51, 52, 53, 36, 36, 
+	36, 36, 54, 55, 56, 57, 38, 36, 
+	37, 58, 39, 40, 41, 42, 43, 36, 
+	36, 36, 36, 36, 36, 48, 49, 50, 
+	36, 51, 52, 53, 36, 36, 36, 36, 
+	40, 55, 56, 57, 59, 36, 40, 41, 
+	42, 43, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 51, 52, 53, 36, 
+	36, 36, 36, 36, 55, 56, 57, 59, 
+	36, 41, 42, 43, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 55, 56, 
+	57, 36, 42, 43, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 55, 56, 
+	57, 36, 43, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 55, 56, 57, 
+	36, 55, 56, 36, 56, 36, 41, 42, 
+	43, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 51, 52, 53, 36, 36, 
+	36, 36, 36, 55, 56, 57, 59, 36, 
+	41, 42, 43, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 52, 53, 
+	36, 36, 36, 36, 36, 55, 56, 57, 
+	59, 36, 41, 42, 43, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 36, 36, 
+	36, 53, 36, 36, 36, 36, 36, 55, 
+	56, 57, 59, 36, 61, 60, 41, 42, 
+	43, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 55, 56, 57, 59, 36, 
+	40, 41, 42, 43, 36, 36, 36, 36, 
+	36, 36, 48, 49, 50, 36, 51, 52, 
+	53, 36, 36, 36, 36, 40, 55, 56, 
+	57, 59, 36, 40, 41, 42, 43, 36, 
+	36, 36, 36, 36, 36, 36, 49, 50, 
+	36, 51, 52, 53, 36, 36, 36, 36, 
+	40, 55, 56, 57, 59, 36, 40, 41, 
+	42, 43, 36, 36, 36, 36, 36, 36, 
+	36, 36, 50, 36, 51, 52, 53, 36, 
+	36, 36, 36, 40, 55, 56, 57, 59, 
+	36, 39, 40, 41, 42, 43, 36, 45, 
+	39, 36, 36, 36, 48, 49, 50, 36, 
+	51, 52, 53, 36, 36, 36, 36, 40, 
+	55, 56, 57, 59, 36, 39, 40, 41, 
+	42, 43, 36, 36, 39, 36, 36, 36, 
+	48, 49, 50, 36, 51, 52, 53, 36, 
+	36, 36, 36, 40, 55, 56, 57, 59, 
+	36, 39, 40, 41, 42, 43, 44, 45, 
+	39, 36, 36, 36, 48, 49, 50, 36, 
+	51, 52, 53, 36, 36, 36, 36, 40, 
+	55, 56, 57, 59, 36, 37, 38, 36, 
+	36, 36, 36, 36, 36, 36, 36, 36, 
+	39, 40, 41, 42, 43, 44, 45, 39, 
+	46, 36, 47, 48, 49, 50, 36, 51, 
+	52, 53, 36, 36, 36, 36, 54, 55, 
+	56, 57, 38, 36, 37, 58, 58, 58, 
+	58, 58, 58, 58, 58, 58, 58, 58, 
+	58, 58, 58, 58, 58, 58, 58, 58, 
+	58, 58, 40, 41, 42, 43, 58, 58, 
+	58, 58, 58, 58, 58, 58, 58, 58, 
+	51, 52, 53, 58, 58, 58, 58, 58, 
+	55, 56, 57, 59, 58, 63, 62, 3, 
+	64, 37, 38, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 39, 40, 41, 42, 
+	43, 44, 45, 39, 46, 1, 47, 48, 
+	49, 50, 36, 51, 52, 53, 36, 0, 
+	35, 36, 54, 55, 56, 57, 38, 36, 
+	5, 6, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 9, 10, 11, 12, 13, 
+	14, 15, 9, 16, 18, 18, 19, 20, 
+	21, 65, 22, 23, 24, 65, 65, 65, 
+	65, 28, 29, 30, 31, 6, 65, 5, 
+	65, 9, 10, 11, 12, 13, 65, 65, 
+	65, 65, 65, 65, 19, 20, 21, 65, 
+	22, 23, 24, 65, 65, 65, 65, 10, 
+	29, 30, 31, 66, 65, 10, 11, 12, 
+	13, 65, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 22, 23, 24, 65, 65, 
+	65, 65, 65, 29, 30, 31, 66, 65, 
+	11, 12, 13, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 29, 30, 31, 
+	65, 12, 13, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 29, 30, 31, 
+	65, 13, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 29, 30, 31, 65, 
+	29, 30, 65, 30, 65, 11, 12, 13, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	65, 65, 22, 23, 24, 65, 65, 65, 
+	65, 65, 29, 30, 31, 66, 65, 11, 
+	12, 13, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 23, 24, 65, 
+	65, 65, 65, 65, 29, 30, 31, 66, 
+	65, 11, 12, 13, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	24, 65, 65, 65, 65, 65, 29, 30, 
+	31, 66, 65, 67, 65, 11, 12, 13, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	65, 65, 29, 30, 31, 66, 65, 10, 
+	11, 12, 13, 65, 65, 65, 65, 65, 
+	65, 19, 20, 21, 65, 22, 23, 24, 
+	65, 65, 65, 65, 10, 29, 30, 31, 
+	66, 65, 10, 11, 12, 13, 65, 65, 
+	65, 65, 65, 65, 65, 20, 21, 65, 
+	22, 23, 24, 65, 65, 65, 65, 10, 
+	29, 30, 31, 66, 65, 10, 11, 12, 
+	13, 65, 65, 65, 65, 65, 65, 65, 
+	65, 21, 65, 22, 23, 24, 65, 65, 
+	65, 65, 10, 29, 30, 31, 66, 65, 
+	9, 10, 11, 12, 13, 65, 15, 9, 
+	65, 65, 65, 19, 20, 21, 65, 22, 
+	23, 24, 65, 65, 65, 65, 10, 29, 
+	30, 31, 66, 65, 9, 10, 11, 12, 
+	13, 65, 65, 9, 65, 65, 65, 19, 
+	20, 21, 65, 22, 23, 24, 65, 65, 
+	65, 65, 10, 29, 30, 31, 66, 65, 
+	9, 10, 11, 12, 13, 14, 15, 9, 
+	65, 65, 65, 19, 20, 21, 65, 22, 
+	23, 24, 65, 65, 65, 65, 10, 29, 
+	30, 31, 66, 65, 5, 6, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 9, 
+	10, 11, 12, 13, 14, 15, 9, 16, 
+	65, 18, 19, 20, 21, 65, 22, 23, 
+	24, 65, 65, 65, 65, 28, 29, 30, 
+	31, 6, 65, 5, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	65, 10, 11, 12, 13, 65, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 22, 
+	23, 24, 65, 65, 65, 65, 65, 29, 
+	30, 31, 66, 65, 68, 65, 7, 65, 
+	1, 65, 65, 65, 1, 65, 65, 65, 
+	65, 65, 5, 6, 7, 65, 65, 65, 
+	65, 65, 65, 65, 65, 9, 10, 11, 
+	12, 13, 14, 15, 9, 16, 17, 18, 
+	19, 20, 21, 65, 22, 23, 24, 65, 
+	25, 26, 65, 28, 29, 30, 31, 6, 
+	65, 5, 6, 65, 65, 65, 65, 65, 
+	65, 65, 65, 65, 9, 10, 11, 12, 
+	13, 14, 15, 9, 16, 17, 18, 19, 
+	20, 21, 65, 22, 23, 24, 65, 65, 
+	65, 65, 28, 29, 30, 31, 6, 65, 
+	25, 26, 65, 26, 65, 1, 69, 69, 
+	69, 1, 69, 71, 70, 32, 70, 32, 
+	71, 70, 71, 70, 32, 70, 33, 70, 
+	0
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
-	2, 31, 42, 2, 3, 2, 26, 28, 
-	51, 52, 54, 29, 32, 33, 34, 35, 
-	36, 46, 47, 48, 55, 49, 43, 44, 
-	45, 39, 40, 41, 56, 57, 58, 50, 
-	37, 38, 2, 59, 61, 2, 4, 5, 
-	6, 7, 8, 9, 10, 21, 22, 23, 
-	24, 18, 19, 20, 13, 14, 15, 25, 
-	11, 12, 2, 2, 16, 2, 17, 2, 
-	27, 2, 30, 2, 2, 0, 1, 2, 
-	53, 2, 60
+	1, 3, 0, 26, 28, 29, 30, 51, 
+	53, 31, 32, 33, 34, 35, 46, 47, 
+	48, 54, 49, 43, 44, 45, 38, 39, 
+	40, 55, 56, 57, 50, 36, 37, 0, 
+	58, 60, 0, 2, 0, 4, 5, 6, 
+	7, 8, 9, 10, 21, 22, 23, 24, 
+	18, 19, 20, 13, 14, 15, 25, 11, 
+	12, 0, 0, 16, 0, 17, 0, 27, 
+	0, 0, 41, 42, 52, 0, 0, 59
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
-	1, 2, 2, 5, 0, 6, 0, 0, 
-	0, 0, 2, 0, 2, 2, 0, 0, 
-	0, 2, 2, 2, 2, 2, 2, 2, 
-	2, 2, 2, 2, 0, 0, 0, 2, 
-	0, 0, 7, 0, 0, 8, 0, 0, 
+	0, 0, 3, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 9, 10, 0, 11, 0, 12, 
-	0, 13, 0, 14, 15, 0, 0, 16, 
-	0, 17, 0
+	0, 0, 0, 0, 0, 0, 0, 4, 
+	0, 0, 5, 0, 6, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 7, 8, 0, 9, 0, 10, 0, 
+	11, 12, 0, 0, 0, 13, 14, 0
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
-	0, 0, 3, 0, 0, 0, 0, 0, 
+	1, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
@@ -333,11 +330,11 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 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[] = {
-	0, 0, 4, 0, 0, 0, 0, 0, 
+	2, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
@@ -344,32 +341,32 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0
+	0, 0, 0, 0, 0
 };
 
 static const short _use_syllable_machine_eof_trans[] = {
-	1, 1, 0, 38, 38, 60, 38, 38, 
-	38, 38, 38, 38, 38, 38, 38, 38, 
-	62, 38, 38, 38, 38, 38, 38, 38, 
-	38, 60, 64, 66, 38, 68, 68, 69, 
-	69, 69, 69, 69, 69, 69, 69, 69, 
-	69, 69, 69, 69, 69, 69, 69, 69, 
-	69, 69, 69, 72, 69, 69, 69, 69, 
-	69, 69, 72, 74, 74, 74
+	0, 35, 35, 37, 37, 59, 37, 37, 
+	37, 37, 37, 37, 37, 37, 37, 37, 
+	61, 37, 37, 37, 37, 37, 37, 37, 
+	37, 59, 63, 65, 37, 66, 66, 66, 
+	66, 66, 66, 66, 66, 66, 66, 66, 
+	66, 66, 66, 66, 66, 66, 66, 66, 
+	66, 66, 66, 66, 66, 66, 66, 66, 
+	66, 70, 71, 71, 71
 };
 
-static const int use_syllable_machine_start = 2;
-static const int use_syllable_machine_first_final = 2;
+static const int use_syllable_machine_start = 0;
+static const int use_syllable_machine_first_final = 0;
 static const int use_syllable_machine_error = -1;
 
-static const int use_syllable_machine_en_main = 2;
+static const int use_syllable_machine_en_main = 0;
 
 
-#line 59 "hb-ot-shape-complex-use-machine.rl"
+#line 58 "hb-ot-shape-complex-use-machine.rl"
 
 
 
-#line 176 "hb-ot-shape-complex-use-machine.rl"
+#line 179 "hb-ot-shape-complex-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
@@ -422,8 +419,8 @@
 
 
 static bool
-not_standard_default_ignorable (const hb_glyph_info_t &i)
-{ return !(i.use_category() == USE(O) && _hb_glyph_info_is_default_ignorable (&i)); }
+not_ccs_default_ignorable (const hb_glyph_info_t &i)
+{ return !(i.use_category() == USE(CGJ) && _hb_glyph_info_is_default_ignorable (&i)); }
 
 static inline void
 find_syllables_use (hb_buffer_t *buffer)
@@ -432,13 +429,13 @@
   auto p =
     + hb_iter (info, buffer->len)
     | hb_enumerate
-    | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); },
+    | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); },
 		 hb_second)
     | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
 		 {
 		   if (p.second.use_category() == USE(ZWNJ))
 		     for (unsigned i = p.first + 1; i < buffer->len; ++i)
-		       if (not_standard_default_ignorable (info[i]))
+		       if (not_ccs_default_ignorable (info[i]))
 			 return !_hb_glyph_info_is_unicode_mark (&info[i]);
 		   return true;
 		 })
@@ -452,7 +449,7 @@
   unsigned int act HB_UNUSED;
   int cs;
   
-#line 456 "hb-ot-shape-complex-use-machine.hh"
+#line 453 "hb-ot-shape-complex-use-machine.hh"
 	{
 	cs = use_syllable_machine_start;
 	ts = 0;
@@ -460,12 +457,12 @@
 	act = 0;
 	}
 
-#line 260 "hb-ot-shape-complex-use-machine.rl"
+#line 263 "hb-ot-shape-complex-use-machine.rl"
 
 
   unsigned int syllable_serial = 1;
   
-#line 469 "hb-ot-shape-complex-use-machine.hh"
+#line 466 "hb-ot-shape-complex-use-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -475,11 +472,11 @@
 		goto _test_eof;
 _resume:
 	switch ( _use_syllable_machine_from_state_actions[cs] ) {
-	case 4:
+	case 2:
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 483 "hb-ot-shape-complex-use-machine.hh"
+#line 480 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -497,76 +494,64 @@
 		goto _again;
 
 	switch ( _use_syllable_machine_trans_actions[_trans] ) {
-	case 2:
-#line 1 "NONE"
-	{te = p+1;}
-	break;
-	case 5:
-#line 163 "hb-ot-shape-complex-use-machine.rl"
-	{te = p+1;{ found_syllable (use_independent_cluster); }}
-	break;
-	case 9:
-#line 166 "hb-ot-shape-complex-use-machine.rl"
+	case 7:
+#line 169 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (use_standard_cluster); }}
 	break;
-	case 7:
-#line 171 "hb-ot-shape-complex-use-machine.rl"
+	case 4:
+#line 174 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (use_broken_cluster); }}
 	break;
-	case 6:
-#line 172 "hb-ot-shape-complex-use-machine.rl"
+	case 3:
+#line 175 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (use_non_cluster); }}
 	break;
-	case 10:
-#line 164 "hb-ot-shape-complex-use-machine.rl"
+	case 8:
+#line 167 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
 	break;
-	case 11:
-#line 165 "hb-ot-shape-complex-use-machine.rl"
+	case 9:
+#line 168 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
 	break;
-	case 8:
-#line 166 "hb-ot-shape-complex-use-machine.rl"
+	case 6:
+#line 169 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_standard_cluster); }}
 	break;
-	case 13:
-#line 167 "hb-ot-shape-complex-use-machine.rl"
+	case 11:
+#line 170 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
 	break;
-	case 12:
-#line 168 "hb-ot-shape-complex-use-machine.rl"
+	case 10:
+#line 171 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_numeral_cluster); }}
 	break;
-	case 14:
-#line 169 "hb-ot-shape-complex-use-machine.rl"
+	case 5:
+#line 172 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_symbol_cluster); }}
 	break;
-	case 17:
-#line 170 "hb-ot-shape-complex-use-machine.rl"
+	case 14:
+#line 173 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
 	break;
-	case 15:
-#line 171 "hb-ot-shape-complex-use-machine.rl"
+	case 12:
+#line 174 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_broken_cluster); }}
 	break;
-	case 16:
-#line 172 "hb-ot-shape-complex-use-machine.rl"
+	case 13:
+#line 175 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_non_cluster); }}
 	break;
-	case 1:
-#line 171 "hb-ot-shape-complex-use-machine.rl"
-	{{p = ((te))-1;}{ found_syllable (use_broken_cluster); }}
-	break;
-#line 561 "hb-ot-shape-complex-use-machine.hh"
+#line 546 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 _again:
 	switch ( _use_syllable_machine_to_state_actions[cs] ) {
-	case 3:
+	case 1:
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 570 "hb-ot-shape-complex-use-machine.hh"
+#line 555 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -582,7 +567,7 @@
 
 	}
 
-#line 265 "hb-ot-shape-complex-use-machine.rl"
+#line 268 "hb-ot-shape-complex-use-machine.rl"
 
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl	2021-11-04 00:51:18 UTC (rev 60943)
@@ -39,7 +39,6 @@
 #define USE(Cat) use_syllable_machine_ex_##Cat
 
 enum use_syllable_type_t {
-  use_independent_cluster,
   use_virama_terminated_cluster,
   use_sakot_terminated_cluster,
   use_standard_cluster,
@@ -68,6 +67,7 @@
 export B	= 1; # BASE
 export N	= 4; # BASE_NUM
 export GB	= 5; # BASE_OTHER
+export CGJ	= 6; # CGJ
 export SUB	= 11; # CONS_SUB
 export H	= 12; # HALANT
 
@@ -74,7 +74,6 @@
 export HN	= 13; # HALANT_NUM
 export ZWNJ	= 14; # Zero width non-joiner
 export R	= 18; # REPHA
-export S	= 19; # SYM
 export CS	= 43; # CONS_WITH_STACKER
 export HVM	= 44; # HALANT_OR_VOWEL_MODIFIER
 export Sk	= 48; # SAKOT
@@ -133,16 +132,22 @@
 numeral_cluster_tail = (HN N)+;
 symbol_cluster_tail = SMAbv+ SMBlw* | SMBlw+;
 
-virama_terminated_cluster =
-	complex_syllable_start
+virama_terminated_cluster_tail =
 	consonant_modifiers
 	h
 ;
-sakot_terminated_cluster =
+virama_terminated_cluster =
 	complex_syllable_start
+	virama_terminated_cluster_tail
+;
+sakot_terminated_cluster_tail =
 	complex_syllable_middle
 	Sk
 ;
+sakot_terminated_cluster =
+	complex_syllable_start
+	sakot_terminated_cluster_tail
+;
 standard_cluster =
 	complex_syllable_start
 	complex_syllable_tail
@@ -149,18 +154,16 @@
 ;
 broken_cluster =
 	R?
-	(complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail)
+	(complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail | virama_terminated_cluster_tail | sakot_terminated_cluster_tail)
 ;
 
 number_joiner_terminated_cluster = N number_joiner_terminated_cluster_tail;
 numeral_cluster = N numeral_cluster_tail?;
-symbol_cluster = (S | GB) symbol_cluster_tail?;
+symbol_cluster = (O | GB) symbol_cluster_tail?;
 hieroglyph_cluster = SB+ | SB* G SE* (J SE* (G SE*)?)*;
-independent_cluster = O;
 other = any;
 
 main := |*
-	independent_cluster			=> { found_syllable (use_independent_cluster); };
 	virama_terminated_cluster		=> { found_syllable (use_virama_terminated_cluster); };
 	sakot_terminated_cluster		=> { found_syllable (use_sakot_terminated_cluster); };
 	standard_cluster			=> { found_syllable (use_standard_cluster); };
@@ -225,8 +228,8 @@
 
 
 static bool
-not_standard_default_ignorable (const hb_glyph_info_t &i)
-{ return !(i.use_category() == USE(O) && _hb_glyph_info_is_default_ignorable (&i)); }
+not_ccs_default_ignorable (const hb_glyph_info_t &i)
+{ return !(i.use_category() == USE(CGJ) && _hb_glyph_info_is_default_ignorable (&i)); }
 
 static inline void
 find_syllables_use (hb_buffer_t *buffer)
@@ -235,13 +238,13 @@
   auto p =
     + hb_iter (info, buffer->len)
     | hb_enumerate
-    | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); },
+    | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); },
 		 hb_second)
     | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
 		 {
 		   if (p.second.use_category() == USE(ZWNJ))
 		     for (unsigned i = p.first + 1; i < buffer->len; ++i)
-		       if (not_standard_default_ignorable (info[i]))
+		       if (not_ccs_default_ignorable (info[i]))
 			 return !_hb_glyph_info_is_unicode_mark (&info[i]);
 		   return true;
 		 })

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -2,7 +2,7 @@
 /*
  * The following table is generated by running:
  *
- *   ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt ArabicShaping.txt Blocks.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
+ *   ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
  *
  * on files with these headers:
  *
@@ -12,22 +12,28 @@
  * # Date: 2021-05-22, 01:01:00 GMT [KW, RP]
  * # ArabicShaping-14.0.0.txt
  * # Date: 2021-05-21, 01:54:00 GMT [KW, RP]
+ * # DerivedCoreProperties-14.0.0.txt
+ * # Date: 2021-08-12, 23:12:53 GMT
  * # Blocks-14.0.0.txt
  * # Date: 2021-01-22, 23:29:00 GMT [KW]
+ * # Scripts-14.0.0.txt
+ * # Date: 2021-07-10, 00:35:31 GMT
  * # Override values For Indic_Syllabic_Category
  * # Not derivable
  * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
- * # Updated  for Unicode 10.0 by Andrew Glass 2017-07-25
- * # Updated  for Unicode 12.1 by Andrew Glass 2019-05-24
- * # Updated  for Unicode 13.0 by Andrew Glass 2020-07-28
+ * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
+ * # Updated for Unicode 12.1 by Andrew Glass 2019-05-24
+ * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
+ * # Updated for Unicode 14.0 by Andrew Glass 2021-09-25
  * # Override values For Indic_Positional_Category
  * # Not derivable
  * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
- * # Updated  for Unicode 10.0 by Andrew Glass 2017-07-25
+ * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
  * # Ammended for Unicode 10.0 by Andrew Glass 2018-09-21
- * # Updated  for L2/19-083    by Andrew Glass 2019-05-06
- * # Updated  for Unicode 12.1 by Andrew Glass 2019-05-30
- * # Updated  for Unicode 13.0 by Andrew Glass 2020-07-28
+ * # Updated for L2/19-083    by Andrew Glass 2019-05-06
+ * # Updated for Unicode 12.1 by Andrew Glass 2019-05-30
+ * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
+ * # Updated for Unicode 14.0 by Andrew Glass 2021-09-28
  * UnicodeData.txt does not have a header.
  */
 
@@ -41,6 +47,7 @@
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-macros"
 #define B	USE(B)	/* BASE */
+#define CGJ	USE(CGJ)	/* CGJ */
 #define CS	USE(CS)	/* CONS_WITH_STACKER */
 #define G	USE(G)	/* HIEROGLYPH */
 #define GB	USE(GB)	/* BASE_OTHER */
@@ -51,7 +58,6 @@
 #define N	USE(N)	/* BASE_NUM */
 #define O	USE(O)	/* OTHER */
 #define R	USE(R)	/* REPHA */
-#define S	USE(S)	/* SYM */
 #define SB	USE(SB)	/* HIEROGLYPH_SEGMENT_BEGIN */
 #define SE	USE(SE)	/* HIEROGLYPH_SEGMENT_END */
 #define SUB	USE(SUB)	/* CONS_SUB */
@@ -101,14 +107,20 @@
   /* 00C0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 00D0 */     O,     O,     O,     O,     O,     O,     O,    GB,
 
-#define use_offset_0x0640u 80
+#define use_offset_0x0348u 80
 
 
+  /* Combining Diacritical Marks */
+                                                                         O,     O,     O,     O,     O,     O,     O,   CGJ,
+
+#define use_offset_0x0640u 88
+
+
   /* Arabic */
 
   /* 0640 */     B,     O,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x07c8u 88
+#define use_offset_0x07c8u 96
 
 
   /* NKo */
@@ -117,7 +129,7 @@
   /* 07E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
   /* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,     B,     O,     O, VMAbv,     O,     O,
 
-#define use_offset_0x0840u 144
+#define use_offset_0x0840u 152
 
 
   /* Mandaic */
@@ -125,7 +137,7 @@
   /* 0840 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0850 */     B,     B,     B,     B,     B,     B,     B,     B,     B, CMBlw, CMBlw, CMBlw,     O,     O,     O,     O,
 
-#define use_offset_0x0900u 176
+#define use_offset_0x0900u 184
 
 
   /* Devanagari */
@@ -238,7 +250,7 @@
   /* 0DE0 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0DF0 */     O,     O,  VPst,  VPst,     O,     O,     O,     O,
 
-#define use_offset_0x0f00u 1448
+#define use_offset_0x0f00u 1456
 
 
   /* Tibetan */
@@ -257,7 +269,7 @@
   /* 0FB0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,     O,     O,
   /* 0FC0 */     O,     O,     O,     O,     O,     O,  FBlw,     O,
 
-#define use_offset_0x1000u 1648
+#define use_offset_0x1000u 1656
 
 
   /* Myanmar */
@@ -273,7 +285,7 @@
   /* 1080 */     B,     B,  MBlw,  VPst,  VPre,  VAbv,  VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw,     B, VMPst,
   /* 1090 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMPst, VMPst,  VPst,  VAbv,     O,     O,
 
-#define use_offset_0x1700u 1808
+#define use_offset_0x1700u 1816
 
 
   /* Tagalog */
@@ -301,7 +313,7 @@
   /* 1780 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1790 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 17A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 17B0 */     B,     B,     B,     B,     O,     O,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VPre,  VPre,
+  /* 17B0 */     B,     B,     B,     B,   CGJ,   CGJ,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VPre,  VPre,
   /* 17C0 */  VPre,  VPre,  VPre,  VPre,  VPre,  VPre, VMAbv, VMPst,  VPst, VMAbv, VMAbv, FMAbv,  FAbv, CMAbv, FMAbv, VMAbv,
   /* 17D0 */ FMAbv,  VAbv,     H, FMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     B, FMAbv,     O,     O,
   /* 17E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
@@ -309,7 +321,7 @@
 
   /* Mongolian */
 
-  /* 1800 */     B,     O,     O,     O,     O,     O,     O,     B,     O,     O,     B,     O,     O,     O,     O,     O,
+  /* 1800 */     B,     O,     O,     O,     O,     O,     O,     B,     O,     O,     B,   CGJ,   CGJ,   CGJ,     O,   CGJ,
   /* 1810 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 1820 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1830 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
@@ -321,7 +333,7 @@
   /* 1890 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 18A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B, CMBlw,     B,     O,     O,     O,     O,     O,
 
-#define use_offset_0x1900u 2240
+#define use_offset_0x1900u 2248
 
 
   /* Limbu */
@@ -365,7 +377,7 @@
   /* 1A80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
   /* 1A90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x1b00u 2656
+#define use_offset_0x1b00u 2664
 
 
   /* Balinese */
@@ -376,7 +388,7 @@
   /* 1B30 */     B,     B,     B,     B, CMAbv,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPre,  VPre,
   /* 1B40 */  VPre,  VPre,  VAbv,  VAbv,     H,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,
   /* 1B50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,    GB,    GB,     O,     O,    GB,
-  /* 1B60 */     O,     S,    GB,     S,     S,     S,     S,     S,    GB,     S,     S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
+  /* 1B60 */     O,     O,    GB,     O,     O,     O,     O,     O,    GB,     O,     O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
   /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Sundanese */
@@ -401,7 +413,7 @@
   /* 1C30 */  FAbv,  FAbv,  FAbv,  FAbv, VMPre, VMPre, FMAbv, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 1C40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,     B,     B,
 
-#define use_offset_0x1cd0u 2992
+#define use_offset_0x1cd0u 3000
 
 
   /* Vedic Extensions */
@@ -410,20 +422,20 @@
   /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,     O,     O,     O,     O, VMBlw,     O,     O,
   /* 1CF0 */     O,     O,     O,     O, VMAbv,    CS,    CS, VMPst, VMAbv, VMAbv,    GB,     O,     O,     O,     O,     O,
 
-#define use_offset_0x1df8u 3040
+#define use_offset_0x1df8u 3048
 
 
   /* Combining Diacritical Marks Supplement */
                                                                          O,     O,     O, FMAbv,     O,     O,     O,     O,
 
-#define use_offset_0x2008u 3048
+#define use_offset_0x2008u 3056
 
 
   /* General Punctuation */
-                                                                         O,     O,     O,     O,  ZWNJ,     O,     O,     O,
+                                                                         O,     O,     O,     O,  ZWNJ,   CGJ,     O,     O,
   /* 2010 */    GB,    GB,    GB,    GB,    GB,     O,     O,     O,
 
-#define use_offset_0x2070u 3064
+#define use_offset_0x2070u 3072
 
 
   /* Superscripts and Subscripts */
@@ -431,7 +443,7 @@
   /* 2070 */     O,     O,     O,     O, FMPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 2080 */     O,     O, FMPst, FMPst, FMPst,     O,     O,     O,
 
-#define use_offset_0x20f0u 3088
+#define use_offset_0x20f0u 3096
 
 
   /* Combining Diacritical Marks for Symbols */
@@ -438,13 +450,13 @@
 
   /* 20F0 */ VMAbv,     O,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x25c8u 3096
+#define use_offset_0x25c8u 3104
 
 
   /* Geometric Shapes */
                                                                          O,     O,     O,     O,     B,     O,     O,     O,
 
-#define use_offset_0x2d30u 3104
+#define use_offset_0x2d30u 3112
 
 
   /* Tifinagh */
@@ -455,7 +467,7 @@
   /* 2D60 */     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,     B,
   /* 2D70 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     H,
 
-#define use_offset_0xa800u 3184
+#define use_offset_0xa800u 3192
 
 
   /* Syloti Nagri */
@@ -542,7 +554,7 @@
   /* AAE0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPre,  VBlw,  VAbv,  VPre,  VPst,
   /* AAF0 */     O,     O,     O,     O,     O, VMPst,     H,     O,
 
-#define use_offset_0xabc0u 3944
+#define use_offset_0xabc0u 3952
 
 
   /* Meetei Mayek */
@@ -552,9 +564,27 @@
   /* ABE0 */     B,     B,     B,  VPst,  VPst,  VAbv,  VPst,  VPst,  VBlw,  VPst,  VPst,     O, VMPst,  VBlw,     O,     O,
   /* ABF0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x10a00u 4008
+#define use_offset_0xfe00u 4016
 
 
+  /* Variation Selectors */
+
+  /* FE00 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+
+#define use_offset_0x10570u 4032
+
+
+  /* Vithkuqi */
+
+  /* 10570 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,
+  /* 10580 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,
+  /* 10590 */     B,     B,     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 105A0 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 105B0 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     O,     O,     O,
+
+#define use_offset_0x10a00u 4112
+
+
   /* Kharoshthi */
 
   /* 10A00 */     B,  VBlw,  VBlw,  VBlw,     O,  VAbv,  VBlw,     O,     O,     O,     O,     O,  VPst, VMBlw, VMBlw, VMAbv,
@@ -563,7 +593,7 @@
   /* 10A30 */     B,     B,     B,     B,     B,     B,     O,     O, CMAbv, CMBlw, CMBlw,     O,     O,     O,     O,     H,
   /* 10A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x10ac0u 4088
+#define use_offset_0x10ac0u 4192
 
 
   /* Manichaean */
@@ -570,9 +600,9 @@
 
   /* 10AC0 */     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,
   /* 10AD0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 10AE0 */     B,     B,     B,     B,     B, CMBlw, CMBlw,     O,
+  /* 10AE0 */     B,     B,     B,     B,     B, CMBlw, CMBlw,     O,     O,     O,     O,     B,     B,     B,     B,     B,
 
-#define use_offset_0x10b80u 4128
+#define use_offset_0x10b80u 4240
 
 
   /* Psalter Pahlavi */
@@ -581,7 +611,7 @@
   /* 10B90 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 10BA0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     O,
 
-#define use_offset_0x10d00u 4176
+#define use_offset_0x10d00u 4288
 
 
   /* Hanifi Rohingya */
@@ -591,7 +621,7 @@
   /* 10D20 */     B,     B,     B,     B, VMAbv, VMAbv, VMAbv, CMAbv,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 10D30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x10e80u 4240
+#define use_offset_0x10e80u 4352
 
 
   /* Yezidi */
@@ -601,7 +631,7 @@
   /* 10EA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,  VAbv,  VAbv,     O,     O,     O,
   /* 10EB0 */     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x10f30u 4296
+#define use_offset_0x10f30u 4408
 
 
   /* Sogdian */
@@ -608,10 +638,15 @@
 
   /* 10F30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 10F40 */     B,     B,     B,     B,     B,     B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,
-  /* 10F50 */ VMBlw,     B,     B,     B,     B,     O,     O,     O,
+  /* 10F50 */ VMBlw,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 10F60 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x10fb0u 4336
+  /* Old Uyghur */
 
+  /* 10F70 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 10F80 */     B,     B, CMBlw, CMBlw, CMBlw, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 10F90 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 10FA0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Chorasmian */
 
@@ -627,7 +662,7 @@
   /* 11010 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11020 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11030 */     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,
-  /* 11040 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,   HVM,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11040 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11050 */     O,     O,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,
   /* 11060 */     N,     N,     N,     N,     N,     N,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11070 */  VAbv,     B,     B,  VAbv,  VAbv,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,    HN,
@@ -640,7 +675,7 @@
   /* 110B0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VAbv,  VAbv,  VPst,  VPst,     H, CMBlw,     O,     O,     O,     O,     O,
   /* 110C0 */     O,     O,  VBlw,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11100u 4616
+#define use_offset_0x11100u 4816
 
 
   /* Chakma */
@@ -678,7 +713,7 @@
   /* 11220 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VPst,  VBlw,
   /* 11230 */  VAbv,  VAbv,  VAbv,  VAbv, VMAbv,     H, CMAbv, CMAbv,     O,     O,     O,     O,     O,     O, VMAbv,     O,
 
-#define use_offset_0x11280u 4936
+#define use_offset_0x11280u 5136
 
 
   /* Multani */
@@ -706,7 +741,7 @@
   /* 11360 */     B,     B,  VPst,  VPst,     O,     O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
   /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
 
-#define use_offset_0x11400u 5184
+#define use_offset_0x11400u 5384
 
 
   /* Newa */
@@ -729,7 +764,7 @@
   /* 114C0 */ VMAbv, VMAbv,     H, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 114D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11580u 5408
+#define use_offset_0x11580u 5608
 
 
   /* Siddham */
@@ -773,7 +808,7 @@
   /* 11730 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
   /* 11740 */     B,     B,     B,     B,     B,     B,     B,     O,
 
-#define use_offset_0x11800u 5864
+#define use_offset_0x11800u 6064
 
 
   /* Dogra */
@@ -783,7 +818,7 @@
   /* 11820 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,
   /* 11830 */  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMPst,     H, CMBlw,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11900u 5928
+#define use_offset_0x11900u 6128
 
 
   /* Dives Akuru */
@@ -795,7 +830,7 @@
   /* 11940 */  MPst,     R,  MPst, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11950 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x119a0u 6024
+#define use_offset_0x119a0u 6224
 
 
   /* Nandinagari */
@@ -823,7 +858,7 @@
   /* 11A80 */     B,     B,     B,     B,     R,     R,     R,     R,     R,     R,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,
   /* 11A90 */  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw, VMAbv, VMPst, CMAbv,     H,     O,     O,     O,     B,     O,     O,
 
-#define use_offset_0x11c00u 6280
+#define use_offset_0x11c00u 6480
 
 
   /* Bhaiksuki */
@@ -844,7 +879,7 @@
   /* 11CA0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 11CB0 */  VBlw,  VPre,  VBlw,  VAbv,  VPst, VMAbv, VMAbv,     O,
 
-#define use_offset_0x11d00u 6464
+#define use_offset_0x11d00u 6664
 
 
   /* Masaram Gondi */
@@ -864,7 +899,7 @@
   /* 11D90 */  VAbv,  VAbv,     O,  VPst,  VPst, VMAbv, VMPst,     H,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11DA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11ee0u 6640
+#define use_offset_0x11ee0u 6840
 
 
   /* Makasar */
@@ -872,86 +907,93 @@
   /* 11EE0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11EF0 */     B,     B,    GB,  VAbv,  VBlw,  VPre,  VPst,     O,
 
-#define use_offset_0x13000u 6664
+#define use_offset_0x13000u 6864
 
 
   /* Egyptian Hieroglyphs */
 
-  /* 13000 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13010 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13020 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13030 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13040 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13050 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13060 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13070 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13080 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13090 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 130A0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 130B0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 130C0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 130D0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 130E0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 130F0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13100 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13110 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13120 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13130 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13140 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13150 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13160 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13170 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13180 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13190 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 131A0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 131B0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 131C0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 131D0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 131E0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 131F0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13200 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13210 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13220 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13230 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13240 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13250 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13260 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13270 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13280 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13290 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 132A0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 132B0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 132C0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 132D0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 132E0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 132F0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13300 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13310 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13320 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13330 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13340 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13350 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13360 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13370 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13380 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13390 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 133A0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 133B0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 133C0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 133D0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 133E0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 133F0 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13400 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13410 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,
-  /* 13420 */     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     G,     O,
+  /* 13000 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13010 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13020 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13030 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13040 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13050 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13060 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13070 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13080 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13090 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 130A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 130B0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 130C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 130D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 130E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 130F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13100 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13110 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13120 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13130 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13140 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13150 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13160 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13170 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13180 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13190 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 131A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 131B0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 131C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 131D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 131E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 131F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13200 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13210 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13220 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13230 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13240 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13250 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13260 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13270 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13280 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13290 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 132A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 132B0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 132C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 132D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 132E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 132F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13300 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13310 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13320 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13330 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13340 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13350 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13360 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13370 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13380 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13390 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 133A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 133B0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 133C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 133D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 133E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 133F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13400 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13410 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 13420 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,
 
   /* Egyptian Hieroglyph Format Controls */
 
-  /* 13430 */     J,     J,     J,     J,     J,     J,     J,    SB,    SE,     O,     O,     O,     O,     O,     O,     O,
+  /* 13430 */     H,     H,     H,     H,     H,     H,     H,     B,     B,     O,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x16b00u 7752
+#define use_offset_0x16ac0u 7952
 
 
+  /* Tangsa */
+
+  /* 16AC0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 16AD0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 16AE0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 16AF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
   /* Pahawh Hmong */
 
   /* 16B00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
@@ -959,7 +1001,7 @@
   /* 16B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,
 
-#define use_offset_0x16f00u 7808
+#define use_offset_0x16f00u 8072
 
 
   /* Miao */
@@ -975,7 +1017,7 @@
   /* 16F80 */  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,     O,     O,     O,     O,     O, VMBlw,
   /* 16F90 */ VMBlw, VMBlw, VMBlw,     O,     O,     O,     O,     O,
 
-#define use_offset_0x16fe0u 7960
+#define use_offset_0x16fe0u 8224
 
 
   /* Ideographic Symbols and Punctuation */
@@ -982,7 +1024,7 @@
 
   /* 16FE0 */     O,     O,     O,     O,     B,     O,     O,     O,
 
-#define use_offset_0x18b00u 7968
+#define use_offset_0x18b00u 8232
 
 
   /* Khitan Small Script */
@@ -1018,7 +1060,7 @@
   /* 18CC0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 18CD0 */     B,     B,     B,     B,     B,     B,     O,     O,
 
-#define use_offset_0x1bc00u 8440
+#define use_offset_0x1bc00u 8704
 
 
   /* Duployan */
@@ -1034,7 +1076,7 @@
   /* 1BC80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,
   /* 1BC90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O, CMBlw, CMBlw,     O,
 
-#define use_offset_0x1e100u 8600
+#define use_offset_0x1e100u 8864
 
 
   /* Nyiakeng Puachue Hmong */
@@ -1045,9 +1087,15 @@
   /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     B,     B,     B,     B,     B,     B,     B,     O,     O,
   /* 1E140 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     B,     B,
 
-#define use_offset_0x1e2c0u 8680
+#define use_offset_0x1e290u 8944
 
 
+  /* Toto */
+
+  /* 1E290 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1E2A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv,     O,
+  /* 1E2B0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
   /* Wancho */
 
   /* 1E2C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
@@ -1055,7 +1103,7 @@
   /* 1E2E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv, VMAbv, VMAbv, VMAbv,
   /* 1E2F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x1e900u 8744
+#define use_offset_0x1e900u 9056
 
 
   /* Adlam */
@@ -1067,8 +1115,29 @@
   /* 1E940 */     B,     B,     B,     B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv,     B,     O,     O,     O,     O,
   /* 1E950 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-}; /* Table items: 8840; occupancy: 79% */
+#define use_offset_0xe0100u 9152
 
+
+  /* Variation Selectors Supplement */
+
+  /* E0100 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0110 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0120 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0130 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0140 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0150 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0160 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0170 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0180 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E0190 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E01A0 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E01B0 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E01C0 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E01D0 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+  /* E01E0 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
+
+}; /* Table items: 9392; occupancy: 79% */
+
 static inline uint8_t
 hb_use_get_category (hb_codepoint_t u)
 {
@@ -1077,6 +1146,7 @@
     case 0x0u:
       if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
       if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u];
       if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u];
       if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u];
       if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u];
@@ -1106,18 +1176,22 @@
       if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u];
       break;
 
+    case 0xFu:
+      if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
+      break;
+
     case 0x10u:
+      if (hb_in_range<hb_codepoint_t> (u, 0x10570u, 0x105BFu)) return use_table[u - 0x10570u + use_offset_0x10570u];
       if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
-      if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AE7u)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u];
       if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u];
       if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u];
       if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u];
-      if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F57u)) return use_table[u - 0x10F30u + use_offset_0x10f30u];
-      if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110C7u)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u];
       break;
 
     case 0x11u:
-      if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110C7u)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
       if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
@@ -1135,7 +1209,7 @@
       break;
 
     case 0x16u:
-      if (hb_in_range<hb_codepoint_t> (u, 0x16B00u, 0x16B37u)) return use_table[u - 0x16B00u + use_offset_0x16b00u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x16AC0u, 0x16B37u)) return use_table[u - 0x16AC0u + use_offset_0x16ac0u];
       if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u];
       if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u];
       break;
@@ -1150,10 +1224,14 @@
 
     case 0x1Eu:
       if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u];
-      if (hb_in_range<hb_codepoint_t> (u, 0x1E2C0u, 0x1E2FFu)) return use_table[u - 0x1E2C0u + use_offset_0x1e2c0u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x1E290u, 0x1E2FFu)) return use_table[u - 0x1E290u + use_offset_0x1e290u];
       if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u];
       break;
 
+    case 0xE0u:
+      if (hb_in_range<hb_codepoint_t> (u, 0xE0100u, 0xE01EFu)) return use_table[u - 0xE0100u + use_offset_0xe0100u];
+      break;
+
     default:
       break;
   }
@@ -1161,6 +1239,7 @@
 }
 
 #undef B
+#undef CGJ
 #undef CS
 #undef G
 #undef GB
@@ -1171,7 +1250,6 @@
 #undef N
 #undef O
 #undef R
-#undef S
 #undef SB
 #undef SE
 #undef SUB

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -257,7 +257,6 @@
     use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
     switch (syllable_type)
     {
-      case use_independent_cluster:
       case use_symbol_cluster:
       case use_hieroglyph_cluster:
       case use_non_cluster:

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	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -171,7 +171,7 @@
   hb_codepoint_t u = buffer->cur().codepoint;
   hb_codepoint_t glyph = 0;
 
-  if (shortest && c->font->get_nominal_glyph (u, &glyph))
+  if (shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found))
   {
     next_char (buffer, glyph);
     return;
@@ -183,7 +183,7 @@
     return;
   }
 
-  if (!shortest && c->font->get_nominal_glyph (u, &glyph))
+  if (!shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found))
   {
     next_char (buffer, glyph);
     return;
@@ -312,6 +312,7 @@
     buffer,
     font,
     buffer->unicode,
+    buffer->not_found,
     plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode,
     plan->shaper->compose   ? plan->shaper->compose   : compose_unicode
   };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -56,6 +56,7 @@
   hb_buffer_t *buffer;
   hb_font_t *font;
   hb_unicode_funcs_t *unicode;
+  const hb_codepoint_t not_found;
   bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
 		     hb_codepoint_t  ab,
 		     hb_codepoint_t *a,

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	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -150,23 +150,25 @@
    */
 
 #ifndef HB_NO_AAT_SHAPE
-  bool has_gsub = hb_ot_layout_has_substitution (face);
+  bool has_kerx = hb_aat_layout_has_positioning (face);
+  bool has_gsub = !apply_morx && hb_ot_layout_has_substitution (face);
 #endif
   bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
   if (false)
     ;
 #ifndef HB_NO_AAT_SHAPE
-  else if (hb_aat_layout_has_positioning (face) && !(has_gsub && has_gpos))
+  /* Prefer GPOS over kerx if GSUB is present;
+   * https://github.com/harfbuzz/harfbuzz/issues/3008 */
+  else if (has_kerx && !(has_gsub && has_gpos))
     plan.apply_kerx = true;
 #endif
-  else if (!apply_morx && has_gpos)
+  else if (has_gpos)
     plan.apply_gpos = true;
 
   if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos))
   {
-    /* Apparently Apple applies kerx if GPOS kern was not applied. */
 #ifndef HB_NO_AAT_SHAPE
-    if (hb_aat_layout_has_positioning (face))
+    if (has_kerx)
       plan.apply_kerx = true;
     else
 #endif

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -0,0 +1,264 @@
+/*
+ * Copyright © 2021  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+#ifndef HB_OT_VAR_COMMON_HH
+#define HB_OT_VAR_COMMON_HH
+
+#include "hb-ot-layout-common.hh"
+
+
+namespace OT {
+
+struct DeltaSetIndexMapFormat0
+{
+  friend struct DeltaSetIndexMap;
+
+  private:
+  DeltaSetIndexMapFormat0* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    unsigned total_size = min_size + mapCount * get_width ();
+    HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
+    if (unlikely (!p)) return_trace (nullptr);
+
+    memcpy (p, this, HBUINT8::static_size * total_size);
+    return_trace (out);
+  }
+
+  template <typename T>
+  bool serialize (hb_serialize_context_t *c, const T &plan)
+  {
+    unsigned int width = plan.get_width ();
+    unsigned int inner_bit_count = plan.get_inner_bit_count ();
+    const hb_array_t<const uint32_t> output_map = plan.get_output_map ();
+
+    TRACE_SERIALIZE (this);
+    if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0))))
+      return_trace (false);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+
+    entryFormat = ((width-1)<<4)|(inner_bit_count-1);
+    mapCount = output_map.length;
+    HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length);
+    if (unlikely (!p)) return_trace (false);
+    for (unsigned int i = 0; i < output_map.length; i++)
+    {
+      unsigned int v = output_map[i];
+      unsigned int outer = v >> 16;
+      unsigned int inner = v & 0xFFFF;
+      unsigned int u = (outer << inner_bit_count) | inner;
+      for (unsigned int w = width; w > 0;)
+      {
+        p[--w] = u;
+        u >>= 8;
+      }
+      p += width;
+    }
+    return_trace (true);
+  }
+
+  uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */
+  {
+    /* If count is zero, pass value unchanged.  This takes
+     * care of direct mapping for advance map. */
+    if (!mapCount)
+      return v;
+
+    if (v >= mapCount)
+      v = mapCount - 1;
+
+    unsigned int u = 0;
+    { /* Fetch it. */
+      unsigned int w = get_width ();
+      const HBUINT8 *p = mapDataZ.arrayZ + w * v;
+      for (; w; w--)
+        u = (u << 8) + *p++;
+    }
+
+    { /* Repack it. */
+      unsigned int n = get_inner_bit_count ();
+      unsigned int outer = u >> n;
+      unsigned int inner = u & ((1 << n) - 1);
+      u = (outer<<16) | inner;
+    }
+
+    return u;
+  }
+
+  unsigned get_map_count () const       { return mapCount; }
+  unsigned get_width () const           { return ((entryFormat >> 4) & 3) + 1; }
+  unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; }
+
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  c->check_range (mapDataZ.arrayZ,
+                                  mapCount,
+                                  get_width ()));
+  }
+
+  protected:
+  HBUINT8       format;         /* Format identifier--format = 0 */
+  HBUINT8       entryFormat;    /* A packed field that describes the compressed
+                                 * representation of delta-set indices. */
+  HBUINT16      mapCount;       /* The number of mapping entries. */
+  UnsizedArrayOf<HBUINT8>
+                mapDataZ;       /* The delta-set index mapping data. */
+
+  public:
+  DEFINE_SIZE_ARRAY (4, mapDataZ);
+};
+
+struct DeltaSetIndexMapFormat1
+{
+  friend struct DeltaSetIndexMap;
+
+  private:
+  DeltaSetIndexMapFormat1* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    unsigned total_size = min_size + mapCount * get_width ();
+    HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
+    if (unlikely (!p)) return_trace (nullptr);
+
+    memcpy (p, this, HBUINT8::static_size * total_size);
+    return_trace (out);
+  }
+
+  unsigned get_map_count () const       { return mapCount; }
+  unsigned get_width () const           { return ((entryFormat >> 4) & 3) + 1; }
+  unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  c->check_range (mapDataZ.arrayZ,
+                                  mapCount,
+                                  get_width ()));
+  }
+
+  protected:
+  HBUINT8       format;         /* Format identifier--format = 1 */
+  HBUINT8       entryFormat;    /* A packed field that describes the compressed
+                                 * representation of delta-set indices. */
+  HBUINT32      mapCount;       /* The number of mapping entries. */
+  UnsizedArrayOf<HBUINT8>
+                mapDataZ;       /* The delta-set index mapping data. */
+
+  public:
+  DEFINE_SIZE_ARRAY (6, mapDataZ);
+};
+
+struct DeltaSetIndexMap
+{
+  template <typename T>
+  bool serialize (hb_serialize_context_t *c, const T &plan)
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.format) {
+    case 0: return_trace (u.format0.serialize (c, plan));
+    default:return_trace (false);
+    }
+  }
+
+  uint32_t map (unsigned v) const
+  {
+    switch (u.format) {
+    case 0: return (u.format0.map (v));
+    default:return v;
+    }
+  }
+
+  unsigned get_map_count () const
+  {
+    switch (u.format) {
+    case 0: return u.format0.get_map_count ();
+    case 1: return u.format1.get_map_count ();
+    default:return 0;
+    }
+  }
+
+  unsigned get_width () const
+  {
+    switch (u.format) {
+    case 0: return u.format0.get_width ();
+    case 1: return u.format1.get_width ();
+    default:return 0;
+    }
+  }
+
+  unsigned get_inner_bit_count () const
+  {
+    switch (u.format) {
+    case 0: return u.format0.get_inner_bit_count ();
+    case 1: return u.format1.get_inner_bit_count ();
+    default:return 0;
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    switch (u.format) {
+    case 0: return_trace (u.format0.sanitize (c));
+    case 1: return_trace (u.format1.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  DeltaSetIndexMap* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.format) {
+    case 0: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format0.copy (c)));
+    case 1: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format1.copy (c)));
+    default:return_trace (nullptr);
+    }
+  }
+
+  protected:
+  union {
+  HBUINT8                       format;         /* Format identifier */
+  DeltaSetIndexMapFormat0       format0;
+  DeltaSetIndexMapFormat1       format1;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (1, format);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_VAR_COMMON_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -28,97 +28,11 @@
 #define HB_OT_VAR_HVAR_TABLE_HH
 
 #include "hb-ot-layout-common.hh"
+#include "hb-ot-var-common.hh"
 
-
 namespace OT {
 
 
-struct DeltaSetIndexMap
-{
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  c->check_range (mapDataZ.arrayZ,
-				  mapCount,
-				  get_width ()));
-  }
-
-  template <typename T>
-  bool serialize (hb_serialize_context_t *c, const T &plan)
-  {
-    unsigned int width = plan.get_width ();
-    unsigned int inner_bit_count = plan.get_inner_bit_count ();
-    const hb_array_t<const uint32_t> output_map = plan.get_output_map ();
-
-    TRACE_SERIALIZE (this);
-    if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0))))
-      return_trace (false);
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-
-    format = ((width-1)<<4)|(inner_bit_count-1);
-    mapCount = output_map.length;
-    HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length);
-    if (unlikely (!p)) return_trace (false);
-    for (unsigned int i = 0; i < output_map.length; i++)
-    {
-      unsigned int v = output_map[i];
-      unsigned int outer = v >> 16;
-      unsigned int inner = v & 0xFFFF;
-      unsigned int u = (outer << inner_bit_count) | inner;
-      for (unsigned int w = width; w > 0;)
-      {
-	p[--w] = u;
-	u >>= 8;
-      }
-      p += width;
-    }
-    return_trace (true);
-  }
-
-  uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */
-  {
-    /* If count is zero, pass value unchanged.  This takes
-     * care of direct mapping for advance map. */
-    if (!mapCount)
-      return v;
-
-    if (v >= mapCount)
-      v = mapCount - 1;
-
-    unsigned int u = 0;
-    { /* Fetch it. */
-      unsigned int w = get_width ();
-      const HBUINT8 *p = mapDataZ.arrayZ + w * v;
-      for (; w; w--)
-	u = (u << 8) + *p++;
-    }
-
-    { /* Repack it. */
-      unsigned int n = get_inner_bit_count ();
-      unsigned int outer = u >> n;
-      unsigned int inner = u & ((1 << n) - 1);
-      u = (outer<<16) | inner;
-    }
-
-    return u;
-  }
-
-  unsigned int get_map_count () const	    { return mapCount; }
-  unsigned int get_width () const           { return ((format >> 4) & 3) + 1; }
-  unsigned int get_inner_bit_count () const { return (format & 0xF) + 1; }
-
-  protected:
-  HBUINT16	format;		/* A packed field that describes the compressed
-				 * representation of delta-set indices. */
-  HBUINT16	mapCount;	/* The number of mapping entries. */
-  UnsizedArrayOf<HBUINT8>
-		mapDataZ;	/* The delta-set index mapping data. */
-
-  public:
-  DEFINE_SIZE_ARRAY (4, mapDataZ);
-};
-
 struct index_map_subset_plan_t
 {
   enum index_map_index_t {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -48,7 +48,7 @@
   }
 
   public:
-  HBGlyphID	glyph;
+  HBGlyphID16	glyph;
   FWORD		vertOriginY;
 
   public:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -33,6 +33,10 @@
 #include "hb-serialize.hh"
 #include "hb-vector.hh"
 
+/*
+ * For a detailed writeup on the overflow resolution algorithm see:
+ * docs/repacker.md
+ */
 
 struct graph_t
 {
@@ -40,16 +44,21 @@
   {
     vertex_t () :
         distance (0),
-        incoming_edges (0),
+        space (0),
+        parents (),
         start (0),
         end (0),
         priority(0) {}
 
-    void fini () { obj.fini (); }
+    void fini () {
+      obj.fini ();
+      parents.fini ();
+    }
 
     hb_serialize_context_t::object_t obj;
     int64_t distance;
-    unsigned incoming_edges;
+    int64_t space;
+    hb_vector_t<unsigned> parents;
     unsigned start;
     unsigned end;
     unsigned priority;
@@ -56,9 +65,39 @@
 
     bool is_shared () const
     {
-      return incoming_edges > 1;
+      return parents.length > 1;
     }
 
+    unsigned incoming_edges () const
+    {
+      return parents.length;
+    }
+
+    void remove_parent (unsigned parent_index)
+    {
+      for (unsigned i = 0; i < parents.length; i++)
+      {
+        if (parents[i] != parent_index) continue;
+        parents.remove (i);
+        break;
+      }
+    }
+
+    void remap_parents (const hb_vector_t<unsigned>& id_map)
+    {
+      for (unsigned i = 0; i < parents.length; i++)
+        parents[i] = id_map[parents[i]];
+    }
+
+    void remap_parent (unsigned old_index, unsigned new_index)
+    {
+      for (unsigned i = 0; i < parents.length; i++)
+      {
+        if (parents[i] == old_index)
+          parents[i] = new_index;
+      }
+    }
+
     bool is_leaf () const
     {
       return !obj.links.length;
@@ -77,7 +116,7 @@
 
       int64_t modified_distance =
           hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFF);
-      return (modified_distance << 24) | (0x00FFFFFF & order);
+      return (modified_distance << 22) | (0x003FFFFF & order);
     }
 
     int64_t distance_modifier () const
@@ -91,36 +130,9 @@
   struct overflow_record_t
   {
     unsigned parent;
-    const hb_serialize_context_t::object_t::link_t* link;
+    unsigned child;
   };
 
-  struct clone_buffer_t
-  {
-    clone_buffer_t () : head (nullptr), tail (nullptr) {}
-
-    bool copy (const hb_serialize_context_t::object_t& object)
-    {
-      fini ();
-      unsigned size = object.tail - object.head;
-      head = (char*) hb_malloc (size);
-      if (!head) return false;
-
-      memcpy (head, object.head, size);
-      tail = head + size;
-      return true;
-    }
-
-    char* head;
-    char* tail;
-
-    void fini ()
-    {
-      if (!head) return;
-      hb_free (head);
-      head = nullptr;
-    }
-  };
-
   /*
    * A topological sorting of an object graph. Ordered
    * in reverse serialization order (first object in the
@@ -129,11 +141,12 @@
    * serializer
    */
   graph_t (const hb_vector_t<hb_serialize_context_t::object_t *>& objects)
-      : edge_count_invalid (true),
+      : parents_invalid (true),
         distance_invalid (true),
         positions_invalid (true),
         successful (true)
   {
+    num_roots_for_space_.push (1);
     bool removed_nil = false;
     for (unsigned i = 0; i < objects.length; i++)
     {
@@ -160,12 +173,13 @@
   ~graph_t ()
   {
     vertices_.fini_deep ();
-    clone_buffers_.fini_deep ();
   }
 
   bool in_error () const
   {
-    return !successful || vertices_.in_error () || clone_buffers_.in_error ();
+    return !successful ||
+        vertices_.in_error () ||
+        num_roots_for_space_.in_error ();
   }
 
   const vertex_t& root () const
@@ -226,12 +240,13 @@
 
     hb_vector_t<unsigned> queue;
     hb_vector_t<vertex_t> sorted_graph;
+    if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
     hb_vector_t<unsigned> id_map;
     if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
 
     hb_vector_t<unsigned> removed_edges;
     if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return;
-    update_incoming_edge_count ();
+    update_parents ();
 
     queue.push (root_idx ());
     int new_id = vertices_.length - 1;
@@ -242,12 +257,12 @@
       queue.remove (0);
 
       vertex_t& next = vertices_[next_id];
-      sorted_graph.push (next);
+      sorted_graph[new_id] = next;
       id_map[next_id] = new_id--;
 
       for (const auto& link : next.obj.links) {
         removed_edges[link.objidx]++;
-        if (!(vertices_[link.objidx].incoming_edges - removed_edges[link.objidx]))
+        if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx]))
           queue.push (link.objidx);
       }
     }
@@ -255,14 +270,11 @@
     check_success (!queue.in_error ());
     check_success (!sorted_graph.in_error ());
     if (!check_success (new_id == -1))
-      DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected.");
+      print_orphaned_nodes ();
 
-    remap_obj_indices (id_map, &sorted_graph);
+    remap_all_obj_indices (id_map, &sorted_graph);
 
-    sorted_graph.as_array ().reverse ();
-
-    vertices_.fini_deep ();
-    vertices_ = sorted_graph;
+    hb_swap (vertices_, sorted_graph);
     sorted_graph.fini_deep ();
   }
 
@@ -283,12 +295,13 @@
 
     hb_priority_queue_t queue;
     hb_vector_t<vertex_t> sorted_graph;
+    if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
     hb_vector_t<unsigned> id_map;
     if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
 
     hb_vector_t<unsigned> removed_edges;
     if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return;
-    update_incoming_edge_count ();
+    update_parents ();
 
     queue.insert (root ().modified_distance (0), root_idx ());
     int new_id = root_idx ();
@@ -298,12 +311,12 @@
       unsigned next_id = queue.pop_minimum().second;
 
       vertex_t& next = vertices_[next_id];
-      sorted_graph.push (next);
+      sorted_graph[new_id] = next;
       id_map[next_id] = new_id--;
 
       for (const auto& link : next.obj.links) {
         removed_edges[link.objidx]++;
-        if (!(vertices_[link.objidx].incoming_edges - removed_edges[link.objidx]))
+        if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx]))
           // Add the order that the links were encountered to the priority.
           // This ensures that ties between priorities objects are broken in a consistent
           // way. More specifically this is set up so that if a set of objects have the same
@@ -317,66 +330,264 @@
     check_success (!queue.in_error ());
     check_success (!sorted_graph.in_error ());
     if (!check_success (new_id == -1))
-      DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected.");
+      print_orphaned_nodes ();
 
-    remap_obj_indices (id_map, &sorted_graph);
+    remap_all_obj_indices (id_map, &sorted_graph);
 
-    sorted_graph.as_array ().reverse ();
-
-    vertices_.fini_deep ();
-    vertices_ = sorted_graph;
+    hb_swap (vertices_, sorted_graph);
     sorted_graph.fini_deep ();
   }
 
   /*
-   * Creates a copy of child and re-assigns the link from
-   * parent to the clone. The copy is a shallow copy, objects
-   * linked from child are not duplicated.
+   * Assign unique space numbers to each connected subgraph of 32 bit offset(s).
    */
-  void duplicate (unsigned parent_idx, unsigned child_idx)
+  bool assign_32bit_spaces ()
   {
-    DEBUG_MSG (SUBSET_REPACK, nullptr, "  Duplicating %d => %d",
-               parent_idx, child_idx);
+    unsigned root_index = root_idx ();
+    hb_set_t visited;
+    hb_set_t roots;
+    for (unsigned i = 0; i <= root_index; i++)
+    {
+      for (auto& l : vertices_[i].obj.links)
+      {
+        if (l.width == 4 && !l.is_signed)
+        {
+          roots.add (l.objidx);
+          find_subgraph (l.objidx, visited);
+        }
+      }
+    }
 
+    // Mark everything not in the subgraphs of 32 bit roots as visited.
+    // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs.
+    visited.invert ();
+
+    if (!roots) return false;
+
+    while (roots)
+    {
+      unsigned next = HB_SET_VALUE_INVALID;
+      if (!roots.next (&next)) break;
+
+      hb_set_t connected_roots;
+      find_connected_nodes (next, roots, visited, connected_roots);
+      isolate_subgraph (connected_roots);
+
+      unsigned next_space = this->next_space ();
+      num_roots_for_space_.push (0);
+      for (unsigned root : connected_roots)
+      {
+        DEBUG_MSG (SUBSET_REPACK, nullptr, "Subgraph %u gets space %u", root, next_space);
+        vertices_[root].space = next_space;
+        num_roots_for_space_[next_space] = num_roots_for_space_[next_space] + 1;
+        distance_invalid = true;
+        positions_invalid = true;
+      }
+
+      // TODO(grieger): special case for GSUB/GPOS use extension promotions to move 16 bit space
+      //                into the 32 bit space as needed, instead of using isolation.
+    }
+
+    return true;
+  }
+
+  /*
+   * Isolates the subgraph of nodes reachable from root. Any links to nodes in the subgraph
+   * that originate from outside of the subgraph will be removed by duplicating the linked to
+   * object.
+   *
+   * Indices stored in roots will be updated if any of the roots are duplicated to new indices.
+   */
+  bool isolate_subgraph (hb_set_t& roots)
+  {
+    update_parents ();
+    hb_hashmap_t<unsigned, unsigned> subgraph;
+
+    // incoming edges to root_idx should be all 32 bit in length so we don't need to de-dup these
+    // set the subgraph incoming edge count to match all of root_idx's incoming edges
+    hb_set_t parents;
+    for (unsigned root_idx : roots)
+    {
+      subgraph.set (root_idx, wide_parents (root_idx, parents));
+      find_subgraph (root_idx, subgraph);
+    }
+
+    unsigned original_root_idx = root_idx ();
+    hb_hashmap_t<unsigned, unsigned> index_map;
+    bool made_changes = false;
+    for (auto entry : subgraph.iter ())
+    {
+      const auto& node = vertices_[entry.first];
+      unsigned subgraph_incoming_edges = entry.second;
+
+      if (subgraph_incoming_edges < node.incoming_edges ())
+      {
+        // Only  de-dup objects with incoming links from outside the subgraph.
+        made_changes = true;
+        duplicate_subgraph (entry.first, index_map);
+      }
+    }
+
+    if (!made_changes)
+      return false;
+
+    if (original_root_idx != root_idx ()
+        && parents.has (original_root_idx))
+    {
+      // If the root idx has changed since parents was determined, update root idx in parents
+      parents.add (root_idx ());
+      parents.del (original_root_idx);
+    }
+
+    auto new_subgraph =
+        + subgraph.keys ()
+        | hb_map([&] (unsigned node_idx) {
+          if (index_map.has (node_idx)) return index_map[node_idx];
+          return node_idx;
+        })
+        ;
+
+    remap_obj_indices (index_map, new_subgraph);
+    remap_obj_indices (index_map, parents.iter (), true);
+
+    // Update roots set with new indices as needed.
+    unsigned next = HB_SET_VALUE_INVALID;
+    while (roots.next (&next))
+    {
+      if (index_map.has (next))
+      {
+        roots.del (next);
+        roots.add (index_map[next]);
+      }
+    }
+
+    return true;
+  }
+
+  void find_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& subgraph)
+  {
+    for (const auto& link : vertices_[node_idx].obj.links)
+    {
+      if (subgraph.has (link.objidx))
+      {
+        subgraph.set (link.objidx, subgraph[link.objidx] + 1);
+        continue;
+      }
+      subgraph.set (link.objidx, 1);
+      find_subgraph (link.objidx, subgraph);
+    }
+  }
+
+  void find_subgraph (unsigned node_idx, hb_set_t& subgraph)
+  {
+    if (subgraph.has (node_idx)) return;
+    subgraph.add (node_idx);
+    for (const auto& link : vertices_[node_idx].obj.links)
+      find_subgraph (link.objidx, subgraph);
+  }
+
+  /*
+   * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign
+   * links. index_map is updated with mappings from old id to new id. If a duplication has already
+   * been performed for a given index, then it will be skipped.
+   */
+  void duplicate_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& index_map)
+  {
+    if (index_map.has (node_idx))
+      return;
+
+    index_map.set (node_idx, duplicate (node_idx));
+    for (const auto& l : object (node_idx).links) {
+      duplicate_subgraph (l.objidx, index_map);
+    }
+  }
+
+  /*
+   * Creates a copy of node_idx and returns it's new index.
+   */
+  unsigned duplicate (unsigned node_idx)
+  {
     positions_invalid = true;
+    distance_invalid = true;
 
     auto* clone = vertices_.push ();
-    auto& child = vertices_[child_idx];
-    clone_buffer_t* buffer = clone_buffers_.push ();
-    if (vertices_.in_error ()
-        || clone_buffers_.in_error ()
-        || !check_success (buffer->copy (child.obj))) {
-      return;
+    auto& child = vertices_[node_idx];
+    if (vertices_.in_error ()) {
+      return -1;
     }
 
-    clone->obj.head = buffer->head;
-    clone->obj.tail = buffer->tail;
+    clone->obj.head = child.obj.head;
+    clone->obj.tail = child.obj.tail;
     clone->distance = child.distance;
+    clone->space = child.space;
+    clone->parents.reset ();
 
+    unsigned clone_idx = vertices_.length - 2;
     for (const auto& l : child.obj.links)
+    {
       clone->obj.links.push (l);
+      vertices_[l.objidx].parents.push (clone_idx);
+    }
 
     check_success (!clone->obj.links.in_error ());
 
+    // The last object is the root of the graph, so swap back the root to the end.
+    // The root's obj idx does change, however since it's root nothing else refers to it.
+    // all other obj idx's will be unaffected.
+    vertex_t root = vertices_[vertices_.length - 2];
+    vertices_[clone_idx] = *clone;
+    vertices_[vertices_.length - 1] = root;
+
+    // Since the root moved, update the parents arrays of all children on the root.
+    for (const auto& l : root.obj.links)
+      vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ());
+
+    return clone_idx;
+  }
+
+  /*
+   * Creates a copy of child and re-assigns the link from
+   * parent to the clone. The copy is a shallow copy, objects
+   * linked from child are not duplicated.
+   */
+  bool duplicate (unsigned parent_idx, unsigned child_idx)
+  {
+    update_parents ();
+
+    unsigned links_to_child = 0;
+    for (const auto& l : vertices_[parent_idx].obj.links)
+    {
+      if (l.objidx == child_idx) links_to_child++;
+    }
+
+    if (vertices_[child_idx].incoming_edges () <= links_to_child)
+    {
+      // Can't duplicate this node, doing so would orphan the original one as all remaining links
+      // to child are from parent.
+      DEBUG_MSG (SUBSET_REPACK, nullptr, "  Not duplicating %d => %d",
+                 parent_idx, child_idx);
+      return false;
+    }
+
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "  Duplicating %d => %d",
+               parent_idx, child_idx);
+
+    unsigned clone_idx = duplicate (child_idx);
+    if (clone_idx == (unsigned) -1) return false;
+    // duplicate shifts the root node idx, so if parent_idx was root update it.
+    if (parent_idx == clone_idx) parent_idx++;
+
     auto& parent = vertices_[parent_idx];
-    unsigned clone_idx = vertices_.length - 2;
     for (unsigned i = 0; i < parent.obj.links.length; i++)
     {
       auto& l = parent.obj.links[i];
-      if (l.objidx == child_idx)
-      {
-        l.objidx = clone_idx;
-        clone->incoming_edges++;
-        child.incoming_edges--;
-      }
+      if (l.objidx != child_idx)
+        continue;
+
+      reassign_link (l, parent_idx, clone_idx);
     }
 
-    // The last object is the root of the graph, so swap back the root to the end.
-    // The root's obj idx does change, however since it's root nothing else refers to it.
-    // all other obj idx's will be unaffected.
-    vertex_t root = vertices_[vertices_.length - 2];
-    vertices_[vertices_.length - 2] = *clone;
-    vertices_[vertices_.length - 1] = root;
+    return true;
   }
 
   /*
@@ -414,7 +625,7 @@
 
         overflow_record_t r;
         r.parent = parent_idx;
-        r.link = &link;
+        r.child = link.objidx;
         overflows->push (r);
       }
     }
@@ -423,26 +634,112 @@
     return overflows->length;
   }
 
+  void print_orphaned_nodes ()
+  {
+    if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
+
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected.");
+    parents_invalid = true;
+    update_parents();
+
+    for (unsigned i = 0; i < root_idx (); i++)
+    {
+      const auto& v = vertices_[i];
+      if (!v.parents)
+        DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i);
+    }
+  }
+
   void print_overflows (const hb_vector_t<overflow_record_t>& overflows)
   {
     if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
 
-    update_incoming_edge_count ();
+    update_parents ();
     for (const auto& o : overflows)
     {
-      const auto& child = vertices_[o.link->objidx];
-      DEBUG_MSG (SUBSET_REPACK, nullptr, "  overflow from %d => %d (%d incoming , %d outgoing)",
+      const auto& parent = vertices_[o.parent];
+      const auto& child = vertices_[o.child];
+      DEBUG_MSG (SUBSET_REPACK, nullptr,
+                 "  overflow from "
+                 "%4d (%4d in, %4d out, space %2d) => "
+                 "%4d (%4d in, %4d out, space %2d)",
                  o.parent,
-                 o.link->objidx,
-                 child.incoming_edges,
-                 child.obj.links.length);
+                 parent.incoming_edges (),
+                 parent.obj.links.length,
+                 space_for (o.parent),
+                 o.child,
+                 child.incoming_edges (),
+                 child.obj.links.length,
+                 space_for (o.child));
     }
   }
 
+  unsigned num_roots_for_space (unsigned space) const
+  {
+    return num_roots_for_space_[space];
+  }
+
+  unsigned next_space () const
+  {
+    return num_roots_for_space_.length;
+  }
+
+  void move_to_new_space (unsigned index)
+  {
+    auto& node = vertices_[index];
+    num_roots_for_space_.push (1);
+    num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1;
+    node.space = num_roots_for_space_.length - 1;
+  }
+
+  unsigned space_for (unsigned index, unsigned* root = nullptr) const
+  {
+    const auto& node = vertices_[index];
+    if (node.space)
+    {
+      if (root != nullptr)
+        *root = index;
+      return node.space;
+    }
+
+    if (!node.parents)
+    {
+      if (root)
+        *root = index;
+      return 0;
+    }
+
+    return space_for (node.parents[0], root);
+  }
+
   void err_other_error () { this->successful = false; }
 
  private:
 
+  /*
+   * Returns the numbers of incoming edges that are 32bits wide.
+   */
+  unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const
+  {
+    unsigned count = 0;
+    hb_set_t visited;
+    for (unsigned p : vertices_[node_idx].parents)
+    {
+      if (visited.has (p)) continue;
+      visited.add (p);
+
+      for (const auto& l : vertices_[p].obj.links)
+      {
+        if (l.objidx == node_idx && l.width == 4 && !l.is_signed)
+        {
+          count++;
+          parents.add (p);
+        }
+      }
+    }
+    return count;
+  }
+
   bool check_success (bool success)
   { return this->successful && (success || (err_other_error (), false)); }
 
@@ -449,22 +746,22 @@
   /*
    * Creates a map from objid to # of incoming edges.
    */
-  void update_incoming_edge_count ()
+  void update_parents ()
   {
-    if (!edge_count_invalid) return;
+    if (!parents_invalid) return;
 
     for (unsigned i = 0; i < vertices_.length; i++)
-      vertices_[i].incoming_edges = 0;
+      vertices_[i].parents.reset ();
 
-    for (const vertex_t& v : vertices_)
+    for (unsigned p = 0; p < vertices_.length; p++)
     {
-      for (auto& l : v.obj.links)
+      for (auto& l : vertices_[p].obj.links)
       {
-        vertices_[l.objidx].incoming_edges++;
+        vertices_[l.objidx].parents.push (p);
       }
     }
 
-    edge_count_invalid = false;
+    parents_invalid = false;
   }
 
   /*
@@ -515,23 +812,25 @@
     hb_priority_queue_t queue;
     queue.insert (0, vertices_.length - 1);
 
-    hb_set_t visited;
+    hb_vector_t<bool> visited;
+    visited.resize (vertices_.length);
 
     while (!queue.in_error () && !queue.is_empty ())
     {
       unsigned next_idx = queue.pop_minimum ().second;
-      if (visited.has (next_idx)) continue;
+      if (visited[next_idx]) continue;
       const auto& next = vertices_[next_idx];
       int64_t next_distance = vertices_[next_idx].distance;
-      visited.add (next_idx);
+      visited[next_idx] = true;
 
       for (const auto& link : next.obj.links)
       {
-        if (visited.has (link.objidx)) continue;
+        if (visited[link.objidx]) continue;
 
         const auto& child = vertices_[link.objidx].obj;
-        int64_t child_weight = child.tail - child.head +
-                               ((int64_t) 1 << (link.width * 8));
+        unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
+        int64_t child_weight = (child.tail - child.head) +
+                               ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
         int64_t child_distance = next_distance + child_weight;
 
         if (child_distance < vertices_[link.objidx].distance)
@@ -545,7 +844,7 @@
     check_success (!queue.in_error ());
     if (!check_success (queue.is_empty ()))
     {
-      DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected.");
+      print_orphaned_nodes ();
       return;
     }
 
@@ -576,6 +875,10 @@
   bool is_valid_offset (int64_t offset,
                         const hb_serialize_context_t::object_t::link_t& link) const
   {
+    if (unlikely (!link.width))
+      // Virtual links can't overflow.
+      return link.is_signed || offset >= 0;
+
     if (link.is_signed)
     {
       if (link.width == 4)
@@ -595,13 +898,50 @@
   }
 
   /*
+   * Updates a link in the graph to point to a different object. Corrects the
+   * parents vector on the previous and new child nodes.
+   */
+  void reassign_link (hb_serialize_context_t::object_t::link_t& link,
+                      unsigned parent_idx,
+                      unsigned new_idx)
+  {
+    unsigned old_idx = link.objidx;
+    link.objidx = new_idx;
+    vertices_[old_idx].remove_parent (parent_idx);
+    vertices_[new_idx].parents.push (parent_idx);
+  }
+
+  /*
+   * Updates all objidx's in all links using the provided mapping. Corrects incoming edge counts.
+   */
+  template<typename Iterator, hb_requires (hb_is_iterator (Iterator))>
+  void remap_obj_indices (const hb_hashmap_t<unsigned, unsigned>& id_map,
+                          Iterator subgraph,
+                          bool only_wide = false)
+  {
+    if (!id_map) return;
+    for (unsigned i : subgraph)
+    {
+      for (unsigned j = 0; j < vertices_[i].obj.links.length; j++)
+      {
+        auto& link = vertices_[i].obj.links[j];
+        if (!id_map.has (link.objidx)) continue;
+        if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
+
+        reassign_link (link, i, id_map[link.objidx]);
+      }
+    }
+  }
+
+  /*
    * Updates all objidx's in all links using the provided mapping.
    */
-  void remap_obj_indices (const hb_vector_t<unsigned>& id_map,
-                          hb_vector_t<vertex_t>* sorted_graph) const
+  void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
+                              hb_vector_t<vertex_t>* sorted_graph) const
   {
     for (unsigned i = 0; i < sorted_graph->length; i++)
     {
+      (*sorted_graph)[i].remap_parents (id_map);
       for (unsigned j = 0; j < (*sorted_graph)[i].obj.links.length; j++)
       {
         auto& link = (*sorted_graph)[i].obj.links[j];
@@ -631,6 +971,9 @@
   {
     switch (link.width)
     {
+    case 0:
+      // Virtual links aren't serialized.
+      return;
     case 4:
       if (link.is_signed)
       {
@@ -656,18 +999,121 @@
     }
   }
 
+  /*
+   * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped.
+   * For this search the graph is treated as being undirected.
+   *
+   * Connected targets will be added to connected and removed from targets. All visited nodes
+   * will be added to visited.
+   */
+  void find_connected_nodes (unsigned start_idx,
+                             hb_set_t& targets,
+                             hb_set_t& visited,
+                             hb_set_t& connected)
+  {
+    if (visited.has (start_idx)) return;
+    visited.add (start_idx);
+
+    if (targets.has (start_idx))
+    {
+      targets.del (start_idx);
+      connected.add (start_idx);
+    }
+
+    const auto& v = vertices_[start_idx];
+
+    // Graph is treated as undirected so search children and parents of start_idx
+    for (const auto& l : v.obj.links)
+      find_connected_nodes (l.objidx, targets, visited, connected);
+
+    for (unsigned p : v.parents)
+      find_connected_nodes (p, targets, visited, connected);
+  }
+
  public:
   // TODO(garretrieger): make private, will need to move most of offset overflow code into graph.
   hb_vector_t<vertex_t> vertices_;
  private:
-  hb_vector_t<clone_buffer_t> clone_buffers_;
-  bool edge_count_invalid;
+  bool parents_invalid;
   bool distance_invalid;
   bool positions_invalid;
   bool successful;
+  hb_vector_t<unsigned> num_roots_for_space_;
 };
 
+static bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows,
+                                      graph_t& sorted_graph)
+{
+  for (int i = overflows.length - 1; i >= 0; i--)
+  {
+    const graph_t::overflow_record_t& r = overflows[i];
+    unsigned root = 0;
+    unsigned space = sorted_graph.space_for (r.parent, &root);
+    if (!space) continue;
+    if (sorted_graph.num_roots_for_space (space) <= 1) continue;
 
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "Overflow in space %d moving subgraph %d to space %d.",
+               space,
+               root,
+               sorted_graph.next_space ());
+
+    hb_set_t roots;
+    roots.add (root);
+    sorted_graph.isolate_subgraph (roots);
+    for (unsigned new_root : roots)
+      sorted_graph.move_to_new_space (new_root);
+    return true;
+  }
+  return false;
+}
+
+static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows,
+                                hb_set_t& priority_bumped_parents,
+                                graph_t& sorted_graph)
+{
+  bool resolution_attempted = false;
+
+  // Try resolving the furthest overflows first.
+  for (int i = overflows.length - 1; i >= 0; i--)
+  {
+    const graph_t::overflow_record_t& r = overflows[i];
+    const auto& child = sorted_graph.vertices_[r.child];
+    if (child.is_shared ())
+    {
+      // The child object is shared, we may be able to eliminate the overflow
+      // by duplicating it.
+      if (!sorted_graph.duplicate (r.parent, r.child)) continue;
+      return true;
+    }
+
+    if (child.is_leaf () && !priority_bumped_parents.has (r.parent))
+    {
+      // This object is too far from it's parent, attempt to move it closer.
+      //
+      // TODO(garretrieger): initially limiting this to leaf's since they can be
+      //                     moved closer with fewer consequences. However, this can
+      //                     likely can be used for non-leafs as well.
+      // TODO(garretrieger): add a maximum priority, don't try to raise past this.
+      // TODO(garretrieger): also try lowering priority of the parent. Make it
+      //                     get placed further up in the ordering, closer to it's children.
+      //                     this is probably preferable if the total size of the parent object
+      //                     is < then the total size of the children (and the parent can be moved).
+      //                     Since in that case moving the parent will cause a smaller increase in
+      //                     the length of other offsets.
+      sorted_graph.raise_childrens_priority (r.parent);
+      priority_bumped_parents.add (r.parent);
+      resolution_attempted = true;
+      continue;
+    }
+
+    // TODO(garretrieger): add additional offset resolution strategies
+    // - Promotion to extension lookups.
+    // - Table splitting.
+  }
+
+  return resolution_attempted;
+}
+
 /*
  * Attempts to modify the topological sorting of the provided object graph to
  * eliminate offset overflows in the links between objects of the graph. If a
@@ -677,10 +1123,15 @@
  * If necessary the structure of the graph may be modified in ways that do not
  * affect the functionality of the graph. For example shared objects may be
  * duplicated.
+ *
+ * For a detailed writeup describing how the algorithm operates see:
+ * docs/repacker.md
  */
 inline void
 hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed,
-                      hb_serialize_context_t* c) {
+                      hb_tag_t table_tag,
+                      hb_serialize_context_t* c,
+                      unsigned max_rounds = 10) {
   // Kahn sort is ~twice as fast as shortest distance sort and works for many fonts
   // so try it first to save time.
   graph_t sorted_graph (packed);
@@ -693,68 +1144,36 @@
 
   sorted_graph.sort_shortest_distance ();
 
+  if ((table_tag == HB_OT_TAG_GPOS
+       ||  table_tag == HB_OT_TAG_GSUB)
+      && sorted_graph.will_overflow ())
+  {
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs.");
+    if (sorted_graph.assign_32bit_spaces ())
+      sorted_graph.sort_shortest_distance ();
+  }
+
   unsigned round = 0;
   hb_vector_t<graph_t::overflow_record_t> overflows;
   // TODO(garretrieger): select a good limit for max rounds.
   while (!sorted_graph.in_error ()
          && sorted_graph.will_overflow (&overflows)
-         && round++ < 10) {
-    DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Over flow resolution round %d ===", round);
+         && round++ < max_rounds) {
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Overflow resolution round %d ===", round);
     sorted_graph.print_overflows (overflows);
 
-    bool resolution_attempted = false;
     hb_set_t priority_bumped_parents;
-    // Try resolving the furthest overflows first.
-    for (int i = overflows.length - 1; i >= 0; i--)
+
+    if (!_try_isolating_subgraphs (overflows, sorted_graph))
     {
-      const graph_t::overflow_record_t& r = overflows[i];
-      const auto& child = sorted_graph.vertices_[r.link->objidx];
-      if (child.is_shared ())
+      if (!_process_overflows (overflows, priority_bumped_parents, sorted_graph))
       {
-        // The child object is shared, we may be able to eliminate the overflow
-        // by duplicating it.
-        sorted_graph.duplicate (r.parent, r.link->objidx);
-        resolution_attempted = true;
-
-        // Stop processing overflows for this round so that object order can be
-        // updated to account for the newly added object.
+        DEBUG_MSG (SUBSET_REPACK, nullptr, "No resolution available :(");
         break;
       }
-
-      if (child.is_leaf () && !priority_bumped_parents.has (r.parent))
-      {
-        // This object is too far from it's parent, attempt to move it closer.
-        //
-        // TODO(garretrieger): initially limiting this to leaf's since they can be
-        //                     moved closer with fewer consequences. However, this can
-        //                     likely can be used for non-leafs as well.
-        // TODO(garretrieger): add a maximum priority, don't try to raise past this.
-        // TODO(garretrieger): also try lowering priority of the parent. Make it
-        //                     get placed further up in the ordering, closer to it's children.
-        //                     this is probably preferable if the total size of the parent object
-        //                     is < then the total size of the children (and the parent can be moved).
-        //                     Since in that case moving the parent will cause a smaller increase in
-        //                     the length of other offsets.
-        sorted_graph.raise_childrens_priority (r.parent);
-        priority_bumped_parents.add (r.parent);
-        resolution_attempted = true;
-        continue;
-      }
-
-      // TODO(garretrieger): add additional offset resolution strategies
-      // - Promotion to extension lookups.
-      // - Table splitting.
     }
 
-    if (resolution_attempted)
-    {
-      sorted_graph.sort_shortest_distance ();
-      continue;
-    }
-
-    DEBUG_MSG (SUBSET_REPACK, nullptr, "No resolution available :(");
-    c->err (HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
-    return;
+    sorted_graph.sort_shortest_distance ();
   }
 
   if (sorted_graph.in_error ())
@@ -762,8 +1181,14 @@
     c->err (HB_SERIALIZE_ERROR_OTHER);
     return;
   }
+
+  if (sorted_graph.will_overflow ())
+  {
+    c->err (HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed.");
+    return;
+  }
   sorted_graph.serialize (c);
 }
 
-
 #endif /* HB_REPACKER_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -145,14 +145,14 @@
   private:
   template <typename T, typename ...Ts> auto
   _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
-  ( obj.sanitize (this, hb_forward<Ts> (ds)...) )
+  ( obj.sanitize (this, std::forward<Ts> (ds)...) )
   template <typename T, typename ...Ts> auto
   _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
-  ( obj.dispatch (this, hb_forward<Ts> (ds)...) )
+  ( obj.dispatch (this, std::forward<Ts> (ds)...) )
   public:
   template <typename T, typename ...Ts> auto
   dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
-  ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) )
+  ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
 
 
   void init (hb_blob_t *b)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -189,8 +189,8 @@
   { return check_success (!hb_deref (obj).in_error ()); }
 
   template <typename T1, typename... Ts> bool propagate_error (T1 &&o1, Ts&&... os)
-  { return propagate_error (hb_forward<T1> (o1)) &&
-	   propagate_error (hb_forward<Ts> (os)...); }
+  { return propagate_error (std::forward<T1> (o1)) &&
+	   propagate_error (std::forward<Ts> (os)...); }
 
   /* To be called around main operation. */
   template <typename Type>
@@ -358,6 +358,35 @@
       assert (packed.tail ()->head == tail);
   }
 
+  // Adds a virtual link from the current object to objidx. A virtual link is not associated with
+  // an actual offset field. They are solely used to enforce ordering constraints between objects.
+  // Adding a virtual link from object a to object b will ensure that object b is always packed after
+  // object a in the final serialized order.
+  //
+  // This is useful in certain situtations where there needs to be a specific ordering in the
+  // final serialization. Such as when platform bugs require certain orderings, or to provide
+  //  guidance to the repacker for better offset overflow resolution.
+  void add_virtual_link (objidx_t objidx)
+  {
+    if (unlikely (in_error ())) return;
+
+    if (!objidx)
+      return;
+
+    assert (current);
+
+    auto& link = *current->links.push ();
+    if (current->links.in_error ())
+      err (HB_SERIALIZE_ERROR_OTHER);
+
+    link.width = 0;
+    link.objidx = objidx;
+    link.is_signed = 0;
+    link.whence = 0;
+    link.position = 0;
+    link.bias = 0;
+  }
+
   template <typename T>
   void add_link (T &ofs, objidx_t objidx,
 		 whence_t whence = Head,
@@ -376,11 +405,22 @@
       err (HB_SERIALIZE_ERROR_OTHER);
 
     link.width = sizeof (T);
-    link.is_signed = hb_is_signed (hb_unwrap_type (T));
+    link.objidx = objidx;
+    if (unlikely (!sizeof (T)))
+    {
+      // This link is not associated with an actual offset and exists merely to enforce
+      // an ordering constraint.
+      link.is_signed = 0;
+      link.whence = 0;
+      link.position = 0;
+      link.bias = 0;
+      return;
+    }
+
+    link.is_signed = std::is_signed<hb_unwrap_type (T)>::value;
     link.whence = (unsigned) whence;
     link.position = (const char *) &ofs - current->head;
     link.bias = bias;
-    link.objidx = objidx;
   }
 
   unsigned to_bias (const void *base) const
@@ -402,6 +442,8 @@
     for (const object_t* parent : ++hb_iter (packed))
       for (const object_t::link_t &link : parent->links)
       {
+        if (unlikely (!link.width)) continue; // Don't need to resolve virtual offsets
+
 	const object_t* child = packed[link.objidx];
 	if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; }
 	unsigned offset = 0;
@@ -494,7 +536,7 @@
 
   template <typename Type, typename ...Ts> auto
   _copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
-  (Type *, src.copy (this, hb_forward<Ts> (ds)...))
+  (Type *, src.copy (this, std::forward<Ts> (ds)...))
 
   template <typename Type> auto
   _copy (const Type &src, hb_priority<0>) -> decltype (&(hb_declval<Type> () = src))
@@ -509,16 +551,16 @@
    * instead of memcpy(). */
   template <typename Type, typename ...Ts>
   Type *copy (const Type &src, Ts&&... ds)
-  { return _copy (src, hb_prioritize, hb_forward<Ts> (ds)...); }
+  { return _copy (src, hb_prioritize, std::forward<Ts> (ds)...); }
   template <typename Type, typename ...Ts>
   Type *copy (const Type *src, Ts&&... ds)
-  { return copy (*src, hb_forward<Ts> (ds)...); }
+  { return copy (*src, std::forward<Ts> (ds)...); }
 
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator)),
 	   typename ...Ts>
   void copy_all (Iterator it, Ts&&... ds)
-  { for (decltype (*it) _ : it) copy (_, hb_forward<Ts> (ds)...); }
+  { for (decltype (*it) _ : it) copy (_, std::forward<Ts> (ds)...); }
 
   template <typename Type>
   hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
@@ -546,10 +588,10 @@
 
   template <typename Type, typename ...Ts>
   Type *extend (Type *obj, Ts&&... ds)
-  { return extend_size (obj, obj->get_size (hb_forward<Ts> (ds)...)); }
+  { return extend_size (obj, obj->get_size (std::forward<Ts> (ds)...)); }
   template <typename Type, typename ...Ts>
   Type *extend (Type &obj, Ts&&... ds)
-  { return extend (hb_addressof (obj), hb_forward<Ts> (ds)...); }
+  { return extend (hb_addressof (obj), std::forward<Ts> (ds)...); }
 
   /* Output routines. */
   hb_bytes_t copy_bytes () const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -168,15 +168,17 @@
  * There is not much science to this: it's a result of intuition
  * and testing.
  */
-typedef hb_set_digest_combiner_t
-<
-  hb_set_digest_lowest_bits_t<unsigned long, 4>,
+using hb_set_digest_t =
   hb_set_digest_combiner_t
   <
-    hb_set_digest_lowest_bits_t<unsigned long, 0>,
-    hb_set_digest_lowest_bits_t<unsigned long, 9>
+    hb_set_digest_lowest_bits_t<unsigned long, 4>,
+    hb_set_digest_combiner_t
+    <
+      hb_set_digest_lowest_bits_t<unsigned long, 0>,
+      hb_set_digest_lowest_bits_t<unsigned long, 9>
+    >
   >
-> hb_set_digest_t;
+;
 
 
 #endif /* HB_SET_DIGEST_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -42,10 +42,23 @@
   ~hb_sparseset_t () { fini (); }
 
   hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); }
-  void operator= (const hb_sparseset_t& other) { set (other); }
-  // TODO Add move construtor/assign
-  // TODO Add constructor for Iterator
+  hb_sparseset_t (hb_sparseset_t&& other) : hb_sparseset_t () { s = std::move (other.s); }
+  hb_sparseset_t& operator= (const hb_sparseset_t& other) { set (other); return *this; }
+  hb_sparseset_t& operator= (hb_sparseset_t&& other) { hb_swap (*this, other); return *this; }
+  friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) { hb_swap (a.s, b.s); }
 
+  hb_sparseset_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t ()
+  {
+    for (auto&& item : lst)
+      add (item);
+  }
+  template <typename Iterable,
+	    hb_requires (hb_is_iterable (Iterable))>
+  hb_sparseset_t (const Iterable &o) : hb_sparseset_t ()
+  {
+    hb_copy (o, *this);
+  }
+
   void init_shallow () { s.init (); }
   void init ()
   {
@@ -140,7 +153,18 @@
   operator iter_t () const { return iter (); }
 };
 
-struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t> {};
+struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t>
+{
+  hb_set_t () = default;
+  ~hb_set_t () = default;
+  hb_set_t (hb_set_t& o) = default;
+  hb_set_t& operator= (const hb_set_t& other) = default;
+  hb_set_t& operator= (hb_set_t&& other) = default;
+  hb_set_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t<hb_bit_set_invertible_t> (lst) {}
+  template <typename Iterable,
+	    hb_requires (hb_is_iterable (Iterable))>
+  hb_set_t (const Iterable &o) : hb_sparseset_t<hb_bit_set_invertible_t> (o) {}
+};
 
 static_assert (hb_set_t::INVALID == HB_SET_VALUE_INVALID, "");
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -113,7 +113,9 @@
   case HB_STYLE_TAG_WIDTH:
     return face->table.OS2->has_data ()
 	   ? face->table.OS2->get_width ()
-	   : (face->table.head->is_condensed () ? 75 : 100);
+	   : (face->table.head->is_condensed () ? 75 :
+	      face->table.head->is_expanded () ? 125 :
+	      100);
   case HB_STYLE_TAG_WEIGHT:
     return face->table.OS2->has_data ()
 	   ? face->table.OS2->usWeightClass

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -42,17 +42,19 @@
 {
   hb_object_header_t header;
 
+  struct sets_t {
+    hb_set_t *glyphs;
+    hb_set_t *unicodes;
+    hb_set_t *no_subset_tables;
+    hb_set_t *drop_tables;
+    hb_set_t *name_ids;
+    hb_set_t *name_languages;
+    hb_set_t *layout_features;
+  };
+
   union {
-    struct {
-      hb_set_t *glyphs;
-      hb_set_t *unicodes;
-      hb_set_t *no_subset_tables;
-      hb_set_t *drop_tables;
-      hb_set_t *name_ids;
-      hb_set_t *name_languages;
-      hb_set_t *layout_features;
-    } sets;
-    hb_set_t* set_ptrs[sizeof (sets) / sizeof (hb_set_t*)];
+    sets_t sets;
+    hb_set_t* set_ptrs[sizeof (sets_t) / sizeof (hb_set_t*)];
   };
 
   unsigned flags;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -38,6 +38,7 @@
 #include "hb-ot-color-colrv1-closure.hh"
 #include "hb-ot-var-fvar-table.hh"
 #include "hb-ot-stat-table.hh"
+#include "hb-ot-math-table.hh"
 
 
 typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map;
@@ -221,7 +222,51 @@
   cmap.fini ();
 }
 
+static void _colr_closure (hb_face_t *face,
+                           hb_map_t *layers_map,
+                           hb_map_t *palettes_map,
+                           hb_set_t *glyphs_colred)
+{
+  OT::COLR::accelerator_t colr;
+  colr.init (face);
+  if (!colr.is_valid ()) return;
+
+  unsigned iteration_count = 0;
+  hb_set_t palette_indices, layer_indices;
+  unsigned glyphs_num;
+  {
+    glyphs_num = glyphs_colred->get_population ();
+
+    // Collect all glyphs referenced by COLRv0
+    hb_set_t glyphset_colrv0;
+    for (hb_codepoint_t gid : glyphs_colred->iter ())
+      colr.closure_glyphs (gid, &glyphset_colrv0);
+    
+    glyphs_colred->union_ (glyphset_colrv0);
+    
+    //closure for COLRv1
+    colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices);
+  } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
+           glyphs_num != glyphs_colred->get_population ());
+
+  colr.closure_V0palette_indices (glyphs_colred, &palette_indices);
+  _remap_indexes (&layer_indices, layers_map);
+  _remap_palette_indexes (&palette_indices, palettes_map);
+  colr.fini ();
+}
+
 static inline void
+_math_closure (hb_face_t           *face,
+               hb_set_t            *glyphset)
+{
+  hb_blob_ptr_t<OT::MATH> math = hb_sanitize_context_t ().reference_table<OT::MATH> (face);
+  if (math->has_data ())
+    math->closure_glyphs (glyphset);
+  math.destroy ();
+}
+
+
+static inline void
 _remove_invalid_gids (hb_set_t *glyphs,
 		      unsigned int num_glyphs)
 {
@@ -301,12 +346,10 @@
 #ifndef HB_NO_SUBSET_CFF
   OT::cff1::accelerator_t cff;
 #endif
-  OT::COLR::accelerator_t colr;
   glyf.init (plan->source);
 #ifndef HB_NO_SUBSET_CFF
   cff.init (plan->source);
 #endif
-  colr.init (plan->source);
 
   plan->_glyphset_gsub->add (0); // Not-def
 
@@ -334,30 +377,17 @@
 #endif
   _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
 
-  // Collect all glyphs referenced by COLRv0
-  hb_set_t* cur_glyphset = plan->_glyphset_gsub;
-  hb_set_t glyphset_colrv0;
-  if (colr.is_valid ())
-  {
-    glyphset_colrv0.union_ (*cur_glyphset);
-    for (hb_codepoint_t gid : cur_glyphset->iter ())
-      colr.closure_glyphs (gid, &glyphset_colrv0);
-    cur_glyphset = &glyphset_colrv0;
-  }
+  hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub);
+  _math_closure (plan->source, plan->_glyphset_mathed);
+  _remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ());
 
-  hb_set_t palette_indices;
-  colr.closure_V0palette_indices (cur_glyphset, &palette_indices);
+  hb_set_t cur_glyphset = *plan->_glyphset_mathed;
+  _colr_closure (plan->source, plan->colrv1_layers, plan->colr_palettes, &cur_glyphset);
+  _remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ());
 
-  hb_set_t layer_indices;
-  colr.closure_forV1 (cur_glyphset, &layer_indices, &palette_indices);
-  _remap_indexes (&layer_indices, plan->colrv1_layers);
-  _remap_palette_indexes (&palette_indices, plan->colr_palettes);
-  colr.fini ();
-  _remove_invalid_gids (cur_glyphset, plan->source->get_num_glyphs ());
-
   // Populate a full set of glyphs to retain by adding all referenced
   // composite glyphs.
-  for (hb_codepoint_t gid : cur_glyphset->iter ())
+  for (hb_codepoint_t gid : cur_glyphset.iter ())
   {
     glyf.add_gid_and_children (gid, plan->_glyphset);
 #ifndef HB_NO_SUBSET_CFF
@@ -468,6 +498,7 @@
 
   plan->_glyphset = hb_set_create ();
   plan->_glyphset_gsub = hb_set_create ();
+  plan->_glyphset_mathed = hb_set_create ();
   plan->codepoint_to_glyph = hb_map_create ();
   plan->glyph_map = hb_map_create ();
   plan->reverse_glyph_map = hb_map_create ();
@@ -535,6 +566,7 @@
   hb_map_destroy (plan->reverse_glyph_map);
   hb_set_destroy (plan->_glyphset);
   hb_set_destroy (plan->_glyphset_gsub);
+  hb_set_destroy (plan->_glyphset_mathed);
   hb_map_destroy (plan->gsub_lookups);
   hb_map_destroy (plan->gpos_lookups);
   hb_map_destroy (plan->gsub_features);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -77,6 +77,7 @@
   unsigned int _num_output_glyphs;
   hb_set_t *_glyphset;
   hb_set_t *_glyphset_gsub;
+  hb_set_t *_glyphset_mathed;
 
   //active lookups we'd like to retain
   hb_map_t *gsub_lookups;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -52,6 +52,7 @@
 #include "hb-ot-layout-gpos-table.hh"
 #include "hb-ot-var-gvar-table.hh"
 #include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-math-table.hh"
 #include "hb-repacker.hh"
 
 /**
@@ -109,7 +110,7 @@
     return nullptr;
 
   hb_serialize_context_t repacked ((void *) buf, buf_size);
-  hb_resolve_overflows (c.object_graph (), &repacked);
+  hb_resolve_overflows (c.object_graph (), tag, &repacked);
 
   if (unlikely (repacked.in_error ()))
     // TODO(garretrieger): refactor so we can share the resize/retry logic with the subset
@@ -305,6 +306,7 @@
   case HB_OT_TAG_CPAL: return _subset<const OT::CPAL> (plan);
   case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan);
   case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */
+  case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan);
 
 #ifndef HB_NO_SUBSET_CFF
   case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -45,14 +45,14 @@
   private:
   template <typename T, typename ...Ts> auto
   _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
-  ( obj.subset (this, hb_forward<Ts> (ds)...) )
+  ( obj.subset (this, std::forward<Ts> (ds)...) )
   template <typename T, typename ...Ts> auto
   _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
-  ( obj.dispatch (this, hb_forward<Ts> (ds)...) )
+  ( obj.dispatch (this, std::forward<Ts> (ds)...) )
   public:
   template <typename T, typename ...Ts> auto
   dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
-  ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) )
+  ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
 
   hb_blob_t *source_blob;
   hb_subset_plan_t *plan;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -121,7 +121,7 @@
   static hb_bool_t
   is_variation_selector (hb_codepoint_t unicode)
   {
-    /* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the
+    /* U+180B..180D, U+180F MONGOLIAN FREE VARIATION SELECTORs are handled in the
      * Arabic shaper.  No need to match them here. */
     return unlikely (hb_in_ranges<hb_codepoint_t> (unicode,
 						   0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */
@@ -136,7 +136,7 @@
    * As such, we make exceptions for those four.
    * Also ignoring U+1BCA0..1BCA3. https://github.com/harfbuzz/harfbuzz/issues/503
    *
-   * Unicode 7.0:
+   * Unicode 14.0:
    * $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
    * 00AD          # Cf       SOFT HYPHEN
    * 034F          # Mn       COMBINING GRAPHEME JOINER
@@ -145,6 +145,7 @@
    * 17B4..17B5    # Mn   [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
    * 180B..180D    # Mn   [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
    * 180E          # Cf       MONGOLIAN VOWEL SEPARATOR
+   * 180F          # Mn       MONGOLIAN FREE VARIATION SELECTOR FOUR
    * 200B..200F    # Cf   [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
    * 202A..202E    # Cf   [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
    * 2060..2064    # Cf   [5] WORD JOINER..INVISIBLE PLUS

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -38,10 +38,23 @@
   typedef Type item_t;
   static constexpr unsigned item_size = hb_static_size (Type);
 
-  hb_vector_t ()  { init (); }
-  hb_vector_t (const hb_vector_t &o)
+  hb_vector_t () = default;
+  hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t ()
   {
-    init ();
+    alloc (lst.size ());
+    for (auto&& item : lst)
+      push (item);
+  }
+  template <typename Iterable,
+	    hb_requires (hb_is_iterable (Iterable))>
+  hb_vector_t (const Iterable &o) : hb_vector_t ()
+  {
+    if (hb_iter (o).is_random_access_iterator)
+      alloc (hb_len (hb_iter (o)));
+    hb_copy (o, *this);
+  }
+  hb_vector_t (const hb_vector_t &o) : hb_vector_t ()
+  {
     alloc (o.length);
     hb_copy (o, *this);
   }
@@ -55,11 +68,11 @@
   ~hb_vector_t () { fini (); }
 
   private:
-  int allocated; /* == -1 means allocation failed. */
+  int allocated = 0; /* == -1 means allocation failed. */
   public:
-  unsigned int length;
+  unsigned int length = 0;
   public:
-  Type *arrayZ;
+  Type *arrayZ = nullptr;
 
   void init ()
   {
@@ -87,6 +100,13 @@
     resize (0);
   }
 
+  friend void swap (hb_vector_t& a, hb_vector_t& b)
+  {
+    hb_swap (a.allocated, b.allocated);
+    hb_swap (a.length, b.length);
+    hb_swap (a.arrayZ, b.arrayZ);
+  }
+
   hb_vector_t& operator = (const hb_vector_t &o)
   {
     reset ();
@@ -96,11 +116,7 @@
   }
   hb_vector_t& operator = (hb_vector_t &&o)
   {
-    fini ();
-    allocated = o.allocated;
-    length = o.length;
-    arrayZ = o.arrayZ;
-    o.init ();
+    hb_swap (*this, o);
     return *this;
   }
 
@@ -134,7 +150,7 @@
 
   /* Sink interface. */
   template <typename T>
-  hb_vector_t& operator << (T&& v) { push (hb_forward<T> (v)); return *this; }
+  hb_vector_t& operator << (T&& v) { push (std::forward<T> (v)); return *this; }
 
   hb_array_t<      Type> as_array ()       { return hb_array (arrayZ, length); }
   hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); }
@@ -182,7 +198,7 @@
       // the created copy to leak memory since we won't have stored a
       // reference to it.
       return p;
-    *p = hb_forward<T> (v);
+    *p = std::forward<T> (v);
     return p;
   }
 
@@ -239,7 +255,7 @@
   Type pop ()
   {
     if (!length) return Null (Type);
-    return hb_move (arrayZ[--length]); /* Does this move actually work? */
+    return std::move (arrayZ[--length]); /* Does this move actually work? */
   }
 
   void remove (unsigned int i)
@@ -295,6 +311,19 @@
 template <typename Type>
 struct hb_sorted_vector_t : hb_vector_t<Type>
 {
+  hb_sorted_vector_t () = default;
+  ~hb_sorted_vector_t () = default;
+  hb_sorted_vector_t (hb_sorted_vector_t& o) = default;
+  hb_sorted_vector_t (hb_sorted_vector_t &&o) = default;
+  hb_sorted_vector_t (std::initializer_list<Type> lst) : hb_vector_t<Type> (lst) {}
+  template <typename Iterable,
+	    hb_requires (hb_is_iterable (Iterable))>
+  hb_sorted_vector_t (const Iterable &o) : hb_vector_t<Type> (o) {}
+  hb_sorted_vector_t& operator = (const hb_sorted_vector_t &o) = default;
+  hb_sorted_vector_t& operator = (hb_sorted_vector_t &&o) = default;
+  friend void swap (hb_sorted_vector_t& a, hb_sorted_vector_t& b)
+  { hb_swap ((hb_vector_t<Type>&) (a), (hb_vector_t<Type>&) (b)); }
+
   hb_sorted_array_t<      Type> as_array ()       { return hb_sorted_array (this->arrayZ, this->length); }
   hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2021-11-04 00:51:18 UTC (rev 60943)
@@ -62,6 +62,7 @@
 
 /* Error.  Should never happen. */
 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR
+#pragma GCC diagnostic error   "-Wbitwise-instead-of-logical"
 #pragma GCC diagnostic error   "-Wcast-align"
 #pragma GCC diagnostic error   "-Wcast-function-type"
 #pragma GCC diagnostic error   "-Wdelete-non-virtual-dtor"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2021-11-04 00:51:18 UTC (rev 60943)
@@ -147,6 +147,7 @@
   'hb-ot-tag-table.hh',
   'hb-ot-tag.cc',
   'hb-ot-var-avar-table.hh',
+  'hb-ot-var-common.hh',
   'hb-ot-var-fvar-table.hh',
   'hb-ot-var-gvar-table.hh',
   'hb-ot-var-hvar-table.hh',
@@ -345,7 +346,7 @@
 if conf.get('HAVE_GRAPHITE2', 0) == 1
   hb_sources += hb_graphite2_sources
   hb_headers += hb_graphite2_headers
-  harfbuzz_deps += [graphite2_dep]
+  harfbuzz_deps += [graphite2_dep, graphite_dep]
 endif
 
 if conf.get('HAVE_GLIB', 0) == 1
@@ -362,7 +363,6 @@
 if conf.get('HAVE_DIRECTWRITE', 0) == 1
   hb_sources += hb_directwrite_sources
   hb_headers += hb_directwrite_headers
-  harfbuzz_deps += directwrite_dep
   # hb-directwrite needs a C++ linker
   libharfbuzz_link_language = 'cpp'
 endif
@@ -488,10 +488,12 @@
     'test-repacker': ['test-repacker.cc', 'hb-static.cc'],
     'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'],
     'test-iter': ['test-iter.cc', 'hb-static.cc'],
-    'test-meta': ['test-meta.cc', 'hb-static.cc'],
+    'test-map': ['test-map.cc', 'hb-static.cc'],
     'test-number': ['test-number.cc', 'hb-number.cc'],
     'test-ot-tag': ['hb-ot-tag.cc'],
+    'test-set': ['test-set.cc', 'hb-static.cc'],
     'test-unicode-ranges': ['test-unicode-ranges.cc'],
+    'test-vector': ['test-vector.cc', 'hb-static.cc'],
     'test-bimap': ['test-bimap.cc', 'hb-static.cc'],
   }
   foreach name, source : compiled_tests

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -0,0 +1,102 @@
+/*
+ * Copyright © 2021  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+#include "hb.hh"
+#include "hb-map.hh"
+
+
+int
+main (int argc, char **argv)
+{
+
+  /* Test copy constructor. */
+  {
+    hb_map_t v1;
+    v1.set (1, 2);
+    hb_map_t v2 {v1};
+    assert (v1.get_population () == 1);
+    assert (v2.get_population () == 1);
+    assert (v1[1] == 2);
+    assert (v2[1] == 2);
+  }
+
+  /* Test copy assignment. */
+  {
+    hb_map_t v1;
+    v1.set (1, 2);
+    hb_map_t v2 = v1;
+    assert (v1.get_population () == 1);
+    assert (v2.get_population () == 1);
+    assert (v1[1] == 2);
+    assert (v2[1] == 2);
+  }
+
+  /* Test move constructor. */
+  {
+    hb_map_t v {hb_map_t {}};
+  }
+
+  /* Test move assignment. */
+  {
+    hb_map_t v;
+    v = hb_map_t {};
+  }
+
+  /* Test initializing from iterable. */
+  {
+    hb_map_t s;
+
+    s.set (1, 2);
+    s.set (3, 4);
+
+    hb_map_t v (s);
+
+    assert (v.get_population () == 2);
+  }
+
+  /* Test initializing from iterator. */
+  {
+    hb_map_t s;
+
+    s.set (1, 2);
+    s.set (3, 4);
+
+    hb_map_t v (hb_iter (s));
+
+    assert (v.get_population () == 2);
+  }
+
+  /* Test initializing from initializer list and swapping. */
+  {
+    using pair_t = hb_pair_t<hb_codepoint_t, hb_codepoint_t>;
+    hb_map_t v1 {pair_t{1,2}, pair_t{4,5}};
+    hb_map_t v2 {pair_t{3,4}};
+    hb_swap (v1, v2);
+    assert (v1.get_population () == 1);
+    assert (v2.get_population () == 2);
+  }
+
+  return 0;
+}

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -1,133 +0,0 @@
-/*
- * Copyright © 2019  Facebook, 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.
- *
- * Facebook Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-#include "hb-meta.hh"
-
-#include <type_traits>
-
-template <typename T> struct U { typedef T type; };
-
-int
-main (int argc, char **argv)
-{
-  static_assert (hb_is_convertible (void, void), "");
-  static_assert (hb_is_convertible (void, const void), "");
-  static_assert (hb_is_convertible (const void, void), "");
-
-  static_assert (hb_is_convertible (int,  int), "");
-  static_assert (hb_is_convertible (char, int), "");
-  static_assert (hb_is_convertible (long, int), "");
-
-  static_assert (hb_is_convertible (int, int), "");
-
-  static_assert (hb_is_convertible (const int, int), "");
-  static_assert (hb_is_convertible (int, const int), "");
-  static_assert (hb_is_convertible (const int, const int), "");
-
-  static_assert (hb_is_convertible (int&, int), "");
-  static_assert (!hb_is_convertible (int, int&), "");
-
-  static_assert (hb_is_convertible (int, const int&), "");
-  static_assert (!hb_is_convertible (const int, int&), "");
-  static_assert (hb_is_convertible (const int, const int&), "");
-  static_assert (hb_is_convertible (int&, const int), "");
-  static_assert (hb_is_convertible (const int&, int), "");
-  static_assert (hb_is_convertible (const int&, const int), "");
-  static_assert (hb_is_convertible (const int&, const int), "");
-
-  struct X {};
-  struct Y : X {};
-
-  static_assert (hb_is_convertible (const X &, const X), "");
-  static_assert (hb_is_convertible (X &, const X), "");
-  static_assert (hb_is_convertible (X &, const X &), "");
-  static_assert (hb_is_convertible (X, const X &), "");
-  static_assert (hb_is_convertible (const X, const X &), "");
-  static_assert (!hb_is_convertible (const X, X &), "");
-  static_assert (!hb_is_convertible (X, X &), "");
-  static_assert (hb_is_convertible (X &, X &), "");
-
-  static_assert (hb_is_convertible (int&, long), "");
-  static_assert (!hb_is_convertible (int&, long&), "");
-
-  static_assert (hb_is_convertible (int *, int *), "");
-  static_assert (hb_is_convertible (int *, const int *), "");
-  static_assert (!hb_is_convertible (const int *, int *), "");
-  static_assert (!hb_is_convertible (int *, long *), "");
-  static_assert (hb_is_convertible (int *, void *), "");
-  static_assert (!hb_is_convertible (void *, int *), "");
-
-  static_assert (hb_is_base_of (void, void), "");
-  static_assert (hb_is_base_of (void, int), "");
-  static_assert (!hb_is_base_of (int, void), "");
-
-  static_assert (hb_is_base_of (int, int), "");
-  static_assert (hb_is_base_of (const int, int), "");
-  static_assert (hb_is_base_of (int, const int), "");
-
-  static_assert (hb_is_base_of (X, X), "");
-  static_assert (hb_is_base_of (X, Y), "");
-  static_assert (hb_is_base_of (const X, Y), "");
-  static_assert (hb_is_base_of (X, const Y), "");
-  static_assert (!hb_is_base_of (Y, X), "");
-
-  static_assert (hb_is_constructible (int), "");
-  static_assert (hb_is_constructible (int, int), "");
-  static_assert (hb_is_constructible (int, char), "");
-  static_assert (hb_is_constructible (int, long), "");
-  static_assert (!hb_is_constructible (int, X), "");
-  static_assert (!hb_is_constructible (int, int, int), "");
-  static_assert (hb_is_constructible (X), "");
-  static_assert (!hb_is_constructible (X, int), "");
-  static_assert (hb_is_constructible (X, X), "");
-  static_assert (!hb_is_constructible (X, X, X), "");
-  static_assert (hb_is_constructible (X, Y), "");
-  static_assert (!hb_is_constructible (Y, X), "");
-
-  static_assert (hb_is_trivially_default_constructible (X), "");
-  static_assert (hb_is_trivially_default_constructible (Y), "");
-  static_assert (hb_is_trivially_copy_constructible (X), "");
-  static_assert (hb_is_trivially_copy_constructible (Y), "");
-  static_assert (hb_is_trivially_move_constructible (X), "");
-  static_assert (hb_is_trivially_move_constructible (Y), "");
-  static_assert (hb_is_trivially_destructible (Y), "");
-
-  static_assert (hb_is_trivially_copyable (int), "");
-  static_assert (hb_is_trivially_copyable (X), "");
-  static_assert (hb_is_trivially_copyable (Y), "");
-
-  static_assert (hb_is_trivial (int), "");
-  static_assert (hb_is_trivial (X), "");
-  static_assert (hb_is_trivial (Y), "");
-
-  static_assert (hb_is_signed (hb_unwrap_type (U<U<U<int>>>)), "");
-  static_assert (hb_is_unsigned (hb_unwrap_type (U<U<U<U<unsigned>>>>)), "");
-
-  /* TODO Add more meaningful tests. */
-
-  return 0;
-}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -56,6 +56,53 @@
   c->add_link (*offset, id);
 }
 
+static void add_wide_offset (unsigned id,
+                             hb_serialize_context_t* c)
+{
+  OT::Offset32* offset = c->start_embed<OT::Offset32> ();
+  c->extend_min (offset);
+  c->add_link (*offset, id);
+}
+
+static void run_resolve_overflow_test (const char* name,
+                                       hb_serialize_context_t& overflowing,
+                                       hb_serialize_context_t& expected,
+                                       unsigned num_iterations = 0)
+{
+  printf (">>> Testing overflowing resolution for %s\n",
+          name);
+
+  graph_t graph (overflowing.object_graph ());
+
+  unsigned buffer_size = overflowing.end - overflowing.start;
+  void* out_buffer = malloc (buffer_size);
+  hb_serialize_context_t out (out_buffer, buffer_size);
+
+  assert (overflowing.offset_overflow ());
+  hb_resolve_overflows (overflowing.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), &out, num_iterations);
+  assert (!out.offset_overflow ());
+  hb_bytes_t result = out.copy_bytes ();
+
+  assert (!expected.offset_overflow ());
+  hb_bytes_t expected_result = expected.copy_bytes ();
+
+  assert (result.length == expected_result.length);
+  for (unsigned i = 0; i < expected_result.length; i++)
+  {
+    assert (result[i] == expected_result[i]);
+  }
+
+  result.fini ();
+  expected_result.fini ();
+  free (out_buffer);
+}
+
+static void add_virtual_offset (unsigned id,
+                                hb_serialize_context_t* c)
+{
+  c->add_virtual_link (id);
+}
+
 static void
 populate_serializer_simple (hb_serialize_context_t* c)
 {
@@ -67,7 +114,7 @@
   start_object ("abc", 3, c);
   add_offset (obj_2, c);
   add_offset (obj_1, c);
-  c->pop_pack ();
+  c->pop_pack (false);
 
   c->end_serialize();
 }
@@ -86,7 +133,7 @@
   add_offset (obj_3, c);
   add_offset (obj_2, c);
   add_offset (obj_1, c);
-  c->pop_pack ();
+  c->pop_pack (false);
 
   c->end_serialize();
 }
@@ -112,6 +159,526 @@
 }
 
 static void
+populate_serializer_with_isolation_overflow (hb_serialize_context_t* c)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_4 = add_object ("4", 1, c);
+
+  start_object (large_string.c_str(), 60000, c);
+  add_offset (obj_4, c);
+  unsigned obj_3 = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 10000, c);
+  add_offset (obj_4, c);
+  unsigned obj_2 = c->pop_pack (false);
+
+  start_object ("1", 1, c);
+  add_wide_offset (obj_3, c);
+  add_offset (obj_2, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_with_isolation_overflow_complex (hb_serialize_context_t* c)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_f = add_object ("f", 1, c);
+
+  start_object ("e", 1, c);
+  add_offset (obj_f, c);
+  unsigned obj_e = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  start_object ("d", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 60000, c);
+  add_offset (obj_d, c);
+  unsigned obj_h = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 60000, c);
+  add_offset (obj_c, c);
+  add_offset (obj_h, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 10000, c);
+  add_offset (obj_d, c);
+  unsigned obj_g = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 11000, c);
+  add_offset (obj_d, c);
+  unsigned obj_i = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_wide_offset (obj_b, c);
+  add_offset (obj_g, c);
+  add_offset (obj_i, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_with_isolation_overflow_complex_expected (hb_serialize_context_t* c)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+
+  // space 1
+
+  unsigned obj_f_prime = add_object ("f", 1, c);
+
+  start_object ("e", 1, c);
+  add_offset (obj_f_prime, c);
+  unsigned obj_e_prime = c->pop_pack (false);
+
+  start_object ("d", 1, c);
+  add_offset (obj_e_prime, c);
+  unsigned obj_d_prime = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 60000, c);
+  add_offset (obj_d_prime, c);
+  unsigned obj_h = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_e_prime, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 60000, c);
+  add_offset (obj_c, c);
+  add_offset (obj_h, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  // space 0
+
+  unsigned obj_f = add_object ("f", 1, c);
+
+  start_object ("e", 1, c);
+  add_offset (obj_f, c);
+  unsigned obj_e = c->pop_pack (false);
+
+
+  start_object ("d", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 11000, c);
+  add_offset (obj_d, c);
+  unsigned obj_i = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 10000, c);
+  add_offset (obj_d, c);
+  unsigned obj_g = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_wide_offset (obj_b, c);
+  add_offset (obj_g, c);
+  add_offset (obj_i, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_with_isolation_overflow_spaces (hb_serialize_context_t* c)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_d = add_object ("f", 1, c);
+  unsigned obj_e = add_object ("f", 1, c);
+
+  start_object (large_string.c_str(), 60000, c);
+  add_offset (obj_d, c);
+  unsigned obj_b = c->pop_pack ();
+
+  start_object (large_string.c_str(), 60000, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack ();
+
+
+  start_object ("a", 1, c);
+  add_wide_offset (obj_b, c);
+  add_wide_offset (obj_c, c);
+  c->pop_pack ();
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_spaces (hb_serialize_context_t* c, bool with_overflow)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_i;
+
+  if (with_overflow)
+    obj_i = add_object ("i", 1, c);
+
+  // Space 2
+  unsigned obj_h = add_object ("h", 1, c);
+
+  start_object (large_string.c_str(), 30000, c);
+  add_offset (obj_h, c);
+  unsigned obj_e = c->pop_pack (false);
+
+  start_object ("b", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  // Space 1
+  if (!with_overflow)
+    obj_i = add_object ("i", 1, c);
+
+  start_object (large_string.c_str(), 30000, c);
+  add_offset (obj_i, c);
+  unsigned obj_g = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 30000, c);
+  add_offset (obj_i, c);
+  unsigned obj_f = c->pop_pack (false);
+
+  start_object ("d", 1, c);
+  add_offset (obj_g, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_f, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_wide_offset (obj_b, c);
+  add_wide_offset (obj_c, c);
+  add_wide_offset (obj_d, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_spaces_16bit_connection (hb_serialize_context_t* c)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_g = add_object ("g", 1, c);
+  unsigned obj_h = add_object ("h", 1, c);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_g, c);
+  unsigned obj_e = c->pop_pack (false);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_h, c);
+  unsigned obj_f = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  start_object ("d", 1, c);
+  add_offset (obj_f, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object ("b", 1, c);
+  add_offset (obj_e, c);
+  add_offset (obj_h, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_offset (obj_b, c);
+  add_wide_offset (obj_c, c);
+  add_wide_offset (obj_d, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_spaces_16bit_connection_expected (hb_serialize_context_t* c)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_g_prime = add_object ("g", 1, c);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_g_prime, c);
+  unsigned obj_e_prime = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_e_prime, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  unsigned obj_h_prime = add_object ("h", 1, c);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_h_prime, c);
+  unsigned obj_f = c->pop_pack (false);
+
+  start_object ("d", 1, c);
+  add_offset (obj_f, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  unsigned obj_g = add_object ("g", 1, c);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_g, c);
+  unsigned obj_e = c->pop_pack (false);
+
+  unsigned obj_h = add_object ("h", 1, c);
+
+  start_object ("b", 1, c);
+  add_offset (obj_e, c);
+  add_offset (obj_h, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_offset (obj_b, c);
+  add_wide_offset (obj_c, c);
+  add_wide_offset (obj_d, c);
+  c->pop_pack (false);
+
+  c->end_serialize ();
+}
+
+static void
+populate_serializer_short_and_wide_subgraph_root (hb_serialize_context_t* c)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_e = add_object ("e", 1, c);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_c, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object ("b", 1, c);
+  add_offset (obj_c, c);
+  add_offset (obj_e, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_offset (obj_b, c);
+  add_wide_offset (obj_c, c);
+  add_wide_offset (obj_d, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_short_and_wide_subgraph_root_expected (hb_serialize_context_t* c)
+{
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_e_prime = add_object ("e", 1, c);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_e_prime, c);
+  unsigned obj_c_prime = c->pop_pack (false);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_c_prime, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  unsigned obj_e = add_object ("e", 1, c);
+
+  start_object (large_string.c_str (), 40000, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack (false);
+
+
+  start_object ("b", 1, c);
+  add_offset (obj_c, c);
+  add_offset (obj_e, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_offset (obj_b, c);
+  add_wide_offset (obj_c_prime, c);
+  add_wide_offset (obj_d, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_with_split_spaces (hb_serialize_context_t* c)
+{
+  // Overflow needs to be resolved by splitting the single space
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_f = add_object ("f", 1, c);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f, c);
+  unsigned obj_e = c->pop_pack (false);
+
+  start_object ("b", 1, c);
+  add_offset (obj_d, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_wide_offset (obj_b, c);
+  add_wide_offset (obj_c, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_with_split_spaces_2 (hb_serialize_context_t* c)
+{
+  // Overflow needs to be resolved by splitting the single space
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_f = add_object ("f", 1, c);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f, c);
+  unsigned obj_e = c->pop_pack (false);
+
+  start_object ("b", 1, c);
+  add_offset (obj_d, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_offset (obj_b, c);
+  add_wide_offset (obj_b, c);
+  add_wide_offset (obj_c, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_with_split_spaces_expected (hb_serialize_context_t* c)
+{
+  // Overflow needs to be resolved by splitting the single space
+
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  unsigned obj_f_prime = add_object ("f", 1, c);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f_prime, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object ("b", 1, c);
+  add_offset (obj_d, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  unsigned obj_f = add_object ("f", 1, c);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f, c);
+  unsigned obj_e = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  start_object ("a", 1, c);
+  add_wide_offset (obj_b, c);
+  add_wide_offset (obj_c, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_with_split_spaces_expected_2 (hb_serialize_context_t* c)
+{
+  // Overflow needs to be resolved by splitting the single space
+
+  std::string large_string(70000, 'a');
+  c->start_serialize<char> ();
+
+  // Space 2
+
+  unsigned obj_f_double_prime = add_object ("f", 1, c);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f_double_prime, c);
+  unsigned obj_d_prime = c->pop_pack (false);
+
+  start_object ("b", 1, c);
+  add_offset (obj_d_prime, c);
+  unsigned obj_b_prime = c->pop_pack (false);
+
+  // Space 1
+
+  unsigned obj_f_prime = add_object ("f", 1, c);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f_prime, c);
+  unsigned obj_e = c->pop_pack (false);
+
+  start_object ("c", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack (false);
+
+  // Space 0
+
+  unsigned obj_f = add_object ("f", 1, c);
+
+  start_object (large_string.c_str(), 40000, c);
+  add_offset (obj_f, c);
+  unsigned obj_d = c->pop_pack (false);
+
+  start_object ("b", 1, c);
+  add_offset (obj_d, c);
+  unsigned obj_b = c->pop_pack (false);
+
+  // Root
+  start_object ("a", 1, c);
+  add_offset (obj_b, c);
+  add_wide_offset (obj_b_prime, c);
+  add_wide_offset (obj_c, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
 populate_serializer_complex_1 (hb_serialize_context_t* c)
 {
   c->start_serialize<char> ();
@@ -126,7 +693,7 @@
   start_object ("abc", 3, c);
   add_offset (obj_2, c);
   add_offset (obj_4, c);
-  c->pop_pack ();
+  c->pop_pack (false);
 
   c->end_serialize();
 }
@@ -152,7 +719,7 @@
   add_offset (obj_2, c);
   add_offset (obj_4, c);
   add_offset (obj_5, c);
-  c->pop_pack ();
+  c->pop_pack (false);
 
   c->end_serialize();
 }
@@ -182,6 +749,33 @@
   add_offset (obj_2, c);
   add_offset (obj_4, c);
   add_offset (obj_5, c);
+  c->pop_pack (false);
+
+  c->end_serialize();
+}
+
+static void
+populate_serializer_virtual_link (hb_serialize_context_t* c)
+{
+  c->start_serialize<char> ();
+
+  unsigned obj_d = add_object ("d", 1, c);
+
+  start_object ("b", 1, c);
+  add_offset (obj_d, c);
+  unsigned obj_b = c->pop_pack ();
+
+  start_object ("e", 1, c);
+  add_virtual_offset (obj_b, c);
+  unsigned obj_e = c->pop_pack();
+
+  start_object ("c", 1, c);
+  add_offset (obj_e, c);
+  unsigned obj_c = c->pop_pack ();
+
+  start_object ("a", 1, c);
+  add_offset (obj_b, c);
+  add_offset (obj_c, c);
   c->pop_pack ();
 
   c->end_serialize();
@@ -433,7 +1027,7 @@
   void* out_buffer = malloc (buffer_size);
   hb_serialize_context_t out (out_buffer, buffer_size);
 
-  hb_resolve_overflows (c.object_graph (), &out);
+  hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, &out);
   assert (!out.offset_overflow ());
   hb_bytes_t result = out.copy_bytes ();
   assert (result.length == (80000 + 3 + 3 * 2));
@@ -454,7 +1048,7 @@
   void* out_buffer = malloc (buffer_size);
   hb_serialize_context_t out (out_buffer, buffer_size);
 
-  hb_resolve_overflows (c.object_graph (), &out);
+  hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, &out);
   assert (!out.offset_overflow ());
   hb_bytes_t result = out.copy_bytes ();
   assert (result.length == (10000 + 2 * 2 + 60000 + 2 + 3 * 2));
@@ -464,8 +1058,196 @@
   free (out_buffer);
 }
 
+static void test_resolve_overflows_via_space_assignment ()
+{
+  size_t buffer_size = 160000;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_spaces (&c, true);
+
+  void* expected_buffer = malloc (buffer_size);
+  hb_serialize_context_t e (expected_buffer, buffer_size);
+  populate_serializer_spaces (&e, false);
+
+  run_resolve_overflow_test ("test_resolve_overflows_via_space_assignment",
+                             c,
+                             e);
+
+  free (buffer);
+  free (expected_buffer);
+}
+
+static void test_resolve_overflows_via_isolation ()
+{
+  size_t buffer_size = 160000;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_with_isolation_overflow (&c);
+  graph_t graph (c.object_graph ());
+
+  void* out_buffer = malloc (buffer_size);
+  hb_serialize_context_t out (out_buffer, buffer_size);
+
+  assert (c.offset_overflow ());
+  hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), &out, 0);
+  assert (!out.offset_overflow ());
+  hb_bytes_t result = out.copy_bytes ();
+  assert (result.length == (1 + 10000 + 60000 + 1 + 1
+                            + 4 + 3 * 2));
+
+  result.fini ();
+  free (buffer);
+  free (out_buffer);
+}
+
+static void test_resolve_overflows_via_isolation_with_recursive_duplication ()
+{
+  size_t buffer_size = 160000;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_with_isolation_overflow_complex (&c);
+
+  void* expected_buffer = malloc (buffer_size);
+  hb_serialize_context_t e (expected_buffer, buffer_size);
+  populate_serializer_with_isolation_overflow_complex_expected (&e);
+
+  run_resolve_overflow_test ("test_resolve_overflows_via_isolation_with_recursive_duplication",
+                             c,
+                             e);
+  free (buffer);
+  free (expected_buffer);
+}
+
+static void test_resolve_overflows_via_isolating_16bit_space ()
+{
+  size_t buffer_size = 160000;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_spaces_16bit_connection (&c);
+
+  void* expected_buffer = malloc (buffer_size);
+  hb_serialize_context_t e (expected_buffer, buffer_size);
+  populate_serializer_spaces_16bit_connection_expected (&e);
+
+  run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space",
+                             c,
+                             e);
+
+  free (buffer);
+  free (expected_buffer);
+}
+
+static void test_resolve_overflows_via_isolating_16bit_space_2 ()
+{
+  size_t buffer_size = 160000;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_short_and_wide_subgraph_root (&c);
+
+  void* expected_buffer = malloc (buffer_size);
+  hb_serialize_context_t e (expected_buffer, buffer_size);
+  populate_serializer_short_and_wide_subgraph_root_expected (&e);
+
+  run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space_2",
+                             c,
+                             e);
+
+  free (buffer);
+  free (expected_buffer);
+}
+
+static void test_resolve_overflows_via_isolation_spaces ()
+{
+  size_t buffer_size = 160000;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_with_isolation_overflow_spaces (&c);
+  graph_t graph (c.object_graph ());
+
+  void* out_buffer = malloc (buffer_size);
+  hb_serialize_context_t out (out_buffer, buffer_size);
+
+  assert (c.offset_overflow ());
+  hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), &out, 0);
+  assert (!out.offset_overflow ());
+  hb_bytes_t result = out.copy_bytes ();
+
+  unsigned expected_length = 3 + 2 * 60000; // objects
+  expected_length += 2 * 4 + 2 * 2; // links
+  assert (result.length == expected_length);
+
+  result.fini ();
+  free (buffer);
+  free (out_buffer);
+}
+
+static void test_resolve_overflows_via_splitting_spaces ()
+{
+  size_t buffer_size = 160000;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_with_split_spaces (&c);
+
+  void* expected_buffer = malloc (buffer_size);
+  hb_serialize_context_t e (expected_buffer, buffer_size);
+  populate_serializer_with_split_spaces_expected (&e);
+
+  run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces",
+                             c,
+                             e,
+                             1);
+
+  free (buffer);
+  free (expected_buffer);
+
+}
+
+static void test_resolve_overflows_via_splitting_spaces_2 ()
+{
+  size_t buffer_size = 160000;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_with_split_spaces_2 (&c);
+
+  void* expected_buffer = malloc (buffer_size);
+  hb_serialize_context_t e (expected_buffer, buffer_size);
+  populate_serializer_with_split_spaces_expected_2 (&e);
+
+  run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces_2",
+                             c,
+                             e,
+                             1);
+  free (buffer);
+  free (expected_buffer);
+}
+
+static void test_virtual_link ()
+{
+  size_t buffer_size = 100;
+  void* buffer = malloc (buffer_size);
+  hb_serialize_context_t c (buffer, buffer_size);
+  populate_serializer_virtual_link (&c);
+
+  void* out_buffer = malloc (buffer_size);
+  hb_serialize_context_t out (out_buffer, buffer_size);
+
+  hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, &out);
+  assert (!out.offset_overflow ());
+
+  hb_bytes_t result = out.copy_bytes ();
+  assert (result.length == 5 + 4 * 2);
+  assert (result[0]  == 'a');
+  assert (result[5]  == 'c');
+  assert (result[8]  == 'e');
+  assert (result[9]  == 'b');
+  assert (result[12] == 'd');
+
+  result.fini ();
+  free (buffer);
+  free (out_buffer);
+}
+
 // TODO(garretrieger): update will_overflow tests to check the overflows array.
-// TODO(garretrieger): add a test(s) using a real font.
 // TODO(garretrieger): add tests for priority raising.
 
 int
@@ -480,6 +1262,15 @@
   test_will_overflow_3 ();
   test_resolve_overflows_via_sort ();
   test_resolve_overflows_via_duplication ();
+  test_resolve_overflows_via_space_assignment ();
+  test_resolve_overflows_via_isolation ();
+  test_resolve_overflows_via_isolation_with_recursive_duplication ();
+  test_resolve_overflows_via_isolation_spaces ();
+  test_resolve_overflows_via_isolating_16bit_space ();
+  test_resolve_overflows_via_isolating_16bit_space_2 ();
+  test_resolve_overflows_via_splitting_spaces ();
+  test_resolve_overflows_via_splitting_spaces_2 ();
   test_duplicate_leaf ();
   test_duplicate_interior ();
+  test_virtual_link ();
 }

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2021  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+#include "hb.hh"
+#include "hb-set.hh"
+
+
+int
+main (int argc, char **argv)
+{
+
+  /* Test copy constructor. */
+  {
+    hb_set_t v1 {1, 2};
+    hb_set_t v2 {v1};
+    assert (v1.get_population () == 2);
+    assert (v2.get_population () == 2);
+  }
+
+  /* Test copy assignment. */
+  {
+    hb_set_t v1 {1, 2};
+    hb_set_t v2 = v1;
+    assert (v1.get_population () == 2);
+    assert (v2.get_population () == 2);
+  }
+
+  /* Test move constructor. */
+  {
+    hb_set_t v {hb_set_t {1, 2}};
+    assert (v.get_population () == 2);
+  }
+
+  /* Test move assignment. */
+  {
+    hb_set_t v;
+    v = hb_set_t {1, 2};
+    assert (v.get_population () == 2);
+  }
+
+  /* Test initializing from iterable. */
+  {
+    hb_set_t s;
+
+    s.add (18);
+    s.add (12);
+
+    hb_set_t v (s);
+
+    assert (v.get_population () == 2);
+  }
+
+  /* Test initializing from iterator. */
+  {
+    hb_set_t s;
+
+    s.add (18);
+    s.add (12);
+
+    hb_set_t v (hb_iter (s));
+
+    assert (v.get_population () == 2);
+  }
+
+  /* Test initializing from initializer list and swapping. */
+  {
+    hb_set_t v1 {1, 2, 3};
+    hb_set_t v2 {4, 5};
+    hb_swap (v1, v2);
+    assert (v1.get_population () == 2);
+    assert (v2.get_population () == 3);
+  }
+
+  return 0;
+}

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc	2021-11-04 00:51:18 UTC (rev 60943)
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2021  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+#include "hb.hh"
+#include "hb-vector.hh"
+#include "hb-set.hh"
+
+
+int
+main (int argc, char **argv)
+{
+
+  /* Test copy constructor. */
+  {
+    hb_vector_t<int> v1 {1, 2};
+    hb_vector_t<int> v2 {v1};
+    hb_vector_t<int> V2 {v1};
+    assert (v1.length == 2);
+    assert (v1[0] == 1);
+    assert (v1[1] == 2);
+    assert (v2.length == 2);
+    assert (v2[0] == 1);
+    assert (v2[1] == 2);
+  }
+
+  /* Test copy assignment. */
+  {
+    hb_vector_t<int> v1 {1, 2};
+    hb_vector_t<int> v2 = v1;
+    hb_vector_t<int> V2 = v1;
+    assert (v1.length == 2);
+    assert (v1[0] == 1);
+    assert (v1[1] == 2);
+    assert (v2.length == 2);
+    assert (v2[0] == 1);
+    assert (v2[1] == 2);
+  }
+
+  /* Test move constructor. */
+  {
+    hb_vector_t<int> v {hb_vector_t<int> {1, 2}};
+    hb_vector_t<int> V {hb_vector_t<int> {1, 2}};
+    assert (v.length == 2);
+    assert (v[0] == 1);
+    assert (v[1] == 2);
+  }
+
+  /* Test move assignment. */
+  {
+    hb_vector_t<int> v;
+    hb_sorted_vector_t<int> V;
+    v = hb_vector_t<int> {1, 2};
+    V = hb_sorted_vector_t<int> {1, 2};
+    assert (v.length == 2);
+    assert (v[0] == 1);
+    assert (v[1] == 2);
+  }
+
+  /* Test initializing from iterable. */
+  {
+    hb_set_t s;
+
+    s.add (18);
+    s.add (12);
+
+    hb_vector_t<int> v (s);
+    hb_sorted_vector_t<int> V (s);
+
+    assert (v.length == 2);
+    assert (V.length == 2);
+    assert (v[0] == 12);
+    assert (V[0] == 12);
+    assert (v[1] == 18);
+    assert (V[1] == 18);
+  }
+
+  /* Test initializing from iterator. */
+  {
+    hb_set_t s;
+
+    s.add (18);
+    s.add (12);
+
+    hb_vector_t<int> v (hb_iter (s));
+    hb_vector_t<int> V (hb_iter (s));
+
+    assert (v.length == 2);
+    assert (V.length == 2);
+    assert (v[0] == 12);
+    assert (V[0] == 12);
+    assert (v[1] == 18);
+    assert (V[1] == 18);
+  }
+
+  /* Test initializing from initializer list and swapping. */
+  {
+    hb_vector_t<int> v1 {1, 2, 3};
+    hb_vector_t<int> v2 {4, 5};
+    hb_swap (v1, v2);
+    assert (v1.length == 2);
+    assert (v1[0] == 4);
+    assert (v2.length == 3);
+    assert (v2[2] == 3);
+  }
+
+  /* Test initializing sorted-vector from initializer list and swapping. */
+  {
+    hb_sorted_vector_t<int> v1 {1, 2, 3};
+    hb_sorted_vector_t<int> v2 {4, 5};
+    hb_swap (v1, v2);
+    assert (v1.length == 2);
+    assert (v1[0] == 4);
+    assert (v2.length == 3);
+    assert (v2[2] == 3);
+  }
+
+  return 0;
+}

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2021-11-04 00:48:43 UTC (rev 60942)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2021-11-04 00:51:18 UTC (rev 60943)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [3.0.0])
+m4_define([harfbuzz_version], [3.1.0])



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