texlive[62894] Build/source/libs: harfbuzz 4.2.0

commits+kakuto at tug.org commits+kakuto at tug.org
Mon Apr 4 00:28:04 CEST 2022


Revision: 62894
          http://tug.org/svn/texlive?view=revision&revision=62894
Author:   kakuto
Date:     2022-04-04 00:28:02 +0200 (Mon, 04 Apr 2022)
Log Message:
-----------
harfbuzz 4.2.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/BUILD.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in
    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/src/Makefile.sources
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-c-linkage-decls.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-header-guards.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-includes.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-harfbuzzcc.py
    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/harfbuzz-subset.pc.in
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.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-deserialize-text.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc
    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-common.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-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-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.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.h
    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.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc
    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-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.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.h
    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.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
    trunk/Build/source/libs/harfbuzz/include/Makefile.am
    trunk/Build/source/libs/harfbuzz/include/Makefile.in
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ChainContextSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ContextSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ExtensionSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/GSUB.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookup.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookupSubTable.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.h

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/TODO

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/README	2022-04-03 22:28:02 UTC (rev 62894)
@@ -25,8 +25,8 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 3.4.0 - checked 13feb22
-  https://github.com/harfbuzz/harfbuzz/releases/download/3.4.0/
+harfbuzz 4.2.0 - checked 04apr22
+  https://github.com/harfbuzz/harfbuzz/releases/download/4.2.0/
 
 icu 70.1 - checked 16jan22
   https://github.com/unicode-org/icu/releases/

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1,3 +1,8 @@
+2022-04-04  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Import harfbuzz-4.2.0.
+	* version.ac, Makefile.am, include/Makefile.am: Adjusted.
+
 2022-02-13  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Import harfbuzz-3.4.0.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2022-04-03 22:28:02 UTC (rev 62894)
@@ -133,6 +133,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.cc \
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.hh \
 	@HARFBUZZ_TREE@/src/hb-subset-input.hh \
+	@HARFBUZZ_TREE@/src/hb-subset-repacker.cc \
 	@HARFBUZZ_TREE@/src/hb-subset.hh \
 	@HARFBUZZ_TREE@/src/hb-ucd-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ucd.cc \
@@ -227,6 +228,30 @@
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-khmer-machine.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar-machine.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-use-machine.hh
+##
+libharfbuzz_a_SOURCES += \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Common.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Sequence.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SingleSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SingleSubstFormat2.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SingleSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/MultipleSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/MultipleSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/AlternateSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/AlternateSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/AlternateSet.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/LigatureSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/LigatureSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/LigatureSet.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Ligature.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ContextSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ChainContextSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ExtensionSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SubstLookupSubTable.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SubstLookup.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/GSUB.hh
 
 ## Graphite library
 AM_CPPFLAGS += $(GRAPHITE2_INCLUDES)

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2022-04-03 22:28:02 UTC (rev 62894)
@@ -143,6 +143,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff-common.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-subset-cff1.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-subset-repacker.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ucd.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-unicode.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-fallback-shape.$(OBJEXT) \
@@ -247,6 +248,7 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-repacker.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
 am__mv = mv -f
@@ -807,6 +809,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.cc \
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.hh \
 	@HARFBUZZ_TREE@/src/hb-subset-input.hh \
+	@HARFBUZZ_TREE@/src/hb-subset-repacker.cc \
 	@HARFBUZZ_TREE@/src/hb-subset.hh \
 	@HARFBUZZ_TREE@/src/hb-ucd-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ucd.cc \
@@ -896,6 +899,28 @@
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-khmer-machine.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar-machine.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-use-machine.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Common.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Sequence.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SingleSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SingleSubstFormat2.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SingleSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/MultipleSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/MultipleSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/AlternateSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/AlternateSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/AlternateSet.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/LigatureSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/LigatureSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/LigatureSet.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Ligature.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ContextSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ChainContextSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/ExtensionSubst.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SubstLookupSubTable.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SubstLookup.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/GSUB.hh \
 	@HARFBUZZ_TREE@/src/hb-graphite2.cc
 @build_TRUE at dist_check_SCRIPTS = harfbuzz.test
 @build_TRUE at TESTS = harfbuzz.test
@@ -1054,6 +1079,9 @@
 @HARFBUZZ_TREE@/src/hb-subset-cff2.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-subset-repacker.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-ucd.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1211,6 +1239,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-repacker.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po at am__quote@ # am--include-marker
 
@@ -1862,6 +1891,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-repacker.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
 	-rm -f Makefile
@@ -1964,6 +1994,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-repacker.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
 	-rm -f Makefile

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1,3 +1,8 @@
+2022-04-04  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Imported harfbuzz-4.2.0 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/4.2.0/
+
 2022-02-13  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Imported harfbuzz-3.4.0 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-3.4.0/ tree as obtained from:
-	https://github.com/harfbuzz/harfbuzz/releases/download/3.4.0/
+Changes applied to the harfbuzz-4.2.0/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/4.2.0/
 
 Removed:
 	COPYING

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/configure	2022-04-03 22:28:02 UTC (rev 62894)
@@ -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.4.0.
+# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 4.2.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.4.0'
-PACKAGE_STRING='harfbuzz (TeX Live) 3.4.0'
+PACKAGE_VERSION='4.2.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 4.2.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.4.0 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 4.2.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.4.0:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 4.2.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.4.0
+harfbuzz (TeX Live) configure 4.2.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.4.0, which was
+It was created by harfbuzz (TeX Live) $as_me 4.2.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.4.0'
+ VERSION='4.2.0'
 
 
 # Some tools Automake needs.
@@ -5033,10 +5033,10 @@
 
 
 
-HB_VERSION_MAJOR=3
-HB_VERSION_MINOR=4
+HB_VERSION_MAJOR=4
+HB_VERSION_MINOR=2
 HB_VERSION_MICRO=0
-HB_VERSION=3.4.0
+HB_VERSION=4.2.0
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8817,7 +8817,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.4.0, which was
+This file was extended by harfbuzz (TeX Live) $as_me 4.2.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8885,7 +8885,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.4.0
+harfbuzz (TeX Live) config.status 4.2.0
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md	2022-04-03 22:28:02 UTC (rev 62894)
@@ -18,7 +18,8 @@
 
 On Windows, meson can build the project like above if a working MSVC's cl.exe (`vcvarsall.bat`)
 or gcc/clang is already on your path, and if you use something like `meson build --wrap-mode=default`
-it fetches and compiles most of the dependencies also.
+it fetches and compiles most of the dependencies also.  It is recommended to install CMake either
+manually or via the Visual Studio installer when building with MSVC when building with meson.
 
 Our CI configurations is also a good source of learning how to build HarfBuzz.
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1,3 +1,2400 @@
+commit 9d5730b958974bc9db95e46e6bad52e9e9cd6e1c
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Mar 30 15:08:34 2022 +0200
+
+    4.2.0
+
+ NEWS                   | 22 +++++++++++++++++++++-
+ configure.ac           |  2 +-
+ docs/harfbuzz-docs.xml |  1 +
+ meson.build            |  2 +-
+ src/hb-set.cc          |  2 +-
+ src/hb-version.h       |  4 ++--
+ 6 files changed, 27 insertions(+), 6 deletions(-)
+
+commit ecb3e7ec929aac83d4b4cef065bd87e0be400660
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Mon Mar 28 19:42:04 2022 -0400
+
+    Enable indic-feature-order.tests
+
+ test/shape/data/in-house/Makefile.sources | 1 +
+ test/shape/data/in-house/meson.build      | 1 +
+ 2 files changed, 2 insertions(+)
+
+commit 044d7a06db552e1564b8575f4d23798f009d9dde
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 28 12:38:56 2022 -0600
+
+    [indic-like] Add per-lookup per-syllable flag
+    
+    This allows mix-and-matching per-syllable and other lookups.
+    In fact, removes the clear-syllables call completely.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3513
+
+ src/hb-ot-layout-gsubgpos.hh                       |  13 +++++--
+ src/hb-ot-layout.cc                                |   1 +
+ src/hb-ot-layout.hh                                |  11 ------
+ src/hb-ot-map.cc                                   |   8 +++--
+ src/hb-ot-map.hh                                   |   8 +++--
+ src/hb-ot-shape-complex-indic.cc                   |  40 ++++++++++-----------
+ src/hb-ot-shape-complex-khmer.cc                   |  22 +++++-------
+ src/hb-ot-shape-complex-myanmar.cc                 |   8 ++---
+ src/hb-ot-shape-complex-use.cc                     |  15 ++++----
+ .../41071178fbce4956d151f50967af458dbf555f7b.ttf   | Bin 0 -> 3216 bytes
+ .../shape/data/in-house/tests/indic-syllable.tests |   1 +
+ 11 files changed, 61 insertions(+), 66 deletions(-)
+
+commit 61486746d3d8937c2b656c3ba72bd666fadef76c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 28 15:57:07 2022 -0600
+
+    Revert "[indic] Clear syllables before presentation features"
+    
+    This reverts commit 90f09b1e877dc6edf63fc4ac2b397ef4e5c92083.
+    
+    This regressed Indic shaping. See:
+    https://github.com/harfbuzz/harfbuzz/issues/3513
+
+ src/hb-ot-shape-complex-indic.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 18c0290cf50eaa4bc5db62678f26c11a1409292f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 28 13:24:16 2022 -0600
+
+    Add test for previous commit
+
+ test/shape/data/in-house/tests/macos.tests | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit e8f3397f4ef0db9700eb28f1b6843ba7e80e373e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 28 12:07:05 2022 -0600
+
+    [matcher] Simplify syllable initialization
+
+ src/hb-ot-layout-gsubgpos.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 94f5c630fc07e6aa653ac552b90444f9e7ea7c7f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 28 11:25:44 2022 -0600
+
+    [aat] Remove morx deleted-glyphs before GPOS processing
+    
+    Fixes new Apple Color Emoji glyphs sequences rendering.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3512
+
+ src/hb-ot-shape.cc | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+commit 0dcbdbde9cff68384bb3a5b9847283ca0676e54a
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sat Mar 26 20:56:50 2022 -0400
+
+    [indic] Categorize U+0D04 as Consonant_Placeholder
+
+ src/hb-ot-shape-complex-indic.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit a665e29ed71602dc37fbb987f0de6806bcc7d710
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Mar 23 17:30:25 2022 -0600
+
+    [use] Avoid O(n^2) in the machine
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3502
+
+ src/hb-ot-shape-complex-use-machine.hh             |  36 ++++++++++++++-------
+ src/hb-ot-shape-complex-use-machine.rl             |  22 ++++++++++---
+ ...rfuzz-testcase-hb-shape-fuzzer-5446125635633152 | Bin 0 -> 655 bytes
+ 3 files changed, 43 insertions(+), 15 deletions(-)
+
+commit ccd9161bfd08b644d2563b58f353ee7fea97608d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 24 13:10:48 2022 -0600
+
+    [apply-lookup] Try to fix the logic for contextual lookups
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1611
+    
+    Notably, this fixes Myles's AdditionFont:
+    https://litherum.blogspot.com/2019/03/addition-font.html
+    
+    Test with AdditionFont, eg.:
+    $ util/hb-view AdditionFont.otf =1112112+1113134=
+
+ src/hb-ot-layout-gsubgpos.hh                       |  22 ++++++++++++++-------
+ .../5bbf3712e6f79775c66a4407837a90e591efbef2.ttf   | Bin 0 -> 6400 bytes
+ .../data/in-house/tests/context-matching.tests     |   1 +
+ 3 files changed, 16 insertions(+), 7 deletions(-)
+
+commit fa15fc44bbf17ae417021f92552b9f04a5c1a69e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 25 15:00:11 2022 -0600
+
+    [subset] Require exact harfbuzz version in .pc file
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1446
+
+ src/harfbuzz-subset.pc.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b619b05f39509b0a4805d844636a31a9183d5dd4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 25 14:56:55 2022 -0600
+
+    [subset] Adjust name in .pc file
+
+ src/harfbuzz-subset.pc.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 122907866036e4ad03ddeefe0fe07a28e559fe8e
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Mar 25 22:41:25 2022 +0200
+
+    [set] Fix annotation
+
+ src/hb-set.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3a78cf92c83c6f05154e42e8f7b17bd8bc93f1d6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 25 12:56:44 2022 -0600
+
+    [gvar] Fix decoding of private vs shared points
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3506
+
+ src/hb-ot-var-gvar-table.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit a02fb4a0dcafce485b0db07fee58a12b7adee83a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 25 12:56:19 2022 -0600
+
+    [glyf] Don't bail rendering glyf even if gvar failed
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/3506
+
+ src/hb-ot-glyf-table.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 0a38878549968e1d636a6d878c55d4efe76ce9fc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 25 09:42:36 2022 -0600
+
+    [set] Minor touch-up on the previous commit
+
+ docs/harfbuzz-sections.txt   |  1 +
+ src/hb-bit-set-invertible.hh | 10 +++++-----
+ src/hb-bit-set.hh            | 12 ++++++------
+ src/hb-set.cc                |  6 +++---
+ src/hb-set.hh                |  4 ++--
+ 5 files changed, 17 insertions(+), 16 deletions(-)
+
+commit a003fc0df1a2dad57e18c1be8b40591dfbcc9547
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 25 09:37:50 2022 -0600
+
+    Remove accidental files
+
+ test/subset/__pycache__/repack_test.cpython-39.pyc       | Bin 1299 -> 0 bytes
+ test/subset/__pycache__/subset_test_suite.cpython-39.pyc | Bin 3501 -> 0 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 0182988229591476eea1606dde0d78a1864ca017
+Author: Andrew John <45769922+andyjgf at users.noreply.github.com>
+Date:   Fri Mar 25 08:36:44 2022 -0700
+
+    [set] Add call to export set contents to an array. (#3500)
+    
+    [set] Add hb_set_next_many.
+
+ src/hb-bit-page.hh                                 |  69 ++++++++++++-
+ src/hb-bit-set-invertible.hh                       |   8 ++
+ src/hb-bit-set.hh                                  |  94 +++++++++++++++++
+ src/hb-set.cc                                      |  25 +++++
+ src/hb-set.h                                       |   6 ++
+ src/hb-set.hh                                      |   3 +
+ test/api/test-set.c                                | 111 +++++++++++++++++++++
+ test/subset/__pycache__/repack_test.cpython-39.pyc | Bin 0 -> 1299 bytes
+ .../__pycache__/subset_test_suite.cpython-39.pyc   | Bin 0 -> 3501 bytes
+ 9 files changed, 315 insertions(+), 1 deletion(-)
+
+commit a55a42444d0578125425c3fe64d5f8172c508f44
+Author: aneejit1 <100675750+aneejit1 at users.noreply.github.com>
+Date:   Thu Mar 24 20:16:41 2022 +0000
+
+     Meson build writes to the source directory (issue #3507 ) (#3508)
+    
+    Don't write to source directory if files did not change
+    
+    Remove writes to the source directory which cause a meson build failure
+    if the source directory is read-only.
+    
+    https://github.com/harfbuzz/harfbuzz/pull/3508
+
+ src/gen-harfbuzzcc.py | 8 ++++++--
+ src/gen-hb-version.py | 8 ++++++--
+ 2 files changed, 12 insertions(+), 4 deletions(-)
+
+commit bf2a845a17ef7b45867c38f9b7c041e4c479d340
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 24 13:09:53 2022 -0600
+
+    [ot-layout] Comment
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a792e16e48188f67d38768c1d25ac5d7f26ec607
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 24 13:08:51 2022 -0600
+
+    [ot-layout] Change max nesting level of lookups from 6 to 64
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f76ffa8374799b5acb16a0e25d72ae80d4d3f964
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Mar 24 06:23:22 2022 +0200
+
+    [build] Change how platform shaper tests are enable
+    
+    Run the tests unconditionally and skip if the shaper is not available.
+    This fixes distcheck (https://github.com/harfbuzz/harfbuzz/pull/3504)
+    and shows SKIP for these tests instead of ignoring them.
+
+ test/shape/data/in-house/Makefile.am      | 14 +++++++++++---
+ test/shape/data/in-house/Makefile.sources | 13 +++----------
+ test/shape/data/in-house/meson.build      | 17 ++++-------------
+ test/shape/meson.build                    | 14 +++-----------
+ test/shape/run-tests.py                   | 17 ++++++++++++++++-
+ 5 files changed, 37 insertions(+), 38 deletions(-)
+
+commit 38575c9042f8c4e7ea03260671b705c0dbf505fe
+Merge: 444c2375a eb44d64bc
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Mar 24 05:51:22 2022 +0200
+
+    Merge pull request #3504 from fanc999/dist-plat-shaper-tests
+    
+    test: Dist the platform shaper test data
+
+commit eb44d64bc25c10028d3d44aa93c5507d217bd193
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Thu Mar 24 10:52:48 2022 +0800
+
+    test: Dist the platform shaper test data
+    
+    For builds from release tarballs, the tests fail in the DirectWrite and
+    Uniscribe tests when these platform shapers are enabled, since the data files
+    were not found in the source tree, when building with Meson at least.
+    
+    Fix this by dist'ing the platform shaper test data files.
+
+ test/shape/data/in-house/Makefile.sources | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 444c2375a155500248d21ed074fffd353304a1d3
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Mar 23 16:49:13 2022 -0700
+
+    [reorg] Use relative includes for hb-ot-layout-gsubgpos.hh
+
+ src/OT/Layout/GSUB/ChainContextSubst.hh | 2 +-
+ src/OT/Layout/GSUB/ContextSubst.hh      | 2 +-
+ src/OT/Layout/GSUB/ExtensionSubst.hh    | 2 +-
+ src/OT/Layout/GSUB/GSUB.hh              | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+commit b342adeb96148570d71d5e0eb07436eb7d53b5e7
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Mar 23 16:28:22 2022 -0700
+
+    [reorg] Move GSUB into OT::Layout::GSUB namespace.
+
+ src/OT/Layout/GSUB/GSUB.hh | 15 +++++++--------
+ src/hb-ot-layout.cc        |  8 +++++---
+ src/hb-subset-plan.cc      |  4 +++-
+ src/hb-subset.cc           |  4 +++-
+ 4 files changed, 18 insertions(+), 13 deletions(-)
+
+commit a9910e258fe2d8f782ccb3594b79f9d150e60e08
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Mar 23 16:09:41 2022 -0700
+
+    [reorg] Move SubstLookup and GSUB into the new layout.
+
+ src/Makefile.sources                      |   6 +
+ src/OT/Layout/GSUB/ChainContextSubst.hh   |  18 ++
+ src/OT/Layout/GSUB/ContextSubst.hh        |  18 ++
+ src/OT/Layout/GSUB/ExtensionSubst.hh      |  22 ++
+ src/OT/Layout/GSUB/GSUB.hh                |  59 ++++++
+ src/OT/Layout/GSUB/SubstLookup.hh         | 224 ++++++++++++++++++++
+ src/OT/Layout/GSUB/SubstLookupSubTable.hh |  77 +++++++
+ src/hb-ot-layout-gsub-table.hh            | 332 +-----------------------------
+ src/hb-ot-layout.hh                       |   8 +-
+ src/meson.build                           |   6 +
+ 10 files changed, 440 insertions(+), 330 deletions(-)
+
+commit 90af2143d58947b4ed82ff6c9b86bc483d3a58bb
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Mar 23 15:28:29 2022 -0700
+
+    [reorg] Move ReverseChainSingleSubst to new layout.
+
+ src/Makefile.sources                               |   2 +
+ src/OT/Layout/GSUB/ReverseChainSingleSubst.hh      |  36 ++++
+ .../Layout/GSUB/ReverseChainSingleSubstFormat1.hh  | 228 ++++++++++++++++++++
+ src/hb-ot-layout-gsub-table.hh                     | 239 +--------------------
+ src/meson.build                                    |   2 +
+ 5 files changed, 270 insertions(+), 237 deletions(-)
+
+commit 403feb3804cb61a73c32ff2c87659fd49900fe4f
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Mar 23 15:19:04 2022 -0700
+
+    [reorg] Move LigatureSubst to new layout.
+
+ src/Makefile.sources                       |   4 +
+ src/OT/Layout/GSUB/Ligature.hh             | 135 ++++++++++
+ src/OT/Layout/GSUB/LigatureSet.hh          | 118 ++++++++
+ src/OT/Layout/GSUB/LigatureSubst.hh        |  59 ++++
+ src/OT/Layout/GSUB/LigatureSubstFormat1.hh | 165 ++++++++++++
+ src/hb-ot-layout-gsub-table.hh             | 420 +----------------------------
+ src/meson.build                            |   4 +
+ 7 files changed, 487 insertions(+), 418 deletions(-)
+
+commit 6a369389d6cb8de126141cfe71f3c6bc0faedd15
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Mar 23 15:04:11 2022 -0700
+
+    [reorg] Move AlternateSubst to new layout.
+
+ src/Makefile.sources                        |   3 +
+ src/OT/Layout/GSUB/AlternateSet.hh          | 110 +++++++++++++
+ src/OT/Layout/GSUB/AlternateSubst.hh        |  51 ++++++
+ src/OT/Layout/GSUB/AlternateSubstFormat1.hh | 128 ++++++++++++++
+ src/hb-ot-layout-gsub-table.hh              | 247 +---------------------------
+ src/meson.build                             |   3 +
+ 6 files changed, 297 insertions(+), 245 deletions(-)
+
+commit dea0681db2cca618e58b27a471863ff42f43bb31
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Mar 23 14:48:58 2022 -0700
+
+    [reorg] Move MultipleSubst into new layout.
+
+ src/Makefile.sources                       |   3 +
+ src/OT/Layout/GSUB/MultipleSubst.hh        |  53 +++++++
+ src/OT/Layout/GSUB/MultipleSubstFormat1.hh | 120 +++++++++++++++
+ src/OT/Layout/GSUB/Sequence.hh             | 103 +++++++++++++
+ src/hb-ot-layout-gsub-table.hh             | 229 +----------------------------
+ src/meson.build                            |   3 +
+ 6 files changed, 284 insertions(+), 227 deletions(-)
+
+commit 7243bf3e4119bf73d31de2252003a5fc4b2ed6d8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 26 08:26:50 2022 -0700
+
+    [reorg] Use relative include
+
+ src/OT/Layout/GSUB/Common.hh             | 3 ++-
+ src/OT/Layout/GSUB/SingleSubstFormat1.hh | 1 -
+ src/OT/Layout/GSUB/SingleSubstFormat2.hh | 1 -
+ 3 files changed, 2 insertions(+), 3 deletions(-)
+
+commit c180f93766cbeec4e516800e9cbf956b740e4779
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 26 08:22:40 2022 -0700
+
+    [reorg] Move sanitize/dispatch and size macros to top
+
+ src/OT/Layout/GSUB/SingleSubst.hh        | 39 ++++++++++++++++----------------
+ src/OT/Layout/GSUB/SingleSubstFormat1.hh | 16 ++++++-------
+ src/OT/Layout/GSUB/SingleSubstFormat2.hh | 16 ++++++-------
+ 3 files changed, 34 insertions(+), 37 deletions(-)
+
+commit f577d02f4a750e462814d385e416c9fd45986d1e
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Jan 20 14:39:48 2022 -0800
+
+    [reorg] Fix check-* scripts to work with sources files in directories.
+
+ src/Makefile.sources                     |  4 ++++
+ src/OT/Layout/GSUB/Common.hh             |  6 +++---
+ src/OT/Layout/GSUB/SingleSubst.hh        |  6 +++---
+ src/OT/Layout/GSUB/SingleSubstFormat1.hh |  6 +++---
+ src/OT/Layout/GSUB/SingleSubstFormat2.hh |  6 +++---
+ src/check-c-linkage-decls.py             | 14 +++++++++++---
+ src/check-header-guards.py               | 19 +++++++++++++++----
+ src/check-includes.py                    | 17 ++++++++++++++---
+ 8 files changed, 56 insertions(+), 22 deletions(-)
+
+commit 3ef180db4492a38f6a9f8d91505828f85d43960b
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Jan 13 15:22:55 2022 -0800
+
+    [reorg] Move SingleSubst opentype fields to top of the classes.
+
+ src/OT/Layout/GSUB/SingleSubstFormat1.hh | 17 ++++++++++-------
+ src/OT/Layout/GSUB/SingleSubstFormat2.hh | 23 +++++++++++++----------
+ 2 files changed, 23 insertions(+), 17 deletions(-)
+
+commit 7dfd9e700190fbe00314bfc61f691953320829e3
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Jan 13 14:17:51 2022 -0800
+
+    [reorganization] WIP move single substitution into separate files.
+
+ src/OT/Layout/GSUB/Common.hh             |  20 +++
+ src/OT/Layout/GSUB/SingleSubst.hh        |  74 ++++++++
+ src/OT/Layout/GSUB/SingleSubstFormat1.hh | 122 ++++++++++++++
+ src/OT/Layout/GSUB/SingleSubstFormat2.hh | 120 +++++++++++++
+ src/hb-ot-layout-gsub-table.hh           | 280 +------------------------------
+ src/meson.build                          |   4 +
+ 6 files changed, 345 insertions(+), 275 deletions(-)
+
+commit c36844d6d923bfc765f841fde10d6f505ff297fd
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Mar 23 07:20:59 2022 +0200
+
+    4.1.0
+
+ NEWS                   | 14 ++++++++++++++
+ configure.ac           |  2 +-
+ docs/harfbuzz-docs.xml |  1 +
+ meson.build            |  2 +-
+ src/hb-set.cc          |  2 +-
+ src/hb-version.h       |  6 +++---
+ 6 files changed, 21 insertions(+), 6 deletions(-)
+
+commit 0fec8ad8482bbbcc134a1f16b315a5a72acacb59
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Mar 22 13:44:22 2022 -0600
+
+    Remove old TODO file
+
+ TODO | 28 ----------------------------
+ 1 file changed, 28 deletions(-)
+
+commit d35c73cd3766953ad6f07ba8e83159868141635c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Mar 22 10:20:28 2022 -0600
+
+    [buffer] Whitespace
+
+ src/hb-buffer.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 280355b31f15528c1690fca035bd68317b0bbaf8
+Merge: f41945e31 36b8f9741
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 22:03:00 2022 -0600
+
+    Merge pull request #3497 from harfbuzz/vertical-origin
+    
+    [ot-font] Fix vertical-origin fallback to match FreeType
+
+commit 36b8f97413a1edcded818b3b14fee45fc320e6b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 21:50:04 2022 -0600
+
+    Update tests for recent changes
+
+ test/api/test-ot-metrics-tt-var.c                  |  4 +--
+ test/shape/data/in-house/tests/collections.tests   |  6 ++--
+ .../data/in-house/tests/indic-decompose.tests      |  2 +-
+ test/shape/data/in-house/tests/spaces.tests        | 34 +++++++++++-----------
+ test/shape/data/in-house/tests/vertical.tests      |  2 +-
+ 5 files changed, 24 insertions(+), 24 deletions(-)
+
+commit 1449498e1df3ea7497c7417f2278b14c50278b1c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 21:40:07 2022 -0600
+
+    [ot-font] Vertically center glyph in vertical writing fallback
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/537
+
+ src/hb-ot-font.cc | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+commit bf03d7e962ec831d720efcfa33e5397bbbaa1ec4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 21:27:31 2022 -0600
+
+    [ot-font] Use ascent+descent for fallback vertical advance
+    
+    This matches what FreeType does.
+    
+    Part of fixing https://github.com/harfbuzz/harfbuzz/issues/537
+
+ src/hb-ot-font.cc | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+commit df42d28d18598d893d4d8e5458b246010058dea7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 21:17:15 2022 -0600
+
+    [hmtx] Change default advance for horizontal direction to upem/2 again
+
+ src/hb-ot-hmtx-table.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 6d0e67dee09d1232f86671b362b04b05ecb0a18f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 21:07:11 2022 -0600
+
+    [ot-font] Only use vmtx side-bearing if table exists
+    
+    Part of fixing https://github.com/harfbuzz/harfbuzz/issues/537
+
+ src/hb-ft.cc            | 1 +
+ src/hb-ot-font.cc       | 3 ++-
+ src/hb-ot-hmtx-table.hh | 2 ++
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+commit f41945e313ca053253bfd339186b87c977da3bf3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 18:24:30 2022 -0600
+
+    [cmap] In collect_unicodes() of format 12/13, limit to max Unicode
+    
+    Fixes fuzzer timeout:
+    https://oss-fuzz.com/testcase-detail/5062368881672192
+
+ src/hb-ot-cmap-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 03085132bac6bb3f69378cab3eaf5a57ad1362ff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 18:06:33 2022 -0600
+
+    [buffer] Fix out-buffer under memory-alloc failure
+    
+    This was broken in July refactoring of the buffer, and exposed to
+    ReverseChainSingleSubstFormat1 in 3807061d634b60bd6235d6e1d8c47a034377f924
+    
+    Fixes:
+    https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=38800
+    https://bugs.chromium.org/p/chromium/issues/detail?id=1303552
+
+ src/hb-buffer.cc                                         |   1 +
+ ...z-testcase-minimized-hb-shape-fuzzer-5349416110784512 | Bin 0 -> 1603 bytes
+ 2 files changed, 1 insertion(+)
+
+commit 116cc6923601d088f6886ef6f535346885c45a7b
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Mar 22 00:11:26 2022 +0200
+
+    [set] Fix documentation
+
+ docs/harfbuzz-sections.txt | 2 +-
+ src/hb-set.cc              | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 98b4852434e5b7583aeb03069efad83caa224a37
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Mon Mar 21 17:17:39 2022 -0400
+
+    [indic] Test clearing syllables earlier
+
+ .../fonts/190a621e48d4af1fffd8144bd41d2027e9a32fbf.ttf   | Bin 0 -> 1320 bytes
+ test/shape/data/in-house/tests/indic-feature-order.tests |   1 +
+ 2 files changed, 1 insertion(+)
+
+commit 90f09b1e877dc6edf63fc4ac2b397ef4e5c92083
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 10:24:23 2022 -0600
+
+    [indic] Clear syllables before presentation features
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3488
+
+ src/hb-ot-shape-complex-indic.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 4289684cdbbe5fbfa394bc3ce568eb8f27f404f4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 15:37:05 2022 -0600
+
+    [set] Fix-up previous commits
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-set.cc              | 10 ++++++++--
+ src/hb-set.h               | 10 +++++-----
+ 3 files changed, 14 insertions(+), 7 deletions(-)
+
+commit 1176620ba4e788d40a2be8d33c2647bc5aba9c82
+Author: Andy John <andyj at google.com>
+Date:   Mon Mar 21 14:31:47 2022 -0700
+
+    Move fn, fix doc.
+
+ src/hb-set.cc | 33 +++++++++++++++++----------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+commit 7d802994be2cc53e5e7fcd90e2eaa9fa497cd12a
+Author: Andy John <andyj at google.com>
+Date:   Mon Mar 21 13:55:34 2022 -0700
+
+    Remove null checks.
+
+ src/hb-set.cc | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit ef588ea97bee45b0ca5bb771c3646f79d5ee7c74
+Author: Andy John <andyj at google.com>
+Date:   Mon Mar 21 13:29:22 2022 -0700
+
+    Add option to insert a sorted arrays of values to sets.
+
+ src/hb-bit-set.hh   |  4 ++--
+ src/hb-set.cc       | 18 ++++++++++++++++++
+ src/hb-set.h        |  5 +++++
+ test/api/test-set.c | 19 +++++++++++++++++++
+ 4 files changed, 44 insertions(+), 2 deletions(-)
+
+commit 7a1e79c3ba3d8bf0dec93907396953aa96393be3
+Author: Andy John <andyj at google.com>
+Date:   Mon Mar 21 13:18:04 2022 -0700
+
+    Fix typo.
+
+ src/hb-bit-set.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4ee00f943f4fde9418c21804a263f902557e76dc
+Author: Andy John <andyj at google.com>
+Date:   Mon Mar 21 13:16:28 2022 -0700
+
+    Use bit shifting instead of multiplying and dividing.
+
+ src/hb-bit-set.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3125f5ae3348a81e20067e55093644d8669d1f16
+Author: Andy John <andyj at google.com>
+Date:   Mon Mar 21 13:12:14 2022 -0700
+
+    Add log base 2 versions of constants.
+
+ src/hb-bit-page.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 1ffe637a0e36577b18e1708c252749fcbcb08754
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Mar 21 10:37:42 2022 -0600
+
+    [coretext] Remove dead code
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3484
+
+ src/hb-coretext.cc | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+commit 7bdc20ec810c14056d6362b076aa6717f10f26a0
+Author: TheBluuDot <62665768+TheBluuDot at users.noreply.github.com>
+Date:   Sat Mar 19 17:47:04 2022 +0500
+
+    restores unintended addition in 43be5ba
+    
+    restores two lines in restore in _hb_allocate_lig_id function that were unintentionally deleted in 43be5ba
+
+ src/hb-ot-layout.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 7cb002cb58d4e3f17fcab174e400c0292880c059
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Mar 14 11:40:35 2022 -0700
+
+    [subset] bug fix in prune_langsys
+    
+    we should not cache visited langsys cause 2 different Record<Langsys>
+    could have different Tag while pointing to the same Langsys, a langsys
+    is redundant in Record<Langsys> A does not mean it's redundant in Record
+    B. Same thing for visited_script.
+    Also adding the number of features in the LangSys's feature list to the
+    visited langsys count so it's more accurate.
+    Plus some improvement in langsys compare()
+
+ src/hb-ot-layout-common.hh                         |  59 ++++++++-------------
+ ...ar.default.61,62,63,64,65,66,67,68,69,6A,6B.ttf | Bin 0 -> 4800 bytes
+ ...drop-hints.61,62,63,64,65,66,67,68,69,6A,6B.ttf | Bin 0 -> 2452 bytes
+ ...an.default.61,62,63,64,65,66,67,68,69,6A,6B.ttf | Bin 0 -> 9704 bytes
+ ...drop-hints.61,62,63,64,65,66,67,68,69,6A,6B.ttf | Bin 0 -> 9704 bytes
+ test/subset/data/tests/full-font.tests             |   1 +
+ 6 files changed, 23 insertions(+), 37 deletions(-)
+
+commit cad2fe8e639f53fee4b0ae6ff0389ef9ed028143
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Mar 15 10:49:29 2022 -0600
+
+    [baseline] Fix HB_NO_METRICS build
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3482
+
+ src/hb-ot-layout.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a8a89b80b406cef53e6dd8e411a49d75ed04cda9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Mar 15 10:48:03 2022 -0600
+
+    [layout] Whitespace
+
+ src/hb-ot-layout.cc | 120 ++++++++++++++++++++++++++--------------------------
+ 1 file changed, 60 insertions(+), 60 deletions(-)
+
+commit 21f5ef56f53247958c6c346ac5205a96f6de0c66
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Mar 15 10:45:50 2022 -0600
+
+    [metrics] Simplify x-height fallback
+
+ src/hb-ot-metrics.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 6bf8f0a38fdb43ef9593eedabd7deba6064df44b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Mar 15 10:44:41 2022 -0600
+
+    [baseline] Use ot-metrics fallback API
+
+ src/hb-ot-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 965cf1d66589b0db60e75961cc58f5a65521078e
+Author: Dominik Röttsches <drott at chromium.org>
+Date:   Mon Mar 14 12:48:18 2022 +0000
+
+    Make load_num_glyphs_from_loca conditional on HB_NO_BORING_EXPANSION
+    
+    Fixes build errors complaining about this function being unused.
+
+ src/hb-static.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 49fb8f9072ae07c6df0ff0067f005e3aaa1ac26b
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sun Mar 13 15:01:11 2022 -0400
+
+    [USE] Treat visible viramas like dependent vowels
+
+ src/gen-use-table.py                               |  17 +-
+ src/hb-ot-shape-complex-use-machine.hh             | 865 +++++++++++----------
+ src/hb-ot-shape-complex-use-machine.rl             |  10 +-
+ src/hb-ot-shape-complex-use-table.hh               |  28 +-
+ src/hb-ot-shape-complex-use.cc                     |   2 +-
+ .../23406a60ab081c4fb15e1596ea1cd4f27ae8443e.ttf   | Bin 0 -> 1400 bytes
+ test/shape/data/in-house/tests/use-syllable.tests  |   1 +
+ test/shape/data/in-house/tests/use.tests           |   1 +
+ 8 files changed, 491 insertions(+), 433 deletions(-)
+
+commit 1f79ba9407ecd54e382997940cbcc3fb71bef8be
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Mar 11 20:19:04 2022 +0200
+
+    4.0.1
+
+ NEWS             | 20 ++++++++++++++++++++
+ configure.ac     |  2 +-
+ meson.build      |  2 +-
+ src/hb-version.h |  4 ++--
+ 4 files changed, 24 insertions(+), 4 deletions(-)
+
+commit a34eea301387f95d34f646b93fc8fc2027f0b0a4
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Mar 11 19:57:53 2022 +0200
+
+    [doc] Add experimental repacker API to private section
+    
+    Hides the warning about them until they are no longer experimental.
+
+ docs/harfbuzz-sections.txt | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit a35757c6bc3a792791c0714d143f47537d7ec110
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Feb 2 10:30:34 2022 -0800
+
+    [repacker] expose hb_subset_repack() API, hb_object_t and hb_link_t structs
+
+ src/Makefile.sources                 |   2 +
+ src/gen-def.py                       |   2 +-
+ src/hb-repacker.hh                   |  19 +--
+ src/hb-serialize.hh                  |  35 ++++++
+ src/hb-subset-repacker.cc            |  49 ++++++++
+ src/hb-subset-repacker.h             |  80 +++++++++++++
+ src/meson.build                      |   6 +-
+ test/api/Makefile.am                 |   2 +
+ test/api/fonts/repacker_expected.otf | Bin 0 -> 1400 bytes
+ test/api/meson.build                 |   1 +
+ test/api/test-subset-repacker.c      | 225 +++++++++++++++++++++++++++++++++++
+ 11 files changed, 411 insertions(+), 10 deletions(-)
+
+commit e7ab42b24618df6fbf6263dfe8aa964c843a006e
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Mar 10 09:05:43 2022 -0500
+
+    [layout] Fix handling of baseline variations
+    
+    For BASE table format 1.1, the handling of design
+    space vs user space coordinates was inconsistent.
+    We were applying design -> user transformation
+    twice for the deltas, leading to wrong baseline
+    values.
+    
+    Patch by Ebrahim Byagowi <ebrahim at gnu.org>
+    
+    Fixes: #3476
+
+ src/hb-ot-layout-base-table.hh | 20 ++++++++++++--------
+ src/hb-ot-layout.cc            |  7 +------
+ 2 files changed, 13 insertions(+), 14 deletions(-)
+
+commit e5707a440caf9e4102c6e580084b35248b27dbfb
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Wed Mar 2 21:30:22 2022 -0500
+
+    Update IANA Language Subtag Registry to 2022-03-02
+
+ src/hb-ot-tag-table.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit 13bb46cfd52c8791077779fc9ffa60547a22f022
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sun Mar 6 15:35:31 2022 -0500
+
+    [USE] Remove obsolete overrides
+
+ src/gen-use-table.py | 20 ++------------------
+ 1 file changed, 2 insertions(+), 18 deletions(-)
+
+commit c33468d48ec8b49971232b457605298c28fd6d5b
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sun Mar 6 12:26:37 2022 -0500
+
+    [USE] Treat all gc=Cn as independent clusters
+
+ src/gen-use-table.py                 |  69 ++---
+ src/hb-ot-shape-complex-use-table.hh | 499 ++++++++++++++++++-----------------
+ src/hb-ot-shape-complex-use.cc       |   2 +-
+ 3 files changed, 290 insertions(+), 280 deletions(-)
+
+commit e497a8f142f127c6a8d52cf854352e3eb2e6ed95
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sun Mar 6 11:36:43 2022 -0500
+
+    [USE] Remove obsolete symbol/punctuation overrides
+
+ src/gen-use-table.py                 | 11 -----------
+ src/hb-ot-shape-complex-use-table.hh |  8 ++++----
+ 2 files changed, 4 insertions(+), 15 deletions(-)
+
+commit 854219e05675bfb380005e2e156bd025e56c1530
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sat Mar 5 10:46:31 2022 -0500
+
+    [USE] Simplify `not_ccs_default_ignorable`
+
+ src/hb-ot-shape-complex-use-machine.hh | 2 +-
+ src/hb-ot-shape-complex-use-machine.rl | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 6e059a46b79894f85cef01f168b5da7f29ffe3ff
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Mar 4 19:18:40 2022 -0500
+
+    [USE] Allow any non-numeric tail in symbol cluster
+
+ src/hb-ot-shape-complex-use-machine.hh | 647 +++++++++++++++++++++------------
+ src/hb-ot-shape-complex-use-machine.rl |   5 +-
+ src/hb-ot-shape-complex-use.cc         |   3 +-
+ 3 files changed, 428 insertions(+), 227 deletions(-)
+
+commit 5b0a59812d97104ec24de8b3658cfca6ce872a27
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Mar 4 20:45:30 2022 -0500
+
+    [USE] Restore the category WJ
+
+ src/gen-use-table.py                              |  11 +-
+ src/hb-ot-shape-complex-use-machine.hh            |  43 +--
+ src/hb-ot-shape-complex-use-machine.rl            |   1 +
+ src/hb-ot-shape-complex-use-table.hh              | 372 +++++++++++++++++++---
+ src/ms-use/IndicPositionalCategory-Additional.txt |  12 +-
+ 5 files changed, 366 insertions(+), 73 deletions(-)
+
+commit 05b3bdb0b382078fcc0a6837bcc28730908531b8
+Author: Florian Pircher <florian at addpixel.net>
+Date:   Sun Mar 6 03:10:48 2022 +0100
+
+    [aat] Update OT to AAT mappings for hist and vrtr
+
+ src/hb-aat-layout.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 4302466481941a470a48573b410892f7ee057fb5
+Merge: 756395270 cf3a0f7ab
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Mar 6 05:24:35 2022 +0200
+
+    Merge pull request #3464 from luzpaz/typos
+    
+    Fixed various misc. typos
+
+commit cf3a0f7ab54984ffb9ab386a673358619dfaab4f
+Author: luz paz <luzpaz at users.noreply.github.com>
+Date:   Tue Mar 1 19:55:58 2022 -0500
+
+    Fixed various misc. typos
+    
+    Found via `codespell -q 3 -S ./perf/texts -L actualy,als,ba,beng,clen,crasher,dependant,eachother,fo,gir,inout,ist,nd,ned,ot,pres,ro,statics,te,teh,timne`
+
+ docs/serializer.md                |  2 +-
+ src/hb-buffer-deserialize-text.hh | 16 ++++++++--------
+ src/hb-buffer-deserialize-text.rl |  2 +-
+ src/hb-buffer.h                   |  2 +-
+ 4 files changed, 11 insertions(+), 11 deletions(-)
+
+commit 756395270dc41efa98036d3756ed282a46046c51
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Mar 2 12:56:33 2022 +0200
+
+    Minor [ci skip]
+
+ NEWS | 52 ++++++++++++++++++++++++++--------------------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+commit 8d1b000a3edc90c12267b836b4ef3f81c0e53edc
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Mar 1 21:27:32 2022 +0200
+
+    4.0.0
+
+ NEWS                   | 92 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ configure.ac           |  2 +-
+ docs/harfbuzz-docs.xml |  1 +
+ meson.build            |  2 +-
+ src/hb-buffer.h        |  4 +--
+ src/hb-draw.cc         | 20 +++++------
+ src/hb-draw.h          | 24 ++++++-------
+ src/hb-font.cc         |  2 +-
+ src/hb-font.h          |  4 +--
+ src/hb-ot-layout.cc    |  4 +--
+ src/hb-ot-layout.h     |  4 +--
+ src/hb-ot-metrics.cc   |  2 +-
+ src/hb-subset-plan.cc  | 16 ++++-----
+ src/hb-subset.cc       |  2 +-
+ src/hb-version.h       |  6 ++--
+ 15 files changed, 138 insertions(+), 47 deletions(-)
+
+commit 6e466256e40a049201a6d3329dcc1bb00ab310fb
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Mar 1 12:01:18 2022 +0200
+
+    [doc] Typo
+
+ src/hb-subset-plan.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f6071c16b0eb482bf6811b2a55b2f882cb6ce02e
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Feb 28 14:45:40 2022 -0700
+
+    [subset] Rename codepoint -> unicode in subset plan api
+
+ docs/harfbuzz-sections.txt | 2 +-
+ src/hb-subset-plan.cc      | 4 ++--
+ src/hb-subset.h            | 2 +-
+ test/api/test-subset.c     | 2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 1b5a2e0809b2f90fea891cbd7e6e2caee1dcb01f
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Feb 25 04:22:33 2022 +0200
+
+    [doc] Various fixes to newly added documentation
+
+ docs/harfbuzz-docs.xml     |  1 -
+ docs/harfbuzz-sections.txt | 10 ++++++++++
+ src/hb-buffer.h            |  1 +
+ src/hb-subset-plan.cc      | 18 +++++++++++++-----
+ 4 files changed, 24 insertions(+), 6 deletions(-)
+
+commit 924dd71de3c8444125f532655a8647c713f0cdc0
+Merge: 222301bfa e045dbf61
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Feb 25 04:31:24 2022 +0200
+
+    Merge pull request #3423 from harfbuzz/revert-ci-msvc
+    
+    Revert "[ci] Downgrade pip on MSVC jobs"
+
+commit 222301bfa4010554abb900df5ed113722885277a
+Merge: 78f3d7f0a fc1548cf7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 24 12:55:01 2022 -0700
+
+    Merge pull request #3429 from harfbuzz/external_plan
+    
+    [subset] expose subset plan in public subsetting API
+
+commit 78f3d7f0a8dc399415dbd6983212997fdf9831b1
+Merge: d4cb07728 256dcde14
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Feb 21 18:21:03 2022 +0200
+
+    Merge pull request #3459 from jameshilliard/icu-defs-mutliarg
+    
+    [meson] handle multiple element ICU DEFS
+
+commit 256dcde149737246a04cfc0fe388cb91acb65522
+Author: James Hilliard <james.hilliard1 at gmail.com>
+Date:   Mon Feb 21 00:07:03 2022 -0700
+
+    [meson] handle multiple element ICU DEFS
+
+ meson.build | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d4cb07728ccf0f8c2f3287e2b3be663995eb5c11
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Feb 18 18:25:56 2022 -0600
+
+    Add a missing file
+    
+    The style test is using notosansitalic.ttf now,
+    but I forgot to add it with the test. Fix that.
+
+ test/api/fonts/notosansitalic.ttf | Bin 0 -> 1464 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 651c280d0b8a9b0894022fea971141015eab73f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 18 18:21:46 2022 -0600
+
+    [style] Move the negation into the constant
+
+ src/hb-style.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 16b232be0ed2c8486a9f30523f989e77dd8d13f2
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Feb 18 18:05:58 2022 -0600
+
+    [hb-style] Fix the sign of slant ratios
+    
+    We want negative slant angles to yield
+    positive slant ratios. Fix that.
+    
+    Test included.
+
+ src/hb-style.cc       |  4 ++--
+ src/hb-style.h        |  4 +++-
+ test/api/test-style.c | 12 ++++++++++++
+ 3 files changed, 17 insertions(+), 3 deletions(-)
+
+commit e76061a7372077d063432548e2fb85db5fad8670
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Feb 18 17:27:19 2022 -0600
+
+    [hb-style] Fix synthetic slant values
+    
+    When reporting the slant ratio of a font
+    that has synthetic slant set, we were
+    reporting twice the expected value.
+    Fix that. Test included.
+
+ src/hb-style.cc       |  3 +--
+ test/api/test-style.c | 17 +++++++++++++++++
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+commit 56f11ec938260836387256225bc47665473e2bbe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 18 14:08:43 2022 -0600
+
+    [buffer] Add HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3454
+
+ src/hb-buffer-verify.cc                               |  3 ++-
+ src/hb-buffer.h                                       | 14 +++++++++++---
+ src/hb-buffer.hh                                      |  4 ++++
+ test/shape/data/in-house/tests/unsafe-to-concat.tests |  2 +-
+ util/shape-options.hh                                 |  3 +++
+ 5 files changed, 21 insertions(+), 5 deletions(-)
+
+commit c0b2f50c0b08e5b2f6238e54bae03d164b12548e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 18 12:29:14 2022 -0600
+
+    [util] Rename template typenames to avoid clashing with actual types
+    
+    Apparently MSVC2015 can confuse them
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3379
+
+ util/hb-ot-shape-closure.cc |  4 ++--
+ util/helper-cairo.hh        |  4 ++--
+ util/main-font-text.hh      | 14 ++++++++++----
+ 3 files changed, 14 insertions(+), 8 deletions(-)
+
+commit fc1548cf71a9396c0addce27134661aa2799429e
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Feb 17 17:16:31 2022 -0800
+
+    [subset] document return values.
+
+ src/hb-subset-plan.cc | 3 ++-
+ src/hb-subset.cc      | 9 ++++++---
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+commit f6efe34f5e9a5657bfe706dc173c9a62817838d3
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Feb 15 17:17:09 2022 -0600
+
+    [ot-metrics] Synthesize missing metrics
+    
+    Add a variant of hb_ot_metrics_get_position that
+    synthesizes missing values.
+    
+    New api: hb_ot_metrics_get_position_with_fallback
+
+ docs/harfbuzz-sections.txt |   1 +
+ src/hb-ot-metrics.cc       | 139 +++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-metrics.h        |   5 ++
+ 3 files changed, 145 insertions(+)
+
+commit f8e9e315bbe809763b89bfc66facad33ffc0491d
+Merge: 8e900f2cd 95bb2ff71
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 17 14:34:46 2022 -0600
+
+    Merge pull request #3437 from matthiasclasen/synthesize-missing-baselines
+    
+    [BASE] Synthesize missing baselines
+
+commit 8e900f2cda0acd938eb50d8294a0b074761f9a91
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 17 13:28:44 2022 -0600
+
+    Revert "hb-algs.hh: Fix build on Visual Studio 2015"
+    
+    This reverts commit 52c536bb8d90cf0f09e13f5e9e21bf489cc08c23.
+    
+    See https://github.com/harfbuzz/harfbuzz/pull/3448
+
+ src/hb-algs.hh | 6 ------
+ 1 file changed, 6 deletions(-)
+
+commit da801cdee1d90bb787e1ac1c6a296f306218d57d
+Merge: 5de67c896 e6aa4b7d0
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Feb 17 13:30:40 2022 +0200
+
+    Merge pull request #3449 from fanc999/msvc-meson-use-cmake
+    
+    Meson: Use CMake more to find dependencies on Windows
+
+commit e6aa4b7d0e3026f3186738b1e8b50286988ba38f
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Thu Feb 17 15:28:42 2022 +0800
+
+    BUILD.md: Mention that installing CMake is recommended for MSVC
+    
+    We are using CMake to help us find dependencies in Meson builds on Visual
+    Studio, so let people know that it's recommended.
+
+ BUILD.md | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit d24ac4aac33bee06082c6bfcca907569740c7f59
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Thu Feb 17 16:18:41 2022 +0800
+
+    freetype2.wrap: Provide fallback for CMake dep as well
+    
+    Add a freetype identifier in the 'provides' section so that the fallback will
+    kick in if FreeType is requested but was not found, and wrap mode is not
+    disabled.
+
+ subprojects/freetype2.wrap | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit f0573d8462ef18bd21c6ae3fc7d2c15c660ff1c7
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Thu Feb 17 14:39:31 2022 +0800
+
+    meson: Clean up finding ICU-UC on Visual Studio
+    
+    Nowadays Meson has much better CMake support which we can use to find
+    dependencies on Visual Studio builds (and Visual Studio 2017 and later provides
+    CMake as an optional install item), so we can use it to help us find ICU-UC
+    on Visual Studio builds, since CMake has built-in support for finding it by
+    the components we need for some time.
+
+ meson.build | 31 +++++++++----------------------
+ 1 file changed, 9 insertions(+), 22 deletions(-)
+
+commit 561e8ba8870d9f18a92c886593f8b0162f98d941
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Thu Feb 17 14:19:35 2022 +0800
+
+    meson: Cleanup finding FreeType on Visual Studio
+    
+    Nowadays, CMake is much better supported with Meson and is a common tool on
+    Windows (it is even an optionally-installed item for Visual Studio 2017+), so
+    make use of that to find FreeType.  The package to search for, however, is
+    `freetype` instead of `freetype2`.
+
+ meson.build | 20 ++++----------------
+ 1 file changed, 4 insertions(+), 16 deletions(-)
+
+commit 95bb2ff7198e4811b1a712c8c6dfbae29e453d49
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Feb 16 13:10:52 2022 -0600
+
+    [ot-layout] Add central baselines
+    
+    Add HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL
+    and HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL
+    which are the centers of the ideographic em-box
+    and face box.
+
+ src/hb-ot-layout.cc | 40 ++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout.h  |  4 ++++
+ 2 files changed, 44 insertions(+)
+
+commit f81578fd86455eb8eba3bd586d604b83aa55ed56
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Feb 13 19:15:36 2022 -0600
+
+    [ot-layout] Synthesize missing baselines
+    
+    Add a variation of hb_ot_layout_get_baseline that
+    synthesizes missing baselines, using heuristics in part
+    taken from the CSS Inline Layout Module, Level 3.
+    
+    Includes some new tests for synthesized baselines.
+    The base2.ttf is a subset of Noto Sans Bengali that
+    includes just the Bengali Ka.
+    
+    New API: hb_ot_layout_get_baseline_with_fallback
+
+ docs/harfbuzz-sections.txt |   1 +
+ src/hb-ot-layout.cc        | 184 ++++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-ot-layout.h         |   8 ++
+ test/api/fonts/base2.ttf   | Bin 0 -> 5236 bytes
+ test/api/test-baseline.c   |  53 +++++++++++++
+ 5 files changed, 245 insertions(+), 1 deletion(-)
+
+commit 5de67c8961555ee6c5ef27ebe7a9e087dda01b56
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 16 17:07:17 2022 -0600
+
+    [ot-layout] Remove commented-out prototypes
+    
+    Not gonna happen.
+
+ docs/harfbuzz-sections.txt |  6 ------
+ src/hb-ot-layout.h         | 47 ----------------------------------------------
+ 2 files changed, 53 deletions(-)
+
+commit d2998faad3e431b8c94262f049b7422fecb6e238
+Merge: 98079109e f567b5561
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 16 14:37:09 2022 -0600
+
+    Merge pull request #3410 from harfbuzz/boring-expansion
+    
+    [Boring Expansion] >64k loca & hmtx tables
+    
+    This does two things:
+    
+    The num-glyphs reported by the face now is the maximum reported by the maxp and that deduced from the length of the loca table; I think this is the right thing to do anyway; According to OpenType such loca tables are invalid.
+    
+    The interpretation hmtx tables that have excessive bytes at the end, again, invalid according to OpenType, has changed. Previously we were interpreting those excessive bytes as extra lsb values. Now we interpret them as extra advance values, the last of which is repeated for all missing glyphs. Again, these are tables that are invalid according to OpenType, and the advances are for glyph indices beyond maxp table's num-glyphs.
+    
+    The combined effect is that the font can have shapes and advances for gid's beyond the maxp limit of 64k. In fact, maxp table becomes optional.
+
+commit 98079109e6ebc8f05b6c8de97fcd0ed5667907d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Feb 13 18:15:32 2022 -0600
+
+    [ot-layout] Add +hb_ot_layout_get_horizontal_baseline_tag_for_script()
+    
+    New API:
+    +hb_ot_layout_get_horizontal_baseline_tag_for_script()
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-ot-layout.cc        | 70 ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout.h         |  3 ++
+ 3 files changed, 74 insertions(+)
+
+commit cfa8cd7fb0962967d647c09e4cfab4b8600fb360
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Feb 16 11:42:36 2022 +0200
+
+    [autotools] Fix make distcheck
+    
+    The test-draw.c can now optionally uses hb-ft, but automake file was not
+    passing FreeType cflags or libs to it.
+
+ test/api/Makefile.am | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 9909e3326806f0ad1405648c16296cd42dff39fc
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Feb 15 18:02:09 2022 -0600
+
+    Improve docs for hb_ot_layout_get_ligature_carets
+    
+    Add some relevant details to the documentation
+    for this function.
+    
+    Fixes: #3168
+
+ src/hb-ot-layout.cc | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit a396543ae15569dca7ab7cc47c060f262f6bdfea
+Merge: 1bf588e28 c8b6036cf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 18:47:55 2022 -0600
+
+    Merge pull request #3411 from harfbuzz/draw
+    
+    [draw] Finish and release draw API
+
+commit f567b5561928e713737edc4655c6532ea6138a1d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 18:26:43 2022 -0600
+
+    [face] Use max numGlyphs of maxp and loca
+
+ src/hb-static.cc | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit c8fd8c133755fd9c62efc67033ca0193bd0dfc76
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 18:02:53 2022 -0600
+
+    [ot-face] Use core tables
+
+ src/hb-ot-face-table-list.hh |  1 +
+ src/hb-ot-glyf-table.hh      |  3 +--
+ src/hb-static.cc             | 24 +++---------------------
+ 3 files changed, 5 insertions(+), 23 deletions(-)
+
+commit 2a430790adfac00a1280c0ebfcf579be1b557ffb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 17:33:52 2022 -0600
+
+    [machinery] Add "core table" machinery
+    
+    To be used in subsequent commit; or tried anyway.
+
+ src/hb-machinery.hh          | 11 ++++++++---
+ src/hb-ot-face-table-list.hh | 13 +++++++++++--
+ src/hb-ot-face.hh            |  3 +++
+ 3 files changed, 22 insertions(+), 5 deletions(-)
+
+commit 67eb9acf792a63e4d6a8447c23cbb5d4b97891dc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 17:17:49 2022 -0600
+
+    [config] Add HB_NO_BORING_EXPANSION
+
+ src/hb-config.hh                 | 1 +
+ src/hb-ot-hmtx-table.hh          | 4 ++++
+ src/hb-static.cc                 | 5 ++++-
+ test/api/test-be-glyph-advance.c | 2 ++
+ test/api/test-be-num-glyphs.c    | 2 ++
+ 5 files changed, 13 insertions(+), 1 deletion(-)
+
+commit 1bf588e28b1ead28b5ca755e840112520c551aba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 16:57:23 2022 -0600
+
+    [test/shape] Internal rename
+    
+    Residual from e0d7060f80f8c4b9b8241c3a4d8faa33f48da86d
+
+ test/shape/meson.build | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit d12c51e6e6225c3a4efaa358f01c711946964d7d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 14:31:59 2022 -0600
+
+    [ci] Rename configs-ci to configs-build
+    
+    Since it doesn't run any tests.
+
+ .github/workflows/{configs-ci.yml => configs-build.yml} | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 197ed8f5923b04cfd843942428814ea14b88632e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 14:30:12 2022 -0600
+
+    [test/api] Fix leaks
+
+ test/api/hb-test.h | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+commit 531c27d199be9413523ae1f48703931d0ebf922f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 14:20:54 2022 -0600
+
+    Fix build
+
+ test/api/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8b7ccc41c4b06ad93927849c54288a9ad1816dba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 15 14:15:12 2022 -0600
+
+    [hmtx] Implement [boring-expansion] >64k expansion
+    
+    This implements https://github.com/be-fonts/boring-expansion-spec/issues/7
+
+ src/hb-ot-face-table-list.hh     |  1 +
+ src/hb-ot-hmtx-table.hh          | 80 +++++++++++++++++++++++++++-------------
+ test/api/test-be-glyph-advance.c |  6 +--
+ 3 files changed, 59 insertions(+), 28 deletions(-)
+
+commit 379e526aa41b216fa1dd19cf4345e55ec3c8a8c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 14 15:02:31 2022 -0600
+
+    [test] Add test for current hmtx logic
+
+ test/api/Makefile.am             |  1 +
+ test/api/meson.build             |  1 +
+ test/api/test-be-glyph-advance.c | 99 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 101 insertions(+)
+
+commit 431c948ed742c936623a340e046e0e708ee0736f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 14 14:13:04 2022 -0600
+
+    [hmtx] Document
+
+ src/hb-ot-hmtx-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit be4ddcc30b8c1932def1b9a5beee9ead90f8928f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 14 14:12:07 2022 -0600
+
+    [hmtx] Rename internal num_advances to num_long_metrics
+
+ src/hb-ot-hmtx-table.hh | 56 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 28 insertions(+), 28 deletions(-)
+
+commit 622cbc485f286770ee816524c0b12aef7e81d510
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 14 14:09:40 2022 -0600
+
+    [hmtx] Internal rename num_metrics to num_bearings
+
+ src/hb-ot-hmtx-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit ed6d287d1105219b246a2810685097918f974497
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 14:10:16 2022 -0600
+
+    [ot-face] Load num-glyphs from `loca` table before `maxp`
+    
+    Implements [boring-expansion] [maxp] Relax
+    https://github.com/be-fonts/boring-expansion-spec/issues/6
+
+ src/hb-ot-hmtx-table.hh       |  2 +-
+ src/hb-static.cc              | 52 ++++++++++++++++++++++++++++----
+ test/api/Makefile.am          |  1 +
+ test/api/hb-test.h            |  7 +++++
+ test/api/meson.build          |  1 +
+ test/api/test-be-num-glyphs.c | 69 +++++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 126 insertions(+), 6 deletions(-)
+
+commit 93962977bcd3de314f4e613990b7e74ac8803a68
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Feb 13 19:38:59 2022 -0600
+
+    Remove return of void
+
+ src/hb-font.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c8b6036cf305a119203c0e1a3f061cb26299b930
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Feb 14 02:17:38 2022 +0200
+
+    [meson] Update Cairo subproject
+    
+    Fixes another color fonts issue.
+
+ subprojects/cairo.wrap | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6b75a30a730356c41a6ed748847fd95494e51ad5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 14 01:38:06 2022 +0330
+
+    [draw/test] Swap a freetype test case with a simpler one
+    
+    As CI failure, apparently the my local freetype and CI one have different
+    result so let's switch the case with a simpler one just to test quadratic command
+    is emitted correctly.
+
+ test/api/test-draw.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+commit ae223764a305e3dbfd3654892e2f5562a89e213a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Feb 13 15:39:14 2022 -0600
+
+    [test/draw] Typo
+
+ test/api/test-draw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 0429921c109a24205ed19e21bc5f0d1cd570400d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 14 00:16:35 2022 +0330
+
+    [draw/test] Add test for freetype callback
+    
+    Let's have that part of the code also covered.
+
+ test/api/test-draw.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 59 insertions(+)
+
+commit d4588204e52eece7dab04f45e37d2986b1545cb7
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Feb 13 23:49:41 2022 +0330
+
+    [draw/glyf] Emit empty contours
+    
+    This makes it actually match freetype behaviour even though rasterizer
+    should filter such contours specially for stroking.
+    
+    See https://github.com/harfbuzz/harfbuzz/pull/3411#discussion_r802283827 for the context.
+
+ src/hb-ot-glyf-table.hh | 6 ++++++
+ test/api/test-draw.c    | 5 +++--
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+commit 94517850dd1105dfcdc7e0f44adbbee0eb92d3a3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Feb 13 13:39:26 2022 -0600
+
+    [algs] Fix typo in hb_pair_t conversion operator
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2083
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f942874facdfe31322b4cbe5cc7bb0dc0db48e5d
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 12 01:43:11 2022 +0200
+
+    [draw] Fix some introspection warnings
+
+ src/hb-draw.cc            | 32 ++++++++++++++++++++++----------
+ src/hb-draw.h             | 10 +++++-----
+ src/hb-font.h             |  3 ---
+ src/hb-gobject-structs.cc |  1 +
+ src/hb-gobject-structs.h  |  4 ++++
+ 5 files changed, 32 insertions(+), 18 deletions(-)
+
+commit 2da6accda6583962feca64d38807fbf694cca601
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 12 01:14:15 2022 +0200
+
+    [meson] Update cairo submodule
+    
+    To include the latest color glyph fixes
+
+ subprojects/cairo.wrap | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0858463ac3e4db60c339e85061f3c9e8ab81ee0a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 11 14:42:15 2022 -0600
+
+    [draw/glyf] Don't skip empty contours of size 2
+    
+    See:
+    https://github.com/harfbuzz/harfbuzz/pull/3411#discussion_r804988217
+
+ src/hb-ot-glyf-table.hh | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit 0e357c504ca18cd0e01dc23eef0a6db6e75a54dc
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Feb 11 04:31:13 2022 +0200
+
+    [draw] Test scaling subfont differently from parent
+
+ test/api/test-draw.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+
+commit 096121badbbc19d77a46015339de968817dc5c4f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 10 19:27:33 2022 -0600
+
+    [util] Implement --sub-font
+    
+    Internally creates a font at 2x and creates a sub-font from it...
+
+ util/font-options.hh      | 11 +++++++++++
+ util/helper-cairo-user.hh | 10 ----------
+ 2 files changed, 11 insertions(+), 10 deletions(-)
+
+commit 57aa8c3b3a5df1a7895269f696e21952e361247b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 10 19:04:52 2022 -0600
+
+    [draw] Another try at a stable draw moveto semantic
+
+ src/hb-draw.hh            |  2 +-
+ src/hb-font.cc            |  6 ------
+ util/helper-cairo-user.hh | 10 ++++++++++
+ 3 files changed, 11 insertions(+), 7 deletions(-)
+
+commit 151f205819dbec29c78fbc0ebcefd72752809ff5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 10 16:27:18 2022 -0600
+
+    [draw] Emit move_to immediately, like other operators
+
+ src/hb-draw.hh                 |  8 +++++---
+ src/hb-font.cc                 |  3 +++
+ test/fuzzing/hb-draw-fuzzer.cc | 22 ++++++----------------
+ 3 files changed, 14 insertions(+), 19 deletions(-)
+
+commit aca80a4a4019f3b808b4ccbd0c26d1bef6a2fdb4
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Feb 9 22:44:38 2022 +0200
+
+    [draw] Add test for applying synthetic slant
+
+ test/api/test-draw.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 44 insertions(+), 1 deletion(-)
+
+commit 052fd2d8b98defaa593dd18d9b30f11652dd6dde
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Feb 9 22:10:23 2022 +0200
+
+    [draw] Add test for hb_draw_move_to() etc
+
+ test/api/test-draw.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+commit 640b6ffddd0dd7dc7d17f66e252d5450333035a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 8 18:20:59 2022 -0600
+
+    [util] Default font-funcs to 'ot' instead of 'ft'
+
+ util/font-options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9cc9ffe3523980fad86ea9950cf82a53b79a9583
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 8 18:18:47 2022 -0600
+
+    [util/draw] If HB_DRAW is not set, choose depending on cairo version
+    
+    If HB_DRAW=0, don't use it, if HB_DRAW=1, use it, if unset, choose depending
+    on cairo version
+
+ util/helper-cairo.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 22f2c78c283846250e029026b15dc778c9fba633
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 8 17:52:56 2022 -0600
+
+    [util/draw] Explicitly chain from render_color_glyph to render_glyph
+    
+    This seems to be more robust.  See:
+    https://github.com/harfbuzz/harfbuzz/pull/3411#issuecomment-1033176635
+
+ util/helper-cairo-user.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6a3dec357ce4a66ed1c78abd1aee982d4646cbac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 8 17:39:16 2022 -0600
+
+    [util/draw] Use hb-draw in hb-view only if HB_DRAW=1
+
+ util/helper-cairo.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 18b8a1c3451be24c61d6471d754e1daeaa8eb4d8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 8 16:33:09 2022 -0600
+
+    [draw] Fix conversion warnings
+
+ util/helper-cairo-user.hh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit 6812f7ee1eeca874ccc132f37f67f173e0e2e3fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 8 16:15:37 2022 -0600
+
+    [draw] Implement COLRv0 fonts
+
+ util/helper-cairo-user.hh | 101 +++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 92 insertions(+), 9 deletions(-)
+
+commit 74ebfc646a662fa84e20f3aafeb02f42daf41496
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Feb 8 22:44:11 2022 +0200
+
+    [meson] Update cairo subproject
+    
+    Update to the current master branch so that is has
+    cairo_user_font_face_set_render_color_glyph_func().
+    
+    I had to disable optimized builds on win[32|64] crossbuild setups
+    because they are now broken in the CI (something about cairo defining
+    _FORTIFY_SOURCE for optimized builds that MingW does not like).
+
+ .ci/build-win32.sh     | 1 -
+ .ci/build-win64.sh     | 1 -
+ meson.build            | 3 +--
+ subprojects/cairo.wrap | 2 +-
+ 4 files changed, 2 insertions(+), 5 deletions(-)
+
+commit 628847b5c8d8783c46a51c9f2bdc481b4bbee960
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Feb 8 22:09:49 2022 +0200
+
+    [doc] Link to respective draw callback functions
+
+ src/hb-draw.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 7245298e259a4ce30d149174d6880e27f9766125
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Feb 8 21:38:57 2022 +0200
+
+    [doc] Document HB_DRAW_STATE_DEFAULT
+
+ src/hb-draw.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 8f519d55ac0ba6ae9c81d83ee598416e851ca3f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 8 13:28:00 2022 -0600
+
+    [meson] Put back Experimental-API infrastructure
+    
+    Just unused for now.
+
+ .github/workflows/coverity-scan.yml | 2 +-
+ meson.build                         | 5 +++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit 8e892bdb544b946e4c1b8705f86baffe67584c54
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Feb 8 19:36:29 2022 +0200
+
+    [doc] Message draw documentation a bit
+
+ src/hb-draw.cc |  9 +++++++
+ src/hb-draw.h  | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-font.cc |  2 +-
+ src/hb-font.h  |  2 +-
+ 4 files changed, 94 insertions(+), 2 deletions(-)
+
+commit cf28821337735bb1bee3599129592e9e84c53616
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Feb 8 19:03:17 2022 +0200
+
+    [meson] fix building with Cairo subproject
+    
+    We can’t pass internal (subproject) dependency to cpp.has_function(), so
+    we manually hard-code the result.
+
+ meson.build | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit cdf1cb35db2e479d40e629e355a9de348ab1c17c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 19:05:52 2022 -0600
+
+    [draw] Destroy callback data
+
+ src/hb-draw.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 5c558586eba3b6cc13e66cfd8271d6d654fd2488
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 18:54:16 2022 -0600
+
+    [util/draw] Apply slant to non-user-fonts as well
+
+ util/helper-cairo.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit c56c13756b637c231843d634d48c26bc891303a9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 18:38:00 2022 -0600
+
+    [draw] Document more
+
+ src/hb-draw.cc | 135 ++++++++++++++++++---------------------------------------
+ src/hb-draw.h  | 105 ++++++++++++++++++++++++++++++++++++--------
+ src/hb-font.cc |   4 +-
+ 3 files changed, 130 insertions(+), 114 deletions(-)
+
+commit 23762305235f25ca89de34bed7948d925c98fba3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 18:23:26 2022 -0600
+
+    [draw] Flesh out docs a bit
+
+ docs/harfbuzz-docs.xml     |  1 +
+ docs/harfbuzz-sections.txt | 31 ++++++++++++++++++++++
+ src/hb-draw.cc             | 64 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 96 insertions(+)
+
+commit bc6c3b84016852a348d425a79d47cfd1aa927984
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 18:04:36 2022 -0600
+
+    [font] Update get_glyph_shape() doc
+
+ src/hb-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 732c749ef7a8e27b8b0d9eb1ec2e37d3902b5712
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 18:02:37 2022 -0600
+
+    [font] Adjust synthetic-slant docs
+
+ src/hb-font.cc | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 4818b7ed72c4f397920d695dfdae8b3649209a16
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 18:00:14 2022 -0600
+
+    [util] Add --font-slant
+
+ util/font-options.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 59067db9f47fa2d0fc6cdc4adcc38d63601f9123
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 17:55:01 2022 -0600
+
+    [font/draw] Slant drawings
+    
+    Need to update hb_font_set_synthetic_slant() docs now that we do this.
+
+ src/hb-ft.cc      | 2 +-
+ src/hb-ot-font.cc | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit aa5c7a3811ae5035bd1bd06a9f8e73119b837b12
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 7 17:53:38 2022 -0600
+
+    [draw-session] Add slant
+
+ src/hb-draw.hh | 50 ++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 36 insertions(+), 14 deletions(-)
+
+commit 4f2704adb61c1fd699822cbf8dd3b32f3313d816
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Feb 6 13:13:34 2022 -0600
+
+    [draw] Add more reserved items to hb_draw_state_t
+    
+    Since these are free basically.
+
+ src/hb-draw.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 2ce19f2868ebbb545d6e376a5642c2b93d966dca
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 5 15:01:15 2022 -0600
+
+    [font/draw] Fetch shape from parent font if not implemented in font
+
+ src/hb-draw.cc |   2 +-
+ src/hb-font.cc | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 116 insertions(+), 3 deletions(-)
+
+commit d6b61dff952c8a1b14629371fc76e1113936c3a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 5 13:46:48 2022 -0600
+
+    [draw] Minor cleanup
+
+ src/hb-draw.cc | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+commit cfc06c24d595b403ea09e5598597127406403a1b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 5 13:31:05 2022 -0600
+
+    [util/draw] Render color glyphs if cairo API available
+
+ configure.ac              |  4 +++
+ meson.build               |  1 +
+ util/helper-cairo-user.hh | 88 ++++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 92 insertions(+), 1 deletion(-)
+
+commit 542f8269cbb5028cead28f7add6500611b57e772
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 4 18:45:04 2022 -0600
+
+    [util/draw/ft] Use hb-draw for font-funcs=ft as well
+    
+    If cairo is >= 1.17.5.
+    
+    This essentially breaks emoji and bitmap fonts for now.
+
+ util/helper-cairo.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 6d5b998f256f8d5217bede6fa32a4c9dd82aca56
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 4 18:44:38 2022 -0600
+
+    [ft/draw] Implement hb-draw for hb-ft
+
+ src/hb-ft.cc | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 82 insertions(+)
+
+commit 370bec938ba0b626ef1a494cb82cf236c7b2c598
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 4 18:40:44 2022 -0600
+
+    [draw] Rename internal draw_session_t to hb_draw_session_t
+
+ src/hb-draw.hh          |  6 +++---
+ src/hb-ot-cff1-table.cc | 10 +++++-----
+ src/hb-ot-cff1-table.hh |  2 +-
+ src/hb-ot-cff2-table.cc |  6 +++---
+ src/hb-ot-cff2-table.hh |  2 +-
+ src/hb-ot-font.cc       |  2 +-
+ src/hb-ot-glyf-table.hh |  6 +++---
+ 7 files changed, 17 insertions(+), 17 deletions(-)
+
+commit 5d2df1208a58e537cb16e3b8009135dcf4d9393b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 17:18:54 2022 -0600
+
+    [util] Use hb-draw to render alternatively to cairo-ft
+    
+    Is automatically enabled if cairo is recent enough, and font-funcs are
+    not 'ft'.
+    
+    Uses cairo-user-font backend internally.
+
+ util/Makefile.sources     |   2 +
+ util/helper-cairo-ft.hh   | 120 +++++++++++++++++++++++++++++++++++++++
+ util/helper-cairo-user.hh | 142 ++++++++++++++++++++++++++++++++++++++++++++++
+ util/helper-cairo.hh      |  86 +++++-----------------------
+ 4 files changed, 279 insertions(+), 71 deletions(-)
+
+commit a357e5d8896e4f540c3e78177f656a2f509a996d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 14:42:56 2022 -0600
+
+    [draw] Do quadratic-to-cubic conversion in nil quadratic implementation
+
+ src/hb-draw.cc | 22 +++++++++++++---------
+ src/hb-draw.hh | 12 +-----------
+ 2 files changed, 14 insertions(+), 20 deletions(-)
+
+commit c681331c3ff6b7743723b082c2100bd47d28bfac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 14:36:12 2022 -0600
+
+    [draw] Rename internal draw_helper_t to draw_session_t
+
+ src/hb-draw.hh          |  6 +++---
+ src/hb-ot-cff1-table.cc | 28 ++++++++++++++--------------
+ src/hb-ot-cff1-table.hh |  2 +-
+ src/hb-ot-cff2-table.cc | 16 ++++++++--------
+ src/hb-ot-cff2-table.hh |  2 +-
+ src/hb-ot-font.cc       |  8 ++++----
+ src/hb-ot-glyf-table.hh | 30 +++++++++++++++---------------
+ 7 files changed, 46 insertions(+), 46 deletions(-)
+
+commit f1a9a9ccaf329e1d1935f468a8299fa9c8d663ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 14:10:40 2022 -0600
+
+    [draw-state] Pass state down to callbacks
+
+ src/hb-draw.cc                 |  5 +++++
+ src/hb-draw.h                  |  5 +++++
+ src/hb-draw.hh                 | 34 +++++++++++++++++-----------------
+ src/main.cc                    |  5 +++++
+ test/api/test-draw.c           |  5 +++++
+ test/fuzzing/hb-draw-fuzzer.cc |  5 +++++
+ 6 files changed, 42 insertions(+), 17 deletions(-)
+
+commit a9dd9f0bae6fc05001d51ecd78d47e3afd3a8d72
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 13:58:36 2022 -0600
+
+    [draw] Add public move_to/line_to/... API that take a draw-state
+
+ src/hb-draw.cc          |  51 ++++++++++++++++++++++
+ src/hb-draw.h           |  31 ++++++++++++++
+ src/hb-draw.hh          | 112 ++++++++++++++++++++++++++++++++----------------
+ src/hb-ot-cff1-table.cc |   2 +-
+ src/hb-ot-glyf-table.hh |   2 +-
+ 5 files changed, 160 insertions(+), 38 deletions(-)
+
+commit 9f05362d435c621e49fe430a0cb4653a9b82b9bf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 13:08:32 2022 -0600
+
+    [test-draw] Fix compiler warning
+
+ test/api/test-draw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ebc2a133c37cd87ee3698d88604de61f2913c1d4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 13:00:39 2022 -0600
+
+    [draw] Rename internal methods
+
+ src/hb-draw.hh | 48 ++++++++++++++++++++++++------------------------
+ 1 file changed, 24 insertions(+), 24 deletions(-)
+
+commit 86fcd4fe98448a564fa72476ddea9d56acae1efa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 12:54:32 2022 -0600
+
+    [draw] Simplify start_path
+
+ src/hb-draw.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1740916ede028c4bc90e5a74f625be0a221884bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 12:50:47 2022 -0600
+
+    [draw] Remove check for no-op
+    
+    This is unnecessary overhead. Up to rasterizers to handle this.  Plus,
+    this throws off point-numbers in uses that rely on it.
+    
+    Disabled one test that broke with this.
+
+ src/hb-draw.hh                 |  9 ---------
+ test/api/test-draw.c           |  2 +-
+ test/fuzzing/hb-draw-fuzzer.cc | 10 +++++-----
+ 3 files changed, 6 insertions(+), 15 deletions(-)
+
+commit fc78592e6767b158e0871446d3d7c8ae54c0ab7e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 12:43:25 2022 -0600
+
+    [draw-state] Add type and use in draw-helper
+
+ src/hb-common.h | 10 ++++++++++
+ src/hb-draw.h   | 19 ++++++++++++++++++
+ src/hb-draw.hh  | 62 ++++++++++++++++++++++++---------------------------------
+ 3 files changed, 55 insertions(+), 36 deletions(-)
+
+commit 5610fa1da0a3f1a5e3753bae60ea97fd6bf32eed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 10:29:04 2022 -0600
+
+    [test-draw] Re-enable two disabled tests
+
+ test/api/test-draw.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit a755f93e8d49672ded0811fa2e68bf75b141ab07
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 10:28:07 2022 -0600
+
+    [draw] Add TODO
+
+ src/hb-font.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit cdb1a1fc06059a866edd17cc6ef95870c22925da
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 01:25:37 2022 -0600
+
+    [draw] Add REPLACEME
+
+ src/hb-font.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 8b4f42900041cf8312c61a1b59f13c802336ff6a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 01:14:47 2022 -0600
+
+    [draw] Virtualize hb_font_draw_glyph() into hb_font_get_glyph_shape()
+    
+    To be implemented in hb-ft.
+
+ src/Makefile.sources           |  1 -
+ src/harfbuzz.cc                |  1 -
+ src/hb-draw-glyph.cc           | 63 -------------------------------------
+ src/hb-font.cc                 | 38 +++++++++++++++++++++++
+ src/hb-font.h                  | 47 +++++++++++++++++++++++++---
+ src/hb-font.hh                 | 10 ++++++
+ src/hb-ot-font.cc              | 21 +++++++++++++
+ src/main.cc                    |  4 +--
+ src/meson.build                |  1 -
+ test/api/test-draw.c           | 70 +++++++++++++++++++++---------------------
+ test/api/test-ot-face.c        |  2 +-
+ test/fuzzing/hb-draw-fuzzer.cc |  2 +-
+ 12 files changed, 150 insertions(+), 110 deletions(-)
+
+commit 92e6e53b30ecf013cf3bfcd43e6c149acc47edf3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 00:23:13 2022 -0600
+
+    [draw] Rename user_data to draw_data
+
+ src/hb-draw-glyph.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 3b915389b517a6e14e2e7566f6e621f93ce6a98c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 00:03:13 2022 -0600
+
+    [draw] Remove unneeded roundf() calls
+
+ src/hb-draw.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 2bed4f46fb09f338fd0959d233d16a40db08cf4e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 21:42:48 2022 -0600
+
+    [draw] Fix draw signatures
+
+ src/hb-draw-glyph.cc           |   2 +-
+ src/hb-draw.cc                 | 141 ++++++++++--------
+ src/hb-draw.h                  |  54 +++----
+ src/hb-draw.hh                 |  97 +++++++++---
+ src/hb-font.h                  |   2 +-
+ src/main.cc                    |  65 ++++----
+ test/api/test-draw.c           | 327 +++++++++++++++++++++--------------------
+ test/fuzzing/hb-draw-fuzzer.cc | 105 +++++++------
+ 8 files changed, 448 insertions(+), 345 deletions(-)
+
+commit 08e1096609394d27683fe4fe8770e6cb980502c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 19:01:42 2022 -0600
+
+    [draw-fuzzer] Fix signatures
+
+ test/fuzzing/hb-draw-fuzzer.cc | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit e0ac6c587bc5099d67c5026355f8acf62c1955a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 18:57:12 2022 -0600
+
+    Remove remaining traces of HB_EXPERIMENTAL_API
+
+ .github/workflows/coverity-scan.yml | 2 +-
+ meson.build                         | 5 -----
+ perf/perf.cc                        | 2 --
+ src/harfbuzz.cc                     | 1 +
+ test/api/test-ot-face.c             | 2 --
+ test/api/test-var-coords.c          | 2 --
+ test/fuzzing/hb-draw-fuzzer.cc      | 8 --------
+ 7 files changed, 2 insertions(+), 20 deletions(-)
+
+commit 5207ce828aacef52e43beaf9ba8c712b8107db21
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 18:54:10 2022 -0600
+
+    [draw] Enable draw tests
+    
+    Disable two failing ones.
+
+ test/api/test-draw.c | 29 ++++++++++++-----------------
+ 1 file changed, 12 insertions(+), 17 deletions(-)
+
+commit 157caf254e4ffe552c3c35b99e3d87f46e320efb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 18:46:34 2022 -0600
+
+    [test-draw] Fix compiler warning
+
+ test/api/test-draw.c | 70 ++++++++++++++++++++++++++--------------------------
+ 1 file changed, 35 insertions(+), 35 deletions(-)
+
+commit 27dfd69fc702550b454a35e1aa7b0ad5676a602d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 18:13:46 2022 -0600
+
+    [draw] Another Since: tag update
+
+ src/hb-draw.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7ac23f4e7887fbbfd96317319b216029ad14561e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 18:12:03 2022 -0600
+
+    [draw] Whitespace
+
+ src/hb-draw.h | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+commit e157b50345214d804023cb744a2daaa5584278df
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 16:16:57 2022 -0600
+
+    [draw] Remove return value of hb_font_draw_glyph()
+
+ src/hb-draw-glyph.cc | 15 +++++++--------
+ src/hb-font.h        |  8 +++++---
+ src/main.cc          |  6 ++----
+ 3 files changed, 14 insertions(+), 15 deletions(-)
+
+commit ddc36df3322ff012956605f5fedeae23d893e3b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 16:15:04 2022 -0600
+
+    [draw] Move hb_font_draw_glyph() to hb-draw-glyph.cc
+
+ src/Makefile.sources |  1 +
+ src/hb-draw-glyph.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-draw.cc       | 35 ----------------------------
+ src/meson.build      |  1 +
+ 4 files changed, 66 insertions(+), 35 deletions(-)
+
+commit 9a1508a2be20c85b08557ec1b8224dc1af3113e3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 16:12:42 2022 -0600
+
+    [draw] Replace API Since tags with REPLACEME
+
+ src/hb-draw.cc | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit a428c1193c3ed5fe0ef3de92c3a87bdcfa1da390
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 16:09:46 2022 -0600
+
+    [main] Fix compiler warnings
+
+ src/main.cc | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit 35190dc9610100fb49050a224536c8b6dfe26b40
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 16:08:40 2022 -0600
+
+    [draw] Convert API to float instead of hb_position_t
+
+ src/hb-draw.cc          | 14 +++++++-------
+ src/hb-draw.h           | 14 +++++++-------
+ src/hb-draw.hh          | 24 ++++++++++++------------
+ src/hb-ot-cff1-table.cc | 10 +++++-----
+ src/hb-ot-cff2-table.cc | 10 +++++-----
+ src/hb-ot-glyf-table.hh | 28 ++++++++++++++--------------
+ src/main.cc             | 22 +++++++++++-----------
+ 7 files changed, 61 insertions(+), 61 deletions(-)
+
+commit d6e49b8278fee01fea521b2a157d797f17580b3f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 15:45:43 2022 -0600
+
+    [font] Add em_fscalef_[xy] That take and return float
+
+ src/hb-font.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 6c0b65a6a8a9a7fec31aaad04e29a01d7991db5c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 15:42:33 2022 -0600
+
+    [font] Add em_scaleff() that returns float
+
+ src/hb-font.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit dd7b6e2c3fddca7896f4cb306bc574b48c7a61a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 2 14:46:10 2022 -0600
+
+    [draw] Remove EXPERIMENTAL_API tag
+
+ src/gen-def.py          | 18 +-----------------
+ src/hb-draw.cc          |  2 --
+ src/hb-draw.h           |  2 --
+ src/hb-draw.hh          |  2 --
+ src/hb-font.h           |  2 --
+ src/hb-ot-cff1-table.cc |  2 --
+ src/hb-ot-cff1-table.hh |  2 --
+ src/hb-ot-cff2-table.cc |  2 --
+ src/hb-ot-cff2-table.hh |  2 --
+ src/hb-ot-glyf-table.hh |  2 --
+ src/main.cc             |  4 ++--
+ 11 files changed, 3 insertions(+), 37 deletions(-)
+
+commit 7af165dbf0617ae102a16e63d90e3001aab1065e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 12 21:25:24 2022 -0600
+
+    Fix compiler warning
+
+ src/hb-ot-shape-complex-use-machine.hh | 4 +++-
+ src/hb-ot-shape-complex-use-machine.rl | 4 +++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit b2f5131029111b8ca585f141845d4bee91469f5d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 12 21:08:43 2022 -0600
+
+    [ci] Add configs-ci.yml to test different configs
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2884
+
+ .github/workflows/configs-ci.yml | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+commit db04af27825621773a701b6226c3287d3615724f
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Feb 13 00:33:12 2022 +0200
+
+    Typo
+
+ NEWS | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
 commit 0a129961341da370ec82bfccdd11ec9b1094b5a2
 Author: Khaled Hosny <khaled at aliftype.com>
 Date:   Sun Feb 13 00:30:50 2022 +0200
@@ -74,6 +2471,54 @@
  .../fonts/crash-d223bc42a8226c4d655c417d63d9a76760d05985  | Bin 0 -> 316 bytes
  1 file changed, 0 insertions(+), 0 deletions(-)
 
+commit 27a6c895ba749c69c8dfd3a14714dd86504b6ad8
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Feb 11 16:19:43 2022 -0800
+
+    [subset] Fix memory leak in plan creation.
+
+ src/hb-subset-plan.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 670ef070bd3a7510fa9c524f79ee11944ce6ae0f
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Feb 11 16:01:33 2022 -0800
+
+    [subset] Change subset plan create to be or_fail.
+
+ src/hb-subset-plan.cc  | 18 +++++++++++-------
+ src/hb-subset.cc       |  7 +++----
+ src/hb-subset.h        |  4 ++--
+ test/api/test-subset.c |  3 ++-
+ 4 files changed, 18 insertions(+), 14 deletions(-)
+
+commit ae8d373bcf94d8cfd4416ff995c264259903aafa
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Feb 11 14:54:23 2022 -0800
+
+    [subset] add subset plan reference, set/get user data functions.
+
+ src/hb-subset-plan.cc  | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-subset.cc       |  4 ++--
+ src/hb-subset.h        | 22 ++++++++++++++++---
+ test/api/test-subset.c |  2 +-
+ 4 files changed, 81 insertions(+), 6 deletions(-)
+
+commit b65e48a7864d53d5047211b57428d2a8bfa95ce5
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Feb 11 12:44:58 2022 -0800
+
+    [subset] Add subset plan to public API.
+    
+    Add the ability to create a subset plan which an be used to gather info on things like glyph mappings in the final subset. The plan can then be passed on to perform the subsetting operation.
+
+ src/hb-subset-plan.cc  | 55 +++++++++++++++++++++++++++++++++++++++++++++-----
+ src/hb-subset-plan.hh  |  9 ---------
+ src/hb-subset.cc       | 29 +++++++++++++++++++++-----
+ src/hb-subset.h        | 28 +++++++++++++++++++++++++
+ test/api/test-subset.c | 38 ++++++++++++++++++++++++++++++++++
+ 5 files changed, 140 insertions(+), 19 deletions(-)
+
 commit 68937238791181b6172ea4cd3d127ff4f6bbdd98
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri Feb 11 13:16:25 2022 -0600
@@ -114,6 +2559,17 @@
  src/hb-algs.hh | 6 ++++++
  1 file changed, 6 insertions(+)
 
+commit e045dbf6174413eafea2169a7987b44b57a6bf84
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Feb 10 04:06:20 2022 +0200
+
+    [ci] Upgrade pip on MSVC job
+    
+    To avoid bad pre-installed version.
+
+ .github/workflows/msvc-ci.yml | 3 +++
+ 1 file changed, 3 insertions(+)
+
 commit 81754a5a962ebefef848237ee218c019f85ef316
 Author: Alexis King <lexi.lambda at gmail.com>
 Date:   Wed Feb 9 12:00:47 2022 -0600
@@ -130,6 +2586,17 @@
  test/api/test-ot-math.c    | 82 ++++++++++++++++++++++++++++++++++++++++++++++
  6 files changed, 230 insertions(+)
 
+commit 02a737e53249e1d4d24e80128fc294db1faa6557
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Feb 8 21:45:42 2022 +0200
+
+    Revert "[ci] Downgrade pip on MSVC jobs"
+    
+    This reverts commit c4cf5ddb272cb1c05a572db5b76629368f9054f5.
+
+ .github/workflows/msvc-ci.yml | 4 ----
+ 1 file changed, 4 deletions(-)
+
 commit 1bc4bad7a59e9d4d79d8faeb9e695df19aa494da
 Author: Alexis King <lexi.lambda at gmail.com>
 Date:   Mon Feb 7 19:57:25 2022 -0600

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1,3 +1,147 @@
+Overview of changes leading to 4.2.0
+Wednesday, March 30, 2022
+====================================
+- Source code reorganization, splitting large hb-ot-layout files into smaller,
+  per-subtable ones under OT/Layout/*. Code for more tables will follow suit in
+  later releases. (Garret Rieger, Behdad Esfahbod)
+- Revert Indic shaper change in previous release that broke some fonts and
+  instead make per-syllable restriction of “GSUB” application limited to
+  script-specific Indic features, while applying them and discretionary
+  features in one go. (Behdad Esfahbod)
+- Fix decoding of private in gvar table. (Behdad Esfahbod)
+- Fix handling of contextual lookups that delete too many glyphs. (Behdad Esfahbod)
+- Make “morx” deleted glyphs don’t block “GPOS” application. (Behdad Esfahbod)
+- Various build fixes. (Chun-wei Fan, Khaled Hosny)
+
+- New API
++hb_set_next_many() (Andrew John)
+
+
+Overview of changes leading to 4.1.0
+Wednesday, March 23, 2022
+====================================
+- Various OSS-Fuzz fixes. (Behdad Esfahbod)
+- Make fallback vertical-origin match FreeType’s. (Behdad Esfahbod)
+- Treat visible viramas like dependent vowels in USE shaper. (David Corbett)
+- Apply presentation forms features and discretionary features in one go in
+  Indic shaper, which seems to match Uniscribe and CoreText behaviour.
+  (Behdad Esfahbod, David Corbett)
+- Various bug fixes.
+
+- New API
++hb_set_add_sorted_array() (Andrew John)
+
+
+Overview of changes leading to 4.0.1
+Friday, March 11, 2022
+====================================
+- Update OpenType to AAT mappings for “hist” and “vrtr” features.
+  (Florian Pircher)
+- Update IANA Language Subtag Registry to 2022-03-02. (David Corbett)
+- Update USE shaper to allow any non-numeric tail in a symbol cluster, and
+  remove obsolete data overrides. (David Corbett)
+- Fix handling of baseline variations to return correctly scaled values.
+  (Matthias Clasen)
+- A new experimental hb_subset_repack_or_fail() to repack an array of objects,
+  eliminating offset overflows. The API is not available unless HarfBuzz is
+  built with experimental APIs enabled. (Qunxin Liu)
+
+- New experimental API
++hb_link_t
++hb_object_t
++hb_subset_repack_or_fail()
+
+
+Overview of changes leading to 4.0.0
+Tuesday, March 1, 2022
+====================================
+- New public API to create subset plan and gather information on things like
+  glyph mappings in the final subset. The plan can then be passed on to perform
+  the subsetting operation. (Garret Rieger)
+- Draw API for extracting glyph shapes have been extended and finalized and is
+  no longer an experimental API. The draw API supports glyf, CFF and CFF2
+  glyph outlines tables, and applies variation settings set on the font as well
+  as synthetic slant. The new public API is not backward compatible with the
+  previous, non-public, experimental API. (Behdad Esfahbod)
+- The hb-view tool will use HarfBuzz draw API to render the glyphs instead of
+  cairo-ft when compiled with Cairo 1.17.5 or newer, setting HB_DRAW
+  environment variable to 1 or 0 will force using or not use the draw API,
+  respectively. (Behdad Esfahbod)
+- The hb-shape and hb-view tools now default to using HarfBuzz’s own font
+  loading functions (ot) instead of FreeType ones (ft). They also have a new
+  option, --font-slant, to apply synthetic slant to the font. (Behdad Esfahbod)
+- HarfBuzz now supports more than 65535 (the OpenType limit) glyph shapes and
+  metrics. See https://github.com/be-fonts/boring-expansion-spec/issues/6 and
+  https://github.com/be-fonts/boring-expansion-spec/issues/7 for details.
+  (Behdad Esfahbod)
+- New API to get the dominant horizontal baseline tag for a given script.
+  (Behdad Esfahbod)
+- New API to get the baseline positions from the font, and synthesize missing
+  ones. As well as new API to get font metrics and synthesize missing ones.
+  (Matthias Clasen)
+- Improvements to finding dependencies on Windows when building with Visual
+  Studio. (Chun-wei Fan)
+- New buffer flag, HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT, that must be set
+  during shaping for HB_GLYPH_FLAG_UNSAFE_TO_CONCAT flag to be reliably
+  produced. This is to limit the performance hit of producing this flag to when
+  it is actually needed. (Behdad Esfahbod)
+- Documentation improvements. (Matthias Clasen)
+
+- New API
+ - General:
+   +HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT
+   +hb_var_num_t
+
+ - Draw:
+   +hb_draw_funcs_t
+   +hb_draw_funcs_create()
+   +hb_draw_funcs_reference()
+   +hb_draw_funcs_destroy()
+   +hb_draw_funcs_is_immutable()
+   +hb_draw_funcs_make_immutable()
+   +hb_draw_move_to_func_t
+   +hb_draw_funcs_set_move_to_func()
+   +hb_draw_line_to_func_t
+   +hb_draw_funcs_set_line_to_func()
+   +hb_draw_quadratic_to_func_t
+   +hb_draw_funcs_set_quadratic_to_func()
+   +hb_draw_cubic_to_func_t
+   +hb_draw_funcs_set_cubic_to_func()
+   +hb_draw_close_path_func_t
+   +hb_draw_funcs_set_close_path_func()
+   +hb_draw_state_t
+   +HB_DRAW_STATE_DEFAULT
+   +hb_draw_move_to()
+   +hb_draw_line_to()
+   +hb_draw_quadratic_to()
+   +hb_draw_cubic_to()
+   +hb_draw_close_path()
+   +hb_font_get_glyph_shape_func_t
+   +hb_font_funcs_set_glyph_shape_func()
+   +hb_font_get_glyph_shape()
+
+ - OpenType layout
+   +HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL
+   +HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL
+   +hb_ot_layout_get_horizontal_baseline_tag_for_script()
+   +hb_ot_layout_get_baseline_with_fallback()
+
+ - Metrics:
+   +hb_ot_metrics_get_position_with_fallback()
+
+ - Subset:
+   +hb_subset_plan_t
+   +hb_subset_plan_create_or_fail()
+   +hb_subset_plan_reference()
+   +hb_subset_plan_destroy()
+   +hb_subset_plan_set_user_data()
+   +hb_subset_plan_get_user_data()
+   +hb_subset_plan_execute_or_fail()
+   +hb_subset_plan_unicode_to_old_glyph_mapping()
+   +hb_subset_plan_new_to_old_glyph_mapping()
+   +hb_subset_plan_old_to_new_glyph_mapping()
+
+
 Overview of changes leading to 3.4.0
 Sunday, February 13, 2022
 ====================================
@@ -10,8 +154,8 @@
   ‘math’ tag. (Alexis King)
 - It is now possible to get at once all math kerning values for a given glyph
   at a given corner. (Alexis King)
-- Fix locale_t portability issues on systems the typdef’s it to a void pointer.
-  (Behdad Esfahbod)
+- Fix locale_t portability issues on systems the typedef’s it to a void
+  pointer. (Behdad Esfahbod)
 
 - New API:
 +HB_BUFFER_FLAG_VERIFY
@@ -18,7 +162,7 @@
 +HB_OT_TAG_MATH_SCRIPT
 +HB_SCRIPT_MATH
 +hb_ot_math_kern_entry_t
-+hb_ot_math_get_glyph_kernings
++hb_ot_math_get_glyph_kernings()
 
 - Deprecated API
 +HB_OT_MATH_SCRIPT

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/TODO
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/TODO	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/TODO	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1,28 +0,0 @@
-API issues:
-===========
-
-- API to accept a list of languages?
-
-- Remove hb_ot_shape_glyphs_closure()?
-
-
-API additions
-=============
-
-- Language to/from script.
-
-- Add hb-cairo glue
-
-- Add sanitize API.
-
-- Add query / enumeration API for aalt-like features?
-
-- Add segmentation API
-
-- Add hb-fribidi glue?
-
-
-hb-view / hb-shape enhancements:
-===============================
-
-- Add --width, --height, --auto-size, --ink-box, --align, etc?

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2022-04-03 22:28:02 UTC (rev 62894)
@@ -12,6 +12,10 @@
 /* Have cairo-ft support in cairo graphics library */
 #undef HAVE_CAIRO_FT
 
+/* Define to 1 if you have the
+   `cairo_user_font_face_set_render_color_glyph_func' function. */
+#undef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
+
 /* Have chafa terminal graphics library */
 #undef HAVE_CHAFA
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [3.4.0],
+        [4.2.0],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
@@ -194,6 +194,10 @@
 have_cairo=false
 if test "x$with_cairo" = "xyes" -o "x$with_cairo" = "xauto"; then
 	PKG_CHECK_MODULES(CAIRO, cairo >= 1.8.0, have_cairo=true, :)
+	save_libs=$LIBS
+	LIBS="$LIBS $CAIRO_LIBS"
+	AC_CHECK_FUNCS(cairo_user_font_face_set_render_color_glyph_func)
+	LIBS=$save_libs
 fi
 if test "x$with_cairo" = "xyes" -a "x$have_cairo" != "xtrue"; then
 	AC_MSG_ERROR([cairo support requested but not found])

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1,6 +1,6 @@
 project('harfbuzz', 'c', 'cpp',
   meson_version: '>= 0.55.0',
-  version: '3.4.0',
+  version: '4.2.0',
   default_options: [
     'cpp_rtti=false',       # Just to support msvc, we are passing -fno-exceptions also anyway
     'cpp_std=c++11',
@@ -83,55 +83,30 @@
 
 m_dep = cpp.find_library('m', required: false)
 
-freetype_dep = null_dep
-if not get_option('freetype').disabled()
-  freetype_dep = dependency('freetype2', required: false)
+# https://github.com/harfbuzz/harfbuzz/pull/2498
+freetype_dep = dependency(cpp.get_argument_syntax() == 'msvc' ? 'freetype' : 'freetype2',
+                          required: get_option('freetype'),
+                          default_options: ['harfbuzz=disabled'])
 
-  if (not freetype_dep.found() and
-      cpp.get_id() == 'msvc' and
-      cpp.has_header('ft2build.h'))
-    freetype_dep = cpp.find_library('freetype', required: false)
-  endif
-
-  if not freetype_dep.found()
-    # https://github.com/harfbuzz/harfbuzz/pull/2498
-    freetype_dep = dependency('freetype2', required: get_option('freetype'),
-                              default_options: ['harfbuzz=disabled'])
-  endif
-endif
-
 glib_dep = dependency('glib-2.0', required: get_option('glib'))
 gobject_dep = dependency('gobject-2.0', required: get_option('gobject'))
 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()
-  icu_dep = dependency('icu-uc', required: false)
-
-  if (not icu_dep.found() and
-      cpp.get_id() == 'msvc' and
-      cpp.has_header('unicode/uchar.h') and
-      cpp.has_header('unicode/unorm2.h') and
-      cpp.has_header('unicode/ustring.h') and
-      cpp.has_header('unicode/utf16.h') and
-      cpp.has_header('unicode/uversion.h') and
-      cpp.has_header('unicode/uscript.h'))
-    if get_option('buildtype') == 'debug'
-      icu_dep = cpp.find_library('icuucd', required: false)
-    else
-      icu_dep = cpp.find_library('icuuc', required: false)
-    endif
-  endif
-
-  if not icu_dep.found()
-    icu_dep = dependency('icu-uc', required: get_option('icu'))
-  endif
+if cpp.get_argument_syntax() == 'msvc'
+  icu_dep = dependency('ICU',
+                       required: get_option('icu'),
+                       components: 'uc',
+                       method: 'cmake')
+else
+  icu_dep = dependency('icu-uc',
+                       required: get_option('icu'),
+                       method: 'pkg-config')
 endif
 
 if icu_dep.found() and icu_dep.type_name() == 'pkgconfig'
-  icu_defs = icu_dep.get_variable(pkgconfig: 'DEFS', default_value: '')
-  if icu_defs != ''
+  icu_defs = icu_dep.get_variable(pkgconfig: 'DEFS', default_value: '').split()
+  if icu_defs.length() > 0
     add_project_arguments(icu_defs, language: ['c', 'cpp'])
   endif
 endif
@@ -186,6 +161,11 @@
 
 if cairo_dep.found()
   conf.set('HAVE_CAIRO', 1)
+  if cairo_dep.type_name() == 'internal'
+    conf.set('HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC', 1)
+  else
+    check_funcs += [['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}]]
+  endif
 endif
 
 if cairo_ft_dep.found()

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2022-04-03 22:28:02 UTC (rev 62894)
@@ -88,6 +88,28 @@
 	hb-ot-layout-gdef-table.hh \
 	hb-ot-layout-gpos-table.hh \
 	hb-ot-layout-gsub-table.hh \
+	OT/Layout/GSUB/Common.hh \
+	OT/Layout/GSUB/Sequence.hh \
+	OT/Layout/GSUB/SingleSubstFormat1.hh \
+	OT/Layout/GSUB/SingleSubstFormat2.hh \
+	OT/Layout/GSUB/SingleSubst.hh \
+	OT/Layout/GSUB/MultipleSubstFormat1.hh \
+	OT/Layout/GSUB/MultipleSubst.hh \
+	OT/Layout/GSUB/AlternateSubstFormat1.hh \
+	OT/Layout/GSUB/AlternateSubst.hh \
+	OT/Layout/GSUB/AlternateSet.hh \
+	OT/Layout/GSUB/LigatureSubstFormat1.hh \
+	OT/Layout/GSUB/LigatureSubst.hh \
+	OT/Layout/GSUB/LigatureSet.hh \
+	OT/Layout/GSUB/Ligature.hh \
+	OT/Layout/GSUB/ReverseChainSingleSubst.hh \
+	OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh \
+	OT/Layout/GSUB/ContextSubst.hh \
+	OT/Layout/GSUB/ChainContextSubst.hh \
+	OT/Layout/GSUB/ExtensionSubst.hh \
+	OT/Layout/GSUB/SubstLookupSubTable.hh \
+	OT/Layout/GSUB/SubstLookup.hh \
+	OT/Layout/GSUB/GSUB.hh \
 	hb-ot-layout-gsubgpos.hh \
 	hb-ot-layout-jstf-table.hh \
 	hb-ot-layout.cc \
@@ -275,6 +297,7 @@
 	hb-subset-input.hh \
 	hb-subset-plan.cc \
 	hb-subset-plan.hh \
+	hb-subset-repacker.cc \
 	hb-subset.cc \
 	hb-subset.hh \
 	hb-repacker.hh \
@@ -282,6 +305,7 @@
 
 HB_SUBSET_headers = \
 	hb-subset.h \
+	hb-subset-repacker.h \
 	$(NULL)
 
 HB_GOBJECT_DIST_sources = hb-gobject-structs.cc

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,110 @@
+#ifndef OT_LAYOUT_GSUB_ALTERNATESET_HH
+#define OT_LAYOUT_GSUB_ALTERNATESET_HH
+
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct AlternateSet
+{
+  protected:
+  Array16Of<HBGlyphID16>
+                alternates;             /* Array of alternate GlyphIDs--in
+                                         * arbitrary order */
+  public:
+  DEFINE_SIZE_ARRAY (2, alternates);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (alternates.sanitize (c));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  { return hb_any (alternates, glyphs); }
+
+  void closure (hb_closure_context_t *c) const
+  { c->output->add_array (alternates.arrayZ, alternates.len); }
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  { c->output->add_array (alternates.arrayZ, alternates.len); }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int count = alternates.len;
+
+    if (unlikely (!count)) return_trace (false);
+
+    hb_mask_t glyph_mask = c->buffer->cur().mask;
+    hb_mask_t lookup_mask = c->lookup_mask;
+
+    /* Note: This breaks badly if two features enabled this lookup together. */
+    unsigned int shift = hb_ctz (lookup_mask);
+    unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
+
+    /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */
+    if (alt_index == HB_OT_MAP_MAX_VALUE && c->random)
+    {
+      /* Maybe we can do better than unsafe-to-break all; but since we are
+       * changing random state, it would be hard to track that.  Good 'nough. */
+      c->buffer->unsafe_to_break (0, c->buffer->len);
+      alt_index = c->random_number () % count + 1;
+    }
+
+    if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
+
+    c->replace_glyph (alternates[alt_index - 1]);
+
+    return_trace (true);
+  }
+
+  unsigned
+  get_alternates (unsigned        start_offset,
+                  unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+                  hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
+  {
+    if (alternates.len && alternate_count)
+    {
+      + alternates.sub_array (start_offset, alternate_count)
+      | hb_sink (hb_array (alternate_glyphs, *alternate_count))
+      ;
+    }
+    return alternates.len;
+  }
+
+  template <typename Iterator,
+            hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c,
+                  Iterator alts)
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (alternates.serialize (c, alts));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto it =
+      + hb_iter (alternates)
+      | hb_filter (glyphset)
+      | hb_map (glyph_map)
+      ;
+
+    auto *out = c->serializer->start_embed (*this);
+    return_trace (out->serialize (c->serializer, it) &&
+                  out->alternates);
+  }
+};
+
+}
+}
+}
+
+
+#endif /* OT_LAYOUT_GSUB_ALTERNATESET_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,51 @@
+#ifndef OT_LAYOUT_GSUB_ALTERNATESUBST_HH
+#define OT_LAYOUT_GSUB_ALTERNATESUBST_HH
+
+#include "AlternateSubstFormat1.hh"
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct AlternateSubst
+{
+  protected:
+  union {
+  HBUINT16              format;         /* Format identifier */
+  AlternateSubstFormat1 format1;
+  } u;
+  public:
+
+  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)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  hb_sorted_array_t<const HBGlyphID16> glyphs,
+                  hb_array_t<const unsigned int> alternate_len_list,
+                  hb_array_t<const HBGlyphID16> alternate_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    unsigned int format = 1;
+    u.format = format;
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list));
+    default:return_trace (false);
+    }
+  }
+};
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_ALTERNATESUBST_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubstFormat1.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubstFormat1.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,128 @@
+#ifndef OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH
+#define OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH
+
+#include "AlternateSet.hh"
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct AlternateSubstFormat1
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  Offset16To<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  Array16OfOffset16To<AlternateSet>
+                alternateSet;           /* Array of AlternateSet tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, alternateSet);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  { return (this+coverage).intersects (glyphs); }
+
+  bool may_have_non_1to1 () const
+  { return false; }
+
+  void closure (hb_closure_context_t *c) const
+  {
+    + hb_zip (this+coverage, alternateSet)
+    | hb_filter (c->parent_active_glyphs (), hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
+    ;
+
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+    + hb_zip (this+coverage, alternateSet)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
+    ;
+  }
+
+  const Coverage &get_coverage () const { return this+coverage; }
+
+  bool would_apply (hb_would_apply_context_t *c) const
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
+
+  unsigned
+  get_glyph_alternates (hb_codepoint_t  gid,
+                        unsigned        start_offset,
+                        unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+                        hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
+  { return (this+alternateSet[(this+coverage).get_coverage (gid)])
+           .get_alternates (start_offset, alternate_count, alternate_glyphs); }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    return_trace ((this+alternateSet[index]).apply (c));
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  hb_sorted_array_t<const HBGlyphID16> glyphs,
+                  hb_array_t<const unsigned int> alternate_len_list,
+                  hb_array_t<const HBGlyphID16> alternate_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    if (unlikely (!alternateSet.serialize (c, glyphs.length))) return_trace (false);
+    for (unsigned int i = 0; i < glyphs.length; i++)
+    {
+      unsigned int alternate_len = alternate_len_list[i];
+      if (unlikely (!alternateSet[i]
+                        .serialize_serialize (c, alternate_glyphs_list.sub_array (0, alternate_len))))
+        return_trace (false);
+      alternate_glyphs_list += alternate_len;
+    }
+    return_trace (coverage.serialize_serialize (c, glyphs));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    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);
+    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, alternateSet)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->alternateSet, 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 (bool (new_coverage));
+  }
+};
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ChainContextSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ChainContextSubst.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ChainContextSubst.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,18 @@
+#ifndef OT_LAYOUT_GSUB_CHAINCONTEXTSUBST_HH
+#define OT_LAYOUT_GSUB_CHAINCONTEXTSUBST_HH
+
+// TODO(garretrieger): move to new layout.
+#include "../../../hb-ot-layout-gsubgpos.hh"
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct ChainContextSubst : ChainContext {};
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_CHAINCONTEXTSUBST_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Common.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Common.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,21 @@
+#ifndef OT_LAYOUT_GSUB_COMMON_HH
+#define OT_LAYOUT_GSUB_COMMON_HH
+
+#include "../../../hb-serialize.hh"
+#include "../../../hb-ot-layout-gsubgpos.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
+
+template<typename Iterator>
+static void SingleSubst_serialize (hb_serialize_context_t *c,
+                                   Iterator it);
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GSUB_COMMON_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ContextSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ContextSubst.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ContextSubst.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,18 @@
+#ifndef OT_LAYOUT_GSUB_CONTEXTSUBST_HH
+#define OT_LAYOUT_GSUB_CONTEXTSUBST_HH
+
+// TODO(garretrieger): move to new layout.
+#include "../../../hb-ot-layout-gsubgpos.hh"
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct ContextSubst : Context {};
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_CONTEXTSUBST_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ExtensionSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ExtensionSubst.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ExtensionSubst.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,22 @@
+#ifndef OT_LAYOUT_GSUB_EXTENSIONSUBST_HH
+#define OT_LAYOUT_GSUB_EXTENSIONSUBST_HH
+
+// TODO(garretrieger): move to new layout.
+#include "../../../hb-ot-layout-gsubgpos.hh"
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct ExtensionSubst : Extension<ExtensionSubst>
+{
+  typedef struct SubstLookupSubTable SubTable;
+  bool is_reverse () const;
+};
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_EXTENSIONSUBST_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/GSUB.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/GSUB.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/GSUB.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,58 @@
+#ifndef OT_LAYOUT_GSUB_GSUB_HH
+#define OT_LAYOUT_GSUB_GSUB_HH
+
+// TODO(garretrieger): move to new layout.
+#include "../../../hb-ot-layout-gsubgpos.hh"
+#include "Common.hh"
+#include "SubstLookup.hh"
+
+using OT::Layout::GSUB::SubstLookup;
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+/*
+ * GSUB -- Glyph Substitution
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gsub
+ */
+
+struct GSUB : GSUBGPOS
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_GSUB;
+
+  const SubstLookup& get_lookup (unsigned int i) const
+  { return static_cast<const SubstLookup &> (GSUBGPOS::get_lookup (i)); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_langsys, c->plan->gsub_features);
+    return GSUBGPOS::subset<SubstLookup> (&l);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  { return GSUBGPOS::sanitize<SubstLookup> (c); }
+
+  HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
+                                   hb_face_t *face) const;
+
+  void closure_lookups (hb_face_t      *face,
+                        const hb_set_t *glyphs,
+                        hb_set_t       *lookup_indexes /* IN/OUT */) const
+  { GSUBGPOS::closure_lookups<SubstLookup> (face, glyphs, lookup_indexes); }
+
+  typedef GSUBGPOS::accelerator_t<GSUB> accelerator_t;
+};
+
+
+}
+}
+
+struct GSUB_accelerator_t : Layout::GSUB::GSUB::accelerator_t {
+  GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::GSUB::accelerator_t (face) {}
+};
+
+
+}
+
+#endif  /* OT_LAYOUT_GSUB_GSUB_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,135 @@
+#ifndef OT_LAYOUT_GSUB_LIGATURE_HH
+#define OT_LAYOUT_GSUB_LIGATURE_HH
+
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct Ligature
+{
+  protected:
+  HBGlyphID16   ligGlyph;               /* GlyphID of ligature to substitute */
+  HeadlessArrayOf<HBGlyphID16>
+                component;              /* Array of component GlyphIDs--start
+                                         * with the second  component--ordered
+                                         * in writing direction */
+  public:
+  DEFINE_SIZE_ARRAY (4, component);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (ligGlyph.sanitize (c) && component.sanitize (c));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  { return hb_all (component, glyphs); }
+
+  void closure (hb_closure_context_t *c) const
+  {
+    if (!intersects (c->glyphs)) return;
+    c->output->add (ligGlyph);
+  }
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    c->input->add_array (component.arrayZ, component.get_length ());
+    c->output->add (ligGlyph);
+  }
+
+  bool would_apply (hb_would_apply_context_t *c) const
+  {
+    if (c->len != component.lenP1)
+      return false;
+
+    for (unsigned int i = 1; i < c->len; i++)
+      if (likely (c->glyphs[i] != component[i]))
+        return false;
+
+    return true;
+  }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int count = component.lenP1;
+
+    if (unlikely (!count)) return_trace (false);
+
+    /* Special-case to make it in-place and not consider this
+     * as a "ligated" substitution. */
+    if (unlikely (count == 1))
+    {
+      c->replace_glyph (ligGlyph);
+      return_trace (true);
+    }
+
+    unsigned int total_component_count = 0;
+
+    unsigned int match_end = 0;
+    unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
+
+    if (likely (!match_input (c, count,
+                              &component[1],
+                              match_glyph,
+                              nullptr,
+                              &match_end,
+                              match_positions,
+                              &total_component_count)))
+    {
+      c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
+      return_trace (false);
+    }
+
+    ligate_input (c,
+                  count,
+                  match_positions,
+                  match_end,
+                  ligGlyph,
+                  total_component_count);
+
+    return_trace (true);
+  }
+
+  template <typename Iterator,
+            hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c,
+                  hb_codepoint_t ligature,
+                  Iterator components /* Starting from second */)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    ligGlyph = ligature;
+    if (unlikely (!component.serialize (c, components))) return_trace (false);
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    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)
+      | hb_map (glyph_map)
+      ;
+
+    auto *out = c->serializer->start_embed (*this);
+    return_trace (out->serialize (c->serializer,
+                                  glyph_map[ligGlyph],
+                                  it));  }
+};
+
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_LIGATURE_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,118 @@
+#ifndef OT_LAYOUT_GSUB_LIGATURESET_HH
+#define OT_LAYOUT_GSUB_LIGATURESET_HH
+
+#include "Common.hh"
+#include "Ligature.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct LigatureSet
+{
+  protected:
+  Array16OfOffset16To<Ligature>
+                ligature;               /* Array LigatureSet tables
+                                         * ordered by preference */
+  public:
+  DEFINE_SIZE_ARRAY (2, ligature);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (ligature.sanitize (c, this));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    return
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
+    | hb_any
+    ;
+  }
+
+  void closure (hb_closure_context_t *c) const
+  {
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Ligature &_) { _.closure (c); })
+    ;
+  }
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
+    ;
+  }
+
+  bool would_apply (hb_would_apply_context_t *c) const
+  {
+    return
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
+    | hb_any
+    ;
+  }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int num_ligs = ligature.len;
+    for (unsigned int i = 0; i < num_ligs; i++)
+    {
+      const Ligature &lig = this+ligature[i];
+      if (lig.apply (c)) return_trace (true);
+    }
+
+    return_trace (false);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  hb_array_t<const HBGlyphID16> ligatures,
+                  hb_array_t<const unsigned int> component_count_list,
+                  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);
+    if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false);
+    for (unsigned int i = 0; i < ligatures.length; i++)
+    {
+      unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0);
+      if (unlikely (!ligature[i].serialize_serialize (c,
+                                                      ligatures[i],
+                                                      component_list.sub_array (0, component_count))))
+        return_trace (false);
+      component_list += component_count;
+    }
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    + hb_iter (ligature)
+    | 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));
+  }
+};
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_LIGATURESET_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,59 @@
+#ifndef OT_LAYOUT_GSUB_LIGATURESUBST_HH
+#define OT_LAYOUT_GSUB_LIGATURESUBST_HH
+
+#include "Common.hh"
+#include "LigatureSubstFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct LigatureSubst
+{
+  protected:
+  union {
+  HBUINT16              format;         /* Format identifier */
+  LigatureSubstFormat1  format1;
+  } u;
+
+  public:
+  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)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  hb_sorted_array_t<const HBGlyphID16> first_glyphs,
+                  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
+                  hb_array_t<const HBGlyphID16> ligatures_list,
+                  hb_array_t<const unsigned int> component_count_list,
+                  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);
+    unsigned int format = 1;
+    u.format = format;
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c,
+                                               first_glyphs,
+                                               ligature_per_first_glyph_count_list,
+                                               ligatures_list,
+                                               component_count_list,
+                                               component_list));
+    default:return_trace (false);
+    }
+  }
+};
+
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_LIGATURESUBST_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,165 @@
+#ifndef OT_LAYOUT_GSUB_LIGATURESUBSTFORMAT1_HH
+#define OT_LAYOUT_GSUB_LIGATURESUBSTFORMAT1_HH
+
+#include "Common.hh"
+#include "LigatureSet.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct LigatureSubstFormat1
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  Offset16To<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  Array16OfOffset16To<LigatureSet>
+                ligatureSet;            /* Array LigatureSet tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, ligatureSet);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    return
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map ([this, glyphs] (const Offset16To<LigatureSet> &_)
+              { return (this+_).intersects (glyphs); })
+    | hb_any
+    ;
+  }
+
+  bool may_have_non_1to1 () const
+  { return true; }
+
+  void closure (hb_closure_context_t *c) const
+  {
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_filter (c->parent_active_glyphs (), hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
+    ;
+
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); })
+    ;
+  }
+
+  const Coverage &get_coverage () const { return this+coverage; }
+
+  bool would_apply (hb_would_apply_context_t *c) const
+  {
+    unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
+    if (likely (index == NOT_COVERED)) return false;
+
+    const LigatureSet &lig_set = this+ligatureSet[index];
+    return lig_set.would_apply (c);
+  }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const LigatureSet &lig_set = this+ligatureSet[index];
+    return_trace (lig_set.apply (c));
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  hb_sorted_array_t<const HBGlyphID16> first_glyphs,
+                  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
+                  hb_array_t<const HBGlyphID16> ligatures_list,
+                  hb_array_t<const unsigned int> component_count_list,
+                  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);
+    if (unlikely (!ligatureSet.serialize (c, first_glyphs.length))) return_trace (false);
+    for (unsigned int i = 0; i < first_glyphs.length; i++)
+    {
+      unsigned int ligature_count = ligature_per_first_glyph_count_list[i];
+      if (unlikely (!ligatureSet[i]
+                        .serialize_serialize (c,
+                                              ligatures_list.sub_array (0, ligature_count),
+                                              component_count_list.sub_array (0, ligature_count),
+                                              component_list))) return_trace (false);
+      ligatures_list += ligature_count;
+      component_count_list += ligature_count;
+    }
+    return_trace (coverage.serialize_serialize (c, first_glyphs));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    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);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    // 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 ([&] (const LigatureSet& _) {
+      return _.intersects (&glyphset);
+    }, hb_second)
+    | hb_map (hb_first)
+    | 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))
+    ;
+
+    return_trace (bool (new_coverage));
+  }
+};
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_LIGATURESUBSTFORMAT1_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,53 @@
+#ifndef OT_LAYOUT_GSUB_MULTIPLESUBST_HH
+#define OT_LAYOUT_GSUB_MULTIPLESUBST_HH
+
+#include "Common.hh"
+#include "MultipleSubstFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct MultipleSubst
+{
+  protected:
+  union {
+  HBUINT16              format;         /* Format identifier */
+  MultipleSubstFormat1  format1;
+  } u;
+
+  public:
+
+  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)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  hb_sorted_array_t<const HBGlyphID16> glyphs,
+                  hb_array_t<const unsigned int> substitute_len_list,
+                  hb_array_t<const HBGlyphID16> substitute_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    unsigned int format = 1;
+    u.format = format;
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, substitute_glyphs_list));
+    default:return_trace (false);
+    }
+  }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GSUB_MULTIPLESUBST_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubstFormat1.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubstFormat1.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,120 @@
+#ifndef OT_LAYOUT_GSUB_MULTIPLESUBSTFORMAT1_HH
+#define OT_LAYOUT_GSUB_MULTIPLESUBSTFORMAT1_HH
+
+#include "Common.hh"
+#include "Sequence.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct MultipleSubstFormat1
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  Offset16To<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  Array16OfOffset16To<Sequence>
+                sequence;               /* Array of Sequence tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, sequence);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && sequence.sanitize (c, this));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  { return (this+coverage).intersects (glyphs); }
+
+  bool may_have_non_1to1 () const
+  { return true; }
+
+  void closure (hb_closure_context_t *c) const
+  {
+    + hb_zip (this+coverage, sequence)
+    | hb_filter (c->parent_active_glyphs (), hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Sequence &_) { _.closure (c); })
+    ;
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+    + hb_zip (this+coverage, sequence)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); })
+    ;
+  }
+
+  const Coverage &get_coverage () const { return this+coverage; }
+
+  bool would_apply (hb_would_apply_context_t *c) const
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    return_trace ((this+sequence[index]).apply (c));
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  hb_sorted_array_t<const HBGlyphID16> glyphs,
+                  hb_array_t<const unsigned int> substitute_len_list,
+                  hb_array_t<const HBGlyphID16> substitute_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    if (unlikely (!sequence.serialize (c, glyphs.length))) return_trace (false);
+    for (unsigned int i = 0; i < glyphs.length; i++)
+    {
+      unsigned int substitute_len = substitute_len_list[i];
+      if (unlikely (!sequence[i]
+                        .serialize_serialize (c, substitute_glyphs_list.sub_array (0, substitute_len))))
+        return_trace (false);
+      substitute_glyphs_list += substitute_len;
+    }
+    return_trace (coverage.serialize_serialize (c, glyphs));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    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);
+    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, sequence)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->sequence, 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 (bool (new_coverage));
+  }
+};
+
+}
+}
+}
+
+
+#endif /* OT_LAYOUT_GSUB_MULTIPLESUBSTFORMAT1_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,36 @@
+#ifndef OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBST_HH
+#define OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBST_HH
+
+#include "Common.hh"
+#include "ReverseChainSingleSubstFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct ReverseChainSingleSubst
+{
+  protected:
+  union {
+  HBUINT16                              format;         /* Format identifier */
+  ReverseChainSingleSubstFormat1        format1;
+  } u;
+
+  public:
+  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)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+};
+
+}
+}
+}
+
+#endif  /* HB_OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBST_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,228 @@
+#ifndef OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH
+#define OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH
+
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct ReverseChainSingleSubstFormat1
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  Offset16To<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of table */
+  Array16OfOffset16To<Coverage>
+                backtrack;              /* Array of coverage tables
+                                         * in backtracking sequence, in glyph
+                                         * sequence order */
+  Array16OfOffset16To<Coverage>
+                lookaheadX;             /* Array of coverage tables
+                                         * in lookahead sequence, in glyph
+                                         * sequence order */
+  Array16Of<HBGlyphID16>
+                substituteX;            /* Array of substitute
+                                         * GlyphIDs--ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_MIN (10);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
+      return_trace (false);
+    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+    if (!lookahead.sanitize (c, this))
+      return_trace (false);
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+    return_trace (substitute.sanitize (c));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    if (!(this+coverage).intersects (glyphs))
+      return false;
+
+    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+
+    unsigned int count;
+
+    count = backtrack.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (!(this+backtrack[i]).intersects (glyphs))
+        return false;
+
+    count = lookahead.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (!(this+lookahead[i]).intersects (glyphs))
+        return false;
+
+    return true;
+  }
+
+  bool may_have_non_1to1 () const
+  { return false; }
+
+  void closure (hb_closure_context_t *c) const
+  {
+    if (!intersects (c->glyphs)) return;
+
+    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+
+    + hb_zip (this+coverage, substitute)
+    | hb_filter (c->parent_active_glyphs (), hb_first)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+
+    unsigned int count;
+
+    count = backtrack.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return;
+
+    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+    count = lookahead.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return;
+
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+    count = substitute.len;
+    c->output->add_array (substitute.arrayZ, substitute.len);
+  }
+
+  const Coverage &get_coverage () const { return this+coverage; }
+
+  bool would_apply (hb_would_apply_context_t *c) const
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
+      return_trace (false); /* No chaining to this type */
+
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+
+    if (unlikely (index >= substitute.len)) return_trace (false);
+
+    unsigned int start_index = 0, end_index = 0;
+    if (match_backtrack (c,
+                         backtrack.len, (HBUINT16 *) backtrack.arrayZ,
+                         match_coverage, this,
+                         &start_index) &&
+        match_lookahead (c,
+                         lookahead.len, (HBUINT16 *) lookahead.arrayZ,
+                         match_coverage, this,
+                         c->buffer->idx + 1, &end_index))
+    {
+      c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
+      c->replace_glyph_inplace (substitute[index]);
+      /* Note: We DON'T decrease buffer->idx.  The main loop does it
+       * for us.  This is useful for preventing surprises if someone
+       * calls us through a Context lookup. */
+      return_trace (true);
+    }
+    else
+    {
+      c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
+      return_trace (false);
+    }
+  }
+
+  template<typename Iterator,
+           hb_requires (hb_is_iterator (Iterator))>
+  bool serialize_coverage_offset_array (hb_subset_context_t *c, Iterator it) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->serializer->start_embed<Array16OfOffset16To<Coverage>> ();
+
+    if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size)))
+      return_trace (false);
+
+    for (auto& offset : it) {
+      auto *o = out->serialize_append (c->serializer);
+      if (unlikely (!o) || !o->serialize_subset (c, offset, this))
+        return_trace (false);
+    }
+
+    return_trace (true);
+  }
+
+  template<typename Iterator, typename BacktrackIterator, typename LookaheadIterator,
+           hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_pair_t)),
+           hb_requires (hb_is_iterator (BacktrackIterator)),
+           hb_requires (hb_is_iterator (LookaheadIterator))>
+  bool serialize (hb_subset_context_t *c,
+                  Iterator coverage_subst_iter,
+                  BacktrackIterator backtrack_iter,
+                  LookaheadIterator lookahead_iter) const
+  {
+    TRACE_SERIALIZE (this);
+
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->check_success (out))) return_trace (false);
+    if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
+    if (unlikely (!c->serializer->embed (this->coverage))) return_trace (false);
+
+    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<HBGlyphID16>> ();
+    auto substitutes =
+    + coverage_subst_iter
+    | hb_map (hb_second)
+    ;
+
+    auto glyphs =
+    + coverage_subst_iter
+    | hb_map_retains_sorting (hb_first)
+    ;
+    if (unlikely (! c->serializer->check_success (substitute_out->serialize (c->serializer, substitutes))))
+        return_trace (false);
+
+    if (unlikely (!out->coverage.serialize_serialize (c->serializer, glyphs)))
+      return_trace (false);
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+    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 HBGlyphID16 &> p) -> hb_codepoint_pair_t
+                              { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
+    ;
+
+    return_trace (bool (it) && serialize (c, it, backtrack.iter (), lookahead.iter ()));
+  }
+};
+
+}
+}
+}
+
+#endif  /* HB_OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,103 @@
+#ifndef OT_LAYOUT_GSUB_SEQUENCE_HH
+#define OT_LAYOUT_GSUB_SEQUENCE_HH
+
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct Sequence
+{
+  protected:
+  Array16Of<HBGlyphID16>
+                substitute;             /* String of GlyphIDs to substitute */
+  public:
+  DEFINE_SIZE_ARRAY (2, substitute);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (substitute.sanitize (c));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  { return hb_all (substitute, glyphs); }
+
+  void closure (hb_closure_context_t *c) const
+  { c->output->add_array (substitute.arrayZ, substitute.len); }
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  { c->output->add_array (substitute.arrayZ, substitute.len); }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int count = substitute.len;
+
+    /* Special-case to make it in-place and not consider this
+     * as a "multiplied" substitution. */
+    if (unlikely (count == 1))
+    {
+      c->replace_glyph (substitute.arrayZ[0]);
+      return_trace (true);
+    }
+    /* Spec disallows this, but Uniscribe allows it.
+     * https://github.com/harfbuzz/harfbuzz/issues/253 */
+    else if (unlikely (count == 0))
+    {
+      c->buffer->delete_glyph ();
+      return_trace (true);
+    }
+
+    unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
+                         HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
+    unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur());
+
+    for (unsigned int i = 0; i < count; i++)
+    {
+      /* If is attached to a ligature, don't disturb that.
+       * https://github.com/harfbuzz/harfbuzz/issues/3069 */
+      if (!lig_id)
+        _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
+      c->output_glyph_for_component (substitute.arrayZ[i], klass);
+    }
+    c->buffer->skip_glyph ();
+
+    return_trace (true);
+  }
+
+  template <typename Iterator,
+            hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c,
+                  Iterator subst)
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (substitute.serialize (c, subst));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    if (!intersects (&glyphset)) return_trace (false);
+
+    auto it =
+    + hb_iter (substitute)
+    | hb_map (glyph_map)
+    ;
+
+    auto *out = c->serializer->start_embed (*this);
+    return_trace (out->serialize (c->serializer, it));
+  }
+};
+
+
+}
+}
+}
+
+
+#endif /* OT_LAYOUT_GSUB_SEQUENCE_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,75 @@
+#ifndef OT_LAYOUT_GSUB_SINGLESUBST_HH
+#define OT_LAYOUT_GSUB_SINGLESUBST_HH
+
+#include "Common.hh"
+#include "SingleSubstFormat1.hh"
+#include "SingleSubstFormat2.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct SingleSubst
+{
+  protected:
+  union {
+  HBUINT16              format;         /* Format identifier */
+  SingleSubstFormat1    format1;
+  SingleSubstFormat2    format2;
+  } u;
+
+  public:
+
+  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 ());
+    }
+  }
+
+  template<typename Iterator,
+           hb_requires (hb_is_sorted_source_of (Iterator,
+                                                const hb_codepoint_pair_t))>
+  bool serialize (hb_serialize_context_t *c,
+                  Iterator glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    unsigned format = 2;
+    unsigned delta = 0;
+    if (glyphs)
+    {
+      format = 1;
+      auto get_delta = [=] (hb_codepoint_pair_t _)
+                       { return (unsigned) (_.second - _.first) & 0xFFFF; };
+      delta = get_delta (*glyphs);
+      if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
+    }
+    u.format = format;
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c,
+                                               + glyphs
+                                               | hb_map_retains_sorting (hb_first),
+                                               delta));
+    case 2: return_trace (u.format2.serialize (c, glyphs));
+    default:return_trace (false);
+    }
+  }
+};
+
+template<typename Iterator>
+static void
+SingleSubst_serialize (hb_serialize_context_t *c,
+                       Iterator it)
+{ c->start_embed<SingleSubst> ()->serialize (c, it); }
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GSUB_SINGLESUBST_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,122 @@
+#ifndef OT_LAYOUT_GSUB_SINGLESUBSTFORMAT1_HH
+#define OT_LAYOUT_GSUB_SINGLESUBSTFORMAT1_HH
+
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct SingleSubstFormat1
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  Offset16To<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  HBUINT16      deltaGlyphID;           /* Add to original GlyphID to get
+                                         * substitute GlyphID, modulo 0x10000 */
+
+  public:
+  DEFINE_SIZE_STATIC (6);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  { return (this+coverage).intersects (glyphs); }
+
+  bool may_have_non_1to1 () const
+  { return false; }
+
+  void closure (hb_closure_context_t *c) const
+  {
+    unsigned d = deltaGlyphID;
+
+    + hb_iter (this+coverage)
+    | hb_filter (c->parent_active_glyphs ())
+    | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+    | hb_sink (c->output)
+    ;
+
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+    unsigned d = deltaGlyphID;
+    + hb_iter (this+coverage)
+    | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+    | hb_sink (c->output)
+    ;
+  }
+
+  const Coverage &get_coverage () const { return this+coverage; }
+
+  bool would_apply (hb_would_apply_context_t *c) const
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    /* According to the Adobe Annotated OpenType Suite, result is always
+     * limited to 16bit. */
+    glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu;
+    c->replace_glyph (glyph_id);
+
+    return_trace (true);
+  }
+
+  template<typename Iterator,
+           hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c,
+                  Iterator glyphs,
+                  unsigned delta)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false);
+    c->check_assign (deltaGlyphID, delta, HB_SERIALIZE_ERROR_INT_OVERFLOW);
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    hb_codepoint_t delta = deltaGlyphID;
+
+    auto it =
+    + hb_iter (this+coverage)
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting ([&] (hb_codepoint_t g) {
+                                return hb_codepoint_pair_t (g,
+                                                            (g + delta) & 0xFFFF); })
+    | hb_filter (glyphset, hb_second)
+    | hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t
+                              { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
+    ;
+
+    bool ret = bool (it);
+    SingleSubst_serialize (c->serializer, it);
+    return_trace (ret);
+  }
+};
+
+}
+}
+}
+
+
+#endif /* OT_LAYOUT_GSUB_SINGLESUBSTFORMAT1_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,120 @@
+#ifndef OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH
+#define OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH
+
+#include "Common.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct SingleSubstFormat2
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 2 */
+  Offset16To<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  Array16Of<HBGlyphID16>
+                substitute;             /* Array of substitute
+                                         * GlyphIDs--ordered by Coverage Index */
+
+  public:
+  DEFINE_SIZE_ARRAY (6, substitute);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && substitute.sanitize (c));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  { return (this+coverage).intersects (glyphs); }
+
+  bool may_have_non_1to1 () const
+  { return false; }
+
+  void closure (hb_closure_context_t *c) const
+  {
+    + hb_zip (this+coverage, substitute)
+    | hb_filter (c->parent_active_glyphs (), hb_first)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
+
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+    + hb_zip (this+coverage, substitute)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
+  }
+
+  const Coverage &get_coverage () const { return this+coverage; }
+
+  bool would_apply (hb_would_apply_context_t *c) const
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    if (unlikely (index >= substitute.len)) return_trace (false);
+
+    c->replace_glyph (substitute[index]);
+
+    return_trace (true);
+  }
+
+  template<typename Iterator,
+           hb_requires (hb_is_sorted_source_of (Iterator,
+                                                hb_codepoint_pair_t))>
+  bool serialize (hb_serialize_context_t *c,
+                  Iterator it)
+  {
+    TRACE_SERIALIZE (this);
+    auto substitutes =
+      + it
+      | hb_map (hb_second)
+      ;
+    auto glyphs =
+      + it
+      | hb_map_retains_sorting (hb_first)
+      ;
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false);
+    if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false);
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    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 HBGlyphID16 &> p) -> hb_codepoint_pair_t
+                              { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
+    ;
+
+    bool ret = bool (it);
+    SingleSubst_serialize (c->serializer, it);
+    return_trace (ret);
+  }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookup.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookup.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookup.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,224 @@
+#ifndef OT_LAYOUT_GSUB_SUBSTLOOKUP_HH
+#define OT_LAYOUT_GSUB_SUBSTLOOKUP_HH
+
+#include "Common.hh"
+#include "SubstLookupSubTable.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct SubstLookup : Lookup
+{
+  typedef SubstLookupSubTable SubTable;
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  { return Lookup::sanitize<SubTable> (c); }
+
+  const SubTable& get_subtable (unsigned int i) const
+  { return Lookup::get_subtable<SubTable> (i); }
+
+  static inline bool lookup_type_is_reverse (unsigned int lookup_type)
+  { return lookup_type == SubTable::ReverseChainSingle; }
+
+  bool is_reverse () const
+  {
+    unsigned int type = get_type ();
+    if (unlikely (type == SubTable::Extension))
+      return reinterpret_cast<const ExtensionSubst &> (get_subtable (0)).is_reverse ();
+    return lookup_type_is_reverse (type);
+  }
+
+  bool may_have_non_1to1 () const
+  {
+    hb_have_non_1to1_context_t c;
+    return dispatch (&c);
+  }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    return_trace (dispatch (c));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    hb_intersects_context_t c (glyphs);
+    return dispatch (&c);
+  }
+
+  hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const
+  {
+    if (!c->should_visit_lookup (this_index))
+      return hb_closure_context_t::default_return_value ();
+
+    c->set_recurse_func (dispatch_closure_recurse_func);
+
+    hb_closure_context_t::return_t ret = dispatch (c);
+
+    c->flush ();
+
+    return ret;
+  }
+
+  hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
+  {
+    if (c->is_lookup_visited (this_index))
+      return hb_closure_lookups_context_t::default_return_value ();
+
+    c->set_lookup_visited (this_index);
+    if (!intersects (c->glyphs))
+    {
+      c->set_lookup_inactive (this_index);
+      return hb_closure_lookups_context_t::default_return_value ();
+    }
+
+    c->set_recurse_func (dispatch_closure_lookups_recurse_func);
+
+    hb_closure_lookups_context_t::return_t ret = dispatch (c);
+    return ret;
+  }
+
+  hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
+    return dispatch (c);
+  }
+
+  template <typename set_t>
+  void collect_coverage (set_t *glyphs) const
+  {
+    hb_collect_coverage_context_t<set_t> c (glyphs);
+    dispatch (&c);
+  }
+
+  bool would_apply (hb_would_apply_context_t *c,
+                    const hb_ot_layout_lookup_accelerator_t *accel) const
+  {
+    if (unlikely (!c->len)) return false;
+    if (!accel->may_have (c->glyphs[0])) return false;
+      return dispatch (c);
+  }
+
+  static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
+
+  bool serialize_single (hb_serialize_context_t *c,
+                         uint32_t lookup_props,
+                         hb_sorted_array_t<const HBGlyphID16> glyphs,
+                         hb_array_t<const HBGlyphID16> substitutes)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
+    if (c->push<SubTable> ()->u.single.serialize (c, hb_zip (glyphs, substitutes)))
+    {
+      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
+      return_trace (true);
+    }
+    c->pop_discard ();
+    return_trace (false);
+  }
+
+  bool serialize_multiple (hb_serialize_context_t *c,
+                           uint32_t lookup_props,
+                           hb_sorted_array_t<const HBGlyphID16> glyphs,
+                           hb_array_t<const unsigned int> substitute_len_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);
+    if (c->push<SubTable> ()->u.multiple.
+        serialize (c,
+                   glyphs,
+                   substitute_len_list,
+                   substitute_glyphs_list))
+    {
+      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
+      return_trace (true);
+    }
+    c->pop_discard ();
+    return_trace (false);
+  }
+
+  bool serialize_alternate (hb_serialize_context_t *c,
+                            uint32_t lookup_props,
+                            hb_sorted_array_t<const HBGlyphID16> glyphs,
+                            hb_array_t<const unsigned int> alternate_len_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);
+
+    if (c->push<SubTable> ()->u.alternate.
+        serialize (c,
+                   glyphs,
+                   alternate_len_list,
+                   alternate_glyphs_list))
+    {
+      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
+      return_trace (true);
+    }
+    c->pop_discard ();
+    return_trace (false);
+  }
+
+  bool serialize_ligature (hb_serialize_context_t *c,
+                           uint32_t lookup_props,
+                           hb_sorted_array_t<const HBGlyphID16> first_glyphs,
+                           hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
+                           hb_array_t<const HBGlyphID16> ligatures_list,
+                           hb_array_t<const unsigned int> component_count_list,
+                           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);
+    if (c->push<SubTable> ()->u.ligature.
+        serialize (c,
+                   first_glyphs,
+                   ligature_per_first_glyph_count_list,
+                   ligatures_list,
+                   component_count_list,
+                   component_list))
+    {
+      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
+      return_trace (true);
+    }
+    c->pop_discard ();
+    return_trace (false);
+  }
+
+  template <typename context_t>
+  static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+
+  static inline typename hb_closure_context_t::return_t closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index);
+
+  static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index)
+  {
+    if (!c->should_visit_lookup (lookup_index))
+      return hb_empty_t ();
+
+    hb_closure_context_t::return_t ret = closure_glyphs_recurse_func (c, lookup_index, covered_seq_indices, seq_index, end_index);
+
+    /* While in theory we should flush here, it will cause timeouts because a recursive
+     * lookup can keep growing the glyph set.  Skip, and outer loop will retry up to
+     * HB_CLOSURE_MAX_STAGES time, which should be enough for every realistic font. */
+    //c->flush ();
+
+    return ret;
+  }
+
+  HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned lookup_index);
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
+
+  bool subset (hb_subset_context_t *c) const
+  { return Lookup::subset<SubTable> (c); }
+};
+
+
+}
+}
+}
+
+#endif  /* OT_LAYOUT_GSUB_SUBSTLOOKUP_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookupSubTable.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookupSubTable.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SubstLookupSubTable.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,77 @@
+#ifndef OT_LAYOUT_GSUB_SUBSTLOOKUPSUBTABLE_HH
+#define OT_LAYOUT_GSUB_SUBSTLOOKUPSUBTABLE_HH
+
+#include "Common.hh"
+#include "SingleSubst.hh"
+#include "MultipleSubst.hh"
+#include "AlternateSubst.hh"
+#include "LigatureSubst.hh"
+#include "ContextSubst.hh"
+#include "ChainContextSubst.hh"
+#include "ExtensionSubst.hh"
+#include "ReverseChainSingleSubst.hh"
+
+namespace OT {
+namespace Layout {
+namespace GSUB {
+
+struct SubstLookupSubTable
+{
+  friend struct ::OT::Lookup;
+  friend struct SubstLookup;
+
+  protected:
+  union {
+  SingleSubst                   single;
+  MultipleSubst                 multiple;
+  AlternateSubst                alternate;
+  LigatureSubst                 ligature;
+  ContextSubst                  context;
+  ChainContextSubst             chainContext;
+  ExtensionSubst                extension;
+  ReverseChainSingleSubst       reverseChainContextSingle;
+  } u;
+  public:
+  DEFINE_SIZE_MIN (0);
+
+  enum Type {
+    Single              = 1,
+    Multiple            = 2,
+    Alternate           = 3,
+    Ligature            = 4,
+    Context             = 5,
+    ChainContext        = 6,
+    Extension           = 7,
+    ReverseChainSingle  = 8
+  };
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
+  {
+    TRACE_DISPATCH (this, lookup_type);
+    switch (lookup_type) {
+    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 ());
+    }
+  }
+
+  bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
+  {
+    hb_intersects_context_t c (glyphs);
+    return dispatch (&c, lookup_type);
+  }
+};
+
+
+}
+}
+}
+
+#endif  /* HB_OT_LAYOUT_GSUB_SUBSTLOOKUPSUBTABLE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-c-linkage-decls.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-c-linkage-decls.py	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-c-linkage-decls.py	2022-04-03 22:28:02 UTC (rev 62894)
@@ -4,11 +4,19 @@
 
 os.chdir (os.getenv ('srcdir', os.path.dirname (__file__)))
 
+def removeprefix(s, prefix):
+    if s.startswith(prefix):
+        return s[len(prefix):]
+    else:
+        return s[:]
+
 HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \
 	[x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')]
-HBSOURCES = [os.path.basename (x) for x in os.getenv ('HBSOURCES', '').split ()] or \
-	[x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh'))]
-
+HBSOURCES = [
+    removeprefix(x, 'src%s' % os.path.sep) for x in os.getenv ('HBSOURCES', '').split ()
+] or [
+    x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh'))
+]
 stat = 0
 
 for x in HBHEADERS:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-header-guards.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-header-guards.py	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-header-guards.py	2022-04-03 22:28:02 UTC (rev 62894)
@@ -4,19 +4,30 @@
 
 os.chdir (os.getenv ('srcdir', os.path.dirname (__file__)))
 
+def removeprefix(s, prefix):
+    if s.startswith(prefix):
+        return s[len(prefix):]
+    else:
+        return s[:]
+
+
 HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \
 	[x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')]
-HBSOURCES = [os.path.basename (x) for x in os.getenv ('HBSOURCES', '').split ()] or \
-	[x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh'))]
+HBSOURCES = [
+    removeprefix(x, 'src%s' % os.path.sep) for x in os.getenv ('HBSOURCES', '').split ()
+] or [
+    x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh'))
+]
 
+
 stat = 0
 
 for x in HBHEADERS + HBSOURCES:
 	if not x.endswith ('h') or x == 'hb-gobject-structs.h': continue
-	tag = x.upper ().replace ('.', '_').replace ('-', '_')
+	tag = x.upper ().replace ('.', '_').replace ('-', '_').replace(os.path.sep, '_').replace('/', '_')
 	with open (x, 'r', encoding='utf-8') as f: content = f.read ()
 	if len (re.findall (tag + r'\b', content)) != 3:
-		print ('Ouch, header file %s does not have correct preprocessor guards' % x)
+		print ('Ouch, header file %s does not have correct preprocessor guards. Expected: %s' % (x, tag))
 		stat = 1
 
 sys.exit (stat)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-includes.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-includes.py	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-includes.py	2022-04-03 22:28:02 UTC (rev 62894)
@@ -4,11 +4,22 @@
 
 os.chdir (os.getenv ('srcdir', os.path.dirname (__file__)))
 
+def removeprefix(s, prefix):
+    if s.startswith(prefix):
+        return s[len(prefix):]
+    else:
+        return s[:]
+
 HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \
 	[x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')]
-HBSOURCES = [os.path.basename (x) for x in os.getenv ('HBSOURCES', '').split ()] or \
-	[x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh'))]
 
+HBSOURCES = [
+    removeprefix(x, 'src%s' % os.path.sep) for x in os.getenv ('HBSOURCES', '').split ()
+] or [
+    x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh'))
+]
+
+
 stat = 0
 
 print ('Checking that public header files #include "hb-common.h" or "hb.h" first (or none)')
@@ -25,7 +36,7 @@
 	with open (x, 'r', encoding='utf-8') as f: content = f.read ()
 	includes = re.findall (r'#.*include.*', content)
 	if includes:
-		if not len (re.findall (r'"hb.*\.hh"', includes[0])):
+		if not len (re.findall (r'".*\.hh"', includes[0])):
 			print ('failure on %s' % x)
 			stat = 1
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py	2022-04-03 22:28:02 UTC (rev 62894)
@@ -19,23 +19,7 @@
 if '--experimental-api' not in sys.argv:
 	# Move these to harfbuzz-sections.txt when got stable
 	experimental_symbols = \
-"""hb_font_draw_glyph
-hb_draw_funcs_t
-hb_draw_close_path_func_t
-hb_draw_cubic_to_func_t
-hb_draw_line_to_func_t
-hb_draw_move_to_func_t
-hb_draw_quadratic_to_func_t
-hb_draw_funcs_create
-hb_draw_funcs_destroy
-hb_draw_funcs_is_immutable
-hb_draw_funcs_make_immutable
-hb_draw_funcs_reference
-hb_draw_funcs_set_close_path_func
-hb_draw_funcs_set_cubic_to_func
-hb_draw_funcs_set_line_to_func
-hb_draw_funcs_set_move_to_func
-hb_draw_funcs_set_quadratic_to_func""".splitlines ()
+"""hb_subset_repack_or_fail""".splitlines ()
 	symbols = [x for x in symbols if x not in experimental_symbols]
 symbols = "\n".join (symbols)
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-harfbuzzcc.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-harfbuzzcc.py	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-harfbuzzcc.py	2022-04-03 22:28:02 UTC (rev 62894)
@@ -14,5 +14,9 @@
 with open (OUTPUT, "wb") as f:
 	f.write ("".join ('#include "{}"\n'.format (os.path.basename (x)) for x in sources if x.endswith (".cc")).encode ())
 
-# copy it also to src/
-shutil.copyfile (OUTPUT, os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT)))
+# copy it also to the source tree, but only if it has changed
+baseline_filename = os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT))
+with open(baseline_filename, "rb") as baseline:
+	with open(OUTPUT, "rb") as generated:
+		if baseline.read() != generated.read():
+			shutil.copyfile (OUTPUT, baseline_filename)

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-hb-version.py	2022-04-03 22:28:02 UTC (rev 62894)
@@ -32,5 +32,9 @@
 			.replace ("@HB_VERSION@", version)
 			.encode ())
 
-# copy it also to src/
-shutil.copyfile (OUTPUT, os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT)))
+# copy it also to the source tree, but only if it has changed
+baseline_filename = os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT))
+with open(baseline_filename, "rb") as baseline:
+	with open(OUTPUT, "rb") as generated:
+		if baseline.read() != generated.read():
+			shutil.copyfile (OUTPUT, baseline_filename)

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2022-04-03 22:28:02 UTC (rev 62894)
@@ -39,7 +39,7 @@
 		headers[j - 1].append(line)
 headers.append (["UnicodeData.txt does not have a header."])
 
-data = [{} for _ in files]
+unicode_data = [{} for _ in files]
 values = [{} for _ in files]
 for i, f in enumerate (files):
 	for line in f:
@@ -73,38 +73,16 @@
 
 		i0 = i if i < 7 else i - 7
 		for u in range (start, end + 1):
-			data[i0][u] = t
+			unicode_data[i0][u] = t
 		values[i0][t] = values[i0].get (t, 0) + end - start + 1
 
 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][0x1B61] = defaults[0]
-data[0][0x1B63] = defaults[0]
-data[0][0x1B64] = defaults[0]
-data[0][0x1B65] = defaults[0]
-data[0][0x1B66] = defaults[0]
-data[0][0x1B67] = defaults[0]
-data[0][0x1B69] = defaults[0]
-data[0][0x1B6A] = defaults[0]
-data[0][0x2060] = defaults[0]
-# TODO https://github.com/harfbuzz/harfbuzz/pull/1685
-data[0][0x1B5B] = 'Consonant_Placeholder'
-data[0][0x1B5C] = 'Consonant_Placeholder'
-data[0][0x1B5F] = 'Consonant_Placeholder'
-data[0][0x1B62] = 'Consonant_Placeholder'
-data[0][0x1B68] = 'Consonant_Placeholder'
-# TODO https://github.com/harfbuzz/harfbuzz/issues/1035
-data[0][0x11C44] = 'Consonant_Placeholder'
-data[0][0x11C45] = 'Consonant_Placeholder'
-# TODO https://github.com/harfbuzz/harfbuzz/pull/1399
-data[0][0x111C8] = 'Consonant_Placeholder'
-
 # Merge data into one dict:
 for i,v in enumerate (defaults):
 	values[i][v] = values[i].get (v, 0) + 1
 combined = {}
-for i,d in enumerate (data):
+for i,d in enumerate (unicode_data):
 	for u,v in d.items ():
 		if not u in combined:
 			if i >= 4:
@@ -112,8 +90,6 @@
 			combined[u] = list (defaults)
 		combined[u][i] = v
 combined = {k: v for k, v in combined.items() if v[6] not in DISABLED_SCRIPTS}
-data = combined
-del combined
 
 
 property_names = [
@@ -226,8 +202,8 @@
 	if UISC == Consonant_Placeholder: return True
 	return U in [0x2015, 0x2022, 0x25FB, 0x25FC, 0x25FD, 0x25FE]
 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]
+	# Also includes VARIATION_SELECTOR and ZWJ
+	return UISC == Joiner 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)
@@ -245,13 +221,7 @@
 def is_CONS_WITH_STACKER(U, UISC, UDI, UGC, AJT):
 	return UISC == Consonant_With_Stacker
 def is_HALANT(U, UISC, UDI, UGC, AJT):
-	return (UISC in [Virama, Invisible_Stacker]
-		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 == 0x1134D
+	return UISC == Virama
 def is_HALANT_NUM(U, UISC, UDI, UGC, AJT):
 	return UISC == Number_Joiner
 def is_HIEROGLYPH(U, UISC, UDI, UGC, AJT):
@@ -262,15 +232,21 @@
 	return UISC == Hieroglyph_Segment_Begin
 def is_HIEROGLYPH_SEGMENT_END(U, UISC, UDI, UGC, AJT):
 	return UISC == Hieroglyph_Segment_End
+def is_INVISIBLE_STACKER(U, UISC, UDI, UGC, AJT):
+	# Split off of HALANT
+	return (UISC == Invisible_Stacker
+		and not is_SAKOT(U, UISC, UDI, UGC, AJT)
+	)
 def is_ZWNJ(U, UISC, UDI, UGC, AJT):
 	return UISC == Non_Joiner
 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])
+	# Also includes BASE_IND and SYM
+	return ((UGC == Po or UISC in [Consonant_Dead, Joiner, Modifying_Letter, Other])
 		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)
+		and not is_Word_Joiner(U, UISC, UDI, UGC, AJT)
 	)
 def is_REPHA(U, UISC, UDI, UGC, AJT):
 	return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
@@ -280,13 +256,17 @@
 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, 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]))
+		UGC != Lo and UISC in [Vowel, Vowel_Dependent])
 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])))
+		UGC != Lo and UISC == Bindu)
+def is_Word_Joiner(U, UISC, UDI, UGC, AJT):
+	# Also includes Rsv
+	return (UDI and U not in [0x115F, 0x1160, 0x3164, 0xFFA0, 0x1BCA0, 0x1BCA1, 0x1BCA2, 0x1BCA3]
+		and UISC == Other
+		and not is_CGJ(U, UISC, UDI, UGC, AJT)
+	) or UGC == Cn
 
 use_mapping = {
 	'B':	is_BASE,
@@ -300,8 +280,8 @@
 	'SUB':	is_CONS_SUB,
 	'CS':	is_CONS_WITH_STACKER,
 	'H':	is_HALANT,
-	'HVM':	is_HALANT_OR_VOWEL_MODIFIER,
 	'HN':	is_HALANT_NUM,
+	'IS':	is_INVISIBLE_STACKER,
 	'G':	is_HIEROGLYPH,
 	'J':	is_HIEROGLYPH_JOINER,
 	'SB':	is_HIEROGLYPH_SEGMENT_BEGIN,
@@ -313,6 +293,7 @@
 	'SM':	is_SYM_MOD,
 	'V':	is_VOWEL,
 	'VM':	is_VOWEL_MOD,
+	'WJ':	is_Word_Joiner,
 }
 
 use_positions = {
@@ -348,7 +329,7 @@
 		'Blw': [Bottom],
 	},
 	'H': None,
-	'HVM': None,
+	'IS': None,
 	'B': None,
 	'FM': {
 		'Abv': [Top],
@@ -380,9 +361,6 @@
 		# the nasalization marks, maybe only for U+1CE9..U+1CF1.
 		if U == 0x1CED: UISC = Tone_Mark
 
-		# 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, UDI, UGC, AJT)]
 		assert len(values) == 1, "%s %s %s %s %s %s" % (hex(U), UISC, UDI, UGC, AJT, values)
 		USE = values[0]
@@ -416,8 +394,7 @@
 		out[U] = (USE, UBlock)
 	return out
 
-defaults = ('O', 'No_Block')
-data = map_to_use(data)
+use_data = map_to_use(combined)
 
 print ("/* == Start of generated table == */")
 print ("/*")
@@ -443,7 +420,7 @@
 total = 0
 used = 0
 last_block = None
-def print_block (block, start, end, data):
+def print_block (block, start, end, use_data):
 	global total, used, last_block
 	if block and block != last_block:
 		print ()
@@ -458,10 +435,16 @@
 		if u % 16 == 0:
 			print ()
 			print ("  /* %04X */" % u, end='')
-		if u in data:
+		if u in use_data:
 			num += 1
-		d = data.get (u, defaults)
-		print ("%6s," % d[0], end='')
+		d = use_data.get (u)
+		if d is not None:
+			d = d[0]
+		elif u in unicode_data[4]:
+			d = 'O'
+		else:
+			d = 'WJ'
+		print ("%6s," % d, end='')
 
 	total += end - start + 1
 	used += num
@@ -468,7 +451,7 @@
 	if block:
 		last_block = block
 
-uu = sorted (data.keys ())
+uu = sorted (use_data.keys ())
 
 last = -100000
 num = 0
@@ -491,19 +474,19 @@
 for u in uu:
 	if u <= last:
 		continue
-	if data[u][0] == 'O':
+	if use_data[u][0] == 'O':
 		continue
-	block = data[u][1]
+	block = use_data[u][1]
 
 	start = u//8*8
 	end = start+1
-	while end in uu and block == data[end][1]:
+	while end in uu and block == use_data[end][1]:
 		end += 1
 	end = (end-1)//8*8 + 7
 
 	if start != last + 1:
 		if start - last <= 1+16*3:
-			print_block (None, last+1, start-1, data)
+			print_block (None, last+1, start-1, use_data)
 		else:
 			if last >= 0:
 				ends.append (last + 1)
@@ -513,7 +496,7 @@
 			print ("#define use_offset_0x%04xu %d" % (start, offset))
 			starts.append (start)
 
-	print_block (block, start, end, data)
+	print_block (block, start, end, use_data)
 	last = end
 ends.append (last + 1)
 offset += ends[-1] - starts[-1]
@@ -524,8 +507,9 @@
 print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy))
 print ()
 print ("static inline uint8_t")
-print ("hb_use_get_category (hb_codepoint_t u)")
+print ("hb_use_get_category (hb_glyph_info_t info)")
 print ("{")
+print ("  hb_codepoint_t u = info.codepoint;")
 print ("  switch (u >> %d)" % page_bits)
 print ("  {")
 pages = set([u>>page_bits for u in starts+ends])
@@ -540,7 +524,9 @@
 print ("    default:")
 print ("      break;")
 print ("  }")
-print ("  return USE(O);")
+print ("  if (_hb_glyph_info_get_general_category (&info) == HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED)")
+print ("    return WJ;")
+print ("  return O;")
 print ("}")
 print ()
 for k in sorted(use_mapping.keys()):

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.pc.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.pc.in	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.pc.in	2022-04-03 22:28:02 UTC (rev 62894)
@@ -3,10 +3,10 @@
 libdir=%libdir%
 includedir=%includedir%
 
-Name: harfbuzz
+Name: harfbuzz subsetter
 Description: HarfBuzz font subsetter
 Version: %VERSION%
 
-Requires: harfbuzz
+Requires: harfbuzz = %VERSION%
 Libs: -L${libdir} -lharfbuzz-subset
 Cflags: -I${includedir}/harfbuzz

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -108,7 +108,7 @@
   {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS,               HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS,             HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS},
   {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT,                (hb_aat_layout_feature_selector_t) 7},
   {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT,            (hb_aat_layout_feature_selector_t) 7},
-  {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,               HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF},
+  {HB_TAG ('h','i','s','t'), (hb_aat_layout_feature_type_t) 40,                  (hb_aat_layout_feature_selector_t) 0,                          (hb_aat_layout_feature_selector_t) 1},
   {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA,          HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF},
   {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES,               HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON,        HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF},
   {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION,         HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL,                HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION},
@@ -170,6 +170,7 @@
   {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA,          HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON,         HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF},
   {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING,            HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT,          (hb_aat_layout_feature_selector_t) 7},
   {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION,   HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON,   HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF},
+  {HB_TAG ('v','r','t','r'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION,   (hb_aat_layout_feature_selector_t) 2,                          (hb_aat_layout_feature_selector_t) 3},
   {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS,      HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON,                HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF},
 };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -226,14 +226,8 @@
   template <typename T> constexpr auto
   impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
 
-/* Sadly, we must give further hints to VS2015 to build the following template item */
-#if !defined (_MSC_VER) || defined (__clang__) || (_MSC_VER >= 1910)
   template <typename T> constexpr auto
   impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
-#else
-  template <typename T> constexpr auto
-  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v).hash ())>>{} (hb_deref (v)))
-#endif
 
   template <typename T,
 	    hb_enable_if (std::is_integral<T>::value)> constexpr auto
@@ -504,7 +498,7 @@
 
   template <typename Q1, typename Q2,
 	    hb_enable_if (hb_is_convertible (T1, Q1) &&
-			  hb_is_convertible (T2, T2))>
+			  hb_is_convertible (T2, Q2))>
   operator hb_pair_t<Q1, Q2> () { return hb_pair_t<Q1, Q2> (first, second); }
 
   hb_pair_t<T1, T2> reverse () const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -86,6 +86,72 @@
   void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v)
   { if (v) add_range (a, b); else del_range (a, b); }
 
+
+  // Writes out page values to the array p. Returns the number of values
+  // written. At most size codepoints will be written.
+  unsigned int write (uint32_t        base,
+		      unsigned int    start_value,
+		      hb_codepoint_t *p,
+		      unsigned int    size) const
+  {
+    unsigned int start_v = start_value >> ELT_BITS_LOG_2;
+    unsigned int start_bit = start_value & ELT_MASK;
+    unsigned int count = 0;
+    for (unsigned i = start_v; i < len () && count < size; i++)
+    {
+      elt_t bits = v[i];
+      uint32_t v_base = base | (i << ELT_BITS_LOG_2);
+      for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++)
+      {
+	if ((elt_t(1) << j) & bits) {
+	  *p++ = v_base | j;
+	  count++;
+	}
+      }
+      start_bit = 0;
+    }
+    return count;
+  }
+
+  // Writes out the values NOT in this page to the array p. Returns the
+  // number of values written. At most size codepoints will be written.
+  // Returns the number of codepoints written. next_value holds the next value
+  // that should be written (if not present in this page). This is used to fill
+  // any missing value gaps between this page and the previous page, if any.
+  // next_value is updated to one more than the last value present in this page.
+  unsigned int write_inverted (uint32_t        base,
+			       unsigned int    start_value,
+			       hb_codepoint_t *p,
+			       unsigned int    size,
+			       hb_codepoint_t *next_value) const
+  {
+    unsigned int start_v = start_value >> ELT_BITS_LOG_2;
+    unsigned int start_bit = start_value & ELT_MASK;
+    unsigned int count = 0;
+    for (unsigned i = start_v; i < len () && count < size; i++)
+    {
+      elt_t bits = v[i];
+      uint32_t v_offset = i << ELT_BITS_LOG_2;
+      for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++)
+      {
+	if ((elt_t(1) << j) & bits)
+	{
+	  hb_codepoint_t value = base | v_offset | j;
+	  // Emit all the missing values from next_value up to value - 1.
+	  for (hb_codepoint_t k = *next_value; k < value && count < size; k++)
+	  {
+	    *p++ = k;
+	    count++;
+	  }
+	  // Skip over this value;
+	  *next_value = value + 1;
+	}
+      }
+      start_bit = 0;
+    }
+    return count;
+  }
+
   bool is_equal (const hb_bit_page_t &other) const
   {
     return 0 == hb_memcmp (&v, &other.v, sizeof (v));
@@ -179,6 +245,9 @@
   typedef unsigned long long elt_t;
   static constexpr unsigned PAGE_BITS = 512;
   static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
+  static constexpr unsigned PAGE_BITS_LOG_2 = 9;
+  static_assert (1 << PAGE_BITS_LOG_2 == PAGE_BITS, "");
+  static constexpr unsigned PAGE_BITMASK = PAGE_BITS - 1;
 
   static unsigned int elt_get_min (const elt_t &elt) { return hb_ctz (elt); }
   static unsigned int elt_get_max (const elt_t &elt) { return hb_bit_storage (elt) - 1; }
@@ -186,7 +255,10 @@
   typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t;
 
   static constexpr unsigned ELT_BITS = sizeof (elt_t) * 8;
+  static constexpr unsigned ELT_BITS_LOG_2 = 6;
+  static_assert (1 << ELT_BITS_LOG_2 == ELT_BITS, "");
   static constexpr unsigned ELT_MASK = ELT_BITS - 1;
+
   static constexpr unsigned BITS = sizeof (vector_t) * 8;
   static constexpr unsigned MASK = BITS - 1;
   static_assert ((unsigned) PAGE_BITS == (unsigned) BITS, "");

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -323,6 +323,14 @@
     return true;
   }
 
+  unsigned int next_many (hb_codepoint_t  codepoint,
+			  hb_codepoint_t *out,
+			  unsigned int    size) const
+  {
+    return inverted ? s.next_many_inverted (codepoint, out, size)
+		    : s.next_many (codepoint, out, size);
+  }
+
   static constexpr hb_codepoint_t INVALID = hb_bit_set_t::INVALID;
 
   /*

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -203,7 +203,7 @@
   bool set_sorted_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T))
   {
     if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
-    if (!count) return true;
+    if (unlikely (!count)) return true;
     dirty ();
     hb_codepoint_t g = *array;
     hb_codepoint_t last_g = g;
@@ -222,7 +222,7 @@
         if (v || page) /* The v check is to optimize out the page check if v is true. */
 	  page->add (g);
 
-	array = (const T *) ((const char *) array + stride);
+	array = &StructAtOffsetUnaligned<T> (array, stride);
 	count--;
       }
       while (count && (g = *array, g < end));
@@ -700,6 +700,99 @@
     return true;
   }
 
+  unsigned int next_many (hb_codepoint_t  codepoint,
+			  hb_codepoint_t *out,
+			  unsigned int    size) const
+  {
+    // By default, start at the first bit of the first page of values.
+    unsigned int start_page = 0;
+    unsigned int start_page_value = 0;
+    if (unlikely (codepoint != INVALID))
+    {
+      const auto* page_map_array = page_map.arrayZ;
+      unsigned int major = get_major (codepoint);
+      unsigned int i = last_page_lookup;
+      if (unlikely (i >= page_map.length || page_map_array[i].major != major))
+      {
+	page_map.bfind (major, &i, HB_NOT_FOUND_STORE_CLOSEST);
+	if (i >= page_map.length)
+	  return 0;  // codepoint is greater than our max element.
+      }
+      start_page = i;
+      start_page_value = page_remainder (codepoint + 1);
+      if (unlikely (start_page_value == 0))
+      {
+        // The export-after value was last in the page. Start on next page.
+        start_page++;
+        start_page_value = 0;
+      }
+    }
+
+    unsigned int initial_size = size;
+    for (unsigned int i = start_page; i < page_map.length && size; i++)
+    {
+      uint32_t base = major_start (page_map[i].major);
+      unsigned int n = pages[page_map[i].index].write (base, start_page_value, out, size);
+      out += n;
+      size -= n;
+      start_page_value = 0;
+    }
+    return initial_size - size;
+  }
+
+  unsigned int next_many_inverted (hb_codepoint_t  codepoint,
+				   hb_codepoint_t *out,
+				   unsigned int    size) const
+  {
+    unsigned int initial_size = size;
+    // By default, start at the first bit of the first page of values.
+    unsigned int start_page = 0;
+    unsigned int start_page_value = 0;
+    if (unlikely (codepoint != INVALID))
+    {
+      const auto* page_map_array = page_map.arrayZ;
+      unsigned int major = get_major (codepoint);
+      unsigned int i = last_page_lookup;
+      if (unlikely (i >= page_map.length || page_map_array[i].major != major))
+      {
+        page_map.bfind(major, &i, HB_NOT_FOUND_STORE_CLOSEST);
+        if (unlikely (i >= page_map.length))
+        {
+          // codepoint is greater than our max element.
+          while (++codepoint != INVALID && size)
+          {
+            *out++ = codepoint;
+            size--;
+          }
+          return initial_size - size;
+        }
+      }
+      start_page = i;
+      start_page_value = page_remainder (codepoint + 1);
+      if (unlikely (start_page_value == 0))
+      {
+        // The export-after value was last in the page. Start on next page.
+        start_page++;
+        start_page_value = 0;
+      }
+    }
+
+    hb_codepoint_t next_value = codepoint + 1;
+    for (unsigned int i=start_page; i<page_map.length && size; i++)
+    {
+      uint32_t base = major_start (page_map[i].major);
+      unsigned int n = pages[page_map[i].index].write_inverted (base, start_page_value, out, size, &next_value);
+      out += n;
+      size -= n;
+      start_page_value = 0;
+    }
+    while (next_value < HB_SET_VALUE_INVALID && size) {
+      *out++ = next_value++;
+      size--;
+    }
+    return initial_size - size;
+  }
+
   bool has_population () const { return population != UINT_MAX; }
   unsigned int get_population () const
   {
@@ -809,8 +902,9 @@
   }
   page_t &page_at (unsigned int i) { return pages[page_map[i].index]; }
   const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; }
-  unsigned int get_major (hb_codepoint_t g) const { return g / page_t::PAGE_BITS; }
-  hb_codepoint_t major_start (unsigned int major) const { return major * page_t::PAGE_BITS; }
+  unsigned int get_major (hb_codepoint_t g) const { return g >> page_t::PAGE_BITS_LOG_2; }
+  unsigned int page_remainder (hb_codepoint_t g) const { return g & page_t::PAGE_BITMASK; }
+  hb_codepoint_t major_start (unsigned int major) const { return major << page_t::PAGE_BITS_LOG_2; }
 };
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -478,7 +478,7 @@
 	case 18:
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
@@ -535,7 +535,7 @@
 	case 16:
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
@@ -635,7 +635,7 @@
 }
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
@@ -645,7 +645,7 @@
 	case 17:
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
@@ -674,7 +674,7 @@
 }
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
@@ -701,7 +701,7 @@
 }
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
@@ -733,7 +733,7 @@
 	case 16:
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
@@ -820,7 +820,7 @@
 }
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl	2022-04-03 22:28:02 UTC (rev 62894)
@@ -56,7 +56,7 @@
 action ensure_unicode { if (unlikely (!buffer->ensure_unicode ())) return false; }
 
 action parse_glyph {
-	/* TODO Unescape delimeters. */
+	/* TODO Unescape delimiters. */
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -397,7 +397,8 @@
     ret = false;
   if (!buffer_verify_unsafe_to_break (this, text_buffer, font, features, num_features, shapers))
     ret = false;
-  if (!buffer_verify_unsafe_to_concat (this, text_buffer, font, features, num_features, shapers))
+  if ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) != 0 &&
+      !buffer_verify_unsafe_to_concat (this, text_buffer, font, features, num_features, shapers))
     ret = false;
   if (!ret)
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -295,7 +295,6 @@
   idx = 0;
   len = 0;
   out_len = 0;
-
   out_info = info;
 
   memset (context, 0, sizeof context);
@@ -405,6 +404,7 @@
 reset:
   have_output = false;
   out_len = 0;
+  out_info = info;
   idx = 0;
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -117,7 +117,7 @@
  * 				   from there, and repeat.
  * 				   At the start of next line a similar algorithm can
  * 				   be implemented. That is: 1. Iterate forward from
- * 				   the line-break position untill the first cluster
+ * 				   the line-break position until the first cluster
  * 				   start position that is NOT unsafe-to-concat, 2.
  * 				   shape the segment from beginning of the line to
  * 				   that position, 3. check whether the resulting
@@ -137,7 +137,11 @@
  * 				   clusters.
  * 				   The #HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag will
  * 				   always imply this flag.
- * 				   Since: 3.3.0
+ *				   To use this flag, you must enable the buffer flag
+ *				   @HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT during
+ *				   shaping, otherwise the buffer flag will not be
+ *				   reliably produced.
+ * 				   Since: 4.0.0
  * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags.
  *
  * Flags for #hb_glyph_info_t.
@@ -365,6 +369,10 @@
  *                      handler is installed on the buffer, or a message is written
  *                      to standard error.  In either case, the shaping result might
  *                      be modified to show the failed output. Since: 3.4.0
+ * @HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT:
+ *                      flag indicating that the @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
+ *                      glyph-flag should be produced by the shaper. By default
+ *                      it will not be produced since it incurs a cost. Since: 4.0.0
  *
  * Flags for #hb_buffer_t.
  *
@@ -377,7 +385,8 @@
   HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES	= 0x00000004u,
   HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES	= 0x00000008u,
   HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE	= 0x00000010u,
-  HB_BUFFER_FLAG_VERIFY				= 0x00000020u
+  HB_BUFFER_FLAG_VERIFY				= 0x00000020u,
+  HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT	= 0x00000040u
 } hb_buffer_flags_t;
 
 HB_EXTERN void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -460,6 +460,8 @@
   }
   void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
   {
+    if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
+      return;
     _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
 		      start, end,
 		      true);
@@ -472,6 +474,8 @@
   }
   void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
   {
+    if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
+      return;
     _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
 		      start, end,
 		      false, true);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -130,7 +130,17 @@
   int8_t i8[4];
 } hb_var_int_t;
 
+typedef union _hb_var_num_t {
+  float f;
+  uint32_t u32;
+  int32_t i32;
+  uint16_t u16[2];
+  int16_t i16[2];
+  uint8_t u8[4];
+  int8_t i8[4];
+} hb_var_num_t;
 
+
 /* hb_tag_t */
 
 /**

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -85,6 +85,7 @@
 #ifdef HB_MINI
 #define HB_NO_AAT
 #define HB_NO_LEGACY
+#define HB_NO_BORING_EXPANSION
 #endif
 
 #if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -897,7 +897,7 @@
     DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs);
 
     buffer->len = 0;
-    uint32_t status_and = ~0, status_or = 0;
+    uint32_t status_or = 0;
     CGFloat advances_so_far = 0;
     /* For right-to-left runs, CoreText returns the glyphs positioned such that
      * any trailing whitespace is to the left of (0,0).  Adjust coordinate system
@@ -918,7 +918,6 @@
       CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i));
       CTRunStatus run_status = CTRunGetStatus (run);
       status_or  |= run_status;
-      status_and &= run_status;
       DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
       CGFloat run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr);
       if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
@@ -1140,21 +1139,6 @@
       buffer->len += num_glyphs;
     }
 
-    /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel,
-     * or if it does, it doesn't respect it.  So we get runs with wrong
-     * directions.  As such, disable the assert...  It wouldn't crash, but
-     * cursoring will be off...
-     *
-     * https://crbug.com/419769
-     */
-    if (false)
-    {
-      /* Make sure all runs had the expected direction. */
-      HB_UNUSED bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
-      assert (bool (status_and & kCTRunStatusRightToLeft) == backward);
-      assert (bool (status_or  & kCTRunStatusRightToLeft) == backward);
-    }
-
     buffer->clear_positions ();
 
     unsigned int count = buffer->len;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -25,237 +25,313 @@
 #include "hb.hh"
 
 #ifndef HB_NO_DRAW
-#ifdef HB_EXPERIMENTAL_API
 
 #include "hb-draw.hh"
-#include "hb-ot.h"
-#include "hb-ot-glyf-table.hh"
-#include "hb-ot-cff1-table.hh"
-#include "hb-ot-cff2-table.hh"
 
 /**
- * hb_draw_funcs_set_move_to_func:
- * @funcs: draw functions object
- * @move_to: move-to callback
+ * SECTION:hb-draw
+ * @title: hb-draw
+ * @short_description: Glyph drawing
+ * @include: hb.h
  *
- * Sets move-to callback to the draw functions object.
- *
- * Since: EXPERIMENTAL
+ * Functions for drawing (extracting) glyph shapes.
  **/
-void
-hb_draw_funcs_set_move_to_func (hb_draw_funcs_t        *funcs,
-				hb_draw_move_to_func_t  move_to)
+
+static void
+hb_draw_move_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
+		     hb_draw_state_t *st HB_UNUSED,
+		     float to_x HB_UNUSED, float to_y HB_UNUSED,
+		     void *user_data HB_UNUSED) {}
+
+static void
+hb_draw_line_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
+		     hb_draw_state_t *st HB_UNUSED,
+		     float to_x HB_UNUSED, float to_y HB_UNUSED,
+		     void *user_data HB_UNUSED) {}
+
+static void
+hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data,
+			  hb_draw_state_t *st,
+			  float control_x, float control_y,
+			  float to_x, float to_y,
+			  void *user_data HB_UNUSED)
 {
-  if (unlikely (hb_object_is_immutable (funcs))) return;
-  funcs->move_to = move_to;
+  dfuncs->emit_cubic_to (draw_data, *st,
+			 (st->current_x + 2.f * control_x) / 3.f,
+			 (st->current_y + 2.f * control_y) / 3.f,
+			 (to_x + 2.f * control_x) / 3.f,
+			 (to_y + 2.f * control_y) / 3.f,
+			 to_x, to_y);
 }
 
+static void
+hb_draw_cubic_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
+		      hb_draw_state_t *st HB_UNUSED,
+		      float control1_x HB_UNUSED, float control1_y HB_UNUSED,
+		      float control2_x HB_UNUSED, float control2_y HB_UNUSED,
+		      float to_x HB_UNUSED, float to_y HB_UNUSED,
+		      void *user_data HB_UNUSED) {}
+
+static void
+hb_draw_close_path_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
+			hb_draw_state_t *st HB_UNUSED,
+			void *user_data HB_UNUSED) {}
+
+
+#define HB_DRAW_FUNC_IMPLEMENT(name)						\
+										\
+void										\
+hb_draw_funcs_set_##name##_func (hb_draw_funcs_t	 *dfuncs,		\
+				 hb_draw_##name##_func_t  func,			\
+				 void			 *user_data,		\
+				 hb_destroy_func_t	  destroy)		\
+{										\
+  if (hb_object_is_immutable (dfuncs))						\
+    return;									\
+										\
+  if (dfuncs->destroy.name)							\
+    dfuncs->destroy.name (dfuncs->user_data.name);				\
+										\
+  if (func) {									\
+    dfuncs->func.name = func;							\
+    dfuncs->user_data.name = user_data;						\
+    dfuncs->destroy.name = destroy;						\
+  } else {									\
+    dfuncs->func.name = hb_draw_##name##_nil;					\
+    dfuncs->user_data.name = nullptr;						\
+    dfuncs->destroy.name = nullptr;						\
+  }										\
+}
+
+HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_DRAW_FUNC_IMPLEMENT
+
 /**
- * hb_draw_funcs_set_line_to_func:
- * @funcs: draw functions object
- * @line_to: line-to callback
+ * hb_draw_funcs_create: (Xconstructor)
  *
- * Sets line-to callback to the draw functions object.
+ * Creates a new draw callbacks object.
  *
- * Since: EXPERIMENTAL
+ * Return value: (transfer full):
+ * A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial
+ * reference count should be released with hb_draw_funcs_destroy when you are
+ * done using the #hb_draw_funcs_t. This function never returns %NULL. If
+ * memory cannot be allocated, a special singleton #hb_draw_funcs_t object will
+ * be returned.
+ *
+ * Since: 4.0.0
  **/
-void
-hb_draw_funcs_set_line_to_func (hb_draw_funcs_t        *funcs,
-				hb_draw_line_to_func_t  line_to)
+hb_draw_funcs_t *
+hb_draw_funcs_create ()
 {
-  if (unlikely (hb_object_is_immutable (funcs))) return;
-  funcs->line_to = line_to;
+  hb_draw_funcs_t *dfuncs;
+  if (unlikely (!(dfuncs = hb_object_create<hb_draw_funcs_t> ())))
+    return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
+
+  dfuncs->func =  Null (hb_draw_funcs_t).func;
+
+  return dfuncs;
 }
 
+DEFINE_NULL_INSTANCE (hb_draw_funcs_t) =
+{
+  HB_OBJECT_HEADER_STATIC,
+
+  {
+#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_nil,
+    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_DRAW_FUNC_IMPLEMENT
+  }
+};
+
+
 /**
- * hb_draw_funcs_set_quadratic_to_func:
- * @funcs: draw functions object
- * @move_to: quadratic-to callback
+ * hb_draw_funcs_reference: (skip)
+ * @dfuncs: draw functions
  *
- * Sets quadratic-to callback to the draw functions object.
+ * Increases the reference count on @dfuncs by one. This prevents @buffer from
+ * being destroyed until a matching call to hb_draw_funcs_destroy() is made.
  *
- * Since: EXPERIMENTAL
+ * Return value: (transfer full):
+ * The referenced #hb_draw_funcs_t.
+ *
+ * Since: 4.0.0
  **/
-void
-hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t             *funcs,
-				     hb_draw_quadratic_to_func_t  quadratic_to)
+hb_draw_funcs_t *
+hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs)
 {
-  if (unlikely (hb_object_is_immutable (funcs))) return;
-  funcs->quadratic_to = quadratic_to;
-  funcs->is_quadratic_to_set = true;
+  return hb_object_reference (dfuncs);
 }
 
 /**
- * hb_draw_funcs_set_cubic_to_func:
- * @funcs: draw functions
- * @cubic_to: cubic-to callback
+ * hb_draw_funcs_destroy: (skip)
+ * @dfuncs: draw functions
  *
- * Sets cubic-to callback to the draw functions object.
+ * Deallocate the @dfuncs.
+ * Decreases the reference count on @dfuncs by one. If the result is zero, then
+ * @dfuncs and all associated resources are freed. See hb_draw_funcs_reference().
  *
- * Since: EXPERIMENTAL
+ * Since: 4.0.0
  **/
 void
-hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t         *funcs,
-				 hb_draw_cubic_to_func_t  cubic_to)
+hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs)
 {
-  if (unlikely (hb_object_is_immutable (funcs))) return;
-  funcs->cubic_to = cubic_to;
+  if (!hb_object_destroy (dfuncs)) return;
+
+#define HB_DRAW_FUNC_IMPLEMENT(name) \
+  if (dfuncs->destroy.name) dfuncs->destroy.name (dfuncs->user_data.name);
+    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_DRAW_FUNC_IMPLEMENT
+
+
+  hb_free (dfuncs);
 }
 
 /**
- * hb_draw_funcs_set_close_path_func:
- * @funcs: draw functions object
- * @close_path: close-path callback
+ * hb_draw_funcs_make_immutable:
+ * @dfuncs: draw functions
  *
- * Sets close-path callback to the draw functions object.
+ * Makes @dfuncs object immutable.
  *
- * Since: EXPERIMENTAL
+ * Since: 4.0.0
  **/
 void
-hb_draw_funcs_set_close_path_func (hb_draw_funcs_t           *funcs,
-				   hb_draw_close_path_func_t  close_path)
+hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs)
 {
-  if (unlikely (hb_object_is_immutable (funcs))) return;
-  funcs->close_path = close_path;
+  if (hb_object_is_immutable (dfuncs))
+    return;
+
+  hb_object_make_immutable (dfuncs);
 }
 
-static void
-_move_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
-
-static void
-_line_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
-
-static void
-_quadratic_to_nil (hb_position_t control_x HB_UNUSED, hb_position_t control_y HB_UNUSED,
-		   hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
-		   void *user_data HB_UNUSED) {}
-
-static void
-_cubic_to_nil (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_UNUSED,
-	       hb_position_t control2_x HB_UNUSED, hb_position_t control2_y HB_UNUSED,
-	       hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
-	       void *user_data HB_UNUSED) {}
-
-static void
-_close_path_nil (void *user_data HB_UNUSED) {}
-
 /**
- * hb_draw_funcs_create:
+ * hb_draw_funcs_is_immutable:
+ * @dfuncs: draw functions
  *
- * Creates a new draw callbacks object.
+ * Checks whether @dfuncs is immutable.
  *
- * Since: EXPERIMENTAL
+ * Return value: %true if @dfuncs is immutable, %false otherwise
+ *
+ * Since: 4.0.0
  **/
-hb_draw_funcs_t *
-hb_draw_funcs_create ()
+hb_bool_t
+hb_draw_funcs_is_immutable (hb_draw_funcs_t *dfuncs)
 {
-  hb_draw_funcs_t *funcs;
-  if (unlikely (!(funcs = hb_object_create<hb_draw_funcs_t> ())))
-    return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
-
-  funcs->move_to = (hb_draw_move_to_func_t) _move_to_nil;
-  funcs->line_to = (hb_draw_line_to_func_t) _line_to_nil;
-  funcs->quadratic_to = (hb_draw_quadratic_to_func_t) _quadratic_to_nil;
-  funcs->is_quadratic_to_set = false;
-  funcs->cubic_to = (hb_draw_cubic_to_func_t) _cubic_to_nil;
-  funcs->close_path = (hb_draw_close_path_func_t) _close_path_nil;
-  return funcs;
+  return hb_object_is_immutable (dfuncs);
 }
 
+
 /**
- * hb_draw_funcs_reference:
- * @funcs: draw functions
+ * hb_draw_move_to:
+ * @dfuncs: draw functions
+ * @draw_data: associated draw data passed by the caller
+ * @st: current draw state
+ * @to_x: X component of target point
+ * @to_y: Y component of target point
  *
- * Add to callbacks object refcount.
+ * Perform a "move-to" draw operation.
  *
- * Returns: The same object.
- * Since: EXPERIMENTAL
+ * Since: 4.0.0
  **/
-hb_draw_funcs_t *
-hb_draw_funcs_reference (hb_draw_funcs_t *funcs)
+void
+hb_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data,
+		 hb_draw_state_t *st,
+		 float to_x, float to_y)
 {
-  return hb_object_reference (funcs);
+  dfuncs->move_to (draw_data, *st,
+		   to_x, to_y);
 }
 
 /**
- * hb_draw_funcs_destroy:
- * @funcs: draw functions
+ * hb_draw_line_to:
+ * @dfuncs: draw functions
+ * @draw_data: associated draw data passed by the caller
+ * @st: current draw state
+ * @to_x: X component of target point
+ * @to_y: Y component of target point
  *
- * Decreases refcount of callbacks object and deletes the object if it reaches
- * to zero.
+ * Perform a "line-to" draw operation.
  *
- * Since: EXPERIMENTAL
+ * Since: 4.0.0
  **/
 void
-hb_draw_funcs_destroy (hb_draw_funcs_t *funcs)
+hb_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data,
+		 hb_draw_state_t *st,
+		 float to_x, float to_y)
 {
-  if (!hb_object_destroy (funcs)) return;
-
-  hb_free (funcs);
+  dfuncs->line_to (draw_data, *st,
+		   to_x, to_y);
 }
 
 /**
- * hb_draw_funcs_make_immutable:
- * @funcs: draw functions
+ * hb_draw_quadratic_to:
+ * @dfuncs: draw functions
+ * @draw_data: associated draw data passed by the caller
+ * @st: current draw state
+ * @control_x: X component of control point
+ * @control_y: Y component of control point
+ * @to_x: X component of target point
+ * @to_y: Y component of target point
  *
- * Makes funcs object immutable.
+ * Perform a "quadratic-to" draw operation.
  *
- * Since: EXPERIMENTAL
+ * Since: 4.0.0
  **/
 void
-hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs)
+hb_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
+		      hb_draw_state_t *st,
+		      float control_x, float control_y,
+		      float to_x, float to_y)
 {
-  if (hb_object_is_immutable (funcs))
-    return;
-
-  hb_object_make_immutable (funcs);
+  dfuncs->quadratic_to (draw_data, *st,
+			control_x, control_y,
+			to_x, to_y);
 }
 
 /**
- * hb_draw_funcs_is_immutable:
- * @funcs: draw functions
+ * hb_draw_cubic_to:
+ * @dfuncs: draw functions
+ * @draw_data: associated draw data passed by the caller
+ * @st: current draw state
+ * @control1_x: X component of first control point
+ * @control1_y: Y component of first control point
+ * @control2_x: X component of second control point
+ * @control2_y: Y component of second control point
+ * @to_x: X component of target point
+ * @to_y: Y component of target point
  *
- * Checks whether funcs is immutable.
+ * Perform a "cubic-to" draw operation.
  *
- * Returns: If is immutable.
- * Since: EXPERIMENTAL
+ * Since: 4.0.0
  **/
-hb_bool_t
-hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs)
+void
+hb_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
+		  hb_draw_state_t *st,
+		  float control1_x, float control1_y,
+		  float control2_x, float control2_y,
+		  float to_x, float to_y)
 {
-  return hb_object_is_immutable (funcs);
+  dfuncs->cubic_to (draw_data, *st,
+		    control1_x, control1_y,
+		    control2_x, control2_y,
+		    to_x, to_y);
 }
 
 /**
- * hb_font_draw_glyph:
- * @font: a font object
- * @glyph: a glyph id
- * @funcs: draw callbacks object
- * @user_data: parameter you like be passed to the callbacks when are called
+ * hb_draw_close_path:
+ * @dfuncs: draw functions
+ * @draw_data: associated draw data passed by the caller
+ * @st: current draw state
  *
- * Draw a glyph.
+ * Perform a "close-path" draw operation.
  *
- * Returns: Whether the font had the glyph and the operation completed successfully.
- * Since: EXPERIMENTAL
+ * Since: 4.0.0
  **/
-hb_bool_t
-hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
-		    const hb_draw_funcs_t *funcs,
-		    void *user_data)
+void
+hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data,
+		    hb_draw_state_t *st)
 {
-  if (unlikely (funcs == &Null (hb_draw_funcs_t) ||
-		glyph >= font->face->get_num_glyphs ()))
-    return false;
+  dfuncs->close_path (draw_data, *st);
+}
 
-  draw_helper_t draw_helper (funcs, user_data);
-  if (font->face->table.glyf->get_path (font, glyph, draw_helper)) return true;
-#ifndef HB_NO_CFF
-  if (font->face->table.cff1->get_path (font, glyph, draw_helper)) return true;
-  if (font->face->table.cff2->get_path (font, glyph, draw_helper)) return true;
-#endif
 
-  return false;
-}
-
 #endif
-#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -33,66 +33,293 @@
 
 HB_BEGIN_DECLS
 
-#ifdef HB_EXPERIMENTAL_API
-typedef void (*hb_draw_move_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data);
-typedef void (*hb_draw_line_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data);
-typedef void (*hb_draw_quadratic_to_func_t) (hb_position_t control_x, hb_position_t control_y,
-					     hb_position_t to_x, hb_position_t to_y,
-					     void *user_data);
-typedef void (*hb_draw_cubic_to_func_t) (hb_position_t control1_x, hb_position_t control1_y,
-					 hb_position_t control2_x, hb_position_t control2_y,
-					 hb_position_t to_x, hb_position_t to_y,
-					 void *user_data);
-typedef void (*hb_draw_close_path_func_t) (void *user_data);
 
 /**
+ * hb_draw_state_t
+ * @path_open: Whether there is an open path
+ * @path_start_x: X component of the start of current path
+ * @path_start_y: Y component of the start of current path
+ * @current_x: X component of current point
+ * @current_y: Y component of current point
+ *
+ * Current drawing state.
+ *
+ * Since: 4.0.0
+ **/
+typedef struct hb_draw_state_t {
+  hb_bool_t path_open;
+
+  float path_start_x;
+  float path_start_y;
+
+  float current_x;
+  float current_y;
+
+  /*< private >*/
+  hb_var_num_t   reserved1;
+  hb_var_num_t   reserved2;
+  hb_var_num_t   reserved3;
+  hb_var_num_t   reserved4;
+  hb_var_num_t   reserved5;
+  hb_var_num_t   reserved6;
+  hb_var_num_t   reserved7;
+} hb_draw_state_t;
+
+/**
+ * HB_DRAW_STATE_DEFAULT:
+ *
+ * The default #hb_draw_state_t at the start of glyph drawing.
+ */
+#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}}
+
+
+/**
  * hb_draw_funcs_t:
  *
  * Glyph draw callbacks.
  *
- * _move_to, _line_to and _cubic_to calls are necessary to be defined but we
- * translate _quadratic_to calls to _cubic_to if the callback isn't defined.
+ * #hb_draw_move_to_func_t, #hb_draw_line_to_func_t and
+ * #hb_draw_cubic_to_func_t calls are necessary to be defined but we translate
+ * #hb_draw_quadratic_to_func_t calls to #hb_draw_cubic_to_func_t if the
+ * callback isn't defined.
  *
- * Since: EXPERIMENTAL
+ * Since: 4.0.0
  **/
+
 typedef struct hb_draw_funcs_t hb_draw_funcs_t;
 
+
+/**
+ * hb_draw_move_to_func_t:
+ * @dfuncs: draw functions object
+ * @draw_data: The data accompanying the draw functions
+ * @st: current draw state
+ * @to_x: X component of target point
+ * @to_y: Y component of target point
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_draw_funcs_t to perform a "move-to" draw
+ * operation.
+ *
+ * Since: 4.0.0
+ *
+ **/
+typedef void (*hb_draw_move_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
+					hb_draw_state_t *st,
+					float to_x, float to_y,
+					void *user_data);
+
+/**
+ * hb_draw_line_to_func_t:
+ * @dfuncs: draw functions object
+ * @draw_data: The data accompanying the draw functions
+ * @st: current draw state
+ * @to_x: X component of target point
+ * @to_y: Y component of target point
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_draw_funcs_t to perform a "line-to" draw
+ * operation.
+ *
+ * Since: 4.0.0
+ *
+ **/
+typedef void (*hb_draw_line_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
+					hb_draw_state_t *st,
+					float to_x, float to_y,
+					void *user_data);
+
+/**
+ * hb_draw_quadratic_to_func_t:
+ * @dfuncs: draw functions object
+ * @draw_data: The data accompanying the draw functions
+ * @st: current draw state
+ * @control_x: X component of control point
+ * @control_y: Y component of control point
+ * @to_x: X component of target point
+ * @to_y: Y component of target point
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_draw_funcs_t to perform a "quadratic-to" draw
+ * operation.
+ *
+ * Since: 4.0.0
+ *
+ **/
+typedef void (*hb_draw_quadratic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
+					     hb_draw_state_t *st,
+					     float control_x, float control_y,
+					     float to_x, float to_y,
+					     void *user_data);
+
+/**
+ * hb_draw_cubic_to_func_t:
+ * @dfuncs: draw functions object
+ * @draw_data: The data accompanying the draw functions
+ * @st: current draw state
+ * @control1_x: X component of first control point
+ * @control1_y: Y component of first control point
+ * @control2_x: X component of second control point
+ * @control2_y: Y component of second control point
+ * @to_x: X component of target point
+ * @to_y: Y component of target point
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_draw_funcs_t to perform a "cubic-to" draw
+ * operation.
+ *
+ * Since: 4.0.0
+ *
+ **/
+typedef void (*hb_draw_cubic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
+					 hb_draw_state_t *st,
+					 float control1_x, float control1_y,
+					 float control2_x, float control2_y,
+					 float to_x, float to_y,
+					 void *user_data);
+
+/**
+ * hb_draw_close_path_func_t:
+ * @dfuncs: draw functions object
+ * @draw_data: The data accompanying the draw functions
+ * @st: current draw state
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_draw_funcs_t to perform a "close-path" draw
+ * operation.
+ *
+ * Since: 4.0.0
+ *
+ **/
+typedef void (*hb_draw_close_path_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
+					   hb_draw_state_t *st,
+					   void *user_data);
+
+/**
+ * hb_draw_funcs_set_move_to_func:
+ * @dfuncs: draw functions object
+ * @func: (closure user_data) (destroy destroy) (scope notified): move-to callback
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets move-to callback to the draw functions object.
+ *
+ * Since: 4.0.0
+ **/
 HB_EXTERN void
-hb_draw_funcs_set_move_to_func (hb_draw_funcs_t        *funcs,
-				hb_draw_move_to_func_t  move_to);
+hb_draw_funcs_set_move_to_func (hb_draw_funcs_t        *dfuncs,
+				hb_draw_move_to_func_t  func,
+				void *user_data, hb_destroy_func_t destroy);
 
+/**
+ * hb_draw_funcs_set_line_to_func:
+ * @dfuncs: draw functions object
+ * @func: (closure user_data) (destroy destroy) (scope notified): line-to callback
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets line-to callback to the draw functions object.
+ *
+ * Since: 4.0.0
+ **/
 HB_EXTERN void
-hb_draw_funcs_set_line_to_func (hb_draw_funcs_t        *funcs,
-				hb_draw_line_to_func_t  line_to);
+hb_draw_funcs_set_line_to_func (hb_draw_funcs_t        *dfuncs,
+				hb_draw_line_to_func_t  func,
+				void *user_data, hb_destroy_func_t destroy);
 
+/**
+ * hb_draw_funcs_set_quadratic_to_func:
+ * @dfuncs: draw functions object
+ * @func: (closure user_data) (destroy destroy) (scope notified): quadratic-to callback
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets quadratic-to callback to the draw functions object.
+ *
+ * Since: 4.0.0
+ **/
 HB_EXTERN void
-hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t             *funcs,
-				     hb_draw_quadratic_to_func_t  quadratic_to);
+hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t             *dfuncs,
+				     hb_draw_quadratic_to_func_t  func,
+				     void *user_data, hb_destroy_func_t destroy);
 
+/**
+ * hb_draw_funcs_set_cubic_to_func:
+ * @dfuncs: draw functions
+ * @func: (closure user_data) (destroy destroy) (scope notified): cubic-to callback
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets cubic-to callback to the draw functions object.
+ *
+ * Since: 4.0.0
+ **/
 HB_EXTERN void
-hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t         *funcs,
-				 hb_draw_cubic_to_func_t  cubic_to);
+hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t         *dfuncs,
+				 hb_draw_cubic_to_func_t  func,
+				 void *user_data, hb_destroy_func_t destroy);
 
+/**
+ * hb_draw_funcs_set_close_path_func:
+ * @dfuncs: draw functions object
+ * @func: (closure user_data) (destroy destroy) (scope notified): close-path callback
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets close-path callback to the draw functions object.
+ *
+ * Since: 4.0.0
+ **/
 HB_EXTERN void
-hb_draw_funcs_set_close_path_func (hb_draw_funcs_t           *funcs,
-				   hb_draw_close_path_func_t  close_path);
+hb_draw_funcs_set_close_path_func (hb_draw_funcs_t           *dfuncs,
+				   hb_draw_close_path_func_t  func,
+				   void *user_data, hb_destroy_func_t destroy);
 
+
 HB_EXTERN hb_draw_funcs_t *
 hb_draw_funcs_create (void);
 
 HB_EXTERN hb_draw_funcs_t *
-hb_draw_funcs_reference (hb_draw_funcs_t *funcs);
+hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs);
 
 HB_EXTERN void
-hb_draw_funcs_destroy (hb_draw_funcs_t *funcs);
+hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs);
 
 HB_EXTERN void
-hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs);
+hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs);
 
 HB_EXTERN hb_bool_t
-hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs);
-#endif
+hb_draw_funcs_is_immutable (hb_draw_funcs_t *dfuncs);
 
+
+HB_EXTERN void
+hb_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data,
+		 hb_draw_state_t *st,
+		 float to_x, float to_y);
+
+HB_EXTERN void
+hb_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data,
+		 hb_draw_state_t *st,
+		 float to_x, float to_y);
+
+HB_EXTERN void
+hb_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
+		      hb_draw_state_t *st,
+		      float control_x, float control_y,
+		      float to_x, float to_y);
+
+HB_EXTERN void
+hb_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
+		  hb_draw_state_t *st,
+		  float control1_x, float control1_y,
+		  float control2_x, float control2_y,
+		  float to_x, float to_y);
+
+HB_EXTERN void
+hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data,
+		    hb_draw_state_t *st);
+
+
 HB_END_DECLS
 
 #endif /* HB_DRAW_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -27,113 +27,205 @@
 
 #include "hb.hh"
 
-#ifdef HB_EXPERIMENTAL_API
+
+/*
+ * hb_draw_funcs_t
+ */
+
+#define HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS \
+  HB_DRAW_FUNC_IMPLEMENT (move_to) \
+  HB_DRAW_FUNC_IMPLEMENT (line_to) \
+  HB_DRAW_FUNC_IMPLEMENT (quadratic_to) \
+  HB_DRAW_FUNC_IMPLEMENT (cubic_to) \
+  HB_DRAW_FUNC_IMPLEMENT (close_path) \
+  /* ^--- Add new callbacks here */
+
 struct hb_draw_funcs_t
 {
   hb_object_header_t header;
 
-  hb_draw_move_to_func_t move_to;
-  hb_draw_line_to_func_t line_to;
-  hb_draw_quadratic_to_func_t quadratic_to;
-  bool is_quadratic_to_set;
-  hb_draw_cubic_to_func_t cubic_to;
-  hb_draw_close_path_func_t close_path;
-};
+  struct {
+#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_func_t name;
+    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_DRAW_FUNC_IMPLEMENT
+  } func;
 
-struct draw_helper_t
-{
-  draw_helper_t (const hb_draw_funcs_t *funcs_, void *user_data_)
-  {
-    funcs = funcs_;
-    user_data = user_data_;
-    path_open = false;
-    path_start_x = current_x = path_start_y = current_y = 0;
-  }
-  ~draw_helper_t () { end_path (); }
+  struct {
+#define HB_DRAW_FUNC_IMPLEMENT(name) void *name;
+    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_DRAW_FUNC_IMPLEMENT
+  } user_data;
 
-  void move_to (hb_position_t x, hb_position_t y)
+  struct {
+#define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
+    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_DRAW_FUNC_IMPLEMENT
+  } destroy;
+
+  void emit_move_to (void *draw_data, hb_draw_state_t &st,
+		     float to_x, float to_y)
+  { func.move_to (this, draw_data, &st,
+		  to_x, to_y,
+		  user_data.move_to); }
+  void emit_line_to (void *draw_data, hb_draw_state_t &st,
+		     float to_x, float to_y)
+  { func.line_to (this, draw_data, &st,
+		  to_x, to_y,
+		  user_data.line_to); }
+  void emit_quadratic_to (void *draw_data, hb_draw_state_t &st,
+			  float control_x, float control_y,
+			  float to_x, float to_y)
+  { func.quadratic_to (this, draw_data, &st,
+		       control_x, control_y,
+		       to_x, to_y,
+		       user_data.quadratic_to); }
+  void emit_cubic_to (void *draw_data, hb_draw_state_t &st,
+		      float control1_x, float control1_y,
+		      float control2_x, float control2_y,
+		      float to_x, float to_y)
+  { func.cubic_to (this, draw_data, &st,
+		   control1_x, control1_y,
+		   control2_x, control2_y,
+		   to_x, to_y,
+		   user_data.cubic_to); }
+  void emit_close_path (void *draw_data, hb_draw_state_t &st)
+  { func.close_path (this, draw_data, &st,
+		     user_data.close_path); }
+
+
+  void move_to (void *draw_data, hb_draw_state_t &st,
+		float to_x, float to_y)
   {
-    if (path_open) end_path ();
-    current_x = path_start_x = x;
-    current_y = path_start_y = y;
+    if (st.path_open) close_path (draw_data, st);
+    st.current_x = to_x;
+    st.current_y = to_y;
   }
 
-  void line_to (hb_position_t x, hb_position_t y)
+  void line_to (void *draw_data, hb_draw_state_t &st,
+		float to_x, float to_y)
   {
-    if (equal_to_current (x, y)) return;
-    if (!path_open) start_path ();
-    funcs->line_to (x, y, user_data);
-    current_x = x;
-    current_y = y;
+    if (!st.path_open) start_path (draw_data, st);
+    emit_line_to (draw_data, st, to_x, to_y);
+    st.current_x = to_x;
+    st.current_y = to_y;
   }
 
   void
-  quadratic_to (hb_position_t control_x, hb_position_t control_y,
-		hb_position_t to_x, hb_position_t to_y)
+  quadratic_to (void *draw_data, hb_draw_state_t &st,
+		float control_x, float control_y,
+		float to_x, float to_y)
   {
-    if (equal_to_current (control_x, control_y) && equal_to_current (to_x, to_y))
-      return;
-    if (!path_open) start_path ();
-    if (funcs->is_quadratic_to_set)
-      funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data);
-    else
-      funcs->cubic_to (roundf ((current_x + 2.f * control_x) / 3.f),
-		       roundf ((current_y + 2.f * control_y) / 3.f),
-		       roundf ((to_x + 2.f * control_x) / 3.f),
-		       roundf ((to_y + 2.f * control_y) / 3.f),
-		       to_x, to_y, user_data);
-    current_x = to_x;
-    current_y = to_y;
+    if (!st.path_open) start_path (draw_data, st);
+    emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
+    st.current_x = to_x;
+    st.current_y = to_y;
   }
 
   void
-  cubic_to (hb_position_t control1_x, hb_position_t control1_y,
-	    hb_position_t control2_x, hb_position_t control2_y,
-	    hb_position_t to_x, hb_position_t to_y)
+  cubic_to (void *draw_data, hb_draw_state_t &st,
+	    float control1_x, float control1_y,
+	    float control2_x, float control2_y,
+	    float to_x, float to_y)
   {
-    if (equal_to_current (control1_x, control1_y) &&
-	equal_to_current (control2_x, control2_y) &&
-	equal_to_current (to_x, to_y))
-      return;
-    if (!path_open) start_path ();
-    funcs->cubic_to (control1_x, control1_y, control2_x, control2_y, to_x, to_y, user_data);
-    current_x = to_x;
-    current_y = to_y;
+    if (!st.path_open) start_path (draw_data, st);
+    emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
+    st.current_x = to_x;
+    st.current_y = to_y;
   }
 
-  void end_path ()
+  void
+  close_path (void *draw_data, hb_draw_state_t &st)
   {
-    if (path_open)
+    if (st.path_open)
     {
-      if ((path_start_x != current_x) || (path_start_y != current_y))
-	funcs->line_to (path_start_x, path_start_y, user_data);
-      funcs->close_path (user_data);
+      if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
+	emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
+      emit_close_path (draw_data, st);
     }
-    path_open = false;
-    path_start_x = current_x = path_start_y = current_y = 0;
+    st.path_open = false;
+    st.path_start_x = st.current_x = st.path_start_y = st.current_y = 0;
   }
 
   protected:
-  bool equal_to_current (hb_position_t x, hb_position_t y)
-  { return current_x == x && current_y == y; }
 
-  void start_path ()
+  void start_path (void *draw_data, hb_draw_state_t &st)
   {
-    if (path_open) end_path ();
-    path_open = true;
-    funcs->move_to (path_start_x, path_start_y, user_data);
+    assert (!st.path_open);
+    emit_move_to (draw_data, st, st.current_x, st.current_y);
+    st.path_open = true;
+    st.path_start_x = st.current_x;
+    st.path_start_y = st.current_y;
   }
+};
+DECLARE_NULL_INSTANCE (hb_draw_funcs_t);
 
-  hb_position_t path_start_x;
-  hb_position_t path_start_y;
+struct hb_draw_session_t
+{
+  hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_ = 0.f)
+    : slant {slant_}, not_slanted {slant == 0.f},
+      funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT
+  {}
 
-  hb_position_t current_x;
-  hb_position_t current_y;
+  ~hb_draw_session_t () { close_path (); }
 
-  bool path_open;
-  const hb_draw_funcs_t *funcs;
-  void *user_data;
+  void move_to (float to_x, float to_y)
+  {
+    if (likely (not_slanted))
+      funcs->move_to (draw_data, st,
+		      to_x, to_y);
+    else
+      funcs->move_to (draw_data, st,
+		      to_x + to_y * slant, to_y);
+  }
+  void line_to (float to_x, float to_y)
+  {
+    if (likely (not_slanted))
+      funcs->line_to (draw_data, st,
+		      to_x, to_y);
+    else
+      funcs->line_to (draw_data, st,
+		      to_x + to_y * slant, to_y);
+  }
+  void
+  quadratic_to (float control_x, float control_y,
+		float to_x, float to_y)
+  {
+    if (likely (not_slanted))
+      funcs->quadratic_to (draw_data, st,
+			   control_x, control_y,
+			   to_x, to_y);
+    else
+      funcs->quadratic_to (draw_data, st,
+			   control_x + control_y * slant, control_y,
+			   to_x + to_y * slant, to_y);
+  }
+  void
+  cubic_to (float control1_x, float control1_y,
+	    float control2_x, float control2_y,
+	    float to_x, float to_y)
+  {
+    if (likely (not_slanted))
+      funcs->cubic_to (draw_data, st,
+		       control1_x, control1_y,
+		       control2_x, control2_y,
+		       to_x, to_y);
+    else
+      funcs->cubic_to (draw_data, st,
+		       control1_x + control1_y * slant, control1_y,
+		       control2_x + control2_y * slant, control2_y,
+		       to_x + to_y * slant, to_y);
+  }
+  void close_path ()
+  {
+    funcs->close_path (draw_data, st);
+  }
+
+  protected:
+  float slant;
+  bool not_slanted;
+  hb_draw_funcs_t *funcs;
+  void *draw_data;
+  hb_draw_state_t st;
 };
-#endif
 
 #endif /* HB_DRAW_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -29,6 +29,7 @@
 #include "hb.hh"
 
 #include "hb-font.hh"
+#include "hb-draw.hh"
 #include "hb-machinery.hh"
 
 #include "hb-ot.h"
@@ -501,6 +502,136 @@
   return font->parent->get_glyph_from_name (name, len, glyph);
 }
 
+static void
+hb_font_get_glyph_shape_nil (hb_font_t       *font HB_UNUSED,
+			     void            *font_data HB_UNUSED,
+			     hb_codepoint_t   glyph,
+			     hb_draw_funcs_t *draw_funcs,
+			     void            *draw_data,
+			     void            *user_data HB_UNUSED)
+{
+}
+
+
+typedef struct hb_font_get_glyph_shape_default_adaptor_t {
+  hb_draw_funcs_t *draw_funcs;
+  void		  *draw_data;
+  float		   x_scale;
+  float		   y_scale;
+} hb_font_get_glyph_shape_default_adaptor_t;
+
+static void
+hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED,
+			 void *draw_data,
+			 hb_draw_state_t *st,
+			 float to_x, float to_y,
+			 void *user_data HB_UNUSED)
+{
+  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  float x_scale = adaptor->x_scale;
+  float y_scale = adaptor->y_scale;
+
+  adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st,
+				     x_scale * to_x, y_scale * to_y);
+}
+
+static void
+hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
+			 hb_draw_state_t *st,
+			 float to_x, float to_y,
+			 void *user_data HB_UNUSED)
+{
+  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  float x_scale = adaptor->x_scale;
+  float y_scale = adaptor->y_scale;
+
+  st->current_x *= x_scale;
+  st->current_y *= y_scale;
+
+  adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st,
+				     x_scale * to_x, y_scale * to_y);
+}
+
+static void
+hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
+			      hb_draw_state_t *st,
+			      float control_x, float control_y,
+			      float to_x, float to_y,
+			      void *user_data HB_UNUSED)
+{
+  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  float x_scale = adaptor->x_scale;
+  float y_scale = adaptor->y_scale;
+
+  st->current_x *= x_scale;
+  st->current_y *= y_scale;
+
+  adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st,
+					  x_scale * control_x, y_scale * control_y,
+					  x_scale * to_x, y_scale * to_y);
+}
+
+static void
+hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
+			  hb_draw_state_t *st,
+			  float control1_x, float control1_y,
+			  float control2_x, float control2_y,
+			  float to_x, float to_y,
+			  void *user_data HB_UNUSED)
+{
+  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  float x_scale = adaptor->x_scale;
+  float y_scale = adaptor->y_scale;
+
+  st->current_x *= x_scale;
+  st->current_y *= y_scale;
+
+  adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st,
+				      x_scale * control1_x, y_scale * control1_y,
+				      x_scale * control2_x, y_scale * control2_y,
+				      x_scale * to_x, y_scale * to_y);
+}
+
+static void
+hb_draw_close_path_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
+			    hb_draw_state_t *st,
+			    void *user_data HB_UNUSED)
+{
+  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+
+  adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st);
+}
+
+static const hb_draw_funcs_t _hb_draw_funcs_default = {
+  HB_OBJECT_HEADER_STATIC,
+
+  {
+#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_default,
+    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_DRAW_FUNC_IMPLEMENT
+  }
+};
+
+static void
+hb_font_get_glyph_shape_default (hb_font_t       *font,
+				 void            *font_data HB_UNUSED,
+				 hb_codepoint_t   glyph,
+				 hb_draw_funcs_t *draw_funcs,
+				 void            *draw_data,
+				 void            *user_data HB_UNUSED)
+{
+  hb_font_get_glyph_shape_default_adaptor_t adaptor = {
+    draw_funcs,
+    draw_data,
+    (float) font->x_scale / (float) font->parent->x_scale,
+    (float) font->y_scale / (float) font->parent->y_scale
+  };
+
+  font->parent->get_glyph_shape (glyph,
+				 const_cast<hb_draw_funcs_t *> (&_hb_draw_funcs_default),
+				 &adaptor);
+}
+
 DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
 {
   HB_OBJECT_HEADER_STATIC,
@@ -1168,6 +1299,26 @@
   return font->get_glyph_from_name (name, len, glyph);
 }
 
+/**
+ * hb_font_get_glyph_shape:
+ * @font: #hb_font_t to work upon
+ * @glyph: : The glyph ID
+ * @dfuncs: #hb_draw_funcs_t to draw to
+ * @draw_data: User data to pass to draw callbacks
+ *
+ * Fetches the glyph shape that corresponds to a glyph in the specified @font.
+ * The shape is returned by way of calls to the callsbacks of the @dfuncs
+ * objects, with @draw_data passed to them.
+ *
+ * Since: 4.0.0
+ **/
+void
+hb_font_get_glyph_shape (hb_font_t *font,
+			 hb_codepoint_t glyph,
+			 hb_draw_funcs_t *dfuncs, void *draw_data)
+{
+  font->get_glyph_shape (glyph, dfuncs, draw_data);
+}
 
 /* A bit higher-level, and with fallback */
 
@@ -1190,7 +1341,7 @@
 				   hb_direction_t     direction,
 				   hb_font_extents_t *extents)
 {
-  return font->get_extents_for_direction (direction, extents);
+  font->get_extents_for_direction (direction, extents);
 }
 /**
  * hb_font_get_glyph_advance_for_direction:
@@ -1215,7 +1366,7 @@
 					 hb_position_t  *x,
 					 hb_position_t  *y)
 {
-  return font->get_glyph_advance_for_direction (glyph, direction, x, y);
+  font->get_glyph_advance_for_direction (glyph, direction, x, y);
 }
 /**
  * hb_font_get_glyph_advances_for_direction:
@@ -2044,12 +2195,16 @@
  * @slant: synthetic slant value.
  *
  * Sets the "synthetic slant" of a font.  By default is zero.
- * Synthetic slant is the graphical skew that the renderer
- * applies to the font at rendering time.
+ * Synthetic slant is the graphical skew applied to the font
+ * at rendering time.
  *
  * HarfBuzz needs to know this value to adjust shaping results,
  * metrics, and style values to match the slanted rendering.
  *
+ * <note>Note: The glyph shape fetched via the
+ * hb_font_get_glyph_shape() is slanted to reflect this value
+ * as well.</note>
+ *
  * <note>Note: The slant value is a ratio.  For example, a
  * 20% slant would be represented as a 0.2 value.</note>
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -511,7 +511,26 @@
 							 hb_codepoint_t *glyph,
 							 void *user_data);
 
+/**
+ * hb_font_get_glyph_shape_func_t:
+ * @font: #hb_font_t to work upon
+ * @font_data: @font user data pointer
+ * @glyph: The glyph ID to query
+ * @draw_funcs: The draw functions to send the shape data to
+ * @draw_data: The data accompanying the draw functions
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * Since: 4.0.0
+ *
+ **/
+typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data,
+						hb_codepoint_t glyph,
+						hb_draw_funcs_t *draw_funcs, void *draw_data,
+						void *user_data);
 
+
 /* func setters */
 
 /**
@@ -770,6 +789,22 @@
 					hb_font_get_glyph_from_name_func_t func,
 					void *user_data, hb_destroy_func_t destroy);
 
+/**
+ * hb_font_funcs_set_glyph_shape_func:
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets the implementation function for #hb_font_get_glyph_shape_func_t.
+ *
+ * Since: 4.0.0
+ **/
+HB_EXTERN void
+hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
+				    hb_font_get_glyph_shape_func_t func,
+				    void *user_data, hb_destroy_func_t destroy);
+
 /* func dispatch */
 
 HB_EXTERN hb_bool_t
@@ -850,7 +885,12 @@
 			     const char *name, int len, /* -1 means nul-terminated */
 			     hb_codepoint_t *glyph);
 
+HB_EXTERN void
+hb_font_get_glyph_shape (hb_font_t *font,
+			 hb_codepoint_t glyph,
+			 hb_draw_funcs_t *dfuncs, void *draw_data);
 
+
 /* high-level funcs, with fallback */
 
 /* Calls either hb_font_get_nominal_glyph() if variation_selector is 0,
@@ -1056,11 +1096,6 @@
 hb_font_set_var_named_instance (hb_font_t *font,
 				unsigned instance_index);
 
-#ifdef HB_EXPERIMENTAL_API
-HB_EXTERN hb_bool_t
-hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
-		    const hb_draw_funcs_t *funcs, void *user_data);
-#endif
 
 HB_END_DECLS
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -57,6 +57,7 @@
   HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
   HB_FONT_FUNC_IMPLEMENT (glyph_name) \
   HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_shape) \
   /* ^--- Add new callbacks here */
 
 struct hb_font_funcs_t
@@ -140,6 +141,8 @@
   hb_position_t em_scalef_y (float v) { return em_scalef (v, y_scale); }
   float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
   float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
+  float em_fscalef_x (float v) { return em_fscalef (v, x_scale); }
+  float em_fscalef_y (float v) { return em_fscalef (v, y_scale); }
   hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
   { return em_mult (v, dir_mult (direction)); }
 
@@ -373,7 +376,16 @@
 					 klass->user_data.glyph_from_name);
   }
 
+  void get_glyph_shape (hb_codepoint_t glyph,
+			hb_draw_funcs_t *draw_funcs, void *draw_data)
+  {
+    klass->get.f.glyph_shape (this, user_data,
+			      glyph,
+			      draw_funcs, draw_data,
+			      klass->user_data.glyph_shape);
+  }
 
+
   /* A bit higher-level, and with fallback */
 
   void get_h_extents_with_fallback (hb_font_extents_t *extents)
@@ -625,7 +637,9 @@
   hb_position_t em_mult (int16_t v, int64_t mult)
   { return (hb_position_t) ((v * mult + 32768) >> 16); }
   hb_position_t em_scalef (float v, int scale)
-  { return (hb_position_t) roundf (v * scale / face->get_upem ()); }
+  { return (hb_position_t) roundf (em_fscalef (v, scale)); }
+  float em_fscalef (float v, int scale)
+  { return v * scale / face->get_upem (); }
   float em_fscale (int16_t v, int scale)
   { return (float) v * scale / face->get_upem (); }
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -33,6 +33,7 @@
 
 #include "hb-ft.h"
 
+#include "hb-draw.hh"
 #include "hb-font.hh"
 #include "hb-machinery.hh"
 #include "hb-cache.hh"
@@ -39,6 +40,7 @@
 
 #include FT_ADVANCES_H
 #include FT_MULTIPLE_MASTERS_H
+#include FT_OUTLINE_H
 #include FT_TRUETYPE_TABLES_H
 
 
@@ -380,6 +382,7 @@
 
   /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
    * have a Y growing upward.  Hence the extra negation. */
+
   return (-v + (1<<9)) >> 10;
 }
 #endif
@@ -565,6 +568,82 @@
   return true;
 }
 
+#ifndef HB_NO_DRAW
+
+static int
+_hb_ft_move_to (const FT_Vector *to,
+		hb_draw_session_t *drawing)
+{
+  drawing->move_to (to->x, to->y);
+  return FT_Err_Ok;
+}
+
+static int
+_hb_ft_line_to (const FT_Vector *to,
+		hb_draw_session_t *drawing)
+{
+  drawing->line_to (to->x, to->y);
+  return FT_Err_Ok;
+}
+
+static int
+_hb_ft_conic_to (const FT_Vector *control,
+		 const FT_Vector *to,
+		 hb_draw_session_t *drawing)
+{
+  drawing->quadratic_to (control->x, control->y,
+			 to->x, to->y);
+  return FT_Err_Ok;
+}
+
+static int
+_hb_ft_cubic_to (const FT_Vector *control1,
+		 const FT_Vector *control2,
+		 const FT_Vector *to,
+		 hb_draw_session_t *drawing)
+{
+  drawing->cubic_to (control1->x, control1->y,
+		     control2->x, control2->y,
+		     to->x, to->y);
+  return FT_Err_Ok;
+}
+
+static void
+hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED,
+		       void *font_data,
+		       hb_codepoint_t glyph,
+		       hb_draw_funcs_t *draw_funcs, void *draw_data,
+		       void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
+  FT_Face ft_face = ft_font->ft_face;
+
+  if (unlikely (FT_Load_Glyph (ft_face, glyph,
+			       FT_LOAD_NO_BITMAP | ft_font->load_flags)))
+    return;
+
+  if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
+    return;
+
+  const FT_Outline_Funcs outline_funcs = {
+    (FT_Outline_MoveToFunc) _hb_ft_move_to,
+    (FT_Outline_LineToFunc) _hb_ft_line_to,
+    (FT_Outline_ConicToFunc) _hb_ft_conic_to,
+    (FT_Outline_CubicToFunc) _hb_ft_cubic_to,
+    0, /* shift */
+    0, /* delta */
+  };
+
+  hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
+
+  FT_Outline_Decompose (&ft_face->glyph->outline,
+			&outline_funcs,
+			&draw_session);
+}
+#endif
+
+
 static inline void free_static_ft_funcs ();
 
 static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft_font_funcs_lazy_loader_t>
@@ -596,6 +675,10 @@
     hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr);
     hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, nullptr, nullptr);
 
+#ifndef HB_NO_DRAW
+    hb_font_funcs_set_glyph_shape_func (funcs, hb_ft_get_glyph_shape, nullptr, nullptr);
+#endif
+
     hb_font_funcs_make_immutable (funcs);
 
     hb_atexit (free_static_ft_funcs);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -90,6 +90,7 @@
 
 HB_DEFINE_OBJECT_TYPE (buffer)
 HB_DEFINE_OBJECT_TYPE (blob)
+HB_DEFINE_OBJECT_TYPE (draw_funcs)
 HB_DEFINE_OBJECT_TYPE (face)
 HB_DEFINE_OBJECT_TYPE (font)
 HB_DEFINE_OBJECT_TYPE (font_funcs)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -49,6 +49,10 @@
 #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ())
 
 HB_EXTERN GType
+hb_gobject_draw_funcs_get_type (void);
+#define HB_GOBJECT_TYPE_DRAW_FUNCS (hb_gobject_draw_funcs_get_type ())
+
+HB_EXTERN GType
 hb_gobject_face_get_type (void);
 #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ())
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -273,14 +273,19 @@
 						hb_face_lazy_loader_t<T, WheresFace>,
 						hb_face_t, WheresFace> {};
 
-template <typename T, unsigned int WheresFace>
+template <typename T, unsigned int WheresFace, bool core=false>
 struct hb_table_lazy_loader_t : hb_lazy_loader_t<T,
-						 hb_table_lazy_loader_t<T, WheresFace>,
+						 hb_table_lazy_loader_t<T, WheresFace, core>,
 						 hb_face_t, WheresFace,
 						 hb_blob_t>
 {
   static hb_blob_t *create (hb_face_t *face)
-  { return hb_sanitize_context_t ().reference_table<T> (face); }
+  {
+    auto c = hb_sanitize_context_t ();
+    if (core)
+      c.set_num_glyphs (0); // So we don't recurse ad infinitum...
+    return c.reference_table<T> (face);
+  }
   static void destroy (hb_blob_t *p) { hb_blob_destroy (p); }
 
   static const hb_blob_t *get_null ()

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -442,13 +442,12 @@
   return true;
 }
 
-#ifdef HB_EXPERIMENTAL_API
 struct cff1_path_param_t
 {
   cff1_path_param_t (const OT::cff1::accelerator_t *cff_, hb_font_t *font_,
-		     draw_helper_t &draw_helper_, point_t *delta_)
+		     hb_draw_session_t &draw_session_, point_t *delta_)
   {
-    draw_helper = &draw_helper_;
+    draw_session = &draw_session_;
     cff = cff_;
     font = font_;
     delta = delta_;
@@ -458,7 +457,7 @@
   {
     point_t point = p;
     if (delta) point.move (*delta);
-    draw_helper->move_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
+    draw_session->move_to (font->em_fscalef_x (point.x.to_real ()), font->em_fscalef_y (point.y.to_real ()));
   }
 
   void line_to (const point_t &p)
@@ -465,7 +464,7 @@
   {
     point_t point = p;
     if (delta) point.move (*delta);
-    draw_helper->line_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
+    draw_session->line_to (font->em_fscalef_x (point.x.to_real ()), font->em_fscalef_y (point.y.to_real ()));
   }
 
   void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
@@ -477,15 +476,15 @@
       point2.move (*delta);
       point3.move (*delta);
     }
-    draw_helper->cubic_to (font->em_scalef_x (point1.x.to_real ()), font->em_scalef_y (point1.y.to_real ()),
-			   font->em_scalef_x (point2.x.to_real ()), font->em_scalef_y (point2.y.to_real ()),
-			   font->em_scalef_x (point3.x.to_real ()), font->em_scalef_y (point3.y.to_real ()));
+    draw_session->cubic_to (font->em_fscalef_x (point1.x.to_real ()), font->em_fscalef_y (point1.y.to_real ()),
+			   font->em_fscalef_x (point2.x.to_real ()), font->em_fscalef_y (point2.y.to_real ()),
+			   font->em_fscalef_x (point3.x.to_real ()), font->em_fscalef_y (point3.y.to_real ()));
   }
 
-  void end_path () { draw_helper->end_path (); }
+  void end_path () { draw_session->close_path (); }
 
   hb_font_t *font;
-  draw_helper_t *draw_helper;
+  hb_draw_session_t *draw_session;
   point_t *delta;
 
   const OT::cff1::accelerator_t *cff;
@@ -513,7 +512,7 @@
 };
 
 static bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
-		       draw_helper_t &draw_helper, bool in_seac = false, point_t *delta = nullptr);
+		       hb_draw_session_t &draw_session, bool in_seac = false, point_t *delta = nullptr);
 
 struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t>
 {
@@ -530,14 +529,14 @@
     hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
 
     if (unlikely (!(!env.in_seac && base && accent
-		    && _get_path (param.cff, param.font, base, *param.draw_helper, true)
-		    && _get_path (param.cff, param.font, accent, *param.draw_helper, true, &delta))))
+		    && _get_path (param.cff, param.font, base, *param.draw_session, true)
+		    && _get_path (param.cff, param.font, accent, *param.draw_session, true, &delta))))
       env.set_error ();
   }
 };
 
 bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
-		draw_helper_t &draw_helper, bool in_seac, point_t *delta)
+		hb_draw_session_t &draw_session, bool in_seac, point_t *delta)
 {
   if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
 
@@ -546,7 +545,7 @@
   const byte_str_t str = (*cff->charStrings)[glyph];
   interp.env.init (str, *cff, fd);
   interp.env.set_in_seac (in_seac);
-  cff1_path_param_t param (cff, font, draw_helper, delta);
+  cff1_path_param_t param (cff, font, draw_session, delta);
   if (unlikely (!interp.interpret (param))) return false;
 
   /* Let's end the path specially since it is called inside seac also */
@@ -555,7 +554,7 @@
   return true;
 }
 
-bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
+bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const
 {
 #ifdef HB_NO_OT_FONT_CFF
   /* XXX Remove check when this code moves to .hh file. */
@@ -562,9 +561,8 @@
   return true;
 #endif
 
-  return _get_path (this, font, glyph, draw_helper);
+  return _get_path (this, font, glyph, draw_session);
 }
-#endif
 
 struct get_seac_param_t
 {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -1347,9 +1347,7 @@
 
     HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
     HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
-#ifdef HB_EXPERIMENTAL_API
-    HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const;
-#endif
+    HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
 
     private:
     struct gname_t

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -143,30 +143,29 @@
   return true;
 }
 
-#ifdef HB_EXPERIMENTAL_API
 struct cff2_path_param_t
 {
-  cff2_path_param_t (hb_font_t *font_, draw_helper_t &draw_helper_)
+  cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
   {
-    draw_helper = &draw_helper_;
+    draw_session = &draw_session_;
     font = font_;
   }
 
   void move_to (const point_t &p)
-  { draw_helper->move_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
+  { draw_session->move_to (font->em_fscalef_x (p.x.to_real ()), font->em_fscalef_y (p.y.to_real ())); }
 
   void line_to (const point_t &p)
-  { draw_helper->line_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
+  { draw_session->line_to (font->em_fscalef_x (p.x.to_real ()), font->em_fscalef_y (p.y.to_real ())); }
 
   void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
   {
-    draw_helper->cubic_to (font->em_scalef_x (p1.x.to_real ()), font->em_scalef_y (p1.y.to_real ()),
-			   font->em_scalef_x (p2.x.to_real ()), font->em_scalef_y (p2.y.to_real ()),
-			   font->em_scalef_x (p3.x.to_real ()), font->em_scalef_y (p3.y.to_real ()));
+    draw_session->cubic_to (font->em_fscalef_x (p1.x.to_real ()), font->em_fscalef_y (p1.y.to_real ()),
+			   font->em_fscalef_x (p2.x.to_real ()), font->em_fscalef_y (p2.y.to_real ()),
+			   font->em_fscalef_x (p3.x.to_real ()), font->em_fscalef_y (p3.y.to_real ()));
   }
 
   protected:
-  draw_helper_t *draw_helper;
+  hb_draw_session_t *draw_session;
   hb_font_t *font;
 };
 
@@ -193,7 +192,7 @@
 
 struct cff2_cs_opset_path_t : cff2_cs_opset_t<cff2_cs_opset_path_t, cff2_path_param_t, cff2_path_procs_path_t> {};
 
-bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
+bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const
 {
 #ifdef HB_NO_OT_FONT_CFF
   /* XXX Remove check when this code moves to .hh file. */
@@ -206,10 +205,9 @@
   cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t> interp;
   const byte_str_t str = (*charStrings)[glyph];
   interp.env.init (str, *this, fd, font->coords, font->num_coords);
-  cff2_path_param_t param (font, draw_helper);
+  cff2_path_param_t param (font, draw_session);
   if (unlikely (!interp.interpret (param))) return false;
   return true;
 }
-#endif
 
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -515,9 +515,7 @@
     HB_INTERNAL bool get_extents (hb_font_t *font,
 				  hb_codepoint_t glyph,
 				  hb_glyph_extents_t *extents) const;
-#ifdef HB_EXPERIMENTAL_API
-    HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const;
-#endif
+    HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
   };
 
   typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t;

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -714,7 +714,7 @@
       if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs))
 	end = start + (hb_codepoint_t) num_glyphs - gid;
 
-      out->add_range (start, end);
+      out->add_range (start, hb_min (end, 0x10FFFFu));
     }
   }
 
@@ -883,7 +883,7 @@
       hb_codepoint_t first = arrayZ[i].startUnicodeValue;
       hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
 				    (hb_codepoint_t) HB_UNICODE_MAX);
-      out->add_range (first, last);
+      out->add_range (first, hb_min (last, 0x10FFFFu));
     }
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -32,6 +32,11 @@
 #define HB_OT_FACE_TABLE_LIST_HH
 #endif /* HB_OT_FACE_TABLE_LIST_HH */ /* Dummy header guards */
 
+#ifndef HB_OT_CORE_TABLE
+#define HB_OT_CORE_TABLE(Namespace, Type) HB_OT_TABLE (Namespace, Type)
+#define _HB_OT_CORE_TABLE_UNDEF
+#endif
+
 #ifndef HB_OT_ACCELERATOR
 #define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
 #define _HB_OT_ACCELERATOR_UNDEF
@@ -46,7 +51,8 @@
 
 
 /* OpenType fundamentals. */
-HB_OT_TABLE (OT, head)
+HB_OT_CORE_TABLE (OT, head)
+HB_OT_CORE_TABLE (OT, maxp)
 #if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
 HB_OT_ACCELERATOR (OT, cmap)
 #endif
@@ -74,6 +80,7 @@
 #endif
 
 /* TrueType outlines. */
+HB_OT_CORE_TABLE (OT, loca) // Also used to determine number of glyphs
 HB_OT_ACCELERATOR (OT, glyf)
 
 /* CFF outlines. */
@@ -138,3 +145,7 @@
 #ifdef _HB_OT_ACCELERATOR_UNDEF
 #undef HB_OT_ACCELERATOR
 #endif
+
+#ifdef _HB_OT_CORE_TABLE_UNDEF
+#undef HB_OT_CORE_TABLE
+#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -63,10 +63,13 @@
   hb_face_t *face; /* MUST be JUST before the lazy loaders. */
 #define HB_OT_TABLE(Namespace, Type) \
   hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
+#define HB_OT_CORE_TABLE(Namespace, Type) \
+  hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type), true> Type;
 #define HB_OT_ACCELERATOR(Namespace, Type) \
   hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
 #include "hb-ot-face-table-list.hh"
 #undef HB_OT_ACCELERATOR
+#undef HB_OT_CORE_TABLE
 #undef HB_OT_TABLE
 };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -131,11 +131,25 @@
   const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
 
-  for (unsigned int i = 0; i < count; i++)
+  if (vmtx.has_data ())
+    for (unsigned int i = 0; i < count; i++)
+    {
+      *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font));
+      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
+      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+    }
+  else
   {
-    *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font));
-    first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
-    first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+    hb_font_extents_t font_extents;
+    font->get_h_extents_with_fallback (&font_extents);
+    hb_position_t advance = -(font_extents.ascender - font_extents.descender);
+
+    for (unsigned int i = 0; i < count; i++)
+    {
+      *first_advance = advance;
+      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
+      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+    }
   }
 }
 #endif
@@ -163,9 +177,19 @@
   hb_glyph_extents_t extents = {0};
   if (ot_face->glyf->get_extents (font, glyph, &extents))
   {
-    const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
-    hb_position_t tsb = vmtx.get_side_bearing (font, glyph);
-    *y = extents.y_bearing + font->em_scale_y (tsb);
+    if (ot_face->vmtx->has_data ())
+    {
+      const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
+      hb_position_t tsb = vmtx.get_side_bearing (font, glyph);
+      *y = extents.y_bearing + font->em_scale_y (tsb);
+      return true;
+    }
+
+    hb_font_extents_t font_extents;
+    font->get_h_extents_with_fallback (&font_extents);
+    hb_position_t advance = font_extents.ascender - font_extents.descender;
+    int diff = advance - -extents.height;
+    *y = extents.y_bearing + (diff >> 1);
     return true;
   }
 
@@ -257,6 +281,23 @@
 }
 #endif
 
+#ifndef HB_NO_DRAW
+static void
+hb_ot_get_glyph_shape (hb_font_t *font,
+		       void *font_data HB_UNUSED,
+		       hb_codepoint_t glyph,
+		       hb_draw_funcs_t *draw_funcs, void *draw_data,
+		       void *user_data)
+{
+  hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
+  if (font->face->table.glyf->get_path (font, glyph, draw_session)) return;
+#ifndef HB_NO_CFF
+  if (font->face->table.cff1->get_path (font, glyph, draw_session)) return;
+  if (font->face->table.cff2->get_path (font, glyph, draw_session)) return;
+#endif
+}
+#endif
+
 static inline void free_static_ot_funcs ();
 
 static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t>
@@ -279,6 +320,10 @@
     hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
 #endif
 
+#ifndef HB_NO_DRAW
+    hb_font_funcs_set_glyph_shape_func (funcs, hb_ot_get_glyph_shape, nullptr, nullptr);
+#endif
+
     hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
     //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
 

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -820,8 +820,7 @@
       }
 
 #ifndef HB_NO_VAR
-      if (unlikely (!glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ())))
-	return false;
+      glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ());
 #endif
 
       switch (type) {
@@ -936,7 +935,7 @@
 	return;
       short_offset = 0 == head.indexToLocFormat;
 
-      loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
+      loca_table = face->table.loca.get_blob (); // Needs no destruct!
       glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
 #ifndef HB_NO_VAR
       gvar = face->table.gvar;
@@ -951,7 +950,6 @@
     }
     ~accelerator_t ()
     {
-      loca_table.destroy ();
       glyf_table.destroy ();
     }
 
@@ -1152,11 +1150,10 @@
       return operation_count;
     }
 
-#ifdef HB_EXPERIMENTAL_API
     struct path_builder_t
     {
       hb_font_t *font;
-      draw_helper_t *draw_helper;
+      hb_draw_session_t *draw_session;
 
       struct optional_point_t
       {
@@ -1171,10 +1168,10 @@
 	{ return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
       } first_oncurve, first_offcurve, last_offcurve;
 
-      path_builder_t (hb_font_t *font_, draw_helper_t &draw_helper_)
+      path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
       {
 	font = font_;
-	draw_helper = &draw_helper_;
+	draw_session = &draw_session_;
 	first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
       }
 
@@ -1184,10 +1181,6 @@
 	 * https://stackoverflow.com/a/20772557 */
       void consume_point (const contour_point_t &point)
       {
-	/* Skip empty contours */
-	if (unlikely (point.is_end_point && !first_oncurve.has_data && !first_offcurve.has_data))
-	  return;
-
 	bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE;
 	optional_point_t p (point.x, point.y);
 	if (!first_oncurve.has_data)
@@ -1195,7 +1188,7 @@
 	  if (is_on_curve)
 	  {
 	    first_oncurve = p;
-	    draw_helper->move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
+	    draw_session->move_to (font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
 	  }
 	  else
 	  {
@@ -1204,7 +1197,7 @@
 	      optional_point_t mid = first_offcurve.lerp (p, .5f);
 	      first_oncurve = mid;
 	      last_offcurve = p;
-	      draw_helper->move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
+	      draw_session->move_to (font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
 	    }
 	    else
 	      first_offcurve = p;
@@ -1216,15 +1209,15 @@
 	  {
 	    if (is_on_curve)
 	    {
-	      draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
-					 font->em_scalef_x (p.x), font->em_scalef_y (p.y));
+	      draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
+					 font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
 	      last_offcurve = optional_point_t ();
 	    }
 	    else
 	    {
 	      optional_point_t mid = last_offcurve.lerp (p, .5f);
-	      draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
-					 font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
+	      draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
+					 font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
 	      last_offcurve = p;
 	    }
 	  }
@@ -1231,7 +1224,7 @@
 	  else
 	  {
 	    if (is_on_curve)
-	      draw_helper->line_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
+	      draw_session->line_to (font->em_fscalef_x (p.x), font->em_fscalef_y (p.y));
 	    else
 	      last_offcurve = p;
 	  }
@@ -1242,24 +1235,30 @@
 	  if (first_offcurve.has_data && last_offcurve.has_data)
 	  {
 	    optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
-	    draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
-				       font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
+	    draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
+				       font->em_fscalef_x (mid.x), font->em_fscalef_y (mid.y));
 	    last_offcurve = optional_point_t ();
 	    /* now check the rest */
 	  }
 
 	  if (first_offcurve.has_data && first_oncurve.has_data)
-	    draw_helper->quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y),
-				       font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
+	    draw_session->quadratic_to (font->em_fscalef_x (first_offcurve.x), font->em_fscalef_y (first_offcurve.y),
+				       font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
 	  else if (last_offcurve.has_data && first_oncurve.has_data)
-	    draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
-				       font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
+	    draw_session->quadratic_to (font->em_fscalef_x (last_offcurve.x), font->em_fscalef_y (last_offcurve.y),
+				       font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
 	  else if (first_oncurve.has_data)
-	    draw_helper->line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
+	    draw_session->line_to (font->em_fscalef_x (first_oncurve.x), font->em_fscalef_y (first_oncurve.y));
+	  else if (first_offcurve.has_data)
+	  {
+	    float x = font->em_fscalef_x (first_offcurve.x), y = font->em_fscalef_x (first_offcurve.y);
+	    draw_session->move_to (x, y);
+	    draw_session->quadratic_to (x, y, x, y);
+	  }
 
 	  /* Getting ready for the next contour */
 	  first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
-	  draw_helper->end_path ();
+	  draw_session->close_path ();
 	}
       }
       void points_end () {}
@@ -1269,9 +1268,8 @@
     };
 
     bool
-    get_path (hb_font_t *font, hb_codepoint_t gid, draw_helper_t &draw_helper) const
-    { return get_points (font, gid, path_builder_t (font, draw_helper)); }
-#endif
+    get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
+    { return get_points (font, gid, path_builder_t (font, draw_session)); }
 
 #ifndef HB_NO_VAR
     const gvar_accelerator_t *gvar;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -28,6 +28,7 @@
 #define HB_OT_HMTX_TABLE_HH
 
 #include "hb-open-type.hh"
+#include "hb-ot-maxp-table.hh"
 #include "hb-ot-hhea-table.hh"
 #include "hb-ot-var-hvar-table.hh"
 #include "hb-ot-metrics.hh"
@@ -98,12 +99,12 @@
 	   hb_requires (hb_is_iterator (Iterator))>
   void serialize (hb_serialize_context_t *c,
 		  Iterator it,
-		  unsigned num_advances)
+		  unsigned num_long_metrics)
   {
     unsigned idx = 0;
     for (auto _ : it)
     {
-      if (idx < num_advances)
+      if (idx < num_long_metrics)
       {
 	LongMetric lm;
 	lm.advance = _.first;
@@ -128,17 +129,17 @@
     if (unlikely (!table_prime)) return_trace (false);
 
     accelerator_t _mtx (c->plan->source);
-    unsigned num_advances;
+    unsigned num_long_metrics;
     {
-      /* Determine num_advances to encode. */
+      /* Determine num_long_metrics to encode. */
       auto& plan = c->plan;
-      num_advances = plan->num_output_glyphs ();
+      num_long_metrics = plan->num_output_glyphs ();
       hb_codepoint_t old_gid = 0;
-      unsigned int last_advance = plan->old_gid_for_new_gid (num_advances - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0;
-      while (num_advances > 1 &&
-	     last_advance == (plan->old_gid_for_new_gid (num_advances - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0))
+      unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0;
+      while (num_long_metrics > 1 &&
+	     last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0))
       {
-	num_advances--;
+	num_long_metrics--;
       }
     }
 
@@ -153,13 +154,13 @@
 	      })
     ;
 
-    table_prime->serialize (c->serializer, it, num_advances);
+    table_prime->serialize (c->serializer, it, num_long_metrics);
 
     if (unlikely (c->serializer->in_error ()))
       return_trace (false);
 
     // Amend header num hmetrics
-    if (unlikely (!subset_update_header (c->plan, num_advances)))
+    if (unlikely (!subset_update_header (c->plan, num_long_metrics)))
       return_trace (false);
 
     return_trace (true);
@@ -169,38 +170,48 @@
   {
     friend struct hmtxvmtx;
 
-    accelerator_t (hb_face_t *face,
-		   unsigned int default_advance_ = 0)
+    accelerator_t (hb_face_t *face)
     {
-      default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
+      table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag);
+      var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag);
 
-      num_advances = T::is_horizontal ?
-		     face->table.hhea->numberOfLongMetrics :
+      default_advance = T::is_horizontal ? hb_face_get_upem (face) / 2 : hb_face_get_upem (face);
+
+      /* Populate count variables and sort them out as we go */
+
+      unsigned int len = table.get_length ();
+      if (len & 1)
+        len--;
+
+      num_long_metrics = T::is_horizontal ?
+			 face->table.hhea->numberOfLongMetrics :
 #ifndef HB_NO_VERTICAL
-		     face->table.vhea->numberOfLongMetrics
+			 face->table.vhea->numberOfLongMetrics
 #else
-		     0
+			 0
 #endif
-		     ;
+			 ;
+      if (unlikely (num_long_metrics * 4 > len))
+	num_long_metrics = len / 4;
+      len -= num_long_metrics * 4;
 
-      table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag);
+      num_bearings = face->table.maxp->get_num_glyphs ();
 
-      /* Cap num_metrics() and num_advances() based on table length. */
-      unsigned int len = table.get_length ();
-      if (unlikely (num_advances * 4 > len))
-	num_advances = len / 4;
-      num_metrics = num_advances + (len - 4 * num_advances) / 2;
+      if (unlikely (num_bearings < num_long_metrics))
+        num_bearings = num_long_metrics;
+      if (unlikely ((num_bearings - num_long_metrics) * 2 > len))
+        num_bearings = num_long_metrics + len / 2;
+      len -= (num_bearings - num_long_metrics) * 2;
 
-      /* We MUST set num_metrics to zero if num_advances is zero.
+      /* We MUST set num_bearings to zero if num_long_metrics is zero.
        * Our get_advance() depends on that. */
-      if (unlikely (!num_advances))
-      {
-	num_metrics = num_advances = 0;
-	table.destroy ();
-	table = hb_blob_get_empty ();
-      }
+      if (unlikely (!num_long_metrics))
+	num_bearings = num_long_metrics = 0;
 
-      var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag);
+      num_advances = num_bearings + len / 2;
+      num_glyphs = face->get_num_glyphs ();
+      if (num_glyphs < num_advances)
+        num_glyphs = num_advances;
     }
     ~accelerator_t ()
     {
@@ -208,16 +219,18 @@
       var_table.destroy ();
     }
 
+    bool has_data () const { return (bool) num_bearings; }
+
     int get_side_bearing (hb_codepoint_t glyph) const
     {
-      if (glyph < num_advances)
+      if (glyph < num_long_metrics)
 	return table->longMetricZ[glyph].sb;
 
-      if (unlikely (glyph >= num_metrics))
+      if (unlikely (glyph >= num_bearings))
 	return 0;
 
-      const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances];
-      return bearings[glyph - num_advances];
+      const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
+      return bearings[glyph - num_long_metrics];
     }
 
     int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
@@ -225,7 +238,7 @@
       int side_bearing = get_side_bearing (glyph);
 
 #ifndef HB_NO_VAR
-      if (unlikely (glyph >= num_metrics) || !font->num_coords)
+      if (unlikely (glyph >= num_bearings) || !font->num_coords)
 	return side_bearing;
 
       if (var_table.get_length ())
@@ -239,18 +252,35 @@
 
     unsigned int get_advance (hb_codepoint_t glyph) const
     {
-      if (unlikely (glyph >= num_metrics))
-      {
-	/* If num_metrics is zero, it means we don't have the metrics table
-	 * for this direction: return default advance.  Otherwise, it means that the
-	 * glyph index is out of bound: return zero. */
-	if (num_metrics)
-	  return 0;
-	else
-	  return default_advance;
-      }
+      /* OpenType case. */
+      if (glyph < num_bearings)
+	return table->longMetricZ[hb_min (glyph, (uint32_t) num_long_metrics - 1)].advance;
 
-      return table->longMetricZ[hb_min (glyph, (uint32_t) num_advances - 1)].advance;
+      /* If num_advances is zero, it means we don't have the metrics table
+       * for this direction: return default advance.  Otherwise, there's a
+       * well-defined answer. */
+      if (unlikely (!num_advances))
+	return default_advance;
+
+#ifdef HB_NO_BORING_EXPANSION
+      return 0;
+#endif
+
+      if (unlikely (glyph >= num_glyphs))
+        return 0;
+
+      /* num_bearings <= glyph < num_glyphs;
+       * num_bearings <= num_advances */
+
+      /* TODO Optimize */
+
+      if (num_bearings == num_advances)
+        return get_advance (num_bearings - 1);
+
+      const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
+      const UFWORD *advances = (const UFWORD *) &bearings[num_bearings - num_long_metrics];
+
+      return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)];
     }
 
     unsigned int get_advance (hb_codepoint_t  glyph,
@@ -259,7 +289,7 @@
       unsigned int advance = get_advance (glyph);
 
 #ifndef HB_NO_VAR
-      if (unlikely (glyph >= num_metrics) || !font->num_coords)
+      if (unlikely (glyph >= num_bearings) || !font->num_coords)
 	return advance;
 
       if (var_table.get_length ())
@@ -272,8 +302,12 @@
     }
 
     protected:
-    unsigned int num_metrics;
-    unsigned int num_advances;
+    // 0 <= num_long_metrics <= num_bearings <= num_advances <= num_glyphs
+    unsigned num_long_metrics;
+    unsigned num_bearings;
+    unsigned num_advances;
+    unsigned num_glyphs;
+
     unsigned int default_advance;
 
     private:
@@ -305,6 +339,8 @@
 				 * the end. This allows a monospaced
 				 * font to vary the side bearing
 				 * values for each glyph. */
+/*UnsizedArrayOf<UFWORD>advancesX;*/
+				/* TODO Document. */
   public:
   DEFINE_SIZE_ARRAY (0, longMetricZ);
 };

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -41,7 +41,10 @@
 
 struct BaseCoordFormat1
 {
-  hb_position_t get_coord () const { return coordinate; }
+  hb_position_t get_coord (hb_font_t *font, hb_direction_t direction) const
+  {
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate);
+  }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -58,10 +61,10 @@
 
 struct BaseCoordFormat2
 {
-  hb_position_t get_coord () const
+  hb_position_t get_coord (hb_font_t *font, hb_direction_t direction) const
   {
     /* TODO */
-    return coordinate;
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -87,9 +90,10 @@
 			   hb_direction_t direction) const
   {
     const Device &device = this+deviceTable;
-    return coordinate + (HB_DIRECTION_IS_VERTICAL (direction) ?
-			 device.get_y_delta (font, var_store) :
-			 device.get_x_delta (font, var_store));
+
+    return HB_DIRECTION_IS_HORIZONTAL (direction)
+	 ? font->em_scale_y (coordinate) + device.get_y_delta (font, var_store)
+	 : font->em_scale_x (coordinate) + device.get_x_delta (font, var_store);
   }
 
 
@@ -120,8 +124,8 @@
 			   hb_direction_t        direction) const
   {
     switch (u.format) {
-    case 1: return u.format1.get_coord ();
-    case 2: return u.format2.get_coord ();
+    case 1: return u.format1.get_coord (font, direction);
+    case 2: return u.format2.get_coord (font, direction);
     case 3: return u.format3.get_coord (font, var_store, direction);
     default:return 0;
     }

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -37,7 +37,7 @@
 
 
 #ifndef HB_MAX_NESTING_LEVEL
-#define HB_MAX_NESTING_LEVEL	6
+#define HB_MAX_NESTING_LEVEL	64
 #endif
 #ifndef HB_MAX_CONTEXT_LENGTH
 #define HB_MAX_CONTEXT_LENGTH	64
@@ -60,6 +60,10 @@
 #define HB_MAX_LANGSYS	2000
 #endif
 
+#ifndef HB_MAX_LANGSYS_FEATURE_COUNT
+#define HB_MAX_LANGSYS_FEATURE_COUNT 50000
+#endif
+
 #ifndef HB_MAX_FEATURES
 #define HB_MAX_FEATURES 750
 #endif
@@ -105,36 +109,17 @@
       script_langsys_map (script_langsys_map_),
       duplicate_feature_map (duplicate_feature_map_),
       new_feature_indexes (new_collected_feature_indexes_),
-      script_count (0),langsys_count (0) {}
+      script_count (0),langsys_feature_count (0) {}
 
-  bool visitedScript (const void *s)
-  {
-    if (script_count++ > HB_MAX_SCRIPTS)
-      return true;
+  bool visitScript ()
+  { return script_count++ < HB_MAX_SCRIPTS; }
 
-    return visited (s, visited_script);
-  }
-
-  bool visitedLangsys (const void *l)
+  bool visitLangsys (unsigned feature_count)
   {
-    if (langsys_count++ > HB_MAX_LANGSYS)
-      return true;
-
-    return visited (l, visited_langsys);
+    langsys_feature_count += feature_count;
+    return langsys_feature_count < HB_MAX_LANGSYS_FEATURE_COUNT;
   }
 
-  private:
-  template <typename T>
-  bool visited (const T *p, hb_set_t &visited_set)
-  {
-    hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) p - (uintptr_t) table);
-    if (visited_set.in_error () || visited_set.has (delta))
-      return true;
-
-    visited_set.add (delta);
-    return false;
-  }
-
   public:
   const void *table;
   hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
@@ -142,10 +127,8 @@
   hb_set_t           *new_feature_indexes;
 
   private:
-  hb_set_t visited_script;
-  hb_set_t visited_langsys;
   unsigned script_count;
-  unsigned langsys_count;
+  unsigned langsys_feature_count;
 };
 
 struct hb_subset_layout_context_t :
@@ -643,11 +626,14 @@
     | hb_map (feature_index_map)
     ;
 
-    if (iter.len () != o_iter.len ())
-      return false;
+    for (; iter && o_iter; iter++, o_iter++)
+    {
+      unsigned a = *iter;
+      unsigned b = *o_iter;
+      if (a != b) return false;
+    }
 
-    for (const auto _ : + hb_zip (iter, o_iter))
-      if (_.first != _.second) return false;
+    if (iter || o_iter) return false;
 
     return true;
   }
@@ -732,7 +718,7 @@
                       unsigned script_index) const
   {
     if (!has_default_lang_sys () && !get_lang_sys_count ()) return;
-    if (c->visitedScript (this)) return;
+    if (!c->visitScript ()) return;
 
     if (!c->script_langsys_map->has (script_index))
     {
@@ -749,15 +735,14 @@
     {
       //only collect features from non-redundant langsys
       const LangSys& d = get_default_lang_sys ();
-      if (!c->visitedLangsys (&d)) {
+      if (c->visitLangsys (d.get_feature_count ())) {
         d.collect_features (c);
       }
 
       for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
       {
-
         const LangSys& l = this+_.first.offset;
-        if (c->visitedLangsys (&l)) continue;
+        if (!c->visitLangsys (l.get_feature_count ())) continue;
         if (l.compare (d, c->duplicate_feature_map)) continue;
 
         l.collect_features (c);
@@ -769,7 +754,7 @@
       for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
       {
         const LangSys& l = this+_.first.offset;
-        if (c->visitedLangsys (&l)) continue;
+        if (!c->visitLangsys (l.get_feature_count ())) continue;
         l.collect_features (c);
         c->script_langsys_map->get (script_index)->add (_.second);
       }

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -29,1727 +29,14 @@
 #ifndef HB_OT_LAYOUT_GSUB_TABLE_HH
 #define HB_OT_LAYOUT_GSUB_TABLE_HH
 
-#include "hb-ot-layout-gsubgpos.hh"
+#include "OT/Layout/GSUB/GSUB.hh"
 
-
 namespace OT {
 
-typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
+using Layout::GSUB::SubstLookup;
+using Layout::GSUB::ExtensionSubst;
 
-template<typename Iterator>
-static void SingleSubst_serialize (hb_serialize_context_t *c,
-				   Iterator it);
-
-
-struct SingleSubstFormat1
-{
-  bool intersects (const hb_set_t *glyphs) const
-  { return (this+coverage).intersects (glyphs); }
-
-  bool may_have_non_1to1 () const
-  { return false; }
-
-  void closure (hb_closure_context_t *c) const
-  {
-    unsigned d = deltaGlyphID;
-
-    + hb_iter (this+coverage)
-    | hb_filter (c->parent_active_glyphs ())
-    | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
-    | hb_sink (c->output)
-    ;
-
-  }
-
-  void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
-    unsigned d = deltaGlyphID;
-    + hb_iter (this+coverage)
-    | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
-    | hb_sink (c->output)
-    ;
-  }
-
-  const Coverage &get_coverage () const { return this+coverage; }
-
-  bool would_apply (hb_would_apply_context_t *c) const
-  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-    hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
-    unsigned int index = (this+coverage).get_coverage (glyph_id);
-    if (likely (index == NOT_COVERED)) return_trace (false);
-
-    /* According to the Adobe Annotated OpenType Suite, result is always
-     * limited to 16bit. */
-    glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu;
-    c->replace_glyph (glyph_id);
-
-    return_trace (true);
-  }
-
-  template<typename Iterator,
-	   hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
-  bool serialize (hb_serialize_context_t *c,
-		  Iterator glyphs,
-		  unsigned delta)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-    if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false);
-    c->check_assign (deltaGlyphID, delta, HB_SERIALIZE_ERROR_INT_OVERFLOW);
-    return_trace (true);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
-
-    hb_codepoint_t delta = deltaGlyphID;
-
-    auto it =
-    + hb_iter (this+coverage)
-    | hb_filter (glyphset)
-    | hb_map_retains_sorting ([&] (hb_codepoint_t g) {
-				return hb_codepoint_pair_t (g,
-							    (g + delta) & 0xFFFF); })
-    | hb_filter (glyphset, hb_second)
-    | hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t
-			      { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
-    ;
-
-    bool ret = bool (it);
-    SingleSubst_serialize (c->serializer, it);
-    return_trace (ret);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
-  }
-
-  protected:
-  HBUINT16	format;			/* Format identifier--format = 1 */
-  Offset16To<Coverage>
-		coverage;		/* Offset to Coverage table--from
-					 * beginning of Substitution table */
-  HBUINT16	deltaGlyphID;		/* Add to original GlyphID to get
-					 * substitute GlyphID, modulo 0x10000 */
-  public:
-  DEFINE_SIZE_STATIC (6);
-};
-
-struct SingleSubstFormat2
-{
-  bool intersects (const hb_set_t *glyphs) const
-  { return (this+coverage).intersects (glyphs); }
-
-  bool may_have_non_1to1 () const
-  { return false; }
-
-  void closure (hb_closure_context_t *c) const
-  {
-    + hb_zip (this+coverage, substitute)
-    | hb_filter (c->parent_active_glyphs (), hb_first)
-    | hb_map (hb_second)
-    | hb_sink (c->output)
-    ;
-
-  }
-
-  void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
-    + hb_zip (this+coverage, substitute)
-    | hb_map (hb_second)
-    | hb_sink (c->output)
-    ;
-  }
-
-  const Coverage &get_coverage () const { return this+coverage; }
-
-  bool would_apply (hb_would_apply_context_t *c) const
-  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
-
-    if (unlikely (index >= substitute.len)) return_trace (false);
-
-    c->replace_glyph (substitute[index]);
-
-    return_trace (true);
-  }
-
-  template<typename Iterator,
-	   hb_requires (hb_is_sorted_source_of (Iterator,
-						hb_codepoint_pair_t))>
-  bool serialize (hb_serialize_context_t *c,
-		  Iterator it)
-  {
-    TRACE_SERIALIZE (this);
-    auto substitutes =
-      + it
-      | hb_map (hb_second)
-      ;
-    auto glyphs =
-      + it
-      | hb_map_retains_sorting (hb_first)
-      ;
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-    if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false);
-    if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false);
-    return_trace (true);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
-
-    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 HBGlyphID16 &> p) -> hb_codepoint_pair_t
-			      { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
-    ;
-
-    bool ret = bool (it);
-    SingleSubst_serialize (c->serializer, it);
-    return_trace (ret);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && substitute.sanitize (c));
-  }
-
-  protected:
-  HBUINT16	format;			/* Format identifier--format = 2 */
-  Offset16To<Coverage>
-		coverage;		/* Offset to Coverage table--from
-					 * beginning of Substitution table */
-  Array16Of<HBGlyphID16>
-		substitute;		/* Array of substitute
-					 * GlyphIDs--ordered by Coverage Index */
-  public:
-  DEFINE_SIZE_ARRAY (6, substitute);
-};
-
-struct SingleSubst
-{
-
-  template<typename Iterator,
-	   hb_requires (hb_is_sorted_source_of (Iterator,
-						const hb_codepoint_pair_t))>
-  bool serialize (hb_serialize_context_t *c,
-		  Iterator glyphs)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (u.format))) return_trace (false);
-    unsigned format = 2;
-    unsigned delta = 0;
-    if (glyphs)
-    {
-      format = 1;
-      auto get_delta = [=] (hb_codepoint_pair_t _)
-		       { return (unsigned) (_.second - _.first) & 0xFFFF; };
-      delta = get_delta (*glyphs);
-      if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
-    }
-    u.format = format;
-    switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c,
-					       + glyphs
-					       | hb_map_retains_sorting (hb_first),
-					       delta));
-    case 2: return_trace (u.format2.serialize (c, glyphs));
-    default:return_trace (false);
-    }
-  }
-
-  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 {
-  HBUINT16		format;		/* Format identifier */
-  SingleSubstFormat1	format1;
-  SingleSubstFormat2	format2;
-  } u;
-};
-
-template<typename Iterator>
-static void
-SingleSubst_serialize (hb_serialize_context_t *c,
-		       Iterator it)
-{ c->start_embed<SingleSubst> ()->serialize (c, it); }
-
-struct Sequence
-{
-  bool intersects (const hb_set_t *glyphs) const
-  { return hb_all (substitute, glyphs); }
-
-  void closure (hb_closure_context_t *c) const
-  { c->output->add_array (substitute.arrayZ, substitute.len); }
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  { c->output->add_array (substitute.arrayZ, substitute.len); }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-    unsigned int count = substitute.len;
-
-    /* Special-case to make it in-place and not consider this
-     * as a "multiplied" substitution. */
-    if (unlikely (count == 1))
-    {
-      c->replace_glyph (substitute.arrayZ[0]);
-      return_trace (true);
-    }
-    /* Spec disallows this, but Uniscribe allows it.
-     * https://github.com/harfbuzz/harfbuzz/issues/253 */
-    else if (unlikely (count == 0))
-    {
-      c->buffer->delete_glyph ();
-      return_trace (true);
-    }
-
-    unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
-			 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
-    unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur());
-
-    for (unsigned int i = 0; i < count; i++)
-    {
-      /* If is attached to a ligature, don't disturb that.
-       * https://github.com/harfbuzz/harfbuzz/issues/3069 */
-      if (!lig_id)
-	_hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
-      c->output_glyph_for_component (substitute.arrayZ[i], klass);
-    }
-    c->buffer->skip_glyph ();
-
-    return_trace (true);
-  }
-
-  template <typename Iterator,
-	    hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
-  bool serialize (hb_serialize_context_t *c,
-		  Iterator subst)
-  {
-    TRACE_SERIALIZE (this);
-    return_trace (substitute.serialize (c, subst));
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
-
-    if (!intersects (&glyphset)) return_trace (false);
-
-    auto it =
-    + hb_iter (substitute)
-    | hb_map (glyph_map)
-    ;
-
-    auto *out = c->serializer->start_embed (*this);
-    return_trace (out->serialize (c->serializer, it));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (substitute.sanitize (c));
-  }
-
-  protected:
-  Array16Of<HBGlyphID16>
-		substitute;		/* String of GlyphIDs to substitute */
-  public:
-  DEFINE_SIZE_ARRAY (2, substitute);
-};
-
-struct MultipleSubstFormat1
-{
-  bool intersects (const hb_set_t *glyphs) const
-  { return (this+coverage).intersects (glyphs); }
-
-  bool may_have_non_1to1 () const
-  { return true; }
-
-  void closure (hb_closure_context_t *c) const
-  {
-    + hb_zip (this+coverage, sequence)
-    | hb_filter (c->parent_active_glyphs (), hb_first)
-    | hb_map (hb_second)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const Sequence &_) { _.closure (c); })
-    ;
-  }
-
-  void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
-    + hb_zip (this+coverage, sequence)
-    | hb_map (hb_second)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); })
-    ;
-  }
-
-  const Coverage &get_coverage () const { return this+coverage; }
-
-  bool would_apply (hb_would_apply_context_t *c) const
-  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-
-    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
-
-    return_trace ((this+sequence[index]).apply (c));
-  }
-
-  bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID16> glyphs,
-		  hb_array_t<const unsigned int> substitute_len_list,
-		  hb_array_t<const HBGlyphID16> substitute_glyphs_list)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-    if (unlikely (!sequence.serialize (c, glyphs.length))) return_trace (false);
-    for (unsigned int i = 0; i < glyphs.length; i++)
-    {
-      unsigned int substitute_len = substitute_len_list[i];
-      if (unlikely (!sequence[i]
-                        .serialize_serialize (c, substitute_glyphs_list.sub_array (0, substitute_len))))
-	return_trace (false);
-      substitute_glyphs_list += substitute_len;
-    }
-    return_trace (coverage.serialize_serialize (c, glyphs));
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    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);
-    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, sequence)
-    | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->sequence, 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 (bool (new_coverage));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && sequence.sanitize (c, this));
-  }
-
-  protected:
-  HBUINT16	format;			/* Format identifier--format = 1 */
-  Offset16To<Coverage>
-		coverage;		/* Offset to Coverage table--from
-					 * beginning of Substitution table */
-  Array16OfOffset16To<Sequence>
-		sequence;		/* Array of Sequence tables
-					 * ordered by Coverage Index */
-  public:
-  DEFINE_SIZE_ARRAY (6, sequence);
-};
-
-struct MultipleSubst
-{
-  bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID16> glyphs,
-		  hb_array_t<const unsigned int> substitute_len_list,
-		  hb_array_t<const HBGlyphID16> substitute_glyphs_list)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (u.format))) return_trace (false);
-    unsigned int format = 1;
-    u.format = format;
-    switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, substitute_glyphs_list));
-    default:return_trace (false);
-    }
-  }
-
-  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)...));
-    default:return_trace (c->default_return_value ());
-    }
-  }
-
-  protected:
-  union {
-  HBUINT16		format;		/* Format identifier */
-  MultipleSubstFormat1	format1;
-  } u;
-};
-
-struct AlternateSet
-{
-  bool intersects (const hb_set_t *glyphs) const
-  { return hb_any (alternates, glyphs); }
-
-  void closure (hb_closure_context_t *c) const
-  { c->output->add_array (alternates.arrayZ, alternates.len); }
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  { c->output->add_array (alternates.arrayZ, alternates.len); }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-    unsigned int count = alternates.len;
-
-    if (unlikely (!count)) return_trace (false);
-
-    hb_mask_t glyph_mask = c->buffer->cur().mask;
-    hb_mask_t lookup_mask = c->lookup_mask;
-
-    /* Note: This breaks badly if two features enabled this lookup together. */
-    unsigned int shift = hb_ctz (lookup_mask);
-    unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
-
-    /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */
-    if (alt_index == HB_OT_MAP_MAX_VALUE && c->random)
-    {
-      /* Maybe we can do better than unsafe-to-break all; but since we are
-       * changing random state, it would be hard to track that.  Good 'nough. */
-      c->buffer->unsafe_to_break (0, c->buffer->len);
-      alt_index = c->random_number () % count + 1;
-    }
-
-    if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
-
-    c->replace_glyph (alternates[alt_index - 1]);
-
-    return_trace (true);
-  }
-
-  unsigned
-  get_alternates (unsigned        start_offset,
-		  unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
-		  hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
-  {
-    if (alternates.len && alternate_count)
-    {
-      + alternates.sub_array (start_offset, alternate_count)
-      | hb_sink (hb_array (alternate_glyphs, *alternate_count))
-      ;
-    }
-    return alternates.len;
-  }
-
-  template <typename Iterator,
-	    hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
-  bool serialize (hb_serialize_context_t *c,
-		  Iterator alts)
-  {
-    TRACE_SERIALIZE (this);
-    return_trace (alternates.serialize (c, alts));
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
-
-    auto it =
-      + hb_iter (alternates)
-      | hb_filter (glyphset)
-      | hb_map (glyph_map)
-      ;
-
-    auto *out = c->serializer->start_embed (*this);
-    return_trace (out->serialize (c->serializer, it) &&
-		  out->alternates);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (alternates.sanitize (c));
-  }
-
-  protected:
-  Array16Of<HBGlyphID16>
-		alternates;		/* Array of alternate GlyphIDs--in
-					 * arbitrary order */
-  public:
-  DEFINE_SIZE_ARRAY (2, alternates);
-};
-
-struct AlternateSubstFormat1
-{
-  bool intersects (const hb_set_t *glyphs) const
-  { return (this+coverage).intersects (glyphs); }
-
-  bool may_have_non_1to1 () const
-  { return false; }
-
-  void closure (hb_closure_context_t *c) const
-  {
-    + hb_zip (this+coverage, alternateSet)
-    | hb_filter (c->parent_active_glyphs (), hb_first)
-    | hb_map (hb_second)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
-    ;
-
-  }
-
-  void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
-    + hb_zip (this+coverage, alternateSet)
-    | hb_map (hb_second)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
-    ;
-  }
-
-  const Coverage &get_coverage () const { return this+coverage; }
-
-  bool would_apply (hb_would_apply_context_t *c) const
-  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
-  unsigned
-  get_glyph_alternates (hb_codepoint_t  gid,
-			unsigned        start_offset,
-			unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
-			hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
-  { return (this+alternateSet[(this+coverage).get_coverage (gid)])
-	   .get_alternates (start_offset, alternate_count, alternate_glyphs); }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-
-    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
-
-    return_trace ((this+alternateSet[index]).apply (c));
-  }
-
-  bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID16> glyphs,
-		  hb_array_t<const unsigned int> alternate_len_list,
-		  hb_array_t<const HBGlyphID16> alternate_glyphs_list)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-    if (unlikely (!alternateSet.serialize (c, glyphs.length))) return_trace (false);
-    for (unsigned int i = 0; i < glyphs.length; i++)
-    {
-      unsigned int alternate_len = alternate_len_list[i];
-      if (unlikely (!alternateSet[i]
-                        .serialize_serialize (c, alternate_glyphs_list.sub_array (0, alternate_len))))
-	return_trace (false);
-      alternate_glyphs_list += alternate_len;
-    }
-    return_trace (coverage.serialize_serialize (c, glyphs));
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    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);
-    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, alternateSet)
-    | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->alternateSet, 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 (bool (new_coverage));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
-  }
-
-  protected:
-  HBUINT16	format;			/* Format identifier--format = 1 */
-  Offset16To<Coverage>
-		coverage;		/* Offset to Coverage table--from
-					 * beginning of Substitution table */
-  Array16OfOffset16To<AlternateSet>
-		alternateSet;		/* Array of AlternateSet tables
-					 * ordered by Coverage Index */
-  public:
-  DEFINE_SIZE_ARRAY (6, alternateSet);
-};
-
-struct AlternateSubst
-{
-  bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID16> glyphs,
-		  hb_array_t<const unsigned int> alternate_len_list,
-		  hb_array_t<const HBGlyphID16> alternate_glyphs_list)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (u.format))) return_trace (false);
-    unsigned int format = 1;
-    u.format = format;
-    switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list));
-    default:return_trace (false);
-    }
-  }
-
-  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)...));
-    default:return_trace (c->default_return_value ());
-    }
-  }
-
-  protected:
-  union {
-  HBUINT16		format;		/* Format identifier */
-  AlternateSubstFormat1	format1;
-  } u;
-};
-
-
-struct Ligature
-{
-  bool intersects (const hb_set_t *glyphs) const
-  { return hb_all (component, glyphs); }
-
-  void closure (hb_closure_context_t *c) const
-  {
-    if (!intersects (c->glyphs)) return;
-    c->output->add (ligGlyph);
-  }
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    c->input->add_array (component.arrayZ, component.get_length ());
-    c->output->add (ligGlyph);
-  }
-
-  bool would_apply (hb_would_apply_context_t *c) const
-  {
-    if (c->len != component.lenP1)
-      return false;
-
-    for (unsigned int i = 1; i < c->len; i++)
-      if (likely (c->glyphs[i] != component[i]))
-	return false;
-
-    return true;
-  }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-    unsigned int count = component.lenP1;
-
-    if (unlikely (!count)) return_trace (false);
-
-    /* Special-case to make it in-place and not consider this
-     * as a "ligated" substitution. */
-    if (unlikely (count == 1))
-    {
-      c->replace_glyph (ligGlyph);
-      return_trace (true);
-    }
-
-    unsigned int total_component_count = 0;
-
-    unsigned int match_end = 0;
-    unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
-
-    if (likely (!match_input (c, count,
-			      &component[1],
-			      match_glyph,
-			      nullptr,
-			      &match_end,
-			      match_positions,
-			      &total_component_count)))
-    {
-      c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
-      return_trace (false);
-    }
-
-    ligate_input (c,
-		  count,
-		  match_positions,
-		  match_end,
-		  ligGlyph,
-		  total_component_count);
-
-    return_trace (true);
-  }
-
-  template <typename Iterator,
-	    hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
-  bool serialize (hb_serialize_context_t *c,
-		  hb_codepoint_t ligature,
-		  Iterator components /* Starting from second */)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-    ligGlyph = ligature;
-    if (unlikely (!component.serialize (c, components))) return_trace (false);
-    return_trace (true);
-  }
-
-  bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
-  {
-    TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    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)
-      | hb_map (glyph_map)
-      ;
-
-    auto *out = c->serializer->start_embed (*this);
-    return_trace (out->serialize (c->serializer,
-				  glyph_map[ligGlyph],
-				  it));
-  }
-
-  public:
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (ligGlyph.sanitize (c) && component.sanitize (c));
-  }
-
-  protected:
-  HBGlyphID16	ligGlyph;		/* GlyphID of ligature to substitute */
-  HeadlessArrayOf<HBGlyphID16>
-		component;		/* Array of component GlyphIDs--start
-					 * with the second  component--ordered
-					 * in writing direction */
-  public:
-  DEFINE_SIZE_ARRAY (4, component);
-};
-
-struct LigatureSet
-{
-  bool intersects (const hb_set_t *glyphs) const
-  {
-    return
-    + hb_iter (ligature)
-    | hb_map (hb_add (this))
-    | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
-    | hb_any
-    ;
-  }
-
-  void closure (hb_closure_context_t *c) const
-  {
-    + hb_iter (ligature)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const Ligature &_) { _.closure (c); })
-    ;
-  }
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    + hb_iter (ligature)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
-    ;
-  }
-
-  bool would_apply (hb_would_apply_context_t *c) const
-  {
-    return
-    + hb_iter (ligature)
-    | hb_map (hb_add (this))
-    | hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
-    | hb_any
-    ;
-  }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-    {
-      const Ligature &lig = this+ligature[i];
-      if (lig.apply (c)) return_trace (true);
-    }
-
-    return_trace (false);
-  }
-
-  bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const HBGlyphID16> ligatures,
-		  hb_array_t<const unsigned int> component_count_list,
-		  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);
-    if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false);
-    for (unsigned int i = 0; i < ligatures.length; i++)
-    {
-      unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0);
-      if (unlikely (!ligature[i].serialize_serialize (c,
-                                                      ligatures[i],
-                                                      component_list.sub_array (0, component_count))))
-	return_trace (false);
-      component_list += component_count;
-    }
-    return_trace (true);
-  }
-
-  bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
-    + hb_iter (ligature)
-    | 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));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (ligature.sanitize (c, this));
-  }
-
-  protected:
-  Array16OfOffset16To<Ligature>
-		ligature;		/* Array LigatureSet tables
-					 * ordered by preference */
-  public:
-  DEFINE_SIZE_ARRAY (2, ligature);
-};
-
-struct LigatureSubstFormat1
-{
-  bool intersects (const hb_set_t *glyphs) const
-  {
-    return
-    + hb_zip (this+coverage, ligatureSet)
-    | hb_filter (*glyphs, hb_first)
-    | hb_map (hb_second)
-    | hb_map ([this, glyphs] (const Offset16To<LigatureSet> &_)
-	      { return (this+_).intersects (glyphs); })
-    | hb_any
-    ;
-  }
-
-  bool may_have_non_1to1 () const
-  { return true; }
-
-  void closure (hb_closure_context_t *c) const
-  {
-    + hb_zip (this+coverage, ligatureSet)
-    | hb_filter (c->parent_active_glyphs (), hb_first)
-    | hb_map (hb_second)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
-    ;
-
-  }
-
-  void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
-
-    + hb_zip (this+coverage, ligatureSet)
-    | hb_map (hb_second)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); })
-    ;
-  }
-
-  const Coverage &get_coverage () const { return this+coverage; }
-
-  bool would_apply (hb_would_apply_context_t *c) const
-  {
-    unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
-    if (likely (index == NOT_COVERED)) return false;
-
-    const LigatureSet &lig_set = this+ligatureSet[index];
-    return lig_set.would_apply (c);
-  }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-
-    unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
-
-    const LigatureSet &lig_set = this+ligatureSet[index];
-    return_trace (lig_set.apply (c));
-  }
-
-  bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID16> first_glyphs,
-		  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-		  hb_array_t<const HBGlyphID16> ligatures_list,
-		  hb_array_t<const unsigned int> component_count_list,
-		  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);
-    if (unlikely (!ligatureSet.serialize (c, first_glyphs.length))) return_trace (false);
-    for (unsigned int i = 0; i < first_glyphs.length; i++)
-    {
-      unsigned int ligature_count = ligature_per_first_glyph_count_list[i];
-      if (unlikely (!ligatureSet[i]
-                        .serialize_serialize (c,
-                                              ligatures_list.sub_array (0, ligature_count),
-                                              component_count_list.sub_array (0, ligature_count),
-                                              component_list))) return_trace (false);
-      ligatures_list += ligature_count;
-      component_count_list += ligature_count;
-    }
-    return_trace (coverage.serialize_serialize (c, first_glyphs));
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    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);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-    out->format = format;
-
-    // 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 ([&] (const LigatureSet& _) {
-      return _.intersects (&glyphset);
-    }, hb_second)
-    | hb_map (hb_first)
-    | 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))
-    ;
-
-    return_trace (bool (new_coverage));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
-  }
-
-  protected:
-  HBUINT16	format;			/* Format identifier--format = 1 */
-  Offset16To<Coverage>
-		coverage;		/* Offset to Coverage table--from
-					 * beginning of Substitution table */
-  Array16OfOffset16To<LigatureSet>
-		ligatureSet;		/* Array LigatureSet tables
-					 * ordered by Coverage Index */
-  public:
-  DEFINE_SIZE_ARRAY (6, ligatureSet);
-};
-
-struct LigatureSubst
-{
-  bool serialize (hb_serialize_context_t *c,
-		  hb_sorted_array_t<const HBGlyphID16> first_glyphs,
-		  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-		  hb_array_t<const HBGlyphID16> ligatures_list,
-		  hb_array_t<const unsigned int> component_count_list,
-		  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);
-    unsigned int format = 1;
-    u.format = format;
-    switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c,
-					       first_glyphs,
-					       ligature_per_first_glyph_count_list,
-					       ligatures_list,
-					       component_count_list,
-					       component_list));
-    default:return_trace (false);
-    }
-  }
-
-  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)...));
-    default:return_trace (c->default_return_value ());
-    }
-  }
-
-  protected:
-  union {
-  HBUINT16		format;		/* Format identifier */
-  LigatureSubstFormat1	format1;
-  } u;
-};
-
-
-struct ContextSubst : Context {};
-
-struct ChainContextSubst : ChainContext {};
-
-struct ExtensionSubst : Extension<ExtensionSubst>
-{
-  typedef struct SubstLookupSubTable SubTable;
-  bool is_reverse () const;
-};
-
-
-struct ReverseChainSingleSubstFormat1
-{
-  bool intersects (const hb_set_t *glyphs) const
-  {
-    if (!(this+coverage).intersects (glyphs))
-      return false;
-
-    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-
-    unsigned int count;
-
-    count = backtrack.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!(this+backtrack[i]).intersects (glyphs))
-	return false;
-
-    count = lookahead.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!(this+lookahead[i]).intersects (glyphs))
-	return false;
-
-    return true;
-  }
-
-  bool may_have_non_1to1 () const
-  { return false; }
-
-  void closure (hb_closure_context_t *c) const
-  {
-    if (!intersects (c->glyphs)) return;
-
-    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
-
-    + hb_zip (this+coverage, substitute)
-    | hb_filter (c->parent_active_glyphs (), hb_first)
-    | hb_map (hb_second)
-    | hb_sink (c->output)
-    ;
-  }
-
-  void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
-  void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
-
-    unsigned int count;
-
-    count = backtrack.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return;
-
-    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-    count = lookahead.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return;
-
-    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
-    count = substitute.len;
-    c->output->add_array (substitute.arrayZ, substitute.len);
-  }
-
-  const Coverage &get_coverage () const { return this+coverage; }
-
-  bool would_apply (hb_would_apply_context_t *c) const
-  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-    if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
-      return_trace (false); /* No chaining to this type */
-
-    unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
-
-    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
-
-    if (unlikely (index >= substitute.len)) return_trace (false);
-
-    unsigned int start_index = 0, end_index = 0;
-    if (match_backtrack (c,
-			 backtrack.len, (HBUINT16 *) backtrack.arrayZ,
-			 match_coverage, this,
-			 &start_index) &&
-	match_lookahead (c,
-			 lookahead.len, (HBUINT16 *) lookahead.arrayZ,
-			 match_coverage, this,
-			 c->buffer->idx + 1, &end_index))
-    {
-      c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
-      c->replace_glyph_inplace (substitute[index]);
-      /* Note: We DON'T decrease buffer->idx.  The main loop does it
-       * for us.  This is useful for preventing surprises if someone
-       * calls us through a Context lookup. */
-      return_trace (true);
-    }
-    else
-    {
-      c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
-      return_trace (false);
-    }
-  }
-
-  template<typename Iterator,
-           hb_requires (hb_is_iterator (Iterator))>
-  bool serialize_coverage_offset_array (hb_subset_context_t *c, Iterator it) const
-  {
-    TRACE_SERIALIZE (this);
-    auto *out = c->serializer->start_embed<Array16OfOffset16To<Coverage>> ();
-
-    if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size)))
-      return_trace (false);
-
-    for (auto& offset : it) {
-      auto *o = out->serialize_append (c->serializer);
-      if (unlikely (!o) || !o->serialize_subset (c, offset, this))
-        return_trace (false);
-    }
-
-    return_trace (true);
-  }
-
-  template<typename Iterator, typename BacktrackIterator, typename LookaheadIterator,
-           hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_pair_t)),
-           hb_requires (hb_is_iterator (BacktrackIterator)),
-           hb_requires (hb_is_iterator (LookaheadIterator))>
-  bool serialize (hb_subset_context_t *c,
-                  Iterator coverage_subst_iter,
-                  BacktrackIterator backtrack_iter,
-                  LookaheadIterator lookahead_iter) const
-  {
-    TRACE_SERIALIZE (this);
-
-    auto *out = c->serializer->start_embed (this);
-    if (unlikely (!c->serializer->check_success (out))) return_trace (false);
-    if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
-    if (unlikely (!c->serializer->embed (this->coverage))) return_trace (false);
-
-    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<HBGlyphID16>> ();
-    auto substitutes =
-    + coverage_subst_iter
-    | hb_map (hb_second)
-    ;
-
-    auto glyphs =
-    + coverage_subst_iter
-    | hb_map_retains_sorting (hb_first)
-    ;
-    if (unlikely (! c->serializer->check_success (substitute_out->serialize (c->serializer, substitutes))))
-        return_trace (false);
-
-    if (unlikely (!out->coverage.serialize_serialize (c->serializer, glyphs)))
-      return_trace (false);
-    return_trace (true);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
-
-    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-    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 HBGlyphID16 &> p) -> hb_codepoint_pair_t
-                              { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
-    ;
-
-    return_trace (bool (it) && serialize (c, it, backtrack.iter (), lookahead.iter ()));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
-      return_trace (false);
-    const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
-    if (!lookahead.sanitize (c, this))
-      return_trace (false);
-    const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
-    return_trace (substitute.sanitize (c));
-  }
-
-  protected:
-  HBUINT16	format;			/* Format identifier--format = 1 */
-  Offset16To<Coverage>
-		coverage;		/* Offset to Coverage table--from
-					 * beginning of table */
-  Array16OfOffset16To<Coverage>
-		backtrack;		/* Array of coverage tables
-					 * in backtracking sequence, in glyph
-					 * sequence order */
-  Array16OfOffset16To<Coverage>
-		lookaheadX;		/* Array of coverage tables
-					 * in lookahead sequence, in glyph
-					 * sequence order */
-  Array16Of<HBGlyphID16>
-		substituteX;		/* Array of substitute
-					 * GlyphIDs--ordered by Coverage Index */
-  public:
-  DEFINE_SIZE_MIN (10);
-};
-
-struct ReverseChainSingleSubst
-{
-  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)...));
-    default:return_trace (c->default_return_value ());
-    }
-  }
-
-  protected:
-  union {
-  HBUINT16				format;		/* Format identifier */
-  ReverseChainSingleSubstFormat1	format1;
-  } u;
-};
-
-
-
-/*
- * SubstLookup
- */
-
-struct SubstLookupSubTable
-{
-  friend struct Lookup;
-  friend struct SubstLookup;
-
-  enum Type {
-    Single		= 1,
-    Multiple		= 2,
-    Alternate		= 3,
-    Ligature		= 4,
-    Context		= 5,
-    ChainContext	= 6,
-    Extension		= 7,
-    ReverseChainSingle	= 8
-  };
-
-  template <typename context_t, typename ...Ts>
-  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
-  {
-    TRACE_DISPATCH (this, lookup_type);
-    switch (lookup_type) {
-    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 ());
-    }
-  }
-
-  bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
-  {
-    hb_intersects_context_t c (glyphs);
-    return dispatch (&c, lookup_type);
-  }
-
-  protected:
-  union {
-  SingleSubst			single;
-  MultipleSubst			multiple;
-  AlternateSubst		alternate;
-  LigatureSubst			ligature;
-  ContextSubst			context;
-  ChainContextSubst		chainContext;
-  ExtensionSubst		extension;
-  ReverseChainSingleSubst	reverseChainContextSingle;
-  } u;
-  public:
-  DEFINE_SIZE_MIN (0);
-};
-
-
-struct SubstLookup : Lookup
-{
-  typedef SubstLookupSubTable SubTable;
-
-  const SubTable& get_subtable (unsigned int i) const
-  { return Lookup::get_subtable<SubTable> (i); }
-
-  static inline bool lookup_type_is_reverse (unsigned int lookup_type)
-  { return lookup_type == SubTable::ReverseChainSingle; }
-
-  bool is_reverse () const
-  {
-    unsigned int type = get_type ();
-    if (unlikely (type == SubTable::Extension))
-      return reinterpret_cast<const ExtensionSubst &> (get_subtable (0)).is_reverse ();
-    return lookup_type_is_reverse (type);
-  }
-
-  bool may_have_non_1to1 () const
-  {
-    hb_have_non_1to1_context_t c;
-    return dispatch (&c);
-  }
-
-  bool apply (hb_ot_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-    return_trace (dispatch (c));
-  }
-
-  bool intersects (const hb_set_t *glyphs) const
-  {
-    hb_intersects_context_t c (glyphs);
-    return dispatch (&c);
-  }
-
-  hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const
-  {
-    if (!c->should_visit_lookup (this_index))
-      return hb_closure_context_t::default_return_value ();
-
-    c->set_recurse_func (dispatch_closure_recurse_func);
-
-    hb_closure_context_t::return_t ret = dispatch (c);
-
-    c->flush ();
-
-    return ret;
-  }
-
-  hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
-  {
-    if (c->is_lookup_visited (this_index))
-      return hb_closure_lookups_context_t::default_return_value ();
-
-    c->set_lookup_visited (this_index);
-    if (!intersects (c->glyphs))
-    {
-      c->set_lookup_inactive (this_index);
-      return hb_closure_lookups_context_t::default_return_value ();
-    }
-
-    c->set_recurse_func (dispatch_closure_lookups_recurse_func);
-
-    hb_closure_lookups_context_t::return_t ret = dispatch (c);
-    return ret;
-  }
-
-  hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
-  {
-    c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
-    return dispatch (c);
-  }
-
-  template <typename set_t>
-  void collect_coverage (set_t *glyphs) const
-  {
-    hb_collect_coverage_context_t<set_t> c (glyphs);
-    dispatch (&c);
-  }
-
-  bool would_apply (hb_would_apply_context_t *c,
-		    const hb_ot_layout_lookup_accelerator_t *accel) const
-  {
-    if (unlikely (!c->len)) return false;
-    if (!accel->may_have (c->glyphs[0])) return false;
-      return dispatch (c);
-  }
-
-  static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
-
-  bool serialize_single (hb_serialize_context_t *c,
-			 uint32_t lookup_props,
-			 hb_sorted_array_t<const HBGlyphID16> glyphs,
-			 hb_array_t<const HBGlyphID16> substitutes)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
-    if (c->push<SubTable> ()->u.single.serialize (c, hb_zip (glyphs, substitutes)))
-    {
-      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
-      return_trace (true);
-    }
-    c->pop_discard ();
-    return_trace (false);
-  }
-
-  bool serialize_multiple (hb_serialize_context_t *c,
-			   uint32_t lookup_props,
-			   hb_sorted_array_t<const HBGlyphID16> glyphs,
-			   hb_array_t<const unsigned int> substitute_len_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);
-    if (c->push<SubTable> ()->u.multiple.
-        serialize (c,
-                   glyphs,
-                   substitute_len_list,
-                   substitute_glyphs_list))
-    {
-      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
-      return_trace (true);
-    }
-    c->pop_discard ();
-    return_trace (false);
-  }
-
-  bool serialize_alternate (hb_serialize_context_t *c,
-			    uint32_t lookup_props,
-			    hb_sorted_array_t<const HBGlyphID16> glyphs,
-			    hb_array_t<const unsigned int> alternate_len_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);
-
-    if (c->push<SubTable> ()->u.alternate.
-        serialize (c,
-                   glyphs,
-                   alternate_len_list,
-                   alternate_glyphs_list))
-    {
-      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
-      return_trace (true);
-    }
-    c->pop_discard ();
-    return_trace (false);
-  }
-
-  bool serialize_ligature (hb_serialize_context_t *c,
-			   uint32_t lookup_props,
-			   hb_sorted_array_t<const HBGlyphID16> first_glyphs,
-			   hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-			   hb_array_t<const HBGlyphID16> ligatures_list,
-			   hb_array_t<const unsigned int> component_count_list,
-			   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);
-    if (c->push<SubTable> ()->u.ligature.
-        serialize (c,
-                   first_glyphs,
-                   ligature_per_first_glyph_count_list,
-                   ligatures_list,
-                   component_count_list,
-                   component_list))
-    {
-      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
-      return_trace (true);
-    }
-    c->pop_discard ();
-    return_trace (false);
-  }
-
-  template <typename context_t>
-  static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
-
-  static inline typename hb_closure_context_t::return_t closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index);
-
-  static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index)
-  {
-    if (!c->should_visit_lookup (lookup_index))
-      return hb_empty_t ();
-
-    hb_closure_context_t::return_t ret = closure_glyphs_recurse_func (c, lookup_index, covered_seq_indices, seq_index, end_index);
-
-    /* While in theory we should flush here, it will cause timeouts because a recursive
-     * lookup can keep growing the glyph set.  Skip, and outer loop will retry up to
-     * HB_CLOSURE_MAX_STAGES time, which should be enough for every realistic font. */
-    //c->flush ();
-
-    return ret;
-  }
-
-  HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned lookup_index);
-
-  template <typename context_t, typename ...Ts>
-  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
-  { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
-
-  bool subset (hb_subset_context_t *c) const
-  { return Lookup::subset<SubTable> (c); }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  { return Lookup::sanitize<SubTable> (c); }
-};
-
-/*
- * GSUB -- Glyph Substitution
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gsub
- */
-
-struct GSUB : GSUBGPOS
-{
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_GSUB;
-
-  const SubstLookup& get_lookup (unsigned int i) const
-  { return static_cast<const SubstLookup &> (GSUBGPOS::get_lookup (i)); }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_langsys, c->plan->gsub_features);
-    return GSUBGPOS::subset<SubstLookup> (&l);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  { return GSUBGPOS::sanitize<SubstLookup> (c); }
-
-  HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
-				   hb_face_t *face) const;
-
-  void closure_lookups (hb_face_t      *face,
-			const hb_set_t *glyphs,
-			hb_set_t       *lookup_indexes /* IN/OUT */) const
-  { GSUBGPOS::closure_lookups<SubstLookup> (face, glyphs, lookup_indexes); }
-
-  typedef GSUBGPOS::accelerator_t<GSUB> accelerator_t;
-};
-
-
-struct GSUB_accelerator_t : GSUB::accelerator_t {
-  GSUB_accelerator_t (hb_face_t *face) : GSUB::accelerator_t (face) {}
-};
-
-
+// TODO(garretrieger): Move into the new layout directory.
 /* Out-of-class implementation for methods recursing */
 
 #ifndef HB_NO_OT_LAYOUT

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -408,12 +408,11 @@
   {
     matcher_t () :
 	     lookup_props (0),
+	     mask (-1),
 	     ignore_zwnj (false),
 	     ignore_zwj (false),
-	     mask (-1),
-#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
-	     syllable arg1(0),
-#undef arg1
+	     per_syllable (false),
+	     syllable {0},
 	     match_func (nullptr),
 	     match_data (nullptr) {}
 
@@ -423,7 +422,8 @@
     void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
     void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
     void set_mask (hb_mask_t mask_) { mask = mask_; }
-    void set_syllable (uint8_t syllable_)  { syllable = syllable_; }
+    void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; }
+    void set_syllable (uint8_t syllable_)  { syllable = per_syllable ? syllable_ : 0; }
     void set_match_func (match_func_t match_func_,
 			 const void *match_data_)
     { match_func = match_func_; match_data = match_data_; }
@@ -469,9 +469,10 @@
 
     protected:
     unsigned int lookup_props;
+    hb_mask_t mask;
     bool ignore_zwnj;
     bool ignore_zwj;
-    hb_mask_t mask;
+    bool per_syllable;
     uint8_t syllable;
     match_func_t match_func;
     const void *match_data;
@@ -490,6 +491,7 @@
       /* Ignore ZWJ if we are matching context, or asked to. */
       matcher.set_ignore_zwj  (context_match || c->auto_zwj);
       matcher.set_mask (context_match ? -1 : c->lookup_mask);
+      matcher.set_per_syllable (c->per_syllable);
     }
     void set_lookup_props (unsigned int lookup_props)
     {
@@ -636,6 +638,7 @@
   bool has_glyph_classes;
   bool auto_zwnj;
   bool auto_zwj;
+  bool per_syllable;
   bool random;
 
   uint32_t random_state;
@@ -664,6 +667,7 @@
 			has_glyph_classes (gdef.has_glyph_classes ()),
 			auto_zwnj (true),
 			auto_zwj (true),
+			per_syllable (false),
 			random (false),
 			random_state (1) { init_iters (); }
 
@@ -676,6 +680,7 @@
   void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; init_iters (); }
   void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); }
   void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); }
+  void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; init_iters (); }
   void set_random (bool random_) { random = random_; }
   void set_recurse_func (recurse_func_t func) { recurse_func = func; }
   void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
@@ -1415,6 +1420,12 @@
     if (unlikely (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index))
       continue;
 
+    unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
+
+    /* This can happen if earlier recursed lookups deleted many entries. */
+    if (unlikely (match_positions[idx] >= orig_len))
+      continue;
+
     if (unlikely (!buffer->move_to (match_positions[idx])))
       break;
 
@@ -1421,7 +1432,6 @@
     if (unlikely (buffer->max_ops <= 0))
       break;
 
-    unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
     if (!c->recurse (lookupRecord[i].lookupListIndex))
       continue;
 
@@ -1457,15 +1467,18 @@
      */
 
     end += delta;
-    if (end <= int (match_positions[idx]))
+    if (end < int (match_positions[idx]))
     {
       /* End might end up being smaller than match_positions[idx] if the recursed
-       * lookup ended up removing many items, more than we have had matched.
-       * Just never rewind end back and get out of here.
-       * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 */
+       * lookup ended up removing many items.
+       * Just never rewind end beyond start of current position, since that is
+       * not possible in the recursed lookup.  Also adjust delta as such.
+       *
+       * https://bugs.chromium.org/p/chromium/issues/detail?id=659496
+       * https://github.com/harfbuzz/harfbuzz/issues/1611
+       */
+      delta += match_positions[idx] - end;
       end = match_positions[idx];
-      /* There can't be any further changes. */
-      break;
     }
 
     unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
@@ -1477,7 +1490,7 @@
     }
     else
     {
-      /* NOTE: delta is negative. */
+      /* NOTE: delta is non-positive. */
       delta = hb_max (delta, (int) next - (int) count);
       next -= delta;
     }

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -54,6 +54,8 @@
 #include "hb-aat-layout-morx-table.hh"
 #include "hb-aat-layout-opbd-table.hh" // Just so we compile it; unused otherwise.
 
+using OT::Layout::GSUB::GSUB;
+
 /**
  * SECTION:hb-ot-layout
  * @title: hb-ot-layout
@@ -361,6 +363,13 @@
  * Fetches a list of the caret positions defined for a ligature glyph in the GDEF
  * table of the font. The list returned will begin at the offset provided.
  *
+ * Note that a ligature that is formed from n characters will have n-1
+ * caret positions. The first character is not represented in the array,
+ * since its caret position is the glyph position.
+ *
+ * The positions returned by this function are 'unshaped', and will have to
+ * be fixed up for kerning that may be applied to the ligature glyph.
+ *
  * Return value: Total number of ligature caret positions for @glyph.
  *
  **/
@@ -382,7 +391,7 @@
  */
 
 bool
-OT::GSUB::is_blocklisted (hb_blob_t *blob HB_UNUSED,
+GSUB::is_blocklisted (hb_blob_t *blob HB_UNUSED,
 			  hb_face_t *face) const
 {
 #ifdef HB_NO_OT_LAYOUT_BLOCKLIST
@@ -999,7 +1008,7 @@
   hb_collect_features_context_t (hb_face_t *face,
 				 hb_tag_t   table_tag,
 				 hb_set_t  *feature_indices_,
-                                 const hb_tag_t *features)
+				 const hb_tag_t *features)
 
     : g (get_gsubgpos_table (face, table_tag)),
       feature_indices (feature_indices_),
@@ -1026,7 +1035,7 @@
     {
       hb_tag_t tag = g.get_feature_tag (i);
       if (features_set.has (tag))
-        feature_indices_filter.add(i);
+	feature_indices_filter.add(i);
     }
   }
 
@@ -1522,7 +1531,7 @@
   hb_map_t done_lookups_glyph_count;
   hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
   OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
-  const OT::GSUB& gsub = *face->table.GSUB->table;
+  const GSUB& gsub = *face->table.GSUB->table;
 
   unsigned int iteration_count = 0;
   unsigned int glyphs_length;
@@ -1801,7 +1810,7 @@
     table (*face->table.GSUB->table),
     accels (face->table.GSUB->accels) {}
 
-  const OT::GSUB &table;
+  const GSUB &table;
   const OT::hb_ot_layout_lookup_accelerator_t *accels;
 };
 
@@ -1922,6 +1931,7 @@
       c.set_auto_zwj (lookups[table_index][i].auto_zwj);
       c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
       c.set_random (lookups[table_index][i].random);
+      c.set_per_syllable (lookups[table_index][i].per_syllable);
 
       apply_string<Proxy> (&c,
 			   proxy.table.get_lookup (lookup_index),
@@ -1960,6 +1970,77 @@
 
 #ifndef HB_NO_BASE
 /**
+ * hb_ot_layout_get_horizontal_baseline_tag_for_script:
+ * @script: a script tag.
+ *
+ * Fetches the dominant horizontal baseline tag used by @script.
+ *
+ * Return value: dominant baseline tag for the @script.
+ *
+ * Since: 4.0.0
+ **/
+hb_ot_layout_baseline_tag_t
+hb_ot_layout_get_horizontal_baseline_tag_for_script (hb_script_t script)
+{
+  /* Keep in sync with hb_ot_layout_get_baseline_with_fallback */
+  switch ((int) script)
+  {
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_BENGALI:
+    case HB_SCRIPT_DEVANAGARI:
+    case HB_SCRIPT_GUJARATI:
+    case HB_SCRIPT_GURMUKHI:
+    /* Unicode-2.0 additions */
+    case HB_SCRIPT_TIBETAN:
+    /* Unicode-4.0 additions */
+    case HB_SCRIPT_LIMBU:
+    /* Unicode-4.1 additions */
+    case HB_SCRIPT_SYLOTI_NAGRI:
+    /* Unicode-5.0 additions */
+    case HB_SCRIPT_PHAGS_PA:
+    /* Unicode-5.2 additions */
+    case HB_SCRIPT_MEETEI_MAYEK:
+    /* Unicode-6.1 additions */
+    case HB_SCRIPT_SHARADA:
+    case HB_SCRIPT_TAKRI:
+    /* Unicode-7.0 additions */
+    case HB_SCRIPT_MODI:
+    case HB_SCRIPT_SIDDHAM:
+    case HB_SCRIPT_TIRHUTA:
+    /* Unicode-9.0 additions */
+    case HB_SCRIPT_MARCHEN:
+    case HB_SCRIPT_NEWA:
+    /* Unicode-10.0 additions */
+    case HB_SCRIPT_SOYOMBO:
+    case HB_SCRIPT_ZANABAZAR_SQUARE:
+    /* Unicode-11.0 additions */
+    case HB_SCRIPT_DOGRA:
+    case HB_SCRIPT_GUNJALA_GONDI:
+    /* Unicode-12.0 additions */
+    case HB_SCRIPT_NANDINAGARI:
+      return HB_OT_LAYOUT_BASELINE_TAG_HANGING;
+
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_HANGUL:
+    case HB_SCRIPT_HAN:
+    case HB_SCRIPT_HIRAGANA:
+    case HB_SCRIPT_KATAKANA:
+    /* Unicode-3.0 additions */
+    case HB_SCRIPT_BOPOMOFO:
+    /* Unicode-9.0 additions */
+    case HB_SCRIPT_TANGUT:
+    /* Unicode-10.0 additions */
+    case HB_SCRIPT_NUSHU:
+    /* Unicode-13.0 additions */
+    case HB_SCRIPT_KHITAN_SMALL_SCRIPT:
+      return HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT;
+
+    default:
+      return HB_OT_LAYOUT_BASELINE_TAG_ROMAN;
+  }
+}
+
+/**
  * hb_ot_layout_get_baseline:
  * @font: a font
  * @baseline_tag: a baseline tag
@@ -1966,7 +2047,7 @@
  * @direction: text direction.
  * @script_tag:  script tag.
  * @language_tag: language tag, currently unused.
- * @coord: (out): baseline value if found.
+ * @coord: (out) (nullable): baseline value if found.
  *
  * Fetches a baseline value from the face.
  *
@@ -1982,13 +2063,231 @@
 			   hb_tag_t                     language_tag,
 			   hb_position_t               *coord        /* OUT.  May be NULL. */)
 {
-  bool result = font->face->table.BASE->get_baseline (font, baseline_tag, direction, script_tag, language_tag, coord);
+  return font->face->table.BASE->get_baseline (font, baseline_tag, direction, script_tag, language_tag, coord);
+}
 
-  if (result && coord)
-    *coord = HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (*coord) : font->em_scale_x (*coord);
+/**
+ * hb_ot_layout_get_baseline_with_fallback:
+ * @font: a font
+ * @baseline_tag: a baseline tag
+ * @direction: text direction.
+ * @script_tag:  script tag.
+ * @language_tag: language tag, currently unused.
+ * @coord: (out): baseline value if found.
+ *
+ * Fetches a baseline value from the face, and synthesizes
+ * it if the font does not have it.
+ *
+ * Since: 4.0.0
+ **/
+void
+hb_ot_layout_get_baseline_with_fallback (hb_font_t                   *font,
+					 hb_ot_layout_baseline_tag_t  baseline_tag,
+					 hb_direction_t               direction,
+					 hb_tag_t                     script_tag,
+					 hb_tag_t                     language_tag,
+					 hb_position_t               *coord /* OUT */)
+{
+  if (hb_ot_layout_get_baseline (font,
+				 baseline_tag,
+				 direction,
+				 script_tag,
+				 language_tag,
+				 coord))
+    return;
 
-  return result;
+  /* Synthesize missing baselines.
+   * See https://www.w3.org/TR/css-inline-3/#baseline-synthesis-fonts
+   */
+  switch (baseline_tag)
+  {
+  case HB_OT_LAYOUT_BASELINE_TAG_ROMAN:
+    *coord = 0; // FIXME origin ?
+    break;
+
+  case HB_OT_LAYOUT_BASELINE_TAG_MATH:
+    {
+      hb_codepoint_t glyph;
+      hb_glyph_extents_t extents;
+      if (HB_DIRECTION_IS_HORIZONTAL (direction) &&
+	  (hb_font_get_nominal_glyph (font, 0x2212u, &glyph) ||
+	   hb_font_get_nominal_glyph (font, '-', &glyph)) &&
+	  hb_font_get_glyph_extents (font, glyph, &extents))
+      {
+	*coord = extents.y_bearing + extents.height / 2;
+      }
+      else
+      {
+	hb_position_t x_height = font->y_scale / 2;
+#ifndef HB_NO_METRICS
+	hb_ot_metrics_get_position_with_fallback (font, HB_OT_METRICS_TAG_X_HEIGHT, &x_height);
+#endif
+	*coord = x_height / 2;
+      }
+    }
+    break;
+
+  case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT:
+  case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT:
+    {
+      hb_position_t embox_top, embox_bottom;
+
+      hb_ot_layout_get_baseline_with_fallback (font,
+					       HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
+					       direction,
+					       script_tag,
+					       language_tag,
+					       &embox_top);
+      hb_ot_layout_get_baseline_with_fallback (font,
+					       HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
+					       direction,
+					       script_tag,
+					       language_tag,
+					       &embox_bottom);
+
+      if (baseline_tag == HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT)
+	*coord = embox_top + (embox_bottom - embox_top) / 10;
+      else
+	*coord = embox_bottom + (embox_top - embox_bottom) / 10;
+    }
+    break;
+
+  case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT:
+    if (hb_ot_layout_get_baseline (font,
+				   HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
+				   direction,
+				   script_tag,
+				   language_tag,
+				   coord))
+      *coord += HB_DIRECTION_IS_HORIZONTAL (direction) ? font->y_scale : font->x_scale;
+    else
+    {
+      hb_font_extents_t font_extents;
+      hb_font_get_extents_for_direction (font, direction, &font_extents);
+      *coord = font_extents.ascender;
+    }
+    break;
+
+  case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT:
+    if (hb_ot_layout_get_baseline (font,
+				   HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
+				   direction,
+				   script_tag,
+				   language_tag,
+				   coord))
+      *coord -= HB_DIRECTION_IS_HORIZONTAL (direction) ? font->y_scale : font->x_scale;
+    else
+    {
+      hb_font_extents_t font_extents;
+      hb_font_get_extents_for_direction (font, direction, &font_extents);
+      *coord = font_extents.descender;
+    }
+    break;
+
+  case HB_OT_LAYOUT_BASELINE_TAG_HANGING:
+    if (HB_DIRECTION_IS_HORIZONTAL (direction))
+    {
+      hb_codepoint_t ch;
+      hb_codepoint_t glyph;
+      hb_glyph_extents_t extents;
+
+      /* Keep in sync with hb_ot_layout_get_horizontal_baseline_for_script */
+      switch ((int) script_tag)
+      {
+      /* Unicode-1.1 additions */
+      case HB_SCRIPT_BENGALI:          ch = 0x0995u; break;
+      case HB_SCRIPT_DEVANAGARI:       ch = 0x0915u; break;
+      case HB_SCRIPT_GUJARATI:         ch = 0x0a95u; break;
+      case HB_SCRIPT_GURMUKHI:         ch = 0x0a15u; break;
+      /* Unicode-2.0 additions */
+      case HB_SCRIPT_TIBETAN:          ch = 0x0f40u; break;
+      /* Unicode-4.0 additions */
+      case HB_SCRIPT_LIMBU:            ch = 0x1901u; break;
+      /* Unicode-4.1 additions */
+      case HB_SCRIPT_SYLOTI_NAGRI:     ch = 0xa807u; break;
+      /* Unicode-5.0 additions */
+      case HB_SCRIPT_PHAGS_PA:         ch = 0xa840u; break;
+      /* Unicode-5.2 additions */
+      case HB_SCRIPT_MEETEI_MAYEK:     ch = 0xabc0u; break;
+      /* Unicode-6.1 additions */
+      case HB_SCRIPT_SHARADA:          ch = 0x11191u; break;
+      case HB_SCRIPT_TAKRI:            ch = 0x1168cu; break;
+      /* Unicode-7.0 additions */
+      case HB_SCRIPT_MODI:             ch = 0x1160eu;break;
+      case HB_SCRIPT_SIDDHAM:          ch = 0x11590u; break;
+      case HB_SCRIPT_TIRHUTA:          ch = 0x1148fu; break;
+      /* Unicode-9.0 additions */
+      case HB_SCRIPT_MARCHEN:          ch = 0x11c72u; break;
+      case HB_SCRIPT_NEWA:             ch = 0x1140eu; break;
+      /* Unicode-10.0 additions */
+      case HB_SCRIPT_SOYOMBO:          ch = 0x11a5cu; break;
+      case HB_SCRIPT_ZANABAZAR_SQUARE: ch = 0x11a0bu; break;
+      /* Unicode-11.0 additions */
+      case HB_SCRIPT_DOGRA:            ch = 0x1180au; break;
+      case HB_SCRIPT_GUNJALA_GONDI:    ch = 0x11d6cu; break;
+      /* Unicode-12.0 additions */
+      case HB_SCRIPT_NANDINAGARI:      ch = 0x119b0u; break;
+      default:                         ch = 0;        break;
+      }
+
+      if (ch &&
+	  hb_font_get_nominal_glyph (font, ch, &glyph) &&
+	  hb_font_get_glyph_extents (font, glyph, &extents))
+	*coord = extents.y_bearing;
+      else
+	*coord = font->y_scale * 6 / 10; // FIXME makes assumptions about origin
+    }
+    else
+      *coord = font->x_scale * 6 / 10; // FIXME makes assumptions about origin
+    break;
+
+  case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL:
+    {
+      hb_position_t top, bottom;
+      hb_ot_layout_get_baseline_with_fallback (font,
+					       HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
+					       direction,
+					       script_tag,
+					       language_tag,
+					       &top);
+      hb_ot_layout_get_baseline_with_fallback (font,
+					       HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
+					       direction,
+					       script_tag,
+					       language_tag,
+					       &bottom);
+      *coord = (top + bottom) / 2;
+
+    }
+    break;
+
+  case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL:
+    {
+      hb_position_t top, bottom;
+      hb_ot_layout_get_baseline_with_fallback (font,
+					       HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT,
+					       direction,
+					       script_tag,
+					       language_tag,
+					       &top);
+      hb_ot_layout_get_baseline_with_fallback (font,
+					       HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT,
+					       direction,
+					       script_tag,
+					       language_tag,
+					       &bottom);
+      *coord = (top + bottom) / 2;
+
+    }
+    break;
+
+  case _HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE:
+  default:
+    *coord = 0;
+    break;
+  }
 }
+
 #endif
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -332,32 +332,7 @@
 				    hb_set_t     *glyphs_after,  /* OUT.  May be NULL */
 				    hb_set_t     *glyphs_output  /* OUT.  May be NULL */);
 
-#ifdef HB_NOT_IMPLEMENTED
-typedef struct
-{
-  const hb_codepoint_t *before,
-  unsigned int          before_length,
-  const hb_codepoint_t *input,
-  unsigned int          input_length,
-  const hb_codepoint_t *after,
-  unsigned int          after_length,
-} hb_ot_layout_glyph_sequence_t;
 
-typedef hb_bool_t
-(*hb_ot_layout_glyph_sequence_func_t) (hb_font_t    *font,
-				       hb_tag_t      table_tag,
-				       unsigned int  lookup_index,
-				       const hb_ot_layout_glyph_sequence_t *sequence,
-				       void         *user_data);
-
-HB_EXTERN void
-Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t    *face,
-					 hb_tag_t      table_tag,
-					 unsigned int  lookup_index,
-					 hb_ot_layout_glyph_sequence_func_t callback,
-					 void         *user_data);
-#endif
-
 /* Variations support */
 
 HB_EXTERN hb_bool_t
@@ -411,19 +386,6 @@
 					 hb_set_t       *glyphs);
 
 
-#ifdef HB_NOT_IMPLEMENTED
-/* Note: You better have GDEF when using this API, or marks won't do much. */
-HB_EXTERN hb_bool_t
-Xhb_ot_layout_lookup_substitute (hb_font_t            *font,
-				unsigned int          lookup_index,
-				const hb_ot_layout_glyph_sequence_t *sequence,
-				unsigned int          out_size,
-				hb_codepoint_t       *glyphs_out,   /* OUT */
-				unsigned int         *clusters_out, /* OUT */
-				unsigned int         *out_length    /* OUT */);
-#endif
-
-
 /*
  * GPOS
  */
@@ -431,15 +393,6 @@
 HB_EXTERN hb_bool_t
 hb_ot_layout_has_positioning (hb_face_t *face);
 
-#ifdef HB_NOT_IMPLEMENTED
-/* Note: You better have GDEF when using this API, or marks won't do much. */
-HB_EXTERN hb_bool_t
-Xhb_ot_layout_lookup_position (hb_font_t            *font,
-			      unsigned int          lookup_index,
-			      const hb_ot_layout_glyph_sequence_t *sequence,
-			      hb_glyph_position_t  *positions /* IN / OUT */);
-#endif
-
 /* Optical 'size' feature info.  Returns true if found.
  * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
 HB_EXTERN hb_bool_t
@@ -487,9 +440,11 @@
  * if the direction is horizontal or vertical, respectively.
  * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT: Ideographic character face top or right edge,
  * if the direction is horizontal or vertical, respectively.
+ * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL: The center of the ideographic character face. Since: 4.0.0
  * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT: Ideographic em-box bottom or left edge,
  * if the direction is horizontal or vertical, respectively.
  * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT: Ideographic em-box top or right edge baseline,
+ * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL: The center of the ideographic em-box. Since: 4.0.0
  * if the direction is horizontal or vertical, respectively.
  * @HB_OT_LAYOUT_BASELINE_TAG_MATH: The baseline about which mathematical characters are centered.
  * In vertical writing mode when mathematical characters rotated 90 degrees clockwise, are centered.
@@ -503,8 +458,10 @@
   HB_OT_LAYOUT_BASELINE_TAG_HANGING			= HB_TAG ('h','a','n','g'),
   HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT	= HB_TAG ('i','c','f','b'),
   HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT	= HB_TAG ('i','c','f','t'),
+  HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL		= HB_TAG ('I','c','f','c'),
   HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT	= HB_TAG ('i','d','e','o'),
   HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT	= HB_TAG ('i','d','t','p'),
+  HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL		= HB_TAG ('I','d','c','e'),
   HB_OT_LAYOUT_BASELINE_TAG_MATH			= HB_TAG ('m','a','t','h'),
 
   /*< private >*/
@@ -511,6 +468,9 @@
   _HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
 } hb_ot_layout_baseline_tag_t;
 
+HB_EXTERN hb_ot_layout_baseline_tag_t
+hb_ot_layout_get_horizontal_baseline_tag_for_script (hb_script_t script);
+
 HB_EXTERN hb_bool_t
 hb_ot_layout_get_baseline (hb_font_t                   *font,
 			   hb_ot_layout_baseline_tag_t  baseline_tag,
@@ -519,6 +479,14 @@
 			   hb_tag_t                     language_tag,
 			   hb_position_t               *coord        /* OUT.  May be NULL. */);
 
+HB_EXTERN void
+hb_ot_layout_get_baseline_with_fallback (hb_font_t                   *font,
+					 hb_ot_layout_baseline_tag_t  baseline_tag,
+					 hb_direction_t               direction,
+					 hb_tag_t                     script_tag,
+					 hb_tag_t                     language_tag,
+					 hb_position_t               *coord        /* OUT */);
+
 HB_END_DECLS
 
 #endif /* HB_OT_LAYOUT_H */

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -108,13 +108,17 @@
 
 namespace OT {
   struct hb_ot_apply_context_t;
+  struct hb_ot_layout_lookup_accelerator_t;
+namespace Layout {
+namespace GSUB {
   struct SubstLookup;
-  struct hb_ot_layout_lookup_accelerator_t;
 }
+}
+}
 
 HB_INTERNAL void
 hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
-				const OT::SubstLookup &lookup,
+				const OT::Layout::GSUB::SubstLookup &lookup,
 				const OT::hb_ot_layout_lookup_accelerator_t &accel);
 
 
@@ -168,18 +172,7 @@
   return start;
 }
 
-static inline void
-_hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
-		     hb_font_t *font HB_UNUSED,
-		     hb_buffer_t *buffer)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    info[i].syllable() = 0;
-}
 
-
 /* unicode_props */
 
 /* Design:
@@ -485,6 +478,8 @@
 _hb_allocate_lig_id (hb_buffer_t *buffer)
 {
   uint8_t lig_id = buffer->next_serial () & 0x07;
+  if (unlikely (!lig_id))
+    lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
   return lig_id;
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -117,7 +117,8 @@
 				  hb_mask_t     mask,
 				  bool          auto_zwnj,
 				  bool          auto_zwj,
-				  bool          random)
+				  bool          random,
+				  bool          per_syllable)
 {
   unsigned int lookup_indices[32];
   unsigned int offset, len;
@@ -145,6 +146,7 @@
       lookup->auto_zwnj = auto_zwnj;
       lookup->auto_zwj = auto_zwj;
       lookup->random = random;
+      lookup->per_syllable = per_syllable;
     }
 
     offset += len;
@@ -277,6 +279,7 @@
     map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ);
     map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
     map->random = !!(info->flags & F_RANDOM);
+    map->per_syllable = !!(info->flags & F_PER_SYLLABLE);
     if ((info->flags & F_GLOBAL) && info->max_value == 1) {
       /* Uses the global bit */
       map->shift = global_bit_shift;
@@ -319,7 +322,8 @@
 		       m.features[i].mask,
 		       m.features[i].auto_zwnj,
 		       m.features[i].auto_zwj,
-		       m.features[i].random);
+		       m.features[i].random,
+		       m.features[i].per_syllable);
 
       /* Sort lookups and merge duplicates */
       if (last_num_lookups < m.lookups[table_index].length)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -56,6 +56,7 @@
     unsigned int auto_zwnj : 1;
     unsigned int auto_zwj : 1;
     unsigned int random : 1;
+    unsigned int per_syllable : 1;
 
     int cmp (const hb_tag_t tag_) const
     { return tag_ < tag ? -1 : tag_ > tag ? 1 : 0; }
@@ -66,6 +67,7 @@
     unsigned short auto_zwnj : 1;
     unsigned short auto_zwj : 1;
     unsigned short random : 1;
+    unsigned short per_syllable : 1;
     hb_mask_t mask;
 
     HB_INTERNAL static int cmp (const void *pa, const void *pb)
@@ -183,7 +185,8 @@
   F_GLOBAL_MANUAL_JOINERS= F_GLOBAL | F_MANUAL_JOINERS,
   F_GLOBAL_HAS_FALLBACK = F_GLOBAL | F_HAS_FALLBACK,
   F_GLOBAL_SEARCH	= 0x0010u, /* If feature not found in LangSys, look for it in global feature list and pick one. */
-  F_RANDOM		= 0x0020u  /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
+  F_RANDOM		= 0x0020u, /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
+  F_PER_SYLLABLE	= 0x0040u  /* Contain lookup application to within syllable. */
 };
 HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t);
 
@@ -237,7 +240,8 @@
 				hb_mask_t     mask,
 				bool          auto_zwnj = true,
 				bool          auto_zwj = true,
-				bool          random = false);
+				bool          random = false,
+				bool          per_syllable = false);
 
   struct feature_info_t {
     hb_tag_t tag;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -238,6 +238,145 @@
   }
 }
 
+/**
+ * hb_ot_metrics_get_position_with_fallback:
+ * @font: an #hb_font_t object.
+ * @metrics_tag: tag of metrics value you like to fetch.
+ * @position: (out) (optional): result of metrics value from the font.
+ *
+ * Fetches metrics value corresponding to @metrics_tag from @font,
+ * and synthesizes a value if it the value is missing in the font.
+ *
+ * Since: 4.0.0
+ **/
+void
+hb_ot_metrics_get_position_with_fallback (hb_font_t           *font,
+					  hb_ot_metrics_tag_t  metrics_tag,
+					  hb_position_t       *position     /* OUT */)
+{
+  hb_font_extents_t font_extents;
+  hb_codepoint_t glyph;
+  hb_glyph_extents_t extents;
+
+  if (hb_ot_metrics_get_position (font, metrics_tag, position))
+    {
+      if ((metrics_tag != HB_OT_METRICS_TAG_STRIKEOUT_SIZE &&
+           metrics_tag != HB_OT_METRICS_TAG_UNDERLINE_SIZE) ||
+          *position != 0)
+        return;
+    }
+
+  switch (metrics_tag)
+  {
+  case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER:
+  case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT:
+    hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
+    *position = font_extents.ascender;
+    break;
+
+  case HB_OT_METRICS_TAG_VERTICAL_ASCENDER:
+    hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
+    *position = font_extents.ascender;
+    break;
+
+  case HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER:
+  case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT:
+    hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
+    *position = font_extents.descender;
+    break;
+
+  case HB_OT_METRICS_TAG_VERTICAL_DESCENDER:
+    hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
+    *position = font_extents.ascender;
+    break;
+
+  case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP:
+    hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
+    *position = font_extents.line_gap;
+    break;
+
+  case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP:
+    hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
+    *position = font_extents.line_gap;
+    break;
+
+  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:
+  case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE:
+    *position = 1;
+    break;
+
+  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:
+  case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN:
+    *position = 0;
+    break;
+
+  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET:
+  case HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET:
+    *position = 0;
+    break;
+
+  case HB_OT_METRICS_TAG_X_HEIGHT:
+    if (hb_font_get_nominal_glyph (font, 'x', &glyph) &&
+        hb_font_get_glyph_extents (font, glyph, &extents))
+      *position = extents.y_bearing;
+    else
+      *position = font->y_scale / 2;
+    break;
+
+  case HB_OT_METRICS_TAG_CAP_HEIGHT:
+    if (hb_font_get_nominal_glyph (font, 'O', &glyph) &&
+        hb_font_get_glyph_extents (font, glyph, &extents))
+      *position = extents.height + 2 * extents.y_bearing;
+    else
+      *position = font->y_scale * 2 / 3;
+    break;
+
+  case HB_OT_METRICS_TAG_STRIKEOUT_SIZE:
+  case HB_OT_METRICS_TAG_UNDERLINE_SIZE:
+    *position = font->y_scale / 18;
+    break;
+
+  case HB_OT_METRICS_TAG_STRIKEOUT_OFFSET:
+    {
+      hb_position_t ascender;
+      hb_ot_metrics_get_position_with_fallback (font,
+                                                HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER,
+                                                &ascender);
+      *position = ascender / 2;
+    }
+    break;
+
+  case HB_OT_METRICS_TAG_UNDERLINE_OFFSET:
+    *position = - font->y_scale / 18;
+    break;
+
+  case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE:
+  case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE:
+    *position = font->x_scale * 10 / 12;
+    break;
+
+  case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE:
+  case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE:
+    *position = font->y_scale * 10 / 12;
+    break;
+
+  case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET:
+  case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET:
+    *position = 0;
+    break;
+
+  case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET:
+  case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET:
+    *position = font->y_scale / 5;
+    break;
+
+  case _HB_OT_METRICS_TAG_MAX_VALUE:
+  default:
+    *position = 0;
+    break;
+  }
+}
+
 #ifndef HB_NO_VAR
 /**
  * hb_ot_metrics_get_variation:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -110,6 +110,11 @@
 			    hb_ot_metrics_tag_t  metrics_tag,
 			    hb_position_t       *position     /* OUT.  May be NULL. */);
 
+HB_EXTERN void
+hb_ot_metrics_get_position_with_fallback (hb_font_t           *font,
+					  hb_ot_metrics_tag_t  metrics_tag,
+					  hb_position_t       *position     /* OUT */);
+
 HB_EXTERN float
 hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
 

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -109,17 +109,17 @@
    * These features are applied in order, one at a time, after initial_reordering,
    * constrained to the syllable.
    */
-  {HB_TAG('n','u','k','t'), F_GLOBAL_MANUAL_JOINERS},
-  {HB_TAG('a','k','h','n'), F_GLOBAL_MANUAL_JOINERS},
-  {HB_TAG('r','p','h','f'),        F_MANUAL_JOINERS},
-  {HB_TAG('r','k','r','f'), F_GLOBAL_MANUAL_JOINERS},
-  {HB_TAG('p','r','e','f'),        F_MANUAL_JOINERS},
-  {HB_TAG('b','l','w','f'),        F_MANUAL_JOINERS},
-  {HB_TAG('a','b','v','f'),        F_MANUAL_JOINERS},
-  {HB_TAG('h','a','l','f'),        F_MANUAL_JOINERS},
-  {HB_TAG('p','s','t','f'),        F_MANUAL_JOINERS},
-  {HB_TAG('v','a','t','u'), F_GLOBAL_MANUAL_JOINERS},
-  {HB_TAG('c','j','c','t'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('n','u','k','t'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('a','k','h','n'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('r','p','h','f'),        F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('r','k','r','f'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('p','r','e','f'),        F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('b','l','w','f'),        F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('a','b','v','f'),        F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('h','a','l','f'),        F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('p','s','t','f'),        F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('v','a','t','u'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('c','j','c','t'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
   /*
    * Other features.
    * These features are applied all at once, after final_reordering, constrained
@@ -127,12 +127,12 @@
    * Default Bengali font in Windows for example has intermixed
    * lookups for init,pres,abvs,blws features.
    */
-  {HB_TAG('i','n','i','t'),        F_MANUAL_JOINERS},
-  {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS},
-  {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS},
-  {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
-  {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
-  {HB_TAG('h','a','l','n'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('i','n','i','t'),        F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('h','a','l','n'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
 };
 
 /*
@@ -183,10 +183,10 @@
   /* Do this before any lookups have been applied. */
   map->add_gsub_pause (setup_syllables_indic);
 
-  map->enable_feature (HB_TAG('l','o','c','l'));
+  map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
   /* The Indic specs do not require ccmp, but we apply it here since if
    * there is a use of it, it's typically at the beginning. */
-  map->enable_feature (HB_TAG('c','c','m','p'));
+  map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
 
 
   unsigned int i = 0;
@@ -201,8 +201,6 @@
 
   for (; i < INDIC_NUM_FEATURES; i++)
     map->add_feature (indic_features[i]);
-
-  map->add_gsub_pause (_hb_clear_syllables);
 }
 
 static void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -368,6 +368,7 @@
   else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */
   else if (unlikely (u == 0x09FCu)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/1613 */
   else if (unlikely (u == 0x0C80u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/623 */
+  else if (unlikely (u == 0x0D04u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/3511 */
   else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u)))
 				    cat = OT_PLACEHOLDER;
   else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -45,11 +45,11 @@
    * These features are applied all at once, before reordering, constrained
    * to the syllable.
    */
-  {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS},
-  {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS},
-  {HB_TAG('a','b','v','f'), F_MANUAL_JOINERS},
-  {HB_TAG('p','s','t','f'), F_MANUAL_JOINERS},
-  {HB_TAG('c','f','a','r'), F_MANUAL_JOINERS},
+  {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('a','b','v','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('p','s','t','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
+  {HB_TAG('c','f','a','r'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
   /*
    * Other features.
    * These features are applied all at once after clearing syllables.
@@ -107,17 +107,11 @@
    *
    * https://github.com/harfbuzz/harfbuzz/issues/974
    */
-  map->enable_feature (HB_TAG('l','o','c','l'));
-  map->enable_feature (HB_TAG('c','c','m','p'));
+  map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
+  map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
 
-  unsigned int i = 0;
-  for (; i < KHMER_BASIC_FEATURES; i++)
+  for (unsigned i = 0; i < KHMER_NUM_FEATURES; i++)
     map->add_feature (khmer_features[i]);
-
-  map->add_gsub_pause (_hb_clear_syllables);
-
-  for (; i < KHMER_NUM_FEATURES; i++)
-    map->add_feature (khmer_features[i]);
 }
 
 static void

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -79,10 +79,10 @@
   /* Do this before any lookups have been applied. */
   map->add_gsub_pause (setup_syllables_myanmar);
 
-  map->enable_feature (HB_TAG('l','o','c','l'));
+  map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
   /* The Indic specs do not require ccmp, but we apply it here since if
    * there is a use of it, it's typically at the beginning. */
-  map->enable_feature (HB_TAG('c','c','m','p'));
+  map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
 
 
   map->add_gsub_pause (reorder_myanmar);
@@ -89,12 +89,10 @@
 
   for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_basic_features); i++)
   {
-    map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ);
+    map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE);
     map->add_gsub_pause (nullptr);
   }
 
-  map->add_gsub_pause (_hb_clear_syllables);
-
   for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_other_features); i++)
     map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
 }

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -69,7 +69,7 @@
 #define use_syllable_machine_ex_GB 5u
 #define use_syllable_machine_ex_H 12u
 #define use_syllable_machine_ex_HN 13u
-#define use_syllable_machine_ex_HVM 44u
+#define use_syllable_machine_ex_IS 44u
 #define use_syllable_machine_ex_J 50u
 #define use_syllable_machine_ex_MAbv 27u
 #define use_syllable_machine_ex_MBlw 28u
@@ -92,41 +92,61 @@
 #define use_syllable_machine_ex_VMPst 39u
 #define use_syllable_machine_ex_VPre 22u
 #define use_syllable_machine_ex_VPst 35u
+#define use_syllable_machine_ex_WJ 16u
 #define use_syllable_machine_ex_ZWNJ 14u
 
 
-#line 99 "hb-ot-shape-complex-use-machine.hh"
+#line 100 "hb-ot-shape-complex-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-	0u, 51u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u, 
+	0u, 51u, 11u, 48u, 11u, 48u, 1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 
+	45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 
+	23u, 48u, 23u, 48u, 23u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 
+	1u, 1u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 48u, 23u, 48u, 
 	24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 
-	1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 
-	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
+	1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 12u, 48u, 12u, 48u, 
+	12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 13u, 13u, 4u, 4u, 11u, 48u, 11u, 48u, 
+	1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 
+	24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 
+	12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 11u, 48u, 11u, 48u, 
+	1u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 
+	24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 
+	12u, 48u, 12u, 48u, 12u, 48u, 12u, 48u, 11u, 48u, 1u, 1u, 4u, 4u, 13u, 13u, 
+	1u, 48u, 11u, 48u, 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 
+	0
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-	52, 2, 1, 38, 38, 1, 27, 26, 
+	52, 38, 38, 48, 26, 24, 23, 22, 
+	2, 1, 25, 25, 25, 1, 25, 27, 
+	26, 26, 26, 37, 37, 37, 37, 38, 
+	1, 38, 2, 1, 38, 38, 48, 26, 
 	24, 23, 22, 2, 1, 25, 25, 25, 
-	1, 25, 26, 26, 26, 27, 27, 27, 
-	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
+	1, 25, 27, 26, 26, 26, 37, 37, 
+	37, 37, 38, 1, 1, 1, 38, 38, 
+	48, 26, 24, 23, 22, 2, 1, 25, 
+	25, 25, 1, 25, 27, 26, 26, 26, 
+	37, 37, 37, 37, 38, 1, 38, 38, 
+	48, 26, 24, 23, 22, 2, 1, 25, 
+	25, 25, 1, 25, 27, 26, 26, 26, 
+	37, 37, 37, 37, 38, 1, 1, 1, 
+	48, 38, 2, 1, 5, 3, 4, 3
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-	0, 53, 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
+	0, 53, 92, 131, 180, 207, 232, 256, 
+	279, 282, 284, 310, 336, 362, 364, 390, 
+	418, 445, 472, 499, 537, 575, 613, 651, 
+	690, 692, 731, 734, 736, 775, 814, 863, 
+	890, 915, 939, 962, 965, 967, 993, 1019, 
+	1045, 1047, 1073, 1101, 1128, 1155, 1182, 1220, 
+	1258, 1296, 1334, 1373, 1375, 1377, 1379, 1418, 
+	1457, 1506, 1533, 1558, 1582, 1605, 1608, 1610, 
+	1636, 1662, 1688, 1690, 1716, 1744, 1771, 1798, 
+	1825, 1863, 1901, 1939, 1977, 2016, 2018, 2057, 
+	2096, 2145, 2172, 2197, 2221, 2244, 2247, 2249, 
+	2275, 2301, 2327, 2329, 2355, 2383, 2410, 2437, 
+	2464, 2502, 2540, 2578, 2616, 2655, 2657, 2659, 
+	2661, 2710, 2749, 2752, 2754, 2760, 2764, 2769
 };
 
 static const char _use_syllable_machine_indicies[] = {
@@ -133,181 +153,369 @@
 	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
+	11, 12, 13, 14, 15, 16, 17, 18, 
+	19, 20, 21, 22, 2, 23, 24, 25, 
+	2, 26, 27, 28, 29, 30, 31, 32, 
+	29, 33, 2, 34, 2, 36, 37, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	38, 39, 40, 41, 42, 43, 44, 45, 
+	46, 47, 48, 49, 50, 51, 35, 52, 
+	53, 54, 35, 55, 56, 35, 57, 58, 
+	59, 60, 57, 35, 36, 37, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 38, 
+	39, 40, 41, 42, 43, 44, 45, 46, 
+	48, 48, 49, 50, 51, 35, 52, 53, 
+	54, 35, 35, 35, 35, 57, 58, 59, 
+	60, 57, 35, 36, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 39, 40, 41, 42, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 52, 
+	53, 54, 35, 35, 35, 35, 35, 58, 
+	59, 60, 61, 35, 39, 40, 41, 42, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 52, 53, 54, 35, 35, 35, 
+	35, 35, 58, 59, 60, 61, 35, 40, 
+	41, 42, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 58, 59, 60, 35, 
+	41, 42, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 58, 59, 60, 35, 
+	42, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 58, 59, 60, 35, 58, 
+	59, 35, 59, 35, 40, 41, 42, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 52, 53, 54, 35, 35, 35, 35, 
+	35, 58, 59, 60, 61, 35, 40, 41, 
+	42, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 53, 54, 35, 35, 
+	35, 35, 35, 58, 59, 60, 61, 35, 
+	40, 41, 42, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 54, 
+	35, 35, 35, 35, 35, 58, 59, 60, 
+	61, 35, 62, 35, 40, 41, 42, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 58, 59, 60, 61, 35, 38, 39, 
+	40, 41, 42, 35, 35, 35, 35, 35, 
+	35, 49, 50, 51, 35, 52, 53, 54, 
+	35, 35, 35, 35, 35, 58, 59, 60, 
+	61, 35, 39, 40, 41, 42, 35, 35, 
+	35, 35, 35, 35, 49, 50, 51, 35, 
+	52, 53, 54, 35, 35, 35, 35, 35, 
+	58, 59, 60, 61, 35, 39, 40, 41, 
+	42, 35, 35, 35, 35, 35, 35, 35, 
+	50, 51, 35, 52, 53, 54, 35, 35, 
+	35, 35, 35, 58, 59, 60, 61, 35, 
+	39, 40, 41, 42, 35, 35, 35, 35, 
+	35, 35, 35, 35, 51, 35, 52, 53, 
+	54, 35, 35, 35, 35, 35, 58, 59, 
+	60, 61, 35, 39, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 38, 39, 40, 
+	41, 42, 35, 44, 45, 35, 35, 35, 
+	49, 50, 51, 35, 52, 53, 54, 35, 
+	35, 35, 35, 35, 58, 59, 60, 61, 
+	35, 39, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 38, 39, 40, 41, 42, 
+	35, 35, 45, 35, 35, 35, 49, 50, 
+	51, 35, 52, 53, 54, 35, 35, 35, 
+	35, 35, 58, 59, 60, 61, 35, 39, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 38, 39, 40, 41, 42, 35, 35, 
+	35, 35, 35, 35, 49, 50, 51, 35, 
+	52, 53, 54, 35, 35, 35, 35, 35, 
+	58, 59, 60, 61, 35, 39, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 38, 
+	39, 40, 41, 42, 43, 44, 45, 35, 
+	35, 35, 49, 50, 51, 35, 52, 53, 
+	54, 35, 35, 35, 35, 35, 58, 59, 
+	60, 61, 35, 36, 37, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 38, 39, 
+	40, 41, 42, 43, 44, 45, 46, 35, 
+	48, 49, 50, 51, 35, 52, 53, 54, 
+	35, 35, 35, 35, 57, 58, 59, 60, 
+	57, 35, 36, 35, 36, 37, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 38, 
+	39, 40, 41, 42, 43, 44, 45, 46, 
+	47, 48, 49, 50, 51, 35, 52, 53, 
+	54, 35, 35, 35, 35, 57, 58, 59, 
+	60, 57, 35, 55, 56, 35, 56, 35, 
+	64, 65, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 66, 67, 68, 69, 70, 
+	71, 72, 73, 74, 1, 75, 76, 77, 
+	78, 63, 79, 80, 81, 63, 63, 63, 
+	63, 82, 83, 84, 85, 86, 63, 64, 
+	65, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 66, 67, 68, 69, 70, 71, 
+	72, 73, 74, 75, 75, 76, 77, 78, 
+	63, 79, 80, 81, 63, 63, 63, 63, 
+	82, 83, 84, 85, 86, 63, 64, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 67, 68, 69, 70, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 79, 80, 81, 63, 63, 63, 
+	63, 63, 83, 84, 85, 87, 63, 67, 
+	68, 69, 70, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 79, 80, 81, 
+	63, 63, 63, 63, 63, 83, 84, 85, 
+	87, 63, 68, 69, 70, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 83, 
+	84, 85, 63, 69, 70, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 83, 
+	84, 85, 63, 70, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 83, 84, 
+	85, 63, 83, 84, 63, 84, 63, 68, 
+	69, 70, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 79, 80, 81, 63, 
+	63, 63, 63, 63, 83, 84, 85, 87, 
+	63, 68, 69, 70, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 80, 
+	81, 63, 63, 63, 63, 63, 83, 84, 
+	85, 87, 63, 68, 69, 70, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 81, 63, 63, 63, 63, 63, 
+	83, 84, 85, 87, 63, 89, 88, 68, 
+	69, 70, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 83, 84, 85, 87, 
+	63, 66, 67, 68, 69, 70, 63, 63, 
+	63, 63, 63, 63, 76, 77, 78, 63, 
+	79, 80, 81, 63, 63, 63, 63, 63, 
+	83, 84, 85, 87, 63, 67, 68, 69, 
+	70, 63, 63, 63, 63, 63, 63, 76, 
+	77, 78, 63, 79, 80, 81, 63, 63, 
+	63, 63, 63, 83, 84, 85, 87, 63, 
+	67, 68, 69, 70, 63, 63, 63, 63, 
+	63, 63, 63, 77, 78, 63, 79, 80, 
+	81, 63, 63, 63, 63, 63, 83, 84, 
+	85, 87, 63, 67, 68, 69, 70, 63, 
+	63, 63, 63, 63, 63, 63, 63, 78, 
+	63, 79, 80, 81, 63, 63, 63, 63, 
+	63, 83, 84, 85, 87, 63, 67, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	66, 67, 68, 69, 70, 63, 72, 73, 
+	63, 63, 63, 76, 77, 78, 63, 79, 
+	80, 81, 63, 63, 63, 63, 63, 83, 
+	84, 85, 87, 63, 67, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 66, 67, 
+	68, 69, 70, 63, 63, 73, 63, 63, 
+	63, 76, 77, 78, 63, 79, 80, 81, 
+	63, 63, 63, 63, 63, 83, 84, 85, 
+	87, 63, 67, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 66, 67, 68, 69, 
+	70, 63, 63, 63, 63, 63, 63, 76, 
+	77, 78, 63, 79, 80, 81, 63, 63, 
+	63, 63, 63, 83, 84, 85, 87, 63, 
+	67, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 66, 67, 68, 69, 70, 71, 
+	72, 73, 63, 63, 63, 76, 77, 78, 
+	63, 79, 80, 81, 63, 63, 63, 63, 
+	63, 83, 84, 85, 87, 63, 64, 65, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 66, 67, 68, 69, 70, 71, 72, 
+	73, 74, 63, 75, 76, 77, 78, 63, 
+	79, 80, 81, 63, 63, 63, 63, 82, 
+	83, 84, 85, 86, 63, 64, 90, 92, 
+	91, 3, 93, 94, 95, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 96, 97, 
+	98, 99, 100, 101, 102, 103, 104, 105, 
+	106, 107, 108, 109, 63, 110, 111, 112, 
+	63, 55, 56, 63, 113, 114, 115, 85, 
+	116, 63, 94, 95, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 96, 97, 98, 
+	99, 100, 101, 102, 103, 104, 106, 106, 
+	107, 108, 109, 63, 110, 111, 112, 63, 
+	63, 63, 63, 113, 114, 115, 85, 116, 
+	63, 94, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 97, 
+	98, 99, 100, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 110, 111, 112, 
+	63, 63, 63, 63, 63, 114, 115, 85, 
+	117, 63, 97, 98, 99, 100, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	110, 111, 112, 63, 63, 63, 63, 63, 
+	114, 115, 85, 117, 63, 98, 99, 100, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 114, 115, 85, 63, 99, 100, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 114, 115, 85, 63, 100, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 114, 115, 85, 63, 114, 115, 63, 
+	115, 63, 98, 99, 100, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 110, 
+	111, 112, 63, 63, 63, 63, 63, 114, 
+	115, 85, 117, 63, 98, 99, 100, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 111, 112, 63, 63, 63, 63, 
+	63, 114, 115, 85, 117, 63, 98, 99, 
+	100, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 112, 63, 63, 
+	63, 63, 63, 114, 115, 85, 117, 63, 
+	118, 88, 98, 99, 100, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 114, 
+	115, 85, 117, 63, 96, 97, 98, 99, 
+	100, 63, 63, 63, 63, 63, 63, 107, 
+	108, 109, 63, 110, 111, 112, 63, 63, 
+	63, 63, 63, 114, 115, 85, 117, 63, 
+	97, 98, 99, 100, 63, 63, 63, 63, 
+	63, 63, 107, 108, 109, 63, 110, 111, 
+	112, 63, 63, 63, 63, 63, 114, 115, 
+	85, 117, 63, 97, 98, 99, 100, 63, 
+	63, 63, 63, 63, 63, 63, 108, 109, 
+	63, 110, 111, 112, 63, 63, 63, 63, 
+	63, 114, 115, 85, 117, 63, 97, 98, 
+	99, 100, 63, 63, 63, 63, 63, 63, 
+	63, 63, 109, 63, 110, 111, 112, 63, 
+	63, 63, 63, 63, 114, 115, 85, 117, 
+	63, 97, 63, 63, 63, 63, 63, 63, 
+	63, 63, 63, 96, 97, 98, 99, 100, 
+	63, 102, 103, 63, 63, 63, 107, 108, 
+	109, 63, 110, 111, 112, 63, 63, 63, 
+	63, 63, 114, 115, 85, 117, 63, 97, 
+	63, 63, 63, 63, 63, 63, 63, 63, 
+	63, 96, 97, 98, 99, 100, 63, 63, 
+	103, 63, 63, 63, 107, 108, 109, 63, 
+	110, 111, 112, 63, 63, 63, 63, 63, 
+	114, 115, 85, 117, 63, 97, 63, 63, 
+	63, 63, 63, 63, 63, 63, 63, 96, 
+	97, 98, 99, 100, 63, 63, 63, 63, 
+	63, 63, 107, 108, 109, 63, 110, 111, 
+	112, 63, 63, 63, 63, 63, 114, 115, 
+	85, 117, 63, 97, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 96, 97, 98, 
+	99, 100, 101, 102, 103, 63, 63, 63, 
+	107, 108, 109, 63, 110, 111, 112, 63, 
+	63, 63, 63, 63, 114, 115, 85, 117, 
+	63, 94, 95, 63, 63, 63, 63, 63, 
+	63, 63, 63, 63, 96, 97, 98, 99, 
+	100, 101, 102, 103, 104, 63, 106, 107, 
+	108, 109, 63, 110, 111, 112, 63, 63, 
+	63, 63, 113, 114, 115, 85, 116, 63, 
+	94, 90, 94, 95, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 96, 97, 98, 
+	99, 100, 101, 102, 103, 104, 105, 106, 
+	107, 108, 109, 63, 110, 111, 112, 63, 
+	63, 63, 63, 113, 114, 115, 85, 116, 
+	63, 5, 6, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 9, 10, 11, 12, 
+	13, 14, 15, 16, 17, 19, 19, 20, 
+	21, 22, 119, 23, 24, 25, 119, 119, 
+	119, 119, 29, 30, 31, 32, 29, 119, 
+	5, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 10, 11, 
+	12, 13, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 23, 24, 25, 119, 
+	119, 119, 119, 119, 30, 31, 32, 120, 
+	119, 10, 11, 12, 13, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 23, 
+	24, 25, 119, 119, 119, 119, 119, 30, 
+	31, 32, 120, 119, 11, 12, 13, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 30, 31, 32, 119, 12, 13, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 30, 31, 32, 119, 13, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	30, 31, 32, 119, 30, 31, 119, 31, 
+	119, 11, 12, 13, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 23, 24, 
+	25, 119, 119, 119, 119, 119, 30, 31, 
+	32, 120, 119, 11, 12, 13, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 24, 25, 119, 119, 119, 119, 119, 
+	30, 31, 32, 120, 119, 11, 12, 13, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 25, 119, 119, 119, 
+	119, 119, 30, 31, 32, 120, 119, 121, 
+	119, 11, 12, 13, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 30, 31, 
+	32, 120, 119, 9, 10, 11, 12, 13, 
+	119, 119, 119, 119, 119, 119, 20, 21, 
+	22, 119, 23, 24, 25, 119, 119, 119, 
+	119, 119, 30, 31, 32, 120, 119, 10, 
+	11, 12, 13, 119, 119, 119, 119, 119, 
+	119, 20, 21, 22, 119, 23, 24, 25, 
+	119, 119, 119, 119, 119, 30, 31, 32, 
+	120, 119, 10, 11, 12, 13, 119, 119, 
+	119, 119, 119, 119, 119, 21, 22, 119, 
+	23, 24, 25, 119, 119, 119, 119, 119, 
+	30, 31, 32, 120, 119, 10, 11, 12, 
+	13, 119, 119, 119, 119, 119, 119, 119, 
+	119, 22, 119, 23, 24, 25, 119, 119, 
+	119, 119, 119, 30, 31, 32, 120, 119, 
+	10, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 9, 10, 11, 12, 13, 119, 
+	15, 16, 119, 119, 119, 20, 21, 22, 
+	119, 23, 24, 25, 119, 119, 119, 119, 
+	119, 30, 31, 32, 120, 119, 10, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	9, 10, 11, 12, 13, 119, 119, 16, 
+	119, 119, 119, 20, 21, 22, 119, 23, 
+	24, 25, 119, 119, 119, 119, 119, 30, 
+	31, 32, 120, 119, 10, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 9, 10, 
+	11, 12, 13, 119, 119, 119, 119, 119, 
+	119, 20, 21, 22, 119, 23, 24, 25, 
+	119, 119, 119, 119, 119, 30, 31, 32, 
+	120, 119, 10, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 9, 10, 11, 12, 
+	13, 14, 15, 16, 119, 119, 119, 20, 
+	21, 22, 119, 23, 24, 25, 119, 119, 
+	119, 119, 119, 30, 31, 32, 120, 119, 
+	5, 6, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 9, 10, 11, 12, 13, 
+	14, 15, 16, 17, 119, 19, 20, 21, 
+	22, 119, 23, 24, 25, 119, 119, 119, 
+	119, 29, 30, 31, 32, 29, 119, 5, 
+	119, 122, 119, 7, 119, 1, 119, 119, 
+	119, 1, 119, 119, 119, 119, 119, 5, 
+	6, 7, 119, 119, 119, 119, 119, 119, 
+	119, 119, 9, 10, 11, 12, 13, 14, 
+	15, 16, 17, 18, 19, 20, 21, 22, 
+	119, 23, 24, 25, 119, 26, 27, 119, 
+	29, 30, 31, 32, 29, 119, 5, 6, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 9, 10, 11, 12, 13, 14, 15, 
+	16, 17, 18, 19, 20, 21, 22, 119, 
+	23, 24, 25, 119, 119, 119, 119, 29, 
+	30, 31, 32, 29, 119, 26, 27, 119, 
+	27, 119, 1, 123, 123, 123, 1, 123, 
+	125, 124, 33, 124, 33, 125, 124, 125, 
+	124, 33, 124, 34, 124, 0
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
-	1, 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
+	1, 28, 0, 52, 54, 79, 80, 102, 
+	104, 92, 81, 82, 83, 84, 96, 97, 
+	98, 99, 105, 100, 93, 94, 95, 87, 
+	88, 89, 106, 107, 108, 101, 85, 86, 
+	0, 109, 111, 0, 2, 3, 15, 4, 
+	5, 6, 7, 19, 20, 21, 22, 25, 
+	23, 16, 17, 18, 10, 11, 12, 26, 
+	27, 24, 8, 9, 0, 13, 14, 0, 
+	29, 30, 42, 31, 32, 33, 34, 46, 
+	47, 48, 49, 50, 43, 44, 45, 37, 
+	38, 39, 51, 35, 36, 0, 51, 40, 
+	0, 41, 0, 0, 53, 0, 55, 56, 
+	68, 57, 58, 59, 60, 72, 73, 74, 
+	75, 78, 76, 69, 70, 71, 63, 64, 
+	65, 77, 61, 62, 77, 66, 67, 0, 
+	90, 91, 103, 0, 0, 110
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
@@ -314,12 +522,19 @@
 	0, 0, 3, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 4, 
-	0, 0, 5, 0, 6, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
+	4, 0, 0, 5, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 7, 8, 0, 9, 0, 10, 0, 
-	11, 12, 0, 0, 0, 13, 14, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 6, 0, 0, 7, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 8, 0, 0, 9, 10, 0, 
+	11, 0, 12, 13, 0, 14, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 8, 0, 0, 10, 0, 0, 15, 
+	0, 0, 0, 16, 17, 0
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
@@ -330,7 +545,13 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	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[] = {
@@ -341,18 +562,30 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0
 };
 
 static const short _use_syllable_machine_eof_trans[] = {
-	0, 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
+	0, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 36, 36, 36, 36, 
+	36, 36, 36, 36, 64, 64, 64, 64, 
+	64, 64, 64, 64, 64, 64, 64, 64, 
+	89, 64, 64, 64, 64, 64, 64, 64, 
+	64, 64, 64, 91, 92, 94, 64, 64, 
+	64, 64, 64, 64, 64, 64, 64, 64, 
+	64, 64, 89, 64, 64, 64, 64, 64, 
+	64, 64, 64, 64, 64, 91, 64, 120, 
+	120, 120, 120, 120, 120, 120, 120, 120, 
+	120, 120, 120, 120, 120, 120, 120, 120, 
+	120, 120, 120, 120, 120, 120, 120, 120, 
+	120, 120, 120, 120, 124, 125, 125, 125
 };
 
 static const int use_syllable_machine_start = 0;
@@ -366,7 +599,7 @@
 
 
 
-#line 179 "hb-ot-shape-complex-use-machine.rl"
+#line 181 "hb-ot-shape-complex-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
@@ -385,7 +618,9 @@
 			  typename Iter::item_t>
 {
   machine_index_t (const Iter& it) : it (it) {}
-  machine_index_t (const machine_index_t& o) : it (o.it) {}
+  machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
+								       typename Iter::item_t> (),
+					       it (o.it), is_null (o.is_null) {}
 
   static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
   static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
@@ -397,14 +632,28 @@
   void __forward__ (unsigned n) { it += n; }
   void __prev__ () { --it; }
   void __rewind__ (unsigned n) { it -= n; }
+
   void operator = (unsigned n)
-  { unsigned index = (*it).first; if (index < n) it += n - index; else if (index > n) it -= index - n; }
-  void operator = (const machine_index_t& o) { *this = (*o.it).first; }
-  bool operator == (const machine_index_t& o) const { return (*it).first == (*o.it).first; }
+  {
+    assert (n == 0);
+    is_null = true;
+  }
+  explicit operator bool () { return !is_null; }
+
+  void operator = (const machine_index_t& o)
+  {
+    is_null = o.is_null;
+    unsigned index = (*it).first;
+    unsigned n = (*o.it).first;
+    if (index < n) it += n - index; else if (index > n) it -= index - n;
+  }
+  bool operator == (const machine_index_t& o) const
+  { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; }
   bool operator != (const machine_index_t& o) const { return !(*this == o); }
 
   private:
   Iter it;
+  bool is_null = false;
 };
 struct
 {
@@ -420,7 +669,7 @@
 
 static bool
 not_ccs_default_ignorable (const hb_glyph_info_t &i)
-{ return !(i.use_category() == USE(CGJ) && _hb_glyph_info_is_default_ignorable (&i)); }
+{ return i.use_category() != USE(CGJ); }
 
 static inline void
 find_syllables_use (hb_buffer_t *buffer)
@@ -449,7 +698,7 @@
   unsigned int act HB_UNUSED;
   int cs;
   
-#line 453 "hb-ot-shape-complex-use-machine.hh"
+#line 702 "hb-ot-shape-complex-use-machine.hh"
 	{
 	cs = use_syllable_machine_start;
 	ts = 0;
@@ -457,12 +706,12 @@
 	act = 0;
 	}
 
-#line 263 "hb-ot-shape-complex-use-machine.rl"
+#line 281 "hb-ot-shape-complex-use-machine.rl"
 
 
   unsigned int syllable_serial = 1;
   
-#line 466 "hb-ot-shape-complex-use-machine.hh"
+#line 715 "hb-ot-shape-complex-use-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -476,7 +725,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 480 "hb-ot-shape-complex-use-machine.hh"
+#line 729 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -494,56 +743,80 @@
 		goto _again;
 
 	switch ( _use_syllable_machine_trans_actions[_trans] ) {
-	case 7:
-#line 169 "hb-ot-shape-complex-use-machine.rl"
+	case 9:
+#line 171 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (use_standard_cluster); }}
 	break;
+	case 6:
+#line 174 "hb-ot-shape-complex-use-machine.rl"
+	{te = p+1;{ found_syllable (use_symbol_cluster); }}
+	break;
 	case 4:
-#line 174 "hb-ot-shape-complex-use-machine.rl"
+#line 176 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (use_broken_cluster); }}
 	break;
 	case 3:
-#line 175 "hb-ot-shape-complex-use-machine.rl"
+#line 177 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (use_non_cluster); }}
 	break;
-	case 8:
-#line 167 "hb-ot-shape-complex-use-machine.rl"
-	{te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
-	break;
-	case 9:
-#line 168 "hb-ot-shape-complex-use-machine.rl"
+	case 11:
+#line 170 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
 	break;
-	case 6:
-#line 169 "hb-ot-shape-complex-use-machine.rl"
+	case 7:
+#line 171 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_standard_cluster); }}
 	break;
-	case 11:
-#line 170 "hb-ot-shape-complex-use-machine.rl"
+	case 14:
+#line 172 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
 	break;
-	case 10:
-#line 171 "hb-ot-shape-complex-use-machine.rl"
+	case 13:
+#line 173 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_numeral_cluster); }}
 	break;
 	case 5:
-#line 172 "hb-ot-shape-complex-use-machine.rl"
+#line 174 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_symbol_cluster); }}
 	break;
-	case 14:
-#line 173 "hb-ot-shape-complex-use-machine.rl"
+	case 17:
+#line 175 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
 	break;
-	case 12:
-#line 174 "hb-ot-shape-complex-use-machine.rl"
+	case 15:
+#line 176 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_broken_cluster); }}
 	break;
-	case 13:
-#line 175 "hb-ot-shape-complex-use-machine.rl"
+	case 16:
+#line 177 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_non_cluster); }}
 	break;
-#line 546 "hb-ot-shape-complex-use-machine.hh"
+	case 12:
+#line 1 "NONE"
+	{	switch( act ) {
+	case 1:
+	{{p = ((te))-1;} found_syllable (use_virama_terminated_cluster); }
+	break;
+	case 2:
+	{{p = ((te))-1;} found_syllable (use_sakot_terminated_cluster); }
+	break;
 	}
+	}
+	break;
+	case 8:
+#line 1 "NONE"
+	{te = p+1;}
+#line 169 "hb-ot-shape-complex-use-machine.rl"
+	{act = 1;}
+	break;
+	case 10:
+#line 1 "NONE"
+	{te = p+1;}
+#line 170 "hb-ot-shape-complex-use-machine.rl"
+	{act = 2;}
+	break;
+#line 819 "hb-ot-shape-complex-use-machine.hh"
+	}
 
 _again:
 	switch ( _use_syllable_machine_to_state_actions[cs] ) {
@@ -551,7 +824,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 555 "hb-ot-shape-complex-use-machine.hh"
+#line 828 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -567,7 +840,7 @@
 
 	}
 
-#line 268 "hb-ot-shape-complex-use-machine.rl"
+#line 286 "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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl	2022-04-03 22:28:02 UTC (rev 62894)
@@ -73,9 +73,10 @@
 
 export HN	= 13; # HALANT_NUM
 export ZWNJ	= 14; # Zero width non-joiner
+export WJ	= 16; # Word joiner
 export R	= 18; # REPHA
 export CS	= 43; # CONS_WITH_STACKER
-export HVM	= 44; # HALANT_OR_VOWEL_MODIFIER
+export IS	= 44; # INVISIBLE_STACKER
 export Sk	= 48; # SAKOT
 export G	= 49; # HIEROGLYPH
 export J	= 50; # HIEROGLYPH_JOINER
@@ -106,12 +107,12 @@
 export FMPst	= 47; # CONS_FINAL_MOD	UIPC = Not_Applicable
 
 
-h = H | HVM | Sk;
+h = H | IS | Sk;
 
 consonant_modifiers = CMAbv* CMBlw* ((h B | SUB) CMAbv? CMBlw*)*;
 medial_consonants = MPre? MAbv? MBlw? MPst?;
-dependent_vowels = VPre* VAbv* VBlw* VPst*;
-vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*;
+dependent_vowels = VPre* VAbv* VBlw* VPst* | H;
+vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*;
 final_consonants = FAbv* FBlw* FPst*;
 final_modifiers = FMAbv* FMBlw* | FMPst?;
 
@@ -134,7 +135,7 @@
 
 virama_terminated_cluster_tail =
 	consonant_modifiers
-	h
+	IS
 ;
 virama_terminated_cluster =
 	complex_syllable_start
@@ -152,14 +153,15 @@
 	complex_syllable_start
 	complex_syllable_tail
 ;
+tail = complex_syllable_tail | sakot_terminated_cluster_tail | symbol_cluster_tail | virama_terminated_cluster_tail;
 broken_cluster =
 	R?
-	(complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail | virama_terminated_cluster_tail | sakot_terminated_cluster_tail)
+	(tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail)
 ;
 
 number_joiner_terminated_cluster = N number_joiner_terminated_cluster_tail;
 numeral_cluster = N numeral_cluster_tail?;
-symbol_cluster = (O | GB) symbol_cluster_tail?;
+symbol_cluster = (O | GB) tail?;
 hieroglyph_cluster = SB+ | SB* G SE* (J SE* (G SE*)?)*;
 other = any;
 
@@ -194,7 +196,9 @@
 			  typename Iter::item_t>
 {
   machine_index_t (const Iter& it) : it (it) {}
-  machine_index_t (const machine_index_t& o) : it (o.it) {}
+  machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
+								       typename Iter::item_t> (),
+					       it (o.it), is_null (o.is_null) {}
 
   static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
   static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
@@ -206,14 +210,28 @@
   void __forward__ (unsigned n) { it += n; }
   void __prev__ () { --it; }
   void __rewind__ (unsigned n) { it -= n; }
+
   void operator = (unsigned n)
-  { unsigned index = (*it).first; if (index < n) it += n - index; else if (index > n) it -= index - n; }
-  void operator = (const machine_index_t& o) { *this = (*o.it).first; }
-  bool operator == (const machine_index_t& o) const { return (*it).first == (*o.it).first; }
+  {
+    assert (n == 0);
+    is_null = true;
+  }
+  explicit operator bool () { return !is_null; }
+
+  void operator = (const machine_index_t& o)
+  {
+    is_null = o.is_null;
+    unsigned index = (*it).first;
+    unsigned n = (*o.it).first;
+    if (index < n) it += n - index; else if (index > n) it -= index - n;
+  }
+  bool operator == (const machine_index_t& o) const
+  { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; }
   bool operator != (const machine_index_t& o) const { return !(*this == o); }
 
   private:
   Iter it;
+  bool is_null = false;
 };
 struct
 {
@@ -229,7 +247,7 @@
 
 static bool
 not_ccs_default_ignorable (const hb_glyph_info_t &i)
-{ return !(i.use_category() == USE(CGJ) && _hb_glyph_info_is_default_ignorable (&i)); }
+{ return i.use_category() != USE(CGJ); }
 
 static inline void
 find_syllables_use (hb_buffer_t *buffer)

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -53,7 +53,7 @@
 #define GB	USE(GB)	/* BASE_OTHER */
 #define H	USE(H)	/* HALANT */
 #define HN	USE(HN)	/* HALANT_NUM */
-#define HVM	USE(HVM)	/* HALANT_OR_VOWEL_MODIFIER */
+#define IS	USE(IS)	/* INVISIBLE_STACKER */
 #define J	USE(J)	/* HIEROGLYPH_JOINER */
 #define N	USE(N)	/* BASE_NUM */
 #define O	USE(O)	/* OTHER */
@@ -62,6 +62,7 @@
 #define SE	USE(SE)	/* HIEROGLYPH_SEGMENT_END */
 #define SUB	USE(SUB)	/* CONS_SUB */
 #define Sk	USE(Sk)	/* SAKOT */
+#define WJ	USE(WJ)	/* Word_Joiner */
 #define ZWNJ	USE(ZWNJ)	/* ZWNJ */
 #define CMAbv	USE(CMAbv)
 #define CMBlw	USE(CMBlw)
@@ -102,7 +103,7 @@
 
   /* Latin-1 Supplement */
 
-  /* 00A0 */    GB,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 00A0 */    GB,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,     O,     O,
   /* 00B0 */     O,     O, FMPst, FMPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 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,
@@ -127,7 +128,7 @@
                                                                          O,     O,     B,     B,     B,     B,     B,     B,
   /* 07D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
+  /* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,     B,    WJ,    WJ, VMAbv,     O,     O,
 
 #define use_offset_0x0840u 152
 
@@ -135,7 +136,7 @@
   /* Mandaic */
 
   /* 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,
+  /* 0850 */     B,     B,     B,     B,     B,     B,     B,     B,     B, CMBlw, CMBlw, CMBlw,    WJ,    WJ,     O,    WJ,
 
 #define use_offset_0x0900u 184
 
@@ -153,102 +154,102 @@
 
   /* Bengali */
 
-  /* 0980 */    GB, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
-  /* 0990 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 09A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
-  /* 09B0 */     B,     O,     B,     O,     O,     O,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPre,
-  /* 09C0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
-  /* 09D0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     B,     B,     O,     B,
-  /* 09E0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O, FMAbv,     O,
+  /* 0980 */    GB, VMAbv, VMPst, VMPst,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,     B,
+  /* 0990 */     B,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 09A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
+  /* 09B0 */     B,    WJ,     B,    WJ,    WJ,    WJ,     B,     B,     B,     B,    WJ,    WJ, CMBlw,     B,  VPst,  VPre,
+  /* 09C0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,    WJ,    WJ,  VPre,  VPre,    WJ,    WJ,  VPre,  VPre,     H,     O,    WJ,
+  /* 09D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,  VPst,    WJ,    WJ,    WJ,    WJ,     B,     B,    WJ,     B,
+  /* 09E0 */     B,     B,  VBlw,  VBlw,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O, FMAbv,    WJ,
 
   /* Gurmukhi */
 
-  /* 0A00 */     O, VMAbv, VMAbv, VMPst,     O,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     B,
-  /* 0A10 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
-  /* 0A30 */     B,     O,     B,     B,     O,     B,     B,     O,     B,     B,     O,     O, CMBlw,     O,  VPst,  VPre,
-  /* 0A40 */  VPst,  VBlw,  VBlw,     O,     O,     O,     O,  VAbv,  VAbv,     O,     O,  VAbv,  VAbv,     H,     O,     O,
-  /* 0A50 */     O, VMBlw,     O,     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     O,     B,     O,
-  /* 0A60 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0A70 */ VMAbv, CMAbv,    GB,    GB,     O,  MBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 0A00 */    WJ, VMAbv, VMAbv, VMPst,    WJ,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,     B,
+  /* 0A10 */     B,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
+  /* 0A30 */     B,    WJ,     B,     B,    WJ,     B,     B,    WJ,     B,     B,    WJ,    WJ, CMBlw,    WJ,  VPst,  VPre,
+  /* 0A40 */  VPst,  VBlw,  VBlw,    WJ,    WJ,    WJ,    WJ,  VAbv,  VAbv,    WJ,    WJ,  VAbv,  VAbv,     H,    WJ,    WJ,
+  /* 0A50 */    WJ, VMBlw,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     B,     B,     B,     B,    WJ,     B,    WJ,
+  /* 0A60 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0A70 */ VMAbv, CMAbv,    GB,    GB,     O,  MBlw,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Gujarati */
 
-  /* 0A80 */     O, VMAbv, VMAbv, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,
-  /* 0A90 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0AA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
-  /* 0AB0 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPre,
-  /* 0AC0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,     O,  VAbv,  VAbv,  VAbv,     O,  VPst,  VPst,     H,     O,     O,
-  /* 0AD0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 0AE0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0AF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     B, VMAbv, VMAbv, VMAbv, CMAbv, CMAbv, CMAbv,
+  /* 0A80 */    WJ, VMAbv, VMAbv, VMPst,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,
+  /* 0A90 */     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0AA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
+  /* 0AB0 */     B,    WJ,     B,     B,    WJ,     B,     B,     B,     B,     B,    WJ,    WJ, CMBlw,     B,  VPst,  VPre,
+  /* 0AC0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,    WJ,  VAbv,  VAbv,  VAbv,    WJ,  VPst,  VPst,     H,    WJ,    WJ,
+  /* 0AD0 */     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 0AE0 */     B,     B,  VBlw,  VBlw,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0AF0 */     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     B, VMAbv, VMAbv, VMAbv, CMAbv, CMAbv, CMAbv,
 
   /* Oriya */
 
-  /* 0B00 */     O, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
-  /* 0B10 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
-  /* 0B30 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VAbv,
-  /* 0B40 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
-  /* 0B50 */     O,     O,     O,     O,     O,  VAbv,  VAbv,  VAbv,     O,     O,     O,     O,     B,     B,     O,     B,
-  /* 0B60 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0B70 */     O,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 0B00 */    WJ, VMAbv, VMPst, VMPst,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,     B,
+  /* 0B10 */     B,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
+  /* 0B30 */     B,    WJ,     B,     B,    WJ,     B,     B,     B,     B,     B,    WJ,    WJ, CMBlw,     B,  VPst,  VAbv,
+  /* 0B40 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,    WJ,    WJ,  VPre,  VPre,    WJ,    WJ,  VPre,  VPre,     H,    WJ,    WJ,
+  /* 0B50 */    WJ,    WJ,    WJ,    WJ,    WJ,  VAbv,  VAbv,  VAbv,    WJ,    WJ,    WJ,    WJ,     B,     B,    WJ,     B,
+  /* 0B60 */     B,     B,  VBlw,  VBlw,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0B70 */     O,     B,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Tamil */
 
-  /* 0B80 */     O,     O, VMAbv,     O,     O,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,     B,
-  /* 0B90 */     B,     O,     B,     B,     B,     B,     O,     O,     O,     B,     B,     O,     B,     O,     B,     B,
-  /* 0BA0 */     O,     O,     O,     B,     B,     O,     O,     O,     B,     B,     B,     O,     O,     O,     B,     B,
-  /* 0BB0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,  VPst,  VPst,
-  /* 0BC0 */  VAbv,  VPst,  VPst,     O,     O,     O,  VPre,  VPre,  VPre,     O,  VPre,  VPre,  VPre,     H,     O,     O,
-  /* 0BD0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 0BE0 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0BF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 0B80 */    WJ,    WJ, VMAbv,     O,    WJ,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,     B,     B,
+  /* 0B90 */     B,    WJ,     B,     B,     B,     B,    WJ,    WJ,    WJ,     B,     B,    WJ,     B,    WJ,     B,     B,
+  /* 0BA0 */    WJ,    WJ,    WJ,     B,     B,    WJ,    WJ,    WJ,     B,     B,     B,    WJ,    WJ,    WJ,     B,     B,
+  /* 0BB0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,  VPst,  VPst,
+  /* 0BC0 */  VAbv,  VPst,  VPst,    WJ,    WJ,    WJ,  VPre,  VPre,  VPre,    WJ,  VPre,  VPre,  VPre,     H,    WJ,    WJ,
+  /* 0BD0 */     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,  VPst,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 0BE0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0BF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Telugu */
 
-  /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, VMAbv,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
-  /* 0C10 */     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0C20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
-  /* 0C30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VAbv,  VAbv,
-  /* 0C40 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,  VAbv,  VAbv,  VAbv,     O,  VAbv,  VAbv,  VAbv,     H,     O,     O,
-  /* 0C50 */     O,     O,     O,     O,     O,  VAbv,  VBlw,     O,     B,     B,     B,     O,     O,     O,     O,     O,
-  /* 0C60 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0C70 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, VMAbv,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,
+  /* 0C10 */     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0C20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
+  /* 0C30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ, CMBlw,     B,  VAbv,  VAbv,
+  /* 0C40 */  VAbv,  VPst,  VPst,  VPst,  VPst,    WJ,  VAbv,  VAbv,  VAbv,    WJ,  VAbv,  VAbv,  VAbv,     H,    WJ,    WJ,
+  /* 0C50 */    WJ,    WJ,    WJ,    WJ,    WJ,  VAbv,  VBlw,    WJ,     B,     B,     B,    WJ,    WJ,     O,    WJ,    WJ,
+  /* 0C60 */     B,     B,  VBlw,  VBlw,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0C70 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Kannada */
 
-  /* 0C80 */     B, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
-  /* 0C90 */     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0CA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
-  /* 0CB0 */     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VAbv,
-  /* 0CC0 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,  VAbv,  VAbv,  VAbv,     O,  VAbv,  VAbv,  VAbv,     H,     O,     O,
-  /* 0CD0 */     O,     O,     O,     O,     O,  VPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     B,     O,
-  /* 0CE0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0CF0 */     O,    CS,    CS,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 0C80 */     B, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,
+  /* 0C90 */     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0CA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
+  /* 0CB0 */     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,    WJ,    WJ, CMBlw,     B,  VPst,  VAbv,
+  /* 0CC0 */  VAbv,  VPst,  VPst,  VPst,  VPst,    WJ,  VAbv,  VAbv,  VAbv,    WJ,  VAbv,  VAbv,  VAbv,     H,    WJ,    WJ,
+  /* 0CD0 */    WJ,    WJ,    WJ,    WJ,    WJ,  VPst,  VPst,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     B,    WJ,
+  /* 0CE0 */     B,     B,  VBlw,  VBlw,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0CF0 */    WJ,    CS,    CS,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Malayalam */
 
-  /* 0D00 */ VMAbv, VMAbv, VMPst, VMPst,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
-  /* 0D10 */     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0D00 */ VMAbv, VMAbv, VMPst, VMPst,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,
+  /* 0D10 */     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0D20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0D30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,     B,  VPst,  VPst,
-  /* 0D40 */  VPst,  VPst,  VPst,  VBlw,  VBlw,     O,  VPre,  VPre,  VPre,     O,  VPre,  VPre,  VPre,     H,     R,     O,
-  /* 0D50 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     O,     B,
-  /* 0D60 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0D40 */  VPst,  VPst,  VPst,  VBlw,  VBlw,    WJ,  VPre,  VPre,  VPre,    WJ,  VPre,  VPre,  VPre,     H,     R,     O,
+  /* 0D50 */    WJ,    WJ,    WJ,    WJ,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     O,     B,
+  /* 0D60 */     B,     B,  VBlw,  VBlw,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0D70 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Sinhala */
 
-  /* 0D80 */     O, VMAbv, VMPst, VMPst,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0D90 */     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,     B,     B,     B,     B,     B,
+  /* 0D80 */    WJ, VMAbv, VMPst, VMPst,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0D90 */     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,     B,     B,     B,     B,     B,     B,
   /* 0DA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0DB0 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     O,     O,
-  /* 0DC0 */     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     H,     O,     O,     O,     O,  VPst,
-  /* 0DD0 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,     O,  VBlw,     O,  VPst,  VPre,  VPre,  VPre,  VPre,  VPre,  VPre,  VPst,
-  /* 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,
+  /* 0DB0 */     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,    WJ,    WJ,
+  /* 0DC0 */     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,     H,    WJ,    WJ,    WJ,    WJ,  VPst,
+  /* 0DD0 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,    WJ,  VBlw,    WJ,  VPst,  VPre,  VPre,  VPre,  VPre,  VPre,  VPre,  VPst,
+  /* 0DE0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0DF0 */    WJ,    WJ,  VPst,  VPst,     O,    WJ,    WJ,    WJ,
 
 #define use_offset_0x0f00u 1456
 
@@ -259,14 +260,14 @@
   /* 0F10 */     O,     O,     O,     O,     O,     O,     O,     O,  VBlw,  VBlw,     O,     O,     O,     O,     O,     O,
   /* 0F20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0F30 */     B,     B,     B,     B,     O,  FBlw,     O,  FBlw,     O, CMAbv,     O,     O,     O,     O,  VPst,  VPre,
-  /* 0F40 */     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,
+  /* 0F40 */     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,
   /* 0F50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0F60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,
-  /* 0F70 */     O, CMBlw,  VBlw,  VAbv,  VAbv,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw, VMAbv,     O,
+  /* 0F60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,
+  /* 0F70 */    WJ, CMBlw,  VBlw,  VAbv,  VAbv,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw, VMAbv,     O,
   /* 0F80 */  VBlw,  VAbv, VMAbv, VMAbv,  VBlw,     O, VMAbv, VMAbv,     B,     B,     B,     B,     B,   SUB,   SUB,   SUB,
-  /* 0F90 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
+  /* 0F90 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,    WJ,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 0FA0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
-  /* 0FB0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,     O,     O,
+  /* 0FB0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,    WJ,     O,     O,
   /* 0FC0 */     O,     O,     O,     O,     O,     O,  FBlw,     O,
 
 #define use_offset_0x1000u 1656
@@ -277,7 +278,7 @@
   /* 1000 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1010 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1020 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VAbv,  VAbv,  VBlw,
-  /* 1030 */  VBlw,  VPre,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMBlw, VMPst,     H,  VAbv,  MPst,  MPre,  MBlw,  MBlw,     B,
+  /* 1030 */  VBlw,  VPre,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMBlw, VMPst,    IS,  VAbv,  MPst,  MPre,  MBlw,  MBlw,     B,
   /* 1040 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,    GB,     O,     O,    GB,     O,
   /* 1050 */     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VBlw,  VBlw,     B,     B,     B,     B,  MBlw,  MBlw,
   /* 1060 */  MBlw,     B,  VPst, VMPst, VMPst,     B,     B,  VPst,  VPst, VMPst, VMPst, VMPst, VMPst, VMPst,     B,     B,
@@ -291,22 +292,22 @@
   /* Tagalog */
 
   /* 1700 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1710 */     B,     B,  VAbv,  VBlw,  VBlw,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,
+  /* 1710 */     B,     B,  VAbv,  VBlw,  VBlw,  VPst,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     B,
 
   /* Hanunoo */
 
   /* 1720 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1730 */     B,     B,  VAbv,  VBlw,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 1730 */     B,     B,  VAbv,  VBlw,  VPst,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Buhid */
 
   /* 1740 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1750 */     B,     B,  VAbv,  VBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 1750 */     B,     B,  VAbv,  VBlw,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Tagbanwa */
 
-  /* 1760 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
-  /* 1770 */     B,     O,  VAbv,  VBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 1760 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,
+  /* 1770 */     B,    WJ,  VAbv,  VBlw,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Khmer */
 
@@ -315,23 +316,23 @@
   /* 17A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
-  /* 17F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 17D0 */ FMAbv,  VAbv,    IS, FMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     B, FMAbv,    WJ,    WJ,
+  /* 17E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 17F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Mongolian */
 
-  /* 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,
+  /* 1800 */     B,     O,     O,     O,     O,     O,     O,     B,     O,     O,     B,   CGJ,   CGJ,   CGJ,    WJ,   CGJ,
+  /* 1810 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
   /* 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,
   /* 1840 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1850 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1860 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1870 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,
+  /* 1870 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
   /* 1880 */    GB,    GB,    GB,    GB,    GB, CMAbv, CMAbv,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
+  /* 18A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B, CMBlw,     B,    WJ,    WJ,    WJ,    WJ,    WJ,
 
 #define use_offset_0x1900u 2248
 
@@ -339,25 +340,25 @@
   /* Limbu */
 
   /* 1900 */    GB,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1910 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,
-  /* 1920 */  VAbv,  VAbv,  VBlw,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,   SUB,   SUB,   SUB,     O,     O,     O,     O,
-  /* 1930 */  FPst,  FPst, VMBlw,  FPst,  FPst,  FPst,  FPst,  FPst,  FPst,  FBlw, VMAbv, FMBlw,     O,     O,     O,     O,
-  /* 1940 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1910 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,
+  /* 1920 */  VAbv,  VAbv,  VBlw,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,   SUB,   SUB,   SUB,    WJ,    WJ,    WJ,    WJ,
+  /* 1930 */  FPst,  FPst, VMBlw,  FPst,  FPst,  FPst,  FPst,  FPst,  FPst,  FBlw, VMAbv, FMBlw,    WJ,    WJ,    WJ,    WJ,
+  /* 1940 */     O,    WJ,    WJ,    WJ,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
 
   /* Tai Le */
 
   /* 1950 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1960 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,
-  /* 1970 */     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 1960 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,
+  /* 1970 */     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* New Tai Lue */
 
   /* 1980 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1990 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 19A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
+  /* 19A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,
   /* 19B0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 19C0 */     B,     B,     B,     B,     B,     B,     B,     B, VMPst, VMPst,     O,     O,     O,     O,     O,     O,
-  /* 19D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,
+  /* 19C0 */     B,     B,     B,     B,     B,     B,     B,     B, VMPst, VMPst,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 19D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,     O,     O,
   /* 19E0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 19F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
@@ -364,7 +365,7 @@
   /* Buginese */
 
   /* 1A00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1A10 */     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VPre,  VPst,  VAbv,     O,     O,     O,     O,
+  /* 1A10 */     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VPre,  VPst,  VAbv,    WJ,    WJ,     O,     O,
 
   /* Tai Tham */
 
@@ -371,11 +372,11 @@
   /* 1A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1A50 */     B,     B,     B,     B,     B,  MPre,  MBlw,   SUB,  FAbv,  FAbv,  MAbv,   SUB,   SUB,   SUB,   SUB,     O,
+  /* 1A50 */     B,     B,     B,     B,     B,  MPre,  MBlw,   SUB,  FAbv,  FAbv,  MAbv,   SUB,   SUB,   SUB,   SUB,    WJ,
   /* 1A60 */    Sk,  VPst,  VAbv,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VAbv,  VBlw,  VPst,  VPre,  VPre,
-  /* 1A70 */  VPre,  VPre,  VPre,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,  VAbv, VMAbv, VMAbv,     O,     O, VMBlw,
-  /* 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,
+  /* 1A70 */  VPre,  VPre,  VPre,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,  VAbv, VMAbv, VMAbv,    WJ,    WJ, VMBlw,
+  /* 1A80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 1A90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
 #define use_offset_0x1b00u 2664
 
@@ -386,16 +387,16 @@
   /* 1B10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,     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,
+  /* 1B40 */  VPre,  VPre,  VAbv,  VAbv,     H,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,
+  /* 1B50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 1B60 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
+  /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,
 
   /* Sundanese */
 
   /* 1B80 */ VMAbv,  FAbv, VMPst,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1B90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1BA0 */     B,   SUB,   SUB,   SUB,  VAbv,  VBlw,  VPre,  VPst,  VAbv,  VAbv,  VPst,     H,   SUB,   SUB,     B,     B,
+  /* 1BA0 */     B,   SUB,   SUB,   SUB,  VAbv,  VBlw,  VPre,  VPst,  VAbv,  VAbv,  VPst,    IS,   SUB,   SUB,     B,     B,
   /* 1BB0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
 
   /* Batak */
@@ -403,7 +404,7 @@
   /* 1BC0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1BD0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1BE0 */     B,     B,     B,     B,     B,     B, CMAbv,  VPst,  VAbv,  VAbv,  VPst,  VPst,  VPst,  VAbv,  VPst,  VAbv,
-  /* 1BF0 */  FAbv,  FAbv, CMBlw, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 1BF0 */  FAbv,  FAbv, CMBlw, CMBlw,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     O,     O,     O,
 
   /* Lepcha */
 
@@ -410,8 +411,8 @@
   /* 1C00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1C10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1C20 */     B,     B,     B,     B,   SUB,   SUB,  VPst,  VPre,  VPre,  VPre,  VPst,  VPst,  VBlw,  FAbv,  FAbv,  FAbv,
-  /* 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,
+  /* 1C30 */  FAbv,  FAbv,  FAbv,  FAbv, VMPre, VMPre, FMAbv, CMBlw,    WJ,    WJ,    WJ,     O,     O,     O,     O,     O,
+  /* 1C40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,     B,     B,     B,
 
 #define use_offset_0x1cd0u 3000
 
@@ -420,7 +421,7 @@
 
   /* 1CD0 */ VMAbv, VMAbv, VMAbv,     O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
   /* 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,
+  /* 1CF0 */     O,     O,     O,     O, VMAbv,    CS,    CS, VMPst, VMAbv, VMAbv,    GB,    WJ,    WJ,    WJ,    WJ,    WJ,
 
 #define use_offset_0x1df8u 3048
 
@@ -432,31 +433,33 @@
 
 
   /* General Punctuation */
-                                                                         O,     O,     O,     O,  ZWNJ,   CGJ,     O,     O,
-  /* 2010 */    GB,    GB,    GB,    GB,    GB,     O,     O,     O,
+                                                                         O,     O,     O,    WJ,  ZWNJ,   CGJ,    WJ,    WJ,
+  /* 2010 */    GB,    GB,    GB,    GB,    GB,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 2020 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,     O,
+  /* 2030 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 2040 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 2050 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 2060 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x2070u 3072
-
-
   /* Superscripts and Subscripts */
 
-  /* 2070 */     O,     O,     O,     O, FMPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 2070 */     O,     O,    WJ,    WJ, 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 3096
+#define use_offset_0x20f0u 3184
 
 
   /* Combining Diacritical Marks for Symbols */
 
-  /* 20F0 */ VMAbv,     O,     O,     O,     O,     O,     O,     O,
+  /* 20F0 */ VMAbv,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x25c8u 3104
+#define use_offset_0x25c8u 3192
 
 
   /* Geometric Shapes */
                                                                          O,     O,     O,     O,     B,     O,     O,     O,
 
-#define use_offset_0x2d30u 3112
+#define use_offset_0x2d30u 3200
 
 
   /* Tifinagh */
@@ -464,10 +467,10 @@
   /* 2D30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 2D40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 2D50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 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,
+  /* 2D60 */     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     B,
+  /* 2D70 */     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     H,
 
-#define use_offset_0xa800u 3192
+#define use_offset_0xa800u 3280
 
 
   /* Syloti Nagri */
@@ -474,8 +477,8 @@
 
   /* A800 */     B,     B,  VAbv,     B,     B,     B,     H,     B,     B,     B,     B, VMAbv,     B,     B,     B,     B,
   /* A810 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* A820 */     B,     B,     B,  VPst,  VPst,  VBlw,  VAbv,  VPst,     O,     O,     O,     O,  VBlw,     O,     O,     O,
-  /* A830 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A820 */     B,     B,     B,  VPst,  VPst,  VBlw,  VAbv,  VPst,     O,     O,     O,     O,  VBlw,    WJ,    WJ,    WJ,
+  /* A830 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Phags-pa */
 
@@ -482,7 +485,7 @@
   /* A840 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A850 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A860 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* A870 */     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A870 */     B,     B,     B,     B,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Saurashtra */
 
@@ -490,8 +493,8 @@
   /* A890 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A8A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A8B0 */     B,     B,     B,     B,  MPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,
-  /* A8C0 */  VPst,  VPst,  VPst,  VPst,     H, VMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* A8D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* A8C0 */  VPst,  VPst,  VPst,  VPst,     H, VMAbv,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     O,
+  /* A8D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Devanagari Extended */
 
@@ -508,9 +511,9 @@
 
   /* A930 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A940 */     B,     B,     B,     B,     B,     B,     B,  VBlw,  VBlw,  VBlw,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  FAbv,
-  /* A950 */  FAbv,  FAbv,  FPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A950 */  FAbv,  FAbv,  FPst,  VPst,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,
   /* A960 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* A970 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A970 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,
 
   /* Javanese */
 
@@ -518,13 +521,13 @@
   /* A990 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A9A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* A9B0 */     B,     B,     B, CMAbv,  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VPre,  VAbv,  MBlw,  MPst,  MBlw,
-  /* A9C0 */     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* A9D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* A9C0 */     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,     O,
+  /* A9D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,     O,     O,
 
   /* Myanmar Extended-B */
 
   /* A9E0 */     B,     B,     B,     B,     B,  VAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* A9F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,
+  /* A9F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,
 
   /* Cham */
 
@@ -531,9 +534,9 @@
   /* AA00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* AA10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* AA20 */     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VAbv,  VPre,
-  /* AA30 */  VPre,  VAbv,  VBlw,  MPst,  MPre,  MAbv,  MBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* AA40 */     B,     B,     B,  FAbv,     B,     B,     B,     B,     B,     B,     B,     B,  FAbv,  FPst,     O,     O,
-  /* AA50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* AA30 */  VPre,  VAbv,  VBlw,  MPst,  MPre,  MAbv,  MBlw,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* AA40 */     B,     B,     B,  FAbv,     B,     B,     B,     B,     B,     B,     B,     B,  FAbv,  FPst,    WJ,    WJ,
+  /* AA50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,     O,     O,     O,     O,
 
   /* Myanmar Extended-A */
 
@@ -546,15 +549,15 @@
   /* AA90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* AAA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* AAB0 */  VAbv,     B,  VAbv,  VAbv,  VBlw,     B,     B,  VAbv,  VAbv,     B,     B,     B,     B,     B,  VAbv, VMAbv,
-  /* AAC0 */     B, VMAbv,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* AAD0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* AAC0 */     B, VMAbv,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* AAD0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     O,     O,     O,     O,
 
   /* Meetei Mayek Extensions */
 
   /* 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,
+  /* AAF0 */     O,     O,     O,     O,     O, VMPst,    IS,    WJ,
 
-#define use_offset_0xabc0u 3952
+#define use_offset_0xabc0u 4040
 
 
   /* Meetei Mayek */
@@ -561,10 +564,10 @@
 
   /* ABC0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* ABD0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 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,
+  /* ABE0 */     B,     B,     B,  VPst,  VPst,  VAbv,  VPst,  VPst,  VBlw,  VPst,  VPst,     O, VMPst,  VBlw,    WJ,    WJ,
+  /* ABF0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0xfe00u 4016
+#define use_offset_0xfe00u 4104
 
 
   /* Variation Selectors */
@@ -571,29 +574,42 @@
 
   /* FE00 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
 
-#define use_offset_0x10570u 4032
+#define use_offset_0xfef8u 4120
 
 
+  /* Arabic Presentation Forms-B */
+                                                                         O,     O,     O,     O,     O,    WJ,    WJ,    WJ,
+
+#define use_offset_0xfff0u 4128
+
+
+  /* Specials */
+
+  /* FFF0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     O,     O,     O,     O,    WJ,    WJ,
+
+#define use_offset_0x10570u 4144
+
+
   /* 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,
+  /* 10570 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,
+  /* 10580 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,
+  /* 10590 */     B,     B,     B,    WJ,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 105A0 */     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 105B0 */     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,    WJ,    WJ,    WJ,
 
-#define use_offset_0x10a00u 4112
+#define use_offset_0x10a00u 4224
 
 
   /* Kharoshthi */
 
-  /* 10A00 */     B,  VBlw,  VBlw,  VBlw,     O,  VAbv,  VBlw,     O,     O,     O,     O,     O,  VPst, VMBlw, VMBlw, VMAbv,
-  /* 10A10 */     B,     B,     B,     B,     O,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,
+  /* 10A00 */     B,  VBlw,  VBlw,  VBlw,    WJ,  VAbv,  VBlw,    WJ,    WJ,    WJ,    WJ,    WJ,  VPst, VMBlw, VMBlw, VMAbv,
+  /* 10A10 */     B,     B,     B,     B,    WJ,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,
   /* 10A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 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,
+  /* 10A30 */     B,     B,     B,     B,     B,     B,    WJ,    WJ, CMAbv, CMBlw, CMBlw,    WJ,    WJ,    WJ,    WJ,    IS,
+  /* 10A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x10ac0u 4192
+#define use_offset_0x10ac0u 4304
 
 
   /* Manichaean */
@@ -600,18 +616,18 @@
 
   /* 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,     O,     O,     O,     B,     B,     B,     B,     B,
+  /* 10AE0 */     B,     B,     B,     B,     B, CMBlw, CMBlw,    WJ,    WJ,    WJ,    WJ,     B,     B,     B,     B,     B,
 
-#define use_offset_0x10b80u 4240
+#define use_offset_0x10b80u 4352
 
 
   /* Psalter Pahlavi */
 
   /* 10B80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 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,
+  /* 10B90 */     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     O,     O,     O,    WJ,    WJ,    WJ,
+  /* 10BA0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     O,
 
-#define use_offset_0x10d00u 4288
+#define use_offset_0x10d00u 4400
 
 
   /* Hanifi Rohingya */
@@ -618,10 +634,10 @@
 
   /* 10D00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 10D10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 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,
+  /* 10D20 */     B,     B,     B,     B, VMAbv, VMAbv, VMAbv, CMAbv,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 10D30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x10e80u 4352
+#define use_offset_0x10e80u 4464
 
 
   /* Yezidi */
@@ -628,10 +644,10 @@
 
   /* 10E80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 10E90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 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,
+  /* 10EA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,  VAbv,  VAbv,     O,    WJ,    WJ,
+  /* 10EB0 */     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x10f30u 4408
+#define use_offset_0x10f30u 4520
 
 
   /* Sogdian */
@@ -638,23 +654,23 @@
 
   /* 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,     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,
+  /* 10F50 */ VMBlw,     B,     B,     B,     B,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 10F60 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* 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,
+  /* 10F80 */     B,     B, CMBlw, CMBlw, CMBlw, CMBlw,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 10F90 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 10FA0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Chorasmian */
 
   /* 10FB0 */     B,     O,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 10FC0 */     O,     B,     B,     B,     B,     O,     O,     O,     O,     B,     B,     B,     O,     O,     O,     O,
-  /* 10FD0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 10FC0 */     O,     B,     B,     B,     B,     O,     O,     O,     O,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,
+  /* 10FD0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
   /* 10FE0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 10FF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 10FF0 */     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Brahmi */
 
@@ -662,10 +678,10 @@
   /* 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,     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,
+  /* 11040 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,     H,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,
+  /* 11050 */    WJ,    WJ,     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,
+  /* 11070 */  VAbv,     B,     B,  VAbv,  VAbv,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    HN,
 
   /* Kaithi */
 
@@ -673,9 +689,9 @@
   /* 11090 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 110A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
+  /* 110C0 */     O,     O,  VBlw,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x11100u 4816
+#define use_offset_0x11100u 4928
 
 
   /* Chakma */
@@ -683,14 +699,14 @@
   /* 11100 */ VMAbv, VMAbv, VMAbv,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11110 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11120 */     B,     B,     B,     B,     B,     B,     B,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPre,  VBlw,  VAbv,  VAbv,
-  /* 11130 */  VBlw,  VAbv,  VAbv,     H, CMAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11140 */     O,     O,     O,     O,     B,  VPst,  VPst,     B,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11130 */  VBlw,  VAbv,  VAbv,    IS, CMAbv,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11140 */     O,     O,     O,     O,     B,  VPst,  VPst,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Mahajani */
 
   /* 11150 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11160 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11170 */     B,     B,     B, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11170 */     B,     B,     B, CMBlw,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Sharada */
 
@@ -698,29 +714,29 @@
   /* 11190 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111B0 */     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,
-  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,    GB, FMBlw, CMBlw,  VAbv,  VBlw,     O,  VPre, VMAbv,
+  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,     O, FMBlw, CMBlw,  VAbv,  VBlw,     O,  VPre, VMAbv,
   /* 111D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,
 
   /* Sinhala Archaic Numbers */
 
-  /* 111E0 */     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 111F0 */     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 111E0 */    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 111F0 */     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Khojki */
 
   /* 11200 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11210 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11210 */     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
+  /* 11230 */  VAbv,  VAbv,  VAbv,  VAbv, VMAbv,     H, CMAbv, CMAbv,     O,     O,     O,     O,     O,     O, VMAbv,    WJ,
 
-#define use_offset_0x11280u 5136
+#define use_offset_0x11280u 5248
 
 
   /* Multani */
 
-  /* 11280 */     B,     B,     B,     B,     B,     B,     B,     O,     B,     O,     B,     B,     B,     B,     O,     B,
-  /* 11290 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,
-  /* 112A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,
+  /* 11280 */     B,     B,     B,     B,     B,     B,     B,    WJ,     B,    WJ,     B,     B,     B,     B,    WJ,     B,
+  /* 11290 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,
+  /* 112A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Khudawadi */
 
@@ -727,21 +743,21 @@
   /* 112B0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 112C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 112D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv,
-  /* 112E0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv, CMBlw,  VBlw,     O,     O,     O,     O,     O,
-  /* 112F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 112E0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv, CMBlw,  VBlw,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 112F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Grantha */
 
-  /* 11300 */ VMAbv, VMAbv, VMAbv, VMAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,
-  /* 11310 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11320 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
-  /* 11330 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O, CMBlw, CMBlw,     B,  VPst,  VPst,
-  /* 11340 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,   HVM,     O,     O,
-  /* 11350 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     B,     B,
-  /* 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,
+  /* 11300 */ VMAbv, VMAbv, VMAbv, VMAbv,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,     B,
+  /* 11310 */     B,    WJ,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11320 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
+  /* 11330 */     B,    WJ,     B,     B,    WJ,     B,     B,     B,     B,     B,    WJ, CMBlw, CMBlw,     B,  VPst,  VPst,
+  /* 11340 */  VAbv,  VPst,  VPst,  VPst,  VPst,    WJ,    WJ,  VPre,  VPre,    WJ,    WJ,  VPre,  VPre,     H,    WJ,    WJ,
+  /* 11350 */     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,  VPst,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     B,     B,
+  /* 11360 */     B,     B,  VPst,  VPst,    WJ,    WJ, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,    WJ,    WJ,    WJ,
+  /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,    WJ,    WJ,    WJ,
 
-#define use_offset_0x11400u 5384
+#define use_offset_0x11400u 5496
 
 
   /* Newa */
@@ -751,9 +767,9 @@
   /* 11420 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11430 */     B,     B,     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,
   /* 11440 */  VPst,  VPst,     H, VMAbv, VMAbv, VMPst, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 11450 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O, FMAbv,     B,
-  /* 11460 */    CS,    CS,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 11470 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11450 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,    WJ,     O, FMAbv,     B,
+  /* 11460 */    CS,    CS,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 11470 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Tirhuta */
 
@@ -761,10 +777,10 @@
   /* 11490 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 114A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 114B0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VPre,  VAbv,  VPre,  VPre,  VPst,  VPre, VMAbv,
-  /* 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,
+  /* 114C0 */ VMAbv, VMAbv,     H, CMBlw,     B,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 114D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x11580u 5608
+#define use_offset_0x11580u 5720
 
 
   /* Siddham */
@@ -772,11 +788,11 @@
   /* 11580 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11590 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 115A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,
-  /* 115B0 */  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,  VPre,  VPre, VMAbv, VMAbv, VMPst,     H,
+  /* 115B0 */  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,    WJ,    WJ,  VPre,  VPre,  VPre,  VPre, VMAbv, VMAbv, VMPst,     H,
   /* 115C0 */ CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 115D0 */     O,     O,     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,  VBlw,  VBlw,     O,     O,
-  /* 115E0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 115F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 115D0 */     O,     O,     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,  VBlw,  VBlw,    WJ,    WJ,
+  /* 115E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 115F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Modi */
 
@@ -784,10 +800,10 @@
   /* 11610 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11620 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11630 */  VPst,  VPst,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPst,  VPst, VMAbv, VMPst,     H,
-  /* 11640 */  VAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 11650 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
-  /* 11660 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 11670 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11640 */  VAbv,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 11650 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 11660 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,
+  /* 11670 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Takri */
 
@@ -794,21 +810,21 @@
   /* 11680 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11690 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 116A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv, VMPst,  VAbv,  VPre,  VPst,
-  /* 116B0 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,     H, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,
-  /* 116C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
-  /* 116D0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 116E0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 116F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 116B0 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,     H, CMBlw,     B,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 116C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 116D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 116E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 116F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Ahom */
 
   /* 11700 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11710 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,  MBlw,  MPre,  MAbv,
-  /* 11720 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VBlw,  VAbv,  VAbv,  VAbv,     O,     O,     O,     O,
+  /* 11710 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,  MBlw,  MPre,  MAbv,
+  /* 11720 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VBlw,  VAbv,  VAbv,  VAbv,    WJ,    WJ,    WJ,    WJ,
   /* 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,
+  /* 11740 */     B,     B,     B,     B,     B,     B,     B,    WJ,
 
-#define use_offset_0x11800u 6064
+#define use_offset_0x11800u 6176
 
 
   /* Dogra */
@@ -816,31 +832,31 @@
   /* 11800 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11810 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
+  /* 11830 */  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMPst,     H, CMBlw,     O,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x11900u 6128
+#define use_offset_0x11900u 6240
 
 
   /* Dives Akuru */
 
-  /* 11900 */     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,     O,     O,     B,     B,     B,     B,
-  /* 11910 */     B,     B,     B,     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11900 */     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,     B,    WJ,    WJ,     B,     B,     B,     B,
+  /* 11910 */     B,     B,     B,     B,    WJ,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11920 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11930 */  VPst,  VPst,  VPst,  VPst,  VPst,  VPre,     O,  VPre,  VPre,     O,     O, VMAbv, VMAbv,  VPst,     H,     R,
-  /* 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,
+  /* 11930 */  VPst,  VPst,  VPst,  VPst,  VPst,  VPre,    WJ,  VPre,  VPre,    WJ,    WJ, VMAbv, VMAbv,  VPst,    IS,     R,
+  /* 11940 */  MPst,     R,  MPst, CMBlw,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 11950 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x119a0u 6224
+#define use_offset_0x119a0u 6336
 
 
   /* Nandinagari */
 
-  /* 119A0 */     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,     B,     B,     B,     B,     B,
+  /* 119A0 */     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,     B,     B,     B,     B,     B,     B,
   /* 119B0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 119C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 119D0 */     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VAbv,  VAbv,  VPst,  VPst, VMPst, VMPst,
-  /* 119E0 */     H,     B,     O,     O,  VPre,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 119F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 119D0 */     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,    WJ,    WJ,  VAbv,  VAbv,  VPst,  VPst, VMPst, VMPst,
+  /* 119E0 */     H,     B,     O,     O,  VPre,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 119F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Zanabazar Square */
 
@@ -848,7 +864,7 @@
   /* 11A10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11A30 */     B,     B,     B, FMBlw,  VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst,     R,  MBlw,  MBlw,  MBlw,  MBlw,    GB,
-  /* 11A40 */     O,     O,     O,     O,     O,    GB,     O,     H,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11A40 */     O,     O,     O,     O,     O,    GB,     O,    IS,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Soyombo */
 
@@ -856,50 +872,50 @@
   /* 11A60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11A70 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
+  /* 11A90 */  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw, VMAbv, VMPst, CMAbv,    IS,     O,     O,     O,     B,     O,     O,
 
-#define use_offset_0x11c00u 6480
+#define use_offset_0x11c00u 6592
 
 
   /* Bhaiksuki */
 
-  /* 11C00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 11C00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
   /* 11C10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11C20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,
-  /* 11C30 */  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,     O,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMAbv, VMPst,     H,
-  /* 11C40 */     B,     O,     O,     O,    GB,    GB,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11C30 */  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,    WJ,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMAbv, VMPst,     H,
+  /* 11C40 */     B,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
   /* 11C50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11C60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,
+  /* 11C60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,
 
   /* Marchen */
 
   /* 11C70 */     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11C80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11C90 */     O,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
-  /* 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,
+  /* 11C90 */    WJ,    WJ,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
+  /* 11CA0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,    WJ,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
+  /* 11CB0 */  VBlw,  VPre,  VBlw,  VAbv,  VPst, VMAbv, VMAbv,    WJ,
 
-#define use_offset_0x11d00u 6664
+#define use_offset_0x11d00u 6776
 
 
   /* Masaram Gondi */
 
-  /* 11D00 */     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,
+  /* 11D00 */     B,     B,     B,     B,     B,     B,     B,    WJ,     B,     B,    WJ,     B,     B,     B,     B,     B,
   /* 11D10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11D20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11D30 */     B,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,     O,     O,     O,  VAbv,     O,  VAbv,  VAbv,     O,  VAbv,
-  /* 11D40 */ VMAbv, VMAbv, CMBlw,  VAbv,  VBlw,     H,     R,  MBlw,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 11D50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 11D30 */     B,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,    WJ,    WJ,    WJ,  VAbv,    WJ,  VAbv,  VAbv,    WJ,  VAbv,
+  /* 11D40 */ VMAbv, VMAbv, CMBlw,  VAbv,  VBlw,    IS,     R,  MBlw,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 11D50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Gunjala Gondi */
 
-  /* 11D60 */     B,     B,     B,     B,     B,     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 11D60 */     B,     B,     B,     B,     B,     B,    WJ,     B,     B,    WJ,     B,     B,     B,     B,     B,     B,
   /* 11D70 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11D80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VPst,  VPst,  VPst,     O,
-  /* 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,
+  /* 11D80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VPst,  VPst,  VPst,    WJ,
+  /* 11D90 */  VAbv,  VAbv,    WJ,  VPst,  VPst, VMAbv, VMPst,    IS,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 11DA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x11ee0u 6840
+#define use_offset_0x11ee0u 6952
 
 
   /* Makasar */
@@ -907,7 +923,7 @@
   /* 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 6864
+#define use_offset_0x13000u 6976
 
 
   /* Egyptian Hieroglyphs */
@@ -978,21 +994,21 @@
   /* 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,
+  /* 13420 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,
 
   /* Egyptian Hieroglyph Format Controls */
 
-  /* 13430 */     H,     H,     H,     H,     H,     H,     H,     B,     B,     O,     O,     O,     O,     O,     O,     O,
+  /* 13430 */     H,     H,     H,     H,     H,     H,     H,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
-#define use_offset_0x16ac0u 7952
+#define use_offset_0x16ac0u 8064
 
 
   /* Tangsa */
 
-  /* 16AC0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 16AC0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
   /* 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,
+  /* 16AE0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    WJ,    WJ,
+  /* 16AF0 */     O,     O,     O,     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Pahawh Hmong */
 
@@ -1001,7 +1017,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 8072
+#define use_offset_0x16f00u 8184
 
 
   /* Miao */
@@ -1010,21 +1026,21 @@
   /* 16F10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 16F20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 16F30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 16F40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O, CMBlw,
+  /* 16F40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ, CMBlw,
   /* 16F50 */     O,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,
   /* 16F60 */  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,
   /* 16F70 */  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,
-  /* 16F80 */  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,     O,     O,     O,     O,     O, VMBlw,
+  /* 16F80 */  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ, VMBlw,
   /* 16F90 */ VMBlw, VMBlw, VMBlw,     O,     O,     O,     O,     O,
 
-#define use_offset_0x16fe0u 8224
+#define use_offset_0x16fe0u 8336
 
 
   /* Ideographic Symbols and Punctuation */
 
-  /* 16FE0 */     O,     O,     O,     O,     B,     O,     O,     O,
+  /* 16FE0 */     O,     O,     O,     O,     B,    WJ,    WJ,    WJ,
 
-#define use_offset_0x18b00u 8232
+#define use_offset_0x18b00u 8344
 
 
   /* Khitan Small Script */
@@ -1058,9 +1074,9 @@
   /* 18CA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 18CB0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
+  /* 18CD0 */     B,     B,     B,     B,     B,     B,    WJ,    WJ,
 
-#define use_offset_0x1bc00u 8704
+#define use_offset_0x1bc00u 8816
 
 
   /* Duployan */
@@ -1071,30 +1087,37 @@
   /* 1BC30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1BC40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1BC50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1BC60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,
-  /* 1BC70 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,
-  /* 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,
+  /* 1BC60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 1BC70 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,
+  /* 1BC80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* 1BC90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,     O, CMBlw, CMBlw,     O,
 
-#define use_offset_0x1e100u 8864
+#define use_offset_0x1d170u 8976
 
 
+  /* Musical Symbols */
+
+  /* 1D170 */     O,     O,     O,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,     O,     O,     O,     O,     O,
+
+#define use_offset_0x1e100u 8992
+
+
   /* Nyiakeng Puachue Hmong */
 
   /* 1E100 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1E110 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1E120 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,
-  /* 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,
+  /* 1E120 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,
+  /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,
+  /* 1E140 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,     B,     B,
 
-#define use_offset_0x1e290u 8944
+#define use_offset_0x1e290u 9072
 
 
   /* 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,
+  /* 1E2A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv,    WJ,
+  /* 1E2B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
 
   /* Wancho */
 
@@ -1101,9 +1124,9 @@
   /* 1E2C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1E2D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 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,
+  /* 1E2F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,    WJ,     O,
 
-#define use_offset_0x1e900u 9056
+#define use_offset_0x1e900u 9184
 
 
   /* Adlam */
@@ -1112,12 +1135,34 @@
   /* 1E910 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1E920 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1E930 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 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,
+  /* 1E940 */     B,     B,     B,     B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv,     B,    WJ,    WJ,    WJ,    WJ,
+  /* 1E950 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    WJ,    WJ,    WJ,    WJ,     O,     O,
 
-#define use_offset_0xe0100u 9152
+#define use_offset_0xe0000u 9280
 
 
+  /* Tags */
+
+  /* E0000 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0010 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0020 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0030 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0040 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0050 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0060 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0070 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+
+  /* No_Block */
+
+  /* E0080 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0090 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E00A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E00B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E00C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E00D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E00E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E00F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+
   /* Variation Selectors Supplement */
 
   /* E0100 */   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,   CGJ,
@@ -1136,11 +1181,240 @@
   /* 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% */
+  /* No_Block */
 
+  /* E01F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0200 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0210 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0220 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0230 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0240 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0250 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0260 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0270 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0280 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0290 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E02A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E02B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E02C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E02D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E02E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E02F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0300 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0310 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0320 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0330 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0340 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0350 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0360 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0370 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0380 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0390 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E03A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E03B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E03C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E03D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E03E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E03F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0400 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0410 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0420 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0430 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0440 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0450 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0460 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0470 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0480 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0490 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E04A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E04B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E04C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E04D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E04E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E04F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0500 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0510 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0520 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0530 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0540 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0550 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0560 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0570 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0580 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0590 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E05A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E05B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E05C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E05D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E05E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E05F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0600 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0610 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0620 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0630 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0640 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0650 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0660 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0670 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0680 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0690 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E06A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E06B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E06C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E06D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E06E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E06F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0700 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0710 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0720 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0730 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0740 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0750 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0760 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0770 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0780 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0790 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E07A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E07B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E07C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E07D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E07E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E07F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0800 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0810 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0820 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0830 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0840 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0850 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0860 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0870 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0880 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0890 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E08A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E08B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E08C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E08D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E08E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E08F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0900 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0910 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0920 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0930 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0940 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0950 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0960 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0970 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0980 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0990 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E09A0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E09B0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E09C0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E09D0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E09E0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E09F0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A00 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A10 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A20 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A30 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A40 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A50 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A60 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A70 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A80 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0A90 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0AA0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0AB0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0AC0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0AD0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0AE0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0AF0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B00 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B10 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B20 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B30 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B40 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B50 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B60 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B70 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B80 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0B90 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0BA0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0BB0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0BC0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0BD0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0BE0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0BF0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C00 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C10 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C20 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C30 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C40 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C50 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C60 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C70 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C80 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0C90 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0CA0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0CB0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0CC0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0CD0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0CE0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0CF0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D00 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D10 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D20 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D30 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D40 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D50 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D60 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D70 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D80 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0D90 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0DA0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0DB0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0DC0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0DD0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0DE0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0DF0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E00 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E10 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E20 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E30 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E40 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E50 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E60 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E70 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E80 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0E90 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0EA0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0EB0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0EC0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0ED0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0EE0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0EF0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F00 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F10 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F20 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F30 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F40 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F50 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F60 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F70 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F80 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0F90 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0FA0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0FB0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0FC0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0FD0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0FE0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+  /* E0FF0 */    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,    WJ,
+
+}; /* Table items: 13376; occupancy: 84% */
+
 static inline uint8_t
-hb_use_get_category (hb_codepoint_t u)
+hb_use_get_category (hb_glyph_info_t info)
 {
+  hb_codepoint_t u = info.codepoint;
   switch (u >> 12)
   {
     case 0x0u:
@@ -1164,8 +1438,7 @@
       break;
 
     case 0x2u:
-      if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u];
-      if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2087u)) return use_table[u - 0x2008u + use_offset_0x2008u];
       if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u];
       if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u];
       if (hb_in_range<hb_codepoint_t> (u, 0x2D30u, 0x2D7Fu)) return use_table[u - 0x2D30u + use_offset_0x2d30u];
@@ -1178,9 +1451,12 @@
 
     case 0xFu:
       if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
+      if (hb_in_range<hb_codepoint_t> (u, 0xFEF8u, 0xFEFFu)) return use_table[u - 0xFEF8u + use_offset_0xfef8u];
+      if (hb_in_range<hb_codepoint_t> (u, 0xFFF0u, 0xFFFFu)) return use_table[u - 0xFFF0u + use_offset_0xfff0u];
       break;
 
     case 0x10u:
+      if (hb_in_range<hb_codepoint_t> (u, 0xFFF0u, 0xFFFFu)) return use_table[u - 0xFFF0u + use_offset_0xfff0u];
       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, 0x10AEFu)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u];
@@ -1222,6 +1498,10 @@
       if (hb_in_range<hb_codepoint_t> (u, 0x1BC00u, 0x1BC9Fu)) return use_table[u - 0x1BC00u + use_offset_0x1bc00u];
       break;
 
+    case 0x1Du:
+      if (hb_in_range<hb_codepoint_t> (u, 0x1D170u, 0x1D17Fu)) return use_table[u - 0x1D170u + use_offset_0x1d170u];
+      break;
+
     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, 0x1E290u, 0x1E2FFu)) return use_table[u - 0x1E290u + use_offset_0x1e290u];
@@ -1229,13 +1509,19 @@
       break;
 
     case 0xE0u:
-      if (hb_in_range<hb_codepoint_t> (u, 0xE0100u, 0xE01EFu)) return use_table[u - 0xE0100u + use_offset_0xe0100u];
+      if (hb_in_range<hb_codepoint_t> (u, 0xE0000u, 0xE0FFFu)) return use_table[u - 0xE0000u + use_offset_0xe0000u];
       break;
 
+    case 0xE1u:
+      if (hb_in_range<hb_codepoint_t> (u, 0xE0000u, 0xE0FFFu)) return use_table[u - 0xE0000u + use_offset_0xe0000u];
+      break;
+
     default:
       break;
   }
-  return USE(O);
+  if (_hb_glyph_info_get_general_category (&info) == HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED)
+    return WJ;
+  return O;
 }
 
 #undef B
@@ -1245,7 +1531,7 @@
 #undef GB
 #undef H
 #undef HN
-#undef HVM
+#undef IS
 #undef J
 #undef N
 #undef O
@@ -1254,6 +1540,7 @@
 #undef SE
 #undef SUB
 #undef Sk
+#undef WJ
 #undef ZWNJ
 #undef CMAbv
 #undef CMBlw

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -115,25 +115,24 @@
   map->add_gsub_pause (setup_syllables_use);
 
   /* "Default glyph pre-processing group" */
-  map->enable_feature (HB_TAG('l','o','c','l'));
-  map->enable_feature (HB_TAG('c','c','m','p'));
-  map->enable_feature (HB_TAG('n','u','k','t'));
-  map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ);
+  map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
+  map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
+  map->enable_feature (HB_TAG('n','u','k','t'), F_PER_SYLLABLE);
+  map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ | F_PER_SYLLABLE);
 
   /* "Reordering group" */
   map->add_gsub_pause (_hb_clear_substitution_flags);
-  map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ);
+  map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ | F_PER_SYLLABLE);
   map->add_gsub_pause (record_rphf_use);
   map->add_gsub_pause (_hb_clear_substitution_flags);
-  map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ);
+  map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ | F_PER_SYLLABLE);
   map->add_gsub_pause (record_pref_use);
 
   /* "Orthographic unit shaping group" */
   for (unsigned int i = 0; i < ARRAY_LENGTH (use_basic_features); i++)
-    map->enable_feature (use_basic_features[i], F_MANUAL_ZWJ);
+    map->enable_feature (use_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE);
 
   map->add_gsub_pause (reorder_use);
-  map->add_gsub_pause (_hb_clear_syllables);
 
   /* "Topographical features" */
   for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++)
@@ -206,7 +205,7 @@
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
-    info[i].use_category() = hb_use_get_category (info[i].codepoint);
+    info[i].use_category() = hb_use_get_category (info[i]);
 }
 
 static void
@@ -257,7 +256,6 @@
     use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
     switch (syllable_type)
     {
-      case use_symbol_cluster:
       case use_hieroglyph_cluster:
       case use_non_cluster:
 	/* These don't join.  Nothing to do. */
@@ -269,6 +267,7 @@
       case use_standard_cluster:
       case use_number_joiner_terminated_cluster:
       case use_numeral_cluster:
+      case use_symbol_cluster:
       case use_broken_cluster:
 
 	bool join = last_form == JOINING_FORM_FINA || last_form == JOINING_FORM_ISOL;
@@ -350,7 +349,7 @@
 static inline bool
 is_halant_use (const hb_glyph_info_t &info)
 {
-  return (info.use_category() == USE(H) || info.use_category() == USE(HVM)) &&
+  return (info.use_category() == USE(H) || info.use_category() == USE(IS)) &&
 	 !_hb_glyph_info_ligated (&info);
 }
 
@@ -363,6 +362,7 @@
 		  (FLAG (use_virama_terminated_cluster) |
 		   FLAG (use_sakot_terminated_cluster) |
 		   FLAG (use_standard_cluster) |
+		   FLAG (use_symbol_cluster) |
 		   FLAG (use_broken_cluster) |
 		   0))))
     return;

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -935,17 +935,23 @@
   _hb_buffer_allocate_gsubgpos_vars (c->buffer);
 
   hb_ot_substitute_complex (c);
+
+#ifndef HB_NO_AAT_SHAPE
+  if (c->plan->apply_morx && c->plan->apply_gpos)
+    hb_aat_layout_remove_deleted_glyphs (c->buffer);
+#endif
 }
 
 static inline void
 hb_ot_substitute_post (const hb_ot_shape_context_t *c)
 {
-  hb_ot_hide_default_ignorables (c->buffer, c->font);
 #ifndef HB_NO_AAT_SHAPE
-  if (c->plan->apply_morx)
+  if (c->plan->apply_morx && !c->plan->apply_gpos)
     hb_aat_layout_remove_deleted_glyphs (c->buffer);
 #endif
 
+  hb_ot_hide_default_ignorables (c->buffer, c->font);
+
   if (c->plan->shaper->postprocess_glyphs &&
     c->buffer->message(c->font, "start postprocess-glyphs")) {
     c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -7,7 +7,7 @@
  * on files with these headers:
  *
  * <meta name="updated_at" content="2022-01-28 10:00 PM" />
- * File-Date: 2021-12-29
+ * File-Date: 2022-03-02
  */
 
 #ifndef HB_OT_TAG_TABLE_HH
@@ -54,6 +54,7 @@
 /*{"aio",	HB_TAG('A','I','O',' ')},*/	/* Aiton */
   {"aiw",	HB_TAG('A','R','I',' ')},	/* Aari */
   {"ajp",	HB_TAG('A','R','A',' ')},	/* South Levantine Arabic -> Arabic */
+  {"ajt",	HB_TAG('A','R','A',' ')},	/* Judeo-Tunisian Arabic (retired code) -> Arabic */
   {"ak",	HB_TAG('A','K','A',' ')},	/* Akan [macrolanguage] */
   {"akb",	HB_TAG('A','K','B',' ')},	/* Batak Angkola */
   {"akb",	HB_TAG('B','T','K',' ')},	/* Batak Angkola -> Batak */
@@ -809,7 +810,7 @@
   {"lac",	HB_TAG('M','Y','N',' ')},	/* Lacandon -> Mayan */
   {"lad",	HB_TAG('J','U','D',' ')},	/* Ladino */
   {"lah",	HB_TAG_NONE	       },	/* Lahnda [macrolanguage] != Lahuli */
-  {"lak",	HB_TAG_NONE	       },	/* Laka (Nigeria) != Lak */
+  {"lak",	HB_TAG_NONE	       },	/* Laka (Nigeria) (retired code) != Lak */
   {"lam",	HB_TAG_NONE	       },	/* Lamba != Lambani */
   {"laz",	HB_TAG_NONE	       },	/* Aribwatsa != Laz */
   {"lb",	HB_TAG('L','T','Z',' ')},	/* Luxembourgish */
@@ -1339,6 +1340,7 @@
   {"sla",	HB_TAG_NONE	       },	/* Slavic [collection] != Slavey */
   {"sm",	HB_TAG('S','M','O',' ')},	/* Samoan */
   {"sma",	HB_TAG('S','S','M',' ')},	/* Southern Sami */
+  {"smd",	HB_TAG('M','B','N',' ')},	/* Sama (retired code) -> Mbundu */
   {"smj",	HB_TAG('L','S','M',' ')},	/* Lule Sami */
   {"sml",	HB_TAG_NONE	       },	/* Central Sama != Somali */
   {"smn",	HB_TAG('I','S','M',' ')},	/* Inari Sami */
@@ -1345,6 +1347,7 @@
   {"sms",	HB_TAG('S','K','S',' ')},	/* Skolt Sami */
   {"smt",	HB_TAG('Q','I','N',' ')},	/* Simte -> Chin */
   {"sn",	HB_TAG('S','N','A','0')},	/* Shona */
+  {"snb",	HB_TAG('I','B','A',' ')},	/* Sebuyau (retired code) -> Iban */
   {"snh",	HB_TAG_NONE	       },	/* Shinabo (retired code) != Sinhala (Sinhalese) */
 /*{"snk",	HB_TAG('S','N','K',' ')},*/	/* Soninke */
   {"so",	HB_TAG('S','M','L',' ')},	/* Somali */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -577,10 +577,11 @@
 
 	hb_bytes_t bytes ((const char *) p, length);
 	hb_vector_t<unsigned int> private_indices;
-	if (iterator.current_tuple->has_private_points () &&
+	bool has_private_points = iterator.current_tuple->has_private_points ();
+	if (has_private_points &&
 	    !GlyphVariationData::unpack_points (p, private_indices, bytes))
 	  return false;
-	const hb_array_t<unsigned int> &indices = private_indices.length ? private_indices : shared_indices;
+	const hb_array_t<unsigned int> &indices = has_private_points ? private_indices : shared_indices;
 
 	bool apply_to_all = (indices.length == 0);
 	unsigned int num_deltas = apply_to_all ? points.length : indices.length;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -37,7 +37,6 @@
  * For a detailed writeup on the overflow resolution algorithm see:
  * docs/repacker.md
  */
-
 struct graph_t
 {
   struct vertex_t
@@ -140,7 +139,8 @@
    * the 'packed' object stack used internally in the
    * serializer
    */
-  graph_t (const hb_vector_t<hb_serialize_context_t::object_t *>& objects)
+  template<typename T>
+  graph_t (const T& objects)
       : parents_invalid (true),
         distance_invalid (true),
         positions_invalid (true),
@@ -1098,8 +1098,9 @@
   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)
+static inline
+bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows,
+                               graph_t& sorted_graph)
 {
   unsigned space = 0;
   hb_set_t roots_to_isolate;
@@ -1147,9 +1148,10 @@
   return true;
 }
 
-static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows,
-                                hb_set_t& priority_bumped_parents,
-                                graph_t& sorted_graph)
+static inline
+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;
 
@@ -1207,8 +1209,9 @@
  * For a detailed writeup describing how the algorithm operates see:
  * docs/repacker.md
  */
+template<typename T>
 inline hb_blob_t*
-hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed,
+hb_resolve_overflows (const T& packed,
                       hb_tag_t table_tag,
                       unsigned max_rounds = 20) {
   // Kahn sort is ~twice as fast as shortest distance sort and works for many fonts

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -36,6 +36,9 @@
 #include "hb-map.hh"
 #include "hb-pool.hh"
 
+#ifdef HB_EXPERIMENTAL_API
+#include "hb-subset-repacker.h"
+#endif
 
 /*
  * Serialize
@@ -70,6 +73,24 @@
       virtual_links.fini ();
     }
 
+    object_t () = default;
+    
+#ifdef HB_EXPERIMENTAL_API
+    object_t (const hb_object_t &o)
+    {
+      head = o.head;
+      tail = o.tail;
+      next = nullptr;
+      real_links.alloc (o.num_real_links);
+      for (unsigned i = 0 ; i < o.num_real_links; i++)
+        real_links.push (o.real_links[i]);
+
+      virtual_links.alloc (o.num_virtual_links);
+      for (unsigned i = 0; i < o.num_virtual_links; i++)
+        virtual_links.push (o.virtual_links[i]);
+    }
+#endif
+
     bool operator == (const object_t &o) const
     {
       // Virtual links aren't considered for equality since they don't affect the functionality
@@ -95,6 +116,20 @@
       unsigned position: 28;
       unsigned bias;
       objidx_t objidx;
+
+      link_t () = default;
+
+#ifdef HB_EXPERIMENTAL_API
+      link_t (const hb_link_t &o)
+      {
+        width = o.width;
+        is_signed = 0;
+        whence = 0;
+        position = o.position;
+        bias = 0;
+        objidx = o.objidx;
+      }
+#endif
     };
 
     char *head;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -257,6 +257,29 @@
 }
 
 /**
+ * hb_set_add_sorted_array:
+ * @set: A set
+ * @sorted_codepoints: (array length=num_codepoints): Array of codepoints to add
+ * @num_codepoints: Length of @sorted_codepoints
+ *
+ * Adds @num_codepoints codepoints to a set at once.
+ * The codepoints array must be in increasing order,
+ * with size at least @num_codepoints.
+ *
+ * Since: 4.1.0
+ */
+HB_EXTERN void
+hb_set_add_sorted_array (hb_set_t             *set,
+		         const hb_codepoint_t *sorted_codepoints,
+		         unsigned int          num_codepoints)
+{
+  /* Immutible-safe. */
+  set->add_sorted_array (sorted_codepoints,
+		         num_codepoints,
+		         sizeof(hb_codepoint_t));
+}
+
+/**
  * hb_set_add_range:
  * @set: A set
  * @first: The first element to add to @set
@@ -591,3 +614,28 @@
 {
   return set->previous_range (first, last);
 }
+
+/**
+ * hb_set_next_many:
+ * @set: A set
+ * @codepoint: Outputting codepoints starting after this one.
+ *             Use #HB_SET_VALUE_INVALID to get started.
+ * @out: (array length=size): An array of codepoints to write to.
+ * @size: The maximum number of codepoints to write out.
+ *
+ * Finds the next element in @set that is greater than @codepoint. Writes out
+ * codepoints to @out, until either the set runs out of elements, or @size
+ * codepoints are written, whichever comes first.
+ *
+ * Return value: the number of values written.
+ *
+ * Since: 4.2.0
+ **/
+unsigned int
+hb_set_next_many (const hb_set_t *set,
+		  hb_codepoint_t  codepoint,
+		  hb_codepoint_t *out,
+		  unsigned int    size)
+{
+  return set->next_many (codepoint, out, size);
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -111,6 +111,11 @@
 		  hb_codepoint_t  last);
 
 HB_EXTERN void
+hb_set_add_sorted_array (hb_set_t             *set,
+		         const hb_codepoint_t *sorted_codepoints,
+		         unsigned int          num_codepoints);
+
+HB_EXTERN void
 hb_set_del (hb_set_t       *set,
 	    hb_codepoint_t  codepoint);
 
@@ -180,6 +185,12 @@
 		       hb_codepoint_t *first,
 		       hb_codepoint_t *last);
 
+/* Pass HB_SET_VALUE_INVALID in to get started. */
+HB_EXTERN unsigned int
+hb_set_next_many (const hb_set_t *set,
+		  hb_codepoint_t  codepoint,
+		  hb_codepoint_t *out,
+		  unsigned int    size);
 
 HB_END_DECLS
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -109,6 +109,7 @@
   typedef bool value_t;
   value_t operator [] (hb_codepoint_t k) const { return get (k); }
   bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+
   /* Predicate. */
   bool operator () (hb_codepoint_t k) const { return has (k); }
 
@@ -138,6 +139,8 @@
   { return s.next_range (first, last); }
   bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const
   { return s.previous_range (first, last); }
+  unsigned int next_many (hb_codepoint_t codepoint, hb_codepoint_t *out, unsigned int size) const
+  { return s.next_many (codepoint, out, size); }
 
   unsigned int get_population () const { return s.get_population (); }
   hb_codepoint_t get_min () const { return s.get_min (); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -33,6 +33,7 @@
 #include "hb-aat-layout-feat-table.hh"
 #include "hb-ot-layout-common.hh"
 #include "hb-ot-cmap-table.hh"
+#include "hb-ot-glyf-table.hh"
 #include "hb-ot-head-table.hh"
 #include "hb-ot-maxp-table.hh"
 
@@ -55,17 +56,43 @@
 
 /* hb_face_t */
 
+#ifndef HB_NO_BORING_EXPANSION
+static inline unsigned
+load_num_glyphs_from_loca (const hb_face_t *face)
+{
+  unsigned ret = 0;
+
+  unsigned indexToLocFormat = face->table.head->indexToLocFormat;
+
+  if (indexToLocFormat <= 1)
+  {
+    bool short_offset = 0 == indexToLocFormat;
+    hb_blob_t *loca_blob = face->table.loca.get_blob ();
+    ret = hb_max (1u, loca_blob->length / (short_offset ? 2 : 4)) - 1;
+  }
+
+  return ret;
+}
+#endif
+
+static inline unsigned
+load_num_glyphs_from_maxp (const hb_face_t *face)
+{
+  return face->table.maxp->get_num_glyphs ();
+}
+
 unsigned int
 hb_face_t::load_num_glyphs () const
 {
-  hb_sanitize_context_t c = hb_sanitize_context_t ();
-  c.set_num_glyphs (0); /* So we don't recurse ad infinitum. */
-  hb_blob_t *maxp_blob = c.reference_table<OT::maxp> (this);
-  const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> ();
+  unsigned ret = 0;
 
-  unsigned int ret = maxp_table->get_num_glyphs ();
+#ifndef HB_NO_BORING_EXPANSION
+  ret = hb_max (ret, load_num_glyphs_from_loca (this));
+#endif
+
+  ret = hb_max (ret, load_num_glyphs_from_maxp (this));
+
   num_glyphs.set_relaxed (ret);
-  hb_blob_destroy (maxp_blob);
   return ret;
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -46,13 +46,13 @@
 static inline float
 _hb_angle_to_ratio (float a)
 {
-  return tanf (a * float (M_PI / 180.));
+  return tanf (a * float (-M_PI / 180.));
 }
 
 static inline float
 _hb_ratio_to_angle (float r)
 {
-  return atanf (r) * float (180. / M_PI);
+  return atanf (r) * float (-180. / M_PI);
 }
 
 /**
@@ -72,8 +72,7 @@
 hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
 {
   if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO))
-    return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE))
-	 + font->slant;
+    return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE));
 
   hb_face_t *face = font->face;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -43,8 +43,10 @@
  * @HB_STYLE_TAG_SLANT_ANGLE: Used to vary between upright and slanted text. Values
  * must be greater than -90 and less than +90. Values can be interpreted as
  * the angle, in counter-clockwise degrees, of oblique slant from whatever the
- * designer considers to be upright for that font design.
+ * designer considers to be upright for that font design. Typical right-leaning
+ * Italic fonts have a negative slant angle (typically around -12)
  * @HB_STYLE_TAG_SLANT_RATIO: same as @HB_STYLE_TAG_SLANT_ANGLE expression as ratio.
+ * Typical right-leaning Italic fonts have a positive slant ratio (typically around 0.2)
  * @HB_STYLE_TAG_WIDTH: Used to vary width of text from narrower to wider.
  * Non-zero. Values can be interpreted as a percentage of whatever the font
  * designer considers “normal width” for that font design.

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -40,7 +40,9 @@
 #include "hb-ot-stat-table.hh"
 #include "hb-ot-math-table.hh"
 
+using OT::Layout::GSUB::GSUB;
 
+
 typedef hb_hashmap_t<unsigned, hb_set_t *> script_langsys_map;
 #ifndef HB_NO_SUBSET_CFF
 static inline void
@@ -111,7 +113,7 @@
       retain_all_features = false;
       continue;
     }
-    
+
     if (visited_features.has (tag))
       continue;
 
@@ -249,9 +251,9 @@
     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 &&
@@ -358,7 +360,7 @@
 #ifndef HB_NO_SUBSET_LAYOUT
   if (close_over_gsub)
     // closure all glyphs/lookups/features needed for GSUB substitutions.
-    _closure_glyphs_lookups_features<OT::GSUB> (
+    _closure_glyphs_lookups_features<GSUB> (
         plan->source,
         plan->_glyphset_gsub,
         plan->layout_features,
@@ -458,7 +460,7 @@
 }
 
 /**
- * hb_subset_plan_create:
+ * hb_subset_plan_create_or_fail:
  * @face: font face to create the plan for.
  * @input: a #hb_subset_input_t input.
  *
@@ -467,17 +469,18 @@
  * which tables and glyphs should be retained.
  *
  * Return value: (transfer full): New subset plan. Destroy with
- * hb_subset_plan_destroy().
+ * hb_subset_plan_destroy(). If there is a failure creating the plan
+ * nullptr will be returned.
  *
- * Since: 1.7.5
+ * Since: 4.0.0
  **/
 hb_subset_plan_t *
-hb_subset_plan_create (hb_face_t	 *face,
-		       const hb_subset_input_t *input)
+hb_subset_plan_create_or_fail (hb_face_t	 *face,
+                               const hb_subset_input_t *input)
 {
   hb_subset_plan_t *plan;
   if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> ())))
-    return const_cast<hb_subset_plan_t *> (&Null (hb_subset_plan_t));
+    return nullptr;
 
   plan->successful = true;
   plan->flags = input->flags;
@@ -514,8 +517,9 @@
   plan->layout_variation_indices = hb_set_create ();
   plan->layout_variation_idx_map = hb_map_create ();
 
-  if (plan->in_error ()) {
-    return plan;
+  if (unlikely (plan->in_error ())) {
+    hb_subset_plan_destroy (plan);
+    return nullptr;
   }
 
   _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan);
@@ -532,6 +536,10 @@
 				  plan->reverse_glyph_map,
 				  &plan->_num_output_glyphs);
 
+  if (unlikely (plan->in_error ())) {
+    hb_subset_plan_destroy (plan);
+    return nullptr;
+  }
   return plan;
 }
 
@@ -542,7 +550,7 @@
  * Decreases the reference count on @plan, and if it reaches zero, destroys
  * @plan, freeing all memory.
  *
- * Since: 1.7.5
+ * Since: 4.0.0
  **/
 void
 hb_subset_plan_destroy (hb_subset_plan_t *plan)
@@ -596,3 +604,116 @@
 
   hb_free (plan);
 }
+
+/**
+ * hb_subset_plan_old_to_new_glyph_mapping:
+ * @plan: a subsetting plan.
+ *
+ * Returns the mapping between glyphs in the original font to glyphs in the
+ * subset that will be produced by @plan
+ *
+ * Return value: (transfer none):
+ * A pointer to the #hb_map_t of the mapping.
+ *
+ * Since: 4.0.0
+ **/
+const hb_map_t*
+hb_subset_plan_old_to_new_glyph_mapping (const hb_subset_plan_t *plan)
+{
+  return plan->glyph_map;
+}
+
+/**
+ * hb_subset_plan_new_to_old_glyph_mapping:
+ * @plan: a subsetting plan.
+ *
+ * Returns the mapping between glyphs in the subset that will be produced by
+ * @plan and the glyph in the original font.
+ *
+ * Return value: (transfer none):
+ * A pointer to the #hb_map_t of the mapping.
+ *
+ * Since: 4.0.0
+ **/
+const hb_map_t*
+hb_subset_plan_new_to_old_glyph_mapping (const hb_subset_plan_t *plan)
+{
+  return plan->reverse_glyph_map;
+}
+
+/**
+ * hb_subset_plan_unicode_to_old_glyph_mapping:
+ * @plan: a subsetting plan.
+ *
+ * Returns the mapping between codepoints in the original font and the
+ * associated glyph id in the original font.
+ *
+ * Return value: (transfer none):
+ * A pointer to the #hb_map_t of the mapping.
+ *
+ * Since: 4.0.0
+ **/
+const hb_map_t*
+hb_subset_plan_unicode_to_old_glyph_mapping (const hb_subset_plan_t *plan)
+{
+  return plan->codepoint_to_glyph;
+}
+
+/**
+ * hb_subset_plan_reference: (skip)
+ * @plan: a #hb_subset_plan_t object.
+ *
+ * Increases the reference count on @plan.
+ *
+ * Return value: @plan.
+ *
+ * Since: 4.0.0
+ **/
+hb_subset_plan_t *
+hb_subset_plan_reference (hb_subset_plan_t *plan)
+{
+  return hb_object_reference (plan);
+}
+
+/**
+ * hb_subset_plan_set_user_data: (skip)
+ * @plan: a #hb_subset_plan_t object.
+ * @key: The user-data key to set
+ * @data: A pointer to the user data
+ * @destroy: (nullable): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
+ *
+ * Attaches a user-data key/data pair to the given subset plan object.
+ *
+ * Return value: %true if success, %false otherwise
+ *
+ * Since: 4.0.0
+ **/
+hb_bool_t
+hb_subset_plan_set_user_data (hb_subset_plan_t   *plan,
+                              hb_user_data_key_t *key,
+                              void               *data,
+                              hb_destroy_func_t   destroy,
+                              hb_bool_t	          replace)
+{
+  return hb_object_set_user_data (plan, key, data, destroy, replace);
+}
+
+/**
+ * hb_subset_plan_get_user_data: (skip)
+ * @plan: a #hb_subset_plan_t object.
+ * @key: The user-data key to query
+ *
+ * Fetches the user data associated with the specified key,
+ * attached to the specified subset plan object.
+ *
+ * Return value: (transfer none): A pointer to the user data
+ *
+ * Since: 4.0.0
+ **/
+void *
+hb_subset_plan_get_user_data (const hb_subset_plan_t *plan,
+                              hb_user_data_key_t     *key)
+{
+  return hb_object_get_user_data (plan, key);
+}

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	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2022-04-03 22:28:02 UTC (rev 62894)
@@ -198,13 +198,4 @@
   }
 };
 
-typedef struct hb_subset_plan_t hb_subset_plan_t;
-
-HB_INTERNAL hb_subset_plan_t *
-hb_subset_plan_create (hb_face_t           *face,
-		       const hb_subset_input_t   *input);
-
-HB_INTERNAL void
-hb_subset_plan_destroy (hb_subset_plan_t *plan);
-
 #endif /* HB_SUBSET_PLAN_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2022  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+#include "hb-repacker.hh"
+
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_subset_repack_or_fail:
+ * @hb_objects: raw array of struct hb_object_t, which provides
+ * object graph info
+ * @num_hb_objs: number of hb_object_t in the hb_objects array.
+ *
+ * Given the input object graph info, repack a table to eliminate
+ * offset overflows. A nullptr is returned if the repacking attempt fails.
+ *
+ * Since: EXPERIMENTAL
+ **/
+hb_blob_t* hb_subset_repack_or_fail (hb_object_t* hb_objects, unsigned num_hb_objs)
+{
+  hb_vector_t<const hb_object_t *> packed;
+  packed.alloc (num_hb_objs + 1);
+  packed.push (nullptr);
+  for (unsigned i = 0 ; i < num_hb_objs ; i++)
+    packed.push (&(hb_objects[i]));
+  return hb_resolve_overflows (packed, HB_OT_TAG_GSUB);
+}
+#endif
+

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.h	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2022  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+#ifndef HB_SUBSET_REPACKER_H
+#define HB_SUBSET_REPACKER_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * struct hb_link_t
+ * width:    offsetSize in bytes
+ * position: position of the offset field in bytes
+ * from beginning of subtable
+ * objidx:   index of subtable
+ **/
+struct hb_link_t
+{
+  unsigned width;
+  unsigned position;
+  unsigned objidx;
+};
+
+typedef struct hb_link_t hb_link_t;
+
+/**
+ * struct hb_object_t
+ * head:    start of object data
+ * tail:    end of object data
+ * num_real_links:    num of offset field in the object
+ * real_links:        pointer to array of offset info
+ * num_virtual_links: num of objects that must be packed
+ * after current object in the final serialized order
+ * virtual_links:     array of virtual link info
+ **/
+struct hb_object_t
+{
+  char *head;
+  char *tail;
+  unsigned num_real_links;
+  hb_link_t *real_links;
+  unsigned num_virtual_links;
+  hb_link_t *virtual_links;
+};
+
+typedef struct hb_object_t hb_object_t;
+
+HB_EXTERN hb_blob_t*
+hb_subset_repack_or_fail (hb_object_t* hb_objects,
+                          unsigned num_hb_objs);
+
+#endif
+
+HB_END_DECLS
+
+#endif /* HB_SUBSET_REPACKER_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -55,6 +55,8 @@
 #include "hb-ot-math-table.hh"
 #include "hb-repacker.hh"
 
+using OT::Layout::GSUB::GSUB;
+
 /**
  * SECTION:hb-subset
  * @title: hb-subset
@@ -312,7 +314,7 @@
 
 #ifndef HB_NO_SUBSET_LAYOUT
   case HB_OT_TAG_GDEF: return _subset<const OT::GDEF> (plan);
-  case HB_OT_TAG_GSUB: return _subset<const OT::GSUB> (plan);
+  case HB_OT_TAG_GSUB: return _subset<const GSUB> (plan);
   case HB_OT_TAG_GPOS: return _subset<const OT::GPOS> (plan);
   case HB_OT_TAG_gvar: return _subset<const OT::gvar> (plan);
   case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan);
@@ -343,17 +345,41 @@
 {
   if (unlikely (!input || !source)) return hb_face_get_empty ();
 
-  hb_subset_plan_t *plan = hb_subset_plan_create (source, input);
-  if (unlikely (plan->in_error ())) {
-    hb_subset_plan_destroy (plan);
+  hb_subset_plan_t *plan = hb_subset_plan_create_or_fail (source, input);
+  if (unlikely (!plan)) {
     return nullptr;
   }
 
+  hb_face_t * result = hb_subset_plan_execute_or_fail (plan);
+  hb_subset_plan_destroy (plan);
+  return result;
+}
+
+
+/**
+ * hb_subset_plan_execute_or_fail:
+ * @plan: a subsetting plan.
+ *
+ * Executes the provided subsetting @plan.
+ *
+ * Return value:
+ * on success returns a reference to generated font subset. If the subsetting operation fails
+ * returns nullptr.
+ *
+ * Since: 4.0.0
+ **/
+hb_face_t *
+hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan)
+{
+  if (unlikely (!plan || plan->in_error ())) {
+    return nullptr;
+  }
+
   hb_set_t tags_set;
   bool success = true;
   hb_tag_t table_tags[32];
   unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
-  while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables))
+  while ((hb_face_get_table_tags (plan->source, offset, &num_tables, table_tags), num_tables))
   {
     for (unsigned i = 0; i < num_tables; ++i)
     {
@@ -367,8 +393,5 @@
   }
 end:
 
-  hb_face_t *result = success ? hb_face_reference (plan->dest) : nullptr;
-
-  hb_subset_plan_destroy (plan);
-  return result;
+  return success ? hb_face_reference (plan->dest) : nullptr;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2022-04-03 22:28:02 UTC (rev 62894)
@@ -40,6 +40,15 @@
 typedef struct hb_subset_input_t hb_subset_input_t;
 
 /**
+ * hb_subset_plan_t:
+ *
+ * Contains information about how the subset operation will be executed.
+ * Such as mappings from the old glyph ids to the new ones in the subset.
+ */
+
+typedef struct hb_subset_plan_t hb_subset_plan_t;
+
+/**
  * hb_subset_flags_t:
  * @HB_SUBSET_FLAGS_DEFAULT: all flags at their default value of false.
  * @HB_SUBSET_FLAGS_NO_HINTING: If set hinting instructions will be dropped in
@@ -124,7 +133,7 @@
 
 HB_EXTERN void *
 hb_subset_input_get_user_data (const hb_subset_input_t *input,
-			       hb_user_data_key_t	   *key);
+			       hb_user_data_key_t      *key);
 
 HB_EXTERN hb_set_t *
 hb_subset_input_unicode_set (hb_subset_input_t *input);
@@ -145,6 +154,41 @@
 HB_EXTERN hb_face_t *
 hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
 
+HB_EXTERN hb_face_t *
+hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan);
+
+HB_EXTERN hb_subset_plan_t *
+hb_subset_plan_create_or_fail (hb_face_t                 *face,
+                               const hb_subset_input_t   *input);
+
+HB_EXTERN void
+hb_subset_plan_destroy (hb_subset_plan_t *plan);
+
+HB_EXTERN const hb_map_t*
+hb_subset_plan_old_to_new_glyph_mapping (const hb_subset_plan_t *plan);
+
+HB_EXTERN const hb_map_t*
+hb_subset_plan_new_to_old_glyph_mapping (const hb_subset_plan_t *plan);
+
+HB_EXTERN const hb_map_t*
+hb_subset_plan_unicode_to_old_glyph_mapping (const hb_subset_plan_t *plan);
+
+
+HB_EXTERN hb_subset_plan_t *
+hb_subset_plan_reference (hb_subset_plan_t *plan);
+
+HB_EXTERN hb_bool_t
+hb_subset_plan_set_user_data (hb_subset_plan_t   *plan,
+                              hb_user_data_key_t *key,
+                              void               *data,
+                              hb_destroy_func_t   destroy,
+                              hb_bool_t	          replace);
+
+HB_EXTERN void *
+hb_subset_plan_get_user_data (const hb_subset_plan_t *plan,
+                              hb_user_data_key_t     *key);
+
+
 HB_END_DECLS
 
 #endif /* HB_SUBSET_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2022-04-03 22:28:02 UTC (rev 62894)
@@ -42,7 +42,7 @@
 #define hb_blob_create_from_file_or_fail(x)  hb_blob_get_empty ()
 #endif
 
-#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) && defined(HB_EXPERIMENTAL_API)
+#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW)
 static void
 svg_dump (hb_face_t *face, unsigned face_index)
 {
@@ -129,7 +129,7 @@
   hb_font_destroy (font);
 }
 
-struct user_data_t
+struct draw_data_t
 {
   FILE *f;
   hb_position_t ascender;
@@ -136,41 +136,53 @@
 };
 
 static void
-move_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data)
+move_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
+	 hb_draw_state_t *st,
+	 float to_x, float to_y,
+	 void *)
 {
-  fprintf (user_data.f, "M%d,%d", to_x, user_data.ascender - to_y);
+  fprintf (draw_data->f, "M%g,%g", to_x, draw_data->ascender - to_y);
 }
 
 static void
-line_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data)
+line_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
+	 hb_draw_state_t *st,
+	 float to_x, float to_y,
+	 void *)
 {
-  fprintf (user_data.f, "L%d,%d", to_x, user_data.ascender - to_y);
+  fprintf (draw_data->f, "L%g,%g", to_x, draw_data->ascender - to_y);
 }
 
 static void
-quadratic_to (hb_position_t control_x, hb_position_t control_y,
-	      hb_position_t to_x, hb_position_t to_y,
-	      user_data_t &user_data)
+quadratic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
+	      hb_draw_state_t *st,
+	      float control_x, float control_y,
+	      float to_x, float to_y,
+	      void *)
 {
-  fprintf (user_data.f, "Q%d,%d %d,%d", control_x, user_data.ascender - control_y,
-					to_x, user_data.ascender - to_y);
+  fprintf (draw_data->f, "Q%g,%g %g,%g", control_x, draw_data->ascender - control_y,
+					to_x, draw_data->ascender - to_y);
 }
 
 static void
-cubic_to (hb_position_t control1_x, hb_position_t control1_y,
-	  hb_position_t control2_x, hb_position_t control2_y,
-	  hb_position_t to_x, hb_position_t to_y,
-	  user_data_t &user_data)
+cubic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
+	  hb_draw_state_t *st,
+	  float control1_x, float control1_y,
+	  float control2_x, float control2_y,
+	  float to_x, float to_y,
+	  void *)
 {
-  fprintf (user_data.f, "C%d,%d %d,%d %d,%d", control1_x, user_data.ascender - control1_y,
-					       control2_x, user_data.ascender - control2_y,
-					       to_x, user_data.ascender - to_y);
+  fprintf (draw_data->f, "C%g,%g %g,%g %g,%g", control1_x, draw_data->ascender - control1_y,
+					       control2_x, draw_data->ascender - control2_y,
+					       to_x, draw_data->ascender - to_y);
 }
 
 static void
-close_path (user_data_t &user_data)
+close_path (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
+	    hb_draw_state_t *st,
+	    void *)
 {
-  fprintf (user_data.f, "Z");
+  fprintf (draw_data->f, "Z");
 }
 
 static void
@@ -218,9 +230,9 @@
 		    " viewBox=\"%d %d %d %d\">\n",
 		    extents.x_bearing, 0,
 		    extents.x_bearing + extents.width, -extents.height);
-	user_data_t user_data;
-	user_data.ascender = extents.y_bearing;
-	user_data.f = f;
+	draw_data_t draw_data;
+	draw_data.ascender = extents.y_bearing;
+	draw_data.f = f;
 
 	for (unsigned layer = 0; layer < num_layers; ++layer)
 	{
@@ -232,8 +244,7 @@
 	  if (hb_color_get_alpha (color) != 255)
 	    fprintf (f, "fill-opacity=\"%.3f\"", (double) hb_color_get_alpha (color) / 255.);
 	  fprintf (f, "d=\"");
-	  if (!hb_font_draw_glyph (font, layers[layer].glyph, funcs, &user_data))
-	    printf ("Failed to decompose layer %d while %d\n", layers[layer].glyph, gid);
+	  hb_font_get_glyph_shape (font, layers[layer].glyph, funcs, &draw_data);
 	  fprintf (f, "\"/>\n");
 	}
 
@@ -269,11 +280,10 @@
 		" viewBox=\"%d %d %d %d\"><path d=\"",
 		extents.x_bearing, 0,
 		extents.x_bearing + extents.width, font_extents.ascender - font_extents.descender);
-    user_data_t user_data;
-    user_data.ascender = font_extents.ascender;
-    user_data.f = f;
-    if (!hb_font_draw_glyph (font, gid, funcs, &user_data))
-      printf ("Failed to decompose gid: %d\n", gid);
+    draw_data_t draw_data;
+    draw_data.ascender = font_extents.ascender;
+    draw_data.f = f;
+    hb_font_get_glyph_shape (font, gid, funcs, &draw_data);
     fprintf (f, "\"/></svg>");
     fclose (f);
   }
@@ -300,11 +310,11 @@
   fclose (font_name_file);
 
   hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
-  hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to);
-  hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to);
-  hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to);
-  hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to);
-  hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path);
+  hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, nullptr, nullptr);
+  hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, nullptr, nullptr);
+  hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, nullptr, nullptr);
+  hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, nullptr, nullptr);
+  hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, nullptr, nullptr);
 
   unsigned num_faces = hb_face_count (blob);
   for (unsigned face_index = 0; face_index < num_faces; ++face_index)
@@ -512,7 +522,7 @@
 #ifndef MAIN_CC_NO_PRIVATE_API
   print_layout_info_using_private_api (blob);
 #endif
-#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) && defined(HB_EXPERIMENTAL_API)
+#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW)
   dump_glyphs (blob, argv[1]);
 #endif
   hb_blob_destroy (blob);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2022-04-03 22:28:02 UTC (rev 62894)
@@ -92,6 +92,28 @@
   'hb-ot-layout-gdef-table.hh',
   'hb-ot-layout-gpos-table.hh',
   'hb-ot-layout-gsub-table.hh',
+  'OT/Layout/GSUB/Common.hh',
+  'OT/Layout/GSUB/Sequence.hh',
+  'OT/Layout/GSUB/SingleSubstFormat1.hh',
+  'OT/Layout/GSUB/SingleSubstFormat2.hh',
+  'OT/Layout/GSUB/SingleSubst.hh',
+  'OT/Layout/GSUB/MultipleSubstFormat1.hh',
+  'OT/Layout/GSUB/MultipleSubst.hh',
+  'OT/Layout/GSUB/AlternateSubstFormat1.hh',
+  'OT/Layout/GSUB/AlternateSubst.hh',
+  'OT/Layout/GSUB/AlternateSet.hh',
+  'OT/Layout/GSUB/LigatureSubstFormat1.hh',
+  'OT/Layout/GSUB/LigatureSubst.hh',
+  'OT/Layout/GSUB/LigatureSet.hh',
+  'OT/Layout/GSUB/Ligature.hh',
+  'OT/Layout/GSUB/ReverseChainSingleSubst.hh',
+  'OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh',
+  'OT/Layout/GSUB/ContextSubst.hh',
+  'OT/Layout/GSUB/ChainContextSubst.hh',
+  'OT/Layout/GSUB/ExtensionSubst.hh',
+  'OT/Layout/GSUB/SubstLookupSubTable.hh',
+  'OT/Layout/GSUB/SubstLookup.hh',
+  'OT/Layout/GSUB/GSUB.hh',
   'hb-ot-layout-gsubgpos.hh',
   'hb-ot-layout-jstf-table.hh',
   'hb-ot-layout.cc',
@@ -276,11 +298,15 @@
   'hb-subset-input.hh',
   'hb-subset-plan.cc',
   'hb-subset-plan.hh',
+  'hb-subset-repacker.cc',
   'hb-subset.cc',
   'hb-subset.hh',
 )
 
-hb_subset_headers = files('hb-subset.h')
+hb_subset_headers = files(
+  'hb-subset.h',
+  'hb-subset-repacker.h'
+)
 
 hb_gobject_sources = files(
   'hb-gobject-structs.cc'

Modified: trunk/Build/source/libs/harfbuzz/include/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/include/Makefile.am	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/include/Makefile.am	2022-04-03 22:28:02 UTC (rev 62894)
@@ -29,6 +29,7 @@
 	$(HARFBUZZ_SRC)/hb-shape.h \
 	$(HARFBUZZ_SRC)/hb-shape-plan.h \
 	$(HARFBUZZ_SRC)/hb-style.h \
+	$(HARFBUZZ_SRC)/hb-subset-repacker.h \
 	$(HARFBUZZ_SRC)/hb-unicode.h \
 	$(HARFBUZZ_BLD)/hb-version.h
 

Modified: trunk/Build/source/libs/harfbuzz/include/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/include/Makefile.in	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/include/Makefile.in	2022-04-03 22:28:02 UTC (rev 62894)
@@ -254,6 +254,7 @@
 	$(HARFBUZZ_SRC)/hb-map.h $(HARFBUZZ_SRC)/hb-ot-deprecated.h \
 	$(HARFBUZZ_SRC)/hb-set.h $(HARFBUZZ_SRC)/hb-shape.h \
 	$(HARFBUZZ_SRC)/hb-shape-plan.h $(HARFBUZZ_SRC)/hb-style.h \
+	$(HARFBUZZ_SRC)/hb-subset-repacker.h \
 	$(HARFBUZZ_SRC)/hb-unicode.h $(HARFBUZZ_BLD)/hb-version.h \
 	$(HARFBUZZ_SRC)/hb-ot.h $(HARFBUZZ_SRC)/hb-ot-color.h \
 	$(HARFBUZZ_SRC)/hb-ot-font.h $(HARFBUZZ_SRC)/hb-ot-layout.h \

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2022-04-03 20:55:41 UTC (rev 62893)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2022-04-03 22:28:02 UTC (rev 62894)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [3.4.0])
+m4_define([harfbuzz_version], [4.2.0])



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