texlive[65304] Build/source/libs: harfbuzz-6.0.0

commits+kakuto at tug.org commits+kakuto at tug.org
Sun Dec 18 02:06:39 CET 2022


Revision: 65304
          http://tug.org/svn/texlive?view=revision&revision=65304
Author:   kakuto
Date:     2022-12-18 02:06:39 +0100 (Sun, 18 Dec 2022)
Log Message:
-----------
harfbuzz-6.0.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/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat2.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairSet.hh
    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/Ligature.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/MultipleSubst.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/glyf/CompositeGlyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/classdef-graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/coverage-graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/pairpos-graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-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-blob.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl
    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-serialize.cc
    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.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
    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-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    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-glib.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
    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-color-cbdt-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-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.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-math-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-default.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-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-pool.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-accelerator.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-array.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/composite-iter.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/coord-setter.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-multimap.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-multimap.cc

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/README	2022-12-18 01:06:39 UTC (rev 65304)
@@ -25,8 +25,8 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 5.3.1 - checked 20oct22
-  https://github.com/harfbuzz/harfbuzz/releases/tag/5.3.1
+harfbuzz 6.0.0 - checked 18dec22
+  https://github.com/harfbuzz/harfbuzz/releases/tag/6.0.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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,3 +1,8 @@
+2022-12-18  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Import harfbuzz-6.0.0.
+	* version.ac, Makefile.am: Adjusted.
+
 2022-10-20  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Import harfbuzz-5.3.1.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2022-12-18 01:06:39 UTC (rev 65304)
@@ -165,6 +165,7 @@
 	@HARFBUZZ_TREE@/src/hb-aat-map.cc \
 	@HARFBUZZ_TREE@/src/hb-aat-map.hh \
 	@HARFBUZZ_TREE@/src/hb-array.hh \
+	@HARFBUZZ_TREE@/src/hb-multimap.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-font.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-layout.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-layout-base-table.hh \
@@ -239,6 +240,9 @@
 	@HARFBUZZ_TREE@/src/OT/glyf/SimpleGlyph.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/CompositeGlyph.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/SubsetGlyph.hh \
+	@HARFBUZZ_TREE@/src/OT/glyf/VarCompositeGlyph.hh \
+	@HARFBUZZ_TREE@/src/OT/glyf/composite-iter.hh \
+	@HARFBUZZ_TREE@/src/OT/glyf/coord-setter.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/Coverage.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/CoverageFormat1.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/CoverageFormat2.hh \

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2022-12-18 01:06:39 UTC (rev 65304)
@@ -834,6 +834,7 @@
 	@HARFBUZZ_TREE@/src/hb-aat-map.cc \
 	@HARFBUZZ_TREE@/src/hb-aat-map.hh \
 	@HARFBUZZ_TREE@/src/hb-array.hh \
+	@HARFBUZZ_TREE@/src/hb-multimap.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-font.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-layout.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-layout-base-table.hh \
@@ -906,6 +907,9 @@
 	@HARFBUZZ_TREE@/src/OT/glyf/SimpleGlyph.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/CompositeGlyph.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/SubsetGlyph.hh \
+	@HARFBUZZ_TREE@/src/OT/glyf/VarCompositeGlyph.hh \
+	@HARFBUZZ_TREE@/src/OT/glyf/composite-iter.hh \
+	@HARFBUZZ_TREE@/src/OT/glyf/coord-setter.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/Coverage.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/CoverageFormat1.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/CoverageFormat2.hh \

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,3 +1,8 @@
+2022-12-18  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Imported harfbuzz-6.0.0 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/6.0.0/
+
 2022-10-20  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Imported harfbuzz-5.3.1 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-5.3.1/ tree as obtained from:
-	https://github.com/harfbuzz/harfbuzz/releases/download/5.3.1/
+Changes applied to the harfbuzz-6.0.0/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/6.0.0/
 
 Removed:
 	COPYING
@@ -18,6 +18,7 @@
 	test-driver
 	src/Makefile.in
 	src/hb-version.h
+	src/hb-features.h.in
 
         unused dirs:
 	docs

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/configure	2022-12-18 01:06:39 UTC (rev 65304)
@@ -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) 5.3.1.
+# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 6.0.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='5.3.1'
-PACKAGE_STRING='harfbuzz (TeX Live) 5.3.1'
+PACKAGE_VERSION='6.0.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 6.0.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) 5.3.1 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 6.0.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) 5.3.1:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 6.0.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 5.3.1
+harfbuzz (TeX Live) configure 6.0.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 5.3.1, which was
+It was created by harfbuzz (TeX Live) $as_me 6.0.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='5.3.1'
+ VERSION='6.0.0'
 
 
 # Some tools Automake needs.
@@ -5033,10 +5033,10 @@
 
 
 
-HB_VERSION_MAJOR=5
-HB_VERSION_MINOR=3
-HB_VERSION_MICRO=1
-HB_VERSION=5.3.1
+HB_VERSION_MAJOR=6
+HB_VERSION_MINOR=0
+HB_VERSION_MICRO=0
+HB_VERSION=6.0.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 5.3.1, which was
+This file was extended by harfbuzz (TeX Live) $as_me 6.0.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 5.3.1
+harfbuzz (TeX Live) config.status 6.0.0
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,3 +1,6070 @@
+commit afcae83a064843d71d47624bc162e121cc56c08b
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Dec 16 23:14:57 2022 +0200
+
+    6.0.0
+
+ NEWS                   | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ configure.ac           |  2 +-
+ docs/harfbuzz-docs.xml |  1 +
+ meson.build            |  2 +-
+ src/hb-subset-input.cc |  6 ++---
+ src/hb-version.h       |  8 +++----
+ 6 files changed, 72 insertions(+), 9 deletions(-)
+
+commit 27ff90d7b8c65017334f15f45b5552d4f6fdb128
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Dec 16 22:08:33 2022 +0200
+
+    [meson] Update freetype2 wrap
+    
+    Use the one from WrapDB and add zlib wrap because current FreeType
+    tarball misses it.
+
+ subprojects/freetype2.wrap | 10 ++++++----
+ subprojects/zlib.wrap      | 12 ++++++++++++
+ 2 files changed, 18 insertions(+), 4 deletions(-)
+
+commit a98c6fdd92f35c2d176f5c808287a0b568aede48
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 14:04:54 2022 -0500
+
+    Mark an argument as unused
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 601d3806c93309ec47c2dc0c53fb36c3b95a3d9d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 13:34:15 2022 -0500
+
+    COLRv1: Revamp extents variation
+    
+    Try to do this a cleaner way.
+
+ src/hb-ot-color-colr-table.hh | 60 ++++++++++++++++++++++++++++---------------
+ 1 file changed, 39 insertions(+), 21 deletions(-)
+
+commit 318df8a706b2cd9b8323d8368f2f7d96117c7348
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Dec 16 21:27:37 2022 +0200
+
+    [meson] Update google-benchmark wrap
+    
+    Use the one from WrapDB.
+
+ subprojects/google-benchmark.wrap | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+commit bd7c458028e1dde0cdeb9099279d17bf63f5b3ff
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Dec 16 21:01:26 2022 +0200
+
+    [meson] Update glib wrap
+    
+    Use the one from WrapDB.
+
+ .circleci/config.yml  |  4 ++--
+ subprojects/glib.wrap | 17 +++++++++--------
+ 2 files changed, 11 insertions(+), 10 deletions(-)
+
+commit 51a17201a734616640e8c46bccaa0b26e1caaa27
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 12:28:30 2022 -0700
+
+    [open-type] In to_float() take offset as float
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9e3bfd9aa169f1ca77d6b1e6227905ee585a4255
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Dec 16 20:10:51 2022 +0200
+
+    [ci] Build Windows binaries without cairo-ft
+
+ .ci/build-win32.sh | 3 ++-
+ .ci/build-win64.sh | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+commit 6add69a6ec422406727186fdc5a7fcde289cbfbe
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Dec 16 19:54:00 2022 +0200
+
+    [hb-view] Allow building without cairo-ft
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3925
+
+ meson.build          |  3 ++-
+ util/helper-cairo.hh | 16 ++++++++++++++--
+ util/meson.build     |  3 +--
+ 3 files changed, 17 insertions(+), 5 deletions(-)
+
+commit f252cf80e194130d26ae3057227dc86dc60f8cb8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 12:03:51 2022 -0700
+
+    [open-type] Allow passing an offset to to_float()
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6ae35365f89e31dfc6ceeafdc47f302d040ffbf8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 11:43:38 2022 -0700
+
+    Fix build
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e957391efe2c00946ddf0586a710a4a4877981df
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 11:33:04 2022 -0700
+
+    [colr] Add NoVariable::varIdxBase
+
+ src/hb-ot-color-colr-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit e06de98c36200f7c6ff8939bb094960079521820
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 11:31:00 2022 -0700
+
+    [var-common] Make VarInstancer take an offset
+
+ src/hb-ot-color-colr-table.hh | 8 ++++----
+ src/hb-ot-var-common.hh       | 4 ++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 251f9f62134bf2b7050a4156dad9b0bb0968879f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 11:29:51 2022 -0700
+
+    [open-type] Add VarIdx::add()
+
+ src/hb-open-type.hh           |  5 +++++
+ src/hb-ot-color-colr-table.hh | 10 +++++-----
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+commit bf2ae3f0ca19c0e18741c39ca19fc2a88d2e972b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 11:26:24 2022 -0700
+
+    [open-type] Add static_assert for NO_VARIATION
+
+ src/hb-open-type.hh           | 1 +
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit d4496e640594ac26cef6f46a6f15f9ee55386eff
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 12:19:39 2022 -0500
+
+    COLRv1: Apply variations correctly
+    
+    The variations are for xMin, yMin, xMAx, yMax.
+    Apply them before converting to extents..
+
+ src/hb-ot-color-colr-table.hh | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+commit 193e0e3e8efc86215990d4e450ea90b723fda9b0
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 15 00:32:11 2022 -0500
+
+    Cosmetic: typo fix
+
+ src/hb-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b5acde43ed81f7c212b4a37aa06c3988bce168a1
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Dec 13 22:04:19 2022 +0000
+
+    [subset] check pending/subsetted tag sets for alloc failure.
+
+ src/hb-subset.cc                                          |   7 ++++++-
+ ...z-testcase-minimized-hb-subset-fuzzer-6164014466203648 | Bin 0 -> 191 bytes
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit 79285a9983983840d60d45220abb4d50cf08be05
+Author: Jordan Petridis <16531710+alatiera at users.noreply.github.com>
+Date:   Tue Dec 13 20:14:20 2022 +0200
+
+    VarC: cast ints (#3934)
+    
+    msvc is rightfully complaining that the types on the sides of
+    the ternary are not matching:
+    
+    ```
+    C:\pango\subprojects\harfbuzz\src\OT\glyf\VarCompositeGlyph.hh(317): error C2446: ':': no conversion from 'const OT::HBUINT16' to 'const OT::HBUINT8'
+    ```
+
+ src/OT/glyf/VarCompositeGlyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 300d82ce2ef1f30d8c9cd839801fe3b429c78d45
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 13 10:48:56 2022 -0700
+
+    Fix compiler warning
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 199345eb29ed821fed300b53000ced1d245c6ef2
+Merge: bd7cb384c 4e9a6cfb4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 18:37:10 2022 -0700
+
+    Merge pull request #3928 from harfbuzz/colrv1-extents
+    
+    COLRv1: use ClipBoxes for extents
+
+commit bd7cb384cf73cb88e3121f3b7ab89ce50a64e5bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 14:10:13 2022 -0700
+
+    [VarC] Remove unused variable
+
+ src/OT/glyf/VarCompositeGlyph.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 51d3ce39bab6270568706ef92d0f55d6d171ab2e
+Merge: 1b278c765 64cbe8b96
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 14:07:44 2022 -0700
+
+    Merge pull request #3933 from googlefonts/cff
+    
+    [subset] Fix infinite loop when instancing CFF fonts
+
+commit 1b278c76580351e52c98b7c8ffa22933cd25a59c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 13:57:05 2022 -0700
+
+    [VarC] Update for new format
+    
+    https://github.com/harfbuzz/boring-expansion-spec/issues/71
+
+ src/OT/glyf/VarCompositeGlyph.hh | 134 ++++++++++++++++++++++++++++++---------
+ 1 file changed, 103 insertions(+), 31 deletions(-)
+
+commit 64cbe8b96273ef2268111c03950610efe3f6e5e5
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 12 20:41:40 2022 +0000
+
+    [subset] Also note that only full instancing works.
+
+ src/hb-subset-input.cc | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 0da59f86a8b33672a3da31e3e2c4bf62fd4cac24
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 12 20:26:11 2022 +0000
+
+    [subset] note that CFF/CFF2 instancing is not yet supported.
+
+ src/hb-subset-input.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 9fbe52b88d07557197191b8080bdd591de4318b6
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 12 20:24:24 2022 +0000
+
+    [subset] enable instancing tests by default.
+
+ test/subset/data/Makefile.sources        |  8 ++++----
+ test/subset/generate-expected-outputs.py |  1 -
+ test/subset/meson.build                  | 15 ++++-----------
+ util/hb-subset.cc                        |  4 ----
+ 4 files changed, 8 insertions(+), 20 deletions(-)
+
+commit 38a962888512da088eb35ddee4f58c2a06392b73
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 12 20:13:17 2022 +0000
+
+    [subset] simplify handling of table subsetting depedencies.
+    
+    Allow the dependency checker to see all tables that will be subset. Use this to fix the HMTX/VMTX dep check against glyf. Don't delay hmtx/vmtx subsetting if no glyf table is present.
+
+ src/hb-subset.cc | 75 ++++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 40 insertions(+), 35 deletions(-)
+
+commit 0853e5d9d7bd15fc7782b111dcf9815d25c6d031
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 12 19:43:31 2022 +0000
+
+    [subset] if table dependencies can't be resolved fail the subset.
+    
+    Avoids getting stuck in an infinite loop.
+
+ src/hb-subset.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 6bb478eeeb665ddb1801a424679644b5b2b6c9e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 11:39:06 2022 -0700
+
+    [VarC] Clamp after addition
+
+ src/OT/glyf/VarCompositeGlyph.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 80a5011eb654275920aed8c08731b75e1a9a7bc9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 11:37:59 2022 -0700
+
+    [VarC] Fix coord setting
+    
+    Those are additive.
+
+ src/OT/glyf/VarCompositeGlyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4e9a6cfb49841d2293883a08e0aaae8481fbc27b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 10:20:51 2022 -0700
+
+    [COLR] Use VarStoreInstancer
+
+ src/hb-ot-color-colr-table.hh | 35 ++++++++++++++++-------------------
+ src/hb-ot-var-common.hh       |  2 ++
+ 2 files changed, 18 insertions(+), 19 deletions(-)
+
+commit a3a3d37b952201265b9f17e1ef58d1127f617210
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 10:17:20 2022 -0700
+
+    [var] Add VarStoreInstancer
+
+ src/hb-ot-var-common.hh | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit c64661b2f856341c399eea5bff10fca35db57f6b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 12 10:11:02 2022 -0700
+
+    [COLR] Fix variation code
+
+ src/hb-ot-color-colr-table.hh | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+commit ff332b14eae0ac122d7cfea90fb7d98e107dea92
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 21:05:14 2022 -0700
+
+    [COLR] Handle HB_OT_LAYOUT_NO_VARIATIONS_INDEX
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9a3f0be2911388e65e1e037e1c40ccfddc8b10bf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 13:40:53 2022 -0700
+
+    [COLR] Apply variations in get_extent
+
+ src/hb-ot-color-colr-table.hh | 36 +++++++++++++++++++++++++++++-------
+ src/hb-ot-layout-common.hh    |  8 ++++++++
+ 2 files changed, 37 insertions(+), 7 deletions(-)
+
+commit 68964efa553e77e0867777f4c4bfa5e962a9bda6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 13:21:01 2022 -0700
+
+    [COLR] Use bsearch in get_extents
+
+ src/hb-ot-color-colr-table.hh | 11 ++++++++---
+ src/hb-static.cc              |  2 ++
+ 2 files changed, 10 insertions(+), 3 deletions(-)
+
+commit d0ee5a452f057386d5dbffef1e8f7912fec8537c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 13:13:35 2022 -0700
+
+    [COLR] Return false from get_extents if table version not 1
+
+ src/hb-ot-color-colr-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit b3d6a5ef8644f7531e320fcfb98971ae56718c9a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 13:04:24 2022 -0700
+
+    [colr] Minor no behavior change
+
+ src/hb-ot-color-colr-table.hh | 21 +++++++++------------
+ 1 file changed, 9 insertions(+), 12 deletions(-)
+
+commit 7a748ad4acacd76b8c6285eab013a68813027997
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 10 19:59:03 2022 -0500
+
+    COLRv1: use ClipBoxes for extents
+    
+    This is a first step; ultimatively, we
+    should compute the extents is ClipBoxes
+    are missing.
+
+ src/hb-ot-color-colr-table.hh | 49 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-font.cc             |  4 ++++
+ 2 files changed, 53 insertions(+)
+
+commit d36a0f8c422cdabd5bb931a048a4c8515cd8b33d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 13:12:19 2022 -0700
+
+    [COLR] Add TODO
+
+ src/hb-ot-color-colr-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit a3068206817c7df57dc13b7c7b48a3e1c538fada
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 13:03:55 2022 -0700
+
+    [colr] Use SortedArray instead of Array
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b9d5e7a8bbc15ffdffd2a00c2ca8497cbed4d85a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 12:54:19 2022 -0700
+
+    [colr] Set HB_COLRV1_MAX_NESTING_LEVEL to 16
+    
+    Was 100. That seemed excessive.
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c17afa48deb932650cb6748328cbfe3b95c7126d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 12:53:55 2022 -0700
+
+    [colr] Remove COLRV1_ENABLE_SUBSETTING
+
+ src/hb-ot-color-colr-table.hh | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+commit 9ab2c8034ee137e84749b9aa2c197b2acec206aa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 11 12:00:54 2022 -0700
+
+    Revert "[glyf] Use component phantom points after transformation"
+    
+    This reverts commit a756bd1944404da6e53173c4061a2aef262e60f3.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3929
+
+ src/OT/glyf/Glyph.hh | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+commit 7f73b57bc1a64438b9a57e866a9ad055b7ef7f23
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 10 17:35:52 2022 -0700
+
+    [subset] Graduate L1 instancing API from experimental
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3926
+
+ docs/harfbuzz-sections.txt | 4 ++--
+ perf/benchmark-subset.cc   | 4 ----
+ src/gen-def.py             | 2 --
+ src/hb-subset-input.cc     | 6 ++----
+ src/hb-subset.h            | 4 ----
+ 5 files changed, 4 insertions(+), 16 deletions(-)
+
+commit 0f4e38cd865afedcb03ebc955f7c6e072415a09c
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Dec 10 16:39:26 2022 +0200
+
+    [subset] Small doc fixes
+
+ src/hb-subset-input.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit bf2e8175491126f7b7f471fb9739e84c623c8d2d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 23:15:26 2022 -0700
+
+    [VarComposites] Support GID24
+
+ src/OT/glyf/VarCompositeGlyph.hh | 36 ++++++++++++++++++++++--------------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+commit 8c641eeefb88659bf88a28dcd9cd7cf52aeb1d35
+Merge: e66d02126 10d38dcdf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 19:43:47 2022 -0700
+
+    Merge pull request #3841 from harfbuzz/varc
+    
+    [glyf] VariableComposites
+
+commit 10d38dcdfd7e0b62f35ac5ff1d6cdf9ce1a78cc2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 19:19:57 2022 -0700
+
+    [varc] Change format slightly
+    
+    Fixes https://github.com/harfbuzz/boring-expansion-spec/issues/70
+
+ src/OT/glyf/VarCompositeGlyph.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit af450a757d8471e55b71d1f3eb3c1e1fd3390d7b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 19:05:16 2022 -0700
+
+    [config] Use HB_EXPERIMENTAL_API instead of adhoc HB_EXPERIMENTAL
+
+ src/hb-config.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5cf0b9ae7d21cdce0c822ac1f6fb8de1e922aed8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 18:59:43 2022 -0700
+
+    [varc] Mark as experimental feature with HB_NO_VAR_COMPOSITES
+
+ src/OT/glyf/Glyph.hh | 4 ++++
+ src/hb-config.hh     | 1 +
+ 2 files changed, 5 insertions(+)
+
+commit 82b4f3791e1348273ebc8c13d410638842eef833
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 18:45:37 2022 -0700
+
+    [coord-setter] Don't modify font coords
+
+ src/OT/glyf/Glyph.hh        |  4 ++--
+ src/OT/glyf/coord-setter.hh | 33 +++++++++------------------------
+ 2 files changed, 11 insertions(+), 26 deletions(-)
+
+commit e9e503b80bba01d42b0987bab4dc240db6368e8f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 18:42:46 2022 -0700
+
+    [Glyph] Pass down coords to get_points
+
+ src/OT/glyf/Glyph.hh | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+commit 8e46870093fe9c214679370bdf34dbd67f388d18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 18:35:30 2022 -0700
+
+    [gvar] Take coords in instead of font in apply_deltas_to_points
+
+ src/OT/glyf/Glyph.hh        | 4 +++-
+ src/hb-ot-var-gvar-table.hh | 6 +++---
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+commit 3caa42a4a7b4879162d19273441c2cc8b44e3142
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 9 14:48:41 2022 -0700
+
+    Fix build after rebase
+
+ src/OT/glyf/Glyph.hh             | 2 +-
+ src/OT/glyf/VarCompositeGlyph.hh | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit bbe59e4211c6dbff929320c7a4332289353cf666
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 8 16:04:19 2022 -0700
+
+    Whitespace
+
+ src/OT/glyf/Glyph.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 13deea7cbd5becb0746585177b9d67e0a52516e7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 18 13:38:12 2022 -0600
+
+    [glyf/VarComposite] Clamp axis coordinates
+
+ src/OT/glyf/VarCompositeGlyph.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a975be4c072b4370ee5efad5409b0b88e818259d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 18 11:00:35 2022 -0600
+
+    [glyf/VarComposite] Minor rename
+
+ src/OT/glyf/Glyph.hh             | 2 +-
+ src/OT/glyf/VarCompositeGlyph.hh | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 1e71db2d264ebf9d86a43dc3378b653b8e5907ea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 18 10:47:32 2022 -0600
+
+    [glyf/VarComposite] Fix transformation
+
+ src/OT/glyf/VarCompositeGlyph.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 1233be61d89b876dee6901137a02b4d7ee7a0e13
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 17 14:06:44 2022 -0600
+
+    [glyf/VarComposite] Remove unneeded resize
+
+ src/OT/glyf/Glyph.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 1a906162cb5d2445975cc571bc808e025f31b5d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 17 14:01:34 2022 -0600
+
+    [glyf/coord-setter] Fix memory issue
+
+ src/OT/glyf/coord-setter.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 7efd68da390f5cd125a1dd3a187ae28bbfb282e0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 17 13:05:22 2022 -0600
+
+    [glyf/VarComposite] Set coordinates
+    
+    Code is untested but complete!
+
+ src/OT/glyf/Glyph.hh             |  3 ++-
+ src/OT/glyf/VarCompositeGlyph.hh | 16 ++++++++++++++++
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+commit 4ec77814978b675d0aa74e869c24abc8b5270678
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 17 12:53:58 2022 -0600
+
+    [glyf] Move coord-setter to its own file
+
+ src/Makefile.sources             |  1 +
+ src/OT/glyf/Glyph.hh             | 29 +-------------------------
+ src/OT/glyf/VarCompositeGlyph.hh |  1 +
+ src/OT/glyf/coord-setter.hh      | 45 ++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 48 insertions(+), 28 deletions(-)
+
+commit dadb4ed71de2da768ee4f07a3b595181813fb0f4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 17 12:48:24 2022 -0600
+
+    [glyf/VarComposite] More, almost there
+
+ src/OT/glyf/Glyph.hh             | 18 ++++++++-----
+ src/OT/glyf/VarCompositeGlyph.hh | 58 +++++++++++++++++++++++++++++++++-------
+ 2 files changed, 60 insertions(+), 16 deletions(-)
+
+commit 0a939b48a60bc5b5cae0d3a5774218f1143b6759
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 17 12:12:40 2022 -0600
+
+    [glyf/VarComposite] Implement more
+
+ src/OT/glyf/Glyph.hh             | 49 +++++++++++++++++++++++++++++++++++++---
+ src/OT/glyf/VarCompositeGlyph.hh |  8 +++++--
+ 2 files changed, 52 insertions(+), 5 deletions(-)
+
+commit 65cc3b5e2b2181e82836c85ea060b2bd8c59ff49
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 13 17:11:12 2022 -0600
+
+    [glyf/VarComposite] More
+
+ src/OT/glyf/VarCompositeGlyph.hh | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+commit 12688ed3865fcbfcd34dd5c1c4ab3ca3bfc63e42
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 13 17:06:07 2022 -0600
+
+    [glyf] Fix distcheck
+
+ src/Makefile.sources | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 60d959a6e7b73ce6492fb1b49b91aefe81ad99a5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 13 14:15:36 2022 -0600
+
+    [glyf/VarComposite] Add use_my_metrics()
+
+ src/OT/glyf/VarCompositeGlyph.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 575d99406a5e40eab04b9d6c5c3a970b674b1753
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 13 13:12:26 2022 -0600
+
+    [glyf] Flesh out VarCompositeGlyph
+
+ src/OT/glyf/VarCompositeGlyph.hh | 218 +++++++++++++++++++++++----------------
+ src/hb-open-type.hh              |   3 +
+ 2 files changed, 132 insertions(+), 89 deletions(-)
+
+commit 21f671bc453ba42b03402774a7e07fa0d3733099
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 13 11:25:29 2022 -0600
+
+    [glyf] Add stub VarCompositeGlyph
+
+ src/OT/glyf/Glyph.hh             |   1 +
+ src/OT/glyf/VarCompositeGlyph.hh | 157 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 158 insertions(+)
+
+commit 435c5eeffec54fe48e190699532ec063c0a12c3a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 13 10:54:58 2022 -0600
+
+    [glyf] Split composite-iter
+
+ src/OT/glyf/CompositeGlyph.hh | 51 ++------------------------------
+ src/OT/glyf/composite-iter.hh | 68 +++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 70 insertions(+), 49 deletions(-)
+
+commit 1024a013fd62eddc65c092f6fb2ff2fae176a618
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Aug 22 09:49:30 2022 -0600
+
+    [glyf] Add CoordSetter
+
+ src/OT/glyf/Glyph.hh | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+commit e66d02126e876ab01d0dacd1f22540106a27d7ec
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Dec 8 22:56:07 2022 +0000
+
+    [subset] replace subset-processing.md reference with link to it on github.
+
+ src/hb-subset-input.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 27201ed32b37d3956b15859e76db1be4ab32d7d5
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Dec 8 22:48:27 2022 +0000
+
+    [subset] fix up hb_subset_preprocess api comment.
+
+ docs/harfbuzz-sections.txt   | 2 +-
+ docs/subset-preprocessing.md | 2 +-
+ src/hb-subset-input.cc       | 8 +++++---
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+commit 13b038835122c6eba53db15d33a02f898ce369a3
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Dec 7 22:53:44 2022 +0000
+
+    [subset] link to preprocessing doc from api comment.
+
+ docs/subset-preprocessing.md | 6 ++++--
+ src/hb-subset-input.cc       | 2 ++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit c097abab52c51568f40b443576dbe030ff3cae89
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Dec 7 22:50:09 2022 +0000
+
+    [subset] set no prune unicode ranges flag in preprocessor.
+    
+    To avoid modifying the original unicode range values in the source font.
+
+ src/hb-subset-input.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 8c021462e6a7c52beb20906b595be52d526d5976
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Dec 7 22:44:50 2022 +0000
+
+    [subset] Add short document on subset preprocessing.
+
+ docs/subset-preprocessing.md | 226 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 226 insertions(+)
+
+commit bc87fe952e62624464933913bcba5874b49379a9
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Dec 7 21:43:14 2022 +0000
+
+    [subset] add note about memory management with preprocessed faces.
+
+ src/hb-subset-input.cc | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 5e713e99bf5121a7d0cd2341c40db3d79bd09879
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 5 23:57:57 2022 +0000
+
+    Revert "[map] Speed up is_real()"
+    
+    This reverts commit f5307c3ba8401fbaf9008705d7f8dfa7d28e944c.
+    
+    Found to slow down the benchmarks in some cases.
+
+ src/hb-map.hh | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+commit eda02c2ebd6527f9072e3488ef8c675e4d85a720
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 5 20:18:41 2022 +0000
+
+    [subset] Move hb_subset_preprocess to be non-experimental.
+
+ perf/benchmark-subset.cc |  4 ----
+ src/gen-def.py           |  1 -
+ src/hb-subset-input.cc   |  6 ++----
+ src/hb-subset.h          |  7 +++----
+ test/subset/run-tests.py | 11 ++++++++---
+ util/hb-subset.cc        |  4 ----
+ 6 files changed, 13 insertions(+), 20 deletions(-)
+
+commit 76d5482a7c6bfc1b10de0b925c229a9cdd220977
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 5 19:40:49 2022 +0000
+
+    [subset] always return a valid face from hb_subset_preprocess.
+
+ src/hb-subset-input.cc | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit a80cae445369ad7feafbca2398601238df8e7e65
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Dec 8 11:17:47 2022 +0200
+
+    [doc] Add missing symbols to harfbuzz-sections.txt
+
+ docs/harfbuzz-sections.txt | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 41edf95893f616c8a518f4853aba6f28c423d056
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Dec 8 11:01:04 2022 +0200
+
+    [doc] Fix sorting
+    
+    * Keep setters and getters together, with setters first.
+    * Keep common functions at the top and in a predictable order.
+    * Put callback functions right above their setters.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3352
+
+ docs/harfbuzz-sections.txt | 411 ++++++++++++++++++++++-----------------------
+ 1 file changed, 205 insertions(+), 206 deletions(-)
+
+commit 35233d2514cc202e9e2f8f94b3102cb620a0d403
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Dec 7 00:47:28 2022 +0000
+
+    [repacker] fix fuzzer reported stack overflow.
+    
+    Fixes https://oss-fuzz.com/testcase-detail/6014493291577344.
+
+ src/graph/graph.hh                                        |   5 +++++
+ src/hb-repacker.hh                                        |   8 ++++++++
+ ...testcase-minimized-hb-repacker-fuzzer-6014493291577344 | Bin 0 -> 921 bytes
+ 3 files changed, 13 insertions(+)
+
+commit b17fbc200bee7b1898862bdb13e46387d0057b38
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 5 20:34:51 2022 +0000
+
+    [repacker] use memcpy to avoid alignment issues.
+
+ test/fuzzing/hb-repacker-fuzzer.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f1d3489388a48a2dcde35bb1872abd1d7aafa192
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 5 19:33:15 2022 +0000
+
+    [repacker] bail on failure  to alloc assigned_bytes set.
+    
+    Fixes fuzzer issue https://oss-fuzz.com/testcase-detail/5390364397928448.
+
+ src/graph/graph.hh                                        |   3 ++-
+ ...testcase-minimized-hb-repacker-fuzzer-5390364397928448 | Bin 0 -> 423 bytes
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit 239a5aca022926d89291701ad9547ac4477c86d6
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 5 19:15:36 2022 +0000
+
+    [repacker] don't allow references to the null object in graph.
+    
+    Fixes fuzzer issue https://oss-fuzz.com/testcase-detail/6714085985353728
+
+ src/graph/graph.hh                                     |   7 ++++---
+ ...tcase-minimized-hb-repacker-fuzzer-6714085985353728 | Bin 0 -> 358596 bytes
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit 4ce0f088978b20b8ef431426faa16dee253a5ea0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 31 12:20:19 2022 -0600
+
+    [coretext] Clamp variation settings to min/max
+    
+    Like our native implementation does; CoreText doesn't itself.
+    
+    Also fix leak of CFNumber's.
+
+ src/hb-coretext.cc | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit 1b867530314e8efe3a67377ac25b04ca2e71e90e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 5 11:44:52 2022 -0700
+
+    [hb-subset] Support -u, -g, -t
+    
+    For --unicodes, --gids, --text.
+
+ util/hb-subset.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 22b0390e2dcefcf737d70f8d965d99b902831a29
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 5 09:43:36 2022 -0700
+
+    Revert "[VarData] Don't clear memory we are going to fill in completely"
+    
+    This reverts commit e28e2dad03a453c5e5c4c5a9d6fd276182c5f80b.
+    
+    This made fuzzer unhappy. I'm not sure how.
+    
+    https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54044
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3c497e2458d358748d0e85f5e3afb9d9e33e717c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 15:35:01 2022 -0700
+
+    [harfbuzz-subset.cc] Revert accidental change
+    
+    These extra files are unnecessary, but our generator currently
+    isn't smart enough to know that. Will fix some time.
+
+ src/harfbuzz-subset.cc | 40 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+commit aa7f5e3742bc737f727a3c62a9884ed12cdb87fa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 15:31:47 2022 -0700
+
+    [subset] Conditionalize call to hb_font_set_variations
+
+ src/OT/glyf/glyf.hh    |  2 ++
+ src/harfbuzz-subset.cc | 40 ----------------------------------------
+ src/hb-subset-plan.cc  |  2 ++
+ 3 files changed, 4 insertions(+), 40 deletions(-)
+
+commit ad5588e80046ea2f5108d21c583a1ecf12efeb82
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 15:27:59 2022 -0700
+
+    [config] If HB_NO_SHAPER then HB_NO_OT_SHAPE
+
+ src/hb-config.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 1a5c749581a9d7d19ab94250599c6e2700660fee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 15:20:51 2022 -0700
+
+    [config] Flesh out HB_NO_SHAPER a bit more
+
+ src/hb-face.cc       | 2 ++
+ src/hb-face.hh       | 2 ++
+ src/hb-shape-plan.cc | 5 +++++
+ src/hb-shape.cc      | 5 +++++
+ 4 files changed, 14 insertions(+)
+
+commit 2c0abf02580ba109abcd6fb1da890f8b7500a9b1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 15:03:36 2022 -0700
+
+    Revert "[harfbuzz-subset.cc] Trim down!"
+    
+    This reverts commit a335458d5776135f8672bfc98681b8862f657d5c.
+    
+    While this can be vastly trimmed down, what I did is not right.
+    It still depends on hb-face, hb-font, hb-blob, hb-set, and hb-map.
+
+ src/harfbuzz-subset.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ src/meson.build        |  2 +-
+ 2 files changed, 46 insertions(+), 1 deletion(-)
+
+commit a335458d5776135f8672bfc98681b8862f657d5c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 14:56:20 2022 -0700
+
+    [harfbuzz-subset.cc] Trim down!
+
+ src/harfbuzz-subset.cc | 45 ---------------------------------------------
+ src/meson.build        |  2 +-
+ 2 files changed, 1 insertion(+), 46 deletions(-)
+
+commit 765a3551da9c05ad6b2868a703ddf50fd84630cd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 14:48:32 2022 -0700
+
+    [face-builder] Minor cast
+
+ src/hb-face.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3fff6d9084e92642f4e13e54e9720c682d5d2bc5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 14:47:38 2022 -0700
+
+    [face-builder] Initialize face orders to -1
+
+ src/hb-face.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 805ce9ad3d3254e4b8dde113cdf914aebb533482
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 14:43:17 2022 -0700
+
+    [face-builer] Protect against wrong face
+    
+    In hb_face_builder_sort_tables.
+
+ src/hb-face.cc | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit 0acfd2b714ad15167c882c1c5be3a650db24e748
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 14:01:05 2022 -0700
+
+    [indic-machine] Regenerate line numbers
+
+ src/hb-ot-shaper-indic-machine.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 9704f8354e92c86aaaec7dc736463091e421b03c
+Merge: 0545949f0 c1aae14a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 13:58:52 2022 -0700
+
+    Merge branch 'config-header'
+
+commit c1aae14a68eaea92c4de20e372cfca05c66c50b1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 13:53:55 2022 -0700
+
+    [features.h] Fix autotools build rules
+
+ src/Makefile.am | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+commit 0545949f018cf48743052de878bfabbb95b4d1d6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 12:44:09 2022 -0700
+
+    [gvar] Minor use array get_size()
+
+ src/hb-ot-var-gvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1bd386515c603a1e77291f77e50dc7cb3437dbcd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 12:29:23 2022 -0700
+
+    [bit-set] Micro-optimize page_for
+
+ src/hb-bit-set.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit b182e2808af51a04b72951781fe21c3e2301e827
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 12:22:17 2022 -0700
+
+    [bit-set] Don't clear pages when copying set
+
+ src/hb-bit-set.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit f5307c3ba8401fbaf9008705d7f8dfa7d28e944c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 11:54:16 2022 -0700
+
+    [map] Speed up is_real()
+
+ src/hb-map.hh | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+commit 301f6e4b47f0ce40758a773cc351f98564eda02c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 11:46:10 2022 -0700
+
+    [Coverage] Remove TODO
+
+ src/OT/Layout/Common/CoverageFormat2.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit dbbb8e8006ea71519546105f229ce635105bf855
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 11:13:39 2022 -0700
+
+    Revert "[map] Add hb_map_filter_invalid"
+    
+    This reverts commit 8d7e92111786b21906157127c24b72b1e444e6e7.
+    
+    Surprisingly this slowed NotoNastaliqUrdu benchmark down by a couple
+    percent instead of speeding it up.
+
+ src/OT/Layout/Common/Coverage.hh | 2 +-
+ src/hb-map.hh                    | 2 --
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+commit 8d7e92111786b21906157127c24b72b1e444e6e7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 4 11:01:45 2022 -0700
+
+    [map] Add hb_map_filter_invalid
+    
+    Use it in one place.
+
+ src/OT/Layout/Common/Coverage.hh | 2 +-
+ src/hb-map.hh                    | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit 260df1fa326c6c19d35e030f78d24e2342cb7370
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sun Dec 4 12:25:22 2022 -0500
+
+    [indic] Support <U+0A02, U+0A40>
+
+ src/gen-indic-table.py                             |  11 +-
+ src/hb-ot-shaper-indic-machine.hh                  | 610 +++++++++++----------
+ src/hb-ot-shaper-indic-machine.rl                  |   3 +-
+ src/hb-ot-shaper-indic-table.cc                    |   7 +-
+ src/hb-ot-shaper-indic.cc                          |  14 +-
+ .../5f73fff1ffc07b5a99a90c0909609f2b09fef274.ttf   | Bin 0 -> 1028 bytes
+ .../data/in-house/tests/indic-special-cases.tests  |   2 +
+ 7 files changed, 349 insertions(+), 298 deletions(-)
+
+commit 8b533763c07f565c1b31505351bf3b51088a62a3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 15:58:12 2022 -0700
+
+    Use hb_len() instead of .len()
+
+ src/hb-open-type.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit e28e2dad03a453c5e5c4c5a9d6fd276182c5f80b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 15:56:43 2022 -0700
+
+    [VarData] Don't clear memory we are going to fill in completely
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0e13b4abbc90574fb3a2c7c87070fc3908b7d4ea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 15:50:24 2022 -0700
+
+    [VarData] Optimize main loop slightly
+
+ src/hb-ot-layout-common.hh | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+commit ad17c0acce14995bcbd67ff18532c6c4283ff9d0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 14:56:57 2022 -0700
+
+    [VarData] Whitespace
+
+ src/hb-ot-layout-common.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit e7eb445d29076f4d5cf9d7d7d09d40288eaf9186
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 14:56:00 2022 -0700
+
+    [VarData] Optimize longWord calculation
+
+ src/hb-ot-layout-common.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit f2c980be2998a909486a4a40515763a57b03846b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 14:49:38 2022 -0700
+
+    [VarData] Optimize wordCount calculation
+    
+    6% speedup in RobotoFlex-Variable/900 benchmark.
+
+ src/hb-ot-layout-common.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 3641b0e01ec46a06cd684c48262680ac74194393
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 14:26:21 2022 -0700
+
+    [VarData] Optimize serialize()
+
+ src/hb-ot-layout-common.hh | 39 +++++++++++++++++++++++++++++++--------
+ 1 file changed, 31 insertions(+), 8 deletions(-)
+
+commit e155f1230702afb6b81b2c2901087945e5d4d249
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 14:14:39 2022 -0700
+
+    [VarData] Minor save a variable
+
+ src/hb-ot-layout-common.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 5596a7308752b619d9417735c8f8718b09ec9a34
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 13:33:48 2022 -0700
+
+    [layout] Speed up ClassDefFormat2 intersects
+
+ src/hb-ot-layout-common.hh | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit 85e7263b38db4a42c56cb7e7d81564576e5607a5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 13:28:02 2022 -0700
+
+    [VariationStore] Minor access array directly
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 41a8597f38b7ebcad3c599105f12104e106d5873
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 13:23:26 2022 -0700
+
+    [layout] Simplify CoverageFormat2 intersects_coverage()
+
+ src/OT/Layout/Common/CoverageFormat2.hh | 18 +++---------------
+ 1 file changed, 3 insertions(+), 15 deletions(-)
+
+commit 1f4d8ccaedfce035567f43fbb47597151bdf89a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 13:17:15 2022 -0700
+
+    [CoverageFormat2] Optimize intersects()
+
+ src/OT/Layout/Common/CoverageFormat2.hh | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit c482b061081a77e8ca085ade01c951406c5d554d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 13:14:31 2022 -0700
+
+    [gpos] Optimize PairPosFormat1::intersects
+
+ src/OT/Layout/GPOS/PairPosFormat1.hh | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+commit 58e9df132fd5db88667bb71a7538358d4109ce33
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 13:04:00 2022 -0700
+
+    [Device] Serialize VariationDevice zerocopy
+
+ src/hb-ot-layout-common.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 071a2bb4f7e433eabb21e38cd560cc4dcfacab7d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 13:03:38 2022 -0700
+
+    [serialize] Support zerocopy while sharing
+
+ src/hb-serialize.hh | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+commit 44a5de3a97c6092547d4994c7b10922fbdce15b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 12:50:32 2022 -0700
+
+    [Device] Save a snap/revert
+
+ src/hb-ot-layout-common.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit 93328cedfc6e55e78f86db1026f4f1b98dd84501
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 12:49:26 2022 -0700
+
+    [Device] Save a map get()
+
+ src/hb-ot-layout-common.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 630b874ae6f54d7c1705ec1c16599d476b8c1c69
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 12:13:15 2022 -0700
+
+    [gsubgpos] Add a cache to intersected_class_glyphs
+    
+    30% gain on subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/1400.
+
+ src/hb-ot-layout-gsubgpos.hh | 72 +++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 54 insertions(+), 18 deletions(-)
+
+commit c044f4af3e3e513e42ffd1b48b7b0b4af7633953
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 11:58:04 2022 -0700
+
+    [gsubgpos] Remove wrong const
+
+ src/hb-ot-layout-gsubgpos.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 2680be1f22e7446fb6da04e99716dc08a112d0c2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 11:53:14 2022 -0700
+
+    [gsubgpos] Don't set unnecessary funcs
+
+ src/hb-ot-layout-gsubgpos.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 023f595dec2b9c0cbc91a6b63a594e9041f1006e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 11:18:05 2022 -0700
+
+    [cmap] Speed up DefaultUVS::copy even more
+    
+    Another 14% on SourceHanSerifVF/10 benchmark.
+
+ src/hb-ot-cmap-table.hh | 81 +++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 59 insertions(+), 22 deletions(-)
+
+commit 4ca610510805764433eea47a4f991aaf059bd9ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 11:15:06 2022 -0700
+
+    [cmap] Remove double-min
+
+ src/hb-ot-cmap-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cd29147e30df819850b9f257bc1bd69470741ed4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 10:41:42 2022 -0700
+
+    [cmap] Minor cast
+
+ src/hb-ot-cmap-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4cdb5cc69b6110fe28b9e01d9c3e4e8f4a8b3272
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 10:40:24 2022 -0700
+
+    [cmap] Minor change iterator
+
+ src/hb-ot-cmap-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2cdaedaf543375a54f0810cf5b2b2a535fd85d3b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 10:16:35 2022 -0700
+
+    Use hb_enumerate in more places
+
+ src/graph/markbasepos-graph.hh |  4 ++--
+ src/hb-ot-var-fvar-table.hh    | 10 +++++-----
+ src/hb-subset-plan.cc          |  6 ++----
+ 3 files changed, 9 insertions(+), 11 deletions(-)
+
+commit 02bc4dd69bc5dc8d11de1404e6531b35e233dd39
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 10:07:16 2022 -0700
+
+    Use hb_enumerate instead of hand-coding
+
+ src/hb-ot-layout-common.hh | 46 ++++++++++++++++++++--------------------------
+ 1 file changed, 20 insertions(+), 26 deletions(-)
+
+commit 4d19c724c0423892810eefe8b9d9c6efcf274ddd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 09:57:29 2022 -0700
+
+    [CoverageFormat1] Speed up intersects()
+    
+    Speeds up SourceHanSerif/10000 benchmark (not in test suite) by
+    32%!
+
+ src/OT/Layout/Common/CoverageFormat1.hh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit a2d33779e1f582e06c89549090ba95251c04be13
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 09:49:00 2022 -0700
+
+    Fix arm bot build
+
+ src/hb-ot-cmap-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit dabbf13d402620e605ad497b58dbfb61aed28a3d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 3 09:46:11 2022 -0700
+
+    [cmap] Speed up DefaultUVS::copy
+
+ src/hb-ot-cmap-table.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 8eadb83640b0f027639d80a10071ad4ae3ab6c47
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Nov 10 10:33:26 2022 -0800
+
+    [subset] Update hb_subset_input_override_name_table API
+    
+    Override the name string for the NameRecord identified by name_id,
+    platform_id, encoding_id and language_ids specified by the user.
+    If a record with specified name_id does not exist, this API will create
+    a new NameRecord with provided info and insert it to the name table.
+
+ src/hb-ot-name-table.hh                     | 154 ++++++++++++++++++++++------
+ src/hb-subset-input.cc                      |  69 +++++++++----
+ src/hb-subset-input.hh                      |  44 +++++++-
+ src/hb-subset-plan.cc                       |  10 +-
+ src/hb-subset-plan.hh                       |  10 +-
+ src/hb-subset.h                             |   5 +-
+ test/api/fonts/nameID.override.expected.ttf | Bin 167936 -> 168012 bytes
+ test/api/test-subset-nameids.c              |  14 ++-
+ 8 files changed, 237 insertions(+), 69 deletions(-)
+
+commit 29903f46b92db764ba8e6b6422c2128c011c7223
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 17:45:01 2022 -0700
+
+    [benchmark-subset] Cache (preprocessed) face amongst runs
+
+ perf/benchmark-subset.cc | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+commit 3fb4ea29cd5a40e76760668e694133fa095e8d55
+Merge: a42fc8ec4 ddeac3658
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 17:08:31 2022 -0700
+
+    Merge pull request #3914 from harfbuzz/multimap
+    
+    [multimap] Add a multimap datastructure & use for gid-to-unicodes subset accelerator
+
+commit ddeac3658b46a6536a67b06b8bc8f3efd9ce5f6f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 16:51:07 2022 -0700
+
+    [test-multimap] More tests
+
+ src/test-multimap.cc | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit ff419789efb2a7b8f997fbd8d87bea738f2a6c59
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 16:25:26 2022 -0700
+
+    [subset-plan] Sort unicode_to_new_gid_list when needed
+
+ src/hb-algs.hh        | 12 ++++++++++++
+ src/hb-subset-plan.cc |  7 ++++++-
+ src/hb-subset-plan.hh |  2 +-
+ 3 files changed, 19 insertions(+), 2 deletions(-)
+
+commit 1a40da4ad1a8896f65a99838d5251613ecc8e350
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 16:13:37 2022 -0700
+
+    [subset-plan] Use add_array instead of add_sorted_array
+    
+    That vector is not declared as sorted.
+
+ src/hb-subset-plan.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 32e049a315a1f1d6e2f751f1f93472134fec8f00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 16:09:10 2022 -0700
+
+    [subset-plan] Use gid-to-unicodes multimap
+    
+    One test fails. Need investigation.
+
+ src/hb-subset-plan.cc | 37 +++++++++++++++++++++++++++++++------
+ 1 file changed, 31 insertions(+), 6 deletions(-)
+
+commit da7961b2e879aab88fedda7cd0c9e2de4c3240a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 16:08:40 2022 -0700
+
+    .
+
+ src/hb-multimap.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7d6893a8034230458ba22f677d54e67c68b1508a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 15:50:52 2022 -0700
+
+    [subset-accelerator] Cache gid-to-unicodes
+
+ src/hb-subset-accelerator.hh | 15 +++++++++++----
+ src/hb-subset-plan.cc        | 12 ++++++++++++
+ 2 files changed, 23 insertions(+), 4 deletions(-)
+
+commit 10c8fc55535e679a75f6f3012273f256e0416d90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 15:34:34 2022 -0700
+
+    [multimap] Add a multimap datastructure
+
+ src/Makefile.am      |  5 +++
+ src/Makefile.sources |  1 +
+ src/hb-multimap.hh   | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/meson.build      |  2 ++
+ src/test-multimap.cc | 50 ++++++++++++++++++++++++++++
+ 5 files changed, 150 insertions(+)
+
+commit a42fc8ec4a55adce3a935fb40183f388ff376f8a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 15:41:18 2022 -0700
+
+    [subset-accelerator] Adjust in_error()
+
+ src/hb-subset-accelerator.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 65d9630312e277dc464122ae60ce877634ad1820
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 14:59:26 2022 -0700
+
+    [subset-cff2] Whitespace
+
+ src/hb-subset-cff2.cc | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit b33297ee26a3965e172ec13d1297eef11783c0c2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 14:43:37 2022 -0700
+
+    [cff2] Remove unused typedef
+
+ src/hb-cff2-interp-cs.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 3ade2ffaa58d639bc825dbeee8aa1d0033ed668b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 14:26:36 2022 -0700
+
+    [serialize] Adjust pop_discard for zerocopy
+
+ src/hb-serialize.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 043eeb29a3913ff92879c35d410669da3574af18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 13:58:36 2022 -0700
+
+    [subset-cff] Optimize encode_subrs
+    
+    Don't loop over all original subrs. Just walk over closure subrs.
+
+ src/hb-subset-cff-common.hh | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+commit 0ad5977cd6679f7d0f19e255d78eaf14ecc4e116
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 13:41:06 2022 -0700
+
+    [subset-cff] Simplify hinting processing
+    
+    We already have drop_hints in the params.
+
+ src/hb-subset-cff-common.hh | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+commit 16cbe41bcaefb9ba1634f781adb7357f8006f645
+Merge: 2a7a1d5a7 16f61a1c8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 12:43:13 2022 -0700
+
+    Merge pull request #3910 from googlefonts/repacker_fuzz
+    
+    [repacker] Add a fuzzer for the hb-subset-repacker api.
+
+commit 2a7a1d5a73f2bd337c69a381d8592a7633113793
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 2 12:33:24 2022 -0700
+
+    [Coverage] Avoid timeout on broken ranges
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53929
+
+ src/OT/Layout/Common/CoverageFormat2.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit c9476527689bd5f061584ba83e1298dd8be3549f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 21:48:35 2022 -0700
+
+    [subset-cff] Micro-optimize
+
+ src/hb-subset-cff-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a24d4e9261ccd280e874177e6d21bdf40dd6d76d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 20:27:56 2022 -0700
+
+    [array] Oops. Fix memcpy copy()!
+
+ src/hb-array.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5e41766bb92d7b58ededf40e1e031b4690464f48
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 20:19:04 2022 -0700
+
+    [array] Fix hb_bytes_t memcpy copy
+    
+    Wasn't being used!
+
+ src/hb-array.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a5616227caf44c5fdcdea3c8f8336808d5b0087b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 20:11:34 2022 -0700
+
+    [subset-cff] Fix buffer size calculation
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 015af5a8e5bbcfbc63328a1196318621ed21e1e7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 20:08:59 2022 -0700
+
+    [subset-cff] Write a couple loops as range-based for
+
+ src/hb-subset-cff-common.hh | 24 +++++++++---------------
+ 1 file changed, 9 insertions(+), 15 deletions(-)
+
+commit bfbbd4af253a2ac58bb8bcdcde650fcba9636038
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 20:05:20 2022 -0700
+
+    [subset-cff] Copy str for call ops
+
+ src/hb-subset-cff-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c755b3884f40595340fe3de615faf8c17842c667
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 20:02:38 2022 -0700
+
+    [subset-cff] Pre-alloc enough for check-less copy
+
+ src/hb-subset-cff-common.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 062e59ae673d645c4b072938a40af7f3931ccaca
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 19:43:48 2022 -0700
+
+    [subset-cff] Optimize vector allocation for preprocessed input
+
+ src/hb-subset-cff-common.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 8e9e94dba971e3b09d4a9853a8abcf68d5c6dc62
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 19:40:21 2022 -0700
+
+    Revert "[vector] Optimize grow_vector() for size"
+    
+    This reverts commit 1dd9396c7a4c24fe9d578551fab735bdd699e52a.
+    
+    Is faster indeed.
+    
+    15% on SourceHanSans/10000 benchmark.
+
+ src/hb-vector.hh | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 2644540a74c19a32fbe3fe904b1266163b8ff2a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 18:49:09 2022 -0700
+
+    [subset-cff] Compact parsed strings if using accelerator
+    
+    Saves 32% on SourceHanSans/10000 benchmark!
+    
+    Also, use memcmp now for writing out strings since now that our
+    ops are not super short, that's faster.
+    
+    This makes cff-japanese test takes super long though; that needs
+    inspection.
+
+ src/hb-subset-cff-common.hh | 55 ++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 45 insertions(+), 10 deletions(-)
+
+commit 6012d3b228bc30397ab46eda48776fb414043315
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 17:33:53 2022 -0700
+
+    [subset-cff] Write out charstrings zerocopy to serializer
+
+ src/hb-serialize.hh   | 21 +++++++++++++++++----
+ src/hb-subset-cff1.cc |  8 +++++++-
+ src/hb-subset-cff2.cc |  8 +++++++-
+ 3 files changed, 31 insertions(+), 6 deletions(-)
+
+commit 16f61a1c87f83ac750bdf529917519593a9ef58e
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Dec 1 23:57:30 2022 +0000
+
+    [repacker] only build repacker fuzzer when experimental api is enabled.
+
+ test/fuzzing/meson.build | 35 +++++++++++++++++++++--------------
+ 1 file changed, 21 insertions(+), 14 deletions(-)
+
+commit 36e1a6339cb0a9bd9ec6e76b64ae83ec871d2f8f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 16:52:29 2022 -0700
+
+    [cff] Add total_size to INDEX
+
+ src/hb-ot-cff-common.hh | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+commit 3843000660d587d81d3f71bfd8a1e76939847b86
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 16:48:22 2022 -0700
+
+    [serialize] Add start_zerocopy()
+
+ src/hb-serialize.hh | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+commit de5a621322a749e96333656a86137a6ee42490b3
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Dec 1 23:37:16 2022 +0000
+
+    [repacker] enforce root node having no incoming edges.
+
+ src/graph/graph.hh                                     |   8 ++++++++
+ .../crash-3bf72494aa4c9f8cbbcbf887fdc2a2858c87feb4     | Bin 0 -> 358596 bytes
+ 2 files changed, 8 insertions(+)
+
+commit a2681c37c171143858ade2f91c9eff876c0aa586
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 16:09:03 2022 -0700
+
+    [cff-subset] Simplify INDEX serialize() more
+
+ src/hb-ot-cff-common.hh | 21 ++++++---------------
+ src/hb-ot-cff1-table.hh |  2 --
+ 2 files changed, 6 insertions(+), 17 deletions(-)
+
+commit c4b05878cbca0b710485c5ea749d8e5e69166aef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 15:56:37 2022 -0700
+
+    [subset-cff] Remove INDEX unused serialize() methods
+
+ src/hb-ot-cff-common.hh | 61 -------------------------------------------------
+ 1 file changed, 61 deletions(-)
+
+commit b3ad4d72cced348ff5a169ef59b28c13b5f09741
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 15:46:00 2022 -0700
+
+    [cff] Another no-memset in INDEX
+
+ src/hb-ot-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5fd2f255fc4bd749d583cf98dc1788e69f40acd6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 15:18:59 2022 -0700
+
+    [open-type] Don't memset 0 in serialize for ArrayOf family
+    
+    Not necessary.
+
+ src/hb-open-type.hh | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit 30e405e470f002693b353db5a1bb90504ba01b2a
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Dec 1 22:12:59 2022 +0000
+
+    [repacker] ensure link obj indices are valid.
+
+ src/graph/graph.hh                                     |  11 +++++++++--
+ .../leak-a77f29b25edb873729f3ab120148fdb213cfa527      | Bin 0 -> 358596 bytes
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+commit 70ac6dfb28e7ec921ab03467dd84e7c9103d87c5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 14:56:28 2022 -0700
+
+    [subset-cff] Don't memset 0 INDEX and other serialize methods
+    
+    Not necessary.
+
+ src/hb-ot-cff-common.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 554ed06fac759508ad959482f784bf02e4839a66
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Dec 1 21:51:17 2022 +0000
+
+    [repacker] add cycle detection to the graph sort.
+    
+    This allows us to bail early if the graph is not acyclic.
+
+ src/graph/graph.hh                 | 14 ++++++++++----
+ src/hb-repacker.hh                 |  5 +++++
+ src/test-repacker.cc               |  1 +
+ test/fuzzing/hb-repacker-fuzzer.cc | 17 +++++++++++++++--
+ 4 files changed, 31 insertions(+), 6 deletions(-)
+
+commit a66de336fb6c98f9946830194e6b28d0f3aaaef8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 14:32:13 2022 -0700
+
+    [vector] Minor use get_size() in as_bytes()
+
+ src/hb-vector.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0b826368fd122691e6d9095a42e8ad3023baa4bb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 14:23:25 2022 -0700
+
+    [serializer] Don't memset memory in embed
+    
+    Not necessary.
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3b68c7146f0722f6ae54f3bee9afa8112dc8dba4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 14:19:27 2022 -0700
+
+    [array] Don't clear serializer buffer when copying out
+    
+    Not needed.
+
+ src/hb-array.hh     |  4 ++--
+ src/hb-serialize.hh | 13 +++++++------
+ 2 files changed, 9 insertions(+), 8 deletions(-)
+
+commit 57808609c98ff037e03c2c1be0c7d9dbffe3f62f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 1 14:03:56 2022 -0700
+
+    [VarData] Move an unlikely
+
+ src/hb-ot-layout-common.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 9e99d08470c455d3ea8fc73e01a244d492fff989
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 8 23:19:02 2022 +0000
+
+    [repacker] validate link widths during repacker setup.
+
+ src/graph/graph.hh                 | 7 +++++++
+ test/fuzzing/hb-repacker-fuzzer.cc | 2 --
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+commit edf7a29595f01bf5548587476b37efdc24c500f1
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 8 22:59:34 2022 +0000
+
+    [repacker] Validate link positions before running the repacker.
+
+ src/graph/graph.hh                                 |  30 +++++++++++++++++++++
+ src/hb-repacker.hh                                 |   6 +++++
+ .../crash-442bfac994a3d9929cf06262ae9fb00f6ee1f774 | Bin 0 -> 358596 bytes
+ test/fuzzing/hb-repacker-fuzzer.cc                 |   1 +
+ 4 files changed, 37 insertions(+)
+
+commit 88d437525ffc25c5f9ee3d81b828aedd234b521c
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 8 21:19:25 2022 +0000
+
+    [repacker] add test for repacker fuzzer.
+
+ test/fuzzing/meson.build                  | 12 ++++++
+ test/fuzzing/run-repacker-fuzzer-tests.py | 68 +++++++++++++++++++++++++++++++
+ 2 files changed, 80 insertions(+)
+
+commit 6627a1ab450066bfda9c064dc48a0e4ea7fa45c8
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 8 21:11:39 2022 +0000
+
+    [repacker] Add a initial seed for the fuzzer repacker.
+
+ test/fuzzing/graphs/noto_nastaliq_urdu | Bin 0 -> 358596 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit deca30b2684f5580606ad614bc3ffb6c35e887a5
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 8 21:10:06 2022 +0000
+
+    [repacker] get repacker fuzzer working.
+    
+    Additionally add helper method that allows a graph to be saved as a fuzzer seed.
+
+ src/graph/graph.hh                 | 50 ++++++++++++++++++++++++++++++++++++++
+ src/hb-repacker.hh                 |  2 +-
+ test/fuzzing/hb-repacker-fuzzer.cc | 13 +++++++---
+ 3 files changed, 60 insertions(+), 5 deletions(-)
+
+commit 261a605f9c75d65570ee70abbc46a03e4ce99f7b
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 7 22:43:06 2022 +0000
+
+    [repacker] verify graph is a dag before using the fuzzer input.
+
+ test/fuzzing/hb-repacker-fuzzer.cc | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+commit 985b19f678cbccc57853796d2ee0e6885b9e7244
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Sep 7 22:21:16 2022 +0000
+
+    [repacker] begin implementing a fuzzer for the repacker api.
+
+ src/graph/graph.hh                 |  12 ++++
+ src/hb-repacker.hh                 |   6 ++
+ test/fuzzing/hb-repacker-fuzzer.cc | 134 +++++++++++++++++++++++++++++++++++++
+ test/fuzzing/meson.build           |   3 +
+ 4 files changed, 155 insertions(+)
+
+commit c6d616cc41561cc0029050e579b36cb5084a05ed
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Oct 17 22:41:51 2022 -0400
+
+    Generate and install hb-features.h
+    
+    This header has defines for all the optional
+    dependendencies that come with their own Harfbuzz
+    headers, so you can do:
+    
+      #include <hb-features.h>
+      #ifdef HB_HAS_DIRECTWRITE
+      #include <hb-directwrite.h>
+      #endif
+
+ src/Makefile.am      | 42 ++++++++++++++++++++++-
+ src/hb-features.h.in | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/meson.build      | 18 ++++++++++
+ 3 files changed, 155 insertions(+), 1 deletion(-)
+
+commit 8805a866b52526e41acd1e7ffe2c9e7bbee5a3b6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 17:15:00 2022 -0700
+
+    [ClassDef2] Write a few loops as range-based for
+
+ src/hb-ot-layout-common.hh | 34 ++++++++++++++--------------------
+ 1 file changed, 14 insertions(+), 20 deletions(-)
+
+commit ac8b232a2d94dcde2cdf00a4cc1db856009edb2a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 16:42:15 2022 -0700
+
+    [gsub] Cache intersects_class results for closure
+    
+    Benchmark                                                                                 Time             CPU      Time Old      Time New       CPU Old       CPU New
+    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+    BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/10                  +0.0246         +0.0240             0             0             0             0
+    BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/64                  -0.5541         -0.5544             4             2             4             2
+    BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/512                 -0.1120         -0.1123            43            38            43            38
+    BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/1400                -0.1154         -0.1159            43            38            43            38
+
+ src/hb-ot-layout-gsubgpos.hh | 58 +++++++++++++++++++++++++++++++-------------
+ 1 file changed, 41 insertions(+), 17 deletions(-)
+
+commit 20a0a467299964b0095295247f455835e63ed009
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 15:59:54 2022 -0700
+
+    [perf] Remove stale run.sh
+
+ perf/run.sh | 25 -------------------------
+ 1 file changed, 25 deletions(-)
+
+commit 38e7bc345c5a55fa910b3af967c4713da2dbcb6a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 15:01:38 2022 -0700
+
+    [benchmark-subset] Support testing arbitrary fonts from cmdline
+
+ perf/benchmark-subset.cc | 38 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 31 insertions(+), 7 deletions(-)
+
+commit c6a4b60116a528afb4f1bb28880326cf80ceafc8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 14:09:59 2022 -0700
+
+    [gsubgpos] Add an unlikely
+
+ src/hb-ot-layout-gsubgpos.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d4dec54c3adec19875f3b29b773b282390e1f1ef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 13:51:14 2022 -0700
+
+    [ci] Switch configs build to Ubuntu 20.04
+    
+    https://github.com/actions/runner-images/issues/6002
+
+ .github/workflows/configs-build.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 52d8346d993ed5ad96356216958323abc89cd514
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 13:50:16 2022 -0700
+
+    [ci] Change Linux runner to Ubuntu 20.04
+    
+    https://github.com/actions/runner-images/issues/6002
+
+ .github/workflows/linux-ci.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 32dd9810cf156b7710bc849030d69b902e58077b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 13:15:58 2022 -0700
+
+    [subset-cff1] Cache glyph-to-sid-map in the accelerator
+    
+    Benchmark                                                                                      Time             CPU      Time Old      Time New       CPU Old       CPU New
+    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+    BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10                   -0.0841         -0.0843             0             0             0             0
+    BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/64                   -0.1305         -0.1305             0             0             0             0
+    BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/512                  -0.1398         -0.1401             1             1             1             1
+    BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/4096                 +0.0382         +0.0380             9             9             9             9
+    BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10000                +0.0213         +0.0211            11            11            11            11
+
+ src/hb-ot-cff2-table.hh     |  5 +++++
+ src/hb-subset-cff-common.hh |  2 ++
+ src/hb-subset-cff1.cc       | 21 +++++++++++++++++----
+ 3 files changed, 24 insertions(+), 4 deletions(-)
+
+commit 72fabef0a46435152ec620b88245d32391858634
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 11:37:49 2022 -0700
+
+    [SingleSubstFormat2] Speed up closure
+
+ src/OT/Layout/GSUB/SingleSubstFormat2.hh | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+commit 2dc2e016d4bc47a37857eebf64d8d0b8378b32db
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 11:25:50 2022 -0700
+
+    [cff] Enable an unlikely
+
+ src/hb-ot-cff-common.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 582a87ef0a320061b991662f081e6b247f7f38f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 30 11:20:19 2022 -0700
+
+    [cff] Speed up FDSelect0 sanitize
+
+ src/hb-ot-cff-common.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 2658370f00981ac95c7031e9acaf8163f2e0f526
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 30 00:19:10 2022 +0000
+
+    [subset] make the cmap cache in accelerator const.
+
+ src/hb-ot-cmap-table.hh      | 30 +++++++++++++++++++++++-------
+ src/hb-subset-accelerator.hh |  4 +---
+ 2 files changed, 24 insertions(+), 10 deletions(-)
+
+commit 7551a668e38248a5c1df3f1315e7a05bc5909ab6
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 30 00:04:16 2022 +0000
+
+    [subset] Make cff_accelerator const.
+    
+    This gives more confidence that it won't be accidentally modified by the subset operation using it.
+
+ src/hb-subset-accelerator.hh |  2 +-
+ src/hb-subset-cff-common.hh  | 34 ++++++++++++++++------------------
+ 2 files changed, 17 insertions(+), 19 deletions(-)
+
+commit d8d0e0669405c5efbd07bcc24ad97b467534ff39
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 21:35:54 2022 -0700
+
+    [array] Comment
+
+ src/hb-array.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 2fecf2aa1997b5f914a9fa545c95929afc79714a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 21:25:01 2022 -0700
+
+    [ClassDef] Minor rename
+
+ src/hb-ot-layout-common.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 8f632ca8843427cefd9e2f7f76e1453c93c33913
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 21:23:35 2022 -0700
+
+    [ClassDef] Write another loop as range for
+
+ src/hb-ot-layout-common.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 87b12aee13778065bbacc601cfec61fac5f62268
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 21:18:48 2022 -0700
+
+    [ClassDef] Write a couple loops as range for
+
+ src/hb-ot-layout-common.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit ccd40c842ccaef4923bd4ed3981e7332d73aed4c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 21:14:44 2022 -0700
+
+    [ClassDef] Optimize intersected_class_glyphs
+
+ src/hb-ot-layout-common.hh | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+commit 44c585a6df139665a953c1f85e6e3adcc204e71f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 20:51:58 2022 -0700
+
+    [ClassDef] Fix disabled codeblock
+
+ src/hb-ot-layout-common.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit 9b7617d433158eeef45461715dd416bce34328a5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 20:29:58 2022 -0700
+
+    [ClassDef2] Use a faster algorithm in subset()
+    
+    Speedup across the board; up to 40% for MPlus1 at small sizes.
+
+ src/hb-ot-layout-common.hh | 66 ++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 55 insertions(+), 11 deletions(-)
+
+commit ae5e6d562bd49eed1438ecafc1c0b37ba77e0da3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 15:48:38 2022 -0700
+
+    [ClassDef2] Micro-optimize
+
+ src/hb-ot-layout-common.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 7129b79406fbbf53e08fa55623b5d8e2fa34e649
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 15:33:07 2022 -0700
+
+    [open-type] Add faster range-based loop to array types
+
+ src/hb-open-type.hh | 12 ++++++++++++
+ src/hb-vector.hh    |  2 +-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+commit dc823340612196ee360b5fb5a32bd1d9e143b256
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 15:26:55 2022 -0700
+
+    Remove a couple of unneeded .iter() invocations
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 00f2657bb8fea82613d67a059dd4c3a5550683f1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 13:49:15 2022 -0700
+
+    [subset] Accelerate sanitize-table-cache
+    
+    Big wins all across small subsets
+    
+    BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/10                              -0.1140         -0.1129             0             0             0             0
+    BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/10                               -0.4717         -0.4714             0             0             0             0
+    BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/10                    -0.8147         -0.8146             0             0             0             0
+    BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/10                  -0.3248         -0.3242             0             0             0             0
+    BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/10                             -0.1262         -0.1260             0             0             0             0
+    BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10                -0.0308         -0.0309             0             0             0             0
+    BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/10                       -0.1374         -0.1373             0             0             0             0
+    BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/10                            -0.4555         -0.4555             0             0             0             0
+    BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/10                             -0.4175         -0.4174             0             0             0             0
+    BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/10                         -0.4214         -0.4214             0             0             0
+
+ src/hb-mutex.hh              |  7 ++++---
+ src/hb-subset-accelerator.hh | 12 ++++++++++--
+ src/hb-subset-plan.hh        | 16 +++++++++-------
+ 3 files changed, 23 insertions(+), 12 deletions(-)
+
+commit 33165f4848608ddd813404602877bcf907e1e683
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 29 15:14:15 2022 -0700
+
+    [bit-page] Remove ELT_BITS_LOG_2
+    
+    My compiler is smart enough to take care of it.
+
+ src/hb-bit-page.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit 58925ed9a0bf0dc7b3e8dff34d296bf50759e2b7
+Author: Satadru Pramanik <satadru at gmail.com>
+Date:   Tue Nov 29 13:14:10 2022 -0500
+
+    Update freetype subproject to 2.12.1
+
+ subprojects/freetype2.wrap | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 80dd751564e8a9153f7466e687b8699a5e7e27c6
+Author: Christoph Reiter <reiter.christoph at gmail.com>
+Date:   Tue Nov 29 19:15:31 2022 +0100
+
+    CI: work around flaky 64bit MSYS2 builds
+    
+    MSYS2 Python+meson has some random crashes in CI which we haven't been
+    able to reproduce yet. Naturally enabling debugging fixes them.. :)
+
+ .github/workflows/msys2-ci.yml | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 8f41b6a13918968476b9b2e917798daca3394352
+Author: Christoph Reiter <reiter.christoph at gmail.com>
+Date:   Tue Nov 29 18:29:46 2022 +0100
+
+    CI: fix msvc build
+    
+    The Windows image for some reason now contains a zlib and freetype build
+    which meson finds and tries to use. Force meson to use the subprojects always
+    to avoid picking up system libs.
+
+ .github/workflows/msvc-ci.yml | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 7a004a7ac27da776b623c0892ebced3d12213c39
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Nov 29 00:47:55 2022 +0000
+
+    [subset] Cache per subtable cmap unicode mappings.
+
+ src/hb-ot-cmap-table.hh      | 108 +++++++++++++++++++++++++++++++++++--------
+ src/hb-subset-accelerator.hh |  15 +++++-
+ src/hb-subset.cc             |   5 ++
+ 3 files changed, 109 insertions(+), 19 deletions(-)
+
+commit d2a2670e54d545db2e5200eeeba0f08191a09f74
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 19:42:27 2022 -0700
+
+    [iter] Simplify has() interface implementations
+
+ src/OT/Layout/Common/Coverage.hh | 6 ++----
+ src/hb-bit-set-invertible.hh     | 6 ++----
+ src/hb-bit-set.hh                | 6 ++----
+ src/hb-map.hh                    | 3 +--
+ src/hb-ot-layout-common.hh       | 6 ++----
+ src/hb-set.hh                    | 6 ++----
+ 6 files changed, 11 insertions(+), 22 deletions(-)
+
+commit cba82829baa1e5344e31095932c383f412a409a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 16:19:54 2022 -0700
+
+    [subset-cff1] Share subrs object
+    
+    Multiple FDs might share the same subrs...
+
+ src/hb-subset-cff1.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c7b998b355f3815d4b288c457aa120770580f3c6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 16:18:21 2022 -0700
+
+    [cff2] Don't share fd-array link
+    
+    No point.
+
+ src/hb-subset-cff2.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3d9e3c2dc7a5cfa2831a30903419a1c98f571757
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 16:17:09 2022 -0700
+
+    [subset-cff2] Don't share varstore object
+
+ src/hb-subset-cff2.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c503cf003e75191f3b3f9200c8dc4e90fdc1c67b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 15:53:35 2022 -0700
+
+    [cmap] Store offset, not pointer, in cmap cache
+
+ src/hb-ot-cmap-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 3e151139a8987a13cdd8cc2ddc025534c51c607f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 14:23:49 2022 -0700
+
+    [PairPos] Optimize get_effective_value_format
+    
+    Speeds up BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/512
+    12%.
+
+ src/OT/Layout/GPOS/PairPosFormat1.hh | 3 +++
+ src/OT/Layout/GPOS/PairPosFormat2.hh | 6 +++++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+commit 3131aecf9fc8b34a22ebf797412496c4baf18c68
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 14:12:55 2022 -0700
+
+    [array/hash] Fix asan issue
+    
+    ../src/hb-algs.hh:240:43: runtime error: reference binding to misaligned address 0x7ffe91a08b0e for type 'const unsigned int', which requires 4 byte alignment
+
+ src/hb-array.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 26ad7a6022533e3497e7fa94d67808830b9915b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 14:09:21 2022 -0700
+
+    [gpos] Minor micro-optimize
+
+ src/OT/Layout/GPOS/PairPosFormat1.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit c769d7e1810cbb30210d0fbcc21e04909e270cf8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 14:03:58 2022 -0700
+
+    [gpos] Whitespace
+
+ src/OT/Layout/GPOS/PairPosFormat1.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 3ea0f37c30aaf354e256ad1374fd2e0956df8120
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 13:58:44 2022 -0700
+
+    [subset-cff] Move an init to constructor
+    
+    The init was not called anyway.
+
+ src/hb-subset-cff-common.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 6c92c3e0cf4e7c09c13e2e2c59cc5467605ad165
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 13:54:24 2022 -0700
+
+    [subset-cff] Remove unnecessary check
+
+ src/hb-subset-cff-common.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 7fd300dd9a7e38973ee9eda0197e973bc88b043f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 13:51:16 2022 -0700
+
+    [subset-cff] Use constructor for parsed_cs_op_t
+
+ src/hb-subset-cff-common.hh | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+commit bd37900e0da9c5b9dbfabccb8af64e97cbe8c956
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Nov 28 20:35:34 2022 +0000
+
+    [subset] use a reference to cached global/loca subrs.
+    
+    Previously they were being copied in. Copying is no longer necessary now that hint dropping doesn't mutate the arrays.
+
+ src/hb-subset-cff-common.hh | 91 +++++++++++++++++----------------------------
+ 1 file changed, 35 insertions(+), 56 deletions(-)
+
+commit ded9de9cd82aa33a5ffbf8e23c473c6ff2c186c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 13:31:40 2022 -0700
+
+    [cff] bsearch in fdselect
+    
+    Saves 8% in NotoSansCJK / 10000 subset benchmark.
+
+ src/hb-ot-cff-common.hh     | 18 ++++++++++++------
+ src/hb-subset-cff-common.hh |  9 ++++-----
+ 2 files changed, 16 insertions(+), 11 deletions(-)
+
+commit 0c33aba30cb06f2798088573efb7880315d94029
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 12:28:13 2022 -0700
+
+    [subset-cff] Rename drop flag to hinting flag
+
+ src/hb-subset-cff-common.hh | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+commit 6f5b531986c5084da7b85d12551018650ac63d5d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 28 11:39:24 2022 -0700
+
+    [subset-cff] Make no-hinting use accelerator as well
+
+ src/hb-subset-cff-common.hh | 43 +++++++++++++++++++++++++++----------------
+ 1 file changed, 27 insertions(+), 16 deletions(-)
+
+commit fad8322b3f126281ff662eb7b1a6d1747f5fc193
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 27 15:09:48 2022 -0700
+
+    [benchmark-subset] Add no-hinting ops
+
+ perf/benchmark-subset.cc | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+commit f51a624e6752441ea081052620129714135559a8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 27 14:54:39 2022 -0700
+
+    [subset-cff] Micro-optimize drop_hints_in_str
+
+ src/hb-subset-cff-common.hh | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+commit 38603266881499db8c7925ab7fc909158b462308
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 27 13:23:13 2022 -0700
+
+    [subset-cff] Write loop more idiomatic
+
+ src/hb-number-parser.hh     |  8 ++++----
+ src/hb-subset-cff-common.hh | 15 ++++++++-------
+ 2 files changed, 12 insertions(+), 11 deletions(-)
+
+commit 3ff502d3aef4cdd1ac4dee29fbcb5af16f43b2cf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 27 12:58:04 2022 -0700
+
+    [subset-cff] Remove unnecessary initialization
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6af4985bf9013cef85bc5cdf3c8b8150fc72c967
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 18:20:20 2022 -0700
+
+    [subset-cff] No need for bitflag here anymore
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 69ce606d1467dbfdd3c01070a5126e141c5c3047
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 18:18:35 2022 -0700
+
+    [subset-cff] Immediately drop subr numbers instead of marking for skip
+    
+    Seems to work and saves ~2% time.
+
+ src/hb-subset-cff-common.hh | 17 ++---------------
+ 1 file changed, 2 insertions(+), 15 deletions(-)
+
+commit 1cf4f3e0830eb45bd9d96fdfcdea15d2fb1af8f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 18:15:28 2022 -0700
+
+    [subset-cff] More comment
+
+ src/hb-subset-cff-common.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit f68221ff43df990f10ddcf91f6a71d4c72a82e82
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 18:12:14 2022 -0700
+
+    [subset-cff] Add comment
+
+ src/hb-subset-cff-common.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 048ab8a066afd5c472e4a436f5e95016ac0d3649
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 18:00:43 2022 -0700
+
+    [subset-cff] Remove unused bits
+
+ src/hb-subset-cff-common.hh | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit 37cbfc0c7ee82ee6f781b2b1df6a8c8555a15c16
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 17:57:44 2022 -0700
+
+    [subset-cff] Remove unneeded member
+
+ src/hb-subset-cff-common.hh | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+commit 46ab15137b0ee04b76e22cb5964969aa9f2e6e7c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 17:49:21 2022 -0700
+
+    [subset-cff] Add has_calls to parsed charstrings
+    
+    Optimize closure based on it.
+
+ src/hb-subset-cff-common.hh | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+commit 6d53074e6375c1680f40b647a1b4ad88dd3cc1c6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 17:23:09 2022 -0700
+
+    [subset-cff] Drop another unused parameter
+
+ src/hb-subset-cff-common.hh | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+commit 42615561b545f2bb7c29618884fa2d63d8dd97a8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 17:10:58 2022 -0700
+
+    Optimize a couple array references
+
+ src/hb-ot-map.cc            | 2 +-
+ src/hb-subset-cff-common.hh | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 04d23b7ca802cde23b04c8570d8d166c1b543ac3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 17:08:00 2022 -0700
+
+    [subset-cff] Micro-optimize collect_subr_refs_in_str
+
+ src/hb-subset-cff-common.hh | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit 9d18180c3c77ed73188d5eda14b9602c5f6d073b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 15:38:21 2022 -0700
+
+    [array] Use hb_hash instead of handrolling
+
+ src/hb-array.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 1e6f77c250825a7f6ef7e550289f67253a469b05
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 15:31:56 2022 -0700
+
+    [benchmark-subset] Adjust num glyphs more
+
+ perf/benchmark-subset.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0382defa5196a28e3e0fcad5d91bcee14f303bad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 15:27:07 2022 -0700
+
+    [benchmark-subset] Adjust number of glyphs of fonts
+
+ perf/benchmark-subset.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 4cb441dfd11221bdd423622a4c57f87e723fc129
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 15:23:07 2022 -0700
+
+    [benchmark-subset] Add AdobeVFPrototype
+
+ perf/benchmark-subset.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit e302b9d5da0641ab9c3e1d20cfab19282649f839
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 15:18:16 2022 -0700
+
+    Fix build
+
+ src/hb-coretext.cc          | 2 +-
+ src/hb-ms-feature-ranges.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 70d97d079b73cc39d457dcb18ffae4eca3b5f5b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 15:16:11 2022 -0700
+
+    [subset-cff] Remove unused argument
+
+ src/hb-cff2-interp-cs.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 4167e93a1507d8fdefa37dba2044d9015f87ad78
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 15:14:52 2022 -0700
+
+    [subset-cff2] Micro-optimize blend operator
+
+ src/hb-cff2-interp-cs.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit f159bf075bb7050eebf307a5a90e1110fc526573
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 15:11:32 2022 -0700
+
+    [cff2] Micro-optimize blend operator
+
+ src/hb-cff2-interp-cs.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit a331e913dc99cba1e5994b06cffa2c5cc007f7ff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 14:59:37 2022 -0700
+
+    [bit-page] Hand-code equality
+    
+    Faster than memcmp() because of alignment.
+
+ src/hb-bit-page.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 9df06a26950ced1017395c771e25be56f20fba5c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 14:56:45 2022 -0700
+
+    [bit-set] Fix is_subset() short-circut criteria
+    
+    Ouch!
+
+ src/hb-bit-set.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 915c1a00cfde01cc153582df31031361ded28b20
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 14:48:57 2022 -0700
+
+    [vector] Add remove_unordered
+    
+    Saves 5% in NotoNastaliq/1000 subset benchmark.
+
+ src/graph/graph.hh             |  4 ++--
+ src/graph/markbasepos-graph.hh |  2 +-
+ src/hb-vector.hh               | 14 +++++++++++++-
+ src/test-vector.cc             |  3 ++-
+ 4 files changed, 18 insertions(+), 5 deletions(-)
+
+commit 4b8d8fbee4dc5fb96d298ea8ea8c5871b7ffbc26
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 14:31:15 2022 -0700
+
+    [ot-map] Micro-optimize for size
+
+ src/hb-ot-map.hh | 6 +++---
+ src/hb-vector.hh | 3 +++
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+commit 93f3a9dbc677ae51e5b0a754c995963207ca97b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 14:19:00 2022 -0700
+
+    [ot-map] Micro-optimize more
+    
+    Another 500 bytes.
+
+ src/hb-ot-map.cc | 33 ++++++++++++++++++---------------
+ 1 file changed, 18 insertions(+), 15 deletions(-)
+
+commit f39f049870ebad20b76e3f56194568e89fa45aac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 14:16:15 2022 -0700
+
+    [ot-map] Micro-optimize
+    
+    Weird that shrinks size by 500 bytes.
+
+ src/hb-ot-map.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 60bb32c45470f8ea3d30baf67980c699dfb9b801
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 14:12:57 2022 -0700
+
+    [ot-map] Minor refactor
+
+ src/hb-ot-map.cc | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+commit e3cc61838fe331167d8074b55271039fbe2d2cb2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 13:58:04 2022 -0700
+
+    [PairPos] Adjust kerning buffer messages
+
+ src/OT/Layout/GPOS/PairPosFormat2.hh | 12 ++++++++++--
+ src/OT/Layout/GPOS/PairSet.hh        | 12 ++++++++++--
+ 2 files changed, 20 insertions(+), 4 deletions(-)
+
+commit a81dd1053dcdd1e26a0516d3a5b84e0b904e2c96
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 13:43:15 2022 -0700
+
+    [layout] Adjust printing feature tags
+    
+    For required-feature, print spaces, not nul bytes.
+
+ src/hb-ot-layout.cc | 6 +++---
+ src/hb-ot-map.hh    | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 56e3868b52ef6e85d6495d28bae57dcc5746d1db
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 26 13:14:23 2022 -0700
+
+    [layout/buffer-message] Print feature name in lookup buffer messages
+
+ src/hb-ot-layout.cc | 6 +++---
+ src/hb-ot-map.cc    | 7 +++++--
+ src/hb-ot-map.hh    | 4 +++-
+ 3 files changed, 11 insertions(+), 6 deletions(-)
+
+commit a5d35fd80a26cb62c4c9030894f94c0785d183e7
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Nov 25 23:17:05 2022 +0000
+
+    [subset] use charstrings directly from accelerator cache if mutability isn't needed.
+
+ src/hb-subset-cff-common.hh | 70 ++++++++++++++++++++++++++++++---------------
+ 1 file changed, 47 insertions(+), 23 deletions(-)
+
+commit 026b64ef76e12f87ec4740c26eeda724193f810e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 14:57:40 2022 -0700
+
+    [subset-cff] Avoid set mallocation in hb_plan_subset_cff_fdselect
+
+ src/hb-subset-cff-common.cc | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+commit 74acf52f3321d3aeeb4b96f5b36040727634efd0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 14:43:44 2022 -0700
+
+    [subset-cff] Micro-optimize copy_str more
+
+ src/hb-subset-cff-common.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit d2f3cde7ef20a7e7d58c3301ac32da6d38a65712
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 14:38:30 2022 -0700
+
+    [subset-cff] Micro-optimize copy_str
+
+ src/hb-subset-cff-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e333223f269a090732ae3a9d468bb93c35bbeb62
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 14:23:57 2022 -0700
+
+    [array] Optimize serializing copy()
+
+ src/hb-array.hh  | 16 +++++++++++++++-
+ src/hb-vector.hh | 11 ++++++-----
+ 2 files changed, 21 insertions(+), 6 deletions(-)
+
+commit 22990fca1d78680a4f24fc29a109a115fe0660d0
+Merge: 7b197446a 8d5c899b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 14:12:58 2022 -0700
+
+    Merge pull request #3894 from googlefonts/cff_accel
+    
+    [subset] Cache parsed char strings in CFF accelerator
+
+commit 8d5c899b0ff43b4b8aeb767623627cf55168c8fb
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Nov 25 20:33:39 2022 +0000
+
+    [subset] In cff accelerator hold reference to CFF table instead of the whole font.
+
+ src/hb-ot-cff1-table.hh     |  2 +-
+ src/hb-ot-cff2-table.hh     |  2 +-
+ src/hb-subset-cff-common.hh | 19 ++++++++++---------
+ 3 files changed, 12 insertions(+), 11 deletions(-)
+
+commit 7b197446acc8b4876d3d193b56ee5ab605424ef3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 13:28:53 2022 -0700
+
+    [vector] Adjust for HB_OPTIMIZE_SIZE
+
+ src/hb-vector.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 75a99f28abbb6d82e51f49dcda95c0d61b225e98
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Nov 25 18:38:13 2022 +0000
+
+    [subset] destruct cff accelerator if present.
+
+ src/hb-subset-accelerator.hh | 7 ++++++-
+ src/hb-subset-cff-common.hh  | 6 ++++--
+ 2 files changed, 10 insertions(+), 3 deletions(-)
+
+commit 1d474194f0a5c164ce629c4e291051ee12979e25
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 13:21:35 2022 -0700
+
+    [subset-cff] Micro-optimize encode_str
+
+ src/hb-subset-cff-common.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 3c4a610b59857665c73e771a4d2448fcd1acaae1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 13:16:30 2022 -0700
+
+    [subset-cff] Micro-optimize copy_str some more
+
+ src/hb-subset-cff-common.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 535aadb309f51dbb243042230c5fef09885c7499
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 13:07:42 2022 -0700
+
+    [subset-cff] Micro-optimize collect_subr_refs_in_str more
+
+ src/hb-subset-cff-common.hh | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit 00a9df3a43484f81d02baf9e726993ff67bb523f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 13:05:05 2022 -0700
+
+    [subset-cff] Micro-optimize collect_subr_refs_in_str
+
+ src/hb-subset-cff-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit d2a2f5bf4ed66979b17332f35b52c3395b02ed2d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 12:44:02 2022 -0700
+
+    [vector] Handroll copy
+
+ src/hb-vector.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 1fed366d5bb5020948b8d6d033ad886fec7e8be8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 12:37:24 2022 -0700
+
+    [serialize] Shut compiler warning off
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f2297e6978087cefd27a947e044adf9e89eab5f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 25 11:33:00 2022 -0700
+
+    [buffer] Documentation
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3889
+
+ src/hb-buffer.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 71c23c1c079cbd992ee3c9e92435ee2b1374c227
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Nov 25 18:04:44 2022 +0000
+
+    [subset] don't copy the entire global/loca subr lists from the accelerator.
+    
+    Instead run a closure on the retained charstrings and copy only the referenced subrs. This significantly speeds up cases with small character sets.
+
+ src/hb-subset-cff-common.hh | 80 ++++++++++++++++++++++++++++++---------------
+ 1 file changed, 53 insertions(+), 27 deletions(-)
+
+commit 4ff09274a86102a69c6e7abebc59d694bc90bbcd
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Nov 24 22:47:29 2022 +0000
+
+    [subset] In CFF accelerator keep a reference to original face.
+    
+    The charstring objects reference memory from the original face so we need to maintain a reference to prevent it from being destroyed.
+
+ src/hb-subset-cff-common.hh | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+commit 6aaa16627c3d6c77da32e6b2019724385103581d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:58:42 2022 -0700
+
+    [Coverage] Comment
+
+ src/OT/Layout/Common/CoverageFormat1.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 06e2147a483a1244b6978c0f7c4ca3fbe3bad227
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:56:04 2022 -0700
+
+    More call set->next() directly
+
+ src/hb-ot-layout-common.hh | 29 ++++++++++++++---------------
+ 1 file changed, 14 insertions(+), 15 deletions(-)
+
+commit 196c9db06fc627a4709886e49ff0823dba3bbdbc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:51:52 2022 -0700
+
+    Call ->next() directly
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 03d64b7469d12d10b498fbf942afb7b87810012f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:33:18 2022 -0700
+
+    [bit-set] Remove TODO that would never happen
+
+ src/hb-bit-set.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 690df8a36955390cfd7251a50a2629e64b52bb82
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:32:51 2022 -0700
+
+    [bit-set] Micro-optimize prev()
+
+ src/hb-bit-set.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit fe5d9176aed02c0d3388d5a5cf3881e6437db71f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:30:18 2022 -0700
+
+    [bit-set] Micro-optimize size
+    
+    It's silly that this saves size at all. :(
+
+ src/hb-bit-set.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cf9b9929df088570c18ea8b55e61ba7f31374532
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:26:28 2022 -0700
+
+    [bit-set] Micro-optimize process()
+
+ src/hb-bit-set.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit d77903db7b165dbb6327141e1949984a09756de7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:22:32 2022 -0700
+
+    [bit-set] Micro-optimize
+
+ src/hb-bit-set.hh | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+commit 13dd4b464b7bf7bfaff790d242b6baeec2edffa9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:20:42 2022 -0700
+
+    [bit-set] Micro-optimize access
+
+ src/hb-bit-set.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a3afa61ce8d01784d88de4af3647ebd5b3e71fe6
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 22:24:39 2022 +0000
+
+    [subset] use cached parsed char strings if available.
+
+ src/hb-subset-cff-common.hh | 67 ++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 16 deletions(-)
+
+commit 47c125845caf1c24f538679ffdc32c04b2f0920b
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 21:02:39 2022 +0000
+
+    [subset] Cache parsed charstrings in the cff accelerator.
+
+ src/hb-subset-cff-common.hh | 36 ++++++++++++++++++++++++++++++++----
+ 1 file changed, 32 insertions(+), 4 deletions(-)
+
+commit 48b68370743264f900457e4b463e9ced5325ceae
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 20:51:51 2022 +0000
+
+    [subset] add a CFF specific accelerator object.
+    
+    This allows CFF specific accelerator structures to be isolated to the CFF code.
+
+ src/hb-subset-accelerator.hh | 12 +++++++++++-
+ src/hb-subset-cff-common.hh  | 22 ++++++++++++++++++++++
+ 2 files changed, 33 insertions(+), 1 deletion(-)
+
+commit d77f346d1a822c7209192f55218fe707e6295183
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:02:46 2022 -0700
+
+    [subset-cff] Minor rename
+
+ src/hb-subset-cff-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 29a0fa089a6c0bf390a02ddaa1757d8894c1a0a7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 14:00:59 2022 -0700
+
+    [subset-cff] Micro-optimize
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d480ae1fac8c2d32fb9df851629b877248331416
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 13:53:43 2022 -0700
+
+    [cff] Remove unused function
+
+ src/hb-cff-interp-common.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 73046d53e5e769ec8c4eff2a1b8306bb15ce0cce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 13:49:29 2022 -0700
+
+    [shaper] Disable dumber shaper if no AAT
+
+ src/hb-ot-shape.cc          | 2 ++
+ src/hb-ot-shaper-default.cc | 2 ++
+ 2 files changed, 4 insertions(+)
+
+commit e9f964c01a4d1273f5632d34f8f3827608cab735
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 13:38:53 2022 -0700
+
+    [ot-face] Declare more tables as core
+
+ src/hb-machinery.hh          |  2 +-
+ src/hb-ot-face-table-list.hh | 28 ++++++++++++++--------------
+ 2 files changed, 15 insertions(+), 15 deletions(-)
+
+commit 5bc27a128dc5fb6ec65591c0f0632973ce9e8116
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 13:30:12 2022 -0700
+
+    [machinery] Comment
+
+ src/hb-machinery.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit d21bfb08615f44ffd60737295b45da5e1a5fca7e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 13:14:05 2022 -0700
+
+    [normalize] Remove an unlikely
+    
+    Keep unlikely for truely unlikely scenarios.
+
+ src/hb-ot-shape-normalize.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9e1239f443bce69200d7203cd3a89b921a382531
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 13:00:47 2022 -0700
+
+    [config] Define HB_NO_VERTICAL in HB_LEAN and as such in HB_TINY
+
+ src/hb-config.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 6f133ccfde9c96ab6de8e18ddbbac4b7509eed0c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 12:59:55 2022 -0700
+
+    [glyf] Fix build with HB_NO_VERTICAL
+
+ src/OT/glyf/Glyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 76420ef769e828db3633578e814409c4ddc7b938
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 12:52:15 2022 -0700
+
+    [machine.rl] Remove unlikely from what happens 1/16 of the time
+
+ src/hb-ot-shaper-indic-machine.hh   | 16 ++++++++--------
+ src/hb-ot-shaper-indic-machine.rl   |  2 +-
+ src/hb-ot-shaper-khmer-machine.hh   | 16 ++++++++--------
+ src/hb-ot-shaper-khmer-machine.rl   |  2 +-
+ src/hb-ot-shaper-myanmar-machine.hh | 16 ++++++++--------
+ src/hb-ot-shaper-myanmar-machine.rl |  2 +-
+ src/hb-ot-shaper-use-machine.hh     | 16 ++++++++--------
+ src/hb-ot-shaper-use-machine.rl     |  2 +-
+ 8 files changed, 36 insertions(+), 36 deletions(-)
+
+commit 1248574454facabe15a96d7670243c7959f4a065
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 12:46:04 2022 -0700
+
+    [config] Disable Zawgyi shaper in HB_MINI/HB_TINY
+
+ src/hb-config.hh            | 1 +
+ src/hb-ot-shaper-myanmar.cc | 2 ++
+ src/hb-ot-shaper.hh         | 2 ++
+ 3 files changed, 5 insertions(+)
+
+commit 05aa084e67705285941c9acd13151e2a38da8b0f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 12:13:31 2022 -0700
+
+    [PairPos] Another attempt at fixing unsafe-to-break with ValueFormat2
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
+    
+    Test:
+    $ hb-shape XBRoya34.ttf  ' الأ' --show-flags --script=arab
+
+ src/OT/Layout/GPOS/PairPosFormat2.hh | 9 +++++----
+ src/OT/Layout/GPOS/PairSet.hh        | 5 +++--
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+commit 54ae3345b225151d9f77189f1dec071c1f075ce9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 11:59:50 2022 -0700
+
+    [buffer] Improve documentation of hb_buffer_add_codepoints()
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3889
+
+ src/hb-buffer.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a4a40786326cef97fe25eee2232852c9173347e7
+Merge: 0c70bc7f3 64e8707ec
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 11:56:58 2022 -0700
+
+    Merge pull request #3893 from googlefonts/preprocess_test
+    
+    [subset] Fix testing of preprocess
+
+commit 0c70bc7f3286ea0c04164f110a6d2caac805812c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 24 11:48:48 2022 -0700
+
+    [skippy-iter] Fix two logic errors
+    
+    First, a signed underflow.
+    
+    Second, a wrong condition.
+    
+    Both were introduced in 42681bdb55a75520d4ac194302fe936d1ce3cb34
+
+ src/hb-ot-layout-gsubgpos.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 64e8707ecac726a4e78772875d069db3f5c0ad6a
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Nov 24 18:24:50 2022 +0000
+
+    [subset] don't use hb repacker when generating test files from fonttools.
+
+ ...astaliqUrdu-Regular.default.627,644,62D,628.ttf | Bin 24564 -> 24532 bytes
+ .../NotoNastaliqUrdu-Regular.default.633,6D2.ttf   | Bin 14296 -> 14292 bytes
+ ...otoNastaliqUrdu-Regular.default.63A,64A,631.ttf | Bin 26152 -> 26124 bytes
+ ...iqUrdu-Regular.default.retain-all-codepoint.ttf | Bin 542388 -> 542328 bytes
+ ...liqUrdu-Regular.retain-gids.627,644,62D,628.ttf | Bin 30464 -> 30432 bytes
+ ...otoNastaliqUrdu-Regular.retain-gids.633,6D2.ttf | Bin 20140 -> 20132 bytes
+ ...astaliqUrdu-Regular.retain-gids.63A,64A,631.ttf | Bin 32012 -> 31984 bytes
+ ...du-Regular.retain-gids.retain-all-codepoint.ttf | Bin 542424 -> 542360 bytes
+ test/subset/generate-expected-outputs.py           |   2 ++
+ 9 files changed, 2 insertions(+)
+
+commit 3b43096ef336cf3ba149518c82541c0079ef0f92
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 22:04:02 2022 -0700
+
+    [buffer] Whitespace
+
+ src/hb-buffer.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 094f80738a57a99a9f541f55bbf8aa796235756c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 22:03:26 2022 -0700
+
+    [buffer] Handle null buffer in set_message_func
+
+ src/hb-buffer.cc | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 1fa64c0c23ed86d60117198420587aee81fdc8d8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 21:38:51 2022 -0700
+
+    [gsubgpos] Conditionalize skippy on unsafe-to-concat
+
+ src/hb-ot-layout-gsubgpos.hh | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 42681bdb55a75520d4ac194302fe936d1ce3cb34
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 21:36:43 2022 -0700
+
+    [gsubgpos] No logic-change minor rewrite
+
+ src/hb-ot-layout-gsubgpos.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit c15efdec496aae23f9e15d08b69d61f77bf6dee0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 21:14:28 2022 -0700
+
+    [gsubgpos] Comment
+
+ src/hb-ot-layout-gsubgpos.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 7ec1c41a55729808d61cb85fb2d632e0b488f53f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 21:12:41 2022 -0700
+
+    [gsubgpos] Skippy-iter: Prefer correctness to performance
+    
+    Prefer unsafe-to-concat correctness, over performance.
+
+ src/hb-ot-layout-gsubgpos.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit b6df3471379bfe66e9360cf1d6625c705e179018
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 20:15:16 2022 -0700
+
+    [perf] Add Hindi test to benchmark-shape
+
+ perf/benchmark-shape.cc |     4 +
+ perf/texts/hi-words.txt | 10000 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 10004 insertions(+)
+
+commit dce3502e10af6f52bffad94c2f772b3cae12fd5e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 18:34:54 2022 -0700
+
+    [array] Add commented-out static asserts
+    
+    They don't work.
+
+ src/hb-array.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit a7fee43cefce95097ba46591090395a3c882741c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 17:46:32 2022 -0700
+
+    [priority-queue] Minor micro-optimize
+
+ src/hb-priority-queue.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ff3cac0ccd0633a7715945e4c9f1e7243f75d1cb
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 23:50:49 2022 +0000
+
+    [subset] Fix unecessary trailing 0 bytes left by ContextFormat2 pruning.
+    
+    Uneeded rules where beind removed from the count by the bytes for them was being left in the font.
+
+ src/hb-ot-layout-gsubgpos.hh                        |   6 +++++-
+ ...subrules_f1.layout-test-retain-gids.41,42,43.otf | Bin 2152 -> 2148 bytes
+ ...le_subrules_f1.layout-test-retain-gids.41,42.otf | Bin 2028 -> 2024 bytes
+ ...layout-test-retain-gids.retain-all-codepoint.otf | Bin 4012 -> 4008 bytes
+ ...t2_multiple_subrules_f1.layout-test.41,42,43.otf | Bin 1440 -> 1436 bytes
+ ...text2_multiple_subrules_f1.layout-test.41,42.otf | Bin 1320 -> 1316 bytes
+ ...subrules_f1.layout-test.retain-all-codepoint.otf | Bin 4012 -> 4008 bytes
+ ...landhar-Regular.default.retain-all-codepoint.ttf | Bin 49248 -> 49244 bytes
+ ...dhar-Regular.drop-hints.retain-all-codepoint.ttf | Bin 29468 -> 29464 bytes
+ ...ndhar-Regular.keep-gdef.retain-all-codepoint.ttf | Bin 49248 -> 49244 bytes
+ ...subrules_f2.layout-test-retain-gids.41,42,43.otf | Bin 2256 -> 2252 bytes
+ ...le_subrules_f2.layout-test-retain-gids.41,42.otf | Bin 2224 -> 2220 bytes
+ ...layout-test-retain-gids.retain-all-codepoint.otf | Bin 4008 -> 4004 bytes
+ ...t2_multiple_subrules_f2.layout-test.41,42,43.otf | Bin 1460 -> 1456 bytes
+ ...text2_multiple_subrules_f2.layout-test.41,42.otf | Bin 1416 -> 1412 bytes
+ ...subrules_f2.layout-test.retain-all-codepoint.otf | Bin 4008 -> 4004 bytes
+ 16 files changed, 5 insertions(+), 1 deletion(-)
+
+commit f2851e4157e302d9932ef0582da6c36cade4f085
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 16:50:30 2022 -0700
+
+    [test-map] Test has() getter with unique-ptr
+
+ src/test-map.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 5f3a780614ee76347fd0692439fe37a7fc02602e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 16:45:46 2022 -0700
+
+    [font] Protect against div-by-zero
+
+ src/hb-font.cc | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 060ecac949dca29a75538ddeedf015441296334b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 16:31:37 2022 -0700
+
+    [font] Respect subfont slant setting in hb-draw
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3890
+
+ src/hb-font.cc | 34 ++++++++++++++++++++--------------
+ 1 file changed, 20 insertions(+), 14 deletions(-)
+
+commit 2e9b270a496de14d3eee9d8b7e1372293bf13888
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 16:17:50 2022 -0700
+
+    [hb-view] Fix cairo slanting condition
+    
+    hb-draw already does slanting. If NOT hb-draw, we should slant
+    through cairo path.  Donno why this was untested before.
+    
+    This was double-slanting with hb-draw, and not slanting without it.
+
+ util/helper-cairo.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 51028e63e68b2e06f969da9e4e727d5c2f912bf4
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 22:51:16 2022 +0000
+
+    [subset] Retain all glyphs in preprocessed face.
+
+ src/hb-subset-input.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 404cb99d86c2d639b4ce2fc59f00f5e66468af34
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 15:35:14 2022 -0700
+
+    [buffer-diff] Fix check for glyph flag equality
+    
+    I'm not sure if the old behavior was intentional, but it was checking
+    that the glyph flags were a subset of the reference buffer's glyph
+    flags.  I don't see why that is useful.  Fix that.
+    
+    Then make the buffer-verify code ignore flag differences when verifying
+    buffers, since our unsafe-to-concat flag at least, is conservative and
+    not guaranteed to be produced the same in fragments.  See:
+    
+    https://github.com/harfbuzz/harfbuzz/issues/3888
+
+ src/hb-buffer-verify.cc | 5 ++---
+ src/hb-buffer.cc        | 2 +-
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+commit 4c49daf7cd961fb47126baf04240243736cae606
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 22:33:57 2022 +0000
+
+    [subset] actually use the preprocessed face in hb-subset.
+    
+    Tests weren't actually using the preprocessed face due to this typo in util/hb-subset.
+
+ src/hb-subset-input.cc | 5 +++++
+ util/hb-subset.cc      | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit 2c0afde7370a27d1aa26983751a422f61924580c
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 20:24:40 2022 +0000
+
+    [subset] add an inprogress accelerator to plan.
+    
+    This allows subset code to cache information into the accelerator during preprocess subset. Previously the accelerator was created at the end of subsetting.
+
+ src/hb-subset-plan.cc | 11 +++++++++++
+ src/hb-subset-plan.hh |  4 ++++
+ src/hb-subset.cc      | 11 ++++++-----
+ 3 files changed, 21 insertions(+), 5 deletions(-)
+
+commit 81640fdffe5a57191b392eda2d93fcf39183dbcf
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 20:22:36 2022 +0000
+
+    [subset] fix leaked font in glyf::subset(...)
+
+ src/OT/glyf/glyf.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit dcce53ddcb52d10dca1ff1d3e118297175892c26
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 13:19:38 2022 -0700
+
+    [cff] Micro-optimize fetch_op
+
+ src/hb-cff-interp-common.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 0bf7d9eb4dd1b706a139e56638d2e8db0ccab933
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 13:00:23 2022 -0700
+
+    [subset-cff] Micro-optimize encode_byte
+
+ src/hb-subset-cff-common.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit a23f820427a7ae7be5b24d66265bd46fb0d4d6df
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 12:56:13 2022 -0700
+
+    [subset-cff] Micro-optimize array access
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1e8f1ac6774226a12cb6d9794f300a103a590ea4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 12:28:29 2022 -0700
+
+    [subset-glyf] Micro-optimize array access
+
+ src/OT/glyf/SimpleGlyph.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 356d135ed698042f6337486e5c8cb2fe6206c44a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 23 12:20:51 2022 -0700
+
+    [subset-glyf] Reduce roundf calls
+    
+    Saves 7% on MPLUS1-Variable/6000 benchmark.
+
+ src/OT/glyf/Glyph.hh | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+commit 463ae07e9982e337b9340cb24598db57d008e33c
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Nov 23 18:41:23 2022 +0000
+
+    [subset] In the preprocess subset call always use long loca.
+    
+    Long loca is needed so that we can store the trimmed glyph bytes to allow us to safely skip trimming in the later subset.
+
+ src/OT/glyf/glyf.hh    | 9 ++++++---
+ src/hb-subset-input.cc | 5 +++++
+ src/hb-subset-input.hh | 4 ++++
+ src/hb-subset-plan.cc  | 1 +
+ src/hb-subset-plan.hh  | 1 +
+ 5 files changed, 17 insertions(+), 3 deletions(-)
+
+commit 299ec902eb3f657b71517ac1cd1f477ceec6b409
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 16:03:02 2022 -0700
+
+    [glyf] Move instanciation to serialize()
+
+ src/OT/glyf/SubsetGlyph.hh | 10 +++++++++-
+ src/OT/glyf/glyf.hh        | 46 ++++++++++++++--------------------------------
+ 2 files changed, 23 insertions(+), 33 deletions(-)
+
+commit d8d881f22d634573afd4860415e9dda29ce44492
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 15:24:16 2022 -0700
+
+    [subset-glyf] Don't create a second glyf accelerator
+
+ src/OT/glyf/glyf.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 75609300707fedc45d7a2bc6d9b62793ad212aa4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 15:22:25 2022 -0700
+
+    [glyf] Add _create_font_for_instancing
+
+ src/OT/glyf/glyf.hh | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+commit 40634ceeb0bf1bdb6c2b12e90ecac9e45c2e4671
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 15:07:16 2022 -0700
+
+    [glyf] Adjust data types
+
+ src/OT/glyf/SimpleGlyph.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit ba0d28ea3647fe5d8108ba4f2ca60be7f267c043
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 15:01:48 2022 -0700
+
+    [glyf] Fix font error check
+
+ src/OT/glyf/glyf.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 04c525019c84e4683e99674624e199c0598e38e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:54:55 2022 -0700
+
+    [glyf] Use a malloc instead of calloc
+
+ src/OT/glyf/SimpleGlyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 024aa818051712a5ea14e8d1ad7603a5ab9ca4ef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:51:42 2022 -0700
+
+    [glyf] Micro-optimize encode_coord
+
+ src/OT/glyf/SimpleGlyph.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit b6694597f9b80d37fd8361723ae34861019a46ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:49:01 2022 -0700
+
+    [glyf] Micro-optimize encode_flag()
+
+ src/OT/glyf/SimpleGlyph.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit d47cfe79364391bd10ceb8588f4cdb55ff6e47e8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:45:04 2022 -0700
+
+    [glyf] Minor use operator ++
+
+ src/OT/glyf/SimpleGlyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 03e6bde79035a5d3e25c9a571fab8b1d916c069c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:40:36 2022 -0700
+
+    [glyf] Minor adjustment to lastflag handling
+    
+    No logic change.
+
+ src/OT/glyf/SimpleGlyph.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 0ca9fda889a97febac66bcc86bda9211628bd7ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:39:10 2022 -0700
+
+    [glyf] Remove misplaced comment
+
+ src/OT/glyf/SimpleGlyph.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 44be8ef4ce883f6ce9680f6f489d37722711fa8e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:21:25 2022 -0700
+
+    [gvar] Skip degenerate all-untouched delta-sets
+
+ src/hb-ot-var-gvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 656bb223f17343d68dcd6118d6afdb85b7298345
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:16:40 2022 -0700
+
+    [gvar] Micro-optimize unpack_points
+
+ src/hb-ot-var-gvar-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit a383027262d5d073da29e4bc45ef2b99c734a1de
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 14:15:17 2022 -0700
+
+    [gvar] Cosmetic
+
+ src/hb-ot-var-gvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit be89919a7097d6ba1fa4e3042627d13fac545e53
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 13:56:20 2022 -0700
+
+    [gvar] is_valid() remove a check
+    
+    I don't know why this check was there, but it doesn't make sense
+    because that function never returns 0 / false.
+
+ src/hb-ot-var-gvar-table.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit e8ddf107d0f3ecd66db901c748028bf642210ae8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 13:29:32 2022 -0700
+
+    [gvar] Optimize a loop
+
+ src/hb-ot-var-gvar-table.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit dd6fcec92ccc609435312dd42b9ae3c98c88af40
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 13:27:40 2022 -0700
+
+    [gvar] Remove a conditional
+
+ src/hb-ot-var-gvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a02317238af994b15f280b33d20a0eb8e75ae711
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 13:24:39 2022 -0700
+
+    [gvar] Refactor deltas array access
+
+ src/hb-ot-var-gvar-table.hh | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+commit c34c77698c473cdaa85a703a75db85ee5f328d7f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 13:21:01 2022 -0700
+
+    [gvar] Don't try IUP if all points are specified
+
+ src/hb-ot-var-gvar-table.hh | 84 ++++++++++++++++++++++++---------------------
+ 1 file changed, 45 insertions(+), 39 deletions(-)
+
+commit 27c4037e5988d41b92c7c3904d4ceeea8c31586c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 13:12:22 2022 -0700
+
+    [gvar] Micro-optimize boundary-checking
+
+ src/hb-ot-var-gvar-table.hh | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit ab8346fb6fee2fd64204cc880c5f75f3b1b33ff9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 13:07:39 2022 -0700
+
+    [gvar] Add an unlikely
+
+ src/hb-ot-var-gvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1e8a342ea2769f368be6dbf0bf6b0aaf99af1db7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 13:02:38 2022 -0700
+
+    [gvar] Micro-optimize int types
+
+ src/hb-ot-var-gvar-table.hh | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit 4afcdf675ba9b134a92659090aa4bf0b7a39d5f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 12:56:48 2022 -0700
+
+    More hb_memcpy
+
+ src/OT/glyf/CompositeGlyph.hh | 16 ++++++++--------
+ src/OT/glyf/SimpleGlyph.hh    | 10 +++++-----
+ src/graph/gsubgpos-graph.hh   |  2 +-
+ src/graph/pairpos-graph.hh    |  2 +-
+ src/graph/serialize.hh        |  2 +-
+ 5 files changed, 16 insertions(+), 16 deletions(-)
+
+commit 58a696d80ed3158c88e8e95345642cbd4db75eaa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 12:56:05 2022 -0700
+
+    More hb_memset
+
+ src/OT/Layout/Common/Coverage.hh  | 2 +-
+ src/hb-buffer-deserialize-json.rl | 4 ++--
+ src/hb-buffer-deserialize-text.rl | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 59c45f6debd8e266286ba7b34314a3b625d8a307
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 12:54:50 2022 -0700
+
+    Use hb_memcpy instead of memcpy consistently
+
+ src/hb-aat-layout-morx-table.hh |  8 ++++----
+ src/hb-blob.cc                  |  2 +-
+ src/hb-buffer-serialize.cc      |  8 ++++----
+ src/hb-buffer.cc                |  6 +++---
+ src/hb-cff-interp-common.hh     |  2 +-
+ src/hb-common.cc                |  8 ++++----
+ src/hb-font.cc                  | 10 +++++-----
+ src/hb-open-file.hh             |  2 +-
+ src/hb-ot-cff-common.hh         |  6 +++---
+ src/hb-ot-cff1-table.hh         |  4 ++--
+ src/hb-ot-cff2-table.hh         |  4 ++--
+ src/hb-ot-color-cbdt-table.hh   |  2 +-
+ src/hb-ot-layout-common.hh      |  2 +-
+ src/hb-ot-math-table.hh         |  4 ++--
+ src/hb-ot-name-table.hh         |  2 +-
+ src/hb-ot-post-table.hh         |  2 +-
+ src/hb-ot-stat-table.hh         |  2 +-
+ src/hb-ot-tag.cc                |  2 +-
+ src/hb-ot-var-common.hh         |  2 +-
+ src/hb-ot-var-gvar-table.hh     |  4 ++--
+ src/hb-serialize.hh             |  8 ++++----
+ src/hb-shape-plan.cc            |  2 +-
+ src/hb-shaper.cc                |  2 +-
+ src/hb-subset-cff-common.hh     |  4 ++--
+ src/hb-uniscribe.cc             |  4 ++--
+ src/test-repacker.cc            |  2 +-
+ 26 files changed, 52 insertions(+), 52 deletions(-)
+
+commit ac0efaf8181636fdecbffa79c629547e072f5287
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 12:50:36 2022 -0700
+
+    Use hb_memset instead of memset consistently
+
+ src/hb-aat-map.hh                 |  2 +-
+ src/hb-bit-page.hh                |  6 +++---
+ src/hb-buffer-deserialize-json.hh |  4 ++--
+ src/hb-buffer-deserialize-text.hh | 28 ++++++++++++++--------------
+ src/hb-buffer.cc                  | 12 ++++++------
+ src/hb-common.cc                  |  4 ++--
+ src/hb-font.cc                    |  6 +++---
+ src/hb-font.hh                    |  6 +++---
+ src/hb-graphite2.cc               |  2 +-
+ src/hb-ot-map.cc                  |  2 +-
+ src/hb-ot-map.hh                  |  2 +-
+ src/hb-pool.hh                    |  2 +-
+ src/hb-uniscribe.cc               |  2 +-
+ 13 files changed, 39 insertions(+), 39 deletions(-)
+
+commit 44a892a233e0441a0bac84a680aebf2362f2c227
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 12:48:52 2022 -0700
+
+    [shape] Use hb_memcmp instead of memcmp
+
+ src/hb-ot-shape.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c53c64812724762b91ff397c56f6701d42d000b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 12:46:25 2022 -0700
+
+    [subset-cff] Another handrolled memcpy
+
+ src/hb-subset-cff-common.hh | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit ae578705c2ac7f8d520ff5f6646c2efe57469902
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 12:23:17 2022 -0700
+
+    [array] Write hash as range for loop again
+    
+    Now that our range loop is faster than our own iter.
+
+ src/hb-array.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 13e1ca9eb520d7a5ca1092d2bf8566669d8b5580
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 12:19:28 2022 -0700
+
+    [cff] Micro-optimize memcpy
+
+ src/hb-cff-interp-common.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 2968dd7844c71734e0e052bb1a9eb7875e214961
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 11:57:29 2022 -0700
+
+    [gvar] Optimize as_array() access
+
+ src/hb-ot-var-gvar-table.hh | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+commit bb3bb76450c575321aecf33b74e5b51d0c5c75e3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 11:53:35 2022 -0700
+
+    [gvar] Optimize scalar = 1.0 case
+
+ src/hb-ot-var-gvar-table.hh | 26 ++++++++++++++++++--------
+ 1 file changed, 18 insertions(+), 8 deletions(-)
+
+commit 2d098d5d7f223d587abe4e8926a911cfbb5eef62
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 11:51:04 2022 -0700
+
+    [gvar] Use memset
+
+ src/hb-ot-var-gvar-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e630a65e604ea4d1fc4fb4818c456c3d450fede4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 11:27:05 2022 -0700
+
+    [gvar] Micro-optize vector extend
+
+ src/hb-ot-var-gvar-table.hh | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+commit 49d4f62135f34983ea1e47828f6f549d4f581f9a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 11:14:56 2022 -0700
+
+    [gvar] Micro-optimize
+
+ src/hb-ot-var-gvar-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1758ee6646f69f80bbcd79d93fc4992aeaf6c2bc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 10:45:49 2022 -0700
+
+    [glyf] Minor write loop more idiomatically
+
+ src/OT/glyf/SimpleGlyph.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 16ec9dcc1bb7f4e710d4c4b83f3900dc15b29c3b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 10:43:46 2022 -0700
+
+    [gvar] Whitespace
+
+ src/hb-ot-var-gvar-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit b567ce51d3724c6dc89cce72257dd5baf245fc9a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 20:08:54 2022 -0700
+
+    [subset] Don't trim glyf's again if preprocessed
+    
+    Speeds up M1/10000 benchmark by 30%!
+
+ src/OT/glyf/glyf.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 72059a47891d2ecf875dcf36836a2cabe599502a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 10:41:37 2022 -0700
+
+    [gvar] Optimize IUP alg
+
+ src/hb-ot-var-gvar-table.hh | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit ee9873b5ede5ee14a542dd1d4bc470695487c5f4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 10:23:17 2022 -0700
+
+    [gvar] Disable initializing vectors when not necessary
+
+ src/hb-ot-var-gvar-table.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit b0d2641186e269da1f1556bf7d1c8b8c7763ccb3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 10:20:11 2022 -0700
+
+    [vector] Add "initialize" argument to resize()
+
+ src/hb-vector.hh | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+commit a2059f8f55ebbc8cbc6adf7df0d1886ee130f2dd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 10:16:21 2022 -0700
+
+    [gvar] Optimize unpack_points
+
+ src/hb-ot-var-gvar-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 6d7206b68bbb4cd99f2a53ff8ac61114d272a958
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 22 10:13:14 2022 -0700
+
+    [gvar] Optimize unpack_deltas
+
+ src/hb-ot-var-gvar-table.hh | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit bca569ae535e4fb7a38f9ec9514e667fc15a29d2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 23:19:42 2022 -0700
+
+    [array] Speed up hash() for byte arrays
+
+ src/hb-array.hh | 32 ++++++++++++++++++++++++++++----
+ 1 file changed, 28 insertions(+), 4 deletions(-)
+
+commit d7b492e3f589f8ba0d034a818a83a1d14a86b443
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 23:08:51 2022 -0700
+
+    Revert "[array] Remove hash specializations for bytes"
+    
+    This reverts commit 213117317cefeb4e75d21c5c21e383309f116bb0.
+
+ src/hb-array.hh | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+commit 1572ba281acb7fb3510d97e0f52bea83a1d6050d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 22:26:44 2022 -0700
+
+    [subset-cff] Return in subr closure if already seen subr
+    
+    Not sure why this was not done before.
+
+ src/hb-subset-cff-common.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit a29ca6efbc7ee4a7832fdf66bdda07654e28496a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 22:02:17 2022 -0700
+
+    [subset-cff] Comment
+
+ src/hb-subset-cff-common.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 28e767ddea3acea744fad3f8e44f1f8f3b4d198d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 21:59:51 2022 -0700
+
+    [subset-cff] Really optimize op_str_t / parsed_cs_op_t layout
+    
+    Now parsed_cs_op_t and op_str_t are both 16 bytes.
+    
+    Saves another 7% in SourceHanSans/10000 benchmark.
+
+ src/hb-cff-interp-common.hh | 9 ++++++---
+ src/hb-subset-cff-common.hh | 5 +++--
+ 2 files changed, 9 insertions(+), 5 deletions(-)
+
+commit 2d5ee23731ecbd779a36142cd32f8d50eae88ff2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 21:37:38 2022 -0700
+
+    [subset-cff] Readjust parsed_cs_op_t
+    
+    Now it doesn't matter anymore since op_str_t is adjusted and
+    is 16 bytes with 8byte alignment.
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4f056b923a99236b70d52236a4e3c293242c3216
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 21:37:38 2022 -0700
+
+    [subset-cff] Optimize op_str_t layout
+
+ src/hb-cff-interp-common.hh | 18 +++++++++++++-----
+ src/hb-subset-cff-common.hh | 20 ++++++++++----------
+ src/hb-subset-cff1.cc       |  5 +++--
+ 3 files changed, 26 insertions(+), 17 deletions(-)
+
+commit a750cb012855558e137c8eb483af1c94ea7d3e00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 21:03:32 2022 -0700
+
+    Simplify rvalue creation
+
+ src/hb-subset-plan.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 86a763c651090094f35f1995cba7a923aaa9e0d3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 20:53:44 2022 -0700
+
+    [map] Make keys moveable
+
+ src/hb-map.hh   | 10 ++++++----
+ src/test-map.cc |  6 ++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+commit cf20d2ec5d609a5a9319b5b1f6cdf5616d41d13d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 20:46:01 2022 -0700
+
+    [map] Take const key
+
+ src/hb-map.hh         | 10 +++++-----
+ src/hb-subset-plan.hh |  6 +++---
+ src/test-map.cc       |  2 +-
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 3d1c76f713844f192aa11af956e9ee84f097b071
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 19:40:32 2022 -0700
+
+    [serializer] Don't hash objects twice
+
+ src/hb-map.hh       | 78 ++++++++++++++++++++++++++---------------------------
+ src/hb-serialize.hh |  6 +++--
+ src/test-map.cc     |  2 +-
+ 3 files changed, 43 insertions(+), 43 deletions(-)
+
+commit 35878df2155f38e981acde5888141bb61bd9ab63
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 19:14:03 2022 -0700
+
+    [algs] Implement swap() for pair_t
+    
+    Helps priority_queue::pop_minimum and friends, which help subsetter
+    repacker. Shows a few percentage improvement on NotoNastaliq benchmark.
+
+ src/hb-algs.hh | 29 ++++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 11 deletions(-)
+
+commit a2984a2932c94312d75dfc64485c8afaa97a34b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 18:40:01 2022 -0700
+
+    [cff] Remove unnecessary namespacing
+
+ src/hb-ot-cff-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit dc3bb5e0ed4f44e3a11474656ecf2cd8b7d86a68
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 18:18:48 2022 -0700
+
+    [subset-cff] Pre-allocate values array for subroutines as well
+
+ src/hb-cff-interp-common.hh | 2 ++
+ src/hb-subset-cff-common.hh | 4 ++++
+ 2 files changed, 6 insertions(+)
+
+commit c6279224dbe5b2b8d3895cd91429178fc408e23a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 18:01:50 2022 -0700
+
+    [cff] Adjust pre-allocation
+    
+    This better matches actual usage, given that ops are one or two
+    bytes, and vector also allocates 50% extra.
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit bab8ec58b044272d45d584e8f16c6715ca21ee89
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 17:46:32 2022 -0700
+
+    [subset-cff] Disable sharing when packing charstring INDEXes
+    
+    Saves another 8%ish.
+
+ src/hb-subset-cff1.cc | 6 +++---
+ src/hb-subset-cff2.cc | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 2cadacad6c1da254fc778db3300aa6c53d0de420
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 17:17:15 2022 -0700
+
+    [cff] Simplify str_encoder_t error handling
+
+ src/hb-subset-cff-common.hh | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+commit f263e3fe2e11810a517925d580640a21402ae36b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 17:04:55 2022 -0700
+
+    [cff] Manually copy short strings instead of memcpy()
+
+ src/hb-subset-cff-common.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 38efd1862fd42e8323aa93da9c6f9685ea4919fc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 17:02:11 2022 -0700
+
+    [cff] Add a likely()
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 191025cc96b2f72dd893619b7d296001609c168d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 16:58:19 2022 -0700
+
+    [cff] Adjust buffer pre-allocation
+    
+    Most ops take one or two bytes, so allocate count*2, not count*3.
+    Shows minor speedup in subsetting benchmark (around 2%).
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4b2caafea2cd2902b866a94c965f20d1caabad5e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 16:46:20 2022 -0700
+
+    [subset-cff] Optimize parsed_cs_op_t size
+    
+    Shows 5% speedup on SourceHanSans-Regular/10000 benchmark.
+
+ src/hb-subset-cff-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit e0b06bd1b1daaac4d8e020db9ac3ec1fcaad38b6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 16:09:39 2022 -0700
+
+    [subset] Cache has_seac in accelerator
+    
+    Speeds up SourceHanSans-Regular/10000 benchmark by %25.
+
+ src/hb-subset-accelerator.hh |  5 ++++-
+ src/hb-subset-plan.cc        | 16 ++++++++++++----
+ src/hb-subset-plan.hh        |  1 +
+ src/hb-subset.cc             |  3 ++-
+ 4 files changed, 19 insertions(+), 6 deletions(-)
+
+commit dd1ba328a8d49ff43633eda43013fd5dd1fe2ada
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Nov 21 23:20:59 2022 +0000
+
+    [repacker] fix fuzzer timeout.
+    
+    For https://oss-fuzz.com/testcase-detail/5845846876356608. Only process the set of unique overflows.
+
+ src/graph/serialize.hh                             |  21 +++++++++++++++++++++
+ ...ase-minimized-hb-subset-fuzzer-5845846876356608 | Bin 0 -> 427854 bytes
+ 2 files changed, 21 insertions(+)
+
+commit 59451502e99ff0dd73361a53fc576cb8b0057d75
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 15:23:16 2022 -0700
+
+    [cff] Optimize env error checking
+
+ src/hb-cff-interp-common.hh | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit b238578a9c9255282b7634bcbf751f03001ceda6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 14:36:57 2022 -0700
+
+    [cff] Optimize INDEX operator[]
+
+ src/hb-ot-cff-common.hh | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit d9de515a382c169f50a56fc7292aa96f62366ce8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 14:23:07 2022 -0700
+
+    [cff] Optimize byte_str_ref_t array access
+
+ src/hb-cff-interp-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a81ec9b2b6734e66c0d532ae4da1b6788dd59f0c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 14:03:28 2022 -0700
+
+    [cff] Optimize byte_str_ref_t inc()
+    
+    Shows a couple percent speedup.
+
+ src/hb-cff-interp-common.hh | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit 3ff75411bdc29094c4664f834703dc5c4cf117c7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 13:08:55 2022 -0700
+
+    [algs] Fix bot fail
+
+ src/hb-algs.hh           | 2 +-
+ src/hb-ot-shaper-thai.cc | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit b81e3989f83da88e387e04b54bdb85d1f26ed5e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 13:02:40 2022 -0700
+
+    Try fixing arm-eabi build after a10cfe3f32861c13578dc21476b2fe4d2e0af43c
+
+ src/hb-ot-shaper-thai.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c14043b06cb28cef5a8a6ebfc39a0c83902d423
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 12:56:33 2022 -0700
+
+    [algs] Add output argument to hb_unsigned_mul_overflows()
+
+ src/hb-algs.hh     | 10 +++++++---
+ src/hb-buffer.cc   | 20 ++++++++++----------
+ src/hb-sanitize.hh | 15 +++++++++------
+ 3 files changed, 26 insertions(+), 19 deletions(-)
+
+commit 25adbb382535de2c981755df211295249a93c4e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 12:47:53 2022 -0700
+
+    [algs] Use __builtin_mul_overflow
+    
+    Compiles to smaller binary.
+
+ src/hb-algs.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit a10cfe3f32861c13578dc21476b2fe4d2e0af43c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 12:37:59 2022 -0700
+
+    [algs] Write hb_in_ranges() recursively
+
+ src/hb-algs.hh | 15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+commit 2e86700e30265e839f7b00e4bdaf43b5fe04bde2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 12:28:10 2022 -0700
+
+    [gvar] Add memory-barrier as in ArrayOf
+
+ src/hb-ot-var-gvar-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit b00a911fa721598b1b7c44943790671506091542
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 12:11:30 2022 -0700
+
+    [sorted-array] Add faster iterator implementation here as well
+
+ src/hb-array.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 7cc79a8a86835bc641bf56c0b82e36063f44e22f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 12:09:24 2022 -0700
+
+    [vector] Adjust comment
+
+ src/hb-vector.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e82a3c69dd5155b7bcd41fe2131514fa780da24a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 12:00:10 2022 -0700
+
+    [array/vector] Optimize range-based for-loop
+    
+    Avoid bounds-checking.
+
+ src/hb-array.hh  |  5 +++++
+ src/hb-iter.hh   | 16 ++++++++++------
+ src/hb-ot-map.cc |  3 +--
+ src/hb-vector.hh |  5 +++++
+ 4 files changed, 21 insertions(+), 8 deletions(-)
+
+commit 0387182c2a198c69f2313bc8627762477bae4bde
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 11:05:47 2022 -0700
+
+    [ot-map] Minor refactor features[i] access
+
+ src/hb-ot-map.cc | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+commit 5ee6d5d77e373314e007d736f04b3686723d1cfd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 11:00:29 2022 -0700
+
+    [cff] Add memory-barrier to INDEX
+    
+    Like we do for ArrayOf.
+
+ src/hb-ot-cff-common.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 6905d36d73f7b33243aaa8507ded49272462d3f8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 10:51:33 2022 -0700
+
+    [cff] Fix fetch_op() bounds-checking
+
+ src/hb-cff-interp-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit b51ab1a9e515f10ed6906b9e1149120854c48260
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 10:27:07 2022 -0700
+
+    [cff] Optimize byte_str_ref_t
+    
+    Make it 16 bytes instead of 24.  This struct is used in the subroutine
+    call stack heavily.
+    
+    This change makes the HB AdobeVFPrototype benchmark to become faster
+    than FT one, with about 6% speedup as a result of this change.
+
+ src/hb-cff-interp-common.hh | 36 ++++++++++++++++--------------------
+ 1 file changed, 16 insertions(+), 20 deletions(-)
+
+commit 7a39464b1883dd4e04608427522d545e049c8389
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 09:48:54 2022 -0700
+
+    [cff] Hide members of byte_str_ref_t
+
+ src/hb-cff-interp-common.hh | 13 +++++++------
+ src/hb-ot-cff1-table.hh     |  2 +-
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+commit 18141f00070d2134fb45a68edad026cc83b0f2ea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 09:47:03 2022 -0700
+
+    [cff] Move a sub_array call
+    
+    No logic change.... I hope?!
+
+ src/hb-cff-interp-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f66415cdd17009463cbc79e6fe3af1edc08a3649
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 09:39:27 2022 -0700
+
+    [cff] Move initialization of a type to constructor
+
+ src/hb-cff-interp-common.hh | 12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+commit 70a5cd53f645ff70f6dbcb306fbde3bc778abece
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 21 08:52:33 2022 -0700
+
+    [algs] Assert trivial copy assignable in stable_sort
+
+ src/hb-algs.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 9bb39423f5c46fb2f69ac8975de1433020e46411
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 20 17:40:54 2022 -0700
+
+    [algs] Simplify stable_sort signatures
+
+ src/hb-algs.hh | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+commit d119568df6bb1691bb9f8146a020811ded5c8dfd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 20 14:11:51 2022 -0700
+
+    [cbdt] Use vector tail()
+
+ src/hb-ot-color-cbdt-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 87a88117c8fe819eccce98c71e5f912a756ade96
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 20 14:10:39 2022 -0700
+
+    [object] Use vector tail()
+
+ src/hb-object.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 76ce390b5ae15004ff8abf8c6360a377c0656dd6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 20 13:54:56 2022 -0700
+
+    [ucd] Document algorithms
+
+ src/gen-ucd-table.py | 33 ++++++++++++++++++++++++++++++---
+ src/hb-ucd.cc        | 16 ++++++++++++++++
+ 2 files changed, 46 insertions(+), 3 deletions(-)
+
+commit ed43bc5118edb0cdcbbfac4d31f514d7aa86ebe4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 20 13:10:19 2022 -0700
+
+    [buffer] Move delete_glyphs_inplace() here
+
+ src/hb-aat-layout.cc |  2 +-
+ src/hb-buffer.cc     | 47 +++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-buffer.hh     |  2 ++
+ src/hb-ot-layout.cc  | 50 --------------------------------------------------
+ src/hb-ot-layout.hh  |  4 ----
+ src/hb-ot-shape.cc   |  2 +-
+ 6 files changed, 51 insertions(+), 56 deletions(-)
+
+commit dd88dae8a9f140c6bbc44d3efd44a37acc71c0c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 15:22:39 2022 -0700
+
+    [unicode] Simplify set_funcs a bit more
+
+ src/hb-unicode.cc | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+commit 2d8ff3bcbe69f9d573f2075ef0e3c3d061f1133f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 15:23:44 2022 -0700
+
+    [unicode] Destroy user_data in set_funcs fail paths
+    
+    This is what the font_funcs / draw_funcs do.
+
+ src/hb-unicode.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 527823ccacf2b1e9807ea5b15e8ea15c1f4ddeb1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 15:19:08 2022 -0700
+
+    [unicode] Destroy user_data in set_funcs fail paths
+    
+    This is what the font_funcs / draw_funcs do.
+
+ src/hb-unicode.cc       | 14 +++++++++++++-
+ test/api/test-unicode.c |  4 ++--
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+commit 56d6b6992b630ea81b681b2876dbcee97164b617
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 15:08:50 2022 -0700
+
+    [font/draw] Remove unneeded branch
+    
+    The preamble sets user_data/destroy to nullptr if func is nullptr.
+
+ src/hb-draw.cc | 19 +++++++------------
+ src/hb-font.cc | 18 +++++++-----------
+ 2 files changed, 14 insertions(+), 23 deletions(-)
+
+commit 976bb26cc14909273959695691c65b099349666b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 15:06:23 2022 -0700
+
+    [draw] Optimize set_func functions
+
+ src/hb-draw.cc | 72 +++++++++++++++++++++++++++++++++++++++++++---------------
+ src/hb-font.cc | 18 +++++++--------
+ 2 files changed, 63 insertions(+), 27 deletions(-)
+
+commit 114167a9333ebd492832ed45fcf86484def1d909
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 14:47:45 2022 -0700
+
+    [font] Optimize set_func functions
+
+ src/hb-font.cc | 81 ++++++++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 54 insertions(+), 27 deletions(-)
+
+commit f9d7b303ede471a58393d730c4ca3cf935ac7f8b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 14:20:36 2022 -0700
+
+    [thai] Use smaller type for arrays
+    
+    No logic change.
+
+ src/hb-ot-shaper-thai.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 72c4e431af13a2c5108998b6d23d3f36d0f97b25
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 13:40:33 2022 -0700
+
+    [use-table] Add a OPTIMIZE_SIZE version
+
+ src/gen-use-table.py          |  28 ++++-
+ src/hb-ot-shaper-use-table.hh | 270 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 293 insertions(+), 5 deletions(-)
+
+commit 83c3a91dc6a1e666383987e37e2ef934ffb245bc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 13:34:58 2022 -0700
+
+    [gen-use-table] Report fullCost
+
+ src/gen-use-table.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit ba08de624ef42229933061ae9837512196b5c53e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 19 13:14:18 2022 -0700
+
+    [ucd] Change OPTIMIZE_SIZE to compression level 9
+    
+    Also changes default compression level from 3 to 5, but that shows
+    no change in the generated table size.
+
+ src/gen-ucd-table.py |   24 +-
+ src/hb-ucd-table.hh  | 3892 ++++++++++++++++++++++++--------------------------
+ 2 files changed, 1871 insertions(+), 2045 deletions(-)
+
+commit b68f9f3cfecc23c7f1af128256e652cdb2c04a80
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 21:35:35 2022 -0700
+
+    [machinery] Adjust comment
+
+ src/hb-machinery.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit a47ba1dc0eafa93af0b390f8cc61a8d0573cbf1a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 21:14:07 2022 -0700
+
+    [lazy-pointer] Hide instance
+
+ src/hb-machinery.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 281b4705b43503e0a377a6ac251f4b48ae00542f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 20:25:05 2022 -0700
+
+    [pool] Rewrite a loop as dagger
+
+ src/hb-pool.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 3ff8abf27287da410883b0f4305cb9426206a60f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 19:35:49 2022 -0700
+
+    Revert "[map] Allow std::move-ing keys into the map"
+    
+    This reverts commit f657ef7e57c889309c2d9d37934368ca255f9d5b.
+    
+    This breaks many compilers with messages like this:
+    
+    hb-subset-plan.hh:226: undefined reference to `OT::head::tableTag'
+    
+    I'm out of my depth re how to fix it.
+
+ src/hb-map.hh   | 15 ++++++---------
+ src/test-map.cc |  6 ++++--
+ 2 files changed, 10 insertions(+), 11 deletions(-)
+
+commit 039e476baccd87786e79e3b483c526d784f5631c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 19:26:02 2022 -0700
+
+    [test-vector] Test sink-move'ing
+
+ src/test-vector.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit a3a218edb57e63f49b49ef847b258b641609a1d7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 19:24:41 2022 -0700
+
+    [map] Add a couple more sink interfaces
+
+ src/hb-map.hh   | 4 ++++
+ src/test-map.cc | 2 ++
+ 2 files changed, 6 insertions(+)
+
+commit 90226eab8933975cb5a6f4e7f7f8067c0a24a68a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 19:21:58 2022 -0700
+
+    [test-map] Test inserting shared_ptr key
+
+ src/test-map.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit f657ef7e57c889309c2d9d37934368ca255f9d5b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 19:17:03 2022 -0700
+
+    [map] Allow std::move-ing keys into the map
+
+ src/hb-map.hh   | 15 +++++++++------
+ src/test-map.cc |  2 ++
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+commit a1768ad82938922cda34603371af86ff8035beac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 19:08:34 2022 -0700
+
+    [map] Fix use of !=
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e74b372b59db623f246499db12e8e9707648ccce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 18:41:39 2022 -0700
+
+    [test-map] Test moving values
+
+ src/test-map.cc | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+commit a9c6a20b193bfa26a43b0d5a1021038dfe4c8ba4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 18:29:12 2022 -0700
+
+    [map] Support moving value in sink interface
+
+ src/hb-algs.hh  |  2 +-
+ src/hb-map.hh   |  2 ++
+ src/test-map.cc | 10 +++++++++-
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+commit 1bf9afaad0c7b05d6fbd97805449561b4cc4c5fe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 18:20:50 2022 -0700
+
+    [test-vector] Test sink interface
+
+ src/test-vector.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit fa0e4b041d8d3525a84f838a27b84d2a100025cf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 18:20:14 2022 -0700
+
+    [test-map] Test sink interface
+
+ src/test-map.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1c612a85415ed3b0aec4907817f5ed7211dd1c3c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 18:18:42 2022 -0700
+
+    [test-set] Test sinking range
+
+ src/test-set.cc | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit 356708e34a52bbf22cafa44771ee6eeaefc8a80b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 18:17:34 2022 -0700
+
+    [test-set] Test length of iterator
+
+ src/test-set.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 2892fc71e8733890db666afe0ccbd491c0c0bbd2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 18:03:59 2022 -0700
+
+    [vector] Add std::move to pop()
+    
+    This was removed in 76fc27713f52cc338f0325650c2c7798f5cfa2ce,
+    but I believe that was faultly. It was because of a bad move
+    implementation in the set.
+
+ src/hb-vector.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 921f45f46d2f973113d79fd68adb59ae8c0141af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 17:26:58 2022 -0700
+
+    [array] Rewrite hash() as dagger
+
+ src/hb-array.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 213117317cefeb4e75d21c5c21e383309f116bb0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 17:24:23 2022 -0700
+
+    [array] Remove hash specializations for bytes
+    
+    Not needed.
+
+ src/hb-array.hh | 15 ---------------
+ 1 file changed, 15 deletions(-)
+
+commit bef5a1c8dc5fd2930e2fd395ad6c1ec4a6a0c2c3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 17:22:17 2022 -0700
+
+    [vector] Comment
+
+ src/hb-vector.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 69b41f92ec97e3c6822541a96daea66258eba637
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 17:04:34 2022 -0700
+
+    [vector] Simplify shift_down_vector()
+    
+    Compiler is smarter than I am.
+
+ src/hb-vector.hh | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+commit 1dd9396c7a4c24fe9d578551fab735bdd699e52a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 17:01:14 2022 -0700
+
+    [vector] Optimize grow_vector() for size
+    
+    Again, compiler is smarter than I am.
+
+ src/hb-vector.hh | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+commit d36f688131070308c222ebb54fbb188c6cbe278f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 17:00:07 2022 -0700
+
+    [vector] Optimize shrink_vector for size
+    
+    Compiler is smarter than I am.
+
+ src/hb-vector.hh | 13 +------------
+ 1 file changed, 1 insertion(+), 12 deletions(-)
+
+commit bc8eded2963376901be02f9d0f563c980b0a67b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:51:24 2022 -0700
+
+    [vector] Remove a for loop
+
+ src/hb-vector.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit afd9a58bd76032f98fa1daf579c780121ddcdfb6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:46:01 2022 -0700
+
+    [vector] Save a couple hb_iter() invocations
+
+ src/hb-vector.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 3ead9863d2fc6ab64984ae5ba49c6c3005679138
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:43:47 2022 -0700
+
+    [map] Add size()
+
+ src/hb-map.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 42db8be1897862d0545471b48a8da765496c7aa0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:41:50 2022 -0700
+
+    [map] Minor remove if condition
+
+ src/hb-map.hh | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+commit 4ec706980c9f5583b9c6db2862b9603bba284055
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:39:30 2022 -0700
+
+    [map] Rewrite hash() as dagger
+    
+    Somehow our daggers instead of for loop save size. I cannot
+    pinpoint why, other than maybe not inlining.
+
+ src/hb-map.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 025a68cb074cde6b150f7edaf9fa87cb11773b56
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:33:04 2022 -0700
+
+    [map] Optimize copy resizing logic
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f1d716871d64641136f2f7f17b0731bed59f3a12
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:31:27 2022 -0700
+
+    [map] Change bucket_for_hash() to item_for_hash()
+
+ src/hb-map.hh | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit d012f9a9b3a38cc313a07780b68e6494cc8c97c0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:29:06 2022 -0700
+
+    [map] Change bucket_for() to item_for()
+
+ src/hb-map.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 68a29020c586a17bcefead7041cf64033a0c3cea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:02:45 2022 -0700
+
+    [bit-page] Write hash() as dagger
+
+ src/hb-bit-page.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 87271e1b2e3e313ab21ee78f947d7470b01fac72
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 16:01:23 2022 -0700
+
+    [bit-page] Write get_population as dagger
+
+ src/hb-bit-page.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 744eb6baf9ff060af52a6457c012e0f6f4c0a0ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 15:56:06 2022 -0700
+
+    [bit-page] Write is_empty() as dagger
+
+ src/hb-bit-page.hh | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit 43a4028f0e22c70a979164ddf037c1f6709a3524
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 15:54:34 2022 -0700
+
+    [algs] Move hb_vector_size_t to bit-page as only user
+
+ src/hb-algs.hh     | 43 -------------------------------------------
+ src/hb-bit-page.hh | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 44 insertions(+), 43 deletions(-)
+
+commit 01f961ac3a1fdfb31c184e66a5b772239a579764
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 15:47:17 2022 -0700
+
+    [gsubgpos] Minor call hb_iter() instead of ->iter() directly
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit bba5765583c5857622512c8c99a40cecc7b38839
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 14:52:17 2022 -0700
+
+    [gsubgpos] Remove a few unnecessary namespace invocations
+
+ src/hb-ot-layout-gsubgpos.hh | 34 +++++++++++++++++-----------------
+ 1 file changed, 17 insertions(+), 17 deletions(-)
+
+commit b4d0d1608d5b86ae5b3021fbf98db0472911c578
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 14:47:33 2022 -0700
+
+    [gsubgpos] Rewrite a couple apply() functions as daggers
+
+ src/hb-ot-layout-gsubgpos.hh | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+commit 76c8214eb51fada2d99c460b59307c7acc4ad074
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 18 12:30:46 2022 -0700
+
+    [gsubgpos] Move member around
+
+ src/hb-ot-layout-gsubgpos.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 81a573008e407a67b9c0ea22d4a9a2d9c22222ac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 16:59:36 2022 -0700
+
+    [map] Optimize storage
+
+ src/hb-map.hh | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit ae080bf202e08f3b9748a2d752ee5a1cc8a522f1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 16:34:58 2022 -0700
+
+    [map] Initialize key and value explicitly
+    
+    If they are of int time they won't be initialized otherwise.
+
+ src/hb-map.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit 1d41b9cb3c5078f4d0dd5b693e611ac8724ec91d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 16:26:48 2022 -0700
+
+    [user-data] std::move item
+
+ src/hb-object.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ff0bb74895ad6b43792cdc2e3add9cbe9c712a15
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 16:17:37 2022 -0700
+
+    [map] Call item_t constructor/destructor directly
+
+ src/hb-map.hh | 34 ++++++++++++++--------------------
+ 1 file changed, 14 insertions(+), 20 deletions(-)
+
+commit 5c8871594955133a5652d4fad07bec20805bfbcf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 16:14:16 2022 -0700
+
+    [map] Add item_t.destruct()
+
+ src/hb-map.hh | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 7f83040836e77c13e5a704ee76b83840389876d4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 16:10:37 2022 -0700
+
+    [map] Simplify (de)construction of item_t
+
+ src/hb-map.hh | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit 99103bd9768fbb2063542c60ecdae317df0ce155
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:57:06 2022 -0700
+
+    [map] Destruct objects when clearing
+
+ src/hb-map.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 4caad5720cecbf28bb9b11aceba4ab8bf79f611e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:51:39 2022 -0700
+
+    [test-map] Add test for reset
+    
+    I expect this to leak now, since we don't destruct items.
+
+ src/test-map.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit e93c01c3ae4e7ed019455dd9098034b506b8c49a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:50:00 2022 -0700
+
+    [map] Rename item clear() to construct()
+
+ src/hb-map.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit fc22d706fe1f72212ad1fba61435a1484b75ffe6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:46:48 2022 -0700
+
+    [test-map] Don't insert null smart-pointers in map
+    
+    Dereferencing them is not supported anymore after
+    3aad7c2ddffc3f882bf33504dbac31be491c4d72
+    
+    We don't support that for regular pointers, so don't supporting
+    them for smart-pointers sounds right to me.
+
+ src/test-map.cc | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit 896377463f880fa653e49184f81ce1190d05e082
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:25:45 2022 -0700
+
+    [map] Don't resize map if not necessary
+
+ src/hb-map.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 7595fa2d9a15518a9ca41f6892a17fd36858e5af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:19:29 2022 -0700
+
+    [map] Fix copy-assignment operator
+    
+    Ouch!
+
+ src/hb-map.hh   |  2 +-
+ src/test-map.cc | 13 ++++++++++++-
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+commit 41f4bdac357a8b4e4a04a470e7afd11f9d416beb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:16:00 2022 -0700
+
+    [map] Fix resize during copy-construction/assignment
+
+ src/hb-map.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3aad7c2ddffc3f882bf33504dbac31be491c4d72
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:10:47 2022 -0700
+
+    [algs] Remove smart-pointers from hb_hash()
+    
+    hb_deref() handles them. I think this code predated that.
+
+ src/hb-algs.hh | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+commit 7bd101728ac1c0223f9f4cda50d37e006bb069da
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 15:01:55 2022 -0700
+
+    [map] Minor use hb_iter instead of hb_array
+
+ src/hb-map.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 238fc14716bc976c1e2891668e79d177a805b8c0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 14:58:50 2022 -0700
+
+    [map] Simplify iterators
+
+ src/hb-map.hh | 35 ++++++++++++++++-------------------
+ 1 file changed, 16 insertions(+), 19 deletions(-)
+
+commit 410c14bfa2c5584d785ac1865a1cd273dfba8c50
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 17 14:53:00 2022 -0700
+
+    [map] Fix equality
+    
+    Ouch!
+
+ src/hb-map.hh   |  2 +-
+ src/test-map.cc | 12 +++++++++++-
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+commit 6dfd4a16e7dd18944c506764983e87f0098bf338
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 22:44:22 2022 -0700
+
+    [ot-font] Remove stale TODO
+
+ src/hb-ot-font.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit a0bde1e1ea5b6496c84424d47461ee48c4517bdc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 21:27:12 2022 -0700
+
+    [open-type] Remove (Sorted)ArrayOf.sub_array()
+
+ src/OT/Layout/GSUB/AlternateSet.hh |  2 +-
+ src/hb-open-file.hh                |  2 +-
+ src/hb-open-type.hh                | 18 ------------------
+ src/hb-ot-layout-common.hh         |  6 +++---
+ src/hb-ot-layout-gdef-table.hh     |  4 ++--
+ src/hb-ot-math-table.hh            |  4 ++--
+ src/hb-ot-meta-table.hh            |  2 +-
+ 7 files changed, 10 insertions(+), 28 deletions(-)
+
+commit f2b5db700f1674e96f7bbf1face89507351e103c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 21:22:43 2022 -0700
+
+    [vector] Remove .sub_array ()
+
+ src/OT/glyf/Glyph.hh | 4 ++--
+ src/hb-ot-map.cc     | 2 +-
+ src/hb-vector.hh     | 9 ---------
+ 3 files changed, 3 insertions(+), 12 deletions(-)
+
+commit c7d57dcf260288818fc0b74852a588d8e5611a12
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 21:21:31 2022 -0700
+
+    [vector/array] Simplify qsort()
+
+ src/hb-array.hh     | 7 -------
+ src/hb-open-type.hh | 4 ++--
+ src/hb-ot-map.cc    | 2 +-
+ src/hb-vector.hh    | 4 +---
+ 4 files changed, 4 insertions(+), 13 deletions(-)
+
+commit 1610008e623ad7cf60b20c28fb02808cdf709aef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 20:02:36 2022 -0700
+
+    [gsubgpos] Minor remove call to hb_iter
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 19ec01d25c68f90bb78150b81363f6744089aa22
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 19:14:42 2022 -0700
+
+    [gsubgpos] Sprinkle const around
+
+ src/hb-ot-layout-gsubgpos.hh | 27 +++++++++++++++------------
+ 1 file changed, 15 insertions(+), 12 deletions(-)
+
+commit 561946c7d57ce2370835236182f475946d646406
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 17:58:59 2022 -0700
+
+    [layout] Comment
+
+ src/hb-ot-layout.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 2268207c19b417e07da4b808b3df257811158c25
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 17:51:22 2022 -0700
+
+    [layout] Update comment
+
+ src/hb-ot-map.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 658f8f4391d768ce87fe7213e7443e79e0982c04
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 17:50:35 2022 -0700
+
+    [layout] Comment
+
+ src/hb-ot-map.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 27a8fe7d58d5bf361ce829ddd9916f8042e129ae
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 17:49:44 2022 -0700
+
+    [layout] Only update buffer digest if buffer changed by a pause
+
+ src/hb-ot-layout.cc          |  9 +++++----
+ src/hb-ot-layout.hh          |  3 ++-
+ src/hb-ot-map.hh             |  2 +-
+ src/hb-ot-shaper-arabic.cc   | 19 +++++++++++--------
+ src/hb-ot-shaper-indic.cc    | 33 ++++++++++++++++++++-------------
+ src/hb-ot-shaper-khmer.cc    | 21 +++++++++++++--------
+ src/hb-ot-shaper-myanmar.cc  | 19 ++++++++++++-------
+ src/hb-ot-shaper-syllabic.cc | 12 +++++++-----
+ src/hb-ot-shaper-syllabic.hh |  4 ++--
+ src/hb-ot-shaper-use.cc      | 33 ++++++++++++++++++++-------------
+ 10 files changed, 93 insertions(+), 62 deletions(-)
+
+commit 8b2a2111235af22ca969898737835e904badf92f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 16:57:44 2022 -0700
+
+    [layout] Keep digest updated in the context
+    
+    Don't recompute digest after every (applied) GSUB lookup.
+
+ src/hb-ot-layout-gsubgpos.hh | 16 ++++++++++------
+ src/hb-ot-layout.cc          | 19 +++++++++----------
+ 2 files changed, 19 insertions(+), 16 deletions(-)
+
+commit a5964a2d2a064941b7090f49f1da2b55938fa95a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 16:45:23 2022 -0700
+
+    [layout] Minor simplify
+
+ src/hb-ot-layout.cc | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 443961971adcfd1a8a2c1d3e8a3aeb8a49297bed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 16:35:00 2022 -0700
+
+    [perf] Add fa-words.txt and use in shape benchmark
+
+ perf/benchmark-shape.cc |     4 +
+ perf/texts/fa-words.txt | 10000 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 10004 insertions(+)
+
+commit 80b87588815bee1be0d083665425caed176ad09e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 16:26:41 2022 -0700
+
+    [layout] Add a buffer message for digest-skipped lookups
+
+ src/hb-ot-layout.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit afa71ee8effa697888daa4e89e4547fa634c42ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 16:22:45 2022 -0700
+
+    Fix alignment error
+
+ src/hb-set-digest.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit dff1b809a0535d3c32cf7e8f10cbd5fb8926bca9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 16:19:05 2022 -0700
+
+    [buffer] Add .digest() and use
+
+ src/hb-buffer.hh    |  9 +++++++++
+ src/hb-ot-layout.cc | 11 ++---------
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+commit 654a2eafc8a0710b2c2edcb4b7d8098bf801cd50
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 16:09:04 2022 -0700
+
+    [layout] Use buffer-digest for GSUB as well
+    
+    Combined with previous commit, this shows up to 12% speed up with
+    Roboto and the en-words (ie. short strings) benchmark, about 5%
+    for longer English tests, and no adverse effect on heavier fonts.
+
+ src/hb-ot-layout.cc | 34 +++++++++++++++++++++-------------
+ 1 file changed, 21 insertions(+), 13 deletions(-)
+
+commit 15b6c3259957f9bbfab848530aa4ff8ece89780e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 15:59:13 2022 -0700
+
+    [layout] Use a buffer digest for GPOS to skip whole lookups
+
+ src/hb-ot-layout-gsubgpos.hh |  2 +-
+ src/hb-ot-layout.cc          | 37 +++++++++++++++++++++++++------------
+ src/hb-set-digest.hh         |  8 ++++++++
+ 3 files changed, 34 insertions(+), 13 deletions(-)
+
+commit a053b84cb92bb8624ae407265377475f45b9f095
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 14:39:25 2022 -0700
+
+    [gsubgpos] Optimize set-digest initialization
+    
+    Previously we were once collecting set-digest for each subtable,
+    and another time for each lookup.
+    
+    Now we compute the one for each lookup simply from the ones for
+    its subtables.
+
+ src/hb-ot-layout-gsubgpos.hh | 7 ++++---
+ src/hb-set-digest.hh         | 8 ++++++++
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+commit 20654cd8891a75e6e44f3f0a467a6d53d65ab3f9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 14:15:58 2022 -0700
+
+    [set-digest] Minor no logic change
+
+ src/hb-set-digest.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit 95b9763dbc011e5aa32b8a9faf2146aa552d6eef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 14:15:01 2022 -0700
+
+    [set-digest] Minor simplify
+
+ src/hb-set-digest.hh | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+commit 9855b678f218ca89376dad44032cd3fc73aadbba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 13:37:34 2022 -0700
+
+    [cache] Minor rewrite assertion
+
+ src/hb-cache.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a10ff20562f9a77b2f1510bdb70a70f3d2699f1c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 13:34:37 2022 -0700
+
+    [ft] Comment
+
+ src/hb-ft.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 557be9502a49b6a2ed736fed8937b77f6afdd5af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 12:47:05 2022 -0700
+
+    [test-vector] Fix test
+
+ src/test-vector.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9027d15410a889a903839aba12b08280d53551ea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 12:39:30 2022 -0700
+
+    [test-iter] Fix leak
+
+ src/test-iter.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit afd716d4cdaa7ac314bc806b4ac4f761d51fbc2e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 12:28:56 2022 -0700
+
+    [serialize] Don't free object-pool in reset()
+
+ src/hb-pool.hh      | 9 +++------
+ src/hb-serialize.hh | 1 -
+ 2 files changed, 3 insertions(+), 7 deletions(-)
+
+commit 02949cf64f6bc9fb9faf5d143519cf50126347f5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 12:06:44 2022 -0700
+
+    [priority-queue] More assert adjustment
+
+ src/hb-priority-queue.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 620ddd762d586d8189212715b56d270ccc6db683
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 12:04:35 2022 -0700
+
+    [priority-queue] Fix asserts
+
+ src/hb-priority-queue.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 57de568aad32ea2f1be894536d695a6aa6b4a12a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 11:50:05 2022 -0700
+
+    [indic-table] Minor adjust empty lines
+
+ src/gen-indic-table.py          |  6 +++---
+ src/hb-ot-shaper-indic-table.cc | 14 ++++++--------
+ 2 files changed, 9 insertions(+), 11 deletions(-)
+
+commit 281a2602cc1c5974814d9eb639e17e1dfd3d112c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 16 11:36:33 2022 -0700
+
+    Update generated file
+
+ src/hb-buffer-deserialize-json.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit f734c26c5c78f56e2d1875f5ce262b6a06093d70
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 15 16:27:56 2022 -0700
+
+    [test-vector] Test inserting set and map
+
+ src/test-vector.cc | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+commit 0a97d27c2b80554d58a51a2f5037a341c18ac993
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 15 16:23:48 2022 -0700
+
+    [test-iter] Add another test
+
+ src/test-iter.cc | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+commit e9e985682af41a8aa106cb0252592a64b536a6db
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 15 16:11:57 2022 -0700
+
+    [fallback-shape] Remove TODO
+
+ src/hb-fallback-shape.cc | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+commit 6df8498da2662cf949770d580d0744817c8acfb8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 15 15:52:04 2022 -0700
+
+    [sample.py] Fix warning
+
+ src/sample.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 49fe5c1e5a329d033e55ce87ceff7fae1bf28f4b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 15 15:37:23 2022 -0700
+
+    [glib] Remove old cruft from pre-2011
+
+ src/hb-glib.cc | 77 +++-------------------------------------------------------
+ 1 file changed, 4 insertions(+), 73 deletions(-)
+
+commit 1bd1a37837c1a57fc8a440a6a75b7e6c2778b810
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 15 15:18:36 2022 -0700
+
+    [test] Minor
+
+ src/test-map.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 35aa492eb71def762ecb24c924c1b65c6abb340c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 15 15:05:15 2022 -0700
+
+    [main] sprintf -> snprintf
+
+ src/main.cc | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit 72c6962012fab7a4bfe345687d10f8d08c672151
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 21:34:16 2022 -0700
+
+    [buffer-deserialize-text] Fix glyph name for glyph flags
+    
+    Skip "#" in glyph names.
+
+ src/hb-buffer-deserialize-text.hh | 462 +++++++++++++-------------------------
+ src/hb-buffer-deserialize-text.rl |   2 +-
+ 2 files changed, 160 insertions(+), 304 deletions(-)
+
+commit dee26de76fc3fdfa2dbfc780c62120206229f1f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 16:24:25 2022 -0700
+
+    [test-buffer-serialize] Allow no font
+
+ src/test-buffer-serialize.cc | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+commit f6076890c5103f7078196d14cfc15323a4781b17
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 16:06:39 2022 -0700
+
+    Hide all mentions of name_table_overrides behind EXPERIMENTAL_API
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3872
+
+ src/hb-ot-name-table.hh | 39 ++++++++++++++++++++++++++++++---------
+ src/hb-subset-input.cc  | 13 +++++++++++--
+ src/hb-subset-input.hh  |  8 +++++++-
+ src/hb-subset-plan.cc   |  3 ++-
+ src/hb-subset-plan.hh   |  4 ++++
+ 5 files changed, 54 insertions(+), 13 deletions(-)
+
+commit ebc382a8474af5a8829750db8f641b384f6f47ec
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 15:59:46 2022 -0700
+
+    Revert "Avoid use values () in hb-hashmap if value_t has an overriden operator &"
+    
+    This reverts commit b92e4cc0091e093f6941019e1a53cc04a137017a.
+
+ src/hb-subset-input.cc | 7 +++----
+ src/hb-subset-plan.cc  | 7 +++----
+ src/hb-subset-plan.hh  | 6 ++----
+ 3 files changed, 8 insertions(+), 12 deletions(-)
+
+commit ff0d0d020e0fcf7be4e45d6791eb5c7155f5c84b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 14:34:20 2022 -0700
+
+    [meta] Use std::decay
+
+ src/hb-meta.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 9650f34a84006c714ac81c72ee59b249bf4e9788
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 14:16:11 2022 -0700
+
+    [CI] Remove coverage testing from macos-ci
+
+ .github/workflows/macos-ci.yml | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+commit 3a9ca6aa698d112c8c7d6733dbbc438b701fd917
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 13:57:02 2022 -0700
+
+    [CI] Try fixing macos-ci
+
+ .github/workflows/macos-ci.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 24cf86b0099ada427936b3113c5b48c3537b3425
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 13:33:06 2022 -0700
+
+    [array] Fix MSVC fail
+
+ src/test-array.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit a87843be3dea86a5893e1fa64667df872408549e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 13:43:58 2022 -0700
+
+    [array] Another try at sizeof sorted_array
+
+ src/hb-array.hh   | 8 ++++----
+ src/test-array.cc | 3 +--
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+commit 72ba0b2aa2bd65ea1bfdbca75fe4127264590e00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 14 13:33:06 2022 -0700
+
+    [array] Fix MSVC fail
+
+ src/test-array.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit b92e4cc0091e093f6941019e1a53cc04a137017a
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Nov 14 08:54:24 2022 -0800
+
+    Avoid use values () in hb-hashmap if value_t has an overriden operator &
+
+ src/hb-subset-input.cc | 7 ++++---
+ src/hb-subset-plan.cc  | 7 ++++---
+ src/hb-subset-plan.hh  | 6 ++++--
+ 3 files changed, 12 insertions(+), 8 deletions(-)
+
+commit ea63e95e4cc287d8efbad6fd215a0b4c541a9e15
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 11 12:45:12 2022 -0700
+
+    [GPOS.PairPos] Adjust unsafe-to-break for non-zero ValueFormat2
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3824
+
+ src/OT/Layout/GPOS/PairPosFormat2.hh | 4 ++++
+ src/OT/Layout/GPOS/PairSet.hh        | 7 ++++++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+commit 85e0be13575d1342645867bc1a788e13e196594f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 13 17:28:09 2022 -0700
+
+    [vector/array] Add simple test for sorted size
+
+ src/test-array.cc  | 2 ++
+ src/test-vector.cc | 1 +
+ 2 files changed, 3 insertions(+)
+
+commit 4e618557a67f6ce49f93d5c10686500628bede30
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 13 17:23:25 2022 -0700
+
+    [vector] Don't subclass sorted vector from unsorted
+    
+    Was doubling the size unnecessarily.
+
+ src/hb-vector.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8f15fb125247de8b19e8b5a9396f40a83114a64a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 13 17:06:58 2022 -0700
+
+    [util] Move variable closer to use
+
+ util/shape-consumer.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 630f09c8b6022184f7a414bb5e07c01898fae60c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 9 11:32:30 2022 -0700
+
+    Another hb_memcpy instead of strncpy use
+
+ src/hb-subset-plan.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cd011ceadfa443767fd818cfe1af8a87150291a2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 9 11:30:44 2022 -0700
+
+    Use hb_memcpy instead of strncpy
+    
+    Nul-termination is not intended.
+
+ src/hb-subset-input.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 604fe807078ce41d0ac7742547e90b17c066709f
+Author: Eli Schwartz <eschwartz93 at gmail.com>
+Date:   Tue Nov 8 16:24:08 2022 -0500
+
+    meson: fix regression in detecting freetype2/icu-uc when explicitly disabled
+    
+    In #3811 / commit 53a194aa3f5f7de0b40e879e41fcbe0de6e9fefe a broken and
+    half-implemented approach to kind of sort of handling the detection of
+    both pkg-config and cmake names for dependencies, was implemented. It
+    just checked for both versions with required: false, but when the build
+    was configured with *disabled* options, it was still found because it
+    was treated as auto.
+    
+    Really, the problem here is trying to outsmart Meson, which handles a
+    lot of edge cases correctly. But it's possible, albeit very wordy, to
+    manually implement Meson's internal logic via if/else fallbacks. Do so
+    here.
+
+ meson.build | 79 +++++++++++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 56 insertions(+), 23 deletions(-)
+
+commit c158b626c3033036321180d4ac90c129206b0ad2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 8 14:15:56 2022 -0700
+
+    [name] Simplify buffer-length calculation
+
+ src/hb-ot-name-table.hh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit 55edf59d521d06a981b16af44a9d6f217093d73b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 8 14:53:27 2022 -0700
+
+    [name] Typo
+
+ src/hb-ot-name-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 27c8bbcb04d506670dad8bbe3b9e9d1bde466aa8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 8 14:48:38 2022 -0700
+
+    Revert "[name] Simplify buffer-length calculation"
+    
+    This reverts commit d70595657e8d56b52d5714d082092d8eb104093e.
+
+ src/hb-ot-name-table.hh | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+commit d70595657e8d56b52d5714d082092d8eb104093e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 8 14:15:56 2022 -0700
+
+    [name] Simplify buffer-length calculation
+
+ src/hb-ot-name-table.hh | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit 6314aa7da4204379cd3ebeeaa447a51fbd7ef7bc
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Oct 28 10:44:48 2022 -0700
+
+    [subset] add an experimental API that can override name strings for specified name_id
+
+ src/gen-def.py                              |   1 +
+ src/hb-ot-name-table.hh                     |  83 ++++++++++++++++++++++++++--
+ src/hb-ot-name.cc                           |  51 +----------------
+ src/hb-subset-input.cc                      |  50 ++++++++++++++++-
+ src/hb-subset-input.hh                      |   3 +-
+ src/hb-subset-plan.cc                       |  23 ++++++++
+ src/hb-subset-plan.hh                       |  11 ++++
+ src/hb-subset.h                             |   7 +++
+ test/api/fonts/nameID.override.expected.ttf | Bin 0 -> 167936 bytes
+ test/api/test-subset-nameids.c              |  35 ++++++++++++
+ 10 files changed, 208 insertions(+), 56 deletions(-)
+
+commit f53ef69d5941514b06f5afbcd83709cf724eb74d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 4 16:00:34 2022 -0600
+
+    [indic] Order left-matras inside-out
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3863
+
+ src/hb-ot-shaper-indic.cc                          |  28 ++++++++++++++++++++-
+ src/hb-ot-shaper-myanmar.cc                        |  27 ++++++++++++++++++++
+ .../9d8c53cb64b8747abdd2b70755cce2ee0eb42ef7.ttf   | Bin 0 -> 3000 bytes
+ .../a232bb734d4c6c898a44506547d19768f0eba6a6.ttf   | Bin 0 -> 2512 bytes
+ .../data/in-house/tests/indic-special-cases.tests  |   2 ++
+ test/shape/data/in-house/tests/myanmar-misc.tests  |   1 +
+ 6 files changed, 57 insertions(+), 1 deletion(-)
+
+commit 2822b589bc837fae6f66233e2cf2eef0f6ce8470
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Nov 3 19:49:49 2022 +0000
+
+    [subset] Include instancing tests in distribution.
+    
+    Automatically enable them when the experimental api is enabled.
+
+ test/subset/data/Makefile.am      |  5 +++++
+ test/subset/data/Makefile.sources |  5 +++++
+ test/subset/meson.build           | 19 ++++++++++++-------
+ 3 files changed, 22 insertions(+), 7 deletions(-)
+
+commit dbb7f47b19e60551ef4707f6a2cb60f1bd8334dd
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Nov 3 11:55:41 2022 -0700
+
+    fix bug in hb_hashmap_t has() interface
+    
+    It was not working when the value type is hb_bytes_t because hb_array_t
+    overloaded operator &
+
+ src/hb-map.hh   |  2 +-
+ src/test-map.cc | 10 ++++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+commit d1f445ec1e6518d2d135eca13e791a79a824025a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 2 12:24:04 2022 -0600
+
+    [name] Typo
+
+ src/hb-ot-name.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fc935fb81b04cce3753b0502897944792be47a19
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 1 14:39:33 2022 -0600
+
+    Fix snprintf use
+    
+    https://github.com/harfbuzz/harfbuzz/pull/3495#issuecomment-1299107964
+
+ src/OT/Layout/GSUB/Ligature.hh | 2 +-
+ src/OT/Layout/GSUB/Sequence.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 2ee42bbac2e2c85e946db525a8241d32d6b01459
+Author: Lorenz Wildberg <lorenz at wild-fisch.de>
+Date:   Tue Nov 1 13:00:18 2022 +0100
+
+    hb_variation_to_string: Fix GIR annotation
+
+ src/hb-common.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0e4f579493c42e34931277dc32aec75d0044af14
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 31 13:51:24 2022 -0600
+
+    [util/hb-view] Default HB_DRAW to 1
+    
+    See comments.
+
+ util/helper-cairo.hh | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 02b76393efa4ca9a335cc08473bdb744be721bda
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 29 11:15:03 2022 -0600
+
+    [config] Re-enable BORING_EXPANSION
+    
+    Only the non-experimental parts (currently avar2) are
+    enabled by default.
+
+ src/OT/Layout/Common/Coverage.hh     | 34 +++++++++++++++++-----------------
+ src/OT/Layout/GPOS/MarkBasePos.hh    |  4 ++--
+ src/OT/Layout/GPOS/MarkLigPos.hh     |  4 ++--
+ src/OT/Layout/GPOS/MarkMarkPos.hh    |  4 ++--
+ src/OT/Layout/GPOS/PairPos.hh        |  4 ++--
+ src/OT/Layout/GSUB/AlternateSubst.hh |  4 ++--
+ src/OT/Layout/GSUB/LigatureSubst.hh  |  4 ++--
+ src/OT/Layout/GSUB/MultipleSubst.hh  |  4 ++--
+ src/OT/Layout/GSUB/SingleSubst.hh    |  8 ++++----
+ src/graph/classdef-graph.hh          |  2 +-
+ src/graph/coverage-graph.hh          |  2 +-
+ src/graph/gsubgpos-graph.hh          |  4 ++--
+ src/graph/markbasepos-graph.hh       |  4 ++--
+ src/graph/pairpos-graph.hh           |  4 ++--
+ src/hb-config.hh                     |  4 ----
+ 15 files changed, 43 insertions(+), 47 deletions(-)
+
+commit 6a47ef34b1ac5c1afc94a37dc7d2bcbe2013975e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 29 11:14:27 2022 -0600
+
+    [config] If not HB_EXPERIMENTAL, then HB_NO_BEYOND_64K
+
+ src/hb-config.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit a0f999cd95834dce7f98f34890aaccb44c3179d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 29 11:13:40 2022 -0600
+
+    [config] Rename HB_NO_VARIATIONS2 to HB_NO_AVAR2
+
+ src/hb-config.hh            | 2 +-
+ src/hb-ot-var-avar-table.hh | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 60c6b7786d9f4651ae2803bfc4ff4435b38a5bc6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 28 14:19:39 2022 -0600
+
+    Disable -Wcast-function-type-strict
+    
+    https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit d88269c827895b38f99f7cf741fa60210d4d5169
+Author: Martin Storsjö <martin at martin.st>
+Date:   Fri Oct 28 22:17:15 2022 +0300
+
+    freetype: Fix function signatures to match without casts
+    
+    Clang 16 has got a new stricter warning for casts of function types
+    (see https://github.com/llvm/llvm-project/commit/1aad641c793090b4d036c03e737df2ebe2c32c57).
+    
+    This new warning gets included as part of the existing error
+    diagnostic setting of -Wcast-function-type.
+    
+    This fixes errors like these:
+    
+    ../src/hb-ft.cc:1011:34: error: cast from 'void (*)(FT_Face)' (aka 'void (*)(FT_FaceRec_ *)') to 'FT_Generic_Finalizer' (aka 'void (*)(void *)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+        ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize;
+                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ src/hb-ft.cc | 30 ++++++++++++++++++------------
+ 1 file changed, 18 insertions(+), 12 deletions(-)
+
+commit 8a5524833ce78484ed38eeacffc476c462a384d8
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Oct 27 09:43:07 2022 -0700
+
+    [instance] update OS2/.usWeightClass and .usWidthClass when
+    no-prune-unicode-ranges option is enabled
+
+ src/hb-ot-os2-table.hh                             |  23 +++++++++++----------
+ ...anges.retain-all-codepoint.wght=150,wdth=80.ttf | Bin 0 -> 114200 bytes
+ ...anges.retain-all-codepoint.wght=300,wdth=90.ttf | Bin 0 -> 114300 bytes
+ test/subset/data/tests/full_instance.tests         |   1 +
+ 4 files changed, 13 insertions(+), 11 deletions(-)
+
+commit fddeba26e4a0363f7b9ae260ddff2daad6939b34
+Merge: e854739b2 db292f6f0
+Author: خالد حسني (Khaled Hosny) <khaled at aliftype.com>
+Date:   Wed Oct 26 22:34:02 2022 +0200
+
+    Merge pull request #3857 from 2xsaiko/outgoing/cmake-abs-path
+    
+    Pass through absolute paths to cmake config directly
+
+commit db292f6f0238581a489aa8cddc585129b6e920cd
+Author: Marco Rebhan <me at dblsaiko.net>
+Date:   Wed Oct 26 20:49:52 2022 +0200
+
+    Pass through absolute paths to cmake config directly
+    
+    The previous code concatenates includedir to _harfbuzz_prefix verbatim,
+    which results in a wrong final include path in case includedir is an absolute
+    path. Instead, we can let meson determine the absolute include and lib paths
+    in advance and save them in the cmake config.
+    
+    This is an issue in nixpkgs, where includedir is set to the final (absolute)
+    path of the built library in the Nix store, which causes CMake projects
+    depending on harfbuzz to not configure.
+    
+    See https://github.com/NixOS/nixpkgs/issues/180054.
+
+ src/harfbuzz-config.cmake.in | 44 ++++++++------------------------------------
+ src/meson.build              |  4 ++--
+ 2 files changed, 10 insertions(+), 38 deletions(-)
+
+commit e854739b2d905a98082dd37344e75beddf795e1a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 26 13:12:56 2022 -0600
+
+    [fuzzing] Add test font for previous commit
+
+ ...testcase-minimized-hb-shape-fuzzer-6635625931735040 | Bin 0 -> 175945 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 477d71724c945c9f1b4ca8a569be1cc5c5f93dcb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 26 13:11:47 2022 -0600
+
+    [glyf] Limit points in a glyf to 10000 roughly
+    
+    Only enforced when components are being expanded.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3838
+
+ src/OT/glyf/Glyph.hh | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit 9aad3dba8f6cc91c8039ebfc2c6c6c5fd179a74b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 26 13:04:02 2022 -0600
+
+    [SingleSubst] Fix degenerate-lookup test
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/3853
+
+ src/OT/Layout/GSUB/SingleSubstFormat1.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 83769b9cb1bc44511c05f89dfeaa96cfec9749a8
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Oct 21 22:37:32 2022 +0000
+
+    [subset] add comment for why we retain empty lookups.
+
+ src/hb-ot-layout-common.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 70e2de2bd440bccbb5e896ca1a08202da7ed0b4d
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Oct 21 22:33:17 2022 +0000
+
+    [subset] Always output Lookup's even if they are empty.
+    
+    The rest of layout subsetting depends on lookup indices being consistent with those computed during planning. So if an empty lookup is discarded during the subset phase it will invalidate all subsequent lookup indices. Generally we shouldn't end up with an empty lookup as we pre-prune them during the planning phase, but it can happen in rare cases such as when a subtable is considered degenerate (eg. #3853)
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3377ddf69e0be9ddacf0330c45c0649eade8ba3e
+Author: Joel Auterson <joel at emitwise.com>
+Date:   Thu Oct 20 21:07:05 2022 +0100
+
+    Add missing underscore
+
+ .github/workflows/arm-ci.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 28cb1b39545aa7ab6a2ec5e9110098fd848a30fa
+Author: Joel Auterson <joel at emitwise.com>
+Date:   Thu Oct 20 21:01:53 2022 +0100
+
+    Fix working-directory
+
+ .github/workflows/arm-ci.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dbbbf02d77a415a3c1c14f01365b348526e01b8a
+Author: Joel Auterson <joel at emitwise.com>
+Date:   Thu Oct 20 20:59:12 2022 +0100
+
+    Fix GHA workflow
+
+ .github/workflows/arm-ci.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 756b5000188a5ca60ba78333aa29d20de8d14320
+Author: Joel Auterson <joel at emitwise.com>
+Date:   Thu Oct 20 20:16:58 2022 +0100
+
+    Add ARM CI workflow
+
+ .github/workflows/arm-ci.yml | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+commit c813f84235b16994c293d2ffa4584056a97c8e73
+Author: Joel Auterson <joel at emitwise.com>
+Date:   Thu Oct 20 19:45:23 2022 +0100
+
+    Make build work for arm-none-eabi
+
+ src/graph/graph.hh               | 14 +++++++-------
+ src/hb-ot-layout-common.hh       |  8 ++++----
+ src/hb-ot-post-table-v2subset.hh |  4 ++--
+ src/hb-ot-var-fvar-table.hh      |  2 +-
+ src/hb-repacker.hh               |  2 +-
+ 5 files changed, 15 insertions(+), 15 deletions(-)
+
+commit b0b7a65388da25ae3fa01e969ad6abc67eed4f49
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 20 17:13:26 2022 -0600
+
+    [subset] Fix check-symbols failure
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3850
+
+ src/check-symbols.py         | 2 +-
+ src/hb-subset-accelerator.hh | 5 +++--
+ src/hb-subset.cc             | 4 ++++
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
 commit 970321db7bddbe8c579b73751fc655a924ea3ce6
 Author: Khaled Hosny <khaled at aliftype.com>
 Date:   Wed Oct 19 22:06:46 2022 +0200

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,3 +1,65 @@
+Overview of changes leading to 6.0.0
+Friday, December 16, 2022
+====================================
+- A new API have been added to pre-process the face and speed up future
+  subsetting operations on that face. Provides up to a 95% reduction in
+  subsetting times when the same face is subset more than once.
+
+  For more details and benchmarks, see:
+  https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md
+
+  (Garret Rieger, Behdad Esfahbod)
+
+- Shaping have been speedup by skipping entire lookups when the buffer contents
+  don't intersect with the lookup. Shows up to a 10% speedup in shaping some
+  fonts. (Behdad Esfahbod)
+
+- A new experimental feature, “Variable Composites” (enabled by passing
+  -Dexperimental_api=true to meson), is also featured in this release.
+  This technology enables drastic compression of fonts in the Chinese,
+  Japanese, Korean, and other writing systems, by reusing the OpenType Font
+  Variations technology for encoding “smart components” into the font.
+
+  The specification for these  extensions to the font format can be found in:
+  https://github.com/harfbuzz/boring-expansion-spec/blob/glyf1/glyf1.md
+
+  A test variable-font with ~7160 Hangul syllables derived from the
+  NotoSerifKR-VF font has been built, with existing OpenType technology, as
+  well as with the new Variable Composites (VarComposites) technology. The
+  VarComposites font is over 90% smaller than the OpenType version of the font!
+  Both fonts can be obtained from the “smarties” repository:
+  https://github.com/behdad/smarties/tree/3.0/fonts/hangul/serif
+
+  When building HarfBuzz with experimental features enabled, you can test
+  the “smarties” font with a sample character like this:
+
+  $ hb-view butchered-hangul-serif-smarties-variable.ttf -u AE01 --variations=wght=700
+
+  (Behdad Esfahbod)
+
+- The HarfBuzz subsetter can now drop axes by pinning them to specific values
+  (also referred to as instancing). There are a couple of restrictions
+  currently:
+
+  - Only works with TrueType (“glyf”) based fonts. “CFF2” fonts are not yet
+    supported.
+  - Only supports the case where all axes in a font are pinned.
+
+  (Garret Rieger, Qunxin Liu)
+
+- Miscellaneous fixes and improvements.
+
+  (Behdad Esfahbod, Christoph Reiter, David Corbett, Eli Schwartz, Garret
+   Rieger, Joel Auterson, Jordan Petridis, Khaled Hosny, Lorenz Wildberg,
+   Marco Rebhan, Martin Storsjö, Matthias Clasen, Qunxin Liu, Satadru Pramanik)
+
+
+- New API
++hb_subset_input_pin_axis_location()
++hb_subset_input_pin_axis_to_default()
++hb_subset_preprocess()
+
+
 Overview of changes leading to 5.3.1
 Wednesday, October 19, 2022
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [5.3.1],
+        [6.0.0],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,6 +1,6 @@
 project('harfbuzz', 'c', 'cpp',
   meson_version: '>= 0.55.0',
-  version: '5.3.1',
+  version: '6.0.0',
   default_options: [
     'cpp_rtti=false',       # Just to support msvc, we are passing -fno-exceptions also anyway
     'cpp_std=c++11',
@@ -83,20 +83,35 @@
 
 m_dep = cpp.find_library('m', required: false)
 
-
-# Try pkgconfig name
-freetype_dep = dependency('freetype2', required: false)
-if not freetype_dep.found()
-  # Try cmake name
-  freetype_dep = dependency('freetype', required: false)
-endif
-if not freetype_dep.found()
-  # Subproject fallback, `allow_fallback: true` means the fallback will be
-  # tried even if the freetype option is set to `auto`.
-  freetype_dep = dependency('freetype2',
+if meson.version().version_compare('>=0.60.0')
+  # pkg-config: freetype2, cmake: Freetype
+  freetype_dep = dependency('freetype2', 'Freetype',
                             required: get_option('freetype'),
                             default_options: ['harfbuzz=disabled'],
                             allow_fallback: true)
+else
+  # painful hack to handle multiple dependencies but also respect options
+  freetype_opt = get_option('freetype')
+  # we want to handle enabled manually after fallbacks, but also handle disabled normally
+  if freetype_opt.enabled()
+    freetype_opt = false
+  endif
+  # try pkg-config name
+  freetype_dep = dependency('freetype2', method: 'pkg-config', required: freetype_opt)
+  # when disabled, leave it not-found
+  if not freetype_dep.found() and not get_option('freetype').disabled()
+    # Try cmake name
+    freetype_dep = dependency('Freetype', method: 'cmake', required: false)
+    # Subproject fallback, `allow_fallback: true` means the fallback will be
+    # tried even if the freetype option is set to `auto`.
+    if not freetype_dep.found()
+      freetype_dep = dependency('freetype2',
+                                method: 'pkg-config',
+                                required: get_option('freetype'),
+                                default_options: ['harfbuzz=disabled'],
+                                allow_fallback: true)
+    endif
+  endif
 endif
 
 glib_dep = dependency('glib-2.0', required: get_option('glib'))
@@ -104,19 +119,37 @@
 graphite2_dep = dependency('graphite2', required: get_option('graphite2'))
 graphite_dep = dependency('graphite2', required: get_option('graphite'))
 
-# Try pkgconfig name
-icu_dep = dependency('icu-uc', required: false)
-if not icu_dep.found()
-  # Try cmake name
-  icu_dep = dependency('ICU',
-                       required: false,
-                       components: 'uc',
-                       method: 'cmake')
+if meson.version().version_compare('>=0.60.0')
+  # pkg-config: icu-uc, cmake: ICU but with components
+  icu_dep = dependency('icu-uc', 'ICU',
+                            components: 'uc',
+                            required: get_option('icu'),
+                            default_options: ['harfbuzz=disabled'],
+                            allow_fallback: true)
+else
+  # painful hack to handle multiple dependencies but also respect options
+  icu_opt = get_option('icu')
+  # we want to handle enabled manually after fallbacks, but also handle disabled normally
+  if icu_opt.enabled()
+    icu_opt = false
+  endif
+  # try pkg-config name
+  icu_dep = dependency('icu-uc', method: 'pkg-config', required: icu_opt)
+  # when disabled, leave it not-found
+  if not icu_dep.found() and not get_option('icu').disabled()
+    # Try cmake name
+    icu_dep = dependency('ICU', method: 'cmake', components: 'uc', required: false)
+    # Try again with subproject fallback. `allow_fallback: true` means the
+    # fallback will be tried even if the icu option is set to `auto`, but
+    # we cannot pass this option until Meson 0.59.0, because no wrap file
+    # is checked into git.
+    if not icu_dep.found()
+      icu_dep = dependency('icu-uc',
+                           method: 'pkg-config',
+                           required: get_option('icu'))
+    endif
+  endif
 endif
-if not icu_dep.found()
-  # Subproject fallback if icu option is enabled
-  icu_dep = dependency('icu-uc', required: get_option('icu'))
-endif
 
 if icu_dep.found() and icu_dep.type_name() == 'pkgconfig'
   icu_defs = icu_dep.get_variable(pkgconfig: 'DEFS', default_value: '').split()
@@ -148,7 +181,8 @@
     # harfbuzz support disabled, so when cairo will lookup freetype2 dependency
     # it will be forced to use that one.
     cairo_dep = dependency('cairo', required: get_option('cairo'))
-    cairo_ft_dep = dependency('cairo-ft', required: get_option('cairo'))
+    cairo_ft_required = get_option('cairo').enabled() and get_option('freetype').enabled()
+    cairo_ft_dep = dependency('cairo-ft', required: cairo_ft_required)
   endif
 endif
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2022-12-18 01:06:39 UTC (rev 65304)
@@ -47,6 +47,9 @@
 HBDEPS   += $(GLIB_DEPS)
 HBSOURCES += $(HB_GLIB_sources)
 HBHEADERS += $(HB_GLIB_headers)
+HB_HAS_GLIB_DEF = define HB_HAS_GLIB 1
+else
+HB_HAS_GLIB_DEF = undef HB_HAS_GLIB
 endif
 
 if HAVE_FREETYPE
@@ -55,6 +58,9 @@
 HBDEPS   += $(FREETYPE_DEPS)
 HBSOURCES += $(HB_FT_sources)
 HBHEADERS += $(HB_FT_headers)
+HB_HAS_FREETYPE_DEF = define HB_HAS_FREETYPE 1
+else
+HB_HAS_FREETYPE_DEF = undef HB_HAS_FREETYPE
 endif
 
 if HAVE_GRAPHITE2
@@ -63,6 +69,9 @@
 HBDEPS   += $(GRAPHITE2_DEPS)
 HBSOURCES += $(HB_GRAPHITE2_sources)
 HBHEADERS += $(HB_GRAPHITE2_headers)
+HB_HAS_GRAPHITE_DEF = define HB_HAS_GRAPHITE 1
+else
+HB_HAS_GRAPHITE_DEF = undef HB_HAS_GRAPHITE
 endif
 
 if HAVE_UNISCRIBE
@@ -70,6 +79,9 @@
 HBNONPCLIBS += $(UNISCRIBE_LIBS)
 HBSOURCES += $(HB_UNISCRIBE_sources)
 HBHEADERS += $(HB_UNISCRIBE_headers)
+HB_HAS_UNISCRIBE_DEF = define HB_HAS_UNISCRIBE 1
+else
+HB_HAS_UNISCRIBE_DEF = undef HB_HAS_UNISCRIBE
 endif
 
 if HAVE_DIRECTWRITE
@@ -77,6 +89,9 @@
 HBNONPCLIBS += $(DIRECTWRITE_LIBS)
 HBSOURCES += $(HB_DIRECTWRITE_sources)
 HBHEADERS += $(HB_DIRECTWRITE_headers)
+HB_HAS_DIRECTWRITE_DEF = define HB_HAS_DIRECTWRITE 1
+else
+HB_HAS_DIRECTWRITE_DEF = undef HB_HAS_DIRECTWRITE
 endif
 
 if HAVE_GDI
@@ -84,6 +99,9 @@
 HBNONPCLIBS += $(GDI_LIBS)
 HBSOURCES += $(HB_GDI_sources)
 HBHEADERS += $(HB_GDI_headers)
+HB_HAS_GDI_DEF = define HB_HAS_GDI 1
+else
+HB_HAS_GDI_DEF = undef HB_HAS_GDI
 endif
 
 if HAVE_CORETEXT
@@ -91,6 +109,9 @@
 HBNONPCLIBS += $(CORETEXT_LIBS)
 HBSOURCES += $(HB_CORETEXT_sources)
 HBHEADERS += $(HB_CORETEXT_headers)
+HB_HAS_CORETEXT_DEF = define HB_HAS_CORETEXT 1
+else
+HB_HAS_CORETEXT_DEF = undef HB_HAS_CORETEXT
 endif
 
 
@@ -147,7 +168,7 @@
 pkgconfig_DATA = harfbuzz.pc
 cmakedir = $(libdir)/cmake/harfbuzz
 cmake_DATA = harfbuzz-config.cmake
-EXTRA_DIST += hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in
+EXTRA_DIST += hb-version.h.in hb-features.h.in harfbuzz.pc.in harfbuzz-config.cmake.in
 
 lib_LTLIBRARIES += libharfbuzz-subset.la
 libharfbuzz_subset_la_LINK = $(chosen_linker) $(libharfbuzz_subset_la_LDFLAGS)
@@ -178,6 +199,7 @@
 HBLIBS += $(ICU_LIBS)
 HBSOURCES += $(HB_ICU_sources)
 HBHEADERS += $(HB_ICU_headers)
+HB_HAS_ICU_DEF = define HB_HAS_ICU 1
 else
 lib_LTLIBRARIES += libharfbuzz-icu.la
 libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources)
@@ -187,6 +209,7 @@
 EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency)
 pkginclude_HEADERS += $(HB_ICU_headers)
 pkgconfig_DATA += harfbuzz-icu.pc
+HB_HAS_ICU_DEF = undef HB_HAS_ICU
 endif
 endif
 EXTRA_DIST += harfbuzz-icu.pc.in
@@ -226,6 +249,25 @@
 	$(NULL)
 
 
+BUILT_SOURCES += \
+	hb-features.h
+DISTCLEANFILES += \
+	hb-features.h
+
+hb-features.h: hb-features.h.in $(top_builddir)/config.status
+	$(AM_V_GEN) $(SED) \
+		-e 's/mesondefine HB_HAS_FREETYPE/$(HB_HAS_FREETYPE_DEF)/' \
+		-e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
+		-e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
+		-e 's/mesondefine HB_HAS_GRAPHITE/$(HB_HAS_GRAPHITE_DEF)/' \
+		-e 's/mesondefine HB_HAS_GLIB/$(HB_HAS_GLIB_DEF)/' \
+		-e 's/mesondefine HB_HAS_UNISCRIBE/$(HB_HAS_UNISCRIBE_DEF)/' \
+		-e 's/mesondefine HB_HAS_DIRECTWRITE/$(HB_HAS_DIRECTWRITE_DEF)/' \
+		-e 's/mesondefine HB_HAS_CORETEXT/$(HB_HAS_CORETEXT_DEF)/' \
+		-e 's/mesondefine HB_HAS_ICU/$(HB_HAS_ICU_DEF)/' \
+		"$<" > "$@" || ($(RM) "$@"; false)
+
+
 %.pc: %.pc.in $(top_builddir)/config.status
 	$(AM_V_GEN) \
 	$(SED)	-e 's@%prefix%@$(prefix)@g' \
@@ -368,6 +410,7 @@
 	test-iter \
 	test-machinery \
 	test-map \
+	test-multimap \
 	test-number \
 	test-ot-tag \
 	test-priority-queue \
@@ -407,6 +450,10 @@
 test_map_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_map_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_multimap_SOURCES = test-multimap.cc hb-static.cc
+test_multimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_multimap_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_number_SOURCES = test-number.cc hb-number.cc
 test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_number_LDADD = $(COMPILED_TESTS_LDADD)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2022-12-18 01:06:39 UTC (rev 65304)
@@ -52,6 +52,7 @@
 	hb-map.hh \
 	hb-meta.hh \
 	hb-ms-feature-ranges.hh \
+	hb-multimap.hh \
 	hb-mutex.hh \
 	hb-null.hh \
 	hb-number.cc \
@@ -95,7 +96,10 @@
 	OT/glyf/Glyph.hh \
 	OT/glyf/GlyphHeader.hh \
 	OT/glyf/SimpleGlyph.hh \
+	OT/glyf/coord-setter.hh \
+	OT/glyf/composite-iter.hh \
 	OT/glyf/CompositeGlyph.hh \
+	OT/glyf/VarCompositeGlyph.hh \
 	OT/glyf/SubsetGlyph.hh \
 	OT/Layout/types.hh \
 	OT/Layout/Common/Coverage.hh \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -49,7 +49,7 @@
   HBUINT16                      format;         /* Format identifier */
   CoverageFormat1_3<SmallTypes> format1;
   CoverageFormat2_4<SmallTypes> format2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   CoverageFormat1_3<MediumTypes>format3;
   CoverageFormat2_4<MediumTypes>format4;
 #endif
@@ -65,7 +65,7 @@
     {
     case 1: return_trace (u.format1.sanitize (c));
     case 2: return_trace (u.format2.sanitize (c));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return_trace (u.format3.sanitize (c));
     case 4: return_trace (u.format4.sanitize (c));
 #endif
@@ -74,10 +74,8 @@
   }
 
   /* Has interface. */
-  static constexpr unsigned SENTINEL = NOT_COVERED;
-  typedef unsigned int value_t;
-  value_t operator [] (hb_codepoint_t k) const { return get (k); }
-  bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+  unsigned operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k] != NOT_COVERED; }
   /* Predicate. */
   bool operator () (hb_codepoint_t k) const { return has (k); }
 
@@ -87,7 +85,7 @@
     switch (u.format) {
     case 1: return u.format1.get_coverage (glyph_id);
     case 2: return u.format2.get_coverage (glyph_id);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return u.format3.get_coverage (glyph_id);
     case 4: return u.format4.get_coverage (glyph_id);
 #endif
@@ -100,7 +98,7 @@
     switch (u.format) {
     case 1: return u.format1.get_population ();
     case 2: return u.format2.get_population ();
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return u.format3.get_population ();
     case 4: return u.format4.get_population ();
 #endif
@@ -127,7 +125,7 @@
     }
     u.format = count <= num_ranges * 3 ? 1 : 2;
 
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     if (count && last > 0xFFFFu)
       u.format += 2;
 #endif
@@ -136,7 +134,7 @@
     {
     case 1: return_trace (u.format1.serialize (c, glyphs));
     case 2: return_trace (u.format2.serialize (c, glyphs));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return_trace (u.format3.serialize (c, glyphs));
     case 4: return_trace (u.format4.serialize (c, glyphs));
 #endif
@@ -166,7 +164,7 @@
     {
     case 1: return u.format1.intersects (glyphs);
     case 2: return u.format2.intersects (glyphs);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return u.format3.intersects (glyphs);
     case 4: return u.format4.intersects (glyphs);
 #endif
@@ -179,7 +177,7 @@
     {
     case 1: return u.format1.intersects_coverage (glyphs, index);
     case 2: return u.format2.intersects_coverage (glyphs, index);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return u.format3.intersects_coverage (glyphs, index);
     case 4: return u.format4.intersects_coverage (glyphs, index);
 #endif
@@ -196,7 +194,7 @@
     {
     case 1: return u.format1.collect_coverage (glyphs);
     case 2: return u.format2.collect_coverage (glyphs);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return u.format3.collect_coverage (glyphs);
     case 4: return u.format4.collect_coverage (glyphs);
 #endif
@@ -212,7 +210,7 @@
     {
     case 1: return u.format1.intersect_set (glyphs, intersect_glyphs);
     case 2: return u.format2.intersect_set (glyphs, intersect_glyphs);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return u.format3.intersect_set (glyphs, intersect_glyphs);
     case 4: return u.format4.intersect_set (glyphs, intersect_glyphs);
 #endif
@@ -225,13 +223,13 @@
     static constexpr bool is_sorted_iterator = true;
     iter_t (const Coverage &c_ = Null (Coverage))
     {
-      memset (this, 0, sizeof (*this));
+      hb_memset (this, 0, sizeof (*this));
       format = c_.u.format;
       switch (format)
       {
       case 1: u.format1.init (c_.u.format1); return;
       case 2: u.format2.init (c_.u.format2); return;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
       case 3: u.format3.init (c_.u.format3); return;
       case 4: u.format4.init (c_.u.format4); return;
 #endif
@@ -244,7 +242,7 @@
       {
       case 1: return u.format1.__more__ ();
       case 2: return u.format2.__more__ ();
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
       case 3: return u.format3.__more__ ();
       case 4: return u.format4.__more__ ();
 #endif
@@ -257,7 +255,7 @@
       {
       case 1: u.format1.__next__ (); break;
       case 2: u.format2.__next__ (); break;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
       case 3: u.format3.__next__ (); break;
       case 4: u.format4.__next__ (); break;
 #endif
@@ -273,7 +271,7 @@
       {
       case 1: return u.format1.get_glyph ();
       case 2: return u.format2.get_glyph ();
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
       case 3: return u.format3.get_glyph ();
       case 4: return u.format4.get_glyph ();
 #endif
@@ -287,7 +285,7 @@
       {
       case 1: return u.format1 != o.u.format1;
       case 2: return u.format2 != o.u.format2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
       case 3: return u.format3 != o.u.format3;
       case 4: return u.format4 != o.u.format4;
 #endif
@@ -302,7 +300,7 @@
       {
       case 1: it.u.format1 = u.format1.__end__ (); break;
       case 2: it.u.format2 = u.format2.__end__ (); break;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
       case 3: it.u.format3 = u.format3.__end__ (); break;
       case 4: it.u.format4 = u.format4.__end__ (); break;
 #endif
@@ -314,7 +312,7 @@
     private:
     unsigned int format;
     union {
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     CoverageFormat2_4<MediumTypes>::iter_t      format4; /* Put this one first since it's larger; helps shut up compiler. */
     CoverageFormat1_3<MediumTypes>::iter_t      format3;
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat1.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat1.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -77,7 +77,14 @@
 
   bool intersects (const hb_set_t *glyphs) const
   {
-    /* TODO Speed up, using hb_set_next() and bsearch()? */
+    if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2)
+    {
+      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+        if (get_coverage (g) != NOT_COVERED)
+	  return true;
+      return false;
+    }
+
     for (const auto& g : glyphArray.as_array ())
       if (glyphs->has (g))
         return true;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat2.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat2.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/CoverageFormat2.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -80,8 +80,6 @@
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
 
-    /* TODO(iter) Write more efficiently? */
-
     unsigned num_ranges = 0;
     hb_codepoint_t last = (hb_codepoint_t) -2;
     for (auto g: glyphs)
@@ -115,26 +113,22 @@
 
   bool intersects (const hb_set_t *glyphs) const
   {
+    if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
+    {
+      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+        if (get_coverage (g) != NOT_COVERED)
+	  return true;
+      return false;
+    }
+
     return hb_any (+ hb_iter (rangeRecord)
                    | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); }));
   }
   bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
   {
-    auto cmp = [] (const void *pk, const void *pr) -> int
-    {
-      unsigned index = * (const unsigned *) pk;
-      const RangeRecord<Types> &range = * (const RangeRecord<Types> *) pr;
-      if (index < range.value) return -1;
-      if (index > (unsigned int) range.value + (range.last - range.first)) return +1;
-      return 0;
-    };
-
-    auto arr = rangeRecord.as_array ();
-    unsigned idx;
-    if (hb_bsearch_impl (&idx, index,
-                         arr.arrayZ, arr.length, sizeof (arr[0]),
-                         (int (*)(const void *_key, const void *_item)) cmp))
-      return arr.arrayZ[idx].intersects (*glyphs);
+    auto *range = rangeRecord.as_array ().bsearch (index);
+    if (range)
+      return range->intersects (*glyphs);
     return false;
   }
 
@@ -142,9 +136,14 @@
 	    hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
   void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
   {
+    /* Break out of loop for overlapping, broken, tables,
+     * to avoid fuzzer timouts. */
+    hb_codepoint_t last = 0;
     for (const auto& range : rangeRecord)
     {
-      hb_codepoint_t last = range.last;
+      if (unlikely (range.first < last))
+        break;
+      last = range.last;
       for (hb_codepoint_t g = range.first - 1;
 	   glyphs.next (&g) && g <= last;)
 	intersect_glyphs << g;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePos.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePos.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -13,7 +13,7 @@
   union {
   HBUINT16				format;         /* Format identifier */
   MarkBasePosFormat1_2<SmallTypes>	format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   MarkBasePosFormat1_2<MediumTypes>	format2;
 #endif
   } u;
@@ -26,7 +26,7 @@
     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)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
 #endif
     default:return_trace (c->default_return_value ());

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPos.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPos.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -13,7 +13,7 @@
   union {
   HBUINT16				format;         /* Format identifier */
   MarkLigPosFormat1_2<SmallTypes>	format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   MarkLigPosFormat1_2<MediumTypes>	format2;
 #endif
   } u;
@@ -26,7 +26,7 @@
     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)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
 #endif
     default:return_trace (c->default_return_value ());

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPos.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPos.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -13,7 +13,7 @@
   union {
   HBUINT16				format;         /* Format identifier */
   MarkMarkPosFormat1_2<SmallTypes>	format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   MarkMarkPosFormat1_2<MediumTypes>	format2;
 #endif
   } u;
@@ -26,7 +26,7 @@
     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)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
 #endif
     default:return_trace (c->default_return_value ());

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPos.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPos.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -15,7 +15,7 @@
   HBUINT16			format;         /* Format identifier */
   PairPosFormat1_3<SmallTypes>	format1;
   PairPosFormat2_4<SmallTypes>	format2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   PairPosFormat1_3<MediumTypes>	format3;
   PairPosFormat2_4<MediumTypes>	format4;
 #endif
@@ -30,7 +30,7 @@
     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)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
     case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -51,8 +51,21 @@
 
   bool intersects (const hb_set_t *glyphs) const
   {
+    auto &cov = this+coverage;
+
+    if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4)
+    {
+      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+      {
+	unsigned i = cov.get_coverage (g);
+	if ((this+pairSet[i]).intersects (glyphs, valueFormat))
+	  return true;
+      }
+      return false;
+    }
+
     return
-    + hb_zip (this+coverage, pairSet)
+    + hb_zip (cov, pairSet)
     | hb_filter (*glyphs, hb_first)
     | hb_map (hb_second)
     | hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_)
@@ -171,12 +184,16 @@
     unsigned format1 = 0;
     unsigned format2 = 0;
     for (const auto & _ :
-             + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second))
+	  + hb_zip (this+coverage, pairSet)
+	  | hb_filter (glyphset, hb_first)
+	  | hb_map (hb_second)
+	)
     {
       const PairSet& set = (this + _);
       const PairValueRecord *record = &set.firstPairValueRecord;
 
-      for (unsigned i = 0; i < set.len; i++)
+      unsigned count = set.len;
+      for (unsigned i = 0; i < count; i++)
       {
         if (record->intersects (glyphset))
         {
@@ -185,6 +202,9 @@
         }
         record = &StructAtOffset<const PairValueRecord> (record, record_size);
       }
+
+      if (format1 == valueFormat[0] && format2 == valueFormat[1])
+        break;
     }
 
     return hb_pair (format1, format2);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -220,7 +220,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "kerning glyphs at %d,%d",
+			  "try kerning glyphs at %d,%d",
 			  c->buffer->idx, skippy_iter.idx);
     }
 
@@ -227,10 +227,18 @@
     applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
     applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
 
+    if (applied_first || applied_second)
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->message (c->font,
+			    "kerned glyphs at %d,%d",
+			    c->buffer->idx, skippy_iter.idx);
+      }
+
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "kerned glyphs at %d,%d",
+			  "tried kerning glyphs at %d,%d",
 			  c->buffer->idx, skippy_iter.idx);
     }
 
@@ -241,10 +249,15 @@
     boring:
       buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
 
+    if (len2)
+    {
+      skippy_iter.idx++;
+      // https://github.com/harfbuzz/harfbuzz/issues/3824
+      // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
+      buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
+    }
 
     buffer->idx = skippy_iter.idx;
-    if (len2)
-      buffer->idx++;
 
     return_trace (true);
   }
@@ -309,6 +322,7 @@
   {
     unsigned len1 = valueFormat1.get_len ();
     unsigned len2 = valueFormat2.get_len ();
+    unsigned record_size = len1 + len2;
 
     unsigned format1 = 0;
     unsigned format2 = 0;
@@ -317,10 +331,13 @@
     {
       for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
       {
-        unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
+        unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size;
         format1 = format1 | valueFormat1.get_effective_format (&values[idx]);
         format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]);
       }
+
+      if (format1 == valueFormat1 && format2 == valueFormat2)
+        break;
     }
 
     return hb_pair (format1, format2);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairSet.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairSet.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairSet.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -112,7 +112,7 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "kerning glyphs at %d,%d",
+			    "try kerning glyphs at %d,%d",
 			    c->buffer->idx, pos);
       }
 
@@ -119,17 +119,31 @@
       bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
       bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
 
+      if (applied_first || applied_second)
+	if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+	{
+	  c->buffer->message (c->font,
+			      "kerned glyphs at %d,%d",
+			      c->buffer->idx, pos);
+	}
+
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "kerned glyphs at %d,%d",
+			    "tried kerning glyphs at %d,%d",
 			    c->buffer->idx, pos);
       }
 
       if (applied_first || applied_second)
         buffer->unsafe_to_break (buffer->idx, pos + 1);
+
       if (len2)
-        pos++;
+      {
+	pos++;
+      // https://github.com/harfbuzz/harfbuzz/issues/3824
+      // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
+      buffer->unsafe_to_break (buffer->idx, pos + 1);
+      }
 
       buffer->idx = pos;
       return_trace (true);

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -84,7 +84,7 @@
   {
     if (alternates.len && alternate_count)
     {
-      + alternates.sub_array (start_offset, alternate_count)
+      + alternates.as_array ().sub_array (start_offset, alternate_count)
       | hb_sink (hb_array (alternate_glyphs, *alternate_count))
       ;
     }

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -14,7 +14,7 @@
   union {
   HBUINT16				format;         /* Format identifier */
   AlternateSubstFormat1_2<SmallTypes>	format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   AlternateSubstFormat1_2<MediumTypes>	format2;
 #endif
   } u;
@@ -27,7 +27,7 @@
     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)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
 #endif
     default:return_trace (c->default_return_value ());

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -118,7 +118,7 @@
 	match_positions[i] += delta;
 	if (i)
 	  *p++ = ',';
-	snprintf (p, sizeof(buf), "%u", match_positions[i]);
+	snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]);
 	p += strlen(p);
       }
 

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -14,7 +14,7 @@
   union {
   HBUINT16				format;         /* Format identifier */
   LigatureSubstFormat1_2<SmallTypes>	format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   LigatureSubstFormat1_2<MediumTypes>	format2;
 #endif
   } u;
@@ -27,7 +27,7 @@
     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)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
 #endif
     default:return_trace (c->default_return_value ());

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -14,7 +14,7 @@
   union {
   HBUINT16				format;         /* Format identifier */
   MultipleSubstFormat1_2<SmallTypes>	format1;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   MultipleSubstFormat1_2<MediumTypes>	format2;
 #endif
   } u;
@@ -28,7 +28,7 @@
     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)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
 #endif
     default:return_trace (c->default_return_value ());

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -117,7 +117,7 @@
       {
 	if (buf < p)
 	  *p++ = ',';
-	snprintf (p, sizeof(buf), "%u", i);
+	snprintf (p, sizeof(buf) - (p - buf), "%u", i);
 	p += strlen(p);
       }
 

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -16,7 +16,7 @@
   HBUINT16				format;         /* Format identifier */
   SingleSubstFormat1_3<SmallTypes>	format1;
   SingleSubstFormat2_4<SmallTypes>	format2;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
   SingleSubstFormat1_3<MediumTypes>	format3;
   SingleSubstFormat2_4<MediumTypes>	format4;
 #endif
@@ -32,7 +32,7 @@
     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)...));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
     case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
 #endif
@@ -55,7 +55,7 @@
       format = 1;
       hb_codepoint_t mask = 0xFFFFu;
 
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
        if (+ glyphs
 	   | hb_map_retains_sorting (hb_first)
 	   | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
@@ -78,7 +78,7 @@
                                                | hb_map_retains_sorting (hb_first),
                                                delta));
     case 2: return_trace (u.format2.serialize (c, glyphs));
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: return_trace (u.format3.serialize (c,
                                                + glyphs
                                                | hb_map_retains_sorting (hb_first),

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -57,7 +57,7 @@
     hb_codepoint_t max_before = intersection.get_max ();
     hb_codepoint_t min_after = (min_before + d) & mask;
     hb_codepoint_t max_after = (max_before + d) & mask;
-    if (pop >= max_before - min_before &&
+    if (intersection.get_population () == max_before - min_before + 1 &&
 	((min_before <= min_after && min_after <= max_before) ||
 	 (min_before <= max_after && max_after <= max_before)))
       return;

Modified: 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	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -36,8 +36,24 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    + hb_zip (this+coverage, substitute)
-    | hb_filter (c->parent_active_glyphs (), hb_first)
+    auto &cov = this+coverage;
+    auto &glyph_set = c->parent_active_glyphs ();
+
+    if (substitute.len > glyph_set.get_population () * 4)
+    {
+      for (auto g : glyph_set)
+      {
+	unsigned i = cov.get_coverage (g);
+	if (i == NOT_COVERED || i >= substitute.len)
+	  continue;
+	c->output->add (substitute.arrayZ[i]);
+      }
+
+      return;
+    }
+
+    + hb_zip (cov, substitute)
+    | hb_filter (glyph_set, hb_first)
     | hb_map (hb_second)
     | hb_sink (c->output)
     ;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -3,6 +3,7 @@
 
 
 #include "../../hb-open-type.hh"
+#include "composite-iter.hh"
 
 
 namespace OT {
@@ -121,7 +122,7 @@
     if (flags & ARG_1_AND_2_ARE_WORDS)
     {
       // no overflow, copy and update value with deltas
-      memcpy (out, this, len);
+      hb_memcpy (out, this, len);
 
       const HBINT16 *px = reinterpret_cast<const HBINT16 *> (p);
       HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val);
@@ -135,7 +136,7 @@
       if (new_x <= 127 && new_x >= -128 &&
           new_y <= 127 && new_y >= -128)
       {
-        memcpy (out, this, len);
+        hb_memcpy (out, this, len);
         HBINT8 *o = reinterpret_cast<HBINT8 *> (out + len_before_val);
         o[0] = new_x;
         o[1] = new_y;
@@ -143,7 +144,7 @@
       else
       {
         // int8 overflows after deltas applied
-        memcpy (out, this, len_before_val);
+        hb_memcpy (out, this, len_before_val);
         
         //update flags
         CompositeGlyphRecord *o = reinterpret_cast<CompositeGlyphRecord *> (out);
@@ -152,14 +153,14 @@
 
         HBINT16 new_value;
         new_value = new_x;
-        memcpy (out, &new_value, HBINT16::static_size);
+        hb_memcpy (out, &new_value, HBINT16::static_size);
         out += HBINT16::static_size;
 
         new_value = new_y;
-        memcpy (out, &new_value, HBINT16::static_size);
+        hb_memcpy (out, &new_value, HBINT16::static_size);
         out += HBINT16::static_size;
 
-        memcpy (out, p+2, len - len_before_val - 2);
+        hb_memcpy (out, p+2, len - len_before_val - 2);
         len += 2;
       }
     }
@@ -252,56 +253,8 @@
   DEFINE_SIZE_MIN (4);
 };
 
-struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphRecord &>
-{
-  typedef const CompositeGlyphRecord *__item_t__;
-  composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
-      glyph (glyph_), current (nullptr), current_size (0)
-  {
-    set_current (current_);
-  }
+using composite_iter_t = composite_iter_tmpl<CompositeGlyphRecord>;
 
-  composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {}
-
-  item_t __item__ () const { return *current; }
-  bool __more__ () const { return current; }
-  void __next__ ()
-  {
-    if (!current->has_more ()) { current = nullptr; return; }
-
-    set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size));
-  }
-  composite_iter_t __end__ () const { return composite_iter_t (); }
-  bool operator != (const composite_iter_t& o) const
-  { return current != o.current; }
-
-
-  void set_current (__item_t__ current_)
-  {
-    if (!glyph.check_range (current_, CompositeGlyphRecord::min_size))
-    {
-      current = nullptr;
-      current_size = 0;
-      return;
-    }
-    unsigned size = current_->get_size ();
-    if (!glyph.check_range (current_, size))
-    {
-      current = nullptr;
-      current_size = 0;
-      return;
-    }
-
-    current = current_;
-    current_size = size;
-  }
-
-  private:
-  hb_bytes_t glyph;
-  __item_t__ current;
-  unsigned current_size;
-};
-
 struct CompositeGlyph
 {
   const GlyphHeader &header;
@@ -382,7 +335,7 @@
       unsigned comp_len = component.get_size ();
       if (component.is_anchored ())
       {
-        memcpy (p, &component, comp_len);
+        hb_memcpy (p, &component, comp_len);
         p += comp_len;
       }
       else
@@ -398,7 +351,7 @@
     if (source_len > source_comp_len)
     {
       unsigned instr_len = source_len - source_comp_len;
-      memcpy (p, (const char *)c + source_comp_len, instr_len);
+      hb_memcpy (p, (const char *)c + source_comp_len, instr_len);
       p += instr_len;
     }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -7,6 +7,8 @@
 #include "GlyphHeader.hh"
 #include "SimpleGlyph.hh"
 #include "CompositeGlyph.hh"
+#include "VarCompositeGlyph.hh"
+#include "coord-setter.hh"
 
 
 namespace OT {
@@ -16,6 +18,11 @@
 namespace glyf_impl {
 
 
+#ifndef HB_GLYF_MAX_POINTS
+#define HB_GLYF_MAX_POINTS 10000
+#endif
+
+
 enum phantom_point_index_t
 {
   PHANTOM_LEFT   = 0,
@@ -27,7 +34,7 @@
 
 struct Glyph
 {
-  enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };
+  enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE };
 
   public:
   composite_iter_t get_composite_iterator () const
@@ -35,6 +42,11 @@
     if (type != COMPOSITE) return composite_iter_t ();
     return CompositeGlyph (*header, bytes).iter ();
   }
+  var_composite_iter_t get_var_composite_iterator () const
+  {
+    if (type != VAR_COMPOSITE) return var_composite_iter_t ();
+    return VarCompositeGlyph (*header, bytes).iter ();
+  }
 
   const hb_bytes_t trim_padding () const
   {
@@ -108,25 +120,25 @@
       if (unlikely (!glyph_header)) return false;
     }
 
-    int xMin = 0, xMax = 0;
-    int yMin = 0, yMax = 0;
+    float xMin = 0, xMax = 0;
+    float yMin = 0, yMax = 0;
     if (all_points.length > 4)
     {
-      xMin = xMax = roundf (all_points[0].x);
-      yMin = yMax = roundf (all_points[0].y);
+      xMin = xMax = all_points[0].x;
+      yMin = yMax = all_points[0].y;
     }
 
     for (unsigned i = 1; i < all_points.length - 4; i++)
     {
-      float rounded_x = roundf (all_points[i].x);
-      float rounded_y = roundf (all_points[i].y);
-      xMin = hb_min (xMin, rounded_x);
-      xMax = hb_max (xMax, rounded_x);
-      yMin = hb_min (yMin, rounded_y);
-      yMax = hb_max (yMax, rounded_y);
+      float x = all_points[i].x;
+      float y = all_points[i].y;
+      xMin = hb_min (xMin, x);
+      xMax = hb_max (xMax, x);
+      yMin = hb_min (yMin, y);
+      yMax = hb_max (yMax, y);
     }
 
-    update_mtx (plan, xMin, yMax, all_points);
+    update_mtx (plan, roundf (xMin), roundf (yMax), all_points);
 
     /*for empty glyphs: all_points only include phantom points.
      *just update metrics and then return */
@@ -134,10 +146,10 @@
       return true;
 
     glyph_header->numberOfContours = header->numberOfContours;
-    glyph_header->xMin = xMin;
-    glyph_header->yMin = yMin;
-    glyph_header->xMax = xMax;
-    glyph_header->yMax = yMax;
+    glyph_header->xMin = roundf (xMin);
+    glyph_header->yMin = roundf (yMin);
+    glyph_header->xMax = roundf (xMax);
+    glyph_header->yMax = roundf (yMax);
 
     dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size);
     return true;
@@ -199,9 +211,14 @@
 		   bool shift_points_hori = true,
 		   bool use_my_metrics = true,
 		   bool phantom_only = false,
+		   hb_array_t<int> coords = hb_array_t<int> (),
 		   unsigned int depth = 0) const
   {
     if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
+
+    if (!coords)
+      coords = hb_array (font->coords, font->num_coords);
+
     contour_point_vector_t stack_points;
     bool inplace = type == SIMPLE && all_points.length == 0;
     /* Load into all_points if it's empty, as an optimization. */
@@ -208,6 +225,10 @@
     contour_point_vector_t &points = inplace ? all_points : stack_points;
 
     switch (type) {
+    case SIMPLE:
+      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
+	return false;
+      break;
     case COMPOSITE:
     {
       /* pseudo component points for each component in composite glyph */
@@ -215,20 +236,25 @@
       if (unlikely (!points.resize (num_points))) return false;
       break;
     }
-    case SIMPLE:
-      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
-	return false;
+#ifndef HB_NO_VAR_COMPOSITES
+    case VAR_COMPOSITE:
+    {
+      for (auto &item : get_var_composite_iterator ())
+        if (unlikely (!item.get_points (points))) return false;
+    }
+#endif
+    default:
       break;
     }
 
     /* Init phantom points */
     if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
-    hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+    hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
     {
       int lsb = 0;
       int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
 		    (int) header->xMin - lsb : 0;
-      int tsb = 0;
+      HB_UNUSED int tsb = 0;
       int v_orig  = (int) header->yMax +
 #ifndef HB_NO_VERTICAL
 		    ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
@@ -257,7 +283,9 @@
     }
 
 #ifndef HB_NO_VAR
-    glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ());
+    glyf_accelerator.gvar->apply_deltas_to_points (gid,
+						   coords,
+						   points.as_array ());
 #endif
 
     // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
@@ -283,11 +311,24 @@
       for (auto &item : get_composite_iterator ())
       {
         comp_points.reset ();
+
 	if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
-				       .get_points (font, glyf_accelerator, comp_points,
-						    deltas, shift_points_hori, use_my_metrics, phantom_only, depth + 1)))
+				       .get_points (font,
+						    glyf_accelerator,
+						    comp_points,
+						    deltas,
+						    shift_points_hori,
+						    use_my_metrics,
+						    phantom_only,
+						    coords,
+						    depth + 1)))
 	  return false;
 
+	/* Copy phantom points from component if USE_MY_METRICS flag set */
+	if (use_my_metrics && item.is_use_my_metrics ())
+	  for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+	    phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+
 	/* Apply component transformation & translation */
 	item.transform_points (comp_points);
 
@@ -308,20 +349,63 @@
 	  }
 	}
 
+	all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
+
+	if (all_points.length > HB_GLYF_MAX_POINTS)
+	  return false;
+
+	comp_index++;
+      }
+
+      all_points.extend (phantoms);
+    } break;
+#ifndef HB_NO_VAR_COMPOSITES
+    case VAR_COMPOSITE:
+    {
+      contour_point_vector_t comp_points;
+      hb_array_t<contour_point_t> points_left = points.as_array ();
+      for (auto &item : get_var_composite_iterator ())
+      {
+	hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item.get_num_points ());
+
+        comp_points.reset ();
+
+	coord_setter_t coord_setter (coords);
+	item.set_variations (coord_setter, record_points);
+
+	if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
+				       .get_points (font,
+						    glyf_accelerator,
+						    comp_points,
+						    deltas,
+						    shift_points_hori,
+						    use_my_metrics,
+						    phantom_only,
+						    coord_setter.get_coords (),
+						    depth + 1)))
+	  return false;
+
+	/* Apply component transformation */
+	item.transform_points (record_points, comp_points);
+
 	/* Copy phantom points from component if USE_MY_METRICS flag set */
 	if (use_my_metrics && item.is_use_my_metrics ())
 	  for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
 	    phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
 
-	all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
+	all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
 
-	comp_index++;
+	if (all_points.length > HB_GLYF_MAX_POINTS)
+	  return false;
+
+	points_left += item.get_num_points ();
       }
-
       all_points.extend (phantoms);
     } break;
+#endif
     default:
       all_points.extend (phantoms);
+      break;
     }
 
     if (depth == 0 && shift_points_hori) /* Apply at top level */
@@ -360,6 +444,7 @@
     int num_contours = header->numberOfContours;
     if (unlikely (num_contours == 0)) type = EMPTY;
     else if (num_contours > 0) type = SIMPLE;
+    else if (num_contours == -2) type = VAR_COMPOSITE;
     else type = COMPOSITE; /* negative numbers */
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -132,8 +132,8 @@
 	if (unlikely (p + 1 > end)) return false;
 	unsigned int repeat_count = *p++;
 	unsigned stop = hb_min (i + repeat_count, count);
-	for (; i < stop;)
-	  points_.arrayZ[i++].flag = flag;
+	for (; i < stop; i++)
+	  points_.arrayZ[i].flag = flag;
       }
     }
     return true;
@@ -223,33 +223,34 @@
       if (value > 0) flag |= same_flag;
       else value = -value;
 
-      coords.push ((uint8_t)value);
+      coords.arrayZ[coords.length++] = (uint8_t) value;
     }
     else
     {
       int16_t val = value;
-      coords.push (val >> 8);
-      coords.push (val & 0xff);
+      coords.arrayZ[coords.length++] = val >> 8;
+      coords.arrayZ[coords.length++] = val & 0xff;
     }
   }
 
   static void encode_flag (uint8_t &flag,
                            uint8_t &repeat,
-                           uint8_t &lastflag,
+                           uint8_t lastflag,
                            hb_vector_t<uint8_t> &flags /* OUT */)
   {
     if (flag == lastflag && repeat != 255)
     {
-      repeat = repeat + 1;
+      repeat++;
       if (repeat == 1)
       {
-        flags.push(flag);
+        /* We know there's room. */
+        flags.arrayZ[flags.length++] = flag;
       }
       else
       {
         unsigned len = flags.length;
-        flags[len-2] = flag | FLAG_REPEAT;
-        flags[len-1] = repeat;
+        flags.arrayZ[len-2] = flag | FLAG_REPEAT;
+        flags.arrayZ[len-1] = repeat;
       }
     }
     else
@@ -257,7 +258,6 @@
       repeat = 0;
       flags.push (flag);
     }
-    lastflag = flag;
   }
 
   bool compile_bytes_with_deltas (const contour_point_vector_t &all_points,
@@ -269,7 +269,6 @@
       dest_bytes = hb_bytes_t ();
       return true;
     }
-    //convert absolute values to relative values
     unsigned num_points = all_points.length - 4;
 
     hb_vector_t<uint8_t> flags, x_coords, y_coords;
@@ -277,23 +276,23 @@
     if (unlikely (!x_coords.alloc (2*num_points))) return false;
     if (unlikely (!y_coords.alloc (2*num_points))) return false;
 
-    uint8_t lastflag = 0, repeat = 0;
-    int prev_x = 0.f, prev_y = 0.f;
-    
+    uint8_t lastflag = 255, repeat = 0;
+    int prev_x = 0, prev_y = 0;
+
     for (unsigned i = 0; i < num_points; i++)
     {
-      uint8_t flag = all_points[i].flag;
+      uint8_t flag = all_points.arrayZ[i].flag;
       flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
 
-      float cur_x = roundf (all_points[i].x);
-      float cur_y = roundf (all_points[i].y);
+      int cur_x = roundf (all_points.arrayZ[i].x);
+      int cur_y = roundf (all_points.arrayZ[i].y);
       encode_coord (cur_x - prev_x, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords);
       encode_coord (cur_y - prev_y, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords);
-      if (i == 0) lastflag = flag + 1; //make lastflag != flag for the first point
       encode_flag (flag, repeat, lastflag, flags);
 
       prev_x = cur_x;
       prev_y = cur_y;
+      lastflag = flag;
     }
 
     unsigned len_before_instrs = 2 * header.numberOfContours + 2;
@@ -303,12 +302,12 @@
     if (!no_hinting)
       total_len += len_instrs;
 
-    char *p = (char *) hb_calloc (total_len, sizeof (char));
+    char *p = (char *) hb_malloc (total_len);
     if (unlikely (!p)) return false;
 
     const char *src = bytes.arrayZ + GlyphHeader::static_size;
     char *cur = p;
-    memcpy (p, src, len_before_instrs);
+    hb_memcpy (p, src, len_before_instrs);
 
     cur += len_before_instrs;
     src += len_before_instrs;
@@ -315,17 +314,17 @@
 
     if (!no_hinting)
     {
-      memcpy (cur, src, len_instrs);
+      hb_memcpy (cur, src, len_instrs);
       cur += len_instrs;
     }
 
-    memcpy (cur, flags.arrayZ, flags.length);
+    hb_memcpy (cur, flags.arrayZ, flags.length);
     cur += flags.length;
 
-    memcpy (cur, x_coords.arrayZ, x_coords.length);
+    hb_memcpy (cur, x_coords.arrayZ, x_coords.length);
     cur += x_coords.length;
 
-    memcpy (cur, y_coords.arrayZ, y_coords.length);
+    hb_memcpy (cur, y_coords.arrayZ, y_coords.length);
 
     dest_bytes = hb_bytes_t (p, total_len);
     return true;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -21,10 +21,18 @@
 
   bool serialize (hb_serialize_context_t *c,
 		  bool use_short_loca,
-		  const hb_subset_plan_t *plan) const
+		  const hb_subset_plan_t *plan,
+		  hb_font_t *font)
   {
     TRACE_SERIALIZE (this);
 
+    if (font)
+    {
+      const OT::glyf_accelerator_t &glyf = *font->face->table.glyf;
+      if (!this->compile_bytes_with_deltas (plan, font, glyf))
+        return_trace (false);
+    }
+
     hb_bytes_t dest_glyph = dest_start.copy (c);
     dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
     unsigned int pad_length = use_short_loca ? padding () : 0;

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -0,0 +1,353 @@
+#ifndef OT_GLYF_VARCOMPOSITEGLYPH_HH
+#define OT_GLYF_VARCOMPOSITEGLYPH_HH
+
+
+#include "../../hb-open-type.hh"
+#include "coord-setter.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct VarCompositeGlyphRecord
+{
+  protected:
+  enum var_composite_glyph_flag_t
+  {
+    USE_MY_METRICS		= 0x0001,
+    AXIS_INDICES_ARE_SHORT	= 0x0002,
+    UNIFORM_SCALE		= 0x0004,
+    HAVE_TRANSLATE_X		= 0x0008,
+    HAVE_TRANSLATE_Y		= 0x0010,
+    HAVE_ROTATION		= 0x0020,
+    HAVE_SCALE_X		= 0x0040,
+    HAVE_SCALE_Y		= 0x0080,
+    HAVE_SKEW_X			= 0x0100,
+    HAVE_SKEW_Y			= 0x0200,
+    HAVE_TCENTER_X		= 0x0400,
+    HAVE_TCENTER_Y		= 0x0800,
+    GID_IS_24			= 0x1000,
+    AXES_HAVE_VARIATION		= 0x2000,
+  };
+
+  public:
+
+  unsigned int get_size () const
+  {
+    unsigned int size = min_size;
+
+    unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
+    size += numAxes * axis_width;
+
+    // gid
+    size += 2;
+    if (flags & GID_IS_24)		size += 1;
+
+    if (flags & HAVE_TRANSLATE_X)	size += 2;
+    if (flags & HAVE_TRANSLATE_Y)	size += 2;
+    if (flags & HAVE_ROTATION)		size += 2;
+    if (flags & HAVE_SCALE_X)		size += 2;
+    if (flags & HAVE_SCALE_Y)		size += 2;
+    if (flags & HAVE_SKEW_X)		size += 2;
+    if (flags & HAVE_SKEW_Y)		size += 2;
+    if (flags & HAVE_TCENTER_X)		size += 2;
+    if (flags & HAVE_TCENTER_Y)		size += 2;
+
+    return size;
+  }
+
+  bool has_more () const { return true; }
+
+  bool is_use_my_metrics () const { return flags & USE_MY_METRICS; }
+
+  hb_codepoint_t get_gid () const
+  {
+    if (flags & GID_IS_24)
+      return StructAfter<const HBGlyphID24> (numAxes);
+    else
+      return StructAfter<const HBGlyphID16> (numAxes);
+  }
+
+  unsigned get_numAxes () const
+  {
+    return numAxes;
+  }
+
+  unsigned get_num_points () const
+  {
+    unsigned num = 0;
+    if (flags & AXES_HAVE_VARIATION)			num += numAxes;
+    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))	num++;
+    if (flags & HAVE_ROTATION)				num++;
+    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))		num++;
+    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))		num++;
+    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))	num++;
+    return num;
+  }
+
+  void transform_points (hb_array_t<contour_point_t> record_points,
+			 contour_point_vector_t &points) const
+  {
+    float matrix[4];
+    contour_point_t trans;
+
+    get_transformation_from_points (record_points, matrix, trans);
+
+    points.transform (matrix);
+    points.translate (trans);
+  }
+
+  static inline void transform (float (&matrix)[4], contour_point_t &trans,
+				float (other)[6])
+  {
+    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268
+    float xx1 = other[0];
+    float xy1 = other[1];
+    float yx1 = other[2];
+    float yy1 = other[3];
+    float dx1 = other[4];
+    float dy1 = other[5];
+    float xx2 = matrix[0];
+    float xy2 = matrix[1];
+    float yx2 = matrix[2];
+    float yy2 = matrix[3];
+    float dx2 = trans.x;
+    float dy2 = trans.y;
+
+    matrix[0] = xx1*xx2 + xy1*yx2;
+    matrix[1] = xx1*xy2 + xy1*yy2;
+    matrix[2] = yx1*xx2 + yy1*yx2;
+    matrix[3] = yx1*xy2 + yy1*yy2;
+    trans.x = xx2*dx1 + yx2*dy1 + dx2;
+    trans.y = xy2*dx1 + yy2*dy1 + dy2;
+  }
+
+  static void translate (float (&matrix)[4], contour_point_t &trans,
+			 float translateX, float translateY)
+  {
+    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213
+    float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY};
+    transform (matrix, trans, other);
+  }
+
+  static void scale (float (&matrix)[4], contour_point_t &trans,
+		     float scaleX, float scaleY)
+  {
+    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224
+    float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f};
+    transform (matrix, trans, other);
+  }
+
+  static void rotate (float (&matrix)[4], contour_point_t &trans,
+		      float rotation)
+  {
+    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
+    rotation = rotation * float (M_PI);
+    float c = cosf (rotation);
+    float s = sinf (rotation);
+    float other[6] = {c, s, -s, c, 0.f, 0.f};
+    transform (matrix, trans, other);
+  }
+
+  static void skew (float (&matrix)[4], contour_point_t &trans,
+		    float skewX, float skewY)
+  {
+    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
+    skewX = skewX * float (M_PI);
+    skewY = skewY * float (M_PI);
+    float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
+    transform (matrix, trans, other);
+  }
+
+  bool get_points (contour_point_vector_t &points) const
+  {
+    float translateX = 0.f;
+    float translateY = 0.f;
+    float rotation = 0.f;
+    float scaleX = 1.f * (1 << 12);
+    float scaleY = 1.f * (1 << 12);
+    float skewX = 0.f;
+    float skewY = 0.f;
+    float tCenterX = 0.f;
+    float tCenterY = 0.f;
+
+    if (unlikely (!points.resize (points.length + get_num_points ()))) return false;
+
+    unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+    unsigned axes_size = numAxes * axis_width;
+
+    const F2DOT14 *q = (const F2DOT14 *) (axes_size +
+					  (flags & GID_IS_24 ? 3 : 2) +
+					  &StructAfter<const HBUINT8> (numAxes));
+
+    hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - get_num_points ());
+
+    unsigned count = numAxes;
+    if (flags & AXES_HAVE_VARIATION)
+    {
+      for (unsigned i = 0; i < count; i++)
+	rec_points[i].x = *q++;
+      rec_points += count;
+    }
+    else
+      q += count;
+
+    const HBUINT16 *p = (const HBUINT16 *) q;
+
+    if (flags & HAVE_TRANSLATE_X)	translateX = * (const FWORD *) p++;
+    if (flags & HAVE_TRANSLATE_Y)	translateY = * (const FWORD *) p++;
+    if (flags & HAVE_ROTATION)		rotation = * (const F2DOT14 *) p++;
+    if (flags & HAVE_SCALE_X)		scaleX = * (const F4DOT12 *) p++;
+    if (flags & HAVE_SCALE_Y)		scaleY = * (const F4DOT12 *) p++;
+    if (flags & HAVE_SKEW_X)		skewX = * (const F2DOT14 *) p++;
+    if (flags & HAVE_SKEW_Y)		skewY = * (const F2DOT14 *) p++;
+    if (flags & HAVE_TCENTER_X)		tCenterX = * (const FWORD *) p++;
+    if (flags & HAVE_TCENTER_Y)		tCenterY = * (const FWORD *) p++;
+
+    if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y))
+      scaleY = scaleX;
+
+    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+    {
+      rec_points[0].x = translateX;
+      rec_points[0].y = translateY;
+      rec_points++;
+    }
+    if (flags & HAVE_ROTATION)
+    {
+      rec_points[0].x = rotation;
+      rec_points++;
+    }
+    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+    {
+      rec_points[0].x = scaleX;
+      rec_points[0].y = scaleY;
+      rec_points++;
+    }
+    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+    {
+      rec_points[0].x = skewX;
+      rec_points[0].y = skewY;
+      rec_points++;
+    }
+    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+    {
+      rec_points[0].x = tCenterX;
+      rec_points[0].y = tCenterY;
+      rec_points++;
+    }
+    assert (!rec_points);
+
+    return true;
+  }
+
+  void get_transformation_from_points (hb_array_t<contour_point_t> rec_points,
+				       float (&matrix)[4], contour_point_t &trans) const
+  {
+    if (flags & AXES_HAVE_VARIATION)
+      rec_points += numAxes;
+
+    matrix[0] = matrix[3] = 1.f;
+    matrix[1] = matrix[2] = 0.f;
+    trans.init (0.f, 0.f);
+
+    float translateX = 0.f;
+    float translateY = 0.f;
+    float rotation = 0.f;
+    float scaleX = 1.f;
+    float scaleY = 1.f;
+    float skewX = 0.f;
+    float skewY = 0.f;
+    float tCenterX = 0.f;
+    float tCenterY = 0.f;
+
+    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+    {
+      translateX = rec_points[0].x;
+      translateY = rec_points[0].y;
+      rec_points++;
+    }
+    if (flags & HAVE_ROTATION)
+    {
+      rotation = rec_points[0].x / (1 << 14);
+      rec_points++;
+    }
+    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+    {
+      scaleX = rec_points[0].x / (1 << 12);
+      scaleY = rec_points[0].y / (1 << 12);
+      rec_points++;
+    }
+    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+    {
+      skewX = rec_points[0].x / (1 << 14);
+      skewY = rec_points[0].y / (1 << 14);
+      rec_points++;
+    }
+    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+    {
+      tCenterX = rec_points[0].x;
+      tCenterY = rec_points[0].y;
+      rec_points++;
+    }
+    assert (!rec_points);
+
+    translate (matrix, trans, translateX + tCenterX, translateY + tCenterY);
+    rotate (matrix, trans, rotation);
+    scale (matrix, trans, scaleX, scaleY);
+    skew (matrix, trans, -skewX, skewY);
+    translate (matrix, trans, -tCenterX, -tCenterY);
+  }
+
+  void set_variations (coord_setter_t &setter,
+		       hb_array_t<contour_point_t> rec_points) const
+  {
+    bool have_variations = flags & AXES_HAVE_VARIATION;
+    unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+
+    const HBUINT8  *p = (const HBUINT8 *)  (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
+    const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
+
+    const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes)));
+
+    unsigned count = numAxes;
+    for (unsigned i = 0; i < count; i++)
+    {
+      unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++;
+
+      signed v = have_variations ? rec_points[i].x : *a++;
+
+      v += setter[axis_index];
+      v = hb_clamp (v, -(1<<14), (1<<14));
+      setter[axis_index] = v;
+    }
+  }
+
+  protected:
+  HBUINT16	flags;
+  HBUINT8	numAxes;
+  public:
+  DEFINE_SIZE_MIN (3);
+};
+
+using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>;
+
+struct VarCompositeGlyph
+{
+  const GlyphHeader &header;
+  hb_bytes_t bytes;
+  VarCompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
+    header (header_), bytes (bytes_) {}
+
+  var_composite_iter_t iter () const
+  { return var_composite_iter_t (bytes, &StructAfter<VarCompositeGlyphRecord, GlyphHeader> (header)); }
+
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_VARCOMPOSITEGLYPH_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/composite-iter.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/composite-iter.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/composite-iter.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -0,0 +1,68 @@
+#ifndef OT_GLYF_COMPOSITE_ITER_HH
+#define OT_GLYF_COMPOSITE_ITER_HH
+
+
+#include "../../hb.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+template <typename CompositeGlyphRecord>
+struct composite_iter_tmpl : hb_iter_with_fallback_t<composite_iter_tmpl<CompositeGlyphRecord>,
+						     const CompositeGlyphRecord &>
+{
+  typedef const CompositeGlyphRecord *__item_t__;
+  composite_iter_tmpl (hb_bytes_t glyph_, __item_t__ current_) :
+      glyph (glyph_), current (nullptr), current_size (0)
+  {
+    set_current (current_);
+  }
+
+  composite_iter_tmpl () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {}
+
+  const CompositeGlyphRecord & __item__ () const { return *current; }
+  bool __more__ () const { return current; }
+  void __next__ ()
+  {
+    if (!current->has_more ()) { current = nullptr; return; }
+
+    set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size));
+  }
+  composite_iter_tmpl __end__ () const { return composite_iter_tmpl (); }
+  bool operator != (const composite_iter_tmpl& o) const
+  { return current != o.current; }
+
+
+  void set_current (__item_t__ current_)
+  {
+    if (!glyph.check_range (current_, CompositeGlyphRecord::min_size))
+    {
+      current = nullptr;
+      current_size = 0;
+      return;
+    }
+    unsigned size = current_->get_size ();
+    if (!glyph.check_range (current_, size))
+    {
+      current = nullptr;
+      current_size = 0;
+      return;
+    }
+
+    current = current_;
+    current_size = size;
+  }
+
+  private:
+  hb_bytes_t glyph;
+  __item_t__ current;
+  unsigned current_size;
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+#endif /* OT_GLYF_COMPOSITE_ITER_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/coord-setter.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/coord-setter.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/coord-setter.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -0,0 +1,34 @@
+#ifndef OT_GLYF_COORD_SETTER_HH
+#define OT_GLYF_COORD_SETTER_HH
+
+
+#include "../../hb.hh"
+
+
+namespace OT {
+namespace glyf_impl {
+
+
+struct coord_setter_t
+{
+  coord_setter_t (hb_array_t<int> coords) :
+    coords (coords) {}
+
+  int& operator [] (unsigned idx)
+  {
+    if (coords.length < idx + 1)
+      coords.resize (idx + 1);
+    return coords[idx];
+  }
+
+  hb_array_t<int> get_coords ()
+  { return coords.as_array (); }
+
+  hb_vector_t<int> coords;
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+#endif /* OT_GLYF_COORD_SETTER_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -42,11 +42,15 @@
   bool serialize (hb_serialize_context_t *c,
 		  Iterator it,
                   bool use_short_loca,
-		  const hb_subset_plan_t *plan)
+		  const hb_subset_plan_t *plan,
+		  hb_font_t *font)
   {
     TRACE_SERIALIZE (this);
+
     unsigned init_len = c->length ();
-    for (const auto &_ : it) _.serialize (c, use_short_loca, plan);
+    for (auto &_ : it)
+      if (unlikely (!_.serialize (c, use_short_loca, plan, font)))
+        return false;
 
     /* As a special case when all glyph in the font are empty, add a zero byte
      * to the table, so that OTS doesn’t reject it, and to make the table work
@@ -74,10 +78,11 @@
     hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
     _populate_subset_glyphs (c->plan, glyphs);
 
+    hb_font_t *font = nullptr;
     if (!c->plan->pinned_at_default)
     {
-      if (!_compile_subset_glyphs_with_deltas (c->plan, &glyphs))
-        return_trace (false);
+      font = _create_font_for_instancing (c->plan);
+      if (unlikely (!font)) return false;
     }
 
     auto padded_offsets =
@@ -85,11 +90,14 @@
     | hb_map (&glyf_impl::SubsetGlyph::padded_size)
     ;
 
-    unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
-    bool use_short_loca = max_offset < 0x1FFFF;
+    bool use_short_loca = false;
+    if (likely (!c->plan->force_long_loca))
+    {
+      unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
+      use_short_loca = max_offset < 0x1FFFF;
+    }
 
-
-    glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan);
+    glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan, font);
     if (!use_short_loca) {
       padded_offsets =
           + hb_iter (glyphs)
@@ -97,9 +105,12 @@
           ;
     }
 
+    if (font)
+    {
+      _free_compiled_subset_glyphs (&glyphs);
+      hb_font_destroy (font);
+    }
 
-    if (!c->plan->pinned_at_default)
-      _free_compiled_subset_glyphs (&glyphs);
     if (unlikely (c->serializer->in_error ())) return_trace (false);
     return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
 									       padded_offsets,
@@ -110,9 +121,8 @@
   _populate_subset_glyphs (const hb_subset_plan_t   *plan,
 			   hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const;
 
-  bool
-  _compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
-                                      hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
+  hb_font_t *
+  _create_font_for_instancing (const hb_subset_plan_t *plan) const;
 
   void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> *glyphs) const
   {
@@ -394,7 +404,11 @@
                   plan->pinned_at_default)
       subset_glyph.source_glyph = glyf_impl::Glyph ();
     else
-      subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
+    {
+      /* If plan has an accelerator, the preprocessing step already trimmed glyphs.
+       * Don't trim them again! */
+      subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, !plan->accelerator);
+    }
 
     if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
       subset_glyph.drop_hints_bytes ();
@@ -403,17 +417,15 @@
   }
 }
 
-inline bool
-glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
-                                          hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
+inline hb_font_t *
+glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const
 {
-  OT::glyf_accelerator_t glyf (plan->source);
   hb_font_t *font = hb_font_create (plan->source);
-  if (unlikely (!font)) return false;
+  if (unlikely (font == hb_font_get_empty ())) return nullptr;
 
   hb_vector_t<hb_variation_t> vars;
   if (unlikely (!vars.alloc (plan->user_axes_location->get_population ())))
-    return false;
+    return nullptr;
 
   for (auto _ : *plan->user_axes_location)
   {
@@ -423,18 +435,10 @@
     vars.push (var);
   }
 
+#ifndef HB_NO_VAR
   hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
-  for (auto& subset_glyph : *glyphs)
-  {
-    if (!const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf))
-    {
-      hb_font_destroy (font);
-      return false;
-    }
-  }
-
-  hb_font_destroy (font);
-  return true;
+#endif
+  return font;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py	2022-12-18 01:06:39 UTC (rev 65304)
@@ -31,7 +31,7 @@
 		symprefix = '_' if suffix == 'dylib' else ''
 
 		EXPORTED_SYMBOLS = [s.split ()[2]
-				    for s in re.findall (r'^.+ [BCDGIRST] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE)
+				    for s in re.findall (r'^.+ [BCDGIRSTu] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE)
 				    if not re.match (r'.* %s(%s)\b' % (symprefix, IGNORED_SYMBOLS), s)]
 
 		# run again c++filt also if is available

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py	2022-12-18 01:06:39 UTC (rev 65304)
@@ -20,9 +20,7 @@
 	# Move these to harfbuzz-sections.txt when got stable
 	experimental_symbols = \
 """hb_subset_repack_or_fail
-hb_subset_input_pin_axis_location
-hb_subset_input_pin_axis_to_default
-hb_subset_preprocess
+hb_subset_input_override_name_table
 """.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-indic-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py	2022-12-18 01:06:39 UTC (rev 65304)
@@ -95,6 +95,7 @@
     'PLACEHOLDER',
     'DOTTEDCIRCLE',
     'RS',
+    'MPst',
     'Repha',
     'Ra',
     'CM',
@@ -168,8 +169,6 @@
   'Vowel'			: 'V',
   'Vowel_Dependent'		: 'M',
   'Vowel_Independent'		: 'V',
-  'Dotted_Circle'		: 'DOTTEDCIRCLE', # Ours, not Unicode's
-  'Ra'				: 'Ra', # Ours, not Unicode's
 }
 position_map = {
   'Not_Applicable'		: 'END',
@@ -240,6 +239,9 @@
   0x0953: 'SM',
   0x0954: 'SM',
 
+  # U+0A40 GURMUKHI VOWEL SIGN II may be preceded by U+0A02 GURMUKHI SIGN BINDI.
+  0x0A40: 'MPst',
+
   # The following act like consonants.
   0x0A72: 'C',
   0x0A73: 'C',
@@ -440,7 +442,7 @@
   indic_data[k] = (new_cat, pos, unicode_data[2][k])
 
 # We only expect position for certain types
-positioned_categories = ('CM', 'SM', 'RS', 'H', 'M')
+positioned_categories = ('CM', 'SM', 'RS', 'H', 'M', 'MPst')
 for k, (cat, pos, block) in indic_data.items():
   if cat not in positioned_categories:
     pos = 'END'
@@ -450,11 +452,12 @@
 
 # Keep in sync with CONSONANT_FLAGS in the shaper
 consonant_categories = ('C', 'CS', 'Ra','CM', 'V', 'PLACEHOLDER', 'DOTTEDCIRCLE')
+matra_categories = ('M', 'MPst')
 smvd_categories = ('SM', 'VD', 'A', 'Symbol')
 for k, (cat, pos, block) in indic_data.items():
   if cat in consonant_categories:
     pos = 'BASE_C'
-  elif cat == 'M':
+  elif cat in matra_categories:
     if block.startswith('Khmer') or block.startswith('Myanmar'):
       cat = position_to_category(pos)
     else:
@@ -634,7 +637,7 @@
 	end = (end-1)//8*8 + 7
 
 	if start != last + 1:
-		if start - last <= 1+16*3:
+		if start - last <= 1+16*2:
 			print_block (None, last+1, start-1, indic_data)
 		else:
 			if last >= 0:
@@ -691,6 +694,6 @@
 print ()
 print ("/* == End of generated table == */")
 
-# Maintain at least 30% occupancy in the table */
-if occupancy < 30:
+# Maintain at least 50% occupancy in the table */
+if occupancy < 50:
 	raise Exception ("Table too sparse, please investigate: ", occupancy)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py	2022-12-18 01:06:39 UTC (rev 65304)
@@ -25,14 +25,28 @@
 
 logging.info('Preparing data tables...')
 
+
+# This is how the data is encoded:
+#
+# General_Category (gc), Canonical_Combining_Class (ccc),
+# and Script (sc) are encoded as integers.
+#
+# Mirroring character (bmg) is encoded as difference from
+# the original character.
+#
+# Composition & Decomposition (dm) are encoded elaborately,
+# as discussed below.
+
 gc = [u['gc'] for u in ucd]
 ccc = [int(u['ccc']) for u in ucd]
 bmg = [int(v, 16) - int(u) if v else 0 for u,v in enumerate(u['bmg'] for u in ucd)]
-#gc_ccc_non0 = set((cat,klass) for cat,klass in zip(gc,ccc) if klass)
-#gc_bmg_non0 = set((cat,mirr) for cat,mirr in zip(gc, bmg) if mirr)
-
 sc = [u['sc'] for u in ucd]
 
+
+# Prepare Compose / Decompose data
+#
+# This code is very dense.  See hb_ucd_compose() / hb_ucd_decompose() for the logic.
+
 dm = {i:tuple(int(v, 16) for v in u['dm'].split()) for i,u in enumerate(ucd)
       if u['dm'] != '#' and u['dt'] == 'can' and not (0xAC00 <= i < 0xAC00+11172)}
 ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'}
@@ -63,6 +77,9 @@
 dm_order.update(dm1_order)
 dm_order.update(dm2_order)
 
+
+# Prepare General_Category / Script mapping arrays
+
 gc_order = dict()
 for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu',
                       'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf',
@@ -83,11 +100,19 @@
     sc_order[i] = tag
     sc_array.append(name)
 
-DEFAULT = 3
-COMPACT = 5
-SLOPPY  = 9
 
+# Write out main data
 
+DEFAULT = 'DEFAULT'
+COMPACT = 'COMPACT'
+SLOPPY  = 'SLOPPY'
+
+compression_level = {
+    DEFAULT: 5,
+    COMPACT: 9,
+    SLOPPY:  9,
+}
+
 logging.info('Generating output...')
 print("/* == Start of generated table == */")
 print("/*")
@@ -104,6 +129,9 @@
 print('#include "hb.hh"')
 print()
 
+
+# Write mapping data
+
 code = packTab.Code('_hb_ucd')
 sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array)
 dm1_p0_array, _ = code.addArray('uint16_t', 'dm1_p0_map', dm1_p0_array)
@@ -120,18 +148,24 @@
     ('dm', dm, None, dm_order),
 ]
 
-for compression in (DEFAULT, COMPACT, SLOPPY):
+
+# Write main data
+
+for step in (DEFAULT, COMPACT, SLOPPY):
+    compression = compression_level[step]
     logging.info('  Compression=%d:' % compression)
     print()
-    if compression == DEFAULT:
+    if step == DEFAULT:
         print('#ifndef HB_OPTIMIZE_SIZE')
-    elif compression == COMPACT:
+    elif step == COMPACT:
         print('#elif !defined(HB_NO_UCD_UNASSIGNED)')
+    elif step == SLOPPY:
+        print('#else')
     else:
-        print('#else')
+        assert False
     print()
 
-    if compression == SLOPPY:
+    if step == SLOPPY:
         for i in range(len(gc)):
             if (i % 128) and gc[i] == 'Cn':
                 gc[i] = gc[i - 1]
@@ -157,6 +191,7 @@
 
     print()
 
+
 print('#endif')
 print()
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,6 +1,9 @@
 #!/usr/bin/env python3
 # flake8: noqa: F821
 
+import logging
+logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
+
 """usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
 
 Input files:
@@ -465,11 +468,30 @@
 
 import packTab
 data = {u:v[0] for u,v in use_data.items()}
-code = packTab.Code('hb_use')
-sol = packTab.pack_table(data, compression=5, default='O')
-sol.genCode(code, f'get_category')
-code.print_c(linkage='static inline')
 
+DEFAULT = 5
+COMPACT = 9
+for compression in (DEFAULT, COMPACT):
+
+    logging.info('  Compression=%d:' % compression)
+    print()
+    if compression == DEFAULT:
+        print('#ifndef HB_OPTIMIZE_SIZE')
+    elif compression == COMPACT:
+        print('#else')
+    else:
+        assert False
+    print()
+
+    code = packTab.Code('hb_use')
+    sol = packTab.pack_table(data, compression=compression, default='O')
+    logging.info('      FullCost=%d' % (sol.fullCost))
+    sol.genCode(code, f'get_category')
+    code.print_c(linkage='static inline')
+    print ()
+
+print('#endif')
+
 print ()
 for k in sorted(use_mapping.keys()):
 	if k in use_positions and use_positions[k]: continue

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/classdef-graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/classdef-graph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/classdef-graph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -112,7 +112,7 @@
     {
     case 1: return ((ClassDefFormat1*)this)->sanitize (vertex);
     case 2: return ((ClassDefFormat2*)this)->sanitize (vertex);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     // Not currently supported
     case 3:
     case 4:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/coverage-graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/coverage-graph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/coverage-graph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -136,7 +136,7 @@
     {
     case 1: return ((CoverageFormat1*)this)->sanitize (vertex);
     case 2: return ((CoverageFormat2*)this)->sanitize (vertex);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     // Not currently supported
     case 3:
     case 4:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -49,6 +49,50 @@
     unsigned end = 0;
     unsigned priority = 0;
 
+
+    bool link_positions_valid (unsigned num_objects, bool removed_nil)
+    {
+      hb_set_t assigned_bytes;
+      for (const auto& l : obj.real_links)
+      {
+        if (l.objidx >= num_objects
+            || (removed_nil && !l.objidx))
+        {
+          DEBUG_MSG (SUBSET_REPACK, nullptr,
+                     "Invalid graph. Invalid object index.");
+          return false;
+        }
+
+        unsigned start = l.position;
+        unsigned end = start + l.width - 1;
+
+        if (unlikely (l.width < 2 || l.width > 4))
+        {
+          DEBUG_MSG (SUBSET_REPACK, nullptr,
+                     "Invalid graph. Invalid link width.");
+          return false;
+        }
+
+        if (unlikely (end >= table_size ()))
+        {
+          DEBUG_MSG (SUBSET_REPACK, nullptr,
+                     "Invalid graph. Link position is out of bounds.");
+          return false;
+        }
+
+        if (unlikely (assigned_bytes.intersects (start, end)))
+        {
+          DEBUG_MSG (SUBSET_REPACK, nullptr,
+                     "Invalid graph. Found offsets whose positions overlap.");
+          return false;
+        }
+
+        assigned_bytes.add_range (start, end);
+      }
+
+      return !assigned_bytes.in_error ();
+    }
+
     void normalize ()
     {
       obj.real_links.qsort ();
@@ -132,7 +176,7 @@
       for (unsigned i = 0; i < parents.length; i++)
       {
         if (parents[i] != parent_index) continue;
-        parents.remove (i);
+        parents.remove_unordered (i);
         break;
       }
     }
@@ -148,7 +192,7 @@
         if ((obj.head + link.position) != offset)
           continue;
 
-        obj.real_links.remove (i);
+        obj.real_links.remove_unordered (i);
         return;
       }
     }
@@ -286,8 +330,6 @@
     vertices_scratch_.alloc (objects.length);
     for (unsigned i = 0; i < objects.length; i++)
     {
-      // TODO(grieger): check all links point to valid objects.
-
       // If this graph came from a serialization buffer object 0 is the
       // nil object. We don't need it for our purposes here so drop it.
       if (i == 0 && !objects[i])
@@ -299,6 +341,9 @@
       vertex_t* v = vertices_.push ();
       if (check_success (!vertices_.in_error ()))
         v->obj = *objects[i];
+
+      check_success (v->link_positions_valid (objects.length, removed_nil));
+
       if (!removed_nil) continue;
       // Fix indices to account for removed nil object.
       for (auto& l : v->obj.all_links_writer ()) {
@@ -418,6 +463,13 @@
       hb_swap (sorted_graph[new_id], vertices_[next_id]);
       const vertex_t& next = sorted_graph[new_id];
 
+      if (unlikely (!check_success(new_id >= 0))) {
+        // We are out of ids. Which means we've visited a node more than once.
+        // This graph contains a cycle which is not allowed.
+        DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle.");
+        return;
+      }
+
       id_map[next_id] = new_id--;
 
       for (const auto& link : next.obj.all_links ()) {
@@ -580,7 +632,7 @@
 
     while (roots)
     {
-      unsigned next = HB_SET_VALUE_INVALID;
+      uint32_t next = HB_SET_VALUE_INVALID;
       if (unlikely (!check_success (!roots.in_error ()))) break;
       if (!roots.next (&next)) break;
 
@@ -661,8 +713,8 @@
 
     auto new_subgraph =
         + subgraph.keys ()
-        | hb_map([&] (unsigned node_idx) {
-          const unsigned *v;
+        | hb_map([&] (uint32_t node_idx) {
+          const uint32_t *v;
           if (index_map.has (node_idx, &v)) return *v;
           return node_idx;
         })
@@ -672,10 +724,10 @@
     remap_obj_indices (index_map, parents.iter (), true);
 
     // Update roots set with new indices as needed.
-    unsigned next = HB_SET_VALUE_INVALID;
+    uint32_t next = HB_SET_VALUE_INVALID;
     while (roots.next (&next))
     {
-      const unsigned *v;
+      const uint32_t *v;
       if (index_map.has (next, &v))
       {
         roots.del (next);
@@ -690,7 +742,7 @@
   {
     for (const auto& link : vertices_[node_idx].obj.all_links ())
     {
-      const unsigned *v;
+      const uint32_t *v;
       if (subgraph.has (link.objidx, &v))
       {
         subgraph.set (link.objidx, *v + 1);
@@ -941,6 +993,72 @@
     return made_change;
   }
 
+  bool is_fully_connected ()
+  {
+    update_parents();
+
+    if (root().parents)
+      // Root cannot have parents.
+      return false;
+
+    for (unsigned i = 0; i < root_idx (); i++)
+    {
+      if (!vertices_[i].parents)
+        return false;
+    }
+    return true;
+  }
+
+#if 0
+  /*
+   * Saves the current graph to a packed binary format which the repacker fuzzer takes
+   * as a seed.
+   */
+  void save_fuzzer_seed (hb_tag_t tag) const
+  {
+    FILE* f = fopen ("./repacker_fuzzer_seed", "w");
+    fwrite ((void*) &tag, sizeof (tag), 1, f);
+
+    uint16_t num_objects = vertices_.length;
+    fwrite ((void*) &num_objects, sizeof (num_objects), 1, f);
+
+    for (const auto& v : vertices_)
+    {
+      uint16_t blob_size = v.table_size ();
+      fwrite ((void*) &blob_size, sizeof (blob_size), 1, f);
+      fwrite ((const void*) v.obj.head, blob_size, 1, f);
+    }
+
+    uint16_t link_count = 0;
+    for (const auto& v : vertices_)
+      link_count += v.obj.real_links.length;
+
+    fwrite ((void*) &link_count, sizeof (link_count), 1, f);
+
+    typedef struct
+    {
+      uint16_t parent;
+      uint16_t child;
+      uint16_t position;
+      uint8_t width;
+    } link_t;
+
+    for (unsigned i = 0; i < vertices_.length; i++)
+    {
+      for (const auto& l : vertices_[i].obj.real_links)
+      {
+        link_t link {
+          (uint16_t) i, (uint16_t) l.objidx,
+          (uint16_t) l.position, (uint8_t) l.width
+        };
+        fwrite ((void*) &link, sizeof (link), 1, f);
+      }
+    }
+
+    fclose (f);
+  }
+#endif
+
   void print_orphaned_nodes ()
   {
     if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
@@ -949,6 +1067,10 @@
     parents_invalid = true;
     update_parents();
 
+    if (root().parents) {
+      DEBUG_MSG (SUBSET_REPACK, nullptr, "Root node has incoming edges.");
+    }
+
     for (unsigned i = 0; i < root_idx (); i++)
     {
       const auto& v = vertices_[i];
@@ -1065,6 +1187,11 @@
       }
     }
 
+    for (unsigned i = 0; i < vertices_.length; i++)
+      // parents arrays must be accurate or downstream operations like cycle detection
+      // and sorting won't work correctly.
+      check_success (!vertices_[i].parents.in_error ());
+
     parents_invalid = false;
   }
 
@@ -1183,7 +1310,7 @@
     {
       for (auto& link : vertices_[i].obj.all_links_writer ())
       {
-        const unsigned *v;
+        const uint32_t *v;
         if (!id_map.has (link.objidx, &v)) continue;
         if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-graph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-graph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -201,7 +201,7 @@
                       + new_subtable_count * OT::Offset16::static_size;
     char* buffer = (char*) hb_calloc (1, new_size);
     c.add_buffer (buffer);
-    memcpy (buffer, v.obj.head, v.table_size());
+    hb_memcpy (buffer, v.obj.head, v.table_size());
 
     v.obj.head = buffer;
     v.obj.tail = buffer + new_size;
@@ -355,7 +355,7 @@
   {
     switch (u.version.major) {
     case 1: return u.version1.get_lookup_list_offset ();
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: return u.version2.get_lookup_list_offset ();
 #endif
     default: return 0;
@@ -374,7 +374,7 @@
   {
     switch (u.version.major) {
       case 1: find_lookups<SmallTypes> (graph, lookups); break;
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
       case 2: find_lookups<MediumTypes> (graph, lookups); break;
 #endif
     }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -112,7 +112,7 @@
       auto& child = c.graph.vertices_[child_idx];
       child.remove_parent (this_index);
 
-      o.real_links.remove (i);
+      o.real_links.remove_unordered (i);
       num_links--;
       i--;
     }
@@ -372,7 +372,7 @@
     if (!mark_coverage) return false;
     hb_set_t marks = sc.marks_for (0, count);
     auto new_coverage =
-        + hb_zip (hb_range (), mark_coverage.table->iter ())
+        + hb_enumerate (mark_coverage.table->iter ())
         | hb_filter (marks, hb_first)
         | hb_map_retains_sorting (hb_second)
         ;
@@ -431,7 +431,7 @@
     if (!mark_coverage) return false;
     hb_set_t marks = sc.marks_for (start, end);
     auto new_coverage =
-        + hb_zip (hb_range (), mark_coverage.table->iter ())
+        + hb_enumerate (mark_coverage.table->iter ())
         | hb_filter (marks, hb_first)
         | hb_map_retains_sorting (hb_second)
         ;
@@ -477,7 +477,7 @@
     switch (u.format) {
     case 1:
       return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: HB_FALLTHROUGH;
       // Don't split 24bit PairPos's.
 #endif
@@ -494,7 +494,7 @@
     switch (u.format) {
     case 1:
       return ((MarkBasePosFormat1*)(&u.format1))->sanitize (vertex);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 2: HB_FALLTHROUGH;
 #endif
     default:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/pairpos-graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/pairpos-graph.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/pairpos-graph.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -434,7 +434,7 @@
 
     char* start_addr = ((char*)&values[0]) + start * split_context.class1_record_size;
     unsigned num_records = end - start;
-    memcpy (&pair_pos_prime->values[0],
+    hb_memcpy (&pair_pos_prime->values[0],
             start_addr,
             num_records * split_context.class1_record_size);
 
@@ -611,7 +611,7 @@
       return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
     case 2:
       return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: HB_FALLTHROUGH;
     case 4: HB_FALLTHROUGH;
       // Don't split 24bit PairPos's.
@@ -631,7 +631,7 @@
       return ((PairPosFormat1*)(&u.format1))->sanitize (vertex);
     case 2:
       return ((PairPosFormat2*)(&u.format2))->sanitize (vertex);
-#ifndef HB_NO_BORING_EXPANSION
+#ifndef HB_NO_BEYOND_64K
     case 3: HB_FALLTHROUGH;
     case 4: HB_FALLTHROUGH;
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -33,6 +33,23 @@
 {
   unsigned parent;
   unsigned child;
+
+  bool operator != (const overflow_record_t o) const
+  { return !(*this == o); }
+
+  inline bool operator == (const overflow_record_t& o) const
+  {
+    return parent == o.parent &&
+        child == o.child;
+  }
+
+  inline uint32_t hash () const
+  {
+    uint32_t current = 0;
+    current = current * 31 + hb_hash (parent);
+    current = current * 31 + hb_hash (child);
+    return current;
+  }
 };
 
 inline
@@ -94,6 +111,7 @@
   if (overflows) overflows->resize (0);
   graph.update_positions ();
 
+  hb_hashmap_t<overflow_record_t*, bool> record_set;
   const auto& vertices = graph.vertices_;
   for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--)
   {
@@ -109,7 +127,10 @@
       overflow_record_t r;
       r.parent = parent_idx;
       r.child = link.objidx;
+      if (record_set.has(&r)) continue; // don't keep duplicate overflows.
+
       overflows->push (r);
+      record_set.set(&r, true);
     }
   }
 
@@ -223,7 +244,7 @@
       return nullptr;
     }
 
-    memcpy (start, vertices[i].obj.head, size);
+    hb_memcpy (start, vertices[i].obj.head, size);
 
     // Only real links needs to be serialized.
     for (const auto& link : vertices[i].obj.real_links)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1,29 +1,5 @@
-# Set these variables so that the `${prefix}/lib` expands to something we can
-# remove.
-set(_harfbuzz_remove_string "REMOVE_ME")
-set(exec_prefix "${_harfbuzz_remove_string}")
-set(prefix "${_harfbuzz_remove_string}")
-
-# Compute the installation prefix by stripping components from our current
-# location.
-get_filename_component(_harfbuzz_prefix "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY)
-get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY)
 set(_harfbuzz_libdir "@libdir@")
-string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_libdir "${_harfbuzz_libdir}")
-set(_harfbuzz_libdir_iter "${_harfbuzz_libdir}")
-while (_harfbuzz_libdir_iter)
-  set(_harfbuzz_libdir_prev_iter "${_harfbuzz_libdir_iter}")
-  get_filename_component(_harfbuzz_libdir_iter "${_harfbuzz_libdir_iter}" DIRECTORY)
-  if (_harfbuzz_libdir_prev_iter STREQUAL _harfbuzz_libdir_iter)
-    break()
-  endif ()
-  get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY)
-endwhile ()
-unset(_harfbuzz_libdir_iter)
-
-# Get the include subdir.
 set(_harfbuzz_includedir "@includedir@")
-string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_includedir "${_harfbuzz_includedir}")
 
 # Extract version information from libtool.
 set(_harfbuzz_version_info "@HB_LIBTOOL_VERSION_INFO@")
@@ -48,20 +24,20 @@
 # Add the libraries.
 add_library(harfbuzz::harfbuzz SHARED IMPORTED)
 set_target_properties(harfbuzz::harfbuzz PROPERTIES
-  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz"
-  IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz${_harfbuzz_lib_suffix}")
+  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
+  IMPORTED_LOCATION "${_harfbuzz_libdir}/libharfbuzz${_harfbuzz_lib_suffix}")
 
 add_library(harfbuzz::icu SHARED IMPORTED)
 set_target_properties(harfbuzz::icu PROPERTIES
-  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz"
+  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
   INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
-  IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-icu${_harfbuzz_lib_suffix}")
+  IMPORTED_LOCATION "${_harfbuzz_libdir}/libharfbuzz-icu${_harfbuzz_lib_suffix}")
 
 add_library(harfbuzz::subset SHARED IMPORTED)
 set_target_properties(harfbuzz::subset PROPERTIES
-  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz"
+  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
   INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
-  IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-subset${_harfbuzz_lib_suffix}")
+  IMPORTED_LOCATION "${_harfbuzz_libdir}/libharfbuzz-subset${_harfbuzz_lib_suffix}")
 
 # Only add the gobject library if it was built.
 set(_harfbuzz_have_gobject "@have_gobject@")
@@ -68,9 +44,9 @@
 if (_harfbuzz_have_gobject)
   add_library(harfbuzz::gobject SHARED IMPORTED)
   set_target_properties(harfbuzz::gobject PROPERTIES
-    INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz"
+    INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
     INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
-    IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-gobject${_harfbuzz_lib_suffix}")
+    IMPORTED_LOCATION "${_harfbuzz_libdir}/libharfbuzz-gobject${_harfbuzz_lib_suffix}")
 endif ()
 
 # Clean out variables we used in our scope.
@@ -80,7 +56,3 @@
 unset(_harfbuzz_age)
 unset(_harfbuzz_includedir)
 unset(_harfbuzz_libdir)
-unset(_harfbuzz_prefix)
-unset(exec_prefix)
-unset(prefix)
-unset(_harfbuzz_remove_string)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -131,14 +131,14 @@
 	  hb_glyph_info_t *info = buffer->info;
 	  hb_glyph_info_t buf[4];
 
-	  memcpy (buf, info + start, l * sizeof (buf[0]));
-	  memcpy (buf + 2, info + end - r, r * sizeof (buf[0]));
+	  hb_memcpy (buf, info + start, l * sizeof (buf[0]));
+	  hb_memcpy (buf + 2, info + end - r, r * sizeof (buf[0]));
 
 	  if (l != r)
 	    memmove (info + start + r, info + start + l, (end - start - l - r) * sizeof (buf[0]));
 
-	  memcpy (info + start, buf + 2, r * sizeof (buf[0]));
-	  memcpy (info + end - l, buf, l * sizeof (buf[0]));
+	  hb_memcpy (info + start, buf + 2, r * sizeof (buf[0]));
+	  hb_memcpy (info + end - l, buf, l * sizeof (buf[0]));
 	  if (reverse_l)
 	  {
 	    buf[0] = info[end - 1];

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -289,7 +289,7 @@
 void
 hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
 {
-  hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
+  buffer->delete_glyphs_inplace (is_deleted_glyph);
 }
 
 /**

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -38,7 +38,7 @@
 
   void init ()
   {
-    memset (this, 0, sizeof (*this));
+    hb_memset (this, 0, sizeof (*this));
     chain_flags.init ();
   }
   void fini () { chain_flags.fini (); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -236,17 +236,6 @@
   template <typename T> constexpr auto
   impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
 
-  template <typename T> constexpr uint32_t
-  impl (const hb::shared_ptr<T>& v, hb_priority<1>) const
-  {
-    return v.get () ? v.get ()->hash () : 0;
-  }
-  template <typename T> constexpr uint32_t
-  impl (const hb::unique_ptr<T>& v, hb_priority<1>) const
-  {
-    return v.get () ? v.get ()->hash () : 0;
-  }
-
   template <typename T> constexpr auto
   impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
 
@@ -495,7 +484,18 @@
 }
 HB_FUNCOBJ (hb_equal);
 
+struct
+{
+  template <typename T> void
+  operator () (T& a, T& b) const
+  {
+    using std::swap; // allow ADL
+    swap (a, b);
+  }
+}
+HB_FUNCOBJ (hb_swap);
 
+
 template <typename T1, typename T2>
 struct hb_pair_t
 {
@@ -507,7 +507,7 @@
 	    hb_enable_if (std::is_default_constructible<U1>::value &&
 			  std::is_default_constructible<U2>::value)>
   hb_pair_t () : first (), second () {}
-  hb_pair_t (T1 a, T2 b) : first (a), second (b) {}
+  hb_pair_t (T1 a, T2 b) : first (std::forward<T1> (a)), second (std::forward<T2> (b)) {}
 
   template <typename Q1, typename Q2,
 	    hb_enable_if (hb_is_convertible (T1, Q1) &&
@@ -524,6 +524,25 @@
   bool operator > (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); }
   bool operator <= (const pair_t& o) const { return !(*this > o); }
 
+  static int cmp (const void *pa, const void *pb)
+  {
+    pair_t *a = (pair_t *) pa;
+    pair_t *b = (pair_t *) pb;
+
+    if (a->first < b->first) return -1;
+    if (a->first > b->first) return +1;
+    if (a->second < b->second) return -1;
+    if (a->second > b->second) return +1;
+    return 0;
+  }
+
+  friend void swap (hb_pair_t& a, hb_pair_t& b)
+  {
+    hb_swap (a.first, b.first);
+    hb_swap (a.second, b.second);
+  }
+
+
   T1 first;
   T2 second;
 };
@@ -570,17 +589,6 @@
 }
 HB_FUNCOBJ (hb_clamp);
 
-struct
-{
-  template <typename T> void
-  operator () (T& a, T& b) const
-  {
-    using std::swap; // allow ADL
-    swap (a, b);
-  }
-}
-HB_FUNCOBJ (hb_swap);
-
 /*
  * Bithacks.
  */
@@ -849,20 +857,15 @@
   return (T)(u - lo) <= (T)(hi - lo);
 }
 template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
+hb_in_ranges (T u, T lo1, T hi1)
 {
-  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
+  return hb_in_range (u, lo1, hi1);
 }
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
+template <typename T, typename ...Ts> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, Ts... ds)
 {
-  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
+  return hb_in_range<T> (u, lo1, hi1) || hb_in_ranges<T> (u, ds...);
 }
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3, T lo4, T hi4)
-{
-  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3) || hb_in_range (u, lo4, hi4);
-}
 
 
 /*
@@ -869,10 +872,18 @@
  * Overflow checking.
  */
 
-/* Consider __builtin_mul_overflow use here also */
 static inline bool
-hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
+hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr)
 {
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+  unsigned stack_result;
+  if (!result)
+    result = &stack_result;
+  return __builtin_mul_overflow (count, size, result);
+#endif
+
+  if (result)
+    *result = count * size;
   return (size > 0) && (count >= ((unsigned int) -1) / size);
 }
 
@@ -1164,9 +1175,12 @@
 }
 
 
-template <typename T, typename T2, typename T3> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2)
+template <typename T, typename T2, typename T3 = int> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2 = nullptr)
 {
+  static_assert (hb_is_trivially_copy_assignable (T), "");
+  static_assert (hb_is_trivially_copy_assignable (T3), "");
+
   for (unsigned int i = 1; i < len; i++)
   {
     unsigned int j = i;
@@ -1189,12 +1203,6 @@
   }
 }
 
-template <typename T> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
-{
-  hb_stable_sort (array, len, compar, (int *) nullptr);
-}
-
 static inline hb_bool_t
 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
 {
@@ -1322,47 +1330,4 @@
 HB_FUNCOBJ (hb_dec);
 
 
-/* Compiler-assisted vectorization. */
-
-/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
- * basically a fixed-size bitset. */
-template <typename elt_t, unsigned int byte_size>
-struct hb_vector_size_t
-{
-  elt_t& operator [] (unsigned int i) { return v[i]; }
-  const elt_t& operator [] (unsigned int i) const { return v[i]; }
-
-  void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); }
-
-  template <typename Op>
-  hb_vector_size_t process (const Op& op) const
-  {
-    hb_vector_size_t r;
-    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
-      r.v[i] = op (v[i]);
-    return r;
-  }
-  template <typename Op>
-  hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
-  {
-    hb_vector_size_t r;
-    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
-      r.v[i] = op (v[i], o.v[i]);
-    return r;
-  }
-  hb_vector_size_t operator | (const hb_vector_size_t &o) const
-  { return process (hb_bitwise_or, o); }
-  hb_vector_size_t operator & (const hb_vector_size_t &o) const
-  { return process (hb_bitwise_and, o); }
-  hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
-  { return process (hb_bitwise_xor, o); }
-  hb_vector_size_t operator ~ () const
-  { return process (hb_bitwise_neg); }
-
-  private:
-  static_assert (0 == byte_size % sizeof (elt_t), "");
-  elt_t v[byte_size / sizeof (elt_t)];
-};
-
-
 #endif /* HB_ALGS_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -100,10 +100,18 @@
   /* Ouch. The operator== compares the contents of the array.  For range-based for loops,
    * it's best if we can just compare arrayZ, though comparing contents is still fast,
    * but also would require that Type has operator==.  As such, we optimize this operator
-   * for range-based for loop and just compare arrayZ and length. */
+   * for range-based for loop and just compare arrayZ and length.
+   *
+   * The above comment is outdated now because we implemented separate begin/end to
+   * objects that were using hb_array_t for range-based loop before. */
   bool operator != (const hb_array_t& o) const
   { return this->arrayZ != o.arrayZ || this->length != o.length; }
 
+  /* Faster range-based for loop without bounds-check. */
+  Type *begin () const { return arrayZ; }
+  Type *end () const { return arrayZ + length; }
+
+
   /* Extra operators.
    */
   Type * operator & () const { return arrayZ; }
@@ -112,11 +120,11 @@
 
   HB_INTERNAL bool operator == (const hb_array_t &o) const;
 
-  uint32_t hash () const {
+  uint32_t hash () const
+  {
     uint32_t current = 0;
-    for (unsigned int i = 0; i < this->length; i++) {
-      current = current * 31 + hb_hash (this->arrayZ[i]);
-    }
+    for (auto &v : *this)
+      current = current * 31 + hb_hash (v);
     return current;
   }
 
@@ -184,6 +192,7 @@
 
   hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*))
   {
+    //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), "");
     if (likely (length))
       hb_qsort (arrayZ, length, this->get_item_size (), cmp_);
     return hb_sorted_array_t<Type> (*this);
@@ -190,17 +199,11 @@
   }
   hb_sorted_array_t<Type> qsort ()
   {
+    //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), "");
     if (likely (length))
       hb_qsort (arrayZ, length, this->get_item_size (), Type::cmp);
     return hb_sorted_array_t<Type> (*this);
   }
-  void qsort (unsigned int start, unsigned int end)
-  {
-    end = hb_min (end, length);
-    assert (start <= end);
-    if (likely (start < end))
-      hb_qsort (arrayZ + start, end - start, this->get_item_size (), Type::cmp);
-  }
 
   /*
    * Other methods.
@@ -262,17 +265,31 @@
   void fini ()
   { hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
 
-  template <typename hb_serialize_context_t>
+  template <typename hb_serialize_context_t,
+	    typename U = Type,
+	    hb_enable_if (!(sizeof (U) < sizeof (long long) && hb_is_trivially_copy_assignable(hb_decay<Type>)))>
   hb_array_t copy (hb_serialize_context_t *c) const
   {
     TRACE_SERIALIZE (this);
     auto* out = c->start_embed (arrayZ);
-    if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ());
+    if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ());
     for (unsigned i = 0; i < length; i++)
       out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
     return_trace (hb_array_t (out, length));
   }
 
+  template <typename hb_serialize_context_t,
+	    typename U = Type,
+	    hb_enable_if (sizeof (U) < sizeof (long long) && hb_is_trivially_copy_assignable(hb_decay<Type>))>
+  hb_array_t copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto* out = c->start_embed (arrayZ);
+    if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ());
+    hb_memcpy (out, arrayZ, get_size ());
+    return_trace (hb_array_t (out, length));
+  }
+
   template <typename hb_sanitize_context_t>
   bool sanitize (hb_sanitize_context_t *c) const
   { return c->check_array (arrayZ, length); }
@@ -295,8 +312,8 @@
 
 template <typename Type>
 struct hb_sorted_array_t :
-	hb_iter_t<hb_sorted_array_t<Type>, Type&>,
-	hb_array_t<Type>
+	hb_array_t<Type>,
+	hb_iter_t<hb_sorted_array_t<Type>, Type&>
 {
   typedef hb_iter_t<hb_sorted_array_t, Type&> iter_base_t;
   HB_ITER_USING (iter_base_t);
@@ -316,8 +333,8 @@
   template <typename U,
 	    hb_enable_if (hb_is_cr_convertible(U, Type))>
   constexpr hb_sorted_array_t (const hb_array_t<U> &o) :
-    hb_iter_t<hb_sorted_array_t, Type&> (),
-    hb_array_t<Type> (o) {}
+    hb_array_t<Type> (o),
+    hb_iter_t<hb_sorted_array_t, Type&> () {}
   template <typename U,
 	    hb_enable_if (hb_is_cr_convertible(U, Type))>
   hb_sorted_array_t& operator = (const hb_array_t<U> &o)
@@ -329,6 +346,11 @@
   bool operator != (const hb_sorted_array_t& o) const
   { return this->arrayZ != o.arrayZ || this->length != o.length; }
 
+  /* Faster range-based for loop without bounds-check. */
+  Type *begin () const { return this->arrayZ; }
+  Type *end () const { return this->arrayZ + this->length; }
+
+
   hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
   { return hb_sorted_array_t (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
   hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
@@ -421,18 +443,42 @@
   return 0 == hb_memcmp (arrayZ, o.arrayZ, length);
 }
 
+
+/* Specialize hash() for byte arrays. */
+
 template <>
-inline uint32_t hb_array_t<const char>::hash () const {
+inline uint32_t hb_array_t<const char>::hash () const
+{
   uint32_t current = 0;
-  for (unsigned int i = 0; i < this->length; i++)
-    current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u);
+  unsigned i = 0;
+
+#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
+    ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
+  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
+  for (; i + 4 <= this->length; i += 4)
+    current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
+#endif
+
+  for (; i < this->length; i++)
+    current = current * 31 + hb_hash (this->arrayZ[i]);
   return current;
 }
+
 template <>
-inline uint32_t hb_array_t<const unsigned char>::hash () const {
+inline uint32_t hb_array_t<const unsigned char>::hash () const
+{
   uint32_t current = 0;
-  for (unsigned int i = 0; i < this->length; i++)
-    current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u);
+  unsigned i = 0;
+
+#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
+    ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
+  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
+  for (; i + 4 <= this->length; i += 4)
+    current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
+#endif
+
+  for (; i < this->length; i++)
+    current = current * 31 + hb_hash (this->arrayZ[i]);
   return current;
 }
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -30,6 +30,53 @@
 
 #include "hb.hh"
 
+
+/* Compiler-assisted vectorization. */
+
+/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
+ * basically a fixed-size bitset. */
+template <typename elt_t, unsigned int byte_size>
+struct hb_vector_size_t
+{
+  elt_t& operator [] (unsigned int i) { return v[i]; }
+  const elt_t& operator [] (unsigned int i) const { return v[i]; }
+
+  void clear (unsigned char v = 0) { hb_memset (this, v, sizeof (*this)); }
+
+  template <typename Op>
+  hb_vector_size_t process (const Op& op) const
+  {
+    hb_vector_size_t r;
+    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+      r.v[i] = op (v[i]);
+    return r;
+  }
+  template <typename Op>
+  hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
+  {
+    hb_vector_size_t r;
+    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+      r.v[i] = op (v[i], o.v[i]);
+    return r;
+  }
+  hb_vector_size_t operator | (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_or, o); }
+  hb_vector_size_t operator & (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_and, o); }
+  hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_xor, o); }
+  hb_vector_size_t operator ~ () const
+  { return process (hb_bitwise_neg); }
+
+  hb_array_t<const elt_t> iter () const
+  { return hb_array (v); }
+
+  private:
+  static_assert (0 == byte_size % sizeof (elt_t), "");
+  elt_t v[byte_size / sizeof (elt_t)];
+};
+
+
 struct hb_bit_page_t
 {
   void init0 () { v.clear (); }
@@ -40,17 +87,17 @@
 
   bool is_empty () const
   {
-    for (unsigned i = 0; i < len (); i++)
-      if (v[i])
-	return false;
-    return true;
+    return
+    + hb_iter (v)
+    | hb_none
+    ;
   }
   uint32_t hash () const
   {
-    uint32_t h = 0;
-    for (unsigned i = 0; i < len (); i++)
-      h = h * 31 + hb_hash (v[i]);
-    return h;
+    return
+    + hb_iter (v)
+    | hb_reduce ([] (uint32_t h, const elt_t &_) { return h * 31 + hb_hash (_); }, (uint32_t) 0u)
+    ;
   }
 
   void add (hb_codepoint_t g) { elt (g) |= mask (g); }
@@ -69,7 +116,7 @@
       *la |= ~(mask (a) - 1);
       la++;
 
-      memset (la, 0xff, (char *) lb - (char *) la);
+      hb_memset (la, 0xff, (char *) lb - (char *) la);
 
       *lb |= ((mask (b) << 1) - 1);
     }
@@ -85,7 +132,7 @@
       *la &= mask (a) - 1;
       la++;
 
-      memset (la, 0, (char *) lb - (char *) la);
+      hb_memset (la, 0, (char *) lb - (char *) la);
 
       *lb &= ~((mask (b) << 1) - 1);
     }
@@ -101,13 +148,13 @@
 		      hb_codepoint_t *p,
 		      unsigned int    size) const
   {
-    unsigned int start_v = start_value >> ELT_BITS_LOG_2;
+    unsigned int start_v = start_value / ELT_BITS;
     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);
+      uint32_t v_base = base | (i * ELT_BITS);
       for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++)
       {
 	if ((elt_t(1) << j) & bits) {
@@ -132,13 +179,13 @@
 			       unsigned int    size,
 			       hb_codepoint_t *next_value) const
   {
-    unsigned int start_v = start_value >> ELT_BITS_LOG_2;
+    unsigned int start_v = start_value / ELT_BITS;
     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;
+      uint32_t v_offset = i * ELT_BITS;
       for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++)
       {
 	if ((elt_t(1) << j) & bits)
@@ -161,7 +208,10 @@
 
   bool is_equal (const hb_bit_page_t &other) const
   {
-    return 0 == hb_memcmp (&v, &other.v, sizeof (v));
+    for (unsigned i = 0; i < len (); i++)
+      if (v[i] != other.v[i])
+	return false;
+    return true;
   }
   bool is_subset (const hb_bit_page_t &larger_page) const
   {
@@ -173,10 +223,10 @@
 
   unsigned int get_population () const
   {
-    unsigned int pop = 0;
-    for (unsigned int i = 0; i < len (); i++)
-      pop += hb_popcount (v[i]);
-    return pop;
+    return
+    + hb_iter (v)
+    | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u)
+    ;
   }
 
   bool next (hb_codepoint_t *codepoint) const
@@ -262,8 +312,6 @@
   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;

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -123,10 +123,8 @@
   bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; }
 
   /* Has interface. */
-  static constexpr bool SENTINEL = false;
-  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; }
+  bool operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k]; }
   /* Predicate. */
   bool operator () (hb_codepoint_t k) const { return has (k); }
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -85,10 +85,10 @@
   void err () { if (successful) successful = false; } /* TODO Remove */
   bool in_error () const { return !successful; }
 
-  bool resize (unsigned int count)
+  bool resize (unsigned int count, bool clear = true)
   {
     if (unlikely (!successful)) return false;
-    if (unlikely (!pages.resize (count) || !page_map.resize (count)))
+    if (unlikely (!pages.resize (count, clear) || !page_map.resize (count, clear)))
     {
       pages.resize (page_map.length);
       successful = false;
@@ -330,10 +330,8 @@
   }
 
   /* Has interface. */
-  static constexpr bool SENTINEL = false;
-  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; }
+  bool operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k]; }
   /* Predicate. */
   bool operator () (hb_codepoint_t k) const { return has (k); }
 
@@ -352,7 +350,7 @@
   {
     if (unlikely (!successful)) return;
     unsigned int count = other.pages.length;
-    if (unlikely (!resize (count)))
+    if (unlikely (!resize (count, false)))
       return;
     population = other.population;
 
@@ -391,7 +389,7 @@
   bool is_subset (const hb_bit_set_t &larger_set) const
   {
     if (has_population () && larger_set.has_population () &&
-	population != larger_set.population)
+	population > larger_set.population)
       return false;
 
     uint32_t spi = 0;
@@ -540,21 +538,21 @@
     b = nb;
     for (; a && b; )
     {
-      if (page_map[a - 1].major == other.page_map[b - 1].major)
+      if (page_map.arrayZ[a - 1].major == other.page_map.arrayZ[b - 1].major)
       {
 	a--;
 	b--;
 	count--;
-	page_map[count] = page_map[a];
+	page_map.arrayZ[count] = page_map.arrayZ[a];
 	page_at (count).v = op (page_at (a).v, other.page_at (b).v);
       }
-      else if (page_map[a - 1].major > other.page_map[b - 1].major)
+      else if (page_map.arrayZ[a - 1].major > other.page_map.arrayZ[b - 1].major)
       {
 	a--;
 	if (passthru_left)
 	{
 	  count--;
-	  page_map[count] = page_map[a];
+	  page_map.arrayZ[count] = page_map.arrayZ[a];
 	}
       }
       else
@@ -563,8 +561,8 @@
 	if (passthru_right)
 	{
 	  count--;
-	  page_map[count].major = other.page_map[b].major;
-	  page_map[count].index = next_page++;
+	  page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
+	  page_map.arrayZ[count].index = next_page++;
 	  page_at (count).v = other.page_at (b).v;
 	}
       }
@@ -574,7 +572,7 @@
       {
 	a--;
 	count--;
-	page_map[count] = page_map [a];
+	page_map.arrayZ[count] = page_map.arrayZ[a];
       }
     if (passthru_right)
       while (b)
@@ -581,8 +579,8 @@
       {
 	b--;
 	count--;
-	page_map[count].major = other.page_map[b].major;
-	page_map[count].index = next_page++;
+	page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
+	page_map.arrayZ[count].index = next_page++;
 	page_at (count).v = other.page_at (b).v;
       }
     assert (!count);
@@ -605,8 +603,6 @@
 
   bool next (hb_codepoint_t *codepoint) const
   {
-    // TODO: this should be merged with prev() as both implementations
-    //       are very similar.
     if (unlikely (*codepoint == INVALID)) {
       *codepoint = get_min ();
       return *codepoint != INVALID;
@@ -640,7 +636,7 @@
 
     for (; i < page_map.length; i++)
     {
-      const page_map_t &current = page_map.arrayZ[i];
+      const page_map_t &current = page_map_array[i];
       hb_codepoint_t m = pages_array[current.index].get_min ();
       if (m != INVALID)
       {
@@ -663,11 +659,11 @@
     page_map_t map = {get_major (*codepoint), 0};
     unsigned int i;
     page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST);
-    if (i < page_map.length && page_map[i].major == map.major)
+    if (i < page_map.length && page_map.arrayZ[i].major == map.major)
     {
-      if (pages[page_map[i].index].previous (codepoint))
+      if (pages[page_map.arrayZ[i].index].previous (codepoint))
       {
-	*codepoint += page_map[i].major * page_t::PAGE_BITS;
+	*codepoint += page_map.arrayZ[i].major * page_t::PAGE_BITS;
 	return true;
       }
     }
@@ -674,10 +670,10 @@
     i--;
     for (; (int) i >= 0; i--)
     {
-      hb_codepoint_t m = pages[page_map[i].index].get_max ();
+      hb_codepoint_t m = pages.arrayZ[page_map.arrayZ[i].index].get_max ();
       if (m != INVALID)
       {
-	*codepoint = page_map[i].major * page_t::PAGE_BITS + m;
+	*codepoint = page_map.arrayZ[i].major * page_t::PAGE_BITS + m;
 	return true;
       }
     }
@@ -905,7 +901,7 @@
     {
       auto &cached_page = page_map.arrayZ[i];
       if (cached_page.major == major)
-	return &pages[cached_page.index];
+	return &pages.arrayZ[cached_page.index];
     }
 
     page_map_t map = {major, pages.length};
@@ -917,15 +913,15 @@
       if (unlikely (!resize (pages.length + 1)))
 	return nullptr;
 
-      pages[map.index].init0 ();
-      memmove (page_map + i + 1,
-	       page_map + i,
+      pages.arrayZ[map.index].init0 ();
+      memmove (page_map.arrayZ + i + 1,
+	       page_map.arrayZ + i,
 	       (page_map.length - 1 - i) * page_map.item_size);
       page_map[i] = map;
     }
 
     last_page_lookup = i;
-    return &pages[page_map[i].index];
+    return &pages.arrayZ[page_map.arrayZ[i].index];
   }
   const page_t *page_for (hb_codepoint_t g) const
   {
@@ -939,7 +935,7 @@
     {
       auto &cached_page = page_map.arrayZ[i];
       if (cached_page.major == major)
-	return &pages[cached_page.index];
+	return &pages.arrayZ[cached_page.index];
     }
 
     page_map_t key = {major};
@@ -947,10 +943,18 @@
       return nullptr;
 
     last_page_lookup = i;
-    return &pages[page_map[i].index];
+    return &pages.arrayZ[page_map[i].index];
   }
-  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]; }
+  page_t &page_at (unsigned int i)
+  {
+    assert (i < page_map.length);
+    return pages.arrayZ[page_map.arrayZ[i].index];
+  }
+  const page_t &page_at (unsigned int i) const
+  {
+    assert (i < page_map.length);
+    return pages.arrayZ[page_map.arrayZ[i].index];
+  }
   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-blob.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -495,7 +495,7 @@
 
   DEBUG_MSG_FUNC (BLOB, this, "dupped successfully -> %p\n", this->data);
 
-  memcpy (new_data, this->data, this->length);
+  hb_memcpy (new_data, this->data, this->length);
   this->destroy_user_data ();
   this->mode = HB_MEMORY_MODE_WRITABLE;
   this->data = new_data;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -32,7 +32,7 @@
 #include "hb.hh"
 
 
-#line 36 "hb-buffer-deserialize-json.hh"
+#line 33 "hb-buffer-deserialize-json.hh"
 static const unsigned char _deserialize_json_trans_keys[] = {
 	0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 
 	48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 
@@ -557,12 +557,12 @@
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
   
-#line 561 "hb-buffer-deserialize-json.hh"
+#line 554 "hb-buffer-deserialize-json.hh"
 	{
 	cs = deserialize_json_start;
 	}
 
-#line 566 "hb-buffer-deserialize-json.hh"
+#line 557 "hb-buffer-deserialize-json.hh"
 	{
 	int _slen;
 	int _trans;
@@ -590,8 +590,8 @@
 	case 1:
 #line 38 "hb-buffer-deserialize-json.rl"
 	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 	break;
 	case 5:
@@ -774,7 +774,7 @@
 	*end_ptr = p;
 }
 	break;
-#line 778 "hb-buffer-deserialize-json.hh"
+#line 735 "hb-buffer-deserialize-json.hh"
 	}
 
 _again:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl	2022-12-18 01:06:39 UTC (rev 65304)
@@ -36,8 +36,8 @@
 write data;
 
 action clear_item {
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 
 action add_item {

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -32,32 +32,30 @@
 #include "hb.hh"
 
 
-#line 36 "hb-buffer-deserialize-text.hh"
+#line 33 "hb-buffer-deserialize-text.hh"
 static const unsigned char _deserialize_text_trans_keys[] = {
-	0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 45u, 57u, 
-	48u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 
-	44u, 57u, 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 
+	0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 48u, 57u, 
+	45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 
+	45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 
 	9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 
 	9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 
-	9u, 124u, 9u, 124u, 9u, 124u, 0
+	0
 };
 
 static const char _deserialize_text_key_spans[] = {
-	0, 83, 1, 1, 55, 77, 10, 13, 
-	10, 10, 10, 13, 10, 1, 13, 10, 
-	14, 82, 13, 10, 116, 116, 0, 77, 
+	0, 83, 1, 1, 55, 77, 10, 10, 
+	13, 10, 13, 10, 10, 13, 10, 1, 
+	13, 10, 14, 82, 116, 116, 0, 77, 
 	116, 116, 116, 116, 116, 116, 116, 116, 
-	116, 116, 116, 116, 116, 116, 116, 116, 
-	116, 116, 116
+	116, 116, 116, 116, 116, 116, 116, 116
 };
 
 static const short _deserialize_text_index_offsets[] = {
 	0, 0, 84, 86, 88, 144, 222, 233, 
-	247, 258, 269, 280, 294, 305, 307, 321, 
-	332, 347, 430, 444, 455, 572, 689, 690, 
+	244, 258, 269, 283, 294, 305, 319, 330, 
+	332, 346, 357, 372, 455, 572, 689, 690, 
 	768, 885, 1002, 1119, 1236, 1353, 1470, 1587, 
-	1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523, 
-	2640, 2757, 2874
+	1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523
 };
 
 static const char _deserialize_text_indicies[] = {
@@ -90,34 +88,34 @@
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 4, 1, 8, 
 	9, 9, 9, 9, 9, 9, 9, 9, 
-	9, 1, 10, 1, 1, 11, 12, 12, 
-	12, 12, 12, 12, 12, 12, 12, 1, 
+	9, 1, 10, 11, 11, 11, 11, 11, 
+	11, 11, 11, 11, 1, 12, 1, 1, 
 	13, 14, 14, 14, 14, 14, 14, 14, 
 	14, 14, 1, 15, 16, 16, 16, 16, 
-	16, 16, 16, 16, 16, 1, 17, 18, 
-	18, 18, 18, 18, 18, 18, 18, 18, 
-	1, 19, 1, 1, 20, 21, 21, 21, 
+	16, 16, 16, 16, 16, 1, 17, 1, 
+	1, 18, 19, 19, 19, 19, 19, 19, 
+	19, 19, 19, 1, 20, 21, 21, 21, 
 	21, 21, 21, 21, 21, 21, 1, 22, 
 	23, 23, 23, 23, 23, 23, 23, 23, 
-	23, 1, 24, 1, 25, 1, 1, 26, 
-	27, 27, 27, 27, 27, 27, 27, 27, 
-	27, 1, 28, 29, 29, 29, 29, 29, 
-	29, 29, 29, 29, 1, 24, 1, 1, 
-	1, 23, 23, 23, 23, 23, 23, 23, 
-	23, 23, 23, 1, 30, 30, 1, 1, 
+	23, 1, 24, 1, 1, 25, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 1, 
+	27, 28, 28, 28, 28, 28, 28, 28, 
+	28, 28, 1, 29, 1, 30, 1, 1, 
+	31, 32, 32, 32, 32, 32, 32, 32, 
+	32, 32, 1, 33, 34, 34, 34, 34, 
+	34, 34, 34, 34, 34, 1, 29, 1, 
+	1, 1, 28, 28, 28, 28, 28, 28, 
+	28, 28, 28, 28, 1, 35, 35, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 30, 1, 
-	1, 30, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 35, 
+	1, 1, 35, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 30, 30, 1, 
+	1, 1, 1, 1, 1, 1, 35, 35, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 30, 1, 31, 
-	1, 1, 32, 33, 33, 33, 33, 33, 
-	33, 33, 33, 33, 1, 34, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 1, 
+	1, 1, 1, 1, 1, 1, 35, 1, 
 	36, 36, 36, 36, 36, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 36, 
@@ -201,98 +199,83 @@
 	48, 48, 48, 48, 48, 48, 48, 48, 
 	48, 48, 48, 48, 48, 48, 48, 48, 
 	48, 48, 48, 48, 48, 48, 56, 48, 
-	57, 57, 57, 57, 57, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 57, 
-	30, 30, 58, 30, 30, 30, 30, 30, 
-	30, 30, 59, 1, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 60, 30, 30, 61, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 62, 63, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 64, 30, 57, 57, 57, 
-	57, 57, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 57, 30, 30, 58, 
-	30, 30, 30, 30, 30, 30, 30, 59, 
-	1, 30, 30, 30, 65, 66, 66, 66, 
-	66, 66, 66, 66, 66, 66, 30, 30, 
-	30, 60, 30, 30, 61, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	62, 63, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	64, 30, 67, 67, 67, 67, 67, 1, 
+	57, 57, 57, 57, 57, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 57, 
+	35, 35, 58, 35, 35, 35, 35, 35, 
+	35, 35, 59, 1, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 60, 35, 35, 61, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 62, 63, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 35, 35, 35, 35, 35, 
+	35, 35, 35, 64, 35, 65, 65, 65, 
+	65, 65, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 65, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 67, 1, 1, 68, 1, 1, 1, 
-	1, 1, 1, 1, 1, 69, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 70, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 66, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 71, 1, 72, 
-	72, 72, 72, 72, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 72, 1, 
+	67, 1, 68, 68, 68, 68, 68, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 68, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 42, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 42, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 73, 1, 74, 74, 74, 74, 
-	74, 48, 48, 48, 48, 48, 48, 48, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 69, 1, 70, 
+	70, 70, 70, 70, 48, 48, 48, 48, 
 	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 74, 48, 48, 50, 48, 
-	48, 48, 48, 48, 48, 48, 51, 1, 
+	48, 48, 48, 48, 48, 48, 70, 48, 
+	48, 50, 48, 48, 48, 48, 48, 48, 
+	48, 51, 1, 48, 48, 48, 48, 48, 
 	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 48, 52, 48, 48, 53, 48, 
 	48, 48, 48, 48, 48, 48, 48, 48, 
-	52, 48, 48, 53, 48, 48, 48, 48, 
 	48, 48, 48, 48, 48, 48, 48, 48, 
 	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 54, 
-	55, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 54, 55, 48, 48, 48, 48, 
 	48, 48, 48, 48, 48, 48, 48, 48, 
 	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 56, 
-	48, 75, 75, 75, 75, 75, 1, 1, 
+	48, 48, 48, 48, 48, 48, 48, 48, 
+	48, 48, 56, 48, 71, 71, 71, 71, 
+	71, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 71, 1, 1, 72, 1, 
+	1, 1, 1, 1, 1, 1, 1, 73, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	75, 1, 1, 76, 1, 1, 1, 1, 
-	1, 1, 1, 77, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	78, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 45, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	74, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 79, 1, 80, 80, 
-	80, 80, 80, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 75, 
+	1, 76, 76, 76, 76, 76, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 80, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	76, 1, 1, 77, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
@@ -299,175 +282,144 @@
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 81, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 78, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 82, 1, 80, 80, 80, 80, 80, 
+	1, 1, 1, 1, 79, 1, 76, 76, 
+	76, 76, 76, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 76, 1, 1, 
+	77, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 21, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 80, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 83, 83, 83, 83, 83, 83, 
-	83, 83, 83, 83, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 78, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 81, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 79, 1, 71, 71, 71, 71, 71, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 82, 1, 
-	84, 84, 84, 84, 84, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 84, 
-	1, 1, 85, 1, 1, 1, 1, 1, 
-	1, 1, 86, 1, 1, 1, 1, 1, 
+	1, 1, 71, 1, 1, 72, 1, 1, 
+	1, 1, 1, 1, 1, 1, 73, 1, 
+	1, 1, 16, 16, 16, 16, 16, 16, 
+	16, 16, 16, 16, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 74, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 87, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 75, 1, 
+	80, 80, 80, 80, 80, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 80, 
+	1, 1, 81, 1, 1, 1, 1, 1, 
+	1, 1, 82, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 88, 1, 84, 84, 84, 
-	84, 84, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 83, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 84, 1, 1, 85, 
-	1, 1, 1, 1, 1, 1, 1, 86, 
-	1, 1, 1, 1, 29, 29, 29, 29, 
-	29, 29, 29, 29, 29, 29, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 45, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 87, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 84, 1, 85, 85, 85, 
+	85, 85, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 85, 1, 1, 86, 
+	1, 1, 1, 1, 1, 1, 1, 87, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	88, 1, 75, 75, 75, 75, 75, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 75, 1, 1, 76, 1, 1, 1, 
-	1, 1, 1, 1, 77, 1, 1, 1, 
-	1, 89, 89, 89, 89, 89, 89, 89, 
-	89, 89, 89, 1, 1, 1, 1, 1, 
-	1, 78, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 45, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 88, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 79, 1, 90, 
-	90, 90, 90, 90, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 90, 1, 
-	1, 91, 1, 1, 1, 1, 1, 1, 
+	89, 1, 85, 85, 85, 85, 85, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 85, 1, 1, 86, 1, 1, 1, 
+	1, 1, 1, 1, 87, 1, 1, 1, 
+	1, 34, 34, 34, 34, 34, 34, 34, 
+	34, 34, 34, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 88, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 92, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 89, 1, 80, 
+	80, 80, 80, 80, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 93, 1, 90, 90, 90, 90, 
-	90, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 80, 1, 
+	1, 81, 1, 1, 1, 1, 1, 1, 
+	1, 82, 1, 1, 1, 1, 90, 90, 
+	90, 90, 90, 90, 90, 90, 90, 90, 
+	1, 1, 1, 1, 1, 1, 83, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 90, 1, 1, 91, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 45, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	92, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 84, 1, 65, 65, 65, 65, 
+	65, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 65, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 93, 
-	1, 67, 67, 67, 67, 67, 1, 1, 
+	1, 1, 1, 91, 91, 91, 91, 91, 
+	91, 91, 91, 91, 91, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	67, 1, 1, 68, 1, 1, 1, 1, 
-	1, 1, 1, 1, 69, 1, 1, 1, 
-	14, 14, 14, 14, 14, 14, 14, 14, 
-	14, 14, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	66, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 70, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 71, 1, 94, 94, 
-	94, 94, 94, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 94, 30, 30, 
-	58, 30, 30, 30, 30, 30, 30, 30, 
-	59, 1, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 60, 30, 30, 61, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 62, 95, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 96, 30, 94, 94, 94, 94, 94, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 94, 30, 30, 58, 30, 30, 
-	30, 30, 30, 30, 30, 59, 1, 30, 
-	30, 30, 97, 97, 97, 97, 97, 97, 
-	97, 97, 97, 97, 30, 30, 30, 60, 
-	30, 30, 61, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 62, 95, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 30, 30, 
-	30, 30, 30, 30, 30, 30, 96, 30, 
-	0
+	1, 1, 1, 1, 1, 1, 1, 67, 
+	1, 0
 };
 
 static const char _deserialize_text_trans_targs[] = {
 	1, 0, 2, 26, 3, 4, 20, 5, 
-	24, 25, 8, 29, 40, 29, 40, 32, 
-	37, 33, 34, 12, 13, 16, 13, 16, 
-	14, 15, 35, 36, 35, 36, 27, 19, 
-	38, 39, 38, 39, 21, 20, 6, 22, 
+	24, 25, 28, 39, 9, 31, 34, 31, 
+	34, 11, 32, 33, 32, 33, 35, 38, 
+	14, 15, 18, 15, 18, 16, 17, 36, 
+	37, 36, 37, 27, 21, 20, 6, 22, 
 	23, 21, 22, 23, 21, 22, 23, 25, 
-	27, 27, 28, 7, 9, 11, 17, 22, 
-	31, 27, 28, 7, 9, 11, 17, 22, 
-	31, 41, 42, 30, 10, 18, 22, 31, 
-	30, 31, 31, 30, 10, 7, 11, 31, 
-	30, 22, 31, 34, 30, 10, 7, 22, 
-	31, 37, 30, 10, 22, 31, 27, 22, 
-	31, 42
+	27, 27, 7, 8, 12, 13, 19, 22, 
+	30, 27, 7, 8, 12, 13, 19, 22, 
+	30, 29, 22, 30, 29, 30, 30, 29, 
+	7, 10, 22, 30, 29, 7, 22, 30, 
+	29, 7, 8, 13, 30, 29, 7, 8, 
+	22, 30, 38, 39
 };
 
 static const char _deserialize_text_trans_actions[] = {
 	0, 0, 0, 0, 1, 0, 2, 0, 
-	2, 2, 3, 4, 4, 5, 5, 4, 
-	4, 4, 4, 3, 3, 3, 0, 0, 
-	6, 3, 4, 4, 5, 5, 5, 3, 
-	4, 4, 5, 5, 7, 8, 9, 7, 
+	2, 2, 3, 3, 4, 3, 3, 5, 
+	5, 4, 3, 3, 5, 5, 3, 3, 
+	4, 4, 4, 0, 0, 6, 4, 3, 
+	3, 5, 5, 5, 7, 8, 9, 7, 
 	7, 0, 0, 0, 10, 10, 10, 8, 
-	12, 13, 14, 15, 15, 15, 16, 11, 
-	11, 18, 19, 20, 20, 20, 0, 17, 
-	17, 4, 4, 21, 22, 22, 21, 21, 
-	0, 0, 13, 10, 23, 23, 23, 10, 
-	24, 24, 24, 5, 25, 26, 26, 25, 
-	25, 5, 27, 28, 27, 27, 30, 29, 
-	29, 5
+	12, 13, 14, 14, 14, 14, 15, 11, 
+	11, 17, 18, 18, 18, 18, 0, 16, 
+	16, 19, 19, 19, 0, 0, 13, 20, 
+	21, 21, 20, 20, 22, 23, 22, 22, 
+	10, 24, 24, 24, 10, 25, 26, 26, 
+	25, 25, 5, 5
 };
 
 static const char _deserialize_text_eof_actions[] = {
@@ -474,9 +426,8 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 7, 0, 0, 0, 
-	10, 10, 11, 17, 17, 21, 0, 11, 
-	10, 24, 24, 25, 25, 10, 27, 27, 
-	21, 29, 29
+	10, 10, 11, 16, 19, 0, 11, 20, 
+	22, 22, 20, 10, 25, 25, 10, 19
 };
 
 static const int deserialize_text_start = 1;
@@ -509,12 +460,12 @@
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
   
-#line 513 "hb-buffer-deserialize-text.hh"
+#line 457 "hb-buffer-deserialize-text.hh"
 	{
 	cs = deserialize_text_start;
 	}
 
-#line 518 "hb-buffer-deserialize-text.hh"
+#line 460 "hb-buffer-deserialize-text.hh"
 	{
 	int _slen;
 	int _trans;
@@ -542,11 +493,11 @@
 	case 1:
 #line 38 "hb-buffer-deserialize-text.rl"
 	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 	break;
-	case 3:
+	case 4:
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
 	tok = p;
@@ -560,7 +511,7 @@
 #line 56 "hb-buffer-deserialize-text.rl"
 	{ if (unlikely (!buffer->ensure_unicode ())) return false; }
 	break;
-	case 20:
+	case 18:
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
 	/* TODO Unescape delimiters. */
@@ -574,7 +525,7 @@
 #line 66 "hb-buffer-deserialize-text.rl"
 	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
 	break;
-	case 23:
+	case 24:
 #line 68 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
 	break;
@@ -586,19 +537,19 @@
 #line 70 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
 	break;
-	case 22:
+	case 21:
 #line 71 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
 	break;
-	case 28:
+	case 23:
 #line 72 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
 	break;
-	case 16:
+	case 15:
 #line 38 "hb-buffer-deserialize-text.rl"
 	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
@@ -605,7 +556,7 @@
 	tok = p;
 }
 	break;
-	case 4:
+	case 3:
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
 	tok = p;
@@ -621,7 +572,7 @@
 #line 56 "hb-buffer-deserialize-text.rl"
 	{ if (unlikely (!buffer->ensure_unicode ())) return false; }
 	break;
-	case 17:
+	case 16:
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
 	/* TODO Unescape delimiters. */
@@ -639,18 +590,6 @@
 	*end_ptr = p;
 }
 	break;
-	case 19:
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 55 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
-	break;
 	case 7:
 #line 66 "hb-buffer-deserialize-text.rl"
 	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
@@ -687,7 +626,7 @@
 	*end_ptr = p;
 }
 	break;
-	case 21:
+	case 20:
 #line 71 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
@@ -699,7 +638,7 @@
 	*end_ptr = p;
 }
 	break;
-	case 27:
+	case 22:
 #line 72 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
@@ -711,7 +650,7 @@
 	*end_ptr = p;
 }
 	break;
-	case 24:
+	case 19:
 #line 73 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
@@ -726,8 +665,8 @@
 	case 12:
 #line 38 "hb-buffer-deserialize-text.rl"
 	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
@@ -736,11 +675,11 @@
 #line 55 "hb-buffer-deserialize-text.rl"
 	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
 	break;
-	case 15:
+	case 14:
 #line 38 "hb-buffer-deserialize-text.rl"
 	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
@@ -755,7 +694,7 @@
 	  return false;
 }
 	break;
-	case 18:
+	case 17:
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
 	/* TODO Unescape delimiters. */
@@ -775,31 +714,11 @@
 	*end_ptr = p;
 }
 	break;
-	case 29:
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 73 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
 	case 11:
 #line 38 "hb-buffer-deserialize-text.rl"
 	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
@@ -822,54 +741,11 @@
 	*end_ptr = p;
 }
 	break;
-	case 14:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 55 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
-	break;
-	case 30:
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 73 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
-#line 55 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
 	case 13:
 #line 38 "hb-buffer-deserialize-text.rl"
 	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
@@ -894,7 +770,7 @@
 	*end_ptr = p;
 }
 	break;
-#line 898 "hb-buffer-deserialize-text.hh"
+#line 715 "hb-buffer-deserialize-text.hh"
 	}
 
 _again:
@@ -906,7 +782,7 @@
 	if ( p == eof )
 	{
 	switch ( _deserialize_text_eof_actions[cs] ) {
-	case 17:
+	case 16:
 #line 58 "hb-buffer-deserialize-text.rl"
 	{
 	/* TODO Unescape delimiters. */
@@ -960,7 +836,7 @@
 	*end_ptr = p;
 }
 	break;
-	case 21:
+	case 20:
 #line 71 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
@@ -972,7 +848,7 @@
 	*end_ptr = p;
 }
 	break;
-	case 27:
+	case 22:
 #line 72 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
@@ -984,7 +860,7 @@
 	*end_ptr = p;
 }
 	break;
-	case 24:
+	case 19:
 #line 73 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
@@ -996,31 +872,11 @@
 	*end_ptr = p;
 }
 	break;
-	case 29:
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 73 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
 	case 11:
 #line 38 "hb-buffer-deserialize-text.rl"
 	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
@@ -1043,7 +899,7 @@
 	*end_ptr = p;
 }
 	break;
-#line 1047 "hb-buffer-deserialize-text.hh"
+#line 825 "hb-buffer-deserialize-text.hh"
 	}
 	}
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl	2022-12-18 01:06:39 UTC (rev 65304)
@@ -36,8 +36,8 @@
 write data;
 
 action clear_item {
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
 }
 
 action add_item {
@@ -76,7 +76,7 @@
 num	= '-'? unum;
 
 glyph_id = unum;
-glyph_name = ([^\\\]=@+,|] | '\\' [\\\]=@+,|]) *;
+glyph_name = ([^\\\]=@+,#|] | '\\' [\\\]=@+,|]) *;
 
 glyph	= (glyph_id | glyph_name) >tok %parse_glyph;
 cluster	= '=' (unum >tok %parse_cluster);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -183,7 +183,7 @@
     unsigned int l = p - b;
     if (buf_size > l)
     {
-      memcpy (buf, b, l);
+      hb_memcpy (buf, b, l);
       buf += l;
       buf_size -= l;
       *buf_consumed += l;
@@ -241,7 +241,7 @@
     unsigned int l = p - b;
     if (buf_size > l)
     {
-      memcpy (buf, b, l);
+      hb_memcpy (buf, b, l);
       buf += l;
       buf_size -= l;
       *buf_consumed += l;
@@ -329,7 +329,7 @@
     unsigned int l = p - b;
     if (buf_size > l)
     {
-      memcpy (buf, b, l);
+      hb_memcpy (buf, b, l);
       buf += l;
       buf_size -= l;
       *buf_consumed += l;
@@ -381,7 +381,7 @@
     unsigned int l = p - b;
     if (buf_size > l)
     {
-      memcpy (buf, b, l);
+      hb_memcpy (buf, b, l);
       buf += l;
       buf_size -= l;
       *buf_consumed += l;

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -186,7 +186,7 @@
 
   bool ret = true;
   hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
-  if (diff)
+  if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
   {
     buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed.");
     ret = false;
@@ -313,7 +313,6 @@
 
   bool ret = true;
   hb_buffer_diff_flags_t diff;
-
   /*
    * Shape the two fragment streams.
    */
@@ -382,7 +381,7 @@
    * Diff results.
    */
   diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
-  if (diff)
+  if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
   {
     buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed.");
     ret = false;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -172,12 +172,13 @@
   while (size >= new_allocated)
     new_allocated += (new_allocated >> 1) + 32;
 
-  static_assert ((sizeof (info[0]) == sizeof (pos[0])), "");
-  if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]))))
+  unsigned new_bytes;
+  if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]), &new_bytes)))
     goto done;
 
-  new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_allocated * sizeof (pos[0]));
-  new_info = (hb_glyph_info_t *) hb_realloc (info, new_allocated * sizeof (info[0]));
+  static_assert (sizeof (info[0]) == sizeof (pos[0]), "");
+  new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_bytes);
+  new_info = (hb_glyph_info_t *) hb_realloc (info, new_bytes);
 
 done:
   if (unlikely (!new_pos || !new_info))
@@ -208,7 +209,7 @@
     assert (have_output);
 
     out_info = (hb_glyph_info_t *) pos;
-    memcpy (out_info, info, out_len * sizeof (out_info[0]));
+    hb_memcpy (out_info, info, out_len * sizeof (out_info[0]));
   }
 
   return true;
@@ -229,7 +230,7 @@
      * Ideally, we should at least set Default_Ignorable bits on
      * these, as well as consistent cluster values.  But the former
      * is layering violation... */
-    memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
+    hb_memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
   }
   len += count;
   idx += count;
@@ -298,8 +299,8 @@
   out_len = 0;
   out_info = info;
 
-  memset (context, 0, sizeof context);
-  memset (context_len, 0, sizeof context_len);
+  hb_memset (context, 0, sizeof context);
+  hb_memset (context_len, 0, sizeof context_len);
 
   deallocate_var_all ();
   serial = 0;
@@ -313,15 +314,14 @@
   serial = 0;
   shaping_failed = false;
   scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
-  if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR)))
+  unsigned mul;
+  if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul)))
   {
-    max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR,
-		      (unsigned) HB_BUFFER_MAX_LEN_MIN);
+    max_len = hb_max (mul, (unsigned) HB_BUFFER_MAX_LEN_MIN);
   }
-  if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR)))
+  if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR, &mul)))
   {
-    max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR,
-		      (unsigned) HB_BUFFER_MAX_OPS_MIN);
+    max_ops = hb_max (mul, (unsigned) HB_BUFFER_MAX_OPS_MIN);
   }
 }
 void
@@ -345,7 +345,7 @@
 
   glyph = &info[len];
 
-  memset (glyph, 0, sizeof (*glyph));
+  hb_memset (glyph, 0, sizeof (*glyph));
   glyph->codepoint = codepoint;
   glyph->mask = 0;
   glyph->cluster = cluster;
@@ -606,6 +606,53 @@
 }
 
 void
+hb_buffer_t::delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info))
+{
+  /* Merge clusters and delete filtered glyphs.
+   * NOTE! We can't use out-buffer as we have positioning data. */
+  unsigned int j = 0;
+  unsigned int count = len;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    if (filter (&info[i]))
+    {
+      /* Merge clusters.
+       * Same logic as delete_glyph(), but for in-place removal. */
+
+      unsigned int cluster = info[i].cluster;
+      if (i + 1 < count && cluster == info[i + 1].cluster)
+	continue; /* Cluster survives; do nothing. */
+
+      if (j)
+      {
+	/* Merge cluster backward. */
+	if (cluster < info[j - 1].cluster)
+	{
+	  unsigned int mask = info[i].mask;
+	  unsigned int old_cluster = info[j - 1].cluster;
+	  for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
+	    set_cluster (info[k - 1], cluster, mask);
+	}
+	continue;
+      }
+
+      if (i + 1 < count)
+	merge_clusters (i, i + 2); /* Merge cluster forward. */
+
+      continue;
+    }
+
+    if (j != i)
+    {
+      info[j] = info[i];
+      pos[j] = pos[i];
+    }
+    j++;
+  }
+  len = j;
+}
+
+void
 hb_buffer_t::guess_segment_properties ()
 {
   assert_unicode ();
@@ -933,7 +980,6 @@
 void
 hb_buffer_set_direction (hb_buffer_t    *buffer,
 			 hb_direction_t  direction)
-
 {
   if (unlikely (hb_object_is_immutable (buffer)))
     return;
@@ -1385,9 +1431,9 @@
 
   /* Wipe the new space */
   if (length > buffer->len) {
-    memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
+    hb_memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
     if (buffer->have_positions)
-      memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
+      hb_memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
   }
 
   buffer->len = length;
@@ -1795,7 +1841,9 @@
  * marks at stat of run.
  *
  * This function does not check the validity of @text, it is up to the caller
- * to ensure it contains a valid Unicode code points.
+ * to ensure it contains a valid Unicode scalar values.  In contrast,
+ * hb_buffer_add_utf32() can be used that takes similar input but performs
+ * sanity-check on the input.
  *
  * Since: 0.9.31
  **/
@@ -1858,9 +1906,9 @@
 
   hb_segment_properties_overlay (&buffer->props, &source->props);
 
-  memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
+  hb_memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
   if (buffer->have_positions)
-    memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
+    hb_memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
 
   if (source->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE)
   {
@@ -2048,7 +2096,7 @@
       result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH;
     if (buf_info->cluster != ref_info->cluster)
       result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH;
-    if ((buf_info->mask & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED))
+    if ((buf_info->mask ^ ref_info->mask) & HB_GLYPH_FLAG_DEFINED)
       result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH;
     if (contains && ref_info->codepoint == dottedcircle_glyph)
       result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
@@ -2103,6 +2151,13 @@
 			    hb_buffer_message_func_t func,
 			    void *user_data, hb_destroy_func_t destroy)
 {
+  if (unlikely (hb_object_is_immutable (buffer)))
+  {
+    if (destroy)
+      destroy (user_data);
+    return;
+  }
+
   if (buffer->message_destroy)
     buffer->message_destroy (buffer->message_data);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -32,6 +32,7 @@
 
 #include "hb.hh"
 #include "hb-unicode.hh"
+#include "hb-set-digest.hh"
 
 
 #ifndef HB_BUFFER_MAX_LEN_FACTOR
@@ -207,6 +208,14 @@
   hb_glyph_info_t &prev ()      { return out_info[out_len ? out_len - 1 : 0]; }
   hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
 
+  hb_set_digest_t digest () const
+  {
+    hb_set_digest_t d;
+    d.init ();
+    d.add_array (&info[0].codepoint, len, sizeof (info[0]));
+    return d;
+  }
+
   HB_INTERNAL void similar (const hb_buffer_t &src);
   HB_INTERNAL void reset ();
   HB_INTERNAL void clear ();
@@ -402,8 +411,10 @@
   HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end);
   /* Merge clusters for deleting current glyph, and skip it. */
   HB_INTERNAL void delete_glyph ();
+  HB_INTERNAL void delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info));
 
 
+
   /* Adds glyph flags in mask to infos with clusters between start and end.
    * The start index will be from out-buffer if from_out_buffer is true.
    * If interior is true, then the cluster having the minimum value is skipped. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -46,7 +46,7 @@
 					  >::type;
 
   static_assert ((key_bits >= cache_bits), "");
-  static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (item_t)), "");
+  static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
 
   void init () { clear (); }
   void fini () {}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -284,65 +284,56 @@
 /* A byte string associated with the current offset and an error condition */
 struct byte_str_ref_t
 {
-  byte_str_ref_t () { init (); }
+  byte_str_ref_t ()
+    : str () {}
 
-  void init ()
-  {
-    str = hb_ubytes_t ();
-    offset = 0;
-    error = false;
-  }
-
-  void fini () {}
-
   byte_str_ref_t (const hb_ubytes_t &str_, unsigned int offset_ = 0)
-    : str (str_), offset (offset_), error (false) {}
+    : str (str_) { set_offset (offset_); }
 
   void reset (const hb_ubytes_t &str_, unsigned int offset_ = 0)
   {
     str = str_;
-    offset = offset_;
-    error = false;
+    set_offset (offset_);
   }
 
   const unsigned char& operator [] (int i) {
-    if (unlikely ((unsigned int) (offset + i) >= str.length))
+    if (unlikely ((unsigned int) (get_offset () + i) >= str.length))
     {
       set_error ();
       return Null (unsigned char);
     }
-    return str[offset + i];
+    return str.arrayZ[get_offset () + i];
   }
 
+  unsigned char head_unchecked () const { return str.arrayZ[get_offset ()]; }
+
   /* Conversion to hb_ubytes_t */
-  operator hb_ubytes_t () const { return str.sub_array (offset, str.length - offset); }
+  operator hb_ubytes_t () const { return str.sub_array (get_offset ()); }
 
   hb_ubytes_t sub_array (unsigned int offset_, unsigned int len_) const
   { return str.sub_array (offset_, len_); }
 
   bool avail (unsigned int count=1) const
-  { return (!in_error () && offset + count <= str.length); }
+  { return get_offset () + count <= str.length; }
   void inc (unsigned int count=1)
   {
-    if (likely (!in_error () && (offset <= str.length) && (offset + count <= str.length)))
-    {
-      offset += count;
-    }
-    else
-    {
-      offset = str.length;
-      set_error ();
-    }
+    /* Automatically puts us in error if count is out-of-range. */
+    set_offset (get_offset () + count);
   }
 
-  void set_error ()      { error = true; }
-  bool in_error () const { return error; }
+  /* We (ab)use ubytes backwards_length as a cursor (called offset),
+   * as well as to store error condition. */
 
-  hb_ubytes_t       str;
-  unsigned int  offset; /* beginning of the sub-string within str */
+  unsigned get_offset () const { return str.backwards_length; }
+  void set_offset (unsigned offset) { str.backwards_length = offset; }
 
+  void set_error ()      { str.backwards_length = str.length + 1; }
+  bool in_error () const { return str.backwards_length > str.length; }
+
+  unsigned total_size () const { return str.length; }
+
   protected:
-  bool	  error;
+  hb_ubytes_t       str;
 };
 
 using byte_str_array_t = hb_vector_t<hb_ubytes_t>;
@@ -491,8 +482,15 @@
 /* an operator prefixed by its operands in a byte string */
 struct op_str_t
 {
-  hb_ubytes_t str;
+  /* This used to have a hb_ubytes_t. Using a pointer and length
+   * in a particular order, saves 8 bytes in this struct and more
+   * in our parsed_cs_op_t subclass. */
+
+  const unsigned char *ptr = nullptr;
+
   op_code_t  op;
+
+  uint8_t length = 0;
 };
 
 /* base of OP_SERIALIZER */
@@ -503,9 +501,11 @@
   {
     TRACE_SERIALIZE (this);
 
-    HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
+    unsigned char *d = c->allocate_size<unsigned char> (opstr.length);
     if (unlikely (!d)) return_trace (false);
-    memcpy (d, &opstr.str[0], opstr.str.length);
+    /* Faster than hb_memcpy for small strings. */
+    for (unsigned i = 0; i < opstr.length; i++)
+      d[i] = opstr.ptr[i];
     return_trace (true);
   }
 };
@@ -529,8 +529,10 @@
   {
     VAL *val = values.push ();
     val->op = op;
-    val->str = str_ref.str.sub_array (opStart, str_ref.offset - opStart);
-    opStart = str_ref.offset;
+    auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
+    val->ptr = arr.arrayZ;
+    val->length = arr.length;
+    opStart = str_ref.get_offset ();
   }
 
   void add_op (op_code_t op, const byte_str_ref_t& str_ref, const VAL &v)
@@ -537,8 +539,10 @@
   {
     VAL *val = values.push (v);
     val->op = op;
-    val->str = str_ref.sub_array ( opStart, str_ref.offset - opStart);
-    opStart = str_ref.offset;
+    auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
+    val->ptr = arr.arrayZ;
+    val->length = arr.length;
+    opStart = str_ref.get_offset ();
   }
 
   bool has_op (op_code_t op) const
@@ -549,8 +553,7 @@
   }
 
   unsigned get_count () const { return values.length; }
-  const VAL &get_value (unsigned int i)   const { return values[i]; }
-  const VAL &operator [] (unsigned int i) const { return get_value (i); }
+  const VAL &operator [] (unsigned int i) const { return values[i]; }
 
   unsigned int       opStart;
   hb_vector_t<VAL>   values;
@@ -565,9 +568,9 @@
     str_ref.reset (str_);
   }
   bool in_error () const
-  { return error || str_ref.in_error () || argStack.in_error (); }
+  { return str_ref.in_error () || argStack.in_error (); }
 
-  void set_error () { error = true; }
+  void set_error () { str_ref.set_error (); }
 
   op_code_t fetch_op ()
   {
@@ -574,14 +577,14 @@
     op_code_t  op = OpCode_Invalid;
     if (unlikely (!str_ref.avail ()))
       return OpCode_Invalid;
-    op = (op_code_t)(unsigned char)str_ref[0];
+    op = (op_code_t) str_ref.head_unchecked ();
+    str_ref.inc ();
     if (op == OpCode_escape) {
       if (unlikely (!str_ref.avail ()))
 	return OpCode_Invalid;
-      op = Make_OpCode_ESC(str_ref[1]);
+      op = Make_OpCode_ESC (str_ref.head_unchecked ());
       str_ref.inc ();
     }
-    str_ref.inc ();
     return op;
   }
 
@@ -596,8 +599,6 @@
 		str_ref;
   arg_stack_t<ARG>
 		argStack;
-  protected:
-  bool		error = false;
 };
 
 using num_interp_env_t =  interp_env_t<>;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -40,13 +40,15 @@
   void set_real (double v) { reset_blends (); number_t::set_real (v); }
 
   void set_blends (unsigned int numValues_, unsigned int valueIndex_,
-		   unsigned int numBlends, hb_array_t<const blend_arg_t> blends_)
+		   hb_array_t<const blend_arg_t> blends_)
   {
     numValues = numValues_;
     valueIndex = valueIndex_;
-    deltas.resize (numBlends);
+    unsigned numBlends = blends_.length;
+    if (unlikely (!deltas.resize (numBlends)))
+      return;
     for (unsigned int i = 0; i < numBlends; i++)
-      deltas[i] = blends_[i];
+      deltas.arrayZ[i] = blends_.arrayZ[i];
   }
 
   bool blending () const { return deltas.length > 0; }
@@ -61,7 +63,6 @@
   hb_vector_t<number_t> deltas;
 };
 
-typedef interp_env_t<blend_arg_t> BlendInterpEnv;
 typedef biased_subrs_t<CFF2Subrs>   cff2_biased_subrs_t;
 
 template <typename ELEM>
@@ -154,8 +155,9 @@
     {
       if (likely (scalars.length == deltas.length))
       {
-	for (unsigned int i = 0; i < scalars.length; i++)
-	  v += (double) scalars[i] * deltas[i].to_real ();
+        unsigned count = scalars.length;
+	for (unsigned i = 0; i < count; i++)
+	  v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real ();
       }
     }
     return v;
@@ -220,7 +222,7 @@
 				 const hb_array_t<const ELEM> blends,
 				 unsigned n, unsigned i)
   {
-    arg.set_blends (n, i, blends.length, blends);
+    arg.set_blends (n, i, blends);
   }
   template <typename T = ELEM,
 	    hb_enable_if (!hb_is_same (T, blend_arg_t))>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -285,7 +285,7 @@
     lang = (hb_language_t) hb_malloc(len);
     if (likely (lang))
     {
-      memcpy((unsigned char *) lang, s, len);
+      hb_memcpy((unsigned char *) lang, s, len);
       for (unsigned char *p = (unsigned char *) lang; *p; p++)
 	*p = canon_map[*p];
     }
@@ -379,7 +379,7 @@
     /* NUL-terminate it. */
     char strbuf[64];
     len = hb_min (len, (int) sizeof (strbuf) - 1);
-    memcpy (strbuf, str, len);
+    hb_memcpy (strbuf, str, len);
     strbuf[len] = '\0';
     item = lang_find_or_insert (strbuf);
   }
@@ -976,7 +976,7 @@
   }
 
   if (feature)
-    memset (feature, 0, sizeof (*feature));
+    hb_memset (feature, 0, sizeof (*feature));
   return false;
 }
 
@@ -1025,7 +1025,7 @@
   }
   assert (len < ARRAY_LENGTH (s));
   len = hb_min (len, size - 1);
-  memcpy (buf, s, len);
+  hb_memcpy (buf, s, len);
   buf[len] = '\0';
 }
 
@@ -1088,7 +1088,7 @@
   }
 
   if (variation)
-    memset (variation, 0, sizeof (*variation));
+    hb_memset (variation, 0, sizeof (*variation));
   return false;
 }
 
@@ -1136,7 +1136,7 @@
 /**
  * hb_variation_to_string:
  * @variation: an #hb_variation_t to convert
- * @buf: (array length=size) (out): output string
+ * @buf: (array length=size) (out caller-allocates): output string
  * @size: the allocated size of @buf
  *
  * Converts an #hb_variation_t into a `NULL`-terminated string in the format
@@ -1166,7 +1166,7 @@
 
   assert (len < ARRAY_LENGTH (s));
   len = hb_min (len, size - 1);
-  memcpy (buf, s, len);
+  hb_memcpy (buf, s, len);
   buf[len] = '\0';
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -35,8 +35,9 @@
 #include "config.h"
 #endif
 
-#ifndef HB_BORING_EXPANSION
-#define HB_NO_BORING_EXPANSION
+#ifndef HB_EXPERIMENTAL_API
+#define HB_NO_BEYOND_64K
+#define HB_NO_VAR_COMPOSITES
 #endif
 
 #ifdef HB_TINY
@@ -84,6 +85,7 @@
 #define HB_NO_OT_SHAPE_FRACTIONS
 #define HB_NO_STYLE
 #define HB_NO_SUBSET_LAYOUT
+#define HB_NO_VERTICAL
 #define HB_NO_VAR
 #endif
 
@@ -104,7 +106,7 @@
 
 #ifdef HB_NO_BORING_EXPANSION
 #define HB_NO_BEYOND_64K
-#define HB_NO_VARIATIONS2
+#define HB_NO_AVAR2
 #endif
 
 #ifdef HB_DISABLE_DEPRECATED
@@ -113,6 +115,11 @@
 #define HB_IF_NOT_DEPRECATED(x) x
 #endif
 
+#ifdef HB_NO_SHAPER
+#define HB_NO_OT_SHAPE
+#define HB_NO_AAT_SHAPE
+#endif
+
 #ifdef HB_NO_AAT
 #define HB_NO_OT_NAME_LANGUAGE_AAT
 #define HB_NO_AAT_SHAPE
@@ -159,6 +166,7 @@
 #define HB_NO_OT_SHAPER_HEBREW_FALLBACK
 #define HB_NO_OT_SHAPER_THAI_FALLBACK
 #define HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS
+#define HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
 #endif
 
 #ifdef NDEBUG

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -347,10 +347,13 @@
       hb_ot_var_axis_info_t info;
       unsigned int c = 1;
       hb_ot_var_get_axis_infos (font->face, i, &c, &info);
-      CFDictionarySetValue (variations,
-	CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag),
-	CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &font->design_coords[i])
-      );
+      float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value);
+
+      CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag);
+      CFNumberRef value_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &v);
+      CFDictionarySetValue (variations, tag_number, value_number);
+      CFRelease (tag_number);
+      CFRelease (value_number);
     }
 
     CFDictionaryRef attributes =
@@ -648,7 +651,7 @@
       } else {
 	active_feature_t *feature = active_features.lsearch (event->feature);
 	if (feature)
-	  active_features.remove (feature - active_features.arrayZ);
+	  active_features.remove_ordered (feature - active_features.arrayZ);
       }
     }
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -80,6 +80,56 @@
 			void *user_data HB_UNUSED) {}
 
 
+static bool
+_hb_draw_funcs_set_preamble (hb_draw_funcs_t    *dfuncs,
+			     bool                func_is_null,
+			     void              **user_data,
+			     hb_destroy_func_t  *destroy)
+{
+  if (hb_object_is_immutable (dfuncs))
+  {
+    if (*destroy)
+      (*destroy) (*user_data);
+    return false;
+  }
+
+  if (func_is_null)
+  {
+    if (*destroy)
+      (*destroy) (*user_data);
+    *destroy = nullptr;
+    *user_data = nullptr;
+  }
+
+  return true;
+}
+
+static bool
+_hb_draw_funcs_set_middle (hb_draw_funcs_t   *dfuncs,
+			   void              *user_data,
+			   hb_destroy_func_t  destroy)
+{
+  if (user_data && !dfuncs->user_data)
+  {
+    dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data));
+    if (unlikely (!dfuncs->user_data))
+      goto fail;
+  }
+  if (destroy && !dfuncs->destroy)
+  {
+    dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy));
+    if (unlikely (!dfuncs->destroy))
+      goto fail;
+  }
+
+  return true;
+
+fail:
+  if (destroy)
+    (destroy) (user_data);
+  return false;
+}
+
 #define HB_DRAW_FUNC_IMPLEMENT(name)						\
 										\
 void										\
@@ -88,43 +138,24 @@
 				 void			 *user_data,		\
 				 hb_destroy_func_t	  destroy)		\
 {										\
-  if (hb_object_is_immutable (dfuncs))						\
-    return;									\
+  if (!_hb_draw_funcs_set_preamble (dfuncs, !func, &user_data, &destroy))\
+      return;                                                            \
 										\
   if (dfuncs->destroy && dfuncs->destroy->name)					\
     dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \
 									 \
-  if (user_data && !dfuncs->user_data)                                   \
-  {                                                                      \
-    dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); \
-    if (unlikely (!dfuncs->user_data))                                   \
-      goto fail;                                                         \
-  }                                                                      \
-  if (destroy && !dfuncs->destroy)                                       \
-  {                                                                      \
-    dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); \
-    if (unlikely (!dfuncs->destroy))                                     \
-      goto fail;                                                         \
-  }                                                                      \
+  if (!_hb_draw_funcs_set_middle (dfuncs, user_data, destroy))           \
+      return;                                                            \
 									\
-  if (func) {								\
+  if (func)								\
     dfuncs->func.name = func;						\
-    if (dfuncs->user_data)						\
-      dfuncs->user_data->name = user_data;				\
-    if (dfuncs->destroy)						\
-      dfuncs->destroy->name = destroy;					\
-  } else {								\
+  else									\
     dfuncs->func.name = hb_draw_##name##_nil;				\
-    if (dfuncs->user_data)						\
-      dfuncs->user_data->name = nullptr;				\
-    if (dfuncs->destroy)						\
-      dfuncs->destroy->name = nullptr;					\
-  }									\
-  return;                                                                \
-                                                                         \
-fail:                                                                    \
-  if (destroy)                                                           \
-    destroy (user_data);                                                 \
+									\
+  if (dfuncs->user_data)						\
+    dfuncs->user_data->name = user_data;				\
+  if (dfuncs->destroy)							\
+    dfuncs->destroy->name = destroy;					\
 }
 
 HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -288,6 +288,7 @@
 {
   if (!hb_object_destroy (face)) return;
 
+#ifndef HB_NO_SHAPER
   for (hb_face_t::plan_node_t *node = face->shape_plans; node; )
   {
     hb_face_t::plan_node_t *next = node->next;
@@ -295,6 +296,7 @@
     hb_free (node);
     node = next;
   }
+#endif
 
   face->data.fini ();
   face->table.fini ();
@@ -636,7 +638,7 @@
 struct face_table_info_t
 {
   hb_blob_t* data;
-  unsigned order;
+  signed order;
 };
 
 struct hb_face_builder_data_t
@@ -784,16 +786,16 @@
 hb_bool_t
 hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
 {
-  if (tag == HB_MAP_VALUE_INVALID)
+  if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
     return false;
 
-  if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
+  if (tag == HB_MAP_VALUE_INVALID)
     return false;
 
   hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
 
   hb_blob_t* previous = data->tables.get (tag).data;
-  if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), 0}))
+  if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1}))
   {
     hb_blob_destroy (blob);
     return false;
@@ -819,13 +821,16 @@
 hb_face_builder_sort_tables (hb_face_t *face,
                              const hb_tag_t  *tags)
 {
+  if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
+    return;
+
   hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
 
   // Sort all unspecified tables after any specified tables.
   for (auto& info : data->tables.values_ref())
-    info.order = -1;
+    info.order = (unsigned) -1;
 
-  unsigned order = 0;
+  signed order = 0;
   for (const hb_tag_t* tag = tags;
        *tag;
        tag++)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -65,7 +65,9 @@
     hb_shape_plan_t *shape_plan;
     plan_node_t *next;
   };
+#ifndef HB_NO_SHAPER
   hb_atomic_ptr_t<plan_node_t> shape_plans;
+#endif
 
   hb_blob_t *reference_table (hb_tag_t tag) const
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -75,16 +75,6 @@
 		    const hb_feature_t *features HB_UNUSED,
 		    unsigned int        num_features HB_UNUSED)
 {
-  /* TODO
-   *
-   * - Apply fallback kern.
-   * - Handle Variation Selectors?
-   * - Apply normalization?
-   *
-   * This will make the fallback shaper into a dumb "TrueType"
-   * shaper which many people unfortunately still request.
-   */
-
   hb_codepoint_t space;
   bool has_space = (bool) font->get_nominal_glyph (' ', &space);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -71,7 +71,7 @@
 				hb_font_extents_t *extents,
 				void              *user_data HB_UNUSED)
 {
-  memset (extents, 0, sizeof (*extents));
+  hb_memset (extents, 0, sizeof (*extents));
   return false;
 }
 
@@ -96,7 +96,7 @@
 				hb_font_extents_t *extents,
 				void              *user_data HB_UNUSED)
 {
-  memset (extents, 0, sizeof (*extents));
+  hb_memset (extents, 0, sizeof (*extents));
   return false;
 }
 
@@ -409,7 +409,7 @@
 			       hb_glyph_extents_t *extents,
 			       void               *user_data HB_UNUSED)
 {
-  memset (extents, 0, sizeof (*extents));
+  hb_memset (extents, 0, sizeof (*extents));
   return false;
 }
 
@@ -518,6 +518,7 @@
   void		  *draw_data;
   float		   x_scale;
   float		   y_scale;
+  float		   slant;
 } hb_font_get_glyph_shape_default_adaptor_t;
 
 static void
@@ -530,9 +531,10 @@
   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;
+  float slant   = adaptor->slant;
 
   adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st,
-				     x_scale * to_x, y_scale * to_y);
+				     x_scale * to_x + slant * to_y, y_scale * to_y);
 }
 
 static void
@@ -544,12 +546,13 @@
   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;
+  float slant   = adaptor->slant;
 
-  st->current_x *= x_scale;
-  st->current_y *= y_scale;
+  st->current_x = st->current_x * x_scale + st->current_y * slant;
+  st->current_y = st->current_y * y_scale;
 
   adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st,
-				     x_scale * to_x, y_scale * to_y);
+				     x_scale * to_x + slant * to_y, y_scale * to_y);
 }
 
 static void
@@ -562,13 +565,14 @@
   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;
+  float slant   = adaptor->slant;
 
-  st->current_x *= x_scale;
-  st->current_y *= y_scale;
+  st->current_x = st->current_x * x_scale + st->current_y * slant;
+  st->current_y = 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);
+					  x_scale * control_x + slant * control_y, y_scale * control_y,
+					  x_scale * to_x + slant * to_y, y_scale * to_y);
 }
 
 static void
@@ -582,14 +586,15 @@
   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;
+  float slant   = adaptor->slant;
 
-  st->current_x *= x_scale;
-  st->current_y *= y_scale;
+  st->current_x = st->current_x * x_scale + st->current_y * slant;
+  st->current_y = 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);
+				      x_scale * control1_x + slant * control1_y, y_scale * control1_y,
+				      x_scale * control2_x + slant * control2_y, y_scale * control2_y,
+				      x_scale * to_x + slant * to_y, y_scale * to_y);
 }
 
 static void
@@ -623,8 +628,10 @@
   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->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f,
+    font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f,
+    font->parent->y_scale ? (font->slant - font->parent->slant) *
+			    (float) font->x_scale / (float) font->parent->y_scale : 0.f
   };
 
   font->parent->get_glyph_shape (glyph,
@@ -822,6 +829,56 @@
 }
 
 
+static bool
+_hb_font_funcs_set_preamble (hb_font_funcs_t    *ffuncs,
+			     bool                func_is_null,
+			     void              **user_data,
+			     hb_destroy_func_t  *destroy)
+{
+  if (hb_object_is_immutable (ffuncs))
+  {
+    if (*destroy)
+      (*destroy) (*user_data);
+    return false;
+  }
+
+  if (func_is_null)
+  {
+    if (*destroy)
+      (*destroy) (*user_data);
+    *destroy = nullptr;
+    *user_data = nullptr;
+  }
+
+  return true;
+}
+
+static bool
+_hb_font_funcs_set_middle (hb_font_funcs_t   *ffuncs,
+			   void              *user_data,
+			   hb_destroy_func_t  destroy)
+{
+  if (user_data && !ffuncs->user_data)
+  {
+    ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data));
+    if (unlikely (!ffuncs->user_data))
+      goto fail;
+  }
+  if (destroy && !ffuncs->destroy)
+  {
+    ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy));
+    if (unlikely (!ffuncs->destroy))
+      goto fail;
+  }
+
+  return true;
+
+fail:
+  if (destroy)
+    (destroy) (user_data);
+  return false;
+}
+
 #define HB_FONT_FUNC_IMPLEMENT(name) \
 									 \
 void                                                                     \
@@ -830,51 +887,24 @@
 				 void                        *user_data, \
 				 hb_destroy_func_t            destroy)   \
 {                                                                        \
-  if (hb_object_is_immutable (ffuncs))                                   \
-    goto fail;                                                           \
-                                                                         \
-  if (!func)                                                             \
-  {                                                                      \
-    if (destroy)                                                         \
-      destroy (user_data);                                               \
-    destroy = nullptr;                                                   \
-    user_data = nullptr;                                                 \
-  }                                                                      \
+  if (!_hb_font_funcs_set_preamble (ffuncs, !func, &user_data, &destroy))\
+      return;                                                            \
 									 \
   if (ffuncs->destroy && ffuncs->destroy->name)                          \
     ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \
                                                                          \
-  if (user_data && !ffuncs->user_data)                                   \
-  {                                                                      \
-    ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); \
-    if (unlikely (!ffuncs->user_data))                                   \
-      goto fail;                                                         \
-  }                                                                      \
-  if (destroy && !ffuncs->destroy)                                       \
-  {                                                                      \
-    ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); \
-    if (unlikely (!ffuncs->destroy))                                     \
-      goto fail;                                                         \
-  }                                                                      \
+  if (!_hb_font_funcs_set_middle (ffuncs, user_data, destroy))           \
+      return;                                                            \
 									 \
-  if (func) {                                                            \
+  if (func)                                                              \
     ffuncs->get.f.name = func;                                           \
-    if (ffuncs->user_data)                                               \
-      ffuncs->user_data->name = user_data;                               \
-    if (ffuncs->destroy)                                                 \
-      ffuncs->destroy->name = destroy;                                   \
-  } else {                                                               \
+  else                                                                   \
     ffuncs->get.f.name = hb_font_get_##name##_default;                   \
-    if (ffuncs->user_data)                                               \
-      ffuncs->user_data->name = nullptr;                                 \
-    if (ffuncs->destroy)						 \
-      ffuncs->destroy->name = nullptr;                                   \
-  }                                                                      \
-  return;                                                                \
-                                                                         \
-fail:                                                                    \
-  if (destroy)                                                           \
-    destroy (user_data);                                                 \
+									 \
+  if (ffuncs->user_data)                                                 \
+    ffuncs->user_data->name = user_data;                                 \
+  if (ffuncs->destroy)                                                   \
+    ffuncs->destroy->name = destroy;                                     \
 }
 
 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
@@ -1323,7 +1353,7 @@
  * @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
+ * The shape is returned by way of calls to the callbacks of the @dfuncs
  * objects, with @draw_data passed to them.
  *
  * Since: 4.0.0
@@ -1780,8 +1810,8 @@
     float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0]));
     if (likely (coords && design_coords))
     {
-      memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
-      memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
+      hb_memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
+      hb_memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
       _hb_font_adopt_var_coords (font, coords, design_coords, num_coords);
     }
     else
@@ -2443,7 +2473,7 @@
   }
 
   if (coords_length)
-    memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
+    hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
 
   hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
@@ -2519,8 +2549,8 @@
 
   if (coords_length)
   {
-    memcpy (copy, coords, coords_length * sizeof (coords[0]));
-    memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
+    hb_memcpy (copy, coords, coords_length * sizeof (coords[0]));
+    hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
   }
 
   /* Best effort design coords simulation */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -206,7 +206,7 @@
 
   hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
   {
-    memset (extents, 0, sizeof (*extents));
+    hb_memset (extents, 0, sizeof (*extents));
     return klass->get.f.font_h_extents (this, user_data,
 					extents,
 					!klass->user_data ? nullptr : klass->user_data->font_h_extents);
@@ -213,7 +213,7 @@
   }
   hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
   {
-    memset (extents, 0, sizeof (*extents));
+    hb_memset (extents, 0, sizeof (*extents));
     return klass->get.f.font_v_extents (this, user_data,
 					extents,
 					!klass->user_data ? nullptr : klass->user_data->font_v_extents);
@@ -342,7 +342,7 @@
   hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
 			       hb_glyph_extents_t *extents)
   {
-    memset (extents, 0, sizeof (*extents));
+    hb_memset (extents, 0, sizeof (*extents));
     return klass->get.f.glyph_extents (this, user_data,
 				       glyph,
 				       extents,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -89,7 +89,7 @@
   bool unref; /* Whether to destroy ft_face when done. */
   bool transform; /* Whether to apply FT_Face's transform. */
 
-  mutable hb_mutex_t lock;
+  mutable hb_mutex_t lock; /* Protects members below. */
   FT_Face ft_face;
   mutable unsigned cached_serial;
   mutable hb_ft_advance_cache_t advance_cache;
@@ -732,8 +732,9 @@
 
 static int
 _hb_ft_move_to (const FT_Vector *to,
-		hb_draw_session_t *drawing)
+		void *arg)
 {
+  hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
   drawing->move_to (to->x, to->y);
   return FT_Err_Ok;
 }
@@ -740,8 +741,9 @@
 
 static int
 _hb_ft_line_to (const FT_Vector *to,
-		hb_draw_session_t *drawing)
+		void *arg)
 {
+  hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
   drawing->line_to (to->x, to->y);
   return FT_Err_Ok;
 }
@@ -749,8 +751,9 @@
 static int
 _hb_ft_conic_to (const FT_Vector *control,
 		 const FT_Vector *to,
-		 hb_draw_session_t *drawing)
+		 void *arg)
 {
+  hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
   drawing->quadratic_to (control->x, control->y,
 			 to->x, to->y);
   return FT_Err_Ok;
@@ -760,8 +763,9 @@
 _hb_ft_cubic_to (const FT_Vector *control1,
 		 const FT_Vector *control2,
 		 const FT_Vector *to,
-		 hb_draw_session_t *drawing)
+		 void *arg)
 {
+  hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
   drawing->cubic_to (control1->x, control1->y,
 		     control2->x, control2->y,
 		     to->x, to->y);
@@ -787,10 +791,10 @@
     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,
+    _hb_ft_move_to,
+    _hb_ft_line_to,
+    _hb_ft_conic_to,
+    _hb_ft_cubic_to,
     0, /* shift */
     0, /* delta */
   };
@@ -975,8 +979,9 @@
 }
 
 static void
-hb_ft_face_finalize (FT_Face ft_face)
+hb_ft_face_finalize (void *arg)
 {
+  FT_Face ft_face = (FT_Face) arg;
   hb_face_destroy ((hb_face_t *) ft_face->generic.data);
 }
 
@@ -1008,7 +1013,7 @@
       ft_face->generic.finalizer (ft_face);
 
     ft_face->generic.data = hb_ft_face_create (ft_face, nullptr);
-    ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize;
+    ft_face->generic.finalizer = hb_ft_face_finalize;
   }
 
   return hb_face_reference ((hb_face_t *) ft_face->generic.data);
@@ -1217,8 +1222,9 @@
 }
 
 static void
-_release_blob (FT_Face ft_face)
+_release_blob (void *arg)
 {
+  FT_Face ft_face = (FT_Face) arg;
   hb_blob_destroy ((hb_blob_t *) ft_face->generic.data);
 }
 
@@ -1271,7 +1277,7 @@
 
 
   ft_face->generic.data = blob;
-  ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
+  ft_face->generic.finalizer = _release_blob;
 
   _hb_ft_font_set_funcs (font, ft_face, true);
   hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -129,32 +129,9 @@
 {
 #if GLIB_CHECK_VERSION(2,29,12)
   return g_unichar_compose (a, b, ab);
+#else
+  return false;
 #endif
-
-  /* We don't ifdef-out the fallback code such that compiler always
-   * sees it and makes sure it's compilable. */
-
-  gchar utf8[12];
-  gchar *normalized;
-  int len;
-  hb_bool_t ret;
-
-  len = g_unichar_to_utf8 (a, utf8);
-  len += g_unichar_to_utf8 (b, utf8 + len);
-  normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFC);
-  len = g_utf8_strlen (normalized, -1);
-  if (unlikely (!len))
-    return false;
-
-  if (len == 1) {
-    *ab = g_utf8_get_char (normalized);
-    ret = true;
-  } else {
-    ret = false;
-  }
-
-  g_free (normalized);
-  return ret;
 }
 
 static hb_bool_t
@@ -166,55 +143,9 @@
 {
 #if GLIB_CHECK_VERSION(2,29,12)
   return g_unichar_decompose (ab, a, b);
+#else
+  return false;
 #endif
-
-  /* We don't ifdef-out the fallback code such that compiler always
-   * sees it and makes sure it's compilable. */
-
-  gchar utf8[6];
-  gchar *normalized;
-  int len;
-  hb_bool_t ret;
-
-  len = g_unichar_to_utf8 (ab, utf8);
-  normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFD);
-  len = g_utf8_strlen (normalized, -1);
-  if (unlikely (!len))
-    return false;
-
-  if (len == 1) {
-    *a = g_utf8_get_char (normalized);
-    *b = 0;
-    ret = *a != ab;
-  } else if (len == 2) {
-    *a = g_utf8_get_char (normalized);
-    *b = g_utf8_get_char (g_utf8_next_char (normalized));
-    /* Here's the ugly part: if ab decomposes to a single character and
-     * that character decomposes again, we have to detect that and undo
-     * the second part :-(. */
-    gchar *recomposed = g_utf8_normalize (normalized, -1, G_NORMALIZE_NFC);
-    hb_codepoint_t c = g_utf8_get_char (recomposed);
-    if (c != ab && c != *a) {
-      *a = c;
-      *b = 0;
-    }
-    g_free (recomposed);
-    ret = true;
-  } else {
-    /* If decomposed to more than two characters, take the last one,
-     * and recompose the rest to get the first component. */
-    gchar *end = g_utf8_offset_to_pointer (normalized, len - 1);
-    gchar *recomposed;
-    *b = g_utf8_get_char (end);
-    recomposed = g_utf8_normalize (normalized, end - normalized, G_NORMALIZE_NFC);
-    /* We expect that recomposed has exactly one character now. */
-    *a = g_utf8_get_char (recomposed);
-    g_free (recomposed);
-    ret = true;
-  }
-
-  g_free (normalized);
-  return ret;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -318,7 +318,7 @@
 
 #undef ALLOCATE_ARRAY
 
-  memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
+  hb_memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
 
   hb_codepoint_t *pg = gids;
   clusters[0].cluster = buffer->info[0].cluster;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -73,8 +73,10 @@
   /* Operators. */
   iter_t iter () const { return *thiz(); }
   iter_t operator + () const { return *thiz(); }
-  iter_t begin () const { return *thiz(); }
-  iter_t end () const { return thiz()->__end__ (); }
+  iter_t _begin () const { return *thiz(); }
+  iter_t begin () const { return _begin (); }
+  iter_t _end () const { return thiz()->__end__ (); }
+  iter_t end () const { return _end (); }
   explicit operator bool () const { return thiz()->__more__ (); }
   unsigned len () const { return thiz()->__len__ (); }
   /* The following can only be enabled if item_t is reference type.  Otherwise
@@ -118,7 +120,9 @@
 
 #define HB_ITER_USING(Name) \
   using item_t = typename Name::item_t; \
+  using Name::_begin; \
   using Name::begin; \
+  using Name::_end; \
   using Name::end; \
   using Name::get_item_size; \
   using Name::is_iterator; \
@@ -377,7 +381,7 @@
   void __forward__ (unsigned n) { it += n; }
   void __prev__ () { --it; }
   void __rewind__ (unsigned n) { it -= n; }
-  hb_map_iter_t __end__ () const { return hb_map_iter_t (it.end (), f); }
+  hb_map_iter_t __end__ () const { return hb_map_iter_t (it._end (), f); }
   bool operator != (const hb_map_iter_t& o) const
   { return it != o.it; }
 
@@ -440,7 +444,7 @@
   bool __more__ () const { return bool (it); }
   void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
   void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
-  hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); }
+  hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it._end (), p, f); }
   bool operator != (const hb_filter_iter_t& o) const
   { return it != o.it; }
 
@@ -553,7 +557,7 @@
   void __forward__ (unsigned n) { a += n; b += n; }
   void __prev__ () { --a; --b; }
   void __rewind__ (unsigned n) { a -= n; b -= n; }
-  hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); }
+  hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a._end (), b._end ()); }
   /* Note, we should stop if ANY of the iters reaches end.  As such two compare
    * unequal if both items are unequal, NOT if either is unequal. */
   bool operator != (const hb_zip_iter_t& o) const
@@ -637,7 +641,7 @@
     }
   }
 
-  hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a.end (), b.end ()); }
+  hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a._end (), b._end ()); }
   bool operator != (const hb_concat_iter_t& o) const
   {
     return a != o.a

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -136,6 +136,13 @@
 
 /*
  * Lazy loaders.
+ *
+ * The lazy-loaders are thread-safe pointer-like objects that create their
+ * instead on-demand.  They also support access to a "data" object that is
+ * necessary for creating their instance.  The data object, if specified,
+ * is accessed via pointer math, located at a location before the position
+ * of the loader itself.  This avoids having to store a pointer to data
+ * for every lazy-loader.  Multiple lazy-loaders can access the same data.
  */
 
 template <typename Data, unsigned int WheresData>
@@ -228,7 +235,8 @@
 
   bool cmpexch (Stored *current, Stored *value) const
   {
-    /* This *must* be called when there are no other threads accessing. */
+    /* This function can only be safely called directly if no
+     * other thread is accessing. */
     return this->instance.cmpexch (current, value);
   }
 
@@ -261,7 +269,7 @@
     hb_free (p);
   }
 
-//  private:
+  private:
   /* Must only have one pointer. */
   hb_atomic_ptr_t<Stored *> instance;
 };
@@ -283,7 +291,7 @@
   {
     auto c = hb_sanitize_context_t ();
     if (core)
-      c.set_num_glyphs (0); // So we don't recurse ad infinitum...
+      c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs
     return c.reference_table<T> (face);
   }
   static void destroy (hb_blob_t *p) { hb_blob_destroy (p); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -43,9 +43,9 @@
   hb_hashmap_t ()  { init (); }
   ~hb_hashmap_t () { fini (); }
 
-  hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (population); hb_copy (o, *this); }
+  hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (o.population); hb_copy (o, *this); }
   hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); }
-  hb_hashmap_t& operator= (const hb_hashmap_t& o)  { resize (population); hb_copy (o, *this); return *this; }
+  hb_hashmap_t& operator= (const hb_hashmap_t& o)  { reset (); resize (o.population); hb_copy (o, *this); return *this; }
   hb_hashmap_t& operator= (hb_hashmap_t&& o)  { hb_swap (*this, o); return *this; }
 
   hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t ()
@@ -71,6 +71,11 @@
     uint32_t is_tombstone_ : 1;
     V value;
 
+    item_t () : key (),
+		hash (0),
+		is_used_ (false), is_tombstone_ (false),
+		value () {}
+
     bool is_used () const { return is_used_; }
     void set_used (bool is_used) { is_used_ = is_used; }
     bool is_tombstone () const { return is_tombstone_; }
@@ -88,17 +93,8 @@
       return minus_1;
     };
 
-    void clear ()
-    {
-      new (std::addressof (key)) K ();
-      new (std::addressof (value)) V ();
-      hash = 0;
-      is_used_ = false;
-      is_tombstone_ = false;
-    }
-
-    bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); }
-    bool operator == (const item_t &o) { return *this == o.key; }
+    bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); }
+    bool operator == (const item_t &o) const { return *this == o.key; }
     hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
     hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); }
 
@@ -107,8 +103,8 @@
   };
 
   hb_object_header_t header;
-  bool successful; /* Allocations successful */
-  unsigned int population; /* Not including tombstones. */
+  unsigned int successful : 1; /* Allocations successful */
+  unsigned int population : 31; /* Not including tombstones. */
   unsigned int occupancy; /* Including tombstones. */
   unsigned int mask;
   unsigned int prime;
@@ -118,7 +114,10 @@
   {
     if (unlikely (!a.successful || !b.successful))
       return;
-    hb_swap (a.population, b.population);
+    unsigned tmp = a.population;
+    a.population = b.population;
+    b.population = tmp;
+    //hb_swap (a.population, b.population);
     hb_swap (a.occupancy, b.occupancy);
     hb_swap (a.mask, b.mask);
     hb_swap (a.prime, b.prime);
@@ -160,7 +159,9 @@
   {
     if (unlikely (!successful)) return false;
 
-    unsigned int power = hb_bit_storage (hb_max (population, new_population) * 2 + 8);
+    if (new_population != 0 && (new_population + new_population / 2) < mask) return true;
+
+    unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8);
     unsigned int new_size = 1u << power;
     item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t));
     if (unlikely (!new_items))
@@ -169,9 +170,9 @@
       return false;
     }
     for (auto &_ : hb_iter (new_items, new_size))
-      _.clear ();
+      new (&_) item_t ();
 
-    unsigned int old_size = mask + 1;
+    unsigned int old_size = size ();
     item_t *old_items = items;
 
     /* Switch to new, empty, array. */
@@ -181,17 +182,16 @@
     items = new_items;
 
     /* Insert back old items. */
-    if (old_items)
-      for (unsigned int i = 0; i < old_size; i++)
+    for (unsigned int i = 0; i < old_size; i++)
+    {
+      if (old_items[i].is_real ())
       {
-	if (old_items[i].is_real ())
-	{
-	  set_with_hash (old_items[i].key,
-			 old_items[i].hash,
-			 std::move (old_items[i].value));
-	}
-	old_items[i].~item_t ();
+	set_with_hash (std::move (old_items[i].key),
+		       old_items[i].hash,
+		       std::move (old_items[i].value));
       }
+      old_items[i].~item_t ();
+    }
 
     hb_free (old_items);
 
@@ -198,30 +198,66 @@
     return true;
   }
 
+  template <typename KK, typename VV>
+  bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false)
+  {
+    if (unlikely (!successful)) return false;
+    if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
+    item_t &item = item_for_hash (key, hash);
+
+    if (is_delete && !(item == key))
+      return true; /* Trying to delete non-existent key. */
+
+    if (item.is_used ())
+    {
+      occupancy--;
+      if (!item.is_tombstone ())
+	population--;
+    }
+
+    item.key = std::forward<KK> (key);
+    item.value = std::forward<VV> (value);
+    item.hash = hash;
+    item.set_used (true);
+    item.set_tombstone (is_delete);
+
+    occupancy++;
+    if (!is_delete)
+      population++;
+
+    return true;
+  }
+
   template <typename VV>
-  bool set (K key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
+  bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
+  template <typename VV>
+  bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward<VV> (value)); }
 
-  const V& get (K key) const
+  const V& get_with_hash (const K &key, uint32_t hash) const
   {
     if (unlikely (!items)) return item_t::default_value ();
-    unsigned int i = bucket_for (key);
-    return items[i].is_real () && items[i] == key ? items[i].value : item_t::default_value ();
+    auto &item = item_for_hash (key, hash);
+    return item.is_real () && item == key ? item.value : item_t::default_value ();
   }
+  const V& get (const K &key) const
+  {
+    if (unlikely (!items)) return item_t::default_value ();
+    return get_with_hash (key, hb_hash (key));
+  }
 
-  void del (K key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
+  void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
 
   /* Has interface. */
-  typedef const V& value_t;
-  value_t operator [] (K k) const { return get (k); }
+  const V& operator [] (K k) const { return get (k); }
   template <typename VV=V>
   bool has (K key, VV **vp = nullptr) const
   {
     if (unlikely (!items))
       return false;
-    unsigned int i = bucket_for (key);
-    if (items[i].is_real () && items[i] == key)
+    auto &item = item_for_hash (key, hb_hash (key));
+    if (item.is_real () && item == key)
     {
-      if (vp) *vp = &items[i].value;
+      if (vp) *vp = std::addressof (item.value);
       return true;
     }
     else
@@ -230,13 +266,18 @@
   /* Projection. */
   V operator () (K k) const { return get (k); }
 
+  unsigned size () const { return mask ? mask + 1 : 0; }
+
   void clear ()
   {
     if (unlikely (!successful)) return;
 
-    if (items)
-      for (auto &_ : hb_iter (items, mask + 1))
-	_.clear ();
+    for (auto &_ : hb_iter (items, size ()))
+    {
+      /* Reconstruct items. */
+      _.~item_t ();
+      new (&_) item_t ();
+    }
 
     population = occupancy = 0;
   }
@@ -246,11 +287,10 @@
 
   uint32_t hash () const
   {
-    uint32_t h = 0;
-    for (const auto &item : + hb_array (items, mask ? mask + 1 : 0)
-			    | hb_filter (&item_t::is_real))
-      h ^= item.total_hash ();
-    return h;
+    return
+    + iter_items ()
+    | hb_reduce ([] (uint32_t h, const item_t &_) { return h ^ _.total_hash (); }, (uint32_t) 0u)
+    ;
   }
 
   bool is_equal (const hb_hashmap_t &other) const
@@ -258,7 +298,7 @@
     if (population != other.population) return false;
 
     for (auto pair : iter ())
-      if (get (pair.first) != pair.second)
+      if (other.get (pair.first) != pair.second)
         return false;
 
     return true;
@@ -271,88 +311,55 @@
   /*
    * Iterator
    */
-  auto iter () const HB_AUTO_RETURN
+
+  auto iter_items () const HB_AUTO_RETURN
   (
-    + hb_array (items, mask ? mask + 1 : 0)
+    + hb_iter (items, size ())
     | hb_filter (&item_t::is_real)
-    | hb_map (&item_t::get_pair)
   )
   auto iter_ref () const HB_AUTO_RETURN
   (
-    + hb_array (items, mask ? mask + 1 : 0)
-    | hb_filter (&item_t::is_real)
+    + iter_items ()
     | hb_map (&item_t::get_pair_ref)
   )
-  auto keys () const HB_AUTO_RETURN
+  auto iter () const HB_AUTO_RETURN
   (
-    + hb_array (items, mask ? mask + 1 : 0)
-    | hb_filter (&item_t::is_real)
-    | hb_map (&item_t::key)
-    | hb_map (hb_ridentity)
+    + iter_items ()
+    | hb_map (&item_t::get_pair)
   )
   auto keys_ref () const HB_AUTO_RETURN
   (
-    + hb_array (items, mask ? mask + 1 : 0)
-    | hb_filter (&item_t::is_real)
+    + iter_items ()
     | hb_map (&item_t::key)
   )
-  auto values () const HB_AUTO_RETURN
+  auto keys () const HB_AUTO_RETURN
   (
-    + hb_array (items, mask ? mask + 1 : 0)
-    | hb_filter (&item_t::is_real)
-    | hb_map (&item_t::value)
+    + keys_ref ()
     | hb_map (hb_ridentity)
   )
   auto values_ref () const HB_AUTO_RETURN
   (
-    + hb_array (items, mask ? mask + 1 : 0)
-    | hb_filter (&item_t::is_real)
+    + iter_items ()
     | hb_map (&item_t::value)
   )
+  auto values () const HB_AUTO_RETURN
+  (
+    + values_ref ()
+    | hb_map (hb_ridentity)
+  )
 
   /* Sink interface. */
   hb_hashmap_t& operator << (const hb_pair_t<K, V>& v)
   { set (v.first, v.second); return *this; }
+  hb_hashmap_t& operator << (const hb_pair_t<K, V&&>& v)
+  { set (v.first, std::move (v.second)); return *this; }
+  hb_hashmap_t& operator << (const hb_pair_t<K&&, V>& v)
+  { set (std::move (v.first), v.second); return *this; }
+  hb_hashmap_t& operator << (const hb_pair_t<K&&, V&&>& v)
+  { set (std::move (v.first), std::move (v.second)); return *this; }
 
-  protected:
-
-  template <typename VV>
-  bool set_with_hash (K key, uint32_t hash, VV&& value, bool is_delete=false)
+  item_t& item_for_hash (const K &key, uint32_t hash) const
   {
-    if (unlikely (!successful)) return false;
-    if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
-    unsigned int i = bucket_for_hash (key, hash);
-
-    if (is_delete && items[i].key != key)
-      return true; /* Trying to delete non-existent key. */
-
-    if (items[i].is_used ())
-    {
-      occupancy--;
-      if (!items[i].is_tombstone ())
-	population--;
-    }
-
-    items[i].key = key;
-    items[i].value = std::forward<VV> (value);
-    items[i].hash = hash;
-    items[i].set_used (true);
-    items[i].set_tombstone (is_delete);
-
-    occupancy++;
-    if (!is_delete)
-      population++;
-
-    return true;
-  }
-
-  unsigned int bucket_for (const K &key) const
-  {
-    return bucket_for_hash (key, hb_hash (key));
-  }
-
-  unsigned int bucket_for_hash (const K &key, uint32_t hash) const
-  {
     hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
     unsigned int i = hash % prime;
     unsigned int step = 0;
@@ -360,12 +367,12 @@
     while (items[i].is_used ())
     {
       if (items[i].hash == hash && items[i] == key)
-	return i;
+	return items[i];
       if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
 	tombstone = i;
       i = (i + ++step) & mask;
     }
-    return tombstone == (unsigned) -1 ? i : tombstone;
+    return items[tombstone == (unsigned) -1 ? i : tombstone];
   }
 
   static unsigned int prime_for (unsigned int shift)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -112,8 +112,7 @@
 template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
 
 
-/* TODO Add feature-parity to std::decay. */
-template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
+template <typename T> using hb_decay = typename std::decay<T>::type;
 
 #define hb_is_convertible(From,To) std::is_convertible<From, To>::value
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -166,7 +166,7 @@
     {
       auto *feature = active_features.lsearch (event->feature);
       if (feature)
-        active_features.remove (feature - active_features.arrayZ);
+        active_features.remove_ordered (feature - active_features.arrayZ);
     }
   }
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-multimap.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-multimap.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-multimap.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2022  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_MULTIMAP_HH
+#define HB_MULTIMAP_HH
+
+#include "hb.hh"
+#include "hb-map.hh"
+#include "hb-vector.hh"
+
+
+/*
+ * hb_multimap_t
+ */
+
+struct hb_multimap_t
+{
+  void add (hb_codepoint_t k, hb_codepoint_t v)
+  {
+    hb_codepoint_t *i;
+    if (multiples_indices.has (k, &i))
+    {
+      multiples_values[*i].push (v);
+      return;
+    }
+
+    hb_codepoint_t *old_v;
+    if (singulars.has (k, &old_v))
+    {
+      hb_codepoint_t old = *old_v;
+      singulars.del (k);
+
+      multiples_indices.set (k, multiples_values.length);
+      auto *vec = multiples_values.push ();
+
+      vec->push (old);
+      vec->push (v);
+
+      return;
+    }
+
+    singulars.set (k, v);
+  }
+
+  hb_array_t<const hb_codepoint_t> get (hb_codepoint_t k) const
+  {
+    hb_codepoint_t *v;
+    if (singulars.has (k, &v))
+      return hb_array (v, 1);
+
+    hb_codepoint_t *i;
+    if (multiples_indices.has (k, &i))
+      return multiples_values[*i].as_array ();
+
+    return hb_array_t<hb_codepoint_t> ();
+  }
+
+  bool in_error () const
+  {
+    return singulars.in_error () || multiples_indices.in_error () || multiples_values.in_error ();
+  }
+
+  protected:
+  hb_map_t singulars;
+  hb_map_t multiples_indices;
+  hb_vector_t<hb_vector_t<hb_codepoint_t>> multiples_values;
+};
+
+
+
+#endif /* HB_MULTIMAP_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -108,10 +108,11 @@
 
 struct hb_lock_t
 {
-  hb_lock_t (hb_mutex_t &mutex_) : mutex (mutex_) { mutex.lock (); }
-  ~hb_lock_t () { mutex.unlock (); }
+  hb_lock_t (hb_mutex_t &mutex_) : mutex (&mutex_) { mutex->lock (); }
+  hb_lock_t (hb_mutex_t *mutex_) : mutex (mutex_) { if (mutex) mutex->lock (); }
+  ~hb_lock_t () { if (mutex) mutex->unlock (); }
   private:
-  hb_mutex_t &mutex;
+  hb_mutex_t *mutex;
 };
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -31,7 +31,7 @@
 #include "hb.hh"
 
 
-#line 35 "hb-number-parser.hh"
+#line 32 "hb-number-parser.hh"
 static const unsigned char _double_parser_trans_keys[] = {
 	0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 
 	46u, 101u, 0
@@ -135,12 +135,12 @@
 
   int cs;
   
-#line 139 "hb-number-parser.hh"
+#line 132 "hb-number-parser.hh"
 	{
 	cs = double_parser_start;
 	}
 
-#line 144 "hb-number-parser.hh"
+#line 135 "hb-number-parser.hh"
 	{
 	int _slen;
 	int _trans;
@@ -198,7 +198,7 @@
 	  exp_overflow = true;
 }
 	break;
-#line 202 "hb-number-parser.hh"
+#line 187 "hb-number-parser.hh"
 	}
 
 _again:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -80,7 +80,7 @@
     if (item)
     {
       item_t old = *item;
-      *item = items[items.length - 1];
+      *item = std::move (items.tail ());
       items.pop ();
       l.unlock ();
       old.fini ();
@@ -123,7 +123,7 @@
     l.lock ();
     while (items.length)
     {
-      item_t old = items[items.length - 1];
+      item_t old = items.tail ();
       items.pop ();
       l.unlock ();
       old.fini ();

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -90,7 +90,7 @@
   {
     if (table_count)
     {
-      + tables.sub_array (start_offset, table_count)
+      + tables.as_array ().sub_array (start_offset, table_count)
       | hb_map (&TableRecord::tag)
       | hb_sink (hb_array (table_tags, *table_count))
       ;
@@ -158,7 +158,7 @@
         return_trace (false);
 
       if (likely (len))
-	memcpy (start, blob->data, len);
+	hb_memcpy (start, blob->data, len);
 
       /* 4-byte alignment. */
       c->align (4);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -148,7 +148,7 @@
   static_assert (Type::static_size * 8 > fraction_bits, "");
 
   HBFixed& operator = (typename Type::type i ) { Type::operator= (i); return *this; }
-  float to_float () const  { return ((int32_t) Type::v) / shift; }
+  float to_float (float offset = 0) const  { return ((int32_t) Type::v + offset) / shift; }
   void set_float (float f) { Type::v = roundf (f * shift); }
   public:
   DEFINE_SIZE_STATIC (Type::static_size);
@@ -157,6 +157,9 @@
 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
 using F2DOT14 = HBFixed<HBINT16, 14>;
 
+/* 16-bit signed fixed number with the low 12 bits of fraction (4.12). */
+using F4DOT12 = HBFixed<HBINT16, 12>;
+
 /* 32-bit signed fixed-point number (16.16). */
 using F16DOT16 = HBFixed<HBINT32, 16>;
 
@@ -209,6 +212,12 @@
 
 struct VarIdx : HBUINT32 {
   static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu;
+  static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, "");
+  static uint32_t add (uint32_t i, unsigned short v)
+  {
+    if (i == NO_VARIATION) return i;
+    return i + v;
+  }
   VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
 };
 DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx);
@@ -493,10 +502,10 @@
   void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1)
   { as_array (len).qsort (start, end); }
 
-  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+  bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend (this, items_len))) return_trace (false);
+    if (unlikely (!c->extend_size (this, get_size (items_len), clear))) return_trace (false);
     return_trace (true);
   }
   template <typename Iterator,
@@ -504,8 +513,8 @@
   bool serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
-    unsigned count = items.len ();
-    if (unlikely (!serialize (c, count))) return_trace (false);
+    unsigned count = hb_len (items);
+    if (unlikely (!serialize (c, count, false))) return_trace (false);
     /* TODO Umm. Just exhaust the iterator instead?  Being extra
      * cautious right now.. */
     for (unsigned i = 0; i < count; i++, ++items)
@@ -646,14 +655,9 @@
   operator   iter_t () const { return   iter (); }
   operator writer_t ()       { return writer (); }
 
-  hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
-  { return as_array ().sub_array (start_offset, count); }
-  hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
-  { return as_array ().sub_array (start_offset, count); }
-  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
-  { return as_array ().sub_array (start_offset, count); }
-  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
-  { return as_array ().sub_array (start_offset, count); }
+  /* Faster range-based for loop. */
+  const Type *begin () const { return arrayZ; }
+  const Type *end () const { return arrayZ + len; }
 
   template <typename T>
   Type &lsearch (const T &x, Type &not_found = Crap (Type))
@@ -667,15 +671,15 @@
 	      unsigned int to_store = (unsigned int) -1) const
   { return as_array ().lfind (x, i, not_found, to_store); }
 
-  void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1)
-  { as_array ().qsort (start, end); }
+  void qsort ()
+  { as_array ().qsort (); }
 
-  HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len)
+  HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len, bool clear = true)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
     c->check_assign (len, items_len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
-    if (unlikely (!c->extend (this))) return_trace (false);
+    if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false);
     return_trace (true);
   }
   template <typename Iterator,
@@ -683,8 +687,8 @@
   HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
-    unsigned count = items.len ();
-    if (unlikely (!serialize (c, count))) return_trace (false);
+    unsigned count = hb_len (items);
+    if (unlikely (!serialize (c, count, false))) return_trace (false);
     /* TODO Umm. Just exhaust the iterator instead?  Being extra
      * cautious right now.. */
     for (unsigned i = 0; i < count; i++, ++items)
@@ -828,21 +832,25 @@
   operator   iter_t () const { return   iter (); }
   operator writer_t ()       { return writer (); }
 
-  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+  /* Faster range-based for loop. */
+  const Type *begin () const { return arrayZ; }
+  const Type *end () const { return arrayZ + get_length (); }
+
+  HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
     c->check_assign (lenP1, items_len + 1, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
-    if (unlikely (!c->extend (this))) return_trace (false);
+    if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false);
     return_trace (true);
   }
   template <typename Iterator,
 	    hb_requires (hb_is_source_of (Iterator, Type))>
-  bool serialize (hb_serialize_context_t *c, Iterator items)
+  HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
-    unsigned count = items.len ();
-    if (unlikely (!serialize (c, count))) return_trace (false);
+    unsigned count = hb_len (items);
+    if (unlikely (!serialize (c, count, false))) return_trace (false);
     /* TODO Umm. Just exhaust the iterator instead?  Being extra
      * cautious right now.. */
     for (unsigned i = 0; i < count; i++, ++items)
@@ -944,14 +952,9 @@
   operator   iter_t () const { return   iter (); }
   operator writer_t ()       { return writer (); }
 
-  hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
-  { return as_array ().sub_array (start_offset, count); }
-  hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
-  { return as_array ().sub_array (start_offset, count); }
-  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
-  { return as_array ().sub_array (start_offset, count); }
-  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
-  { return as_array ().sub_array (start_offset, count); }
+  /* Faster range-based for loop. */
+  const Type *begin () const { return this->arrayZ; }
+  const Type *end () const { return this->arrayZ + this->len; }
 
   bool serialize (hb_serialize_context_t *c, unsigned int items_len)
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -66,95 +66,25 @@
   {
     TRACE_SERIALIZE (this);
     unsigned int size = get_size ();
-    CFFIndex *out = c->allocate_size<CFFIndex> (size);
+    CFFIndex *out = c->allocate_size<CFFIndex> (size, false);
     if (likely (out))
-      memcpy (out, this, size);
+      hb_memcpy (out, this, size);
     return_trace (out);
   }
 
+  template <typename Iterable,
+	    hb_requires (hb_is_iterable (Iterable))>
   bool serialize (hb_serialize_context_t *c,
-		  unsigned int offSize_,
-		  const byte_str_array_t &byteArray)
+		  const Iterable &iterable)
   {
     TRACE_SERIALIZE (this);
-
-    if (byteArray.length == 0)
-    {
-      COUNT *dest = c->allocate_min<COUNT> ();
-      if (unlikely (!dest)) return_trace (false);
-      *dest = 0;
-      return_trace (true);
-    }
-
-    /* serialize CFFIndex header */
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-    this->count = byteArray.length;
-    this->offSize = offSize_;
-    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (byteArray.length + 1))))
-      return_trace (false);
-
-    /* serialize indices */
-    unsigned int  offset = 1;
-    unsigned int  i = 0;
-    for (; i < byteArray.length; i++)
-    {
-      set_offset_at (i, offset);
-      offset += byteArray[i].get_size ();
-    }
-    set_offset_at (i, offset);
-
-    /* serialize data */
-    for (unsigned int i = 0; i < byteArray.length; i++)
-    {
-      const hb_ubytes_t &bs = byteArray[i];
-      unsigned char *dest = c->allocate_size<unsigned char> (bs.length);
-      if (unlikely (!dest)) return_trace (false);
-      memcpy (dest, &bs[0], bs.length);
-    }
-
-    return_trace (true);
-  }
-
-  bool serialize (hb_serialize_context_t *c,
-		  unsigned int offSize_,
-		  const str_buff_vec_t &buffArray)
-  {
-    byte_str_array_t  byteArray;
-    byteArray.init ();
-    byteArray.resize (buffArray.length);
-    for (unsigned int i = 0; i < byteArray.length; i++)
-      byteArray[i] = hb_ubytes_t (buffArray[i].arrayZ, buffArray[i].length);
-    bool result = this->serialize (c, offSize_, byteArray);
-    byteArray.fini ();
-    return result;
-  }
-
-  template <typename Iterator,
-	    hb_requires (hb_is_iterator (Iterator))>
-  bool serialize (hb_serialize_context_t *c,
-		  Iterator it)
-  {
-    TRACE_SERIALIZE (this);
-    serialize_header(c, + it | hb_map ([] (const hb_ubytes_t &_) { return _.length; }));
+    auto it = hb_iter (iterable);
+    serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len));
     for (const auto &_ : +it)
-      _.copy (c);
+      hb_iter (_).copy (c);
     return_trace (true);
   }
 
-  bool serialize (hb_serialize_context_t *c,
-		  const byte_str_array_t &byteArray)
-  { return serialize (c, + hb_iter (byteArray)); }
-
-  bool serialize (hb_serialize_context_t *c,
-		  const str_buff_vec_t &buffArray)
-  {
-    auto it =
-    + hb_iter (buffArray)
-    | hb_map ([] (const str_buff_t &_) { return hb_ubytes_t (_.arrayZ, _.length); })
-    ;
-    return serialize (c, it);
-  }
-
   template <typename Iterator,
 	    hb_requires (hb_is_iterator (Iterator))>
   bool serialize_header (hb_serialize_context_t *c,
@@ -171,7 +101,7 @@
     if (!this->count) return_trace (true);
     if (unlikely (!c->extend (this->offSize))) return_trace (false);
     this->offSize = off_size;
-    if (unlikely (!c->allocate_size<HBUINT8> (off_size * (this->count + 1))))
+    if (unlikely (!c->allocate_size<HBUINT8> (off_size * (this->count + 1), false)))
       return_trace (false);
 
     /* serialize indices */
@@ -179,14 +109,27 @@
     unsigned int i = 0;
     for (unsigned _ : +it)
     {
-      CFFIndex<COUNT>::set_offset_at (i++, offset);
+      set_offset_at (i++, offset);
       offset += _;
     }
-    CFFIndex<COUNT>::set_offset_at (i, offset);
+    set_offset_at (i, offset);
 
     return_trace (true);
   }
 
+  template <typename Iterable,
+	    hb_requires (hb_is_iterable (Iterable))>
+  static unsigned total_size (const Iterable &iterable)
+  {
+    auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len);
+    if (!it) return 0;
+
+    unsigned total = + it | hb_reduce (hb_add, 0);
+    unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
+
+    return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total;
+  }
+
   void set_offset_at (unsigned int index, unsigned int offset)
   {
     assert (index <= count);
@@ -207,10 +150,14 @@
 
     unsigned int size = offSize;
     const HBUINT8 *p = offsets + size * index;
-    unsigned int offset = 0;
-    for (; size; size--)
-      offset = (offset << 8) + *p++;
-    return offset;
+    switch (size)
+    {
+      case 1: return * (HBUINT8  *) p;
+      case 2: return * (HBUINT16 *) p;
+      case 3: return * (HBUINT24 *) p;
+      case 4: return * (HBUINT32 *) p;
+      default: return 0;
+    }
   }
 
   unsigned int length_at (unsigned int index) const
@@ -229,6 +176,7 @@
   hb_ubytes_t operator [] (unsigned int index) const
   {
     if (unlikely (index >= count)) return hb_ubytes_t ();
+    _hb_compiler_memory_r_barrier ();
     unsigned length = length_at (index);
     if (unlikely (!length)) return hb_ubytes_t ();
     return hb_ubytes_t (data_base () + offset_at (index) - 1, length);
@@ -280,7 +228,7 @@
     if (unlikely (!c->extend_min (this))) return_trace (false);
     this->count = dataArrayLen;
     this->offSize = offSize_;
-    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1))))
+    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1), false)))
       return_trace (false);
 
     /* serialize indices */
@@ -288,10 +236,10 @@
     unsigned int  i = 0;
     for (; i < dataArrayLen; i++)
     {
-      CFFIndex<COUNT>::set_offset_at (i, offset);
+      this->set_offset_at (i, offset);
       offset += dataSizeArray[i];
     }
-    CFFIndex<COUNT>::set_offset_at (i, offset);
+    this->set_offset_at (i, offset);
 
     /* serialize data */
     for (unsigned int i = 0; i < dataArrayLen; i++)
@@ -324,13 +272,12 @@
   template <typename T, typename V>
   static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, V value, op_code_t intOp)
   {
-    // XXX: not sure why but LLVM fails to compile the following 'unlikely' macro invocation
-    if (/*unlikely*/ (!serialize_int<T, V> (c, intOp, value)))
+    if (unlikely ((!serialize_int<T, V> (c, intOp, value))))
       return false;
 
     TRACE_SERIALIZE (this);
     /* serialize the opcode */
-    HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op));
+    HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op), false);
     if (unlikely (!p)) return_trace (false);
     if (Is_OpCode_ESC (op))
     {
@@ -415,9 +362,8 @@
     TRACE_SANITIZE (this);
     if (unlikely (!(c->check_struct (this))))
       return_trace (false);
-    for (unsigned int i = 0; i < c->get_num_glyphs (); i++)
-      if (unlikely (!fds[i].sanitize (c)))
-	return_trace (false);
+    if (unlikely (!c->check_array (fds, c->get_num_glyphs ())))
+      return_trace (false);
 
     return_trace (true);
   }
@@ -471,16 +417,22 @@
     return_trace (true);
   }
 
-  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
+  static int _cmp_range (const void *_key, const void *_item)
   {
-    unsigned int i;
-    for (i = 1; i < nRanges (); i++)
-      if (glyph < ranges[i].first)
-	break;
+    hb_codepoint_t glyph = * (hb_codepoint_t *) _key;
+    FDSelect3_4_Range<GID_TYPE, FD_TYPE> *range = (FDSelect3_4_Range<GID_TYPE, FD_TYPE> *) _item;
 
-    return (hb_codepoint_t) ranges[i - 1].fd;
+    if (glyph < range[0].first) return -1;
+    if (glyph < range[1].first) return 0;
+    return +1;
   }
 
+  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
+  {
+    auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
+    return range ? range->fd : ranges[nRanges () - 1].fd;
+  }
+
   GID_TYPE        &nRanges ()       { return ranges.len; }
   GID_TYPE         nRanges () const { return ranges.len; }
   GID_TYPE       &sentinel ()       { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
@@ -501,9 +453,9 @@
   {
     TRACE_SERIALIZE (this);
     unsigned int size = src.get_size (num_glyphs);
-    FDSelect *dest = c->allocate_size<FDSelect> (size);
+    FDSelect *dest = c->allocate_size<FDSelect> (size, false);
     if (unlikely (!dest)) return_trace (false);
-    memcpy (dest, &src, size);
+    hb_memcpy (dest, &src, size);
     return_trace (true);
   }
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -175,7 +175,7 @@
     unsigned int size = src.get_size ();
     Encoding *dest = c->allocate_size<Encoding> (size);
     if (unlikely (!dest)) return_trace (false);
-    memcpy (dest, &src, size);
+    hb_memcpy (dest, &src, size);
     return_trace (true);
   }
 
@@ -471,7 +471,7 @@
     unsigned int size = src.get_size (num_glyphs);
     Charset *dest = c->allocate_size<Charset> (size);
     if (unlikely (!dest)) return_trace (false);
-    memcpy (dest, &src, size);
+    hb_memcpy (dest, &src, size);
     return_trace (true);
   }
 
@@ -617,7 +617,6 @@
     }
 
     byte_str_array_t bytesArray;
-    bytesArray.init ();
     if (!bytesArray.resize (sidmap.get_population ()))
       return_trace (false);
     for (unsigned int i = 0; i < strings.count; i++)
@@ -628,7 +627,6 @@
     }
 
     bool result = CFF1Index::serialize (c, bytesArray);
-    bytesArray.fini ();
     return_trace (result);
   }
 };
@@ -813,7 +811,7 @@
 	break;
 
       default:
-	env.last_offset = env.str_ref.offset;
+	env.last_offset = env.str_ref.get_offset ();
 	top_dict_opset_t<cff1_top_dict_val_t>::process_op (op, env, dictval);
 	/* Record this operand below if stack is empty, otherwise done */
 	if (!env.argStack.is_empty ()) return;
@@ -1295,10 +1293,10 @@
     }
 
     protected:
-    hb_blob_t	           *blob = nullptr;
     hb_sanitize_context_t   sc;
 
     public:
+    hb_blob_t               *blob = nullptr;
     const Encoding	    *encoding = nullptr;
     const Charset	    *charset = nullptr;
     const CFF1NameIndex     *nameIndex = nullptr;

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -56,7 +56,7 @@
     unsigned int size = src.get_size (num_glyphs);
     CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size);
     if (unlikely (!dest)) return_trace (false);
-    memcpy (dest, &src, size);
+    hb_memcpy (dest, &src, size);
     return_trace (true);
   }
 
@@ -124,7 +124,7 @@
     unsigned int size_ = varStore->get_size ();
     CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_);
     if (unlikely (!dest)) return_trace (false);
-    memcpy (dest, varStore, size_);
+    hb_memcpy (dest, varStore, size_);
     return_trace (true);
   }
 
@@ -483,13 +483,18 @@
       blob = nullptr;
     }
 
+    hb_map_t *create_glyph_to_sid_map () const
+    {
+      return nullptr;
+    }
+
     bool is_valid () const { return blob; }
 
     protected:
-    hb_blob_t			*blob = nullptr;
     hb_sanitize_context_t	sc;
 
     public:
+    hb_blob_t			*blob = nullptr;
     cff2_top_dict_values_t	topDict;
     const CFF2Subrs		*globalSubrs = nullptr;
     const CFF2VariationStore	*varStore = nullptr;

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -909,7 +909,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, hb_min (last, 0x10FFFFu));
+      out->add_range (first, last);
     }
   }
 
@@ -925,37 +925,75 @@
     if (unlikely (!c->copy<HBUINT32> (len))) return nullptr;
     unsigned init_len = c->length ();
 
-    hb_codepoint_t lastCode = HB_MAP_VALUE_INVALID;
-    int count = -1;
+    if (this->len > unicodes->get_population () * hb_bit_storage ((unsigned) this->len))
+    {
+      hb_codepoint_t start = HB_SET_VALUE_INVALID;
+      hb_codepoint_t end = HB_SET_VALUE_INVALID;
 
-    for (const UnicodeValueRange& _ : as_array ())
-    {
-      for (const unsigned addcnt : hb_range ((unsigned) _.additionalCount + 1))
+      for (hb_codepoint_t u = HB_SET_VALUE_INVALID;
+	   unicodes->next (&u);)
       {
-	unsigned curEntry = (unsigned) _.startUnicodeValue + addcnt;
-	if (!unicodes->has (curEntry)) continue;
-	count += 1;
-	if (lastCode == HB_MAP_VALUE_INVALID)
-	  lastCode = curEntry;
-	else if (lastCode + count != curEntry)
+        if (!as_array ().bsearch (u))
+	  continue;
+	if (start == HB_SET_VALUE_INVALID)
 	{
+	  start = u;
+	  end = start - 1;
+	}
+	if (end + 1 != u || end - start == 255)
+        {
 	  UnicodeValueRange rec;
-	  rec.startUnicodeValue = lastCode;
-	  rec.additionalCount = count - 1;
+	  rec.startUnicodeValue = start;
+	  rec.additionalCount = end - start;
 	  c->copy<UnicodeValueRange> (rec);
-
-	  lastCode = curEntry;
-	  count = 0;
+	  start = u;
 	}
+	end = u;
       }
+      if (start != HB_SET_VALUE_INVALID)
+      {
+	UnicodeValueRange rec;
+	rec.startUnicodeValue = start;
+	rec.additionalCount = end - start;
+	c->copy<UnicodeValueRange> (rec);
+      }
+
     }
+    else
+    {
+      hb_codepoint_t lastCode = HB_SET_VALUE_INVALID;
+      int count = -1;
 
-    if (lastCode != HB_MAP_VALUE_INVALID)
-    {
-      UnicodeValueRange rec;
-      rec.startUnicodeValue = lastCode;
-      rec.additionalCount = count;
-      c->copy<UnicodeValueRange> (rec);
+      for (const UnicodeValueRange& _ : *this)
+      {
+	hb_codepoint_t curEntry = (hb_codepoint_t) (_.startUnicodeValue - 1);
+	hb_codepoint_t end = curEntry + _.additionalCount + 2;
+
+	for (; unicodes->next (&curEntry) && curEntry < end;)
+	{
+	  count += 1;
+	  if (lastCode == HB_SET_VALUE_INVALID)
+	    lastCode = curEntry;
+	  else if (lastCode + count != curEntry)
+	  {
+	    UnicodeValueRange rec;
+	    rec.startUnicodeValue = lastCode;
+	    rec.additionalCount = count - 1;
+	    c->copy<UnicodeValueRange> (rec);
+
+	    lastCode = curEntry;
+	    count = 0;
+	  }
+	}
+      }
+
+      if (lastCode != HB_MAP_VALUE_INVALID)
+      {
+	UnicodeValueRange rec;
+	rec.startUnicodeValue = lastCode;
+	rec.additionalCount = count;
+	c->copy<UnicodeValueRange> (rec);
+      }
     }
 
     if (c->length () - init_len == 0)
@@ -1474,32 +1512,80 @@
   DEFINE_SIZE_STATIC (8);
 };
 
+struct cmap;
+
 struct SubtableUnicodesCache {
 
  private:
-  const void* base;
-  hb_hashmap_t<intptr_t, hb::unique_ptr<hb_set_t>> cached_unicodes;
+  hb_blob_ptr_t<cmap> base_blob;
+  const char* base;
+  hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> cached_unicodes;
 
  public:
+
+  static SubtableUnicodesCache* create (hb_blob_ptr_t<cmap> source_table)
+  {
+    SubtableUnicodesCache* cache =
+        (SubtableUnicodesCache*) hb_malloc (sizeof(SubtableUnicodesCache));
+    new (cache) SubtableUnicodesCache (source_table);
+    return cache;
+  }
+
+  static void destroy (void* value) {
+    if (!value) return;
+
+    SubtableUnicodesCache* cache = (SubtableUnicodesCache*) value;
+    cache->~SubtableUnicodesCache ();
+    hb_free (cache);
+  }
+
   SubtableUnicodesCache(const void* cmap_base)
-      : base(cmap_base), cached_unicodes() {}
+      : base_blob(),
+        base ((const char*) cmap_base),
+        cached_unicodes ()
+  {}
 
-  hb_set_t* set_for (const EncodingRecord* record)
+  SubtableUnicodesCache(hb_blob_ptr_t<cmap> base_blob_)
+      : base_blob(base_blob_),
+        base ((const char *) base_blob.get()),
+        cached_unicodes ()
+  {}
+
+  ~SubtableUnicodesCache()
   {
-    if (!cached_unicodes.has ((intptr_t) record))
+    base_blob.destroy ();
+  }
+
+  bool same_base(const void* other) const
+  {
+    return other == (const void*) base;
+  }
+
+  const hb_set_t* set_for (const EncodingRecord* record,
+                           SubtableUnicodesCache& mutable_cache) const
+  {
+    if (cached_unicodes.has ((unsigned) ((const char *) record - base)))
+      return cached_unicodes.get ((unsigned) ((const char *) record - base));
+
+    return mutable_cache.set_for (record);
+  }
+
+  const hb_set_t* set_for (const EncodingRecord* record)
+  {
+    if (!cached_unicodes.has ((unsigned) ((const char *) record - base)))
     {
       hb_set_t *s = hb_set_create ();
       if (unlikely (s->in_error ()))
 	return hb_set_get_empty ();
-	
+
       (base+record->subtable).collect_unicodes (s);
 
-      if (unlikely (!cached_unicodes.set ((intptr_t) record, hb::unique_ptr<hb_set_t> {s})))
+      if (unlikely (!cached_unicodes.set ((unsigned) ((const char *) record - base), hb::unique_ptr<hb_set_t> {s})))
         return hb_set_get_empty ();
 
       return s;
     }
-    return cached_unicodes.get ((intptr_t) record);
+    return cached_unicodes.get ((unsigned) ((const char *) record - base));
   }
 
 };
@@ -1523,6 +1609,23 @@
 {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
 
+
+  static SubtableUnicodesCache* create_filled_cache(hb_blob_ptr_t<cmap> source_table) {
+    const cmap* cmap = source_table.get();
+    auto it =
+    + hb_iter (cmap->encodingRecord)
+    | hb_filter ([&](const EncodingRecord& _) {
+      return cmap::filter_encoding_records_for_subset (cmap, _);
+    })
+    ;
+
+    SubtableUnicodesCache* cache = SubtableUnicodesCache::create(source_table);
+    for (const EncodingRecord& _ : it)
+      cache->set_for(&_); // populate the cache for this encoding record.
+
+    return cache;
+  }
+
   template<typename Iterator, typename EncodingRecIter,
 	   hb_requires (hb_is_iterator (EncodingRecIter))>
   bool serialize (hb_serialize_context_t *c,
@@ -1529,7 +1632,7 @@
 		  Iterator it,
 		  EncodingRecIter encodingrec_iter,
 		  const void *base,
-		  const hb_subset_plan_t *plan,
+		  hb_subset_plan_t *plan,
                   bool drop_format_4 = false)
   {
     if (unlikely (!c->extend_min ((*this))))  return false;
@@ -1538,7 +1641,14 @@
     unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0;
     auto snap = c->snapshot ();
 
-    SubtableUnicodesCache unicodes_cache (base);
+    SubtableUnicodesCache local_unicodes_cache (base);
+    const SubtableUnicodesCache* unicodes_cache = &local_unicodes_cache;
+
+    if (plan->accelerator &&
+        plan->accelerator->cmap_cache &&
+        plan->accelerator->cmap_cache->same_base (base))
+      unicodes_cache = plan->accelerator->cmap_cache;
+
     for (const EncodingRecord& _ : encodingrec_iter)
     {
       if (c->in_error ())
@@ -1547,7 +1657,7 @@
       unsigned format = (base+_.subtable).u.format;
       if (format != 4 && format != 12 && format != 14) continue;
 
-      hb_set_t* unicodes_set = unicodes_cache.set_for (&_);
+      const hb_set_t* unicodes_set = unicodes_cache->set_for (&_, local_unicodes_cache);
 
       if (!drop_format_4 && format == 4)
       {
@@ -1566,7 +1676,13 @@
 
       else if (format == 12)
       {
-        if (_can_drop (_, *unicodes_set, base, unicodes_cache, + it | hb_map (hb_first), encodingrec_iter)) continue;
+        if (_can_drop (_,
+                       *unicodes_set,
+                       base,
+                       *unicodes_cache,
+                       local_unicodes_cache,
+                       + it | hb_map (hb_first), encodingrec_iter))
+          continue;
         c->copy (_, + it | hb_filter (*unicodes_set, hb_first), 12u, base, plan, &format12objidx);
       }
       else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx);
@@ -1585,7 +1701,8 @@
   bool _can_drop (const EncodingRecord& cmap12,
                   const hb_set_t& cmap12_unicodes,
                   const void* base,
-                  SubtableUnicodesCache& unicodes_cache,
+                  const SubtableUnicodesCache& unicodes_cache,
+                  SubtableUnicodesCache& local_unicodes_cache,
                   Iterator subset_unicodes,
                   EncodingRecordIterator encoding_records)
   {
@@ -1616,7 +1733,7 @@
           || (base+_.subtable).get_language() != target_language)
         continue;
 
-      hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_);
+      const hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_, local_unicodes_cache);
 
       auto cmap12 = + subset_unicodes | hb_filter (cmap12_unicodes);
       auto sibling = + subset_unicodes | hb_filter (*sibling_unicodes);
@@ -1653,17 +1770,9 @@
 
     auto encodingrec_iter =
     + hb_iter (encodingRecord)
-    | hb_filter ([&] (const EncodingRecord& _)
-		{
-		  if ((_.platformID == 0 && _.encodingID == 3) ||
-		      (_.platformID == 0 && _.encodingID == 4) ||
-		      (_.platformID == 3 && _.encodingID == 1) ||
-		      (_.platformID == 3 && _.encodingID == 10) ||
-		      (this + _.subtable).u.format == 14)
-		    return true;
-
-		  return false;
-		})
+    | hb_filter ([&](const EncodingRecord& _) {
+      return cmap::filter_encoding_records_for_subset (this, _);
+    })
     ;
 
     if (unlikely (!encodingrec_iter.len ())) return_trace (false);
@@ -1692,7 +1801,11 @@
 		 { return (_.second != HB_MAP_VALUE_INVALID); })
     ;
 
-    return_trace (cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan));
+    return_trace (cmap_prime->serialize (c->serializer,
+                                         it,
+                                         encodingrec_iter,
+                                         this,
+                                         c->plan));
   }
 
   const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const
@@ -1928,6 +2041,19 @@
 		  encodingRecord.sanitize (c, this));
   }
 
+ private:
+
+  static bool filter_encoding_records_for_subset(const cmap* cmap,
+                                                 const EncodingRecord& _)
+  {
+    return
+        (_.platformID == 0 && _.encodingID == 3) ||
+        (_.platformID == 0 && _.encodingID == 4) ||
+        (_.platformID == 3 && _.encodingID == 1) ||
+        (_.platformID == 3 && _.encodingID == 10) ||
+        (cmap + _.subtable).u.format == 14;
+  }
+
   protected:
   HBUINT16	version;	/* Table version number (0). */
   SortedArray16Of<EncodingRecord>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -67,7 +67,7 @@
 {
   unsigned int new_len = cbdt_prime->length + length;
   if (unlikely (!cbdt_prime->alloc (new_len))) return false;
-  memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
+  hb_memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
   cbdt_prime->length = new_len;
   return true;
 }
@@ -468,13 +468,13 @@
     if (unlikely (!c->serializer->check_success (records->resize (records->length + 1))))
       return_trace (false);
 
-    (*records)[records->length - 1].firstGlyphIndex = 1;
-    (*records)[records->length - 1].lastGlyphIndex = 0;
+    records->tail ().firstGlyphIndex = 1;
+    records->tail ().lastGlyphIndex = 0;
     bitmap_size_context->size += IndexSubtableRecord::min_size;
 
     c->serializer->push ();
 
-    if (unlikely (!add_new_subtable (c, bitmap_size_context, &((*records)[records->length - 1]), lookup, base, start)))
+    if (unlikely (!add_new_subtable (c, bitmap_size_context, &(records->tail ()), lookup, base, start)))
     {
       c->serializer->pop_discard ();
       c->serializer->revert (snap);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -39,13 +39,9 @@
 #define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
 
 #ifndef HB_COLRV1_MAX_NESTING_LEVEL
-#define HB_COLRV1_MAX_NESTING_LEVEL	100
+#define HB_COLRV1_MAX_NESTING_LEVEL	16
 #endif
 
-#ifndef COLRV1_ENABLE_SUBSETTING
-#define COLRV1_ENABLE_SUBSETTING 1
-#endif
-
 namespace OT {
 
 struct COLR;
@@ -188,6 +184,7 @@
 
   protected:
   T      value;
+  public:
   VarIdx varIdxBase;
   public:
   DEFINE_SIZE_STATIC (4 + T::static_size);
@@ -196,6 +193,8 @@
 template <typename T>
 struct NoVariable
 {
+  static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION;
+
   NoVariable<T>* copy (hb_serialize_context_t *c) const
   {
     TRACE_SERIALIZE (this);
@@ -888,6 +887,11 @@
   DEFINE_SIZE_STATIC (8);
 };
 
+struct ClipBoxData
+{
+  int xMin, yMin, xMax, yMax;
+};
+
 struct ClipBoxFormat1
 {
   bool sanitize (hb_sanitize_context_t *c) const
@@ -896,6 +900,14 @@
     return_trace (c->check_struct (this));
   }
 
+  void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const
+  {
+    clip_box.xMin = xMin;
+    clip_box.yMin = yMin;
+    clip_box.xMax = xMax;
+    clip_box.yMax = yMax;
+  }
+
   public:
   HBUINT8	format; /* format = 1(noVar) or 2(Var)*/
   FWORD		xMin;
@@ -906,7 +918,20 @@
   DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size);
 };
 
-struct ClipBoxFormat2 : Variable<ClipBoxFormat1> {};
+struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
+{
+  void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const
+  {
+    value.get_clip_box(clip_box, instancer);
+    if (instancer)
+    {
+      clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
+      clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
+      clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
+      clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
+    }
+  }
+};
 
 struct ClipBox
 {
@@ -932,6 +957,28 @@
     }
   }
 
+  bool get_extents (hb_glyph_extents_t *extents,
+                    const VarStoreInstancer &instancer) const
+  {
+    ClipBoxData clip_box;
+    switch (u.format) {
+    case 1:
+      u.format1.get_clip_box (clip_box, instancer);
+      break;
+    case 2:
+      u.format2.get_clip_box (clip_box, instancer);
+      break;
+    default:
+      return false;
+    }
+
+    extents->x_bearing = clip_box.xMin;
+    extents->y_bearing = clip_box.yMax;
+    extents->width = clip_box.xMax - clip_box.xMin;
+    extents->height = clip_box.yMin - clip_box.yMax;
+    return true;
+  }
+
   protected:
   union {
   HBUINT8		format;         /* Format identifier */
@@ -942,6 +989,9 @@
 
 struct ClipRecord
 {
+  int cmp (hb_codepoint_t g) const
+  { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
+
   ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
   {
     TRACE_SERIALIZE (this);
@@ -957,6 +1007,13 @@
     return_trace (c->check_struct (this) && clipBox.sanitize (c, base));
   }
 
+  bool get_extents (hb_glyph_extents_t *extents,
+		    const void *base,
+		    const VarStoreInstancer &instancer) const
+  {
+    return (base+clipBox).get_extents (extents, instancer);
+  }
+
   public:
   HBUINT16		startGlyphID;  // first gid clip applies to
   HBUINT16		endGlyphID;    // last gid clip applies to, inclusive
@@ -964,6 +1021,7 @@
   public:
   DEFINE_SIZE_STATIC (7);
 };
+DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
 
 struct ClipList
 {
@@ -1052,11 +1110,26 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
+    // TODO Make a formatted struct!
     return_trace (c->check_struct (this) && clips.sanitize (c, this));
   }
 
+  bool
+  get_extents (hb_codepoint_t gid,
+	       hb_glyph_extents_t *extents,
+	       const VarStoreInstancer &instancer) const
+  {
+    auto *rec = clips.as_array ().bsearch (gid);
+    if (rec)
+    {
+      rec->get_extents (extents, this, instancer);
+      return true;
+    }
+    return false;
+  }
+
   HBUINT8			format;  // Set to 1.
-  Array32Of<ClipRecord>		clips;  // Clip records, sorted by startGlyphID
+  SortedArray32Of<ClipRecord>	clips;  // Clip records, sorted by startGlyphID
   public:
   DEFINE_SIZE_ARRAY_SIZED (5, clips);
 };
@@ -1359,7 +1432,7 @@
                   (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
                   (this+layersZ).sanitize (c, numLayers) &&
                   (version == 0 ||
-		   (COLRV1_ENABLE_SUBSETTING && version == 1 &&
+		   (version == 1 &&
 		    baseGlyphList.sanitize (c, this) &&
 		    layerList.sanitize (c, this) &&
 		    clipList.sanitize (c, this) &&
@@ -1516,6 +1589,30 @@
     return_trace (true);
   }
 
+  bool
+  get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+  {
+    if (version != 1)
+      return false;
+
+    VarStoreInstancer instancer (this+varStore,
+				 this+varIdxMap,
+				 hb_array (font->coords, font->num_coords));
+
+    if ((this+clipList).get_extents (glyph,
+				     extents,
+				     instancer))
+    {
+      extents->x_bearing = font->em_scale_x (extents->x_bearing);
+      extents->y_bearing = font->em_scale_x (extents->y_bearing);
+      extents->width = font->em_scale_x (extents->width);
+      extents->height = font->em_scale_x (extents->height);
+      return true;
+    }
+
+    return false;
+  }
+
   protected:
   HBUINT16	version;	/* Table version number (starts at 0). */
   HBUINT16	numBaseGlyphs;	/* Number of Base Glyph Records. */

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face-table-list.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -56,9 +56,9 @@
 #if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
 HB_OT_ACCELERATOR (OT, cmap)
 #endif
-HB_OT_TABLE (OT, hhea)
+HB_OT_CORE_TABLE (OT, hhea)
 HB_OT_ACCELERATOR (OT, hmtx)
-HB_OT_TABLE (OT, OS2)
+HB_OT_CORE_TABLE (OT, OS2)
 #if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS) || !defined(HB_NO_STYLE)
 HB_OT_ACCELERATOR (OT, post)
 #endif
@@ -66,7 +66,7 @@
 HB_OT_ACCELERATOR (OT, name)
 #endif
 #ifndef HB_NO_STYLE
-HB_OT_TABLE (OT, STAT)
+HB_OT_CORE_TABLE (OT, STAT)
 #endif
 #ifndef HB_NO_META
 HB_OT_ACCELERATOR (OT, meta)
@@ -74,9 +74,9 @@
 
 /* Vertical layout. */
 #ifndef HB_NO_VERTICAL
-HB_OT_TABLE (OT, vhea)
+HB_OT_CORE_TABLE (OT, vhea)
 HB_OT_ACCELERATOR (OT, vmtx)
-HB_OT_TABLE (OT, VORG)
+HB_OT_CORE_TABLE (OT, VORG)
 #endif
 
 /* TrueType outlines. */
@@ -91,15 +91,15 @@
 
 /* OpenType variations. */
 #ifndef HB_NO_VAR
-HB_OT_TABLE (OT, fvar)
-HB_OT_TABLE (OT, avar)
+HB_OT_CORE_TABLE (OT, fvar)
+HB_OT_CORE_TABLE (OT, avar)
 HB_OT_ACCELERATOR (OT, gvar)
-HB_OT_TABLE (OT, MVAR)
+HB_OT_CORE_TABLE (OT, MVAR)
 #endif
 
 /* Legacy kern. */
 #ifndef HB_NO_OT_KERN
-HB_OT_TABLE (OT, kern)
+HB_OT_CORE_TABLE (OT, kern)
 #endif
 
 /* OpenType shaping. */
@@ -107,12 +107,12 @@
 HB_OT_ACCELERATOR (OT, GDEF)
 HB_OT_ACCELERATOR (OT, GSUB)
 HB_OT_ACCELERATOR (OT, GPOS)
-//HB_OT_TABLE (OT, JSTF)
+//HB_OT_CORE_TABLE (OT, JSTF)
 #endif
 
 /* OpenType baseline. */
 #ifndef HB_NO_BASE
-HB_OT_TABLE (OT, BASE)
+HB_OT_CORE_TABLE (OT, BASE)
 #endif
 
 /* AAT shaping. */
@@ -129,8 +129,8 @@
 
 /* OpenType color fonts. */
 #ifndef HB_NO_COLOR
-HB_OT_TABLE (OT, COLR)
-HB_OT_TABLE (OT, CPAL)
+HB_OT_CORE_TABLE (OT, COLR)
+HB_OT_CORE_TABLE (OT, CPAL)
 HB_OT_ACCELERATOR (OT, CBDT)
 HB_OT_ACCELERATOR (OT, sbix)
 HB_OT_ACCELERATOR (OT, SVG)
@@ -138,7 +138,7 @@
 
 /* OpenType math. */
 #ifndef HB_NO_MATH
-HB_OT_TABLE (OT, MATH)
+HB_OT_CORE_TABLE (OT, MATH)
 #endif
 
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -45,6 +45,7 @@
 #include "hb-ot-vorg-table.hh"
 #include "hb-ot-color-cbdt-table.hh"
 #include "hb-ot-color-sbix-table.hh"
+#include "hb-ot-color-colr-table.hh"
 
 
 /**
@@ -350,6 +351,9 @@
   if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
   if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
 #endif
+#if !defined(HB_NO_COLOR)
+  if (ot_face->COLR->get_extents (font, glyph, extents)) return true;
+#endif
   if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
 #ifndef HB_NO_OT_FONT_CFF
   if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
@@ -356,7 +360,6 @@
   if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
 #endif
 
-  // TODO Hook up side-bearings variations.
   return false;
 }
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -478,7 +478,7 @@
   {
     if (_count)
     {
-      + this->sub_array (start_offset, _count)
+      + this->as_array ().sub_array (start_offset, _count)
       | hb_sink (hb_array (_indexes, *_count))
       ;
     }
@@ -658,7 +658,7 @@
   {
     if (char_count)
     {
-      + characters.sub_array (start_offset, char_count)
+      + characters.as_array ().sub_array (start_offset, char_count)
       | hb_sink (hb_array (chars, *char_count))
       ;
     }
@@ -932,7 +932,7 @@
   {
     if (record_count)
     {
-      + this->sub_array (start_offset, record_count)
+      + this->as_array ().sub_array (start_offset, record_count)
       | hb_map (&Record<Type>::tag)
       | hb_sink (hb_array (record_tags, *record_count))
       ;
@@ -980,18 +980,16 @@
     auto *out = c->serializer->start_embed (*this);
     if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
 
-    unsigned count = this->len;
-
-    + hb_zip (*this, hb_range (count))
-    | hb_filter (l->feature_index_map, hb_second)
-    | hb_apply ([l, out, this] (const hb_pair_t<const Record<Feature>&, unsigned>& _)
+    + hb_enumerate (*this)
+    | hb_filter (l->feature_index_map, hb_first)
+    | hb_apply ([l, out, this] (const hb_pair_t<unsigned, const Record<Feature>&>& _)
                 {
                   const Feature *f_sub = nullptr;
                   const Feature **f = nullptr;
-                  if (l->feature_substitutes_map->has (_.second, &f))
+                  if (l->feature_substitutes_map->has (_.first, &f))
                     f_sub = *f;
 
-                  subset_record_array (l, out, this, f_sub) (_.first);
+                  subset_record_array (l, out, this, f_sub) (_.second);
                 })
     ;
 
@@ -1079,7 +1077,7 @@
     auto *out = c->serializer->start_embed (*this);
     if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
 
-    const unsigned *v;
+    const uint32_t *v;
     out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu;
 
     if (!l->visitFeatureIndex (featureIndex.len))
@@ -1147,7 +1145,6 @@
 	return;
     }
 
-    unsigned langsys_count = get_lang_sys_count ();
     if (has_default_lang_sys ())
     {
       //only collect features from non-redundant langsys
@@ -1156,24 +1153,24 @@
         d.collect_features (c);
       }
 
-      for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
+      for (auto _ : + hb_enumerate (langSys))
       {
-        const LangSys& l = this+_.first.offset;
+        const LangSys& l = this+_.second.offset;
         if (!c->visitLangsys (l.get_feature_count ())) continue;
         if (l.compare (d, c->duplicate_feature_map)) continue;
 
         l.collect_features (c);
-        c->script_langsys_map->get (script_index)->add (_.second);
+        c->script_langsys_map->get (script_index)->add (_.first);
       }
     }
     else
     {
-      for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
+      for (auto _ : + hb_enumerate (langSys))
       {
-        const LangSys& l = this+_.first.offset;
+        const LangSys& l = this+_.second.offset;
         if (!c->visitLangsys (l.get_feature_count ())) continue;
         l.collect_features (c);
-        c->script_langsys_map->get (script_index)->add (_.second);
+        c->script_langsys_map->get (script_index)->add (_.first);
       }
     }
   }
@@ -1211,10 +1208,9 @@
     const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index);
     if (active_langsys)
     {
-      unsigned count = langSys.len;
-      + hb_zip (langSys, hb_range (count))
-      | hb_filter (active_langsys, hb_second)
-      | hb_map (hb_first)
+      + hb_enumerate (langSys)
+      | hb_filter (active_langsys, hb_first)
+      | hb_map (hb_second)
       | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); })
       | hb_apply (subset_record_array (l, &(out->langSys), this))
       ;
@@ -1250,12 +1246,11 @@
     auto *out = c->serializer->start_embed (*this);
     if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
 
-    unsigned count = this->len;
-    for (auto _ : + hb_zip (*this, hb_range (count)))
+    for (auto _ : + hb_enumerate (*this))
     {
       auto snap = c->serializer->snapshot ();
-      l->cur_script_index = _.second;
-      bool ret = _.first.subset (l, this);
+      l->cur_script_index = _.first;
+      bool ret = _.second.subset (l, this);
       if (!ret) c->serializer->revert (snap);
       else out->len++;
     }
@@ -1388,7 +1383,13 @@
       outMarkFilteringSet = markFilteringSet;
     }
 
-    return_trace (out->subTable.len);
+    // Always keep the lookup even if it's empty. The rest of layout subsetting depends on lookup
+    // indices being consistent with those computed during planning. So if an empty lookup is
+    // discarded during the subset phase it will invalidate all subsequent lookup indices.
+    // Generally we shouldn't end up with an empty lookup as we pre-prune them during the planning
+    // phase, but it can happen in rare cases such as when during closure subtable is considered
+    // degenerate (see: https://github.com/harfbuzz/harfbuzz/issues/3853)
+    return true;
   }
 
   template <typename TSubTable>
@@ -1454,10 +1455,9 @@
     auto *out = c->serializer->start_embed (this);
     if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
 
-    unsigned count = this->len;
-    + hb_zip (*this, hb_range (count))
-    | hb_filter (l->lookup_index_map, hb_second)
-    | hb_map (hb_first)
+    + hb_enumerate (*this)
+    | hb_filter (l->lookup_index_map, hb_first)
+    | hb_map (hb_second)
     | hb_apply (subset_offset_array (c, *out, this))
     ;
     return_trace (true);
@@ -1491,7 +1491,7 @@
     klass_map->set (0, 0);
 
   unsigned idx = klass_map->has (0) ? 1 : 0;
-  for (const unsigned k: klasses.iter ())
+  for (const unsigned k: klasses)
   {
     if (klass_map->has (k)) continue;
     klass_map->set (k, idx);
@@ -1524,6 +1524,11 @@
     return classValue[(unsigned int) (glyph_id - startGlyph)];
   }
 
+  unsigned get_population () const
+  {
+    return classValue.len;
+  }
+
   template<typename Iterator,
 	   hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c,
@@ -1548,7 +1553,7 @@
 
     startGlyph = glyph_min;
     if (unlikely (!classValue.serialize (c, glyph_count))) return_trace (false);
-    for (const hb_pair_t<hb_codepoint_t, unsigned> gid_klass_pair : + it)
+    for (const hb_pair_t<hb_codepoint_t, uint32_t> gid_klass_pair : + it)
     {
       unsigned idx = gid_klass_pair.first - glyph_min;
       classValue[idx] = gid_klass_pair.second;
@@ -1639,11 +1644,10 @@
 
   bool intersects (const hb_set_t *glyphs) const
   {
-    /* TODO Speed up, using hb_set_next()? */
     hb_codepoint_t start = startGlyph;
     hb_codepoint_t end = startGlyph + classValue.len;
     for (hb_codepoint_t iter = startGlyph - 1;
-	 hb_set_next (glyphs, &iter) && iter < end;)
+	 glyphs->next (&iter) && iter < end;)
       if (classValue[iter - start]) return true;
     return false;
   }
@@ -1654,10 +1658,10 @@
     {
       /* Match if there's any glyph that is not listed! */
       hb_codepoint_t g = HB_SET_VALUE_INVALID;
-      if (!hb_set_next (glyphs, &g)) return false;
+      if (!glyphs->next (&g)) return false;
       if (g < startGlyph) return true;
       g = startGlyph + count - 1;
-      if (hb_set_next (glyphs, &g)) return true;
+      if (glyphs->next (&g)) return true;
       /* Fall through. */
     }
     /* TODO Speed up, using set overlap first? */
@@ -1675,12 +1679,12 @@
     if (klass == 0)
     {
       unsigned start_glyph = startGlyph;
-      for (unsigned g = HB_SET_VALUE_INVALID;
-	   hb_set_next (glyphs, &g) && g < start_glyph;)
+      for (uint32_t g = HB_SET_VALUE_INVALID;
+	   glyphs->next (&g) && g < start_glyph;)
 	intersect_glyphs->add (g);
 
-      for (unsigned g = startGlyph + count - 1;
-	   hb_set_next (glyphs, &g);)
+      for (uint32_t g = startGlyph + count - 1;
+	   glyphs-> next (&g);)
 	intersect_glyphs->add (g);
 
       return;
@@ -1696,7 +1700,7 @@
     unsigned start_glyph = startGlyph;
     unsigned end_glyph = start_glyph + count;
     for (unsigned g = startGlyph - 1;
-	 hb_set_next (glyphs, &g) && g < end_glyph;)
+	 glyphs->next (&g) && g < end_glyph;)
       if (classValue.arrayZ[g - start_glyph] == klass)
         intersect_glyphs->add (g);
 #endif
@@ -1739,6 +1743,14 @@
     return rangeRecord.bsearch (glyph_id).value;
   }
 
+  unsigned get_population () const
+  {
+    typename Types::large_int ret = 0;
+    for (const auto &r : rangeRecord)
+      ret += r.get_population ();
+    return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
+  }
+
   template<typename Iterator,
 	   hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c,
@@ -1802,29 +1814,46 @@
   {
     TRACE_SUBSET (this);
     const hb_map_t &glyph_map = *c->plan->glyph_map_gsub;
+    const hb_set_t &glyph_set = *c->plan->glyphset_gsub ();
 
     hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
     hb_set_t orig_klasses;
 
-    unsigned num_source_glyphs = c->plan->source->get_num_glyphs ();
-    unsigned count = rangeRecord.len;
-    for (unsigned i = 0; i < count; i++)
+    if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2
+	< get_population ())
     {
-      unsigned klass = rangeRecord[i].value;
-      if (!klass) continue;
-      hb_codepoint_t start = rangeRecord[i].first;
-      hb_codepoint_t end   = hb_min (rangeRecord[i].last + 1, num_source_glyphs);
-      for (hb_codepoint_t g = start; g < end; g++)
+      for (hb_codepoint_t g : glyph_set)
       {
-        hb_codepoint_t new_gid = glyph_map[g];
+	unsigned klass = get_class (g);
+	if (!klass) continue;
+	hb_codepoint_t new_gid = glyph_map[g];
 	if (new_gid == HB_MAP_VALUE_INVALID) continue;
-        if (glyph_filter && !glyph_filter->has (g)) continue;
-
+	if (glyph_filter && !glyph_filter->has (g)) continue;
 	glyph_and_klass.push (hb_pair (new_gid, klass));
 	orig_klasses.add (klass);
       }
     }
+    else
+    {
+      unsigned num_source_glyphs = c->plan->source->get_num_glyphs ();
+      for (auto &range : rangeRecord)
+      {
+	unsigned klass = range.value;
+	if (!klass) continue;
+	hb_codepoint_t start = range.first;
+	hb_codepoint_t end   = hb_min (range.last + 1, num_source_glyphs);
+	for (hb_codepoint_t g = start; g < end; g++)
+	{
+	  hb_codepoint_t new_gid = glyph_map[g];
+	  if (new_gid == HB_MAP_VALUE_INVALID) continue;
+	  if (glyph_filter && !glyph_filter->has (g)) continue;
 
+	  glyph_and_klass.push (hb_pair (new_gid, klass));
+	  orig_klasses.add (klass);
+	}
+      }
+    }
+
     const hb_set_t& glyphset = *c->plan->glyphset_gsub ();
     unsigned glyph_count = glyph_filter
                            ? hb_len (hb_iter (glyphset) | hb_filter (glyph_filter))
@@ -1850,10 +1879,9 @@
   template <typename set_t>
   bool collect_coverage (set_t *glyphs) const
   {
-    unsigned int count = rangeRecord.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (rangeRecord[i].value)
-	if (unlikely (!rangeRecord[i].collect_coverage (glyphs)))
+    for (auto &range : rangeRecord)
+      if (range.value)
+	if (unlikely (!range.collect_coverage (glyphs)))
 	  return false;
     return true;
   }
@@ -1861,11 +1889,10 @@
   template <typename set_t>
   bool collect_class (set_t *glyphs, unsigned int klass) const
   {
-    unsigned int count = rangeRecord.len;
-    for (unsigned int i = 0; i < count; i++)
+    for (auto &range : rangeRecord)
     {
-      if (rangeRecord[i].value == klass)
-	if (unlikely (!rangeRecord[i].collect_coverage (glyphs)))
+      if (range.value == klass)
+	if (unlikely (!range.collect_coverage (glyphs)))
 	  return false;
     }
     return true;
@@ -1873,32 +1900,32 @@
 
   bool intersects (const hb_set_t *glyphs) const
   {
-    /* TODO Speed up, using hb_set_next() and bsearch()? */
-    unsigned int count = rangeRecord.len;
-    for (unsigned int i = 0; i < count; i++)
+    if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
     {
-      const auto& range = rangeRecord[i];
-      if (range.intersects (*glyphs) && range.value)
-	return true;
+      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+        if (get_class (g))
+	  return true;
+      return false;
     }
-    return false;
+
+    return hb_any (+ hb_iter (rangeRecord)
+                   | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs) && range.value; }));
   }
   bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const
   {
-    unsigned int count = rangeRecord.len;
     if (klass == 0)
     {
       /* Match if there's any glyph that is not listed! */
       hb_codepoint_t g = HB_SET_VALUE_INVALID;
-      for (unsigned int i = 0; i < count; i++)
+      for (auto &range : rangeRecord)
       {
-	if (!hb_set_next (glyphs, &g))
+	if (!glyphs->next (&g))
 	  break;
-	if (g < rangeRecord[i].first)
+	if (g < range.first)
 	  return true;
-	g = rangeRecord[i].last;
+	g = range.last;
       }
-      if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
+      if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
 	return true;
       /* Fall through. */
     }
@@ -1910,23 +1937,22 @@
 
   void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const
   {
-    unsigned count = rangeRecord.len;
     if (klass == 0)
     {
       hb_codepoint_t g = HB_SET_VALUE_INVALID;
-      for (unsigned int i = 0; i < count; i++)
+      for (auto &range : rangeRecord)
       {
-	if (!hb_set_next (glyphs, &g))
+	if (!glyphs->next (&g))
 	  goto done;
-	while (g < rangeRecord[i].first)
+	while (g < range.first)
 	{
 	  intersect_glyphs->add (g);
-	  if (!hb_set_next (glyphs, &g))
+	  if (!glyphs->next (&g))
 	    goto done;
         }
-        g = rangeRecord[i].last;
+        g = range.last;
       }
-      while (hb_set_next (glyphs, &g))
+      while (glyphs->next (&g))
 	intersect_glyphs->add (g);
       done:
 
@@ -1933,26 +1959,27 @@
       return;
     }
 
-#if 0
-    /* The following implementation is faster asymptotically, but slower
-     * in practice. */
-    if ((count >> 3) > glyphs->get_population ())
+    unsigned count = rangeRecord.len;
+    if (count > glyphs->get_population () * hb_bit_storage (count) * 8)
     {
       for (hb_codepoint_t g = HB_SET_VALUE_INVALID;
-	   hb_set_next (glyphs, &g);)
-        if (rangeRecord.as_array ().bfind (g))
+	   glyphs->next (&g);)
+      {
+        unsigned i;
+        if (rangeRecord.as_array ().bfind (g, &i) &&
+	    rangeRecord.arrayZ[i].value == klass)
 	  intersect_glyphs->add (g);
+      }
       return;
     }
-#endif
 
-    for (unsigned int i = 0; i < count; i++)
+    for (auto &range : rangeRecord)
     {
-      if (rangeRecord[i].value != klass) continue;
+      if (range.value != klass) continue;
 
-      unsigned end = rangeRecord[i].last + 1;
-      for (hb_codepoint_t g = rangeRecord[i].first - 1;
-	   hb_set_next (glyphs, &g) && g < end;)
+      unsigned end = range.last + 1;
+      for (hb_codepoint_t g = range.first - 1;
+	   glyphs->next (&g) && g < end;)
 	intersect_glyphs->add (g);
     }
   }
@@ -1961,25 +1988,24 @@
   {
     if (glyphs->is_empty ()) return;
 
-    unsigned count = rangeRecord.len;
     hb_codepoint_t g = HB_SET_VALUE_INVALID;
-    for (unsigned int i = 0; i < count; i++)
+    for (auto &range : rangeRecord)
     {
-      if (!hb_set_next (glyphs, &g))
+      if (!glyphs->next (&g))
         break;
-      if (g < rangeRecord[i].first)
+      if (g < range.first)
       {
         intersect_classes->add (0);
         break;
       }
-      g = rangeRecord[i].last;
+      g = range.last;
     }
-    if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
+    if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
       intersect_classes->add (0);
 
-    for (const auto& record : rangeRecord.iter ())
-      if (record.intersects (*glyphs))
-        intersect_classes->add (record.value);
+    for (const auto& range : rangeRecord)
+      if (range.intersects (*glyphs))
+        intersect_classes->add (range.value);
   }
 
   protected:
@@ -1994,10 +2020,8 @@
 struct ClassDef
 {
   /* Has interface. */
-  static constexpr unsigned SENTINEL = 0;
-  typedef unsigned int value_t;
-  value_t operator [] (hb_codepoint_t k) const { return get (k); }
-  bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+  unsigned operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k]; }
   /* Projection. */
   hb_codepoint_t operator () (hb_codepoint_t k) const { return get (k); }
 
@@ -2015,6 +2039,19 @@
     }
   }
 
+  unsigned get_population () const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_population ();
+    case 2: return u.format2.get_population ();
+#ifndef HB_NO_BEYOND_64K
+    case 3: return u.format3.get_population ();
+    case 4: return u.format4.get_population ();
+#endif
+    default:return NOT_COVERED;
+    }
+  }
+
   template<typename Iterator,
 	   hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c, Iterator it_with_class_zero)
@@ -2332,7 +2369,7 @@
     {
       unsigned int backward = region_map.backward (r);
       if (backward >= region_count) return_trace (false);
-      memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount);
+      hb_memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount);
     }
 
     return_trace (true);
@@ -2442,21 +2479,26 @@
     unsigned ri_count = src->regionIndices.len;
     enum delta_size_t { kZero=0, kNonWord, kWord };
     hb_vector_t<delta_size_t> delta_sz;
-    hb_vector_t<unsigned int> ri_map;	/* maps old index to new index */
+    hb_vector_t<unsigned int> ri_map;	/* maps new index to old index */
     delta_sz.resize (ri_count);
     ri_map.resize (ri_count);
     unsigned int new_word_count = 0;
     unsigned int r;
 
+    const HBUINT8 *src_delta_bytes = src->get_delta_bytes ();
+    unsigned src_row_size = src->get_row_size ();
+    unsigned src_word_count = src->wordCount ();
+    bool     src_long_words = src->longWords ();
+
     bool has_long = false;
-    if (src->longWords ())
+    if (src_long_words)
     {
-      for (r = 0; r < ri_count; r++)
+      for (r = 0; r < src_word_count; r++)
       {
 	for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
 	{
 	  unsigned int old = inner_map.backward (i);
-	  int32_t delta = src->get_item_delta (old, r);
+	  int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
 	  if (delta < -65536 || 65535 < delta)
 	  {
 	    has_long = true;
@@ -2470,11 +2512,13 @@
     signed max_threshold = has_long ? +65535 : +127;
     for (r = 0; r < ri_count; r++)
     {
+      bool short_circuit = src_long_words == has_long && src_word_count <= r;
+
       delta_sz[r] = kZero;
       for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
       {
 	unsigned int old = inner_map.backward (i);
-	int32_t delta = src->get_item_delta (old, r);
+	int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
 	if (delta < min_threshold || max_threshold < delta)
 	{
 	  delta_sz[r] = kWord;
@@ -2482,7 +2526,11 @@
 	  break;
 	}
 	else if (delta != 0)
+	{
 	  delta_sz[r] = kNonWord;
+	  if (short_circuit)
+	    break;
+	}
       }
     }
 
@@ -2492,7 +2540,8 @@
     for (r = 0; r < ri_count; r++)
       if (delta_sz[r])
       {
-	ri_map[r] = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
+	unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
+	ri_map[new_r] = r;
 	new_ri_count++;
       }
 
@@ -2502,14 +2551,20 @@
 
     if (unlikely (!c->extend (this))) return_trace (false);
 
-    for (r = 0; r < ri_count; r++)
-      if (delta_sz[r]) regionIndices[ri_map[r]] = region_map[src->regionIndices[r]];
+    for (r = 0; r < new_ri_count; r++)
+      regionIndices[r] = region_map[src->regionIndices[ri_map[r]]];
 
-    for (unsigned int i = 0; i < itemCount; i++)
+    HBUINT8 *delta_bytes = get_delta_bytes ();
+    unsigned row_size = get_row_size ();
+    unsigned count = itemCount;
+    for (unsigned int i = 0; i < count; i++)
     {
-      unsigned int	old = inner_map.backward (i);
-      for (unsigned int r = 0; r < ri_count; r++)
-	if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r));
+      unsigned int old = inner_map.backward (i);
+      for (unsigned int r = 0; r < new_ri_count; r++)
+	set_item_delta_fast (i, r,
+			     src->get_item_delta_fast (old, ri_map[r],
+						       src_delta_bytes, src_row_size),
+			     delta_bytes, row_size);
     }
 
     return_trace (true);
@@ -2517,12 +2572,15 @@
 
   void collect_region_refs (hb_set_t &region_indices, const hb_inc_bimap_t &inner_map) const
   {
+    const HBUINT8 *delta_bytes = get_delta_bytes ();
+    unsigned row_size = get_row_size ();
+
     for (unsigned int r = 0; r < regionIndices.len; r++)
     {
-      unsigned int region = regionIndices[r];
+      unsigned int region = regionIndices.arrayZ[r];
       if (region_indices.has (region)) continue;
       for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
-	if (get_item_delta (inner_map.backward (i), r) != 0)
+	if (get_item_delta_fast (inner_map.backward (i), r, delta_bytes, row_size) != 0)
 	{
 	  region_indices.add (region);
 	  break;
@@ -2537,10 +2595,12 @@
   HBUINT8 *get_delta_bytes ()
   { return &StructAfter<HBUINT8> (regionIndices); }
 
-  int32_t get_item_delta (unsigned int item, unsigned int region) const
+  int32_t get_item_delta_fast (unsigned int item, unsigned int region,
+			       const HBUINT8 *delta_bytes, unsigned row_size) const
   {
-    if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
-    const HBINT8 *p = (const HBINT8 *) get_delta_bytes () + item * get_row_size ();
+    if (unlikely (item >= itemCount || region >= regionIndices.len)) return 0;
+
+    const HBINT8 *p = (const HBINT8 *) delta_bytes + item * row_size;
     unsigned word_count = wordCount ();
     bool is_long = longWords ();
     if (is_long)
@@ -2558,10 +2618,17 @@
 	return (p + HBINT16::static_size * word_count)[region - word_count];
     }
   }
+  int32_t get_item_delta (unsigned int item, unsigned int region) const
+  {
+     return get_item_delta_fast (item, region,
+				 get_delta_bytes (),
+				 get_row_size ());
+  }
 
-  void set_item_delta (unsigned int item, unsigned int region, int32_t delta)
+  void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta,
+			    HBUINT8 *delta_bytes, unsigned row_size)
   {
-    HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size ();
+    HBINT8 *p = (HBINT8 *) delta_bytes + item * row_size;
     unsigned word_count = wordCount ();
     bool is_long = longWords ();
     if (is_long)
@@ -2579,6 +2646,12 @@
 	(p + HBINT16::static_size * word_count)[region - word_count] = delta;
     }
   }
+  void set_item_delta (unsigned int item, unsigned int region, int32_t delta)
+  {
+    set_item_delta_fast (item, region, delta,
+			 get_delta_bytes (),
+			 get_row_size ());
+  }
 
   bool longWords () const { return wordSizeCount & 0x8000u /* LONG_WORDS */; }
   unsigned wordCount () const { return wordSizeCount & 0x7FFFu /* WORD_DELTA_COUNT_MASK */; }
@@ -2642,6 +2715,14 @@
     unsigned int inner = index & 0xFFFF;
     return get_delta (outer, inner, coords, coord_count, cache);
   }
+  float get_delta (unsigned int index,
+		   hb_array_t<int> coords,
+		   VarRegionList::cache_t *cache = nullptr) const
+  {
+    return get_delta (index,
+		      coords.arrayZ, coords.length,
+		      cache);
+  }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -2948,7 +3029,7 @@
 
     // all conditions met
     if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
- 
+
     //check if condition_set is unique with variations
     if (c->conditionset_map->has (p))
       //duplicate found, drop the entire record
@@ -3420,17 +3501,16 @@
   {
     TRACE_SERIALIZE (this);
     if (!layout_variation_idx_delta_map) return_trace (nullptr);
-    auto snap = c->snapshot ();
+
+    hb_pair_t<unsigned, int> *v;
+    if (!layout_variation_idx_delta_map->has (varIdx, &v))
+      return_trace (nullptr);
+
+    c->start_zerocopy (this->static_size);
     auto *out = c->embed (this);
     if (unlikely (!out)) return_trace (nullptr);
 
-    /* TODO Just get() and bail if NO_VARIATION. Needs to setup the map to return that. */
-    if (!layout_variation_idx_delta_map->has (varIdx))
-    {
-      c->revert (snap);
-      return_trace (nullptr);
-    }
-    unsigned new_idx = hb_first (layout_variation_idx_delta_map->get (varIdx));
+    unsigned new_idx = hb_first (*v);
     out->varIdx = new_idx;
     return_trace (out);
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -73,7 +73,7 @@
 
     if (point_count)
     {
-      + points.sub_array (start_offset, point_count)
+      + points.as_array ().sub_array (start_offset, point_count)
       | hb_sink (hb_array (point_array, *point_count))
       ;
     }
@@ -322,7 +322,7 @@
   {
     if (caret_count)
     {
-      + carets.sub_array (start_offset, caret_count)
+      + carets.as_array ().sub_array (start_offset, caret_count)
       | hb_map (hb_add (this))
       | hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); })
       | hb_sink (hb_array (caret_array, *caret_count))

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -100,8 +100,8 @@
 
   bool is_lookup_done (unsigned int lookup_index)
   {
-    if (done_lookups_glyph_count->in_error () ||
-        done_lookups_glyph_set->in_error ())
+    if (unlikely (done_lookups_glyph_count->in_error () ||
+		  done_lookups_glyph_set->in_error ()))
       return true;
 
     /* Have we visited this lookup with the current set of glyphs? */
@@ -535,7 +535,12 @@
     bool next (unsigned *unsafe_to = nullptr)
     {
       assert (num_items > 0);
-      while (idx + num_items < end)
+      /* The alternate condition below is faster at string boundaries,
+       * but produces subpar "unsafe-to-concat" values. */
+      signed stop = (signed) end - (signed) num_items;
+      if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
+        stop = (signed) end - 1;
+      while ((signed) idx < stop)
       {
 	idx++;
 	hb_glyph_info_t &info = c->buffer->info[idx];
@@ -568,7 +573,12 @@
     bool prev (unsigned *unsafe_from = nullptr)
     {
       assert (num_items > 0);
-      while (idx > num_items - 1)
+      /* The alternate condition below is faster at string boundaries,
+       * but produces subpar "unsafe-to-concat" values. */
+      unsigned stop = num_items - 1;
+      if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
+        stop = 1 - 1;
+      while (idx > stop)
       {
 	idx--;
 	hb_glyph_info_t &info = c->buffer->out_info[idx];
@@ -672,6 +682,7 @@
   const GDEF &gdef;
   const VariationStore &var_store;
   VariationStore::cache_t *var_store_cache;
+  hb_set_digest_t digest;
 
   hb_direction_t direction;
   hb_mask_t lookup_mask = 1;
@@ -707,6 +718,7 @@
 					 nullptr
 #endif
 					),
+			digest (buffer_->digest ()),
 			direction (buffer_->props.direction),
 			has_glyph_classes (gdef.has_glyph_classes ())
   { init_iters (); }
@@ -781,8 +793,10 @@
   void _set_glyph_class (hb_codepoint_t glyph_index,
 			  unsigned int class_guess = 0,
 			  bool ligature = false,
-			  bool component = false) const
+			  bool component = false)
   {
+    digest.add (glyph_index);
+
     if (new_syllables != (unsigned) -1)
       buffer->cur().syllable() = new_syllables;
 
@@ -815,24 +829,24 @@
       _hb_glyph_info_set_glyph_props (&buffer->cur(), props);
   }
 
-  void replace_glyph (hb_codepoint_t glyph_index) const
+  void replace_glyph (hb_codepoint_t glyph_index)
   {
     _set_glyph_class (glyph_index);
     (void) buffer->replace_glyph (glyph_index);
   }
-  void replace_glyph_inplace (hb_codepoint_t glyph_index) const
+  void replace_glyph_inplace (hb_codepoint_t glyph_index)
   {
     _set_glyph_class (glyph_index);
     buffer->cur().codepoint = glyph_index;
   }
   void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
-				    unsigned int class_guess) const
+				    unsigned int class_guess)
   {
     _set_glyph_class (glyph_index, class_guess, true);
     (void) buffer->replace_glyph (glyph_index);
   }
   void output_glyph_for_component (hb_codepoint_t glyph_index,
-				   unsigned int class_guess) const
+				   unsigned int class_guess)
   {
     _set_glyph_class (glyph_index, class_guess, false, true);
     (void) buffer->output_glyph (glyph_index);
@@ -844,7 +858,7 @@
        hb_dispatch_context_t<hb_accelerate_subtables_context_t>
 {
   template <typename Type>
-  static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
+  static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c)
   {
     const Type *typed_obj = (const Type *) obj;
     return typed_obj->apply (c);
@@ -852,11 +866,11 @@
 
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   template <typename T>
-  static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
+  static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
   template <typename T>
-  static inline auto apply_cached_ (const T *obj, OT::hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
+  static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
   template <typename Type>
-  static inline bool apply_cached_to (const void *obj, OT::hb_ot_apply_context_t *c)
+  static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c)
   {
     const Type *typed_obj = (const Type *) obj;
     return apply_cached_ (typed_obj, c, hb_prioritize);
@@ -863,11 +877,11 @@
   }
 
   template <typename T>
-  static inline auto cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) )
+  static inline auto cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) )
   template <typename T>
-  static inline bool cache_func_ (const T *obj, OT::hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; }
+  static inline bool cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; }
   template <typename Type>
-  static inline bool cache_func_to (const void *obj, OT::hb_ot_apply_context_t *c, bool enter)
+  static inline bool cache_func_to (const void *obj, hb_ot_apply_context_t *c, bool enter)
   {
     const Type *typed_obj = (const Type *) obj;
     return cache_func_ (typed_obj, c, enter, hb_prioritize);
@@ -874,8 +888,8 @@
   }
 #endif
 
-  typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
-  typedef bool (*hb_cache_func_t) (const void *obj, OT::hb_ot_apply_context_t *c, bool enter);
+  typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c);
+  typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter);
 
   struct hb_applicable_t
   {
@@ -901,20 +915,20 @@
       obj_.get_coverage ().collect_coverage (&digest);
     }
 
-    bool apply (OT::hb_ot_apply_context_t *c) const
+    bool apply (hb_ot_apply_context_t *c) const
     {
       return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c);
     }
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
-    bool apply_cached (OT::hb_ot_apply_context_t *c) const
+    bool apply_cached (hb_ot_apply_context_t *c) const
     {
       return digest.may_have (c->buffer->cur().codepoint) &&  apply_cached_func (obj, c);
     }
-    bool cache_enter (OT::hb_ot_apply_context_t *c) const
+    bool cache_enter (hb_ot_apply_context_t *c) const
     {
       return cache_func (obj, c, true);
     }
-    void cache_leave (OT::hb_ot_apply_context_t *c) const
+    void cache_leave (hb_ot_apply_context_t *c) const
     {
       cache_func (obj, c, false);
     }
@@ -988,8 +1002,8 @@
 };
 
 
-typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data);
-typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs);
+typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data, void *cache);
+typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache);
 typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, unsigned value, const void *data);
 typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data);
 
@@ -1012,16 +1026,25 @@
 };
 
 
-static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED)
+static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED, void *cache HB_UNUSED)
 {
   return glyphs->has (value);
 }
-static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data)
+static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data, void *cache)
 {
   const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
-  return class_def.intersects_class (glyphs, value);
+  hb_map_t *map = (hb_map_t *) cache;
+
+  hb_codepoint_t *cached_v;
+  if (map->has (value, &cached_v))
+    return *cached_v;
+
+  bool v = class_def.intersects_class (glyphs, value);
+  map->set (value, v);
+
+  return v;
 }
-static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data)
+static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data, void *cache HB_UNUSED)
 {
   Offset16To<Coverage> coverage;
   coverage = value;
@@ -1029,17 +1052,36 @@
 }
 
 
-static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs)
+static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache)
 {
   unsigned g = reinterpret_cast<const HBUINT16 *>(data)[value];
   intersected_glyphs->add (g);
 }
-static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs)
+
+using intersected_class_cache_t = hb_hashmap_t<unsigned, hb_set_t>;
+
+static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache)
 {
   const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
-  class_def.intersected_class_glyphs (glyphs, value, intersected_glyphs);
+
+  intersected_class_cache_t *map = (intersected_class_cache_t *) cache;
+
+  hb_set_t *cached_v;
+  if (map->has (value, &cached_v))
+  {
+    intersected_glyphs->union_ (*cached_v);
+    return;
+  }
+
+  hb_set_t v;
+  class_def.intersected_class_glyphs (glyphs, value, &v);
+
+  intersected_glyphs->union_ (v);
+
+  map->set (value, std::move (v));
 }
-static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs)
+
+static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache)
 {
   Offset16To<Coverage> coverage;
   coverage = value;
@@ -1052,10 +1094,11 @@
 				       unsigned int count,
 				       const HBUINT values[],
 				       intersects_func_t intersects_func,
-				       const void *intersects_data)
+				       const void *intersects_data,
+				       void *cache)
 {
   for (const auto &_ : + hb_iter (values, count))
-    if (!intersects_func (glyphs, _, intersects_data)) return false;
+    if (!intersects_func (glyphs, _, intersects_data, cache)) return false;
   return true;
 }
 
@@ -1492,7 +1535,8 @@
 					     unsigned value,
 					     ContextFormat context_format,
 					     const void *data,
-					     intersected_glyphs_func_t intersected_glyphs_func)
+					     intersected_glyphs_func_t intersected_glyphs_func,
+					     void *cache)
 {
   hb_set_t *covered_seq_indicies = hb_set_create ();
   for (unsigned int i = 0; i < lookupCount; i++)
@@ -1513,7 +1557,7 @@
           pos_glyphs.add (value);
           break;
         case ContextFormat::ClassBasedContext:
-          intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs);
+          intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs, cache);
           break;
         case ContextFormat::CoverageBasedContext:
           pos_glyphs.set (c->parent_active_glyphs ());
@@ -1530,7 +1574,7 @@
           input_value = input[seqIndex - 1];
         }
 
-        intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs);
+        intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs, cache);
       }
     }
 
@@ -1710,6 +1754,8 @@
   ContextClosureFuncs funcs;
   ContextFormat context_format;
   const void *intersects_data;
+  void *intersects_cache;
+  void *intersected_glyphs_cache;
 };
 
 struct ContextCollectGlyphsLookupContext
@@ -1732,7 +1778,9 @@
 {
   return array_is_subset_of (glyphs,
 			     inputCount ? inputCount - 1 : 0, input,
-			     lookup_context.funcs.intersects, lookup_context.intersects_data);
+			     lookup_context.funcs.intersects,
+			     lookup_context.intersects_data,
+			     lookup_context.intersects_cache);
 }
 
 template <typename HBUINT>
@@ -1753,7 +1801,8 @@
 				     value,
 				     lookup_context.context_format,
 				     lookup_context.intersects_data,
-				     lookup_context.funcs.intersected_glyphs);
+				     lookup_context.funcs.intersected_glyphs,
+				     lookup_context.intersected_glyphs_cache);
 }
 
 template <typename HBUINT>
@@ -1777,7 +1826,7 @@
 					       const HBUINT input[], /* Array of input values--start with second glyph */
 					       unsigned int lookupCount HB_UNUSED,
 					       const LookupRecord lookupRecord[] HB_UNUSED,
-					       ContextApplyLookupContext &lookup_context)
+					       const ContextApplyLookupContext &lookup_context)
 {
   return would_match_input (c,
 			    inputCount, input,
@@ -1790,7 +1839,7 @@
 					 const HBUINT input[], /* Array of input values--start with second glyph */
 					 unsigned int lookupCount,
 					 const LookupRecord lookupRecord[],
-					 ContextApplyLookupContext &lookup_context)
+					 const ContextApplyLookupContext &lookup_context)
 {
   unsigned match_end = 0;
   unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
@@ -1858,7 +1907,7 @@
   }
 
   bool would_apply (hb_would_apply_context_t *c,
-		    ContextApplyLookupContext &lookup_context) const
+		    const ContextApplyLookupContext &lookup_context) const
   {
     const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
 					   (inputZ.as_array (inputCount ? inputCount - 1 : 0));
@@ -1869,7 +1918,7 @@
   }
 
   bool apply (hb_ot_apply_context_t *c,
-	      ContextApplyLookupContext &lookup_context) const
+	      const ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
     const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
@@ -1989,7 +2038,7 @@
   }
 
   bool would_apply (hb_would_apply_context_t *c,
-		    ContextApplyLookupContext &lookup_context) const
+		    const ContextApplyLookupContext &lookup_context) const
   {
     return
     + hb_iter (rule)
@@ -2000,7 +2049,7 @@
   }
 
   bool apply (hb_ot_apply_context_t *c,
-	      ContextApplyLookupContext &lookup_context) const
+	      const ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
     return_trace (
@@ -2108,7 +2157,7 @@
   void closure_lookups (hb_closure_lookups_context_t *c) const
   {
     struct ContextClosureLookupContext lookup_context = {
-      {intersects_glyph, intersected_glyph},
+      {intersects_glyph, nullptr},
       ContextFormat::SimpleContext,
       nullptr
     };
@@ -2220,10 +2269,12 @@
 
     const ClassDef &class_def = this+classDef;
 
+    hb_map_t cache;
     struct ContextClosureLookupContext lookup_context = {
-      {intersects_class, intersected_class_glyphs},
+      {intersects_class, nullptr},
       ContextFormat::ClassBasedContext,
-      &class_def
+      &class_def,
+      &cache
     };
 
     hb_set_t retained_coverage_glyphs;
@@ -2259,10 +2310,14 @@
 
     const ClassDef &class_def = this+classDef;
 
+    hb_map_t cache;
+    intersected_class_cache_t intersected_cache;
     struct ContextClosureLookupContext lookup_context = {
       {intersects_class, intersected_class_glyphs},
       ContextFormat::ClassBasedContext,
-      &class_def
+      &class_def,
+      &cache,
+      &intersected_cache
     };
 
     + hb_enumerate (ruleSet)
@@ -2286,10 +2341,12 @@
 
     const ClassDef &class_def = this+classDef;
 
+    hb_map_t cache;
     struct ContextClosureLookupContext lookup_context = {
-      {intersects_class, intersected_class_glyphs},
+      {intersects_class, nullptr},
       ContextFormat::ClassBasedContext,
-      &class_def
+      &class_def,
+      &cache
     };
 
     + hb_iter (ruleSet)
@@ -2407,6 +2464,7 @@
     const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
     bool ret = true;
     int non_zero_index = -1, index = 0;
+    auto snapshot = c->serializer->snapshot();
     for (const auto& _ : + hb_enumerate (ruleSet)
 			 | hb_filter (klass_map, hb_first))
     {
@@ -2418,8 +2476,10 @@
       }
 
       if (coverage_glyph_classes.has (_.first) &&
-	  o->serialize_subset (c, _.second, this, lookup_map, &klass_map))
+	  o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) {
 	non_zero_index = index;
+        snapshot = c->serializer->snapshot();
+      }
 
       index++;
     }
@@ -2433,6 +2493,7 @@
       out->ruleSet.pop ();
       index--;
     }
+    c->serializer->revert (snapshot);
 
     return_trace (bool (out->ruleSet));
   }
@@ -2469,7 +2530,7 @@
       return false;
 
     struct ContextClosureLookupContext lookup_context = {
-      {intersects_coverage, intersected_coverage_glyphs},
+      {intersects_coverage, nullptr},
       ContextFormat::CoverageBasedContext,
       this
     };
@@ -2655,6 +2716,8 @@
   ContextClosureFuncs funcs;
   ContextFormat context_format;
   const void *intersects_data[3];
+  void *intersects_cache[3];
+  void *intersected_glyphs_cache;
 };
 
 struct ChainContextCollectGlyphsLookupContext
@@ -2681,13 +2744,19 @@
 {
   return array_is_subset_of (glyphs,
 			     backtrackCount, backtrack,
-			     lookup_context.funcs.intersects, lookup_context.intersects_data[0])
+			     lookup_context.funcs.intersects,
+			     lookup_context.intersects_data[0],
+			     lookup_context.intersects_cache[0])
       && array_is_subset_of (glyphs,
 			     inputCount ? inputCount - 1 : 0, input,
-			     lookup_context.funcs.intersects, lookup_context.intersects_data[1])
+			     lookup_context.funcs.intersects,
+			     lookup_context.intersects_data[1],
+			     lookup_context.intersects_cache[1])
       && array_is_subset_of (glyphs,
 			     lookaheadCount, lookahead,
-			     lookup_context.funcs.intersects, lookup_context.intersects_data[2]);
+			     lookup_context.funcs.intersects,
+			     lookup_context.intersects_data[2],
+			     lookup_context.intersects_cache[2]);
 }
 
 template <typename HBUINT>
@@ -2714,7 +2783,8 @@
 		     value,
 		     lookup_context.context_format,
 		     lookup_context.intersects_data[1],
-		     lookup_context.funcs.intersected_glyphs);
+		     lookup_context.funcs.intersected_glyphs,
+		     lookup_context.intersected_glyphs_cache);
 }
 
 template <typename HBUINT>
@@ -2752,7 +2822,7 @@
 						     const HBUINT lookahead[] HB_UNUSED,
 						     unsigned int lookupCount HB_UNUSED,
 						     const LookupRecord lookupRecord[] HB_UNUSED,
-						     ChainContextApplyLookupContext &lookup_context)
+						     const ChainContextApplyLookupContext &lookup_context)
 {
   return (c->zero_context ? !backtrackCount && !lookaheadCount : true)
       && would_match_input (c,
@@ -2770,7 +2840,7 @@
 					       const HBUINT lookahead[],
 					       unsigned int lookupCount,
 					       const LookupRecord lookupRecord[],
-					       ChainContextApplyLookupContext &lookup_context)
+					       const ChainContextApplyLookupContext &lookup_context)
 {
   unsigned end_index = c->buffer->idx;
   unsigned match_end = 0;
@@ -2864,7 +2934,7 @@
   }
 
   bool would_apply (hb_would_apply_context_t *c,
-		    ChainContextApplyLookupContext &lookup_context) const
+		    const ChainContextApplyLookupContext &lookup_context) const
   {
     const auto &input = StructAfter<decltype (inputX)> (backtrack);
     const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
@@ -2876,7 +2946,8 @@
 					     lookup.arrayZ, lookup_context);
   }
 
-  bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+  bool apply (hb_ot_apply_context_t *c,
+	      const ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
     const auto &input = StructAfter<decltype (inputX)> (backtrack);
@@ -3042,7 +3113,8 @@
     ;
   }
 
-  bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+  bool would_apply (hb_would_apply_context_t *c,
+		    const ChainContextApplyLookupContext &lookup_context) const
   {
     return
     + hb_iter (rule)
@@ -3052,7 +3124,8 @@
     ;
   }
 
-  bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+  bool apply (hb_ot_apply_context_t *c,
+	      const ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
     return_trace (
@@ -3166,7 +3239,7 @@
   void closure_lookups (hb_closure_lookups_context_t *c) const
   {
     struct ChainContextClosureLookupContext lookup_context = {
-      {intersects_glyph, intersected_glyph},
+      {intersects_glyph, nullptr},
       ContextFormat::SimpleContext,
       {nullptr, nullptr, nullptr}
     };
@@ -3278,12 +3351,14 @@
     const ClassDef &input_class_def = this+inputClassDef;
     const ClassDef &lookahead_class_def = this+lookaheadClassDef;
 
+    hb_map_t caches[3] = {};
     struct ChainContextClosureLookupContext lookup_context = {
-      {intersects_class, intersected_class_glyphs},
+      {intersects_class, nullptr},
       ContextFormat::ClassBasedContext,
       {&backtrack_class_def,
        &input_class_def,
-       &lookahead_class_def}
+       &lookahead_class_def},
+      {&caches[0], &caches[1], &caches[2]}
     };
 
     hb_set_t retained_coverage_glyphs;
@@ -3321,12 +3396,16 @@
     const ClassDef &input_class_def = this+inputClassDef;
     const ClassDef &lookahead_class_def = this+lookaheadClassDef;
 
+    hb_map_t caches[3] = {};
+    intersected_class_cache_t intersected_cache;
     struct ChainContextClosureLookupContext lookup_context = {
       {intersects_class, intersected_class_glyphs},
       ContextFormat::ClassBasedContext,
       {&backtrack_class_def,
        &input_class_def,
-       &lookahead_class_def}
+       &lookahead_class_def},
+      {&caches[0], &caches[1], &caches[2]},
+      &intersected_cache
     };
 
     + hb_enumerate (ruleSet)
@@ -3352,12 +3431,14 @@
     const ClassDef &input_class_def = this+inputClassDef;
     const ClassDef &lookahead_class_def = this+lookaheadClassDef;
 
+    hb_map_t caches[3] = {};
     struct ChainContextClosureLookupContext lookup_context = {
-      {intersects_class, intersected_class_glyphs},
+      {intersects_class, nullptr},
       ContextFormat::ClassBasedContext,
       {&backtrack_class_def,
        &input_class_def,
-       &lookahead_class_def}
+       &lookahead_class_def},
+      {&caches[0], &caches[1], &caches[2]}
     };
 
     + hb_iter (ruleSet)
@@ -3587,7 +3668,7 @@
 
     const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
     struct ChainContextClosureLookupContext lookup_context = {
-      {intersects_coverage, intersected_coverage_glyphs},
+      {intersects_coverage, nullptr},
       ContextFormat::CoverageBasedContext,
       {this, this, this}
     };
@@ -3938,13 +4019,14 @@
   template <typename TLookup>
   void init (const TLookup &lookup)
   {
-    digest.init ();
-    lookup.collect_coverage (&digest);
-
     subtables.init ();
-    OT::hb_accelerate_subtables_context_t c_accelerate_subtables (subtables);
+    hb_accelerate_subtables_context_t c_accelerate_subtables (subtables);
     lookup.dispatch (&c_accelerate_subtables);
 
+    digest.init ();
+    for (auto& subtable : hb_iter (subtables))
+      digest.add (subtable.digest);
+
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
     cache_user_idx = c_accelerate_subtables.cache_user_idx;
     for (unsigned i = 0; i < subtables.length; i++)
@@ -3962,21 +4044,25 @@
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
     if (use_cache)
     {
-      for (unsigned int i = 0; i < subtables.length; i++)
-        if (subtables[i].apply_cached (c))
-	  return true;
+      return
+      + hb_iter (subtables)
+      | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); })
+      | hb_any
+      ;
     }
     else
 #endif
     {
-      for (unsigned int i = 0; i < subtables.length; i++)
-        if (subtables[i].apply (c))
-	  return true;
+      return
+      + hb_iter (subtables)
+      | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); })
+      | hb_any
+      ;
     }
     return false;
   }
 
-  bool cache_enter (OT::hb_ot_apply_context_t *c) const
+  bool cache_enter (hb_ot_apply_context_t *c) const
   {
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
     return cache_user_idx != (unsigned) -1 &&
@@ -3985,7 +4071,7 @@
     return false;
 #endif
   }
-  void cache_leave (OT::hb_ot_apply_context_t *c) const
+  void cache_leave (hb_ot_apply_context_t *c) const
   {
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
     subtables[cache_user_idx].cache_leave (c);
@@ -3993,8 +4079,8 @@
   }
 
 
+  hb_set_digest_t digest;
   private:
-  hb_set_digest_t digest;
   hb_accelerate_subtables_context_t::array_t subtables;
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   unsigned cache_user_idx = (unsigned) -1;
@@ -4255,11 +4341,11 @@
 			hb_set_t       *lookup_indexes /* IN/OUT */) const
   {
     hb_set_t visited_lookups, inactive_lookups;
-    OT::hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
+    hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
 
     c.set_recurse_func (TLookup::template dispatch_recurse_func<hb_closure_lookups_context_t>);
 
-    for (unsigned lookup_index : + hb_iter (lookup_indexes))
+    for (unsigned lookup_index : *lookup_indexes)
       reinterpret_cast<const TLookup &> (get_lookup (lookup_index)).closure_lookups (&c, lookup_index);
 
     hb_set_union (lookup_indexes, &visited_lookups);
@@ -4301,7 +4387,7 @@
     }
 #endif
 
-    for (unsigned i : feature_indices->iter())
+    for (unsigned i : hb_iter (feature_indices))
     {
       hb_tag_t tag =  get_feature_tag (i);
       if (tag == HB_TAG ('p', 'r', 'e', 'f'))

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1465,56 +1465,6 @@
   _hb_ot_layout_set_glyph_props (font, buffer);
 }
 
-void
-hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer,
-				    bool (*filter) (const hb_glyph_info_t *info))
-{
-  /* Merge clusters and delete filtered glyphs.
-   * NOTE! We can't use out-buffer as we have positioning data. */
-  unsigned int j = 0;
-  unsigned int count = buffer->len;
-  hb_glyph_info_t *info = buffer->info;
-  hb_glyph_position_t *pos = buffer->pos;
-  for (unsigned int i = 0; i < count; i++)
-  {
-    if (filter (&info[i]))
-    {
-      /* Merge clusters.
-       * Same logic as buffer->delete_glyph(), but for in-place removal. */
-
-      unsigned int cluster = info[i].cluster;
-      if (i + 1 < count && cluster == info[i + 1].cluster)
-	continue; /* Cluster survives; do nothing. */
-
-      if (j)
-      {
-	/* Merge cluster backward. */
-	if (cluster < info[j - 1].cluster)
-	{
-	  unsigned int mask = info[i].mask;
-	  unsigned int old_cluster = info[j - 1].cluster;
-	  for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
-	    buffer->set_cluster (info[k - 1], cluster, mask);
-	}
-	continue;
-      }
-
-      if (i + 1 < count)
-	buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */
-
-      continue;
-    }
-
-    if (j != i)
-    {
-      info[j] = info[i];
-      pos[j] = pos[i];
-    }
-    j++;
-  }
-  buffer->len = j;
-}
-
 /**
  * hb_ot_layout_lookup_substitute_closure:
  * @face: #hb_face_t to work upon
@@ -1867,7 +1817,7 @@
   while (buffer->idx < buffer->len && buffer->successful)
   {
     bool applied = false;
-    if (accel.may_have (buffer->cur().codepoint) &&
+    if (accel.digest.may_have (buffer->cur().codepoint) &&
 	(buffer->cur().mask & c->lookup_mask) &&
 	c->check_glyph_property (&buffer->cur(), c->lookup_props))
      {
@@ -1894,7 +1844,7 @@
   hb_buffer_t *buffer = c->buffer;
   do
   {
-    if (accel.may_have (buffer->cur().codepoint) &&
+    if (accel.digest.may_have (buffer->cur().codepoint) &&
 	(buffer->cur().mask & c->lookup_mask) &&
 	c->check_glyph_property (&buffer->cur(), c->lookup_props))
      ret |= accel.apply (c, false);
@@ -1908,15 +1858,16 @@
 }
 
 template <typename Proxy>
-static inline void
+static inline bool
 apply_string (OT::hb_ot_apply_context_t *c,
 	      const typename Proxy::Lookup &lookup,
 	      const OT::hb_ot_layout_lookup_accelerator_t &accel)
 {
+  bool ret = false;
   hb_buffer_t *buffer = c->buffer;
 
   if (unlikely (!buffer->len || !c->lookup_mask))
-    return;
+    return ret;
 
   c->set_lookup_props (lookup.get_props ());
 
@@ -1927,7 +1878,7 @@
       buffer->clear_output ();
 
     buffer->idx = 0;
-    apply_forward (c, accel);
+    ret = apply_forward (c, accel);
 
     if (!Proxy::always_inplace)
       buffer->sync ();
@@ -1937,8 +1888,10 @@
     /* in-place backward substitution/positioning */
     assert (!buffer->have_output);
     buffer->idx = buffer->len - 1;
-    apply_backward (c, accel);
+    ret = apply_backward (c, accel);
   }
+
+  return ret;
 }
 
 template <typename Proxy>
@@ -1957,23 +1910,42 @@
     const stage_map_t *stage = &stages[table_index][stage_index];
     for (; i < stage->last_lookup; i++)
     {
-      unsigned int lookup_index = lookups[table_index][i].index;
-      if (!buffer->message (font, "start lookup %d", lookup_index)) continue;
-      c.set_lookup_index (lookup_index);
-      c.set_lookup_mask (lookups[table_index][i].mask);
-      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);
+      auto &lookup = lookups[table_index][i];
 
-      apply_string<Proxy> (&c,
-			   proxy.table.get_lookup (lookup_index),
-			   proxy.accels[lookup_index]);
-      (void) buffer->message (font, "end lookup %d", lookup_index);
+      unsigned int lookup_index = lookup.index;
+      if (!buffer->message (font, "start lookup %d feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue;
+
+      /* c.digest is a digest of all the current glyphs in the buffer
+       * (plus some past glyphs).
+       *
+       * Only try applying the lookup if there is any overlap. */
+      if (proxy.accels[lookup_index].digest.may_have (c.digest))
+      {
+	c.set_lookup_index (lookup_index);
+	c.set_lookup_mask (lookup.mask);
+	c.set_auto_zwj (lookup.auto_zwj);
+	c.set_auto_zwnj (lookup.auto_zwnj);
+	c.set_random (lookup.random);
+	c.set_per_syllable (lookup.per_syllable);
+
+	apply_string<Proxy> (&c,
+			     proxy.table.get_lookup (lookup_index),
+			     proxy.accels[lookup_index]);
+      }
+      else
+	(void) buffer->message (font, "skipped lookup %d feature '%c%c%c%c' because no glyph matches", lookup_index, HB_UNTAG (lookup.feature_tag));
+
+      (void) buffer->message (font, "end lookup %d feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag));
     }
 
     if (stage->pause_func)
-      stage->pause_func (plan, font, buffer);
+    {
+      if (stage->pause_func (plan, font, buffer))
+      {
+	/* Refresh working buffer digest since buffer changed. */
+	c.digest = buffer->digest ();
+      }
+    }
   }
 }
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -102,10 +102,6 @@
 hb_ot_layout_substitute_start (hb_font_t    *font,
 			       hb_buffer_t  *buffer);
 
-HB_INTERNAL void
-hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer,
-				    bool (*filter) (const hb_glyph_info_t *info));
-
 namespace OT {
   struct hb_ot_apply_context_t;
   struct hb_ot_layout_lookup_accelerator_t;
@@ -552,7 +548,7 @@
   info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
 }
 
-static inline void
+static inline bool
 _hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
 			      hb_font_t *font HB_UNUSED,
 			      hb_buffer_t *buffer)
@@ -561,6 +557,7 @@
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)
     _hb_glyph_info_clear_substituted (&info[i]);
+  return false;
 }
 
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -45,7 +45,7 @@
 hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
 					  const hb_segment_properties_t &props_)
 {
-  memset (this, 0, sizeof (*this));
+  hb_memset (this, 0, sizeof (*this));
 
   feature_infos.init ();
   for (unsigned int table_index = 0; table_index < 2; table_index++)
@@ -133,7 +133,8 @@
 				  bool          auto_zwnj,
 				  bool          auto_zwj,
 				  bool          random,
-				  bool          per_syllable)
+				  bool          per_syllable,
+				  hb_tag_t      feature_tag)
 {
   unsigned int lookup_indices[32];
   unsigned int offset, len;
@@ -162,6 +163,7 @@
       lookup->auto_zwj = auto_zwj;
       lookup->random = random;
       lookup->per_syllable = per_syllable;
+      lookup->feature_tag = feature_tag;
     }
 
     offset += len;
@@ -212,24 +214,26 @@
   if (feature_infos.length)
   {
     feature_infos.qsort ();
+    auto *f = feature_infos.arrayZ;
     unsigned int j = 0;
-    for (unsigned int i = 1; i < feature_infos.length; i++)
-      if (feature_infos[i].tag != feature_infos[j].tag)
-	feature_infos[++j] = feature_infos[i];
+    unsigned count = feature_infos.length;
+    for (unsigned int i = 1; i < count; i++)
+      if (f[i].tag != f[j].tag)
+	f[++j] = f[i];
       else {
-	if (feature_infos[i].flags & F_GLOBAL) {
-	  feature_infos[j].flags |= F_GLOBAL;
-	  feature_infos[j].max_value = feature_infos[i].max_value;
-	  feature_infos[j].default_value = feature_infos[i].default_value;
+	if (f[i].flags & F_GLOBAL) {
+	  f[j].flags |= F_GLOBAL;
+	  f[j].max_value = f[i].max_value;
+	  f[j].default_value = f[i].default_value;
 	} else {
-	  if (feature_infos[j].flags & F_GLOBAL)
-	    feature_infos[j].flags ^= F_GLOBAL;
-	  feature_infos[j].max_value = hb_max (feature_infos[j].max_value, feature_infos[i].max_value);
+	  if (f[j].flags & F_GLOBAL)
+	    f[j].flags ^= F_GLOBAL;
+	  f[j].max_value = hb_max (f[j].max_value, f[i].max_value);
 	  /* Inherit default_value from j */
 	}
-	feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
-	feature_infos[j].stage[0] = hb_min (feature_infos[j].stage[0], feature_infos[i].stage[0]);
-	feature_infos[j].stage[1] = hb_min (feature_infos[j].stage[1], feature_infos[i].stage[1]);
+	f[j].flags |= (f[i].flags & F_HAS_FALLBACK);
+	f[j].stage[0] = hb_min (f[j].stage[0], f[i].stage[0]);
+	f[j].stage[1] = hb_min (f[j].stage[1], f[i].stage[1]);
       }
     feature_infos.shrink (j + 1);
   }
@@ -239,7 +243,8 @@
   static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
   unsigned int next_bit = hb_popcount (HB_GLYPH_FLAG_DEFINED) + 1;
 
-  for (unsigned int i = 0; i < feature_infos.length; i++)
+  unsigned count = feature_infos.length;
+  for (unsigned int i = 0; i < count; i++)
   {
     const feature_info_t *info = &feature_infos[i];
 
@@ -308,7 +313,7 @@
     map->_1_mask = (1u << map->shift) & map->mask;
     map->needs_fallback = !found;
   }
-  feature_infos.shrink (0); /* Done with these */
+  //feature_infos.shrink (0); /* Done with these */
 
 
   add_gsub_pause (nullptr);
@@ -317,6 +322,7 @@
   for (unsigned int table_index = 0; table_index < 2; table_index++)
   {
     /* Collect lookup indices for features */
+    auto &lookups = m.lookups[table_index];
 
     unsigned int stage_index = 0;
     unsigned int last_num_lookups = 0;
@@ -329,36 +335,39 @@
 		     key.variations_index[table_index],
 		     global_bit_mask);
 
-      for (unsigned i = 0; i < m.features.length; i++)
-	if (m.features[i].stage[table_index] == stage)
+      for (auto &feature : m.features)
+      {
+	if (feature.stage[table_index] == stage)
 	  add_lookups (m, table_index,
-		       m.features[i].index[table_index],
+		       feature.index[table_index],
 		       key.variations_index[table_index],
-		       m.features[i].mask,
-		       m.features[i].auto_zwnj,
-		       m.features[i].auto_zwj,
-		       m.features[i].random,
-		       m.features[i].per_syllable);
+		       feature.mask,
+		       feature.auto_zwnj,
+		       feature.auto_zwj,
+		       feature.random,
+		       feature.per_syllable,
+		       feature.tag);
+      }
 
       /* Sort lookups and merge duplicates */
-      if (last_num_lookups < m.lookups[table_index].length)
+      if (last_num_lookups < lookups.length)
       {
-	m.lookups[table_index].qsort (last_num_lookups, m.lookups[table_index].length);
+	lookups.as_array ().sub_array (last_num_lookups, lookups.length - last_num_lookups).qsort ();
 
 	unsigned int j = last_num_lookups;
-	for (unsigned int i = j + 1; i < m.lookups[table_index].length; i++)
-	  if (m.lookups[table_index][i].index != m.lookups[table_index][j].index)
-	    m.lookups[table_index][++j] = m.lookups[table_index][i];
+	for (unsigned int i = j + 1; i < lookups.length; i++)
+	  if (lookups.arrayZ[i].index != lookups.arrayZ[j].index)
+	    lookups.arrayZ[++j] = lookups.arrayZ[i];
 	  else
 	  {
-	    m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask;
-	    m.lookups[table_index][j].auto_zwnj &= m.lookups[table_index][i].auto_zwnj;
-	    m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj;
+	    lookups.arrayZ[j].mask |= lookups.arrayZ[i].mask;
+	    lookups.arrayZ[j].auto_zwnj &= lookups.arrayZ[i].auto_zwnj;
+	    lookups.arrayZ[j].auto_zwj &= lookups.arrayZ[i].auto_zwj;
 	  }
-	m.lookups[table_index].shrink (j + 1);
+	lookups.shrink (j + 1);
       }
 
-      last_num_lookups = m.lookups[table_index].length;
+      last_num_lookups = lookups.length;
 
       if (stage_index < stages[table_index].length && stages[table_index][stage_index].index == stage) {
 	hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push ();

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -69,6 +69,7 @@
     unsigned short random : 1;
     unsigned short per_syllable : 1;
     hb_mask_t mask;
+    hb_tag_t feature_tag;
 
     HB_INTERNAL static int cmp (const void *pa, const void *pb)
     {
@@ -78,7 +79,9 @@
     }
   };
 
-  typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
+  /* Pause functions return true if new glyph indices might have been
+   * added to the buffer.  This is used to update buffer digest. */
+  typedef bool (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
 
   struct stage_map_t {
     unsigned int last_lookup; /* Cumulative */
@@ -87,13 +90,13 @@
 
   void init ()
   {
-    memset (this, 0, sizeof (*this));
+    hb_memset (this, 0, sizeof (*this));
 
-    features.init ();
+    features.init0 ();
     for (unsigned int table_index = 0; table_index < 2; table_index++)
     {
-      lookups[table_index].init ();
-      stages[table_index].init ();
+      lookups[table_index].init0 ();
+      stages[table_index].init0 ();
     }
   }
   void fini ()
@@ -239,7 +242,8 @@
 				bool          auto_zwnj = true,
 				bool          auto_zwj = true,
 				bool          random = false,
-				bool          per_syllable = false);
+				bool          per_syllable = false,
+				hb_tag_t      feature_tag = HB_TAG(' ',' ',' ',' '));
 
   struct feature_info_t {
     hb_tag_t tag;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -77,11 +77,11 @@
 
     HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2);
     if (unlikely (!p)) return_trace (nullptr);
-    memcpy (p, percentScaleDown, HBINT16::static_size * 2);
+    hb_memcpy (p, percentScaleDown, HBINT16::static_size * 2);
 
     HBUINT16 *m = c->allocate_size<HBUINT16> (HBUINT16::static_size * 2);
     if (unlikely (!m)) return_trace (nullptr);
-    memcpy (m, minHeight, HBUINT16::static_size * 2);
+    hb_memcpy (m, minHeight, HBUINT16::static_size * 2);
 
     unsigned count = ARRAY_LENGTH (mathValueRecords);
     for (unsigned i = 0; i < count; i++)
@@ -786,7 +786,7 @@
     if (parts_count)
     {
       int64_t mult = font->dir_mult (direction);
-      for (auto _ : hb_zip (partRecords.sub_array (start_offset, parts_count),
+      for (auto _ : hb_zip (partRecords.as_array ().sub_array (start_offset, parts_count),
 			    hb_array (parts, *parts_count)))
 	_.first.extract (_.second, mult, font);
     }
@@ -855,7 +855,7 @@
     if (variants_count)
     {
       int64_t mult = font->dir_mult (direction);
-      for (auto _ : hb_zip (mathGlyphVariantRecord.sub_array (start_offset, variants_count),
+      for (auto _ : hb_zip (mathGlyphVariantRecord.as_array ().sub_array (start_offset, variants_count),
 			    hb_array (variants, *variants_count)))
 	_.second = {_.first.variantGlyph, font->em_mult (_.first.advanceMeasurement, mult)};
     }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -84,7 +84,7 @@
     {
       if (count)
       {
-	+ table->dataMaps.sub_array (start_offset, count)
+	+ table->dataMaps.as_array ().sub_array (start_offset, count)
 	| hb_map (&DataMap::get_tag)
 	| hb_map ([](hb_tag_t tag) { return (hb_ot_meta_tag_t) tag; })
 	| hb_sink (hb_array (entries, *count))

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -30,11 +30,56 @@
 #include "hb-open-type.hh"
 #include "hb-ot-name-language.hh"
 #include "hb-aat-layout.hh"
+#include "hb-utf.hh"
 
 
 namespace OT {
 
+template <typename in_utf_t, typename out_utf_t>
+inline unsigned int
+hb_ot_name_convert_utf (hb_bytes_t                       bytes,
+			unsigned int                    *text_size /* IN/OUT */,
+			typename out_utf_t::codepoint_t *text /* OUT */)
+{
+  unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t);
+  const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ;
+  const typename in_utf_t::codepoint_t *src_end = src + src_len;
 
+  typename out_utf_t::codepoint_t *dst = text;
+
+  hb_codepoint_t unicode;
+  const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+
+  if (text_size && *text_size)
+  {
+    (*text_size)--; /* Save room for NUL-termination. */
+    const typename out_utf_t::codepoint_t *dst_end = text + *text_size;
+
+    while (src < src_end && dst < dst_end)
+    {
+      const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
+      typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
+      if (dst_next == dst)
+	break; /* Out-of-room. */
+
+      dst = dst_next;
+      src = src_next;
+    }
+
+    *text_size = dst - text;
+    *dst = 0; /* NUL-terminate. */
+  }
+
+  /* Accumulate length of rest. */
+  unsigned int dst_len = dst - text;
+  while (src < src_end)
+  {
+    src = in_utf_t::next (src, src_end, &unicode, replacement);
+    dst_len += out_utf_t::encode_len (unicode);
+  }
+  return dst_len;
+}
+
 #define entry_score var.u16[0]
 #define entry_index var.u16[1]
 
@@ -97,12 +142,68 @@
     return UNSUPPORTED;
   }
 
-  NameRecord* copy (hb_serialize_context_t *c, const void *base) const
+  NameRecord* copy (hb_serialize_context_t *c, const void *base
+#ifdef HB_EXPERIMENTAL_API
+                    , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
+#endif
+		    ) const
   {
     TRACE_SERIALIZE (this);
+    HB_UNUSED auto snap = c->snapshot ();
     auto *out = c->embed (this);
     if (unlikely (!out)) return_trace (nullptr);
-    out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
+#ifdef HB_EXPERIMENTAL_API
+    hb_ot_name_record_ids_t record_ids (platformID, encodingID, languageID, nameID);
+    hb_bytes_t* name_bytes;
+
+    if (name_table_overrides->has (record_ids, &name_bytes)) {
+      hb_bytes_t encoded_bytes = *name_bytes;
+      char *name_str_utf16_be = nullptr;
+
+      if (platformID != 1)
+      {
+        unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr);
+  
+        text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf()
+        unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
+        name_str_utf16_be = (char *) hb_calloc (byte_len, 1);
+        if (!name_str_utf16_be)
+        {
+          c->revert (snap);
+          return_trace (nullptr);
+        }
+        hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size,
+                                                          (hb_utf16_be_t::codepoint_t *) name_str_utf16_be);
+  
+        unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
+        if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
+          c->revert (snap);
+          hb_free (name_str_utf16_be);
+          return_trace (nullptr);
+        }
+  
+        encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len);
+      }
+      else
+      {
+        // mac platform, copy the UTF-8 string(all ascii characters) as is
+        if (!c->check_assign (out->length, encoded_bytes.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
+          c->revert (snap);
+          return_trace (nullptr);
+        }
+      }
+
+      out->offset = 0;
+      c->push ();
+      encoded_bytes.copy (c);
+      c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0);
+      hb_free (name_str_utf16_be);
+    }
+    else
+#endif
+    {
+      out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
+    }
     return_trace (out);
   }
 
@@ -216,29 +317,61 @@
 	    hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
   bool serialize (hb_serialize_context_t *c,
 		  Iterator it,
-		  const void *src_string_pool)
+		  const void *src_string_pool
+#ifdef HB_EXPERIMENTAL_API
+                  , const hb_vector_t<hb_ot_name_record_ids_t>& insert_name_records
+		  , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
+#endif
+		  )
   {
     TRACE_SERIALIZE (this);
 
     if (unlikely (!c->extend_min ((*this))))  return_trace (false);
 
+    unsigned total_count = it.len ()
+#ifdef HB_EXPERIMENTAL_API
+        + insert_name_records.length
+#endif
+        ;
     this->format = 0;
-    this->count = it.len ();
+    if (!c->check_assign (this->count, total_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return false;
 
-    NameRecord *name_records = (NameRecord *) hb_calloc (it.len (), NameRecord::static_size);
+    NameRecord *name_records = (NameRecord *) hb_calloc (total_count, NameRecord::static_size);
     if (unlikely (!name_records)) return_trace (false);
 
-    hb_array_t<NameRecord> records (name_records, it.len ());
+    hb_array_t<NameRecord> records (name_records, total_count);
 
     for (const NameRecord& record : it)
     {
+      hb_memcpy (name_records, &record, NameRecord::static_size);
+      name_records++;
+    }
+
+#ifdef HB_EXPERIMENTAL_API
+    for (unsigned i = 0; i < insert_name_records.length; i++)
+    {
+      const hb_ot_name_record_ids_t& ids = insert_name_records[i];
+      NameRecord record;
+      record.platformID = ids.platform_id;
+      record.encodingID = ids.encoding_id;
+      record.languageID = ids.language_id;
+      record.nameID = ids.name_id;
+      record.length = 0; // handled in NameRecord copy()
+      record.offset = 0;
       memcpy (name_records, &record, NameRecord::static_size);
       name_records++;
     }
+#endif
 
     records.qsort ();
 
-    c->copy_all (records, src_string_pool);
+    c->copy_all (records,
+		 src_string_pool
+#ifdef HB_EXPERIMENTAL_API
+		 , name_table_overrides
+#endif
+		 );
     hb_free (records.arrayZ);
 
 
@@ -256,6 +389,11 @@
     name *name_prime = c->serializer->start_embed<name> ();
     if (unlikely (!name_prime)) return_trace (false);
 
+#ifdef HB_EXPERIMENTAL_API
+    const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides =
+        c->plan->name_table_overrides;
+#endif
+    
     auto it =
     + nameRecordZ.as_array (count)
     | hb_filter (c->plan->name_ids, &NameRecord::nameID)
@@ -265,10 +403,48 @@
           (c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY)
           || namerecord.isUnicode ();
     })
+#ifdef HB_EXPERIMENTAL_API
+    | hb_filter ([&] (const NameRecord& namerecord) {
+      if (name_table_overrides->is_empty ())
+        return true;
+      hb_ot_name_record_ids_t rec_ids (namerecord.platformID,
+                                       namerecord.encodingID,
+                                       namerecord.languageID,
+                                       namerecord.nameID);
+
+      hb_bytes_t *p;
+      if (name_table_overrides->has (rec_ids, &p) &&
+          (*p).length == 0)
+        return false;
+      return true;
+    })
+#endif
     ;
 
-    name_prime->serialize (c->serializer, it, std::addressof (this + stringOffset));
-    return_trace (name_prime->count);
+#ifdef HB_EXPERIMENTAL_API
+    hb_vector_t<hb_ot_name_record_ids_t> insert_name_records;
+    if (!name_table_overrides->is_empty ())
+    {
+      if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population ())))
+        return_trace (false);
+      for (const auto& record_ids : name_table_overrides->keys ())
+      {
+        if (name_table_overrides->get (record_ids).length == 0)
+          continue;
+        if (has_name_record_with_ids (record_ids))
+          continue;
+        insert_name_records.push (record_ids);
+      }
+    }
+#endif
+
+    return (name_prime->serialize (c->serializer, it,
+                                   std::addressof (this + stringOffset)
+#ifdef HB_EXPERIMENTAL_API
+                                   , insert_name_records
+                                   , name_table_overrides
+#endif
+                                   ));
   }
 
   bool sanitize_records (hb_sanitize_context_t *c) const
@@ -378,6 +554,23 @@
     hb_vector_t<hb_ot_name_entry_t> names;
   };
 
+  private:
+  // sometimes NameRecords are not sorted in the font file, so use linear search
+  // here
+  bool has_name_record_with_ids (const hb_ot_name_record_ids_t& record_ids) const
+  {
+    for (const auto& record : nameRecordZ.as_array (count))
+    {
+      if (record.platformID == record_ids.platform_id &&
+          record.encodingID == record_ids.encoding_id &&
+          record.languageID == record_ids.language_id &&
+          record.nameID == record_ids.name_id)
+        return true;
+    }
+    return false;
+  }
+
+  public:
   /* We only implement format 0 for now. */
   HBUINT16	format;		/* Format selector (=0/1). */
   HBUINT16	count;		/* Number of name records. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -64,52 +64,6 @@
   return (const hb_ot_name_entry_t *) name.names;
 }
 
-
-template <typename in_utf_t, typename out_utf_t>
-static inline unsigned int
-hb_ot_name_convert_utf (hb_bytes_t                       bytes,
-			unsigned int                    *text_size /* IN/OUT */,
-			typename out_utf_t::codepoint_t *text /* OUT */)
-{
-  unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t);
-  const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ;
-  const typename in_utf_t::codepoint_t *src_end = src + src_len;
-
-  typename out_utf_t::codepoint_t *dst = text;
-
-  hb_codepoint_t unicode;
-  const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
-
-  if (text_size && *text_size)
-  {
-    (*text_size)--; /* Same room for NUL-termination. */
-    const typename out_utf_t::codepoint_t *dst_end = text + *text_size;
-
-    while (src < src_end && dst < dst_end)
-    {
-      const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
-      typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
-      if (dst_next == dst)
-	break; /* Out-of-room. */
-
-      dst = dst_next;
-      src = src_next;
-    }
-
-    *text_size = dst - text;
-    *dst = 0; /* NUL-terminate. */
-  }
-
-  /* Accumulate length of rest. */
-  unsigned int dst_len = dst - text;
-  while (src < src_end)
-  {
-    src = in_utf_t::next (src, src_end, &unicode, replacement);
-    dst_len += out_utf_t::encode_len (unicode);
-  }
-  return dst_len;
-}
-
 template <typename utf_t>
 static inline unsigned int
 hb_ot_name_get_utf (hb_face_t       *face,
@@ -130,10 +84,10 @@
     hb_bytes_t bytes = name.get_name (idx);
 
     if (width == 2) /* UTF16-BE */
-      return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text);
+      return OT::hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text);
 
     if (width == 1) /* ASCII */
-      return hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text);
+      return OT::hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text);
   }
 
   if (text_size)
@@ -227,5 +181,4 @@
   return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
 }
 
-
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -212,18 +212,7 @@
     TRACE_SUBSET (this);
     OS2 *os2_prime = c->serializer->embed (this);
     if (unlikely (!os2_prime)) return_trace (false);
-    if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
-      return_trace (true);
 
-    /* when --gids option is not used, no need to do collect_mapping that is
-       * iterating all codepoints in each subtable, which is not efficient */
-    uint16_t min_cp, max_cp;
-    find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp);
-    os2_prime->usFirstCharIndex = min_cp;
-    os2_prime->usLastCharIndex = max_cp;
-
-    _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange);
-
     if (c->plan->user_axes_location->has (HB_TAG ('w','g','h','t')) &&
         !c->plan->pinned_at_default)
     {
@@ -244,6 +233,18 @@
         return_trace (false);
     }
 
+    if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
+      return_trace (true);
+
+    /* when --gids option is not used, no need to do collect_mapping that is
+       * iterating all codepoints in each subtable, which is not efficient */
+    uint16_t min_cp, max_cp;
+    find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp);
+    os2_prime->usFirstCharIndex = min_cp;
+    os2_prime->usLastCharIndex = max_cp;
+
+    _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange);
+
     return_trace (true);
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -78,7 +78,7 @@
 
   post::accelerator_t _post (c->plan->source);
 
-  hb_hashmap_t<hb_bytes_t, unsigned, true> glyph_name_to_new_index;
+  hb_hashmap_t<hb_bytes_t, uint32_t, true> glyph_name_to_new_index;
   for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
   {
     hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
@@ -85,7 +85,7 @@
     unsigned old_index = glyphNameIndex[old_gid];
 
     unsigned new_index;
-    const unsigned *new_index2;
+    const uint32_t *new_index2;
     if (old_index <= 257) new_index = old_index;
     else if (old_new_index_map.has (old_index, &new_index2))
     {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -84,7 +84,7 @@
     post *post_prime = c->allocate_min<post> ();
     if (unlikely (!post_prime))  return_trace (false);
 
-    memcpy (post_prime, this, post::min_size);
+    hb_memcpy (post_prime, this, post::min_size);
     if (!glyph_names)
       return_trace (c->check_assign (post_prime->version.major, 3,
                                      HB_SERIALIZE_ERROR_INT_OVERFLOW)); // Version 3 does not have any glyph names.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -341,7 +341,7 @@
     {
       unsigned int end;
       for (end = buffer->idx + 1; end < count; end++)
-	if (unlikely (_hb_glyph_info_is_unicode_mark (&buffer->info[end])))
+	if (_hb_glyph_info_is_unicode_mark (&buffer->info[end]))
 	  break;
 
       if (end < count)

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -91,9 +91,11 @@
   script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
   script_fallback_mark_positioning = shaper->fallback_position;
 
+#ifndef HB_NO_AAT_SHAPE
   /* https://github.com/harfbuzz/harfbuzz/issues/1528 */
   if (apply_morx && shaper != &_hb_ot_shaper_default)
     shaper = &_hb_ot_shaper_dumber;
+#endif
 }
 
 void
@@ -864,7 +866,7 @@
     }
   }
   else
-    hb_ot_layout_delete_glyphs_inplace (buffer, _hb_glyph_info_is_default_ignorable);
+    buffer->delete_glyphs_inplace (_hb_glyph_info_is_default_ignorable);
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -51,7 +51,7 @@
 
   bool equal (const hb_ot_shape_plan_key_t *other)
   {
-    return 0 == memcmp (this, other, sizeof (*this));
+    return 0 == hb_memcmp (this, other, sizeof (*this));
   }
 };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -161,22 +161,23 @@
 };
 
 
-static void
+static bool
 arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer);
 
-static void
+static bool
 record_stch (const hb_ot_shape_plan_t *plan,
 	     hb_font_t *font,
 	     hb_buffer_t *buffer);
 
-static void
+static bool
 deallocate_buffer_var (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer)
 {
   HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
+  return false;
 }
 
 static void
@@ -412,19 +413,19 @@
   setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
 }
 
-static void
+static bool
 arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer)
 {
 #ifdef HB_NO_OT_SHAPER_ARABIC_FALLBACK
-  return;
+  return false;
 #endif
 
   const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
 
   if (!arabic_plan->do_fallback)
-    return;
+    return false;
 
 retry:
   arabic_fallback_plan_t *fallback_plan = arabic_plan->fallback_plan;
@@ -440,6 +441,7 @@
   }
 
   arabic_fallback_plan_shape (fallback_plan, font, buffer);
+  return true;
 }
 
 /*
@@ -450,7 +452,7 @@
  * marks can use it as well.
  */
 
-static void
+static bool
 record_stch (const hb_ot_shape_plan_t *plan,
 	     hb_font_t *font HB_UNUSED,
 	     hb_buffer_t *buffer)
@@ -457,7 +459,7 @@
 {
   const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
   if (!arabic_plan->has_stch)
-    return;
+    return false;
 
   /* 'stch' feature was just applied.  Look for anything that multiplied,
    * and record it for stch treatment later.  Note that rtlm, frac, etc
@@ -473,6 +475,7 @@
       info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED;
       buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH;
     }
+  return false;
 }
 
 static void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-default.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-default.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-default.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -49,6 +49,7 @@
   true, /* fallback_position */
 };
 
+#ifndef HB_NO_AAT_SHAPE
 /* Same as default but no mark advance zeroing / fallback positioning.
  * Dumbest shaper ever, basically. */
 const hb_ot_shaper_t _hb_ot_shaper_dumber =
@@ -68,6 +69,7 @@
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
+#endif
 
 
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -53,7 +53,7 @@
 };
 
 
-#line 57 "hb-ot-shaper-indic-machine.hh"
+#line 54 "hb-ot-shaper-indic-machine.hh"
 #define indic_syllable_machine_ex_A 9u
 #define indic_syllable_machine_ex_C 1u
 #define indic_syllable_machine_ex_CM 16u
@@ -61,6 +61,7 @@
 #define indic_syllable_machine_ex_DOTTEDCIRCLE 11u
 #define indic_syllable_machine_ex_H 4u
 #define indic_syllable_machine_ex_M 7u
+#define indic_syllable_machine_ex_MPst 13u
 #define indic_syllable_machine_ex_N 3u
 #define indic_syllable_machine_ex_PLACEHOLDER 10u
 #define indic_syllable_machine_ex_RS 12u
@@ -75,261 +76,295 @@
 #define indic_syllable_machine_ex_ZWNJ 5u
 
 
-#line 79 "hb-ot-shaper-indic-machine.hh"
+#line 75 "hb-ot-shaper-indic-machine.hh"
 static const unsigned char _indic_syllable_machine_trans_keys[] = {
-	8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 8u, 8u, 8u, 
-	5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 12u, 4u, 12u, 8u, 8u, 5u, 7u, 
-	5u, 8u, 4u, 8u, 4u, 8u, 4u, 12u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 
-	4u, 8u, 5u, 8u, 8u, 8u, 1u, 18u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 
-	5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 1u, 15u, 1u, 15u, 3u, 9u, 
-	4u, 9u, 5u, 9u, 4u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 
-	3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 
-	5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 
-	4u, 9u, 5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 8u, 
-	3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 
-	5u, 9u, 1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u, 
-	5u, 9u, 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 12u, 4u, 8u, 3u, 16u, 
-	3u, 16u, 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 
-	1u, 15u, 1u, 15u, 3u, 9u, 4u, 9u, 5u, 9u, 3u, 16u, 4u, 9u, 5u, 9u, 
-	5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 12u, 5u, 9u, 
-	9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, 
-	1u, 15u, 0
+	8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 
+	8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 
+	8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, 
+	5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 5u, 13u, 8u, 8u, 1u, 18u, 
+	3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, 
+	1u, 15u, 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, 
+	5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 3u, 16u, 3u, 16u, 4u, 16u, 
+	1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 
+	1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, 5u, 9u, 
+	5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 13u, 3u, 16u, 3u, 16u, 
+	4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 
+	1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, 
+	5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 13u, 4u, 13u, 3u, 16u, 3u, 16u, 
+	4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, 
+	1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, 
+	5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 13u, 5u, 13u, 
+	5u, 13u, 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, 
+	5u, 9u, 1u, 15u, 0
 };
 
 static const char _indic_syllable_machine_key_spans[] = {
-	1, 5, 3, 4, 5, 9, 5, 1, 
-	3, 4, 5, 9, 9, 9, 1, 3, 
-	4, 5, 5, 9, 1, 3, 4, 5, 
-	5, 4, 1, 18, 14, 14, 13, 15, 
-	5, 5, 1, 5, 15, 15, 15, 7, 
-	6, 5, 6, 5, 7, 5, 14, 14, 
-	14, 14, 13, 15, 14, 14, 13, 15, 
-	5, 1, 5, 15, 15, 7, 6, 5, 
-	6, 5, 5, 7, 5, 14, 14, 5, 
-	14, 14, 13, 15, 14, 15, 5, 1, 
-	5, 15, 15, 7, 6, 5, 14, 6, 
-	5, 5, 7, 5, 14, 9, 5, 14, 
-	14, 13, 15, 14, 15, 5, 1, 5, 
-	15, 15, 7, 6, 5, 14, 6, 5, 
-	5, 7, 5, 16, 14, 16, 9, 5, 
-	1, 5, 15, 7, 5, 5, 1, 5, 
-	15
+	1, 10, 9, 9, 1, 10, 10, 10, 
+	1, 9, 9, 1, 10, 10, 10, 10, 
+	1, 9, 9, 1, 10, 10, 10, 1, 
+	9, 9, 1, 10, 10, 9, 1, 18, 
+	14, 14, 13, 15, 5, 5, 1, 5, 
+	15, 15, 15, 11, 10, 9, 9, 10, 
+	5, 7, 5, 14, 14, 14, 14, 13, 
+	15, 14, 14, 13, 15, 5, 1, 5, 
+	15, 15, 11, 10, 9, 9, 10, 5, 
+	5, 7, 5, 14, 14, 10, 14, 14, 
+	13, 15, 14, 15, 5, 1, 5, 15, 
+	15, 11, 10, 9, 9, 14, 10, 5, 
+	5, 7, 5, 14, 10, 10, 14, 14, 
+	13, 15, 14, 15, 5, 1, 5, 15, 
+	15, 11, 10, 9, 9, 14, 10, 5, 
+	5, 7, 5, 16, 14, 16, 10, 9, 
+	9, 1, 5, 15, 7, 5, 5, 1, 
+	5, 15
 };
 
 static const short _indic_syllable_machine_index_offsets[] = {
-	0, 2, 8, 12, 17, 23, 33, 39, 
-	41, 45, 50, 56, 66, 76, 86, 88, 
-	92, 97, 103, 109, 119, 121, 125, 130, 
-	136, 142, 147, 149, 168, 183, 198, 212, 
-	228, 234, 240, 242, 248, 264, 280, 296, 
-	304, 311, 317, 324, 330, 338, 344, 359, 
-	374, 389, 404, 418, 434, 449, 464, 478, 
-	494, 500, 502, 508, 524, 540, 548, 555, 
-	561, 568, 574, 580, 588, 594, 609, 624, 
-	630, 645, 660, 674, 690, 705, 721, 727, 
-	729, 735, 751, 767, 775, 782, 788, 803, 
-	810, 816, 822, 830, 836, 851, 861, 867, 
-	882, 897, 911, 927, 942, 958, 964, 966, 
-	972, 988, 1004, 1012, 1019, 1025, 1040, 1047, 
-	1053, 1059, 1067, 1073, 1090, 1105, 1122, 1132, 
-	1138, 1140, 1146, 1162, 1170, 1176, 1182, 1184, 
-	1190
+	0, 2, 13, 23, 33, 35, 46, 57, 
+	68, 70, 80, 90, 92, 103, 114, 125, 
+	136, 138, 148, 158, 160, 171, 182, 193, 
+	195, 205, 215, 217, 228, 239, 249, 251, 
+	270, 285, 300, 314, 330, 336, 342, 344, 
+	350, 366, 382, 398, 410, 421, 431, 441, 
+	452, 458, 466, 472, 487, 502, 517, 532, 
+	546, 562, 577, 592, 606, 622, 628, 630, 
+	636, 652, 668, 680, 691, 701, 711, 722, 
+	728, 734, 742, 748, 763, 778, 789, 804, 
+	819, 833, 849, 864, 880, 886, 888, 894, 
+	910, 926, 938, 949, 959, 969, 984, 995, 
+	1001, 1007, 1015, 1021, 1036, 1047, 1058, 1073, 
+	1088, 1102, 1118, 1133, 1149, 1155, 1157, 1163, 
+	1179, 1195, 1207, 1218, 1228, 1238, 1253, 1264, 
+	1270, 1276, 1284, 1290, 1307, 1322, 1339, 1350, 
+	1360, 1370, 1372, 1378, 1394, 1402, 1408, 1414, 
+	1416, 1422
 };
 
 static const unsigned char _indic_syllable_machine_indicies[] = {
-	1, 0, 2, 3, 3, 4, 1, 0, 
-	3, 3, 4, 0, 3, 3, 4, 1, 
-	0, 5, 3, 3, 4, 1, 0, 2, 
-	3, 3, 4, 1, 0, 0, 0, 6, 
-	0, 8, 9, 9, 10, 11, 7, 11, 
-	7, 9, 9, 10, 7, 9, 9, 10, 
-	11, 7, 12, 9, 9, 10, 11, 7, 
-	8, 9, 9, 10, 11, 7, 7, 7, 
-	13, 7, 8, 9, 9, 10, 11, 7, 
-	7, 7, 14, 7, 16, 17, 17, 18, 
-	19, 15, 15, 15, 20, 15, 19, 15, 
-	17, 17, 18, 21, 17, 17, 18, 19, 
-	15, 16, 17, 17, 18, 19, 15, 22, 
-	17, 17, 18, 19, 15, 24, 25, 25, 
-	26, 27, 23, 23, 23, 28, 23, 27, 
-	23, 25, 25, 26, 23, 25, 25, 26, 
-	27, 23, 24, 25, 25, 26, 27, 23, 
-	29, 25, 25, 26, 27, 23, 17, 17, 
-	18, 1, 0, 31, 30, 33, 34, 35, 
-	36, 37, 38, 18, 19, 39, 40, 40, 
-	20, 32, 41, 42, 43, 44, 45, 32, 
-	47, 48, 49, 50, 4, 1, 51, 46, 
-	46, 6, 46, 46, 46, 52, 46, 53, 
-	48, 54, 54, 4, 1, 51, 46, 46, 
-	46, 46, 46, 46, 52, 46, 48, 54, 
-	54, 4, 1, 51, 46, 46, 46, 46, 
-	46, 46, 52, 46, 33, 46, 46, 46, 
-	55, 56, 46, 1, 51, 46, 46, 46, 
-	46, 46, 33, 46, 57, 57, 46, 1, 
-	51, 46, 51, 46, 46, 58, 51, 46, 
-	51, 46, 51, 46, 46, 46, 51, 46, 
-	33, 46, 59, 46, 57, 57, 46, 1, 
-	51, 46, 46, 46, 46, 46, 33, 46, 
-	33, 46, 46, 46, 57, 57, 46, 1, 
-	51, 46, 46, 46, 46, 46, 33, 46, 
-	33, 46, 46, 46, 57, 56, 46, 1, 
-	51, 46, 46, 46, 46, 46, 33, 46, 
-	60, 61, 62, 62, 4, 1, 51, 46, 
-	61, 62, 62, 4, 1, 51, 46, 62, 
-	62, 4, 1, 51, 46, 63, 64, 64, 
-	4, 1, 51, 46, 55, 65, 46, 1, 
-	51, 46, 55, 46, 57, 57, 46, 1, 
-	51, 46, 57, 65, 46, 1, 51, 46, 
-	47, 48, 54, 54, 4, 1, 51, 46, 
-	46, 46, 46, 46, 46, 52, 46, 47, 
-	48, 49, 54, 4, 1, 51, 46, 46, 
-	6, 46, 46, 46, 52, 46, 67, 68, 
-	69, 70, 10, 11, 71, 66, 66, 14, 
-	66, 66, 66, 72, 66, 73, 68, 74, 
-	70, 10, 11, 71, 66, 66, 66, 66, 
-	66, 66, 72, 66, 68, 74, 70, 10, 
-	11, 71, 66, 66, 66, 66, 66, 66, 
-	72, 66, 75, 66, 66, 66, 76, 77, 
-	66, 11, 71, 66, 66, 66, 66, 66, 
-	75, 66, 78, 68, 79, 80, 10, 11, 
-	71, 66, 66, 13, 66, 66, 66, 72, 
-	66, 81, 68, 74, 74, 10, 11, 71, 
-	66, 66, 66, 66, 66, 66, 72, 66, 
-	68, 74, 74, 10, 11, 71, 66, 66, 
-	66, 66, 66, 66, 72, 66, 75, 66, 
-	66, 66, 82, 77, 66, 11, 71, 66, 
-	66, 66, 66, 66, 75, 66, 71, 66, 
-	66, 83, 71, 66, 71, 66, 71, 66, 
-	66, 66, 71, 66, 75, 66, 84, 66, 
-	82, 82, 66, 11, 71, 66, 66, 66, 
-	66, 66, 75, 66, 75, 66, 66, 66, 
-	82, 82, 66, 11, 71, 66, 66, 66, 
-	66, 66, 75, 66, 85, 86, 87, 87, 
-	10, 11, 71, 66, 86, 87, 87, 10, 
-	11, 71, 66, 87, 87, 10, 11, 71, 
-	66, 88, 89, 89, 10, 11, 71, 66, 
-	76, 90, 66, 11, 71, 66, 82, 82, 
-	66, 11, 71, 66, 76, 66, 82, 82, 
-	66, 11, 71, 66, 82, 90, 66, 11, 
-	71, 66, 78, 68, 74, 74, 10, 11, 
-	71, 66, 66, 66, 66, 66, 66, 72, 
-	66, 78, 68, 79, 74, 10, 11, 71, 
-	66, 66, 13, 66, 66, 66, 72, 66, 
-	8, 9, 9, 10, 11, 66, 67, 68, 
-	74, 70, 10, 11, 71, 66, 66, 66, 
-	66, 66, 66, 72, 66, 92, 36, 93, 
-	93, 18, 19, 39, 91, 91, 91, 91, 
-	91, 91, 43, 91, 36, 93, 93, 18, 
-	19, 39, 91, 91, 91, 91, 91, 91, 
-	43, 91, 94, 91, 91, 91, 95, 96, 
-	91, 19, 39, 91, 91, 91, 91, 91, 
-	94, 91, 35, 36, 97, 98, 18, 19, 
-	39, 91, 91, 20, 91, 91, 91, 43, 
-	91, 94, 91, 91, 91, 99, 96, 91, 
-	19, 39, 91, 91, 91, 91, 91, 94, 
-	91, 39, 91, 91, 100, 39, 91, 39, 
-	91, 39, 91, 91, 91, 39, 91, 94, 
-	91, 101, 91, 99, 99, 91, 19, 39, 
-	91, 91, 91, 91, 91, 94, 91, 94, 
-	91, 91, 91, 99, 99, 91, 19, 39, 
-	91, 91, 91, 91, 91, 94, 91, 102, 
-	103, 104, 104, 18, 19, 39, 91, 103, 
-	104, 104, 18, 19, 39, 91, 104, 104, 
-	18, 19, 39, 91, 35, 36, 93, 93, 
-	18, 19, 39, 91, 91, 91, 91, 91, 
-	91, 43, 91, 105, 106, 106, 18, 19, 
-	39, 91, 95, 107, 91, 19, 39, 91, 
-	99, 99, 91, 19, 39, 91, 95, 91, 
-	99, 99, 91, 19, 39, 91, 99, 107, 
-	91, 19, 39, 91, 35, 36, 97, 93, 
-	18, 19, 39, 91, 91, 20, 91, 91, 
-	91, 43, 91, 16, 17, 17, 18, 19, 
-	108, 108, 108, 20, 108, 16, 17, 17, 
-	18, 19, 108, 110, 111, 112, 113, 26, 
-	27, 114, 109, 109, 28, 109, 109, 109, 
-	115, 109, 116, 111, 113, 113, 26, 27, 
-	114, 109, 109, 109, 109, 109, 109, 115, 
-	109, 111, 113, 113, 26, 27, 114, 109, 
-	109, 109, 109, 109, 109, 115, 109, 117, 
-	109, 109, 109, 118, 119, 109, 27, 114, 
-	109, 109, 109, 109, 109, 117, 109, 110, 
-	111, 112, 40, 26, 27, 114, 109, 109, 
-	28, 109, 109, 109, 115, 109, 117, 109, 
-	109, 109, 120, 119, 109, 27, 114, 109, 
-	109, 109, 109, 109, 117, 109, 114, 109, 
-	109, 121, 114, 109, 114, 109, 114, 109, 
-	109, 109, 114, 109, 117, 109, 122, 109, 
-	120, 120, 109, 27, 114, 109, 109, 109, 
-	109, 109, 117, 109, 117, 109, 109, 109, 
-	120, 120, 109, 27, 114, 109, 109, 109, 
-	109, 109, 117, 109, 123, 124, 125, 125, 
-	26, 27, 114, 109, 124, 125, 125, 26, 
-	27, 114, 109, 125, 125, 26, 27, 114, 
-	109, 110, 111, 113, 113, 26, 27, 114, 
-	109, 109, 109, 109, 109, 109, 115, 109, 
-	126, 127, 127, 26, 27, 114, 109, 118, 
-	128, 109, 27, 114, 109, 120, 120, 109, 
-	27, 114, 109, 118, 109, 120, 120, 109, 
-	27, 114, 109, 120, 128, 109, 27, 114, 
-	109, 33, 34, 35, 36, 97, 93, 18, 
-	19, 39, 40, 40, 20, 91, 91, 33, 
-	43, 91, 47, 129, 49, 50, 4, 1, 
-	51, 46, 46, 6, 46, 46, 46, 52, 
-	46, 33, 34, 35, 36, 130, 131, 18, 
-	132, 133, 46, 40, 20, 46, 46, 33, 
-	43, 46, 16, 134, 134, 18, 132, 51, 
-	46, 46, 20, 46, 133, 46, 46, 135, 
-	133, 46, 133, 46, 133, 46, 46, 46, 
-	133, 46, 33, 46, 59, 16, 134, 134, 
-	18, 132, 51, 46, 46, 46, 46, 46, 
-	33, 46, 137, 136, 138, 138, 136, 31, 
-	139, 136, 138, 138, 136, 31, 139, 136, 
-	139, 136, 136, 140, 139, 136, 139, 136, 
-	139, 136, 136, 136, 139, 136, 33, 108, 
-	108, 108, 108, 108, 108, 108, 108, 40, 
-	108, 108, 108, 108, 33, 108, 0
+	1, 0, 2, 3, 3, 4, 5, 0, 
+	0, 0, 0, 4, 0, 3, 3, 4, 
+	6, 0, 0, 0, 0, 4, 0, 3, 
+	3, 4, 5, 0, 0, 0, 0, 4, 
+	0, 4, 0, 7, 3, 3, 4, 5, 
+	0, 0, 0, 0, 4, 0, 2, 3, 
+	3, 4, 5, 0, 0, 0, 8, 4, 
+	0, 10, 11, 11, 12, 13, 9, 9, 
+	9, 9, 12, 9, 14, 9, 11, 11, 
+	12, 15, 9, 9, 9, 9, 12, 9, 
+	11, 11, 12, 13, 9, 9, 9, 9, 
+	12, 9, 12, 9, 16, 11, 11, 12, 
+	13, 9, 9, 9, 9, 12, 9, 10, 
+	11, 11, 12, 13, 9, 9, 9, 17, 
+	12, 9, 10, 11, 11, 12, 13, 9, 
+	9, 9, 18, 12, 9, 20, 21, 21, 
+	22, 23, 19, 19, 19, 24, 22, 19, 
+	25, 19, 21, 21, 22, 27, 26, 26, 
+	26, 26, 22, 26, 21, 21, 22, 23, 
+	19, 19, 19, 19, 22, 19, 22, 26, 
+	20, 21, 21, 22, 23, 19, 19, 19, 
+	19, 22, 19, 28, 21, 21, 22, 23, 
+	19, 19, 19, 19, 22, 19, 30, 31, 
+	31, 32, 33, 29, 29, 29, 34, 32, 
+	29, 35, 29, 31, 31, 32, 36, 29, 
+	29, 29, 29, 32, 29, 31, 31, 32, 
+	33, 29, 29, 29, 29, 32, 29, 32, 
+	29, 30, 31, 31, 32, 33, 29, 29, 
+	29, 29, 32, 29, 37, 31, 31, 32, 
+	33, 29, 29, 29, 29, 32, 29, 21, 
+	21, 22, 38, 0, 0, 0, 0, 22, 
+	0, 40, 39, 42, 43, 44, 45, 46, 
+	47, 22, 23, 48, 49, 49, 24, 22, 
+	50, 51, 52, 53, 54, 41, 56, 57, 
+	58, 59, 4, 5, 60, 55, 55, 8, 
+	4, 55, 55, 61, 55, 62, 57, 63, 
+	63, 4, 5, 60, 55, 55, 55, 4, 
+	55, 55, 61, 55, 57, 63, 63, 4, 
+	5, 60, 55, 55, 55, 4, 55, 55, 
+	61, 55, 42, 55, 55, 55, 64, 65, 
+	55, 1, 60, 55, 55, 55, 55, 55, 
+	42, 55, 66, 66, 55, 1, 60, 55, 
+	60, 55, 55, 67, 60, 55, 60, 55, 
+	60, 55, 55, 55, 60, 55, 42, 55, 
+	68, 55, 66, 66, 55, 1, 60, 55, 
+	55, 55, 55, 55, 42, 55, 42, 55, 
+	55, 55, 66, 66, 55, 1, 60, 55, 
+	55, 55, 55, 55, 42, 55, 42, 55, 
+	55, 55, 66, 65, 55, 1, 60, 55, 
+	55, 55, 55, 55, 42, 55, 69, 70, 
+	71, 71, 4, 5, 60, 55, 55, 55, 
+	4, 55, 70, 71, 71, 4, 5, 60, 
+	55, 55, 55, 4, 55, 71, 71, 4, 
+	5, 60, 55, 55, 55, 4, 55, 60, 
+	55, 55, 67, 60, 55, 55, 55, 4, 
+	55, 72, 73, 73, 4, 5, 60, 55, 
+	55, 55, 4, 55, 64, 74, 55, 1, 
+	60, 55, 64, 55, 66, 66, 55, 1, 
+	60, 55, 66, 74, 55, 1, 60, 55, 
+	56, 57, 63, 63, 4, 5, 60, 55, 
+	55, 55, 4, 55, 55, 61, 55, 56, 
+	57, 58, 63, 4, 5, 60, 55, 55, 
+	8, 4, 55, 55, 61, 55, 76, 77, 
+	78, 79, 12, 13, 80, 75, 75, 18, 
+	12, 75, 75, 81, 75, 82, 77, 83, 
+	79, 12, 13, 80, 75, 75, 75, 12, 
+	75, 75, 81, 75, 77, 83, 79, 12, 
+	13, 80, 75, 75, 75, 12, 75, 75, 
+	81, 75, 84, 75, 75, 75, 85, 86, 
+	75, 14, 80, 75, 75, 75, 75, 75, 
+	84, 75, 87, 77, 88, 89, 12, 13, 
+	80, 75, 75, 17, 12, 75, 75, 81, 
+	75, 90, 77, 83, 83, 12, 13, 80, 
+	75, 75, 75, 12, 75, 75, 81, 75, 
+	77, 83, 83, 12, 13, 80, 75, 75, 
+	75, 12, 75, 75, 81, 75, 84, 75, 
+	75, 75, 91, 86, 75, 14, 80, 75, 
+	75, 75, 75, 75, 84, 75, 80, 75, 
+	75, 92, 80, 75, 80, 75, 80, 75, 
+	75, 75, 80, 75, 84, 75, 93, 75, 
+	91, 91, 75, 14, 80, 75, 75, 75, 
+	75, 75, 84, 75, 84, 75, 75, 75, 
+	91, 91, 75, 14, 80, 75, 75, 75, 
+	75, 75, 84, 75, 94, 95, 96, 96, 
+	12, 13, 80, 75, 75, 75, 12, 75, 
+	95, 96, 96, 12, 13, 80, 75, 75, 
+	75, 12, 75, 96, 96, 12, 13, 80, 
+	75, 75, 75, 12, 75, 80, 75, 75, 
+	92, 80, 75, 75, 75, 12, 75, 97, 
+	98, 98, 12, 13, 80, 75, 75, 75, 
+	12, 75, 85, 99, 75, 14, 80, 75, 
+	91, 91, 75, 14, 80, 75, 85, 75, 
+	91, 91, 75, 14, 80, 75, 91, 99, 
+	75, 14, 80, 75, 87, 77, 83, 83, 
+	12, 13, 80, 75, 75, 75, 12, 75, 
+	75, 81, 75, 87, 77, 88, 83, 12, 
+	13, 80, 75, 75, 17, 12, 75, 75, 
+	81, 75, 10, 11, 11, 12, 13, 75, 
+	75, 75, 75, 12, 75, 76, 77, 83, 
+	79, 12, 13, 80, 75, 75, 75, 12, 
+	75, 75, 81, 75, 101, 45, 102, 102, 
+	22, 23, 48, 100, 100, 100, 22, 100, 
+	100, 52, 100, 45, 102, 102, 22, 23, 
+	48, 100, 100, 100, 22, 100, 100, 52, 
+	100, 103, 100, 100, 100, 104, 105, 100, 
+	25, 48, 100, 100, 100, 100, 100, 103, 
+	100, 44, 45, 106, 107, 22, 23, 48, 
+	100, 100, 24, 22, 100, 100, 52, 100, 
+	103, 100, 100, 100, 108, 105, 100, 25, 
+	48, 100, 100, 100, 100, 100, 103, 100, 
+	48, 100, 100, 109, 48, 100, 48, 100, 
+	48, 100, 100, 100, 48, 100, 103, 100, 
+	110, 100, 108, 108, 100, 25, 48, 100, 
+	100, 100, 100, 100, 103, 100, 103, 100, 
+	100, 100, 108, 108, 100, 25, 48, 100, 
+	100, 100, 100, 100, 103, 100, 111, 112, 
+	113, 113, 22, 23, 48, 100, 100, 100, 
+	22, 100, 112, 113, 113, 22, 23, 48, 
+	100, 100, 100, 22, 100, 113, 113, 22, 
+	23, 48, 100, 100, 100, 22, 100, 48, 
+	100, 100, 109, 48, 100, 100, 100, 22, 
+	100, 44, 45, 102, 102, 22, 23, 48, 
+	100, 100, 100, 22, 100, 100, 52, 100, 
+	114, 115, 115, 22, 23, 48, 100, 100, 
+	100, 22, 100, 104, 116, 100, 25, 48, 
+	100, 108, 108, 100, 25, 48, 100, 104, 
+	100, 108, 108, 100, 25, 48, 100, 108, 
+	116, 100, 25, 48, 100, 44, 45, 106, 
+	102, 22, 23, 48, 100, 100, 24, 22, 
+	100, 100, 52, 100, 20, 21, 21, 22, 
+	23, 117, 117, 117, 24, 22, 117, 20, 
+	21, 21, 22, 23, 117, 117, 117, 117, 
+	22, 117, 119, 120, 121, 122, 32, 33, 
+	123, 118, 118, 34, 32, 118, 118, 124, 
+	118, 125, 120, 122, 122, 32, 33, 123, 
+	118, 118, 118, 32, 118, 118, 124, 118, 
+	120, 122, 122, 32, 33, 123, 118, 118, 
+	118, 32, 118, 118, 124, 118, 126, 118, 
+	118, 118, 127, 128, 118, 35, 123, 118, 
+	118, 118, 118, 118, 126, 118, 119, 120, 
+	121, 49, 32, 33, 123, 118, 118, 34, 
+	32, 118, 118, 124, 118, 126, 118, 118, 
+	118, 129, 128, 118, 35, 123, 118, 118, 
+	118, 118, 118, 126, 118, 123, 118, 118, 
+	130, 123, 118, 123, 118, 123, 118, 118, 
+	118, 123, 118, 126, 118, 131, 118, 129, 
+	129, 118, 35, 123, 118, 118, 118, 118, 
+	118, 126, 118, 126, 118, 118, 118, 129, 
+	129, 118, 35, 123, 118, 118, 118, 118, 
+	118, 126, 118, 132, 133, 134, 134, 32, 
+	33, 123, 118, 118, 118, 32, 118, 133, 
+	134, 134, 32, 33, 123, 118, 118, 118, 
+	32, 118, 134, 134, 32, 33, 123, 118, 
+	118, 118, 32, 118, 123, 118, 118, 130, 
+	123, 118, 118, 118, 32, 118, 119, 120, 
+	122, 122, 32, 33, 123, 118, 118, 118, 
+	32, 118, 118, 124, 118, 135, 136, 136, 
+	32, 33, 123, 118, 118, 118, 32, 118, 
+	127, 137, 118, 35, 123, 118, 129, 129, 
+	118, 35, 123, 118, 127, 118, 129, 129, 
+	118, 35, 123, 118, 129, 137, 118, 35, 
+	123, 118, 42, 43, 44, 45, 106, 102, 
+	22, 23, 48, 49, 49, 24, 22, 100, 
+	42, 52, 100, 56, 138, 58, 59, 4, 
+	5, 60, 55, 55, 8, 4, 55, 55, 
+	61, 55, 42, 43, 44, 45, 139, 140, 
+	22, 141, 142, 55, 49, 24, 22, 55, 
+	42, 52, 55, 20, 143, 143, 22, 141, 
+	60, 55, 55, 24, 22, 55, 60, 55, 
+	55, 67, 60, 55, 55, 55, 22, 55, 
+	142, 55, 55, 144, 142, 55, 55, 55, 
+	22, 55, 142, 55, 142, 55, 55, 55, 
+	142, 55, 42, 55, 68, 20, 143, 143, 
+	22, 141, 60, 55, 55, 55, 22, 55, 
+	42, 55, 146, 145, 147, 147, 145, 40, 
+	148, 145, 147, 147, 145, 40, 148, 145, 
+	148, 145, 145, 149, 148, 145, 148, 145, 
+	148, 145, 145, 145, 148, 145, 42, 117, 
+	117, 117, 117, 117, 117, 117, 117, 49, 
+	117, 117, 117, 117, 42, 117, 0
 };
 
 static const unsigned char _indic_syllable_machine_trans_targs[] = {
-	27, 33, 38, 2, 39, 45, 46, 27, 
-	55, 8, 61, 56, 68, 69, 72, 27, 
-	77, 15, 83, 78, 86, 27, 91, 27, 
-	100, 21, 106, 101, 109, 114, 27, 125, 
-	27, 28, 48, 73, 75, 93, 94, 79, 
-	95, 115, 116, 87, 123, 128, 27, 29, 
-	31, 5, 47, 34, 42, 30, 1, 32, 
-	36, 0, 35, 37, 40, 41, 3, 43, 
-	4, 44, 27, 49, 51, 12, 71, 57, 
-	64, 50, 6, 52, 66, 59, 53, 11, 
-	70, 54, 7, 58, 60, 62, 63, 9, 
-	65, 10, 67, 27, 74, 17, 76, 89, 
-	81, 13, 92, 14, 80, 82, 84, 85, 
-	16, 88, 18, 90, 27, 27, 96, 98, 
-	19, 23, 102, 110, 97, 99, 112, 104, 
-	20, 103, 105, 107, 108, 22, 111, 24, 
-	113, 117, 118, 122, 119, 120, 25, 121, 
-	27, 124, 26, 126, 127
+	31, 37, 42, 2, 43, 46, 4, 50, 
+	51, 31, 60, 9, 66, 69, 61, 11, 
+	74, 75, 78, 31, 83, 17, 89, 92, 
+	93, 84, 31, 19, 98, 31, 107, 24, 
+	113, 116, 117, 108, 26, 122, 127, 31, 
+	134, 31, 32, 53, 79, 81, 100, 101, 
+	85, 102, 123, 124, 94, 132, 137, 31, 
+	33, 35, 6, 52, 38, 47, 34, 1, 
+	36, 40, 0, 39, 41, 44, 45, 3, 
+	48, 5, 49, 31, 54, 56, 14, 77, 
+	62, 70, 55, 7, 57, 72, 64, 58, 
+	13, 76, 59, 8, 63, 65, 67, 68, 
+	10, 71, 12, 73, 31, 80, 20, 82, 
+	96, 87, 15, 99, 16, 86, 88, 90, 
+	91, 18, 95, 21, 97, 31, 31, 103, 
+	105, 22, 27, 109, 118, 104, 106, 120, 
+	111, 23, 110, 112, 114, 115, 25, 119, 
+	28, 121, 125, 126, 131, 128, 129, 29, 
+	130, 31, 133, 30, 135, 136
 };
 
 static const char _indic_syllable_machine_trans_actions[] = {
-	1, 0, 2, 0, 2, 2, 2, 3, 
-	2, 0, 2, 0, 2, 2, 2, 4, 
-	2, 0, 5, 0, 5, 6, 2, 7, 
-	2, 0, 2, 0, 2, 2, 8, 0, 
-	11, 2, 2, 5, 0, 12, 12, 0, 
-	2, 5, 2, 5, 2, 0, 13, 2, 
-	0, 0, 2, 0, 2, 2, 0, 2, 
+	1, 0, 2, 0, 2, 0, 0, 2, 
+	2, 3, 2, 0, 2, 0, 0, 0, 
+	2, 2, 2, 4, 2, 0, 5, 0, 
+	5, 0, 6, 0, 2, 7, 2, 0, 
+	2, 0, 2, 0, 0, 2, 0, 8, 
+	0, 11, 2, 2, 5, 0, 12, 12, 
+	0, 2, 5, 2, 5, 2, 0, 13, 
+	2, 0, 0, 2, 0, 2, 2, 0, 
+	2, 2, 0, 0, 2, 2, 2, 0, 
+	0, 0, 2, 14, 2, 0, 0, 2, 
+	0, 2, 2, 0, 2, 2, 2, 2, 
+	0, 2, 2, 0, 0, 2, 2, 2, 
+	0, 0, 0, 2, 15, 5, 0, 5, 
+	2, 2, 0, 5, 0, 0, 2, 5, 
+	5, 0, 0, 0, 2, 16, 17, 2, 
+	0, 0, 0, 0, 2, 2, 2, 2, 
 	2, 0, 0, 2, 2, 2, 0, 0, 
-	0, 2, 14, 2, 0, 0, 2, 0, 
-	2, 2, 0, 2, 2, 2, 2, 0, 
-	2, 2, 0, 0, 2, 2, 2, 0, 
-	0, 0, 2, 15, 5, 0, 5, 2, 
-	2, 0, 5, 0, 0, 2, 5, 5, 
-	0, 0, 0, 2, 16, 17, 2, 0, 
-	0, 0, 0, 2, 2, 2, 2, 2, 
-	0, 0, 2, 2, 2, 0, 0, 0, 
-	2, 0, 18, 18, 0, 0, 0, 0, 
-	19, 2, 0, 0, 0
+	0, 2, 0, 18, 18, 0, 0, 0, 
+	0, 19, 2, 0, 0, 0
 };
 
 static const char _indic_syllable_machine_to_state_actions[] = {
@@ -336,7 +371,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 9, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 9, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
@@ -349,7 +384,8 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0
 };
 
 static const char _indic_syllable_machine_from_state_actions[] = {
@@ -356,7 +392,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 10, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 10, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
@@ -369,34 +405,36 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0
 };
 
 static const short _indic_syllable_machine_eof_trans[] = {
-	1, 1, 1, 1, 1, 1, 8, 8, 
-	8, 8, 8, 8, 8, 16, 16, 22, 
-	16, 16, 16, 24, 24, 24, 24, 24, 
-	24, 1, 31, 0, 47, 47, 47, 47, 
-	47, 47, 47, 47, 47, 47, 47, 47, 
-	47, 47, 47, 47, 47, 47, 47, 47, 
-	67, 67, 67, 67, 67, 67, 67, 67, 
-	67, 67, 67, 67, 67, 67, 67, 67, 
-	67, 67, 67, 67, 67, 67, 67, 67, 
-	67, 92, 92, 92, 92, 92, 92, 92, 
-	92, 92, 92, 92, 92, 92, 92, 92, 
-	92, 92, 92, 92, 92, 109, 109, 110, 
-	110, 110, 110, 110, 110, 110, 110, 110, 
-	110, 110, 110, 110, 110, 110, 110, 110, 
-	110, 110, 110, 92, 47, 47, 47, 47, 
-	47, 47, 47, 137, 137, 137, 137, 137, 
-	109
+	1, 1, 1, 1, 1, 1, 1, 10, 
+	10, 10, 10, 10, 10, 10, 10, 20, 
+	20, 27, 20, 27, 20, 20, 30, 30, 
+	30, 30, 30, 30, 30, 1, 40, 0, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 56, 56, 56, 
+	56, 56, 56, 56, 56, 76, 76, 76, 
+	76, 76, 76, 76, 76, 76, 76, 76, 
+	76, 76, 76, 76, 76, 76, 76, 76, 
+	76, 76, 76, 76, 76, 76, 76, 101, 
+	101, 101, 101, 101, 101, 101, 101, 101, 
+	101, 101, 101, 101, 101, 101, 101, 101, 
+	101, 101, 101, 101, 118, 118, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 119, 119, 119, 119, 119, 
+	119, 119, 119, 101, 56, 56, 56, 56, 
+	56, 56, 56, 56, 146, 146, 146, 146, 
+	146, 118
 };
 
-static const int indic_syllable_machine_start = 27;
-static const int indic_syllable_machine_first_final = 27;
+static const int indic_syllable_machine_start = 31;
+static const int indic_syllable_machine_first_final = 31;
 static const int indic_syllable_machine_error = -1;
 
-static const int indic_syllable_machine_en_main = 27;
+static const int indic_syllable_machine_en_main = 31;
 
 
 #line 58 "hb-ot-shaper-indic-machine.rl"
@@ -403,7 +441,7 @@
 
 
 
-#line 117 "hb-ot-shaper-indic-machine.rl"
+#line 118 "hb-ot-shaper-indic-machine.rl"
 
 
 #define found_syllable(syllable_type) \
@@ -412,7 +450,7 @@
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \
-    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+    if (syllable_serial == 16) syllable_serial = 1; \
   } HB_STMT_END
 
 inline void
@@ -422,7 +460,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 426 "hb-ot-shaper-indic-machine.hh"
+#line 453 "hb-ot-shaper-indic-machine.hh"
 	{
 	cs = indic_syllable_machine_start;
 	ts = 0;
@@ -430,7 +468,7 @@
 	act = 0;
 	}
 
-#line 137 "hb-ot-shaper-indic-machine.rl"
+#line 138 "hb-ot-shaper-indic-machine.rl"
 
 
   p = 0;
@@ -438,7 +476,7 @@
 
   unsigned int syllable_serial = 1;
   
-#line 442 "hb-ot-shaper-indic-machine.hh"
+#line 465 "hb-ot-shaper-indic-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -452,7 +490,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 456 "hb-ot-shaper-indic-machine.hh"
+#line 477 "hb-ot-shaper-indic-machine.hh"
 	}
 
 	_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -475,51 +513,51 @@
 	{te = p+1;}
 	break;
 	case 11:
-#line 113 "hb-ot-shaper-indic-machine.rl"
+#line 114 "hb-ot-shaper-indic-machine.rl"
 	{te = p+1;{ found_syllable (indic_non_indic_cluster); }}
 	break;
 	case 13:
-#line 108 "hb-ot-shaper-indic-machine.rl"
+#line 109 "hb-ot-shaper-indic-machine.rl"
 	{te = p;p--;{ found_syllable (indic_consonant_syllable); }}
 	break;
 	case 14:
-#line 109 "hb-ot-shaper-indic-machine.rl"
+#line 110 "hb-ot-shaper-indic-machine.rl"
 	{te = p;p--;{ found_syllable (indic_vowel_syllable); }}
 	break;
 	case 17:
-#line 110 "hb-ot-shaper-indic-machine.rl"
+#line 111 "hb-ot-shaper-indic-machine.rl"
 	{te = p;p--;{ found_syllable (indic_standalone_cluster); }}
 	break;
 	case 19:
-#line 111 "hb-ot-shaper-indic-machine.rl"
+#line 112 "hb-ot-shaper-indic-machine.rl"
 	{te = p;p--;{ found_syllable (indic_symbol_cluster); }}
 	break;
 	case 15:
-#line 112 "hb-ot-shaper-indic-machine.rl"
+#line 113 "hb-ot-shaper-indic-machine.rl"
 	{te = p;p--;{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
 	break;
 	case 16:
-#line 113 "hb-ot-shaper-indic-machine.rl"
+#line 114 "hb-ot-shaper-indic-machine.rl"
 	{te = p;p--;{ found_syllable (indic_non_indic_cluster); }}
 	break;
 	case 1:
-#line 108 "hb-ot-shaper-indic-machine.rl"
+#line 109 "hb-ot-shaper-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }}
 	break;
 	case 3:
-#line 109 "hb-ot-shaper-indic-machine.rl"
+#line 110 "hb-ot-shaper-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }}
 	break;
 	case 7:
-#line 110 "hb-ot-shaper-indic-machine.rl"
+#line 111 "hb-ot-shaper-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }}
 	break;
 	case 8:
-#line 111 "hb-ot-shaper-indic-machine.rl"
+#line 112 "hb-ot-shaper-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }}
 	break;
 	case 4:
-#line 112 "hb-ot-shaper-indic-machine.rl"
+#line 113 "hb-ot-shaper-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
 	break;
 	case 6:
@@ -540,19 +578,19 @@
 	case 18:
 #line 1 "NONE"
 	{te = p+1;}
-#line 108 "hb-ot-shaper-indic-machine.rl"
+#line 109 "hb-ot-shaper-indic-machine.rl"
 	{act = 1;}
 	break;
 	case 5:
 #line 1 "NONE"
 	{te = p+1;}
-#line 112 "hb-ot-shaper-indic-machine.rl"
+#line 113 "hb-ot-shaper-indic-machine.rl"
 	{act = 5;}
 	break;
 	case 12:
 #line 1 "NONE"
 	{te = p+1;}
-#line 113 "hb-ot-shaper-indic-machine.rl"
+#line 114 "hb-ot-shaper-indic-machine.rl"
 	{act = 6;}
 	break;
 #line 559 "hb-ot-shaper-indic-machine.hh"
@@ -564,7 +602,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 568 "hb-ot-shaper-indic-machine.hh"
+#line 566 "hb-ot-shaper-indic-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -580,7 +618,7 @@
 
 	}
 
-#line 145 "hb-ot-shaper-indic-machine.rl"
+#line 146 "hb-ot-shaper-indic-machine.rl"
 
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl	2022-12-18 01:06:39 UTC (rev 65304)
@@ -74,6 +74,7 @@
 export PLACEHOLDER = 10;
 export DOTTEDCIRCLE = 11;
 export RS    = 12;
+export MPst  = 13;
 export Repha = 14;
 export Ra    = 15;
 export CM    = 16;
@@ -88,7 +89,7 @@
 
 cn = c.ZWJ?.n?;
 symbol = Symbol.N?;
-matra_group = z*.M.N?.H?;
+matra_group = z*.(M | SM? MPst).N?.H?;
 syllable_tail = (z?.SM.SM?.ZWNJ?)? (A | VD)*;
 halant_group = (z?.H.(ZWJ.N?)?);
 final_halant_group = halant_group | H.ZWNJ;
@@ -122,7 +123,7 @@
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \
-    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+    if (syllable_serial == 16) syllable_serial = 1; \
   } HB_STMT_END
 
 inline void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-table.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-table.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -42,6 +42,7 @@
 #define OT_PLACEHOLDER I_Cat(PLACEHOLDER)
 #define OT_DOTTEDCIRCLE I_Cat(DOTTEDCIRCLE)
 #define OT_RS I_Cat(RS)
+#define OT_MPst I_Cat(MPst)
 #define OT_Repha I_Cat(Repha)
 #define OT_Ra I_Cat(Ra)
 #define OT_CM I_Cat(CM)
@@ -80,9 +81,10 @@
 #define _OT_CS   OT_CS           /*   2 chars; CS */
 #define _OT_DC   OT_DOTTEDCIRCLE /*   1 chars; DOTTEDCIRCLE */
 #define _OT_H    OT_H            /*  11 chars; H */
-#define _OT_M    OT_M            /* 143 chars; M */
+#define _OT_M    OT_M            /* 142 chars; M */
 #define _OT_MH   OT_MH           /*   1 chars; MH */
 #define _OT_ML   OT_ML           /*   1 chars; ML */
+#define _OT_MP   OT_MPst         /*   1 chars; MPst */
 #define _OT_MR   OT_MR           /*   1 chars; MR */
 #define _OT_MW   OT_MW           /*   2 chars; MW */
 #define _OT_MY   OT_MY           /*   3 chars; MY */
@@ -200,7 +202,7 @@
   /* 0A28 */  _(C,C),  _(X,X),  _(C,C),  _(C,C),  _(C,C),  _(C,C),  _(C,C),  _(C,C),
   /* 0A30 */  _(R,C),  _(X,X),  _(C,C),  _(C,C),  _(X,X),  _(C,C),  _(C,C),  _(X,X),
   /* 0A38 */  _(C,C),  _(C,C),  _(X,X),  _(X,X),  _(N,X),  _(X,X), _(M,AP), _(M,LM),
-  /* 0A40 */ _(M,AP), _(M,AP), _(M,AP),  _(X,X),  _(X,X),  _(X,X),  _(X,X), _(M,AP),
+  /* 0A40 */_(MP,AP), _(M,AP), _(M,AP),  _(X,X),  _(X,X),  _(X,X),  _(X,X), _(M,AP),
   /* 0A48 */ _(M,AP),  _(X,X),  _(X,X), _(M,AP), _(M,AP),  _(H,B),  _(X,X),  _(X,X),
   /* 0A50 */  _(X,X),  _(M,B),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),
   /* 0A58 */  _(X,X),  _(C,C),  _(C,C),  _(C,C),  _(C,C),  _(X,X),  _(C,C),  _(X,X),
@@ -451,15 +453,12 @@
   /* Grantha */
 
   /* 11300 */  _(X,X),_(SM,SM),_(SM,SM),_(SM,SM),  _(X,X),  _(X,X),  _(X,X),  _(X,X),
-  /* 11308 */  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),
-  /* 11310 */  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),
-  /* 11318 */  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),
-  /* 11320 */  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),
-  /* 11328 */  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),
-  /* 11330 */  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),  _(X,X),
+
+#define indic_offset_0x11338u 1720
+
   /* 11338 */  _(X,X),  _(X,X),  _(X,X),  _(N,X),  _(N,X),  _(X,X),  _(X,X),  _(X,X),
 
-}; /* Table items: 1776; occupancy: 69% */
+}; /* Table items: 1728; occupancy: 71% */
 
 uint16_t
 hb_indic_get_categories (hb_codepoint_t u)
@@ -497,7 +496,8 @@
       break;
 
     case 0x11u:
-      if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x1133Fu)) return indic_table[u - 0x11300u + indic_offset_0x11300u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x11307u)) return indic_table[u - 0x11300u + indic_offset_0x11300u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x11338u, 0x1133Fu)) return indic_table[u - 0x11338u + indic_offset_0x11338u];
       break;
 
     default:
@@ -519,6 +519,7 @@
 #undef _OT_M
 #undef _OT_MH
 #undef _OT_ML
+#undef _OT_MP
 #undef _OT_MR
 #undef _OT_MW
 #undef _OT_MY

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -223,15 +223,15 @@
   INDIC_BASIC_FEATURES = INDIC_INIT, /* Don't forget to update this! */
 };
 
-static void
+static bool
 setup_syllables_indic (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer);
-static void
+static bool
 initial_reordering_indic (const hb_ot_shape_plan_t *plan,
 			  hb_font_t *font,
 			  hb_buffer_t *buffer);
-static void
+static bool
 final_reordering_indic (const hb_ot_shape_plan_t *plan,
 			hb_font_t *font,
 			hb_buffer_t *buffer);
@@ -413,7 +413,7 @@
     set_indic_properties (info[i]);
 }
 
-static void
+static bool
 setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
 		       hb_font_t *font HB_UNUSED,
 		       hb_buffer_t *buffer)
@@ -422,6 +422,7 @@
   find_syllables_indic (buffer);
   foreach_syllable (buffer, start, end)
     buffer->unsafe_to_break (start, end);
+  return false;
 }
 
 static int
@@ -714,6 +715,9 @@
 	    }
 	}
       } else if (info[i].indic_position() != POS_SMVD) {
+	if (info[i].indic_category() == I_Cat(MPst) &&
+	    i > start && info[i - 1].indic_category() == I_Cat(SM))
+	  info[i - 1].indic_position() = info[i].indic_position();
 	last_pos = (indic_position_t) info[i].indic_position();
       }
     }
@@ -729,7 +733,7 @@
 	  if (info[j].indic_position() < POS_SMVD)
 	    info[j].indic_position() = info[i].indic_position();
 	last = i;
-      } else if (info[i].indic_category() == I_Cat(M))
+      } else if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
 	last = i;
   }
 
@@ -742,14 +746,40 @@
 
     /* Sit tight, rock 'n roll! */
     hb_stable_sort (info + start, end - start, compare_indic_order);
-    /* Find base again */
+
+    /* Find base again; also flip left-matra sequence. */
+    unsigned first_left_matra = end;
+    unsigned last_left_matra = end;
     base = end;
     for (unsigned int i = start; i < end; i++)
+    {
       if (info[i].indic_position() == POS_BASE_C)
       {
 	base = i;
 	break;
       }
+      else if (info[i].indic_position() == POS_PRE_M)
+      {
+        if (first_left_matra == end)
+	  first_left_matra = i;
+	last_left_matra = i;
+      }
+    }
+    /* https://github.com/harfbuzz/harfbuzz/issues/3863 */
+    if (first_left_matra < last_left_matra)
+    {
+      /* No need to merge clusters, handled later. */
+      buffer->reverse_range (first_left_matra, last_left_matra + 1);
+      /* Reverse back nuktas, etc. */
+      unsigned i = first_left_matra;
+      for (unsigned j = i; j <= last_left_matra; j++)
+	if (FLAG_UNSAFE (info[j].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
+	{
+	  buffer->reverse_range (i, j + 1);
+	  i = j + 1;
+	}
+    }
+
     /* Things are out-of-control for post base positions, they may shuffle
      * around like crazy.  In old-spec mode, we move halants around, so in
      * that case merge all clusters after base.  Otherwise, check the sort
@@ -955,25 +985,29 @@
   }
 }
 
-static void
+static bool
 initial_reordering_indic (const hb_ot_shape_plan_t *plan,
 			  hb_font_t *font,
 			  hb_buffer_t *buffer)
 {
+  bool ret = false;
   if (!buffer->message (font, "start reordering indic initial"))
-    return;
+    return ret;
 
   update_consonant_positions_indic (plan, font, buffer);
-  hb_syllabic_insert_dotted_circles (font, buffer,
-				     indic_broken_cluster,
-				     I_Cat(DOTTEDCIRCLE),
-				     I_Cat(Repha),
-				     POS_END);
+  if (hb_syllabic_insert_dotted_circles (font, buffer,
+					 indic_broken_cluster,
+					 I_Cat(DOTTEDCIRCLE),
+					 I_Cat(Repha),
+					 POS_END))
+    ret = true;
 
   foreach_syllable (buffer, start, end)
     initial_reordering_syllable_indic (plan, font->face, buffer, start, end);
 
   (void) buffer->message (font, "end reordering indic initial");
+
+  return ret;
 }
 
 static void
@@ -1116,7 +1150,7 @@
     {
     search:
       while (new_pos > start &&
-	     !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(H))))))
+	     !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)) | FLAG (I_Cat(H))))))
 	new_pos--;
 
       /* If we found no Halant we are done.
@@ -1316,7 +1350,8 @@
 	  unlikely (is_halant (info[new_reph_pos])))
       {
 	for (unsigned int i = base + 1; i < new_reph_pos; i++)
-	  if (info[i].indic_category() == I_Cat(M)) {
+	  if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
+	  {
 	    /* Ok, got it. */
 	    new_reph_pos--;
 	  }
@@ -1376,7 +1411,7 @@
 	  if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
 	  {
 	    while (new_pos > start &&
-		   !(is_one_of (info[new_pos - 1], FLAG(I_Cat(M)) | FLAG (I_Cat(H)))))
+		   !(is_one_of (info[new_pos - 1], FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)) | FLAG (I_Cat(H)))))
 	      new_pos--;
 	  }
 
@@ -1439,13 +1474,13 @@
 }
 
 
-static void
+static bool
 final_reordering_indic (const hb_ot_shape_plan_t *plan,
 			hb_font_t *font HB_UNUSED,
 			hb_buffer_t *buffer)
 {
   unsigned int count = buffer->len;
-  if (unlikely (!count)) return;
+  if (unlikely (!count)) return false;
 
   if (buffer->message (font, "start reordering indic final")) {
     foreach_syllable (buffer, start, end)
@@ -1455,6 +1490,8 @@
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
   HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
+
+  return false;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -48,7 +48,7 @@
 };
 
 
-#line 52 "hb-ot-shaper-khmer-machine.hh"
+#line 49 "hb-ot-shaper-khmer-machine.hh"
 #define khmer_syllable_machine_ex_C 1u
 #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u
 #define khmer_syllable_machine_ex_H 4u
@@ -66,7 +66,7 @@
 #define khmer_syllable_machine_ex_ZWNJ 5u
 
 
-#line 70 "hb-ot-shaper-khmer-machine.hh"
+#line 65 "hb-ot-shaper-khmer-machine.hh"
 static const unsigned char _khmer_syllable_machine_trans_keys[] = {
 	5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 
 	5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 
@@ -284,7 +284,7 @@
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \
-    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+    if (syllable_serial == 16) syllable_serial = 1; \
   } HB_STMT_END
 
 inline void
@@ -294,7 +294,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 298 "hb-ot-shaper-khmer-machine.hh"
+#line 287 "hb-ot-shaper-khmer-machine.hh"
 	{
 	cs = khmer_syllable_machine_start;
 	ts = 0;
@@ -310,7 +310,7 @@
 
   unsigned int syllable_serial = 1;
   
-#line 314 "hb-ot-shaper-khmer-machine.hh"
+#line 299 "hb-ot-shaper-khmer-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -324,7 +324,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 328 "hb-ot-shaper-khmer-machine.hh"
+#line 311 "hb-ot-shaper-khmer-machine.hh"
 	}
 
 	_keys = _khmer_syllable_machine_trans_keys + (cs<<1);
@@ -394,7 +394,7 @@
 #line 98 "hb-ot-shaper-khmer-machine.rl"
 	{act = 3;}
 	break;
-#line 398 "hb-ot-shaper-khmer-machine.hh"
+#line 368 "hb-ot-shaper-khmer-machine.hh"
 	}
 
 _again:
@@ -403,7 +403,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 407 "hb-ot-shaper-khmer-machine.hh"
+#line 375 "hb-ot-shaper-khmer-machine.hh"
 	}
 
 	if ( ++p != pe )

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl	2022-12-18 01:06:39 UTC (rev 65304)
@@ -107,7 +107,7 @@
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \
-    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+    if (syllable_serial == 16) syllable_serial = 1; \
   } HB_STMT_END
 
 inline void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -89,11 +89,11 @@
   info.khmer_category() = (khmer_category_t) (type & 0xFFu);
 }
 
-static void
+static bool
 setup_syllables_khmer (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer);
-static void
+static bool
 reorder_khmer (const hb_ot_shape_plan_t *plan,
 	       hb_font_t *font,
 	       hb_buffer_t *buffer);
@@ -192,7 +192,7 @@
     set_khmer_properties (info[i]);
 }
 
-static void
+static bool
 setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
 		       hb_font_t *font HB_UNUSED,
 		       hb_buffer_t *buffer)
@@ -201,6 +201,7 @@
   find_syllables_khmer (buffer);
   foreach_syllable (buffer, start, end)
     buffer->unsafe_to_break (start, end);
+  return false;
 }
 
 
@@ -303,17 +304,19 @@
   }
 }
 
-static void
+static bool
 reorder_khmer (const hb_ot_shape_plan_t *plan,
 	       hb_font_t *font,
 	       hb_buffer_t *buffer)
 {
+  bool ret = false;
   if (buffer->message (font, "start reordering khmer"))
   {
-    hb_syllabic_insert_dotted_circles (font, buffer,
-				       khmer_broken_cluster,
-				       K_Cat(DOTTEDCIRCLE),
-				       (unsigned) -1);
+    if (hb_syllabic_insert_dotted_circles (font, buffer,
+					   khmer_broken_cluster,
+					   K_Cat(DOTTEDCIRCLE),
+					   (unsigned) -1))
+      ret = true;
 
     foreach_syllable (buffer, start, end)
       reorder_syllable_khmer (plan, font->face, buffer, start, end);
@@ -320,6 +323,8 @@
     (void) buffer->message (font, "end reordering khmer");
   }
   HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
+
+  return ret;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -50,7 +50,7 @@
 };
 
 
-#line 54 "hb-ot-shaper-myanmar-machine.hh"
+#line 51 "hb-ot-shaper-myanmar-machine.hh"
 #define myanmar_syllable_machine_ex_A 9u
 #define myanmar_syllable_machine_ex_As 32u
 #define myanmar_syllable_machine_ex_C 1u
@@ -77,7 +77,7 @@
 #define myanmar_syllable_machine_ex_ZWNJ 5u
 
 
-#line 81 "hb-ot-shaper-myanmar-machine.hh"
+#line 76 "hb-ot-shaper-myanmar-machine.hh"
 static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
 	1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, 
 	5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u, 
@@ -433,7 +433,7 @@
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \
-    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+    if (syllable_serial == 16) syllable_serial = 1; \
   } HB_STMT_END
 
 inline void
@@ -443,7 +443,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 447 "hb-ot-shaper-myanmar-machine.hh"
+#line 436 "hb-ot-shaper-myanmar-machine.hh"
 	{
 	cs = myanmar_syllable_machine_start;
 	ts = 0;
@@ -459,7 +459,7 @@
 
   unsigned int syllable_serial = 1;
   
-#line 463 "hb-ot-shaper-myanmar-machine.hh"
+#line 448 "hb-ot-shaper-myanmar-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -473,7 +473,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 477 "hb-ot-shaper-myanmar-machine.hh"
+#line 460 "hb-ot-shaper-myanmar-machine.hh"
 	}
 
 	_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -519,7 +519,7 @@
 #line 113 "hb-ot-shaper-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
 	break;
-#line 523 "hb-ot-shaper-myanmar-machine.hh"
+#line 498 "hb-ot-shaper-myanmar-machine.hh"
 	}
 
 _again:
@@ -528,7 +528,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 532 "hb-ot-shaper-myanmar-machine.hh"
+#line 505 "hb-ot-shaper-myanmar-machine.hh"
 	}
 
 	if ( ++p != pe )

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl	2022-12-18 01:06:39 UTC (rev 65304)
@@ -122,7 +122,7 @@
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \
-    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+    if (syllable_serial == 16) syllable_serial = 1; \
   } HB_STMT_END
 
 inline void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -98,11 +98,11 @@
 }
 
 
-static void
+static bool
 setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
 			 hb_font_t *font,
 			 hb_buffer_t *buffer);
-static void
+static bool
 reorder_myanmar (const hb_ot_shape_plan_t *plan,
 		 hb_font_t *font,
 		 hb_buffer_t *buffer);
@@ -150,7 +150,7 @@
     set_myanmar_properties (info[i]);
 }
 
-static void
+static bool
 setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
 			 hb_font_t *font HB_UNUSED,
 			 hb_buffer_t *buffer)
@@ -159,6 +159,7 @@
   find_syllables_myanmar (buffer);
   foreach_syllable (buffer, start, end)
     buffer->unsafe_to_break (start, end);
+  return false;
 }
 
 static int
@@ -270,6 +271,33 @@
 
   /* Sit tight, rock 'n roll! */
   buffer->sort (start, end, compare_myanmar_order);
+
+  /* Flip left-matra sequence. */
+  unsigned first_left_matra = end;
+  unsigned last_left_matra = end;
+  for (unsigned int i = start; i < end; i++)
+  {
+    if (info[i].myanmar_position() == POS_PRE_M)
+    {
+      if (first_left_matra == end)
+	first_left_matra = i;
+      last_left_matra = i;
+    }
+  }
+  /* https://github.com/harfbuzz/harfbuzz/issues/3863 */
+  if (first_left_matra < last_left_matra)
+  {
+    /* No need to merge clusters, done already? */
+    buffer->reverse_range (first_left_matra, last_left_matra + 1);
+    /* Reverse back VS, etc. */
+    unsigned i = first_left_matra;
+    for (unsigned j = i; j <= last_left_matra; j++)
+      if (info[j].myanmar_category() == M_Cat(VPre))
+      {
+	buffer->reverse_range (i, j + 1);
+	i = j + 1;
+      }
+  }
 }
 
 static void
@@ -291,16 +319,18 @@
   }
 }
 
-static void
+static bool
 reorder_myanmar (const hb_ot_shape_plan_t *plan,
 		 hb_font_t *font,
 		 hb_buffer_t *buffer)
 {
+  bool ret = false;
   if (buffer->message (font, "start reordering myanmar"))
   {
-    hb_syllabic_insert_dotted_circles (font, buffer,
-				       myanmar_broken_cluster,
-				       M_Cat(DOTTEDCIRCLE));
+    if (hb_syllabic_insert_dotted_circles (font, buffer,
+					   myanmar_broken_cluster,
+					   M_Cat(DOTTEDCIRCLE)))
+      ret = true;
 
     foreach_syllable (buffer, start, end)
       reorder_syllable_myanmar (plan, font->face, buffer, start, end);
@@ -309,6 +339,8 @@
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
   HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
+
+  return ret;
 }
 
 
@@ -331,6 +363,7 @@
 };
 
 
+#ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
 /* Ugly Zawgyi encoding.
  * Disable all auto processing.
  * https://github.com/harfbuzz/harfbuzz/issues/1162 */
@@ -351,6 +384,7 @@
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
+#endif
 
 
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -29,7 +29,7 @@
 #include "hb-ot-shaper-syllabic.hh"
 
 
-void
+bool
 hb_syllabic_insert_dotted_circles (hb_font_t *font,
 				   hb_buffer_t *buffer,
 				   unsigned int broken_syllable_type,
@@ -38,13 +38,13 @@
 				   int dottedcircle_position)
 {
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
-    return;
+    return false;
   if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE)))
-    return;
+    return false;
 
   hb_codepoint_t dottedcircle_glyph;
   if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
-    return;
+    return false;
 
   hb_glyph_info_t dottedcircle = {0};
   dottedcircle.codepoint = 0x25CCu;
@@ -84,14 +84,16 @@
       (void) buffer->next_glyph ();
   }
   buffer->sync ();
+  return true;
 }
 
-HB_INTERNAL void
+HB_INTERNAL bool
 hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer)
 {
   HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
+  return false;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-syllabic.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -30,7 +30,7 @@
 #include "hb-ot-shaper.hh"
 
 
-HB_INTERNAL void
+HB_INTERNAL bool
 hb_syllabic_insert_dotted_circles (hb_font_t *font,
 				   hb_buffer_t *buffer,
 				   unsigned int broken_syllable_type,
@@ -38,7 +38,7 @@
 				   int repha_category = -1,
 				   int dottedcircle_position = -1);
 
-HB_INTERNAL void
+HB_INTERNAL bool
 hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-thai.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -98,9 +98,9 @@
 thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font)
 {
   struct thai_pua_mapping_t {
-    hb_codepoint_t u;
-    hb_codepoint_t win_pua;
-    hb_codepoint_t mac_pua;
+    uint16_t u;
+    uint16_t win_pua;
+    uint16_t mac_pua;
   } const *pua_mappings = nullptr;
   static const thai_pua_mapping_t SD_mappings[] = {
     {0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -53,7 +53,7 @@
 };
 
 
-#line 57 "hb-ot-shaper-use-machine.hh"
+#line 54 "hb-ot-shaper-use-machine.hh"
 #define use_syllable_machine_ex_B 1u
 #define use_syllable_machine_ex_CGJ 6u
 #define use_syllable_machine_ex_CMAbv 31u
@@ -97,7 +97,7 @@
 #define use_syllable_machine_ex_ZWNJ 14u
 
 
-#line 101 "hb-ot-shaper-use-machine.hh"
+#line 96 "hb-ot-shaper-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
 	0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 
 	14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 
@@ -839,7 +839,7 @@
     for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \
-    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+    if (syllable_serial == 16) syllable_serial = 1; \
   } HB_STMT_END
 
 
@@ -929,7 +929,7 @@
   unsigned int act HB_UNUSED;
   int cs;
   
-#line 933 "hb-ot-shaper-use-machine.hh"
+#line 922 "hb-ot-shaper-use-machine.hh"
 	{
 	cs = use_syllable_machine_start;
 	ts = 0;
@@ -942,7 +942,7 @@
 
   unsigned int syllable_serial = 1;
   
-#line 946 "hb-ot-shaper-use-machine.hh"
+#line 931 "hb-ot-shaper-use-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -956,7 +956,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 960 "hb-ot-shaper-use-machine.hh"
+#line 943 "hb-ot-shaper-use-machine.hh"
 	}
 
 	_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -1046,7 +1046,7 @@
 #line 178 "hb-ot-shaper-use-machine.rl"
 	{te = p;p--;{ found_syllable (use_non_cluster); }}
 	break;
-#line 1050 "hb-ot-shaper-use-machine.hh"
+#line 1014 "hb-ot-shaper-use-machine.hh"
 	}
 
 _again:
@@ -1055,7 +1055,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 1059 "hb-ot-shaper-use-machine.hh"
+#line 1021 "hb-ot-shaper-use-machine.hh"
 	}
 
 	if ( ++p != pe )

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl	2022-12-18 01:06:39 UTC (rev 65304)
@@ -187,7 +187,7 @@
     for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \
-    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+    if (syllable_serial == 16) syllable_serial = 1; \
   } HB_STMT_END
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -91,6 +91,9 @@
 #define VMPre	USE(VMPre)
 #pragma GCC diagnostic pop
 
+
+#ifndef HB_OPTIMIZE_SIZE
+
 static const uint8_t
 hb_use_u8[3141] =
 {
@@ -357,6 +360,273 @@
   return u<921600u?hb_use_u8[2777+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
 }
 
+
+#else
+
+static const uint8_t
+hb_use_u8[3413] =
+{
+     16,   50,   51,   51,   51,   52,   51,   83,  118,  131,   51,   57,   58,  179,  195,   61,
+     51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+     51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+     51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+     51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+     51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+     51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+     14,    0,    1,    1,    2,    1,    1,    3,    4,    5,    6,    7,    8,    9,   10,    1,
+     11,   12,    1,    1,    1,    1,    1,    1,   13,   14,   15,   16,   17,   18,   19,    1,
+      1,   20,    1,    1,    1,    1,   21,    1,    1,    1,    1,    1,    1,    1,   22,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,   23,   24,   25,   26,    1,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   27,
+     28,    1,    1,    1,    1,    1,   29,    1,    1,    1,    1,   30,   31,    1,   32,   33,
+     34,   35,   36,   37,   38,   39,   40,   41,   42,   43,   44,   45,    1,   46,   47,   48,
+     49,   50,   50,   50,   50,   51,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   52,   53,    1,    1,    1,
+     54,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   50,   55,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   56,    1,    1,
+      1,    1,   57,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+      1,    1,   58,   59,    1,   60,    1,    1,    1,    1,   61,    1,    1,    1,    1,    1,
+      1,   62,   63,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,
+     62,    0,    1,    0,    0,    0,    2,    3,    0,    0,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    4,    0,    0,    0,    0,    0,    0,    0,    5,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    6,    7,    0,    0,    8,    0,    0,    0,    0,
+      0,    9,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
+     24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,
+     40,   41,   42,   43,   36,   44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
+      0,   55,   56,   57,   58,   59,    0,    0,    0,   60,   61,   62,   63,   55,   64,   65,
+     66,   67,   55,   55,   68,   69,   70,    0,    0,   71,   72,   73,   74,   55,   75,   76,
+      0,   77,   55,   78,   79,   80,    0,    0,    0,   81,   82,   83,   84,   85,   86,   55,
+     87,   55,   88,   89,    0,    0,    0,   90,   91,    0,    0,    0,    0,    0,    0,    0,
+     92,   93,   94,    0,   95,   96,    0,    0,   97,    0,    0,    0,    0,    0,    0,   98,
+      0,    0,   99,   55,  100,    0,    0,    0,    0,  101,  102,   55,  103,  104,  105,  106,
+    107,   55,  108,  109,    0,  110,  111,  112,  113,   55,  114,  115,  116,   55,  117,  118,
+    119,    0,    0,    0,    0,    0,    0,   55,  120,  121,    0,    0,    0,    0,    0,    0,
+    122,    0,    0,    0,    0,    0,    0,    0,  123,    0,    0,    0,  124,  125,  126,    0,
+      0,  127,  128,  129,    0,    0,    0,   50,  130,    0,    0,    0,    0,  131,  132,    0,
+      0,   55,  133,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   55,  134,    0,
+      0,    0,   99,  135,   99,  136,  137,  138,    0,  139,  140,  141,  142,  143,  144,  145,
+      0,  146,  147,  148,  149,  143,  150,  151,  152,  153,  154,  155,    0,  156,  157,  158,
+    159,  160,  161,  162,  163,    0,    0,    0,    0,   55,  164,  165,  166,  167,  168,  169,
+      0,    0,    0,    0,    0,   55,  170,  171,    0,   55,  172,  173,    0,   55,  174,   66,
+      0,  175,  176,  177,    0,    0,    0,    0,    0,   55,  178,    0,    0,    0,    0,    0,
+      0,  179,  180,  181,    0,    0,  182,  183,  184,  185,  186,  187,   55,  188,    0,    0,
+      0,  189,  190,  191,  192,  193,  194,    0,    0,  195,  196,  197,  198,  199,   66,    0,
+      0,    0,    0,    0,    0,    0,    0,    0,  200,  201,  202,  203,    0,    0,    0,    0,
+      0,   55,   55,   55,   55,   55,   55,   55,   55,   55,  204,  205,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,   66,    0,   55,  206,    0,    0,    0,    0,    0,
+      0,   55,   55,  207,  208,  209,    0,    0,  210,   55,   55,   55,   55,   55,   55,  211,
+      0,   55,   55,   55,  212,  213,    0,    0,    0,    0,    0,    0,  214,    0,    0,    0,
+      0,   55,  215,  216,    0,    0,    0,    0,    0,    0,    0,    0,    0,   99,  217,   55,
+    218,    0,    0,    0,    0,    0,    0,   99,  219,   55,   55,  220,    0,    0,    0,    0,
+      0,  221,  221,  221,  221,  221,  221,  221,  221,  222,  222,  222,  222,  222,  222,  222,
+    223,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
+      0,    2,    2,    2,    2,    2,    0,    0,    0,    3,    0,    0,    0,    0,    0,    4,
+      0,    0,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    0,    6,    7,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    8,    9,    9,    9,    9,    0,    0,    0,    7,   10,
+      0,    2,    2,    2,    2,   11,   12,    0,    0,    9,   13,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,   14,   15,   16,   17,   18,   19,   20,   14,   21,   22,
+     23,   10,   24,   25,   18,    2,    2,    2,    2,    2,   18,    0,    2,    2,    2,    2,
+      2,    0,    2,    2,    2,    2,    2,    2,    2,   26,   27,   28,    2,    2,    2,    7,
+     28,    7,   28,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    7,    2,    2,
+      2,    7,    7,    0,    2,    2,    0,   15,   16,   17,   18,   29,   30,   31,   30,   32,
+      0,    0,    0,    0,   33,    0,    0,    2,   28,    2,    0,    0,    0,    0,    0,    7,
+     34,   10,   13,   28,    2,    2,    7,    0,   28,    7,    2,   28,    7,    2,    0,   35,
+     16,   17,   29,    0,   25,   36,   25,   37,    0,   38,    0,    0,    0,   28,    2,    7,
+      7,    0,    0,    0,    2,    2,    2,    2,    2,   39,   40,   41,    0,    0,    0,    0,
+      0,   10,   13,   28,    2,    2,    2,    2,   28,    2,   28,    2,    2,    2,    2,    2,
+      2,    7,    2,   28,    2,    2,    0,   15,   16,   17,   18,   19,   25,   20,   33,   22,
+      0,    0,    0,    0,    0,   28,   39,   39,   42,   10,   27,   28,    2,    2,    2,    7,
+     28,    7,    2,   28,    2,    2,    0,   15,   43,    0,    0,   25,   20,    0,    0,    2,
+     28,   28,    0,    0,    0,    0,    0,    0,    0,    0,   44,   28,    2,    2,    7,    0,
+      2,    7,    2,    2,    0,   28,    7,    7,    2,    0,   28,    7,    0,    2,    7,    0,
+      2,    2,    2,    2,    2,    2,    0,    0,   21,   14,   45,    0,   46,   31,   46,   32,
+      0,    0,    0,    0,   33,    0,    0,    0,    0,   13,   27,   47,    2,    2,    2,    7,
+      2,    7,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    0,   15,
+     20,   14,   21,   45,   20,   36,   20,   37,    0,    0,    0,   25,   29,    2,    7,    0,
+      0,    8,   27,   28,    2,    2,    2,    7,    2,    2,    2,   28,    2,    2,    0,   15,
+     43,    0,    0,   33,   45,    0,    0,    0,    7,   48,   49,    0,    0,    0,    0,    0,
+      0,    9,   27,    2,    2,    2,    2,    7,    2,    2,    2,    2,    2,    2,   50,   51,
+     21,   21,   17,   29,   46,   31,   46,   32,   52,    0,    0,    0,   33,    0,    0,    0,
+     28,   10,   27,   28,    2,    2,    2,    2,    2,    2,    2,    2,    7,    0,    2,    2,
+      2,    2,   28,    2,    2,    2,    2,   28,    0,    2,    2,    2,    7,    0,   53,    0,
+     33,   21,   20,   29,   29,   16,   46,   46,   23,    0,   21,    0,    0,    0,    0,    0,
+      0,    2,    0,    2,    7,    0,    0,    0,    0,    0,    0,    0,    0,   18,    0,    0,
+      0,    2,    2,   54,   54,   55,    0,    0,   16,    2,    2,    2,    2,   28,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    7,    0,   56,   19,   57,   20,   20,   18,   18,
+     44,   19,    9,   29,    9,    2,    2,   58,   59,   59,   59,   59,   59,   60,   59,   59,
+     59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   61,
+      0,    0,    0,    0,   62,    0,    0,    0,    0,    2,    2,    2,    2,    2,   63,   43,
+     57,   64,   20,   20,   65,   66,   67,   68,   69,    2,    2,    2,    2,    2,    1,    0,
+      3,    2,    2,    2,   21,   18,    2,    2,   70,   69,   71,   72,   63,   71,   27,   27,
+      2,   50,   20,   51,    2,    2,    2,    2,    2,    2,   73,   74,   75,   27,   27,   76,
+     77,    2,    2,    2,    2,    2,   27,   43,    0,    2,   57,   78,    0,    0,    0,    0,
+     28,    2,   57,   45,    0,    0,    0,    0,    0,    2,   57,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,    7,    2,    7,   57,    0,    0,    0,    0,    0,
+      0,    2,    2,   79,   43,   20,   57,   18,   46,   46,   46,   46,   13,   80,   81,   82,
+     83,   84,   85,    0,    0,    0,    0,   86,    0,    7,    0,    0,   28,    0,   87,   79,
+     88,    2,    2,    2,    2,    7,    0,    0,    0,   40,   40,   89,   90,    2,    2,    2,
+      2,    2,    2,    2,    2,   11,    7,    0,    0,   91,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    7,   20,   78,   43,   20,   92,   59,    0,
+      0,   93,   94,   93,   93,   95,   96,    0,    0,    2,    2,    2,    2,    2,    2,    2,
+      0,    2,    2,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    0,
+      0,    2,    2,    2,    2,   27,    0,    0,    0,    2,    2,    2,    2,    2,    7,    0,
+      0,    2,    2,    2,   50,   97,   43,    0,    0,    2,    2,   98,   99,  100,  101,   59,
+     61,  102,   14,   43,   20,   57,   19,   78,   46,   46,   74,    9,    9,    9,  103,   44,
+     38,    9,  104,   72,    2,    2,    2,    2,    2,    2,    2,  105,   20,   18,   18,   20,
+     46,   46,   20,  106,    2,    2,    2,    7,    0,    0,    0,    0,    0,    0,  107,  108,
+    109,  109,  109,    0,    0,    0,    0,    0,    0,  104,   72,    2,    2,    2,    2,    2,
+      2,   58,   59,   57,   23,   20,  110,   59,    2,    2,    2,    2,  105,   20,   21,   43,
+     43,  100,   12,    0,    0,    0,    0,    0,    0,    2,    2,   59,   16,   46,   21,  111,
+    100,  100,  100,  112,  113,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   28,
+      2,    9,   44,  114,  114,  114,    9,  114,  114,   13,  114,  114,  114,   24,    0,   38,
+      0,    0,    0,  115,   49,    9,    3,    0,    0,    0,    0,    0,    0,    0,  116,    0,
+      0,    0,    0,    0,    0,    0,    4,  117,  118,   40,   40,    3,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,  118,  118,  119,  118,  118,  118,  118,  118,  118,  118,
+    118,    0,    0,  120,    0,    0,    0,    0,    0,    0,    5,  120,    0,    0,    0,    0,
+      0,   44,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    7,
+      0,    2,    2,    2,    2,    0,    0,    0,   28,    0,    0,    0,    0,    0,    0,    0,
+    121,    2,   51,    2,  106,    2,    8,    2,    2,    2,   63,   17,   14,    0,    0,   29,
+      0,    2,    2,    0,    0,    0,    0,    0,    0,   27,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,  122,   21,   21,   21,   21,   21,   21,   21,  123,    0,    0,    0,    0,
+      0,    9,    9,    9,    9,    9,    9,    9,    9,    9,    2,    0,    0,    0,    0,    0,
+     50,    2,    2,    2,   20,   20,  124,  114,    0,    2,    2,    2,  125,   18,   57,   18,
+    111,  100,  126,    0,    0,    0,    0,    0,    0,    9,  127,    2,    2,    2,    2,    2,
+      2,    2,  128,   21,   20,   18,   46,  129,  130,  131,    0,    0,    0,    0,    0,    0,
+      0,    2,    2,   50,   28,    2,    2,    2,    2,    2,    2,    2,    2,    8,   20,   57,
+     97,   74,  132,  133,  134,    0,    0,    0,    0,    2,  135,    2,    2,    2,    2,  136,
+      0,   28,    2,   40,    3,    0,   77,   13,    2,   51,   20,  137,   50,   51,    2,    2,
+    103,    8,    7,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  138,   19,
+     23,    0,    0,  139,  140,    0,    0,    0,    0,    2,   63,   43,   21,   78,   45,  141,
+      0,   79,   79,   79,   79,   79,   79,   79,   79,    0,    0,    0,    0,    0,    0,    0,
+      4,  118,  118,  118,  118,  119,    0,    0,    0,    2,    2,    2,    2,    2,    7,    2,
+      2,    2,    7,    2,   28,    2,    2,    2,    2,    2,   28,    2,    2,    2,   28,    7,
+      0,  125,   18,   25,   29,    0,    0,  142,  143,    2,    2,   28,    2,   28,    2,    2,
+      2,    2,    2,    2,    0,   12,   35,    0,  144,    2,    2,   11,   35,    0,   28,    2,
+      2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   28,    2,    2,
+      7,    2,    2,    9,   39,    0,    0,    0,    0,    2,    2,    2,    2,    2,   25,   36,
+      0,    2,    2,    2,  114,  114,  114,  114,  114,  145,    2,    7,    0,    0,    0,    0,
+      0,    2,   12,   12,    0,    0,    0,    0,    0,    7,    2,    2,    7,    2,    2,    2,
+      2,   28,    2,    7,    0,   28,    2,    0,    0,  146,  147,  148,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,   20,   20,   18,   18,   18,   20,   20,  131,    0,    0,    0,
+      0,    0,  149,  149,  149,  149,  149,  149,  149,  149,  149,  149,    2,    2,    2,    2,
+      2,   51,   50,   51,    0,    0,    0,    0,  150,    9,   72,    2,    2,    2,    2,    2,
+      2,   16,   17,   19,   14,   22,   35,    0,    0,    0,   29,    0,    0,    0,    0,    0,
+      0,    9,   47,    2,    2,    2,    2,    2,    2,    2,    2,    2,  125,   18,   20,  151,
+     20,   19,  152,  153,    2,    2,    2,    2,    2,    0,    0,   63,  154,    0,    0,    0,
+      0,    2,   11,    0,    0,    0,    0,    0,    0,    2,   63,   23,   18,   18,   18,   20,
+     20,  106,  155,    0,    0,   54,  156,   29,  157,   28,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,   21,   17,   20,   20,  158,   42,    0,    0,    0,
+     47,  125,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    7,    7,    2,    2,
+     28,    2,    2,    2,    2,    2,    2,    2,   28,    2,    2,    2,    2,    2,    2,    2,
+      8,   16,   17,   19,   20,  159,   29,    0,    0,    9,    9,   28,    2,    2,    2,    7,
+     28,    7,    2,   28,    2,    2,   56,   15,   21,   14,   21,   45,   30,   31,   30,   32,
+      0,    0,    0,    0,   33,    0,    0,    0,    2,    2,   21,    0,    9,    9,    9,   44,
+      0,    9,    9,   44,    0,    0,    0,    0,    0,    2,    2,   63,   23,   18,   18,   18,
+     20,   21,  123,   13,   15,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
+    160,  161,    0,    0,    0,    0,    0,    0,    0,   16,   17,   18,   18,   64,   97,   23,
+    157,    9,  162,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
+     63,   23,   18,   18,    0,   46,   46,    9,  163,   35,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    2,    2,   18,    0,   21,   17,   18,   18,   19,   14,   80,
+    163,   36,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    8,  164,
+     23,   18,   20,   20,  162,    7,    0,    0,    0,    2,    2,    2,    2,    2,    7,   41,
+    133,   21,   20,   18,   74,   19,   20,    0,    0,    2,    2,    2,    7,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,   16,   17,   18,   19,   20,  103,  163,   35,    0,
+      0,    2,    2,    2,    7,   28,    0,    2,    2,    2,    2,   28,    7,    2,    2,    2,
+      2,   21,   21,   16,   30,   31,   10,  165,  166,  167,  168,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    0,    2,    2,    2,   63,   23,   18,   18,    0,   20,   21,
+     27,  106,    0,   31,    0,    0,    0,    0,    0,   50,   18,   20,   20,   20,  137,    2,
+      2,    2,  169,  170,    9,   13,  171,   70,  172,    0,    0,    1,  144,    0,    0,    0,
+      0,   50,   18,   20,   14,   17,   18,    2,    2,    2,    2,  155,  155,  155,  173,  173,
+    173,  173,  173,  173,   13,  174,    0,   28,    0,   20,   18,   18,   29,   20,   20,    9,
+    163,    0,   59,   59,   59,   59,   59,   59,   59,   64,   19,   80,   44,    0,    0,    0,
+      0,    2,    2,    2,    7,    2,   28,    2,    2,   50,   20,   20,   29,    0,   36,   20,
+     25,    9,  156,  175,  171,    0,    0,    0,    0,    2,    2,    2,   28,    7,    2,    2,
+      2,    2,    2,    2,    2,    2,   21,   21,   45,   20,   33,   80,   66,    0,    0,    0,
+      0,    2,  176,   64,   45,    0,    0,    0,    0,    9,  177,    2,    2,    2,    2,    2,
+      2,    2,    2,   21,   20,   18,   29,    0,   46,   14,  140,    0,    0,    0,    0,    0,
+      0,  178,  178,  178,  106,  179,  178,    0,    0,  145,    2,    2,  180,  114,  114,  114,
+    114,  114,  114,  114,    0,    0,    0,    0,    0,    9,    9,    9,   44,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    7,    0,   56,  181,   18,   18,   18,   18,   18,   18,
+     18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,    0,    0,    0,
+     38,  114,   24,    0,    0,    0,    0,    0,    0,    0,    0,    7,    0,    0,    0,    0,
+      0,    2,    2,    2,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   56,
+     35,    0,    4,  118,  118,  118,  119,    0,    0,    9,    9,    9,   47,    2,    2,    2,
+      0,    2,    2,    2,    2,    2,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,
+     44,    2,    2,    2,    2,    2,    2,    9,    9,    2,    2,    2,    2,    2,    2,   20,
+     20,    2,    2,   42,   42,   42,   90,    0,    0,    O,    O,    O,   GB,    B,    B,   GB,
+      O,    O,   WJ,FMPst,FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,VMAbv,    O,VMAbv,    B,
+  CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
+   VAbv, VAbv, VAbv, VPst, VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O, VAbv,   GB,VMAbv,VMPst,
+  VMPst,    O,    B, VBlw,    O,    O, VPre, VPre,    O, VPre,    H,    O, VPst,FMAbv,    O,CMBlw,
+      O, VAbv,    O, VAbv,    H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O, MBlw,CMAbv,CMAbv, VPst,
+   VAbv,VMAbv,    O, VPst,    O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,VMPst,    B, VAbv, VAbv,
+      B,    R,    O,  HVM,    O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv, VBlw,    B,  SUB,  SUB,
+    SUB,    O,  SUB,  SUB,    O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst,   IS, VAbv,
+   MPst, MPre, MBlw, MBlw,    B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw, VPst, VPre, VAbv, VAbv,
+  VMPst,VMPst,VMBlw,    B,VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
+  VMAbv,FMAbv, VAbv,   IS,FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,CMAbv,CMAbv,    B,   GB,
+      B, VAbv,  SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre,    B, MPre, MBlw,
+    SUB, FAbv, FAbv, MAbv,  SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst,    H,    B,    O,
+  SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
+     CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,    O,    H, MPst, VPst,    H,
+  VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,
+      O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,
+  VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,
+     CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,
+      R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,
+      H,VMPst, VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,    R,
+   MBlw, MBlw,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB, VAbv,    R,VMPst,    H,    H,    B,
+      H,    B,VMBlw,    O, VBlw,
+};
+static const uint16_t
+hb_use_u16[448] =
+{
+    0,  0,  1,  2,  3,  4,  0,  5,  6,  0,  7,  0,  8,  9, 10, 11,
+    9, 12, 13,  9,  9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+   17, 25, 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35,  0,
+   17, 36, 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46,
+   30,  0, 47, 48, 21, 49, 50, 51, 17,  0, 52, 48, 21, 53, 50, 54,
+   17, 55, 56, 48,  9, 57, 58, 59, 60, 61,  9, 62, 63, 64, 30, 65,
+   66, 67,  9, 68, 69,  9, 70, 71, 72, 73, 74, 75, 76,  0,  9,  9,
+   77, 78, 79, 80, 81, 82, 83, 84,  9, 85,  9, 86,  9, 87, 88, 89,
+    9, 90, 91, 92,  2,  0, 93,  0,  9, 94, 95,  9, 96,  0, 97, 98,
+   99,100, 30,  9,101,102,103,  9,104,105,  9,106,  9,107,108,109,
+    2,  2,110,  9,  9,111,112,  2,113,114,115,  9,116,  9,117,118,
+  119,120,121,  0,  0,122,123,124,  0,125,126,127,128,  0,129,130,
+  131,  0,  0,132,133,  0,  0,  9,134,135,136,  9,137,  0,  9,138,
+  139,  9,  9,140,141,  2,142,143,144,  9,145,146,147,  9,  9,148,
+  149,  2,150, 98,151,152,153,  2,  9,154,  9,155,156,  0,157,158,
+  159,  2,160,  0,  0,161,  0,162,  0,163,163,164, 33,165,166,167,
+    9,168, 94,  0,169,  0,  9,170,171,  0,172,  2,173,170,174,175,
+  176,  0,  0,177,178,  0,179,  9,  9,180,181,182,183,184,185,  9,
+    9,186,187,  0,188,  9,189,190,191,  9,  9,192,  9,193,194,105,
+  195,102,  9, 33,196,197,198,  0,199,200, 94,  9,  9,201,202,  2,
+  203, 20, 21,204,205,206,207,208,  9,209,210,211,212,  0,195,  9,
+    9,213,214,  2,215,216,217,218,  9,219,220,  2,221,222,  9,223,
+  224,103,225,  0,226,227,228,229,  9,230,231,  2,232,  9,  9,233,
+  234,  0,235,  9,  9,236,237,238,239,240, 21,  9,215,241,  7,  9,
+   70, 18,  9,242, 73,243,244,  9,  9,245,246,  2,247,  9,248,249,
+    9,250,251, 48,  9,252,253,  2,  9,254,255,256,  9,257,258,259,
+  260,260,261,262,263,  0,  9,264,105, 70, 94,265,  0,266, 70,267,
+  268,  0,269,  0,270,  2,271,  2,272,  2,129,129,160,160,160,129,
+};
+
+static inline unsigned
+hb_use_b4 (const uint8_t* a, unsigned i)
+{
+  return (a[i>>1]>>((i&1u)<<2))&15u;
+}
+static inline uint_fast8_t
+hb_use_get_category (unsigned u)
+{
+  return u<921600u?hb_use_u8[3049+(((hb_use_u8[865+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
+}
+
+#endif
+
 #undef B
 #undef CGJ
 #undef CS

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -89,19 +89,19 @@
   HB_TAG('p','s','t','s'),
 };
 
-static void
+static bool
 setup_syllables_use (const hb_ot_shape_plan_t *plan,
 		     hb_font_t *font,
 		     hb_buffer_t *buffer);
-static void
+static bool
 record_rphf_use (const hb_ot_shape_plan_t *plan,
 		 hb_font_t *font,
 		 hb_buffer_t *buffer);
-static void
+static bool
 record_pref_use (const hb_ot_shape_plan_t *plan,
 		 hb_font_t *font,
 		 hb_buffer_t *buffer);
-static void
+static bool
 reorder_use (const hb_ot_shape_plan_t *plan,
 	     hb_font_t *font,
 	     hb_buffer_t *buffer);
@@ -293,7 +293,7 @@
   }
 }
 
-static void
+static bool
 setup_syllables_use (const hb_ot_shape_plan_t *plan,
 		     hb_font_t *font HB_UNUSED,
 		     hb_buffer_t *buffer)
@@ -304,9 +304,10 @@
     buffer->unsafe_to_break (start, end);
   setup_rphf_mask (plan, buffer);
   setup_topographical_masks (plan, buffer);
+  return false;
 }
 
-static void
+static bool
 record_rphf_use (const hb_ot_shape_plan_t *plan,
 		 hb_font_t *font HB_UNUSED,
 		 hb_buffer_t *buffer)
@@ -314,7 +315,7 @@
   const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
 
   hb_mask_t mask = use_plan->rphf_mask;
-  if (!mask) return;
+  if (!mask) return false;
   hb_glyph_info_t *info = buffer->info;
 
   foreach_syllable (buffer, start, end)
@@ -327,9 +328,10 @@
 	break;
       }
   }
+  return false;
 }
 
-static void
+static bool
 record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
 		 hb_font_t *font HB_UNUSED,
 		 hb_buffer_t *buffer)
@@ -346,6 +348,7 @@
 	break;
       }
   }
+  return false;
 }
 
 static inline bool
@@ -438,17 +441,19 @@
   }
 }
 
-static void
+static bool
 reorder_use (const hb_ot_shape_plan_t *plan,
 	     hb_font_t *font,
 	     hb_buffer_t *buffer)
 {
+  bool ret = false;
   if (buffer->message (font, "start reordering USE"))
   {
-    hb_syllabic_insert_dotted_circles (font, buffer,
-				       use_broken_cluster,
-				       USE(B),
-				       USE(R));
+    if (hb_syllabic_insert_dotted_circles (font, buffer,
+					   use_broken_cluster,
+					   USE(B),
+					   USE(R)))
+      ret = true;
 
     foreach_syllable (buffer, start, end)
       reorder_syllable_use (buffer, start, end);
@@ -457,6 +462,8 @@
   }
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
+
+  return ret;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -262,11 +262,13 @@
 	return &_hb_ot_shaper_myanmar;
 
 
+#ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
 #define HB_SCRIPT_MYANMAR_ZAWGYI	((hb_script_t) HB_TAG ('Q','a','a','g'))
     case HB_SCRIPT_MYANMAR_ZAWGYI:
     /* https://github.com/harfbuzz/harfbuzz/issues/1162 */
 
       return &_hb_ot_shaper_myanmar_zawgyi;
+#endif
 
 
     /* Unicode-2.0 additions */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -320,7 +320,7 @@
     unsigned total_size = min_size + axisCount * AxisValueRecord::static_size;
     auto *out = c->serializer->allocate_size<AxisValueFormat4> (total_size);
     if (unlikely (!out)) return_trace (false);
-    memcpy (out, this, total_size);
+    hb_memcpy (out, this, total_size);
     return_trace (true);
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -577,7 +577,7 @@
       else
       {
 	int shift;
-	memcpy (buf, lang_str, len);
+	hb_memcpy (buf, lang_str, len);
 	if (lang_str[0] != 'x' || lang_str[1] != '-') {
 	  buf[len++] = '-';
 	  buf[len++] = 'x';

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -143,7 +143,7 @@
     TRACE_SANITIZE (this);
     if (!(version.sanitize (c) &&
 	  (version.major == 1
-#ifndef HB_NO_VARIATIONS2
+#ifndef HB_NO_AVAR2
 	   || version.major == 2
 #endif
 	   ) &&
@@ -159,7 +159,7 @@
       map = &StructAfter<SegmentMaps> (*map);
     }
 
-#ifndef HB_NO_VARIATIONS2
+#ifndef HB_NO_AVAR2
     if (version.major < 2)
       return_trace (true);
 
@@ -182,7 +182,7 @@
       map = &StructAfter<SegmentMaps> (*map);
     }
 
-#ifndef HB_NO_VARIATIONS2
+#ifndef HB_NO_AVAR2
     if (version.major < 2)
       return;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -47,7 +47,7 @@
     HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
     if (unlikely (!p)) return_trace (nullptr);
 
-    memcpy (p, this, HBUINT8::static_size * total_size);
+    hb_memcpy (p, this, HBUINT8::static_size * total_size);
     return_trace (out);
   }
 
@@ -219,6 +219,25 @@
   DEFINE_SIZE_UNION (1, format);
 };
 
+
+struct VarStoreInstancer
+{
+  VarStoreInstancer (const VariationStore &varStore,
+		     const DeltaSetIndexMap &varIdxMap,
+		     hb_array_t<int> coords) :
+    varStore (varStore), varIdxMap (varIdxMap), coords (coords) {}
+
+  operator bool () const { return bool (coords); }
+
+  float operator() (uint32_t varIdx, unsigned short offset = 0) const
+  { return varStore.get_delta (varIdxMap.map (VarIdx::add (varIdx, offset)), coords); }
+
+  const VariationStore &varStore;
+  const DeltaSetIndexMap &varIdxMap;
+  hb_array_t<int> coords;
+};
+
+
 } /* namespace OT */
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -59,7 +59,7 @@
     const hb_hashmap_t<hb_tag_t, float> *axes_location = c->plan->user_axes_location;
     for (unsigned i = 0 ; i < axis_count; i++)
     {
-      unsigned *axis_tag;
+      uint32_t *axis_tag;
       // only keep instances whose coordinates == pinned axis location
       if (!c->plan->axes_old_index_tag_map->has (i, &axis_tag)) continue;
 
@@ -337,13 +337,13 @@
     {
       const InstanceRecord *instance = get_instance (i);
 
-      if (hb_any (+ hb_zip (instance->get_coordinates (axisCount), hb_range ((unsigned)axisCount))
-                  | hb_filter (pinned_axes, hb_second)
-                  | hb_map ([&] (const hb_pair_t<const F16DOT16&, unsigned>& _)
+      if (hb_any (+ hb_enumerate (instance->get_coordinates (axisCount))
+                  | hb_filter (pinned_axes, hb_first)
+                  | hb_map ([&] (const hb_pair_t<unsigned, const F16DOT16&>& _)
                             {
-                              hb_tag_t axis_tag = pinned_axes.get (_.second);
+                              hb_tag_t axis_tag = pinned_axes.get (_.first);
                               float location = user_axes_location->get (axis_tag);
-                              if (fabs ((double)location - (double)_.first.to_float ()) > 0.001) return true;
+                              if (fabs ((double)location - (double)_.second.to_float ()) > 0.001) return true;
                               return false;
                             })
                   ))

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -56,12 +56,11 @@
   void extend (const hb_array_t<contour_point_t> &a)
   {
     unsigned int old_len = length;
-    if (unlikely (!resize (old_len + a.length)))
+    if (unlikely (!resize (old_len + a.length, false)))
       return;
     auto arrayZ = this->arrayZ + old_len;
     unsigned count = a.length;
-    for (unsigned int i = 0; i < count; i++)
-      arrayZ[i] = a.arrayZ[i];
+    hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
   }
 
   void transform (const float (&matrix)[4])
@@ -231,8 +230,8 @@
     {
       return (index < var_data->tupleVarCount.get_count ()) &&
 	     var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) &&
-	     var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), current_tuple->get_size (axis_count))) &&
-	     current_tuple->get_size (axis_count);
+	     var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (),
+								current_tuple->get_size (axis_count)));
     }
 
     bool move_to_next ()
@@ -281,42 +280,42 @@
 
     if (unlikely (p + 1 > end)) return false;
 
-    uint16_t count = *p++;
+    unsigned count = *p++;
     if (count & POINTS_ARE_WORDS)
     {
       if (unlikely (p + 1 > end)) return false;
       count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
     }
-    if (unlikely (!points.resize (count))) return false;
+    if (unlikely (!points.resize (count, false))) return false;
 
-    unsigned int n = 0;
-    uint16_t i = 0;
+    unsigned n = 0;
+    unsigned i = 0;
     while (i < count)
     {
       if (unlikely (p + 1 > end)) return false;
-      uint16_t j;
-      uint8_t control = *p++;
-      uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
+      unsigned control = *p++;
+      unsigned run_count = (control & POINT_RUN_COUNT_MASK) + 1;
+      if (unlikely (i + run_count > count)) return false;
+      unsigned j;
       if (control & POINTS_ARE_WORDS)
       {
-	for (j = 0; j < run_count && i < count; j++, i++)
+	if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
+	for (j = 0; j < run_count; j++, i++)
 	{
-	  if (unlikely (p + HBUINT16::static_size > end)) return false;
 	  n += *(const HBUINT16 *)p;
-	  points[i] = n;
+	  points.arrayZ[i] = n;
 	  p += HBUINT16::static_size;
 	}
       }
       else
       {
-	for (j = 0; j < run_count && i < count; j++, i++)
+	if (unlikely (p + run_count > end)) return false;
+	for (j = 0; j < run_count; j++, i++)
 	{
-	  if (unlikely (p + 1 > end)) return false;
 	  n += *p++;
-	  points[i] = n;
+	  points.arrayZ[i] = n;
 	}
       }
-      if (j < run_count) return false;
     }
     return true;
   }
@@ -332,32 +331,37 @@
       DELTA_RUN_COUNT_MASK = 0x3F
     };
 
-    unsigned int i = 0;
-    unsigned int count = deltas.length;
+    unsigned i = 0;
+    unsigned count = deltas.length;
     while (i < count)
     {
       if (unlikely (p + 1 > end)) return false;
-      uint8_t control = *p++;
-      unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
-      unsigned int j;
+      unsigned control = *p++;
+      unsigned run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
+      if (unlikely (i + run_count > count)) return false;
+      unsigned j;
       if (control & DELTAS_ARE_ZERO)
-	for (j = 0; j < run_count && i < count; j++, i++)
-	  deltas[i] = 0;
+      {
+	for (j = 0; j < run_count; j++, i++)
+	  deltas.arrayZ[i] = 0;
+      }
       else if (control & DELTAS_ARE_WORDS)
-	for (j = 0; j < run_count && i < count; j++, i++)
+      {
+	if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
+	for (j = 0; j < run_count; j++, i++)
 	{
-	  if (unlikely (p + HBUINT16::static_size > end)) return false;
-	  deltas[i] = *(const HBINT16 *) p;
+	  deltas.arrayZ[i] = * (const HBINT16 *) p;
 	  p += HBUINT16::static_size;
 	}
+      }
       else
-	for (j = 0; j < run_count && i < count; j++, i++)
+      {
+	if (unlikely (p + run_count > end)) return false;
+	for (j = 0; j < run_count; j++, i++)
 	{
-	  if (unlikely (p + 1 > end)) return false;
-	  deltas[i] = *(const HBINT8 *) p++;
+	  deltas.arrayZ[i] = * (const HBINT8 *) p++;
 	}
-      if (j < run_count)
-	return false;
+      }
     }
     return true;
   }
@@ -450,7 +454,7 @@
       F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size);
       if (!tuples) return_trace (false);
       out->sharedTuples = (char *) tuples - (char *) out;
-      memcpy (tuples, this+sharedTuples, shared_tuple_size);
+      hb_memcpy (tuples, this+sharedTuples, shared_tuple_size);
     }
 
     char *subset_data = c->serializer->allocate_size<char> (subset_data_size);
@@ -473,7 +477,7 @@
 	((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2;
 
       if (var_data_bytes.length > 0)
-	memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
+	hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
       subset_data += var_data_bytes.length;
       glyph_offset += var_data_bytes.length;
     }
@@ -501,6 +505,7 @@
   unsigned get_offset (unsigned i) const
   {
     if (unlikely (i > glyphCount)) return 0;
+    _hb_compiler_memory_r_barrier ();
     return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2;
   }
 
@@ -521,11 +526,11 @@
 			      unsigned int target, unsigned int prev, unsigned int next,
 			      float contour_point_t::*m)
     {
-      float target_val = points[target].*m;
-      float prev_val = points[prev].*m;
-      float next_val = points[next].*m;
-      float prev_delta =  deltas[prev].*m;
-      float next_delta =  deltas[next].*m;
+      float target_val = points.arrayZ[target].*m;
+      float prev_val = points.arrayZ[prev].*m;
+      float next_val = points.arrayZ[next].*m;
+      float prev_delta =  deltas.arrayZ[prev].*m;
+      float next_delta =  deltas.arrayZ[next].*m;
 
       if (prev_val == next_val)
 	return (prev_delta == next_delta) ? prev_delta : 0.f;
@@ -543,10 +548,11 @@
     { return (i >= end) ? start : (i + 1); }
 
     public:
-    bool apply_deltas_to_points (hb_codepoint_t glyph, hb_font_t *font,
+    bool apply_deltas_to_points (hb_codepoint_t glyph,
+				 hb_array_t<int> coords,
 				 const hb_array_t<contour_point_t> points) const
     {
-      if (!font->num_coords) return true;
+      if (!coords) return true;
 
       if (unlikely (glyph >= table->glyphCount)) return true;
 
@@ -559,20 +565,20 @@
 	return true; /* so isn't applied at all */
 
       /* Save original points for inferred delta calculation */
-      contour_point_vector_t orig_points;
-      if (unlikely (!orig_points.resize (points.length))) return false;
-      for (unsigned int i = 0; i < orig_points.length; i++)
-	orig_points.arrayZ[i] = points.arrayZ[i];
+      contour_point_vector_t orig_points_vec;
+      orig_points_vec.extend (points);
+      if (unlikely (orig_points_vec.in_error ())) return false;
+      auto orig_points = orig_points_vec.as_array ();
 
-      contour_point_vector_t deltas; /* flag is used to indicate referenced point */
-      if (unlikely (!deltas.resize (points.length))) return false;
+      contour_point_vector_t deltas_vec; /* flag is used to indicate referenced point */
+      if (unlikely (!deltas_vec.resize (points.length, false))) return false;
+      auto deltas = deltas_vec.as_array ();
 
       hb_vector_t<unsigned> end_points;
       for (unsigned i = 0; i < points.length; ++i)
-	if (points[i].is_end_point)
+	if (points.arrayZ[i].is_end_point)
 	  end_points.push (i);
 
-      auto coords = hb_array (font->coords, font->num_coords);
       unsigned num_coords = table->axisCount;
       hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
 
@@ -598,70 +604,89 @@
 
 	bool apply_to_all = (indices.length == 0);
 	unsigned int num_deltas = apply_to_all ? points.length : indices.length;
-	if (unlikely (!x_deltas.resize (num_deltas))) return false;
+	if (unlikely (!x_deltas.resize (num_deltas, false))) return false;
 	if (unlikely (!GlyphVariationData::unpack_deltas (p, x_deltas, end))) return false;
-	if (unlikely (!y_deltas.resize (num_deltas))) return false;
+	if (unlikely (!y_deltas.resize (num_deltas, false))) return false;
 	if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false;
 
-	for (unsigned int i = 0; i < deltas.length; i++)
-	  deltas[i].init ();
-	for (unsigned int i = 0; i < num_deltas; i++)
-	{
-	  unsigned int pt_index = apply_to_all ? i : indices[i];
-	  if (unlikely (pt_index >= deltas.length)) continue;
-	  deltas.arrayZ[pt_index].flag = 1;	/* this point is referenced, i.e., explicit deltas specified */
-	  deltas.arrayZ[pt_index].x += x_deltas.arrayZ[i] * scalar;
-	  deltas.arrayZ[pt_index].y += y_deltas.arrayZ[i] * scalar;
-	}
+	hb_memset (deltas.arrayZ, 0, deltas.get_size ());
 
+	unsigned ref_points = 0;
+	if (scalar != 1.0f)
+	  for (unsigned int i = 0; i < num_deltas; i++)
+	  {
+	    unsigned int pt_index = apply_to_all ? i : indices[i];
+	    if (unlikely (pt_index >= deltas.length)) continue;
+	    auto &delta = deltas.arrayZ[pt_index];
+	    ref_points += !delta.flag;
+	    delta.flag = 1;	/* this point is referenced, i.e., explicit deltas specified */
+	    delta.x += x_deltas.arrayZ[i] * scalar;
+	    delta.y += y_deltas.arrayZ[i] * scalar;
+	  }
+	else
+	  for (unsigned int i = 0; i < num_deltas; i++)
+	  {
+	    unsigned int pt_index = apply_to_all ? i : indices[i];
+	    if (unlikely (pt_index >= deltas.length)) continue;
+	    auto &delta = deltas.arrayZ[pt_index];
+	    ref_points += !delta.flag;
+	    delta.flag = 1;	/* this point is referenced, i.e., explicit deltas specified */
+	    delta.x += x_deltas.arrayZ[i];
+	    delta.y += y_deltas.arrayZ[i];
+	  }
+
 	/* infer deltas for unreferenced points */
-	unsigned start_point = 0;
-	for (unsigned c = 0; c < end_points.length; c++)
+	if (ref_points && ref_points < orig_points.length)
 	{
-	  unsigned end_point = end_points[c];
+	  unsigned start_point = 0;
+	  for (unsigned c = 0; c < end_points.length; c++)
+	  {
+	    unsigned end_point = end_points.arrayZ[c];
 
-	  /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
-	  unsigned unref_count = 0;
-	  for (unsigned i = start_point; i <= end_point; i++)
-	    if (!deltas[i].flag) unref_count++;
+	    /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
+	    unsigned unref_count = 0;
+	    for (unsigned i = start_point; i < end_point + 1; i++)
+	      unref_count += deltas.arrayZ[i].flag;
+	    unref_count = (end_point - start_point + 1) - unref_count;
 
-	  unsigned j = start_point;
-	  if (unref_count == 0 || unref_count > end_point - start_point)
-	    goto no_more_gaps;
+	    unsigned j = start_point;
+	    if (unref_count == 0 || unref_count > end_point - start_point)
+	      goto no_more_gaps;
 
-	  for (;;)
-	  {
-	    /* Locate the next gap of unreferenced points between two referenced points prev and next.
-	     * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
-	     */
-	    unsigned int prev, next, i;
 	    for (;;)
 	    {
-	      i = j;
-	      j = next_index (i, start_point, end_point);
-	      if (deltas[i].flag && !deltas[j].flag) break;
+	      /* Locate the next gap of unreferenced points between two referenced points prev and next.
+	       * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
+	       */
+	      unsigned int prev, next, i;
+	      for (;;)
+	      {
+		i = j;
+		j = next_index (i, start_point, end_point);
+		if (deltas.arrayZ[i].flag && !deltas.arrayZ[j].flag) break;
+	      }
+	      prev = j = i;
+	      for (;;)
+	      {
+		i = j;
+		j = next_index (i, start_point, end_point);
+		if (!deltas.arrayZ[i].flag && deltas.arrayZ[j].flag) break;
+	      }
+	      next = j;
+	      /* Infer deltas for all unref points in the gap between prev and next */
+	      i = prev;
+	      for (;;)
+	      {
+		i = next_index (i, start_point, end_point);
+		if (i == next) break;
+		deltas.arrayZ[i].x = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::x);
+		deltas.arrayZ[i].y = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::y);
+		if (--unref_count == 0) goto no_more_gaps;
+	      }
 	    }
-	    prev = j = i;
-	    for (;;)
-	    {
-	      i = j;
-	      j = next_index (i, start_point, end_point);
-	      if (!deltas[i].flag && deltas[j].flag) break;
-	    }
-	    next = j;
-	    /* Infer deltas for all unref points in the gap between prev and next */
-	    i = prev;
-	    for (;;)
-	    {
-	      i = next_index (i, start_point, end_point);
-	      if (i == next) break;
-	      deltas[i].x = infer_delta (orig_points.as_array (), deltas.as_array (), i, prev, next, &contour_point_t::x);
-	      deltas[i].y = infer_delta (orig_points.as_array (), deltas.as_array (), i, prev, next, &contour_point_t::y);
-	      if (--unref_count == 0) goto no_more_gaps;
-	    }
+	  no_more_gaps:
+	    start_point = end_point + 1;
 	  }
-	no_more_gaps:
-	  start_point = end_point + 1;
 	}
 
 	/* apply specified / inferred deltas to points */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -35,15 +35,13 @@
 struct hb_pool_t
 {
   hb_pool_t () : next (nullptr) {}
-  ~hb_pool_t () { fini (); }
-
-  void fini ()
+  ~hb_pool_t ()
   {
     next = nullptr;
 
-    for (chunk_t *_ : chunks) hb_free (_);
-
-    chunks.fini ();
+    + hb_iter (chunks)
+    | hb_apply (hb_free)
+    ;
   }
 
   T* alloc ()
@@ -60,7 +58,7 @@
     T* obj = next;
     next = * ((T**) next);
 
-    memset (obj, 0, sizeof (T));
+    hb_memset (obj, 0, sizeof (T));
 
     return obj;
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -63,8 +63,10 @@
 
     heap.arrayZ[0] = heap.arrayZ[heap.length - 1];
     heap.shrink (heap.length - 1);
-    bubble_down (0);
 
+    if (!is_empty ())
+      bubble_down (0);
+
     return result;
   }
 
@@ -100,7 +102,7 @@
 
   void bubble_down (unsigned index)
   {
-    assert (index <= heap.length);
+    assert (index < heap.length);
 
     unsigned left = left_child (index);
     unsigned right = right_child (index);
@@ -112,7 +114,7 @@
 
     bool has_right = right < heap.length;
     if (heap.arrayZ[index].first <= heap.arrayZ[left].first
-        && (!has_right || heap[index].first <= heap.arrayZ[right].first))
+        && (!has_right || heap.arrayZ[index].first <= heap.arrayZ[right].first))
       return;
 
     if (!has_right || heap.arrayZ[left].first < heap.arrayZ[right].first)
@@ -128,7 +130,7 @@
 
   void bubble_up (unsigned index)
   {
-    assert (index <= heap.length);
+    assert (index < heap.length);
 
     if (index == 0) return;
 
@@ -142,8 +144,8 @@
 
   void swap (unsigned a, unsigned b)
   {
-    assert (a <= heap.length);
-    assert (b <= heap.length);
+    assert (a < heap.length);
+    assert (b < heap.length);
     hb_swap (heap.arrayZ[a], heap.arrayZ[b]);
   }
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -209,7 +209,7 @@
     // Only move at most half of the roots in a space at a time.
     unsigned extra = roots_to_isolate.get_population () - maximum_to_move;
     while (extra--) {
-      unsigned root = HB_SET_VALUE_INVALID;
+      uint32_t root = HB_SET_VALUE_INVALID;
       roots_to_isolate.previous (&root);
       roots_to_isolate.del (root);
     }
@@ -283,6 +283,11 @@
                             graph_t& sorted_graph /* IN/OUT */)
 {
   sorted_graph.sort_shortest_distance ();
+  if (sorted_graph.in_error ())
+  {
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state after initial sort.");
+    return false;
+  }
 
   bool will_overflow = graph::will_overflow (sorted_graph);
   if (!will_overflow)
@@ -376,6 +381,26 @@
                       unsigned max_rounds = 20,
                       bool recalculate_extensions = false) {
   graph_t sorted_graph (packed);
+  if (sorted_graph.in_error ())
+  {
+    // Invalid graph definition.
+    return nullptr;
+  }
+
+  if (!sorted_graph.is_fully_connected ())
+  {
+    sorted_graph.print_orphaned_nodes ();
+    return nullptr;
+  }
+
+  if (sorted_graph.in_error ())
+  {
+    // Allocations failed somewhere
+    DEBUG_MSG (SUBSET_REPACK, nullptr,
+               "Graph is in error, likely due to a memory allocation error.");
+    return nullptr;
+  }
+
   if (!hb_resolve_graph_overflows (table_tag, max_rounds, recalculate_extensions, sorted_graph))
     return nullptr;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -198,10 +198,11 @@
   void start_processing ()
   {
     reset_object ();
-    if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR)))
+    unsigned m;
+    if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m)))
       this->max_ops = HB_SANITIZE_MAX_OPS_MAX;
     else
-      this->max_ops = hb_clamp ((unsigned) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
+      this->max_ops = hb_clamp (m,
 				(unsigned) HB_SANITIZE_MAX_OPS_MIN,
 				(unsigned) HB_SANITIZE_MAX_OPS_MAX);
     this->edit_count = 0;
@@ -252,8 +253,9 @@
 		    unsigned int a,
 		    unsigned int b) const
   {
-    return !hb_unsigned_mul_overflows (a, b) &&
-	   this->check_range (base, a * b);
+    unsigned m;
+    return !hb_unsigned_mul_overflows (a, b, &m) &&
+	   this->check_range (base, m);
   }
 
   template <typename T>
@@ -262,8 +264,9 @@
 		    unsigned int b,
 		    unsigned int c) const
   {
-    return !hb_unsigned_mul_overflows (a, b) &&
-	   this->check_range (base, a * b, c);
+    unsigned m;
+    return !hb_unsigned_mul_overflows (a, b, &m) &&
+	   this->check_range (base, m, c);
   }
 
   template <typename T>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -194,7 +194,6 @@
       current = current->next;
       _->fini ();
     }
-    object_pool.fini ();
   }
 
   bool in_error () const { return bool (errors); }
@@ -224,6 +223,7 @@
     this->errors = HB_SERIALIZE_ERROR_NONE;
     this->head = this->start;
     this->tail = this->end;
+    this->zerocopy = nullptr;
     this->debug_depth = 0;
 
     fini ();
@@ -326,7 +326,8 @@
     if (unlikely (in_error() && !only_overflow ())) return;
 
     current = current->next;
-    revert (obj->head, obj->tail);
+    revert (zerocopy ? zerocopy : obj->head, obj->tail);
+    zerocopy = nullptr;
     obj->fini ();
     object_pool.release (obj);
   }
@@ -344,8 +345,11 @@
     current = current->next;
     obj->tail = head;
     obj->next = nullptr;
+    assert (obj->head <= obj->tail);
     unsigned len = obj->tail - obj->head;
-    head = obj->head; /* Rewind head. */
+    head = zerocopy ? zerocopy : obj->head; /* Rewind head. */
+    bool was_zerocopy = zerocopy;
+    zerocopy = nullptr;
 
     if (!len)
     {
@@ -355,9 +359,11 @@
     }
 
     objidx_t objidx;
+    uint32_t hash = 0;
     if (share)
     {
-      objidx = packed_map.get (obj);
+      hash = hb_hash (obj);
+      objidx = packed_map.get_with_hash (obj, hash);
       if (objidx)
       {
         merge_virtual_links (obj, objidx);
@@ -367,7 +373,10 @@
     }
 
     tail -= len;
-    memmove (tail, obj->head, len);
+    if (was_zerocopy)
+      assert (tail == obj->head);
+    else
+      memmove (tail, obj->head, len);
 
     obj->head = tail;
     obj->tail = tail + len;
@@ -385,7 +394,7 @@
 
     objidx = packed.length - 1;
 
-    if (share) packed_map.set (obj, objidx);
+    if (share) packed_map.set_with_hash (obj, hash, objidx);
     propagate_error (packed_map);
 
     return objidx;
@@ -569,8 +578,26 @@
     return !bool ((errors = (errors | err_type)));
   }
 
+  bool start_zerocopy (size_t size)
+  {
+    if (unlikely (in_error ())) return false;
+
+    if (unlikely (size > INT_MAX || this->tail - this->head < ptrdiff_t (size)))
+    {
+      err (HB_SERIALIZE_ERROR_OUT_OF_ROOM);
+      return false;
+    }
+
+    assert (!this->zerocopy);
+    this->zerocopy = this->head;
+
+    assert (this->current->head == this->head);
+    this->current->head = this->current->tail = this->head = this->tail - size;
+    return true;
+  }
+
   template <typename Type>
-  Type *allocate_size (size_t size)
+  Type *allocate_size (size_t size, bool clear = true)
   {
     if (unlikely (in_error ())) return nullptr;
 
@@ -579,7 +606,8 @@
       err (HB_SERIALIZE_ERROR_OUT_OF_ROOM);
       return nullptr;
     }
-    hb_memset (this->head, 0, size);
+    if (clear)
+      hb_memset (this->head, 0, size);
     char *ret = this->head;
     this->head += size;
     return reinterpret_cast<Type *> (ret);
@@ -593,9 +621,9 @@
   Type *embed (const Type *obj)
   {
     unsigned int size = obj->get_size ();
-    Type *ret = this->allocate_size<Type> (size);
+    Type *ret = this->allocate_size<Type> (size, false);
     if (unlikely (!ret)) return nullptr;
-    memcpy (ret, obj, size);
+    hb_memcpy (ret, obj, size);
     return ret;
   }
   template <typename Type>
@@ -616,7 +644,7 @@
   }
 
   /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data
-   * instead of memcpy(). */
+   * instead of hb_memcpy(). */
   template <typename Type, typename ...Ts>
   Type *copy (const Type &src, Ts&&... ds)
   { return _copy (src, hb_prioritize, std::forward<Ts> (ds)...); }
@@ -634,7 +662,7 @@
   hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
 
   template <typename Type>
-  Type *extend_size (Type *obj, size_t size)
+  Type *extend_size (Type *obj, size_t size, bool clear = true)
   {
     if (unlikely (in_error ())) return nullptr;
 
@@ -642,12 +670,12 @@
     assert ((char *) obj <= this->head);
     assert ((size_t) (this->head - (char *) obj) <= size);
     if (unlikely (((char *) obj + size < (char *) obj) ||
-		  !this->allocate_size<Type> (((char *) obj) + size - this->head))) return nullptr;
+		  !this->allocate_size<Type> (((char *) obj) + size - this->head, clear))) return nullptr;
     return reinterpret_cast<Type *> (obj);
   }
   template <typename Type>
-  Type *extend_size (Type &obj, size_t size)
-  { return extend_size (std::addressof (obj), size); }
+  Type *extend_size (Type &obj, size_t size, bool clear = true)
+  { return extend_size (std::addressof (obj), size, clear); }
 
   template <typename Type>
   Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); }
@@ -676,8 +704,8 @@
     char *p = (char *) hb_malloc (len);
     if (unlikely (!p)) return hb_bytes_t ();
 
-    memcpy (p, this->start, this->head - this->start);
-    memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
+    hb_memcpy (p, this->start, this->head - this->start);
+    hb_memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
     return hb_bytes_t (p, len);
   }
   template <typename Type>
@@ -704,7 +732,7 @@
   }
 
   public:
-  char *start, *head, *tail, *end;
+  char *start, *head, *tail, *end, *zerocopy;
   unsigned int debug_depth;
   hb_serialize_error_t errors;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set-digest.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -28,6 +28,7 @@
 #define HB_SET_DIGEST_HH
 
 #include "hb.hh"
+#include "hb-machinery.hh"
 
 /*
  * The set-digests here implement various "filters" that support
@@ -75,6 +76,8 @@
 
   void init () { mask = 0; }
 
+  void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; }
+
   void add (hb_codepoint_t g) { mask |= mask_for (g); }
 
   bool add_range (hb_codepoint_t a, hb_codepoint_t b)
@@ -95,7 +98,7 @@
     for (unsigned int i = 0; i < count; i++)
     {
       add (*array);
-      array = (const T *) (stride + (const char *) array);
+      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
     }
   }
   template <typename T>
@@ -103,16 +106,15 @@
   template <typename T>
   bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
   {
-    for (unsigned int i = 0; i < count; i++)
-    {
-      add (*array);
-      array = (const T *) (stride + (const char *) array);
-    }
+    add_array (array, count, stride);
     return true;
   }
   template <typename T>
   bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
 
+  bool may_have (const hb_set_digest_bits_pattern_t &o) const
+  { return mask & o.mask; }
+
   bool may_have (hb_codepoint_t g) const
   { return mask & mask_for (g); }
 
@@ -132,6 +134,12 @@
     tail.init ();
   }
 
+  void add (const hb_set_digest_combiner_t &o)
+  {
+    head.add (o.head);
+    tail.add (o.tail);
+  }
+
   void add (hb_codepoint_t g)
   {
     head.add (g);
@@ -140,9 +148,8 @@
 
   bool add_range (hb_codepoint_t a, hb_codepoint_t b)
   {
-    head.add_range (a, b);
-    tail.add_range (a, b);
-    return true;
+    return head.add_range (a, b) &&
+	   tail.add_range (a, b);
   }
   template <typename T>
   void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
@@ -155,13 +162,17 @@
   template <typename T>
   bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
   {
-    head.add_sorted_array (array, count, stride);
-    tail.add_sorted_array (array, count, stride);
-    return true;
+    return head.add_sorted_array (array, count, stride) &&
+	   tail.add_sorted_array (array, count, stride);
   }
   template <typename T>
   bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
 
+  bool may_have (const hb_set_digest_combiner_t &o) const
+  {
+    return head.may_have (o.head) && tail.may_have (o.tail);
+  }
+
   bool may_have (hb_codepoint_t g) const
   {
     return head.may_have (g) && tail.may_have (g);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -105,10 +105,8 @@
   bool get (hb_codepoint_t g) const { return s.get (g); }
 
   /* Has interface. */
-  static constexpr bool SENTINEL = false;
-  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; }
+  bool operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k]; }
 
   /* Predicate. */
   bool operator () (hb_codepoint_t k) const { return has (k); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -31,6 +31,8 @@
 #include "hb-buffer.hh"
 
 
+#ifndef HB_NO_SHAPER
+
 /**
  * SECTION:hb-shape-plan
  * @title: hb-shape-plan
@@ -74,7 +76,7 @@
   this->user_features = copy ? features : user_features;
   if (copy && num_user_features)
   {
-    memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
+    hb_memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
     /* Make start/end uniform to easier catch bugs. */
     for (unsigned int i = 0; i < num_user_features; i++)
     {
@@ -574,3 +576,6 @@
 
   return hb_shape_plan_reference (shape_plan);
 }
+
+
+#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -35,6 +35,8 @@
 #include "hb-machinery.hh"
 
 
+#ifndef HB_NO_SHAPER
+
 /**
  * SECTION:hb-shape
  * @title: hb-shape
@@ -192,3 +194,6 @@
 {
   hb_shape_full (font, buffer, features, num_features, nullptr);
 }
+
+
+#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -53,7 +53,7 @@
     if (unlikely (!shapers))
       return nullptr;
 
-    memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers));
+    hb_memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers));
 
      /* Reorder shaper list to prefer requested shapers. */
     unsigned int i = 0;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -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-color-colr-table.hh"
 #include "hb-ot-glyf-table.hh"
 #include "hb-ot-head-table.hh"
 #include "hb-ot-maxp-table.hh"
@@ -47,6 +48,7 @@
 DEFINE_NULL_NAMESPACE_BYTES (OT, VarIdx) =  {0xFF,0xFF,0xFF,0xFF};
 DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00};
 DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x01};
+DEFINE_NULL_NAMESPACE_BYTES (OT, ClipRecord) = {0x01};
 DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00};
 DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF};
 DEFINE_NULL_NAMESPACE_BYTES (AAT, Lookup) = {0xFF,0xFF};

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-accelerator.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-accelerator.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-accelerator.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -31,21 +31,34 @@
 #include "hb.hh"
 
 #include "hb-map.hh"
+#include "hb-multimap.hh"
 #include "hb-set.hh"
 
+extern HB_INTERNAL hb_user_data_key_t _hb_subset_accelerator_user_data_key;
+
+namespace CFF {
+struct cff_subset_accelerator_t;
+}
+
+namespace OT {
+struct SubtableUnicodesCache;
+};
+
 struct hb_subset_accelerator_t
 {
   static hb_user_data_key_t* user_data_key()
   {
-    static hb_user_data_key_t key;
-    return &key;
+    return &_hb_subset_accelerator_user_data_key;
   }
 
   static hb_subset_accelerator_t* create(const hb_map_t& unicode_to_gid_,
-                                         const hb_set_t& unicodes_) {
+					 const hb_multimap_t gid_to_unicodes_,
+					 const hb_set_t& unicodes_,
+					 bool has_seac_) {
     hb_subset_accelerator_t* accel =
         (hb_subset_accelerator_t*) hb_malloc (sizeof(hb_subset_accelerator_t));
-    new (accel) hb_subset_accelerator_t (unicode_to_gid_, unicodes_);
+    new (accel) hb_subset_accelerator_t (unicode_to_gid_, gid_to_unicodes_, unicodes_);
+    accel->has_seac = has_seac_;
     return accel;
   }
 
@@ -53,22 +66,54 @@
     if (!value) return;
 
     hb_subset_accelerator_t* accel = (hb_subset_accelerator_t*) value;
+
+    if (accel->cff_accelerator && accel->destroy_cff_accelerator)
+      accel->destroy_cff_accelerator ((void*) accel->cff_accelerator);
+
+    if (accel->cmap_cache && accel->destroy_cmap_cache)
+      accel->destroy_cmap_cache ((void*) accel->cmap_cache);
+
     accel->~hb_subset_accelerator_t ();
     hb_free (accel);
   }
 
-  hb_subset_accelerator_t(const hb_map_t& unicode_to_gid_,
+  hb_subset_accelerator_t (const hb_map_t& unicode_to_gid_,
+			   const hb_multimap_t& gid_to_unicodes_,
                           const hb_set_t& unicodes_)
-      : unicode_to_gid(unicode_to_gid_), unicodes(unicodes_) {}
+      : unicode_to_gid(unicode_to_gid_), gid_to_unicodes (gid_to_unicodes_), unicodes(unicodes_),
+        cmap_cache(nullptr), destroy_cmap_cache(nullptr),
+        has_seac(false), cff_accelerator(nullptr), destroy_cff_accelerator(nullptr)
+  { sanitized_table_cache_lock.init (); }
 
+  ~hb_subset_accelerator_t ()
+  { sanitized_table_cache_lock.fini (); }
+
+  // Generic
+
+  mutable hb_mutex_t sanitized_table_cache_lock;
+  mutable hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache;
+
   const hb_map_t unicode_to_gid;
+  const hb_multimap_t gid_to_unicodes;
   const hb_set_t unicodes;
+
+  // cmap
+  const OT::SubtableUnicodesCache* cmap_cache;
+  hb_destroy_func_t destroy_cmap_cache;
+
+  // CFF
+  bool has_seac;
+  const CFF::cff_subset_accelerator_t* cff_accelerator;
+  hb_destroy_func_t destroy_cff_accelerator;
+
   // TODO(garretrieger): cumulative glyf checksum map
-  // TODO(garretrieger): sanitized table cache.
 
   bool in_error () const
   {
-    return unicode_to_gid.in_error() || unicodes.in_error ();
+    return unicode_to_gid.in_error () ||
+	   gid_to_unicodes.in_error () ||
+	   unicodes.in_error () ||
+	   sanitized_table_cache.in_error ();
   }
 };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -66,8 +66,7 @@
 
   {
     /* use hb_set to determine the subset of font dicts */
-    hb_set_t *set = hb_set_create ();
-    if (unlikely (set == &Null (hb_set_t))) return false;
+    hb_set_t set;
     hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
     for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
     {
@@ -79,7 +78,7 @@
 	glyph = i;
       }
       fd = src.get_fd (glyph);
-      set->add (fd);
+      set.add (fd);
 
       if (fd != prev_fd)
       {
@@ -90,12 +89,11 @@
       }
     }
 
-    subset_fd_count = set->get_population ();
+    subset_fd_count = set.get_population ();
     if (subset_fd_count == fdCount)
     {
       /* all font dicts belong to the subset. no need to subset FDSelect & FDArray */
       fdmap.identity (fdCount);
-      hb_set_destroy (set);
     }
     else
     {
@@ -103,9 +101,8 @@
       fdmap.reset ();
 
       hb_codepoint_t fd = CFF_UNDEF_CODE;
-      while (set->next (&fd))
+      while (set.next (&fd))
 	fdmap.add (fd);
-      hb_set_destroy (set);
       if (unlikely (fdmap.get_population () != subset_fd_count))
 	return false;
     }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -38,15 +38,16 @@
 struct str_encoder_t
 {
   str_encoder_t (str_buff_t &buff_)
-    : buff (buff_), error (false) {}
+    : buff (buff_) {}
 
   void reset () { buff.reset (); }
 
   void encode_byte (unsigned char b)
   {
-    buff.push (b);
-    if (unlikely (buff.in_error ()))
-      set_error ();
+    if (likely ((signed) buff.length < buff.allocated))
+      buff.arrayZ[buff.length++] = b;
+    else
+      buff.push (b);
   }
 
   void encode_int (int v)
@@ -108,27 +109,18 @@
       encode_byte (op);
   }
 
-  void copy_str (const hb_ubytes_t &str)
+  void copy_str (const unsigned char *str, unsigned length)
   {
-    unsigned int  offset = buff.length;
-    /* Manually resize buffer since faster. */
-    if ((signed) (buff.length + str.length) <= buff.allocated)
-      buff.length += str.length;
-    else if (unlikely (!buff.resize (offset + str.length)))
-    {
-      set_error ();
-      return;
-    }
-    memcpy (buff.arrayZ + offset, &str[0], str.length);
+    assert ((signed) (buff.length + length) <= buff.allocated);
+    hb_memcpy (buff.arrayZ + buff.length, str, length);
+    buff.length += length;
   }
 
-  bool is_error () const { return error; }
+  bool in_error () const { return buff.in_error (); }
 
   protected:
-  void set_error () { error = true; }
 
   str_buff_t &buff;
-  bool    error;
 };
 
 struct cff_sub_table_info_t {
@@ -187,9 +179,12 @@
     }
     else
     {
-      HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
+      unsigned char *d = c->allocate_size<unsigned char> (opstr.length);
       if (unlikely (!d)) return_trace (false);
-      memcpy (d, &opstr.str[0], opstr.str.length);
+      /* Faster than hb_memcpy for small strings. */
+      for (unsigned i = 0; i < opstr.length; i++)
+	d[i] = opstr.ptr[i];
+      //hb_memcpy (d, opstr.ptr, opstr.length);
     }
     return_trace (true);
   }
@@ -239,11 +234,10 @@
 
   bool flatten (str_buff_vec_t &flat_charstrings)
   {
-    if (!flat_charstrings.resize (plan->num_output_glyphs ()))
+    unsigned count = plan->num_output_glyphs ();
+    if (!flat_charstrings.resize (count))
       return false;
-    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
-      flat_charstrings[i].init ();
-    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+    for (unsigned int i = 0; i < count; i++)
     {
       hb_codepoint_t  glyph;
       if (!plan->old_gid_for_new_gid (i, &glyph))
@@ -259,7 +253,7 @@
       ENV env (str, acc, fd);
       cs_interpreter_t<ENV, OPSET, flatten_param_t> interp (env);
       flatten_param_t  param = {
-        flat_charstrings[i],
+        flat_charstrings.arrayZ[i],
         (bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
       };
       if (unlikely (!interp.interpret (param)))
@@ -274,11 +268,9 @@
 
 struct subr_closures_t
 {
-  subr_closures_t (unsigned int fd_count) : valid (false), global_closure (), local_closures ()
+  subr_closures_t (unsigned int fd_count) : global_closure (), local_closures ()
   {
-    valid = true;
-    if (!local_closures.resize (fd_count))
-      valid = false;
+    local_closures.resize (fd_count);
   }
 
   void reset ()
@@ -288,8 +280,7 @@
       local_closures[i].clear();
   }
 
-  bool is_valid () const { return valid; }
-  bool  valid;
+  bool in_error () const { return local_closures.in_error (); }
   hb_set_t  global_closure;
   hb_vector_t<hb_set_t> local_closures;
 };
@@ -296,39 +287,31 @@
 
 struct parsed_cs_op_t : op_str_t
 {
-  void init (unsigned int subr_num_ = 0)
-  {
-    subr_num = subr_num_;
-    drop_flag = false;
-    keep_flag = false;
-    skip_flag = false;
-  }
+  parsed_cs_op_t (unsigned int subr_num_ = 0) :
+    subr_num (subr_num_) {}
 
-  bool for_drop () const { return drop_flag; }
-  void set_drop ()       { if (!for_keep ()) drop_flag = true; }
+  bool is_hinting () const { return hinting_flag; }
+  void set_hinting ()       { hinting_flag = true; }
 
-  bool for_keep () const { return keep_flag; }
-  void set_keep ()       { keep_flag = true; }
+  /* The layout of this struct is designed to fit within the
+   * padding of op_str_t! */
 
-  bool for_skip () const { return skip_flag; }
-  void set_skip ()       { skip_flag = true; }
+  protected:
+  bool	  hinting_flag = false;
 
-  unsigned int  subr_num;
-
-  protected:
-  bool	  drop_flag;
-  bool	  keep_flag;
-  bool	  skip_flag;
+  public:
+  uint16_t subr_num;
 };
 
 struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t>
 {
-  void init ()
+  parsed_cs_str_t () :
+    parsed (false),
+    hint_dropped (false),
+    has_prefix_ (false),
+    has_calls_ (false)
   {
     SUPER::init ();
-    parsed = false;
-    hint_dropped = false;
-    has_prefix_ = false;
   }
 
   void add_op (op_code_t op, const byte_str_ref_t& str_ref)
@@ -341,13 +324,12 @@
   {
     if (!is_parsed ())
     {
-      unsigned int parsed_len = get_count ();
-      if (likely (parsed_len > 0))
-	values[parsed_len-1].set_skip ();
+      has_calls_ = true;
 
-      parsed_cs_op_t val;
-      val.init (subr_num);
-      SUPER::add_op (op, str_ref, val);
+      /* Pop the subroutine number. */
+      values.pop ();
+
+      SUPER::add_op (op, str_ref, {subr_num});
     }
   }
 
@@ -377,11 +359,14 @@
   op_code_t prefix_op () const         { return prefix_op_; }
   const number_t &prefix_num () const { return prefix_num_; }
 
+  bool has_calls () const          { return has_calls_; }
+
   protected:
-  bool    parsed;
-  bool    hint_dropped;
-  bool    vsindex_dropped;
-  bool    has_prefix_;
+  bool    parsed : 1;
+  bool    hint_dropped : 1;
+  bool    vsindex_dropped : 1;
+  bool    has_prefix_ : 1;
+  bool    has_calls_ : 1;
   op_code_t	prefix_op_;
   number_t	prefix_num_;
 
@@ -395,6 +380,59 @@
   typedef hb_vector_t<parsed_cs_str_t> SUPER;
 };
 
+struct cff_subset_accelerator_t
+{
+  static cff_subset_accelerator_t* create (
+      hb_blob_t* original_blob,
+      const parsed_cs_str_vec_t& parsed_charstrings,
+      const parsed_cs_str_vec_t& parsed_global_subrs,
+      const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs) {
+    cff_subset_accelerator_t* accel =
+        (cff_subset_accelerator_t*) hb_malloc (sizeof(cff_subset_accelerator_t));
+    new (accel) cff_subset_accelerator_t (original_blob,
+                                          parsed_charstrings,
+                                          parsed_global_subrs,
+                                          parsed_local_subrs);
+    return accel;
+  }
+
+  static void destroy (void* value) {
+    if (!value) return;
+
+    cff_subset_accelerator_t* accel = (cff_subset_accelerator_t*) value;
+    accel->~cff_subset_accelerator_t ();
+    hb_free (accel);
+  }
+
+  cff_subset_accelerator_t(
+      hb_blob_t* original_blob_,
+      const parsed_cs_str_vec_t& parsed_charstrings_,
+      const parsed_cs_str_vec_t& parsed_global_subrs_,
+      const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs_)
+  {
+    parsed_charstrings = parsed_charstrings_;
+    parsed_global_subrs = parsed_global_subrs_;
+    parsed_local_subrs = parsed_local_subrs_;
+
+    // the parsed charstrings point to memory in the original CFF table so we must hold a reference
+    // to it to keep the memory valid.
+    original_blob = hb_blob_reference (original_blob_);
+  }
+
+  ~cff_subset_accelerator_t() {
+    hb_blob_destroy (original_blob);
+    hb_map_destroy (glyph_to_sid_map.get_relaxed ());
+  }
+
+  parsed_cs_str_vec_t parsed_charstrings;
+  parsed_cs_str_vec_t parsed_global_subrs;
+  hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
+  mutable hb_atomic_ptr_t<hb_map_t> glyph_to_sid_map = nullptr;
+
+ private:
+  hb_blob_t* original_blob;
+};
+
 struct subr_subset_param_t
 {
   subr_subset_param_t (parsed_cs_str_t *parsed_charstring_,
@@ -446,7 +484,11 @@
     if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.length > 0)))
       env.set_error ();
     else
+    {
+      if (!parsed_str->is_parsed ())
+        parsed_str->alloc (env.str_ref.total_size () / 2);
       current_parsed_str = parsed_str;
+    }
   }
 
   parsed_cs_str_t	*current_parsed_str;
@@ -506,7 +548,7 @@
   {
     global_remap.create (&closures.global_closure);
     for (unsigned int i = 0; i < local_remaps.length; i++)
-      local_remaps[i].create (&closures.local_closures[i]);
+      local_remaps.arrayZ[i].create (&closures.local_closures[i]);
   }
 
   subr_remap_t	       global_remap;
@@ -517,7 +559,8 @@
 struct subr_subsetter_t
 {
   subr_subsetter_t (ACC &acc_, const hb_subset_plan_t *plan_)
-      : acc (acc_), plan (plan_), closures(acc_.fdCount), remaps(acc_.fdCount)
+      : acc (acc_), plan (plan_), closures(acc_.fdCount),
+        remaps(acc_.fdCount)
   {}
 
   /* Subroutine subsetting with --no-desubroutinize runs in phases:
@@ -536,55 +579,96 @@
    */
   bool subset (void)
   {
-    parsed_charstrings.resize (plan->num_output_glyphs ());
-    parsed_global_subrs.resize (acc.globalSubrs->count);
+    unsigned fd_count = acc.fdCount;
+    const cff_subset_accelerator_t* cff_accelerator = nullptr;
+    if (plan->accelerator && plan->accelerator->cff_accelerator) {
+      cff_accelerator = plan->accelerator->cff_accelerator;
+      fd_count = cff_accelerator->parsed_local_subrs.length;
+    }
 
+    if (cff_accelerator) {
+      // If we are not dropping hinting then charstrings are not modified so we can
+      // just use a reference to the cached copies.
+      cached_charstrings.resize (plan->num_output_glyphs ());
+      parsed_global_subrs = &cff_accelerator->parsed_global_subrs;
+      parsed_local_subrs = &cff_accelerator->parsed_local_subrs;
+    } else {
+      parsed_charstrings.resize (plan->num_output_glyphs ());
+      parsed_global_subrs_storage.resize (acc.globalSubrs->count);
+
+      if (unlikely (!parsed_local_subrs_storage.resize (fd_count))) return false;
+
+      for (unsigned int i = 0; i < acc.fdCount; i++)
+      {
+        unsigned count = acc.privateDicts[i].localSubrs->count;
+        parsed_local_subrs_storage[i].resize (count);
+        if (unlikely (parsed_local_subrs_storage[i].in_error ())) return false;
+      }
+
+      parsed_global_subrs = &parsed_global_subrs_storage;
+      parsed_local_subrs = &parsed_local_subrs_storage;
+    }
+
     if (unlikely (remaps.in_error()
+                  || cached_charstrings.in_error ()
                   || parsed_charstrings.in_error ()
-                  || parsed_global_subrs.in_error ())) {
+                  || parsed_global_subrs->in_error ()
+                  || closures.in_error ())) {
       return false;
     }
 
-    if (unlikely (!parsed_local_subrs.resize (acc.fdCount))) return false;
-
-    for (unsigned int i = 0; i < acc.fdCount; i++)
-    {
-      parsed_local_subrs[i].resize (acc.privateDicts[i].localSubrs->count);
-      if (unlikely (parsed_local_subrs[i].in_error ())) return false;
-    }
-    if (unlikely (!closures.valid))
-      return false;
-
     /* phase 1 & 2 */
     for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
     {
       hb_codepoint_t  glyph;
       if (!plan->old_gid_for_new_gid (i, &glyph))
-	continue;
+        continue;
+
       const hb_ubytes_t str = (*acc.charStrings)[glyph];
       unsigned int fd = acc.fdSelect->get_fd (glyph);
       if (unlikely (fd >= acc.fdCount))
-	return false;
+        return false;
 
+      if (cff_accelerator)
+      {
+        // parsed string already exists in accelerator, copy it and move
+        // on.
+        if (cached_charstrings)
+          cached_charstrings[i] = &cff_accelerator->parsed_charstrings[glyph];
+        else
+          parsed_charstrings[i] = cff_accelerator->parsed_charstrings[glyph];
+
+        continue;
+      }
+
       ENV env (str, acc, fd);
       cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp (env);
 
-      parsed_charstrings[i].alloc (str.length);
+      parsed_charstrings[i].alloc (str.length / 2);
       subr_subset_param_t  param (&parsed_charstrings[i],
-				  &parsed_global_subrs,
-				  &parsed_local_subrs[fd],
-				  &closures.global_closure,
-				  &closures.local_closures[fd],
-				  plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
+                                  &parsed_global_subrs_storage,
+                                  &parsed_local_subrs_storage[fd],
+                                  &closures.global_closure,
+                                  &closures.local_closures[fd],
+                                  plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
 
       if (unlikely (!interp.interpret (param)))
-	return false;
+        return false;
 
       /* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
       SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]);
     }
 
-    if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+    // Since parsed strings were loaded from accelerator, we still need
+    // to compute the subroutine closures which would have normally happened during
+    // parsing.
+    if (cff_accelerator &&
+        !closure_subroutines(*parsed_global_subrs,
+                             *parsed_local_subrs))
+      return false;
+
+    if ((plan->flags & HB_SUBSET_FLAGS_NO_HINTING && !cff_accelerator) ||
+	plan->inprogress_accelerator)
     {
       /* mark hint ops and arguments for drop */
       for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
@@ -596,8 +680,8 @@
 	if (unlikely (fd >= acc.fdCount))
 	  return false;
 	subr_subset_param_t  param (&parsed_charstrings[i],
-				    &parsed_global_subrs,
-				    &parsed_local_subrs[fd],
+				    &parsed_global_subrs_storage,
+				    &parsed_local_subrs_storage[fd],
 				    &closures.global_closure,
 				    &closures.local_closures[fd],
 				    plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
@@ -612,27 +696,14 @@
       }
 
       /* after dropping hints recreate closures of actually used subrs */
-      closures.reset ();
-      for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
-      {
-	hb_codepoint_t  glyph;
-	if (!plan->old_gid_for_new_gid (i, &glyph))
-	  continue;
-	unsigned int fd = acc.fdSelect->get_fd (glyph);
-	if (unlikely (fd >= acc.fdCount))
-	  return false;
-	subr_subset_param_t  param (&parsed_charstrings[i],
-				    &parsed_global_subrs,
-				    &parsed_local_subrs[fd],
-				    &closures.global_closure,
-				    &closures.local_closures[fd],
-				    plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
-	collect_subr_refs_in_str (parsed_charstrings[i], param);
-      }
+      if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING &&
+	  !cff_accelerator &&
+	  !closure_subroutines(*parsed_global_subrs, *parsed_local_subrs)) return false;
     }
 
     remaps.create (closures);
 
+    populate_subset_accelerator ();
     return true;
   }
 
@@ -646,13 +717,13 @@
       if (!plan->old_gid_for_new_gid (i, &glyph))
       {
 	/* add an endchar only charstring for a missing glyph if CFF1 */
-	if (endchar_op != OpCode_Invalid) buffArray[i].push (endchar_op);
+	if (endchar_op != OpCode_Invalid) buffArray.arrayZ[i].push (endchar_op);
 	continue;
       }
       unsigned int  fd = acc.fdSelect->get_fd (glyph);
       if (unlikely (fd >= acc.fdCount))
 	return false;
-      if (unlikely (!encode_str (parsed_charstrings[i], fd, buffArray[i])))
+      if (unlikely (!encode_str (get_parsed_charstring (i), fd, buffArray.arrayZ[i])))
 	return false;
     }
     return true;
@@ -664,14 +735,13 @@
 
     if (unlikely (!buffArray.resize (count)))
       return false;
-    for (unsigned int old_num = 0; old_num < subrs.length; old_num++)
+    for (unsigned int new_num = 0; new_num < count; new_num++)
     {
-      hb_codepoint_t new_num = remap[old_num];
-      if (new_num != CFF_UNDEF_CODE)
-      {
-	if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num])))
-	  return false;
-      }
+      hb_codepoint_t old_num = remap.backward (new_num);
+      assert (old_num != CFF_UNDEF_CODE);
+
+      if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num])))
+	return false;
     }
     return true;
   }
@@ -678,12 +748,12 @@
 
   bool encode_globalsubrs (str_buff_vec_t &buffArray)
   {
-    return encode_subrs (parsed_global_subrs, remaps.global_remap, 0, buffArray);
+    return encode_subrs (*parsed_global_subrs, remaps.global_remap, 0, buffArray);
   }
 
   bool encode_localsubrs (unsigned int fd, str_buff_vec_t &buffArray) const
   {
-    return encode_subrs (parsed_local_subrs[fd], remaps.local_remaps[fd], fd, buffArray);
+    return encode_subrs ((*parsed_local_subrs)[fd], remaps.local_remaps[fd], fd, buffArray);
   }
 
   protected:
@@ -712,7 +782,7 @@
      * then this entire subroutine must be a hint. drop its call. */
     if (drop.ends_in_hint)
     {
-      str.values[pos].set_drop ();
+      str.values[pos].set_hinting ();
       /* if this subr call is at the end of the parent subr, propagate the flag
        * otherwise reset the flag */
       if (!str.at_end (pos))
@@ -720,7 +790,7 @@
     }
     else if (drop.all_dropped)
     {
-      str.values[pos].set_drop ();
+      str.values[pos].set_hinting ();
     }
 
     return has_hint;
@@ -731,20 +801,22 @@
   {
     bool  seen_hint = false;
 
-    for (unsigned int pos = 0; pos < str.values.length; pos++)
+    unsigned count = str.values.length;
+    auto *values = str.values.arrayZ;
+    for (unsigned int pos = 0; pos < count; pos++)
     {
       bool  has_hint = false;
-      switch (str.values[pos].op)
+      switch (values[pos].op)
       {
 	case OpCode_callsubr:
 	  has_hint = drop_hints_in_subr (str, pos,
-					*param.parsed_local_subrs, str.values[pos].subr_num,
+					*param.parsed_local_subrs, values[pos].subr_num,
 					param, drop);
 	  break;
 
 	case OpCode_callgsubr:
 	  has_hint = drop_hints_in_subr (str, pos,
-					*param.parsed_global_subrs, str.values[pos].subr_num,
+					*param.parsed_global_subrs, values[pos].subr_num,
 					param, drop);
 	  break;
 
@@ -758,7 +830,7 @@
 	case OpCode_cntrmask:
 	  if (drop.seen_moveto)
 	  {
-	    str.values[pos].set_drop ();
+	    values[pos].set_hinting ();
 	    break;
 	  }
 	  HB_FALLTHROUGH;
@@ -768,13 +840,13 @@
 	case OpCode_hstem:
 	case OpCode_vstem:
 	  has_hint = true;
-	  str.values[pos].set_drop ();
+	  values[pos].set_hinting ();
 	  if (str.at_end (pos))
 	    drop.ends_in_hint = true;
 	  break;
 
 	case OpCode_dotsection:
-	  str.values[pos].set_drop ();
+	  values[pos].set_hinting ();
 	  break;
 
 	default:
@@ -785,10 +857,10 @@
       {
 	for (int i = pos - 1; i >= 0; i--)
 	{
-	  parsed_cs_op_t  &csop = str.values[(unsigned)i];
-	  if (csop.for_drop ())
+	  parsed_cs_op_t  &csop = values[(unsigned)i];
+	  if (csop.is_hinting ())
 	    break;
-	  csop.set_drop ();
+	  csop.set_hinting ();
 	  if (csop.op == OpCode_vsindexcs)
 	    drop.vsindex_dropped = true;
 	}
@@ -801,12 +873,12 @@
      * only (usually one) hintmask operator, then calls to this subr can be dropped.
      */
     drop.all_dropped = true;
-    for (unsigned int pos = 0; pos < str.values.length; pos++)
+    for (unsigned int pos = 0; pos < count; pos++)
     {
-      parsed_cs_op_t  &csop = str.values[pos];
+      parsed_cs_op_t  &csop = values[pos];
       if (csop.op == OpCode_return)
 	break;
-      if (!csop.for_drop ())
+      if (!csop.is_hinting ())
       {
 	drop.all_dropped = false;
 	break;
@@ -816,32 +888,62 @@
     return seen_hint;
   }
 
-  void collect_subr_refs_in_subr (parsed_cs_str_t &str, unsigned int pos,
-				  unsigned int subr_num, parsed_cs_str_vec_t &subrs,
+  bool closure_subroutines (const parsed_cs_str_vec_t& global_subrs,
+                            const hb_vector_t<parsed_cs_str_vec_t>& local_subrs)
+  {
+    closures.reset ();
+    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+    {
+      hb_codepoint_t  glyph;
+      if (!plan->old_gid_for_new_gid (i, &glyph))
+        continue;
+      unsigned int fd = acc.fdSelect->get_fd (glyph);
+      if (unlikely (fd >= acc.fdCount))
+        return false;
+
+      // Note: const cast is safe here because the collect_subr_refs_in_str only performs a
+      //       closure and does not modify any of the charstrings.
+      subr_subset_param_t  param (const_cast<parsed_cs_str_t*> (&get_parsed_charstring (i)),
+                                  const_cast<parsed_cs_str_vec_t*> (&global_subrs),
+                                  const_cast<parsed_cs_str_vec_t*> (&local_subrs[fd]),
+                                  &closures.global_closure,
+                                  &closures.local_closures[fd],
+                                  plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
+      collect_subr_refs_in_str (get_parsed_charstring (i), param);
+    }
+
+    return true;
+  }
+
+  void collect_subr_refs_in_subr (unsigned int subr_num, parsed_cs_str_vec_t &subrs,
 				  hb_set_t *closure,
 				  const subr_subset_param_t &param)
   {
+    if (closure->has (subr_num))
+      return;
     closure->add (subr_num);
     collect_subr_refs_in_str (subrs[subr_num], param);
   }
 
-  void collect_subr_refs_in_str (parsed_cs_str_t &str, const subr_subset_param_t &param)
+  void collect_subr_refs_in_str (const parsed_cs_str_t &str,
+                                 const subr_subset_param_t &param)
   {
-    for (unsigned int pos = 0; pos < str.values.length; pos++)
+    if (!str.has_calls ())
+      return;
+
+    for (auto &opstr : str.values)
     {
-      if (!str.values[pos].for_drop ())
+      if (!param.drop_hints || !opstr.is_hinting ())
       {
-	switch (str.values[pos].op)
+	switch (opstr.op)
 	{
 	  case OpCode_callsubr:
-	    collect_subr_refs_in_subr (str, pos,
-				       str.values[pos].subr_num, *param.parsed_local_subrs,
+	    collect_subr_refs_in_subr (opstr.subr_num, *param.parsed_local_subrs,
 				       param.local_closure, param);
 	    break;
 
 	  case OpCode_callgsubr:
-	    collect_subr_refs_in_subr (str, pos,
-				       str.values[pos].subr_num, *param.parsed_global_subrs,
+	    collect_subr_refs_in_subr (opstr.subr_num, *param.parsed_global_subrs,
 				       param.global_closure, param);
 	    break;
 
@@ -853,44 +955,115 @@
 
   bool encode_str (const parsed_cs_str_t &str, const unsigned int fd, str_buff_t &buff) const
   {
-    unsigned count = str.get_count ();
     str_encoder_t  encoder (buff);
     encoder.reset ();
-    buff.alloc (count * 3);
+    bool hinting = !(plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
     /* if a prefix (CFF1 width or CFF2 vsindex) has been removed along with hints,
      * re-insert it at the beginning of charstreing */
-    if (str.has_prefix () && str.is_hint_dropped ())
+    if (str.has_prefix () && !hinting && str.is_hint_dropped ())
     {
       encoder.encode_num (str.prefix_num ());
       if (str.prefix_op () != OpCode_Invalid)
 	encoder.encode_op (str.prefix_op ());
     }
-    for (unsigned int i = 0; i < count; i++)
+
+    unsigned size = 0;
+    for (auto &opstr : str.values)
     {
-      const parsed_cs_op_t  &opstr = str.values[i];
-      if (!opstr.for_drop () && !opstr.for_skip ())
+      size += opstr.length;
+      if (opstr.op == OpCode_callsubr || opstr.op == OpCode_callgsubr)
+        size += 3;
+    }
+    if (!buff.alloc (buff.length + size))
+      return false;
+
+    for (auto &opstr : str.values)
+    {
+      if (hinting || !opstr.is_hinting ())
       {
 	switch (opstr.op)
 	{
 	  case OpCode_callsubr:
 	    encoder.encode_int (remaps.local_remaps[fd].biased_num (opstr.subr_num));
-	    encoder.encode_op (OpCode_callsubr);
+	    encoder.copy_str (opstr.ptr, opstr.length);
 	    break;
 
 	  case OpCode_callgsubr:
 	    encoder.encode_int (remaps.global_remap.biased_num (opstr.subr_num));
-	    encoder.encode_op (OpCode_callgsubr);
+	    encoder.copy_str (opstr.ptr, opstr.length);
 	    break;
 
 	  default:
-	    encoder.copy_str (opstr.str);
+	    encoder.copy_str (opstr.ptr, opstr.length);
 	    break;
 	}
       }
     }
-    return !encoder.is_error ();
+    return !encoder.in_error ();
   }
 
+  void compact_parsed_strings () const
+  {
+    for (auto &cs : parsed_charstrings)
+      compact_string (cs);
+    for (auto &cs : parsed_global_subrs_storage)
+      compact_string (cs);
+    for (auto &vec : parsed_local_subrs_storage)
+      for (auto &cs : vec)
+	compact_string (cs);
+  }
+
+  static void compact_string (parsed_cs_str_t &str)
+  {
+    unsigned count = str.values.length;
+    if (unlikely (!count)) return;
+    auto &opstr = str.values.arrayZ;
+    unsigned j = 0;
+    for (unsigned i = 1; i < count; i++)
+    {
+      /* See if we can combine op j and op i. */
+      bool combine =
+        (opstr[j].op != OpCode_callsubr && opstr[j].op != OpCode_callgsubr) &&
+        (opstr[i].op != OpCode_callsubr && opstr[i].op != OpCode_callgsubr) &&
+        (opstr[j].is_hinting () == opstr[i].is_hinting ()) &&
+        (opstr[j].ptr + opstr[j].length == opstr[i].ptr) &&
+        (opstr[j].length + opstr[i].length <= 255);
+
+      if (combine)
+      {
+	opstr[j].length += opstr[i].length;
+	opstr[j].op = OpCode_Invalid;
+      }
+      else
+      {
+	opstr[++j] = opstr[i];
+      }
+    }
+    str.values.shrink (j + 1);
+  }
+
+  void populate_subset_accelerator () const
+  {
+    if (!plan->inprogress_accelerator) return;
+
+    compact_parsed_strings ();
+
+    plan->inprogress_accelerator->cff_accelerator =
+        cff_subset_accelerator_t::create(acc.blob,
+                                         parsed_charstrings,
+                                         parsed_global_subrs_storage,
+                                         parsed_local_subrs_storage);
+    plan->inprogress_accelerator->destroy_cff_accelerator =
+        cff_subset_accelerator_t::destroy;
+
+  }
+
+  const parsed_cs_str_t& get_parsed_charstring (unsigned i) const
+  {
+    if (cached_charstrings) return *(cached_charstrings[i]);
+    return parsed_charstrings[i];
+  }
+
   protected:
   const ACC			&acc;
   const hb_subset_plan_t	*plan;
@@ -897,13 +1070,17 @@
 
   subr_closures_t		closures;
 
-  parsed_cs_str_vec_t		parsed_charstrings;
-  parsed_cs_str_vec_t		parsed_global_subrs;
-  hb_vector_t<parsed_cs_str_vec_t>  parsed_local_subrs;
+  hb_vector_t<const parsed_cs_str_t*>     cached_charstrings;
+  const parsed_cs_str_vec_t*              parsed_global_subrs;
+  const hb_vector_t<parsed_cs_str_vec_t>* parsed_local_subrs;
 
   subr_remaps_t			remaps;
 
   private:
+
+  parsed_cs_str_vec_t		parsed_charstrings;
+  parsed_cs_str_vec_t		parsed_global_subrs_storage;
+  hb_vector_t<parsed_cs_str_vec_t>  parsed_local_subrs_storage;
   typedef typename SUBRS::count_type subr_count_type;
 };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -167,9 +167,10 @@
 	   * for supplement, the original byte string is copied along with the op code */
 	  op_str_t supp_op;
 	  supp_op.op = op;
-	  if ( unlikely (!(opstr.str.length >= opstr.last_arg_offset + 3)))
+	  if ( unlikely (!(opstr.length >= opstr.last_arg_offset + 3)))
 	    return_trace (false);
-	  supp_op.str = hb_ubytes_t (&opstr.str + opstr.last_arg_offset, opstr.str.length - opstr.last_arg_offset);
+	  supp_op.ptr = opstr.ptr + opstr.last_arg_offset;
+	  supp_op.length = opstr.length - opstr.last_arg_offset;
 	  return_trace (UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::registry]) &&
 			UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) &&
 			copy_opstr (c, supp_op));
@@ -442,8 +443,17 @@
       return;
     }
 
-    bool use_glyph_to_sid_map = plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.;
-    hb_map_t *glyph_to_sid_map = use_glyph_to_sid_map ? acc.create_glyph_to_sid_map () : nullptr;
+    hb_map_t *glyph_to_sid_map = (plan->accelerator && plan->accelerator->cff_accelerator) ?
+				  plan->accelerator->cff_accelerator->glyph_to_sid_map :
+				  nullptr;
+    bool created_map = false;
+    if (!glyph_to_sid_map &&
+	((plan->accelerator && plan->accelerator->cff_accelerator) ||
+	 plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.))
+    {
+      created_map = true;
+      glyph_to_sid_map = acc.create_glyph_to_sid_map ();
+    }
 
     unsigned int glyph;
     for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
@@ -467,8 +477,12 @@
       last_sid = sid;
     }
 
-    if (glyph_to_sid_map)
-      hb_map_destroy (glyph_to_sid_map);
+    if (created_map)
+    {
+      if (!(plan->accelerator && plan->accelerator->cff_accelerator) ||
+	  !plan->accelerator->cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map))
+	hb_map_destroy (glyph_to_sid_map);
+    }
 
     bool two_byte = subset_charset_ranges.complete (glyph);
 
@@ -728,11 +742,17 @@
 
   /* CharStrings */
   {
+    c->push<CFF1CharStrings> ();
+
+    unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings);
+    if (unlikely (!c->start_zerocopy (total_size)))
+       return false;
+
     CFF1CharStrings  *cs = c->start_embed<CFF1CharStrings> ();
     if (unlikely (!cs)) return false;
-    c->push ();
+
     if (likely (cs->serialize (c, plan.subset_charstrings)))
-      plan.info.char_strings_link = c->pop_pack ();
+      plan.info.char_strings_link = c->pop_pack (false);
     else
     {
       c->pop_discard ();
@@ -815,7 +835,7 @@
     CFF1Subrs *dest = c->start_embed <CFF1Subrs> ();
     if (unlikely (!dest)) return false;
     if (likely (dest->serialize (c, plan.subset_globalsubrs)))
-      c->pop_pack ();
+      c->pop_pack (false);
     else
     {
       c->pop_discard ();

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -334,7 +334,7 @@
 	if (unlikely (!dest)) return false;
 	c->push ();
 	if (likely (dest->serialize (c, plan.subset_localsubrs[i])))
-	  subrs_link = c->pop_pack ();
+	  subrs_link = c->pop_pack (false);
 	else
 	{
 	  c->pop_discard ();
@@ -361,11 +361,17 @@
 
   /* CharStrings */
   {
+    c->push ();
+
+    unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings);
+    if (unlikely (!c->start_zerocopy (total_size)))
+       return false;
+
     CFF2CharStrings  *cs = c->start_embed<CFF2CharStrings> ();
     if (unlikely (!cs)) return false;
-    c->push ();
+
     if (likely (cs->serialize (c, plan.subset_charstrings)))
-      plan.info.char_strings_link = c->pop_pack ();
+      plan.info.char_strings_link = c->pop_pack (false);
     else
     {
       c->pop_discard ();
@@ -377,9 +383,10 @@
   if (acc.fdSelect != &Null (CFF2FDSelect))
   {
     c->push ();
-    if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect, 					      plan.orig_fdcount,
-					    plan.subset_fdselect_format, plan.subset_fdselect_size,
-					    plan.subset_fdselect_ranges)))
+    if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect,
+					   plan.orig_fdcount,
+					   plan.subset_fdselect_format, plan.subset_fdselect_size,
+					   plan.subset_fdselect_ranges)))
       plan.info.fd_select.link = c->pop_pack ();
     else
     {
@@ -401,7 +408,7 @@
 	      hb_iter (private_dict_infos))
     ;
     if (unlikely (!fda->serialize (c, it, fontSzr))) return false;
-    plan.info.fd_array_link = c->pop_pack ();
+    plan.info.fd_array_link = c->pop_pack (false);
   }
 
   /* variation store */
@@ -410,7 +417,7 @@
     c->push ();
     CFF2VariationStore *dest = c->start_embed<CFF2VariationStore> ();
     if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false;
-    plan.info.var_store_link = c->pop_pack ();
+    plan.info.var_store_link = c->pop_pack (false);
   }
 
   OT::cff2 *cff2 = c->allocate_min<OT::cff2> ();

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -26,7 +26,7 @@
 
 #include "hb-subset.hh"
 #include "hb-set.hh"
-
+#include "hb-utf.hh"
 /**
  * hb_subset_input_create_or_fail:
  *
@@ -49,8 +49,15 @@
     set = hb_set_create ();
 
   input->axes_location = hb_hashmap_create<hb_tag_t, float> ();
+#ifdef HB_EXPERIMENTAL_API
+  input->name_table_overrides = hb_hashmap_create<hb_ot_name_record_ids_t, hb_bytes_t> ();
+#endif
 
-  if (!input->axes_location || input->in_error ())
+  if (!input->axes_location ||
+#ifdef HB_EXPERIMENTAL_API
+      !input->name_table_overrides ||
+#endif
+      input->in_error ())
   {
     hb_subset_input_destroy (input);
     return nullptr;
@@ -248,6 +255,15 @@
 
   hb_hashmap_destroy (input->axes_location);
 
+#ifdef HB_EXPERIMENTAL_API
+  if (input->name_table_overrides)
+  {
+    for (auto _ : *input->name_table_overrides)
+      _.second.fini ();
+  }
+  hb_hashmap_destroy (input->name_table_overrides);
+#endif
+
   hb_free (input);
 }
 
@@ -379,7 +395,6 @@
   return hb_object_get_user_data (input, key);
 }
 
-#ifdef HB_EXPERIMENTAL_API
 #ifndef HB_NO_VAR
 /**
  * hb_subset_input_pin_axis_to_default: (skip)
@@ -388,9 +403,12 @@
  *
  * Pin an axis to its default location in the given subset input object.
  *
+ * Currently only works for fonts with 'glyf' tables. CFF and CFF2 is not
+ * yet supported. Additionally all axes in a font must be pinned.
+ *
  * Return value: `true` if success, `false` otherwise
  *
- * Since: EXPERIMENTAL
+ * Since: 6.0.0
  **/
 HB_EXTERN hb_bool_t
 hb_subset_input_pin_axis_to_default (hb_subset_input_t  *input,
@@ -412,9 +430,12 @@
  *
  * Pin an axis to a fixed location in the given subset input object.
  *
+ * Currently only works for fonts with 'glyf' tables. CFF and CFF2 is not
+ * yet supported. Additionally all axes in a font must be pinned.
+ *
  * Return value: `true` if success, `false` otherwise
  *
- * Since: EXPERIMENTAL
+ * Since: 6.0.0
  **/
 HB_EXTERN hb_bool_t
 hb_subset_input_pin_axis_location (hb_subset_input_t  *input,
@@ -430,18 +451,26 @@
   return input->axes_location->set (axis_tag, val);
 }
 #endif
-#endif
 
-#ifdef HB_EXPERIMENTAL_API
 /**
- * hb_subset_preprocess
- * @input: a #hb_face_t object.
+ * hb_subset_preprocess:
+ * @source: a #hb_face_t object.
  *
  * Preprocesses the face and attaches data that will be needed by the
  * subsetter. Future subsetting operations can then use the precomputed data
  * to speed up the subsetting operation.
  *
- * Since: EXPERIMENTAL
+ * See [subset-preprocessing](https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md)
+ * for more information.
+ *
+ * Note: the preprocessed face may contain sub-blobs that reference the memory
+ * backing the source #hb_face_t. Therefore in the case that this memory is not
+ * owned by the source face you will need to ensure that memory lives
+ * as long as the returned #hb_face_t.
+ *
+ * Returns: a new #hb_face_t.
+ *
+ * Since: 6.0.0
  **/
 
 HB_EXTERN hb_face_t *
@@ -448,10 +477,15 @@
 hb_subset_preprocess (hb_face_t *source)
 {
   hb_subset_input_t* input = hb_subset_input_create_or_fail ();
+  if (!input)
+    return source;
 
   hb_set_clear (hb_subset_input_set(input, HB_SUBSET_SETS_UNICODE));
   hb_set_invert (hb_subset_input_set(input, HB_SUBSET_SETS_UNICODE));
 
+  hb_set_clear (hb_subset_input_set(input, HB_SUBSET_SETS_GLYPH_INDEX));
+  hb_set_invert (hb_subset_input_set(input, HB_SUBSET_SETS_GLYPH_INDEX));
+
   hb_set_clear (hb_subset_input_set(input,
                                     HB_SUBSET_SETS_LAYOUT_FEATURE_TAG));
   hb_set_invert (hb_subset_input_set(input,
@@ -467,15 +501,100 @@
   hb_set_invert (hb_subset_input_set(input,
                                      HB_SUBSET_SETS_NAME_ID));
 
+  hb_set_clear (hb_subset_input_set(input,
+                                    HB_SUBSET_SETS_NAME_LANG_ID));
+  hb_set_invert (hb_subset_input_set(input,
+                                     HB_SUBSET_SETS_NAME_LANG_ID));
+
   hb_subset_input_set_flags(input,
                             HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
                             HB_SUBSET_FLAGS_GLYPH_NAMES |
-                            HB_SUBSET_FLAGS_RETAIN_GIDS);
+                            HB_SUBSET_FLAGS_RETAIN_GIDS |
+                            HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES);
   input->attach_accelerator_data = true;
 
+  // Always use long loca in the preprocessed version. This allows
+  // us to store the glyph bytes unpadded which allows the future subset
+  // operation to run faster by skipping the trim padding step.
+  input->force_long_loca = true;
+
   hb_face_t* new_source = hb_subset_or_fail (source, input);
   hb_subset_input_destroy (input);
 
+  if (!new_source) {
+    DEBUG_MSG (SUBSET, nullptr, "Preprocessing failed due to subset failure.");
+    return source;
+  }
+
   return new_source;
 }
+
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_subset_input_override_name_table:
+ * @input: a #hb_subset_input_t object.
+ * @name_id: name_id of a nameRecord
+ * @platform_id: platform ID of a nameRecord
+ * @encoding_id: encoding ID of a nameRecord
+ * @language_id: language ID of a nameRecord
+ * @name_str: pointer to name string new value or null to indicate should remove
+ * @str_len: the size of @name_str, or -1 if it is `NULL`-terminated
+ *
+ * Override the name string of the NameRecord identified by name_id,
+ * platform_id, encoding_id and language_id. If a record with that name_id
+ * doesn't exist, create it and insert to the name table.
+ *
+ * Note: for mac platform, we only support name_str with all ascii characters,
+ * name_str with non-ascii characters will be ignored.
+ *
+ * Since: EXPERIMENTAL
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_override_name_table (hb_subset_input_t  *input,
+                                     hb_ot_name_id_t     name_id,
+                                     unsigned            platform_id,
+                                     unsigned            encoding_id,
+                                     unsigned            language_id,
+                                     const char         *name_str,
+                                     int                 str_len /* -1 means nul-terminated */)
+{
+  if (!name_str)
+  {
+    str_len = 0;
+  }
+  else if (str_len == -1)
+  {
+      str_len = strlen (name_str);
+  }
+
+  hb_bytes_t name_bytes (nullptr, 0);
+  if (str_len)
+  {
+    if (platform_id == 1)
+    {
+      const uint8_t *src = reinterpret_cast<const uint8_t*> (name_str);
+      const uint8_t *src_end = src + str_len;
+
+      hb_codepoint_t unicode;
+      const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+      while (src < src_end)
+      {
+        src = hb_utf8_t::next (src, src_end, &unicode, replacement);
+        if (unicode >= 0x0080u)
+        {
+          printf ("Non-ascii character detected, ignored...This API supports acsii characters only for mac platform\n");
+          return false;
+        }
+      }
+    }
+    char *override_name = (char *) hb_malloc (str_len);
+    if (unlikely (!override_name)) return false;
+
+    hb_memcpy (override_name, name_str, str_len);
+    name_bytes = hb_bytes_t (override_name, str_len);
+  }
+  input->name_table_overrides->set (hb_ot_name_record_ids_t (platform_id, encoding_id, language_id, name_id), name_bytes);
+  return true;
+}
+
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -36,6 +36,48 @@
 
 #include "hb-font.hh"
 
+struct hb_ot_name_record_ids_t
+{
+  hb_ot_name_record_ids_t () = default;
+  hb_ot_name_record_ids_t (unsigned platform_id_,
+                           unsigned encoding_id_,
+                           unsigned language_id_,
+                           unsigned name_id_)
+      :platform_id (platform_id_),
+      encoding_id (encoding_id_),
+      language_id (language_id_),
+      name_id (name_id_) {}
+
+  bool operator != (const hb_ot_name_record_ids_t o) const
+  { return !(*this == o); }
+
+  inline bool operator == (const hb_ot_name_record_ids_t& o) const
+  {
+    return platform_id == o.platform_id &&
+           encoding_id == o.encoding_id &&
+           language_id == o.language_id &&
+           name_id == o.name_id;
+  }
+
+  inline uint32_t hash () const
+  {
+    uint32_t current = 0;
+    current = current * 31 + hb_hash (platform_id);
+    current = current * 31 + hb_hash (encoding_id);
+    current = current * 31 + hb_hash (language_id);
+    current = current * 31 + hb_hash (name_id);
+    return current;
+  }
+
+  unsigned platform_id;
+  unsigned encoding_id;
+  unsigned language_id;
+  unsigned name_id;
+};
+
+typedef struct hb_ot_name_record_ids_t hb_ot_name_record_ids_t;
+
+
 HB_MARK_AS_FLAG_T (hb_subset_flags_t);
 
 struct hb_subset_input_t
@@ -60,7 +102,14 @@
 
   unsigned flags;
   bool attach_accelerator_data = false;
+
+  // If set loca format will always be the long version.
+  bool force_long_loca = false;
+
   hb_hashmap_t<hb_tag_t, float> *axes_location;
+#ifdef HB_EXPERIMENTAL_API
+  hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides;
+#endif
 
   inline unsigned num_sets () const
   {
@@ -80,7 +129,11 @@
         return true;
     }
 
-    return axes_location->in_error ();
+    return axes_location->in_error ()
+#ifdef HB_EXPERIMENTAL_API
+	|| name_table_overrides->in_error ()
+#endif
+	;
   }
 };
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -27,6 +27,7 @@
 #include "hb-subset-plan.hh"
 #include "hb-subset-accelerator.hh"
 #include "hb-map.hh"
+#include "hb-multimap.hh"
 #include "hb-set.hh"
 
 #include "hb-ot-cmap-table.hh"
@@ -47,7 +48,7 @@
 
 typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map;
 #ifndef HB_NO_SUBSET_CFF
-static inline void
+static inline bool
 _add_cff_seac_components (const OT::cff1::accelerator_t &cff,
 			  hb_codepoint_t gid,
 			  hb_set_t *gids_to_retain)
@@ -57,7 +58,9 @@
   {
     gids_to_retain->add (base_gid);
     gids_to_retain->add (accent_gid);
+    return true;
   }
+  return false;
 }
 #endif
 
@@ -82,11 +85,9 @@
 _remap_indexes (const hb_set_t *indexes,
 		hb_map_t       *mapping /* OUT */)
 {
-  unsigned count = indexes->get_population ();
+  for (auto _ : + hb_enumerate (indexes->iter ()))
+    mapping->set (_.second, _.first);
 
-  for (auto _ : + hb_zip (indexes->iter (), hb_range (count)))
-    mapping->set (_.first, _.second);
-
 }
 
 #ifndef HB_NO_SUBSET_LAYOUT
@@ -344,7 +345,9 @@
     vars.push (var);
   }
 
+#ifndef HB_NO_VAR
   hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
+#endif
   return font;
 }
 
@@ -521,16 +524,46 @@
       cmap_unicodes = &plan->accelerator->unicodes;
     }
 
-    for (hb_codepoint_t cp : *cmap_unicodes)
+    if (plan->accelerator &&
+	unicodes->get_population () < cmap_unicodes->get_population () &&
+	glyphs->get_population () < cmap_unicodes->get_population ())
     {
-      hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
-      if (!unicodes->has (cp) && !glyphs->has (gid))
-        continue;
+      auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes;
+      for (hb_codepoint_t gid : *glyphs)
+      {
+        auto unicodes = gid_to_unicodes.get (gid);
 
-      plan->codepoint_to_glyph->set (cp, gid);
-      plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+	for (hb_codepoint_t cp : unicodes)
+	{
+	  plan->codepoint_to_glyph->set (cp, gid);
+	  plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+	}
+      }
+      for (hb_codepoint_t cp : *unicodes)
+      {
+	/* Don't double-add entry. */
+	if (plan->codepoint_to_glyph->has (cp))
+	  continue;
+
+	hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
+	plan->codepoint_to_glyph->set (cp, gid);
+	plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+      }
+      plan->unicode_to_new_gid_list.qsort ();
     }
+    else
+    {
+      for (hb_codepoint_t cp : *cmap_unicodes)
+      {
+	hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
+	if (!unicodes->has (cp) && !glyphs->has (gid))
+	  continue;
 
+	plan->codepoint_to_glyph->set (cp, gid);
+	plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+      }
+    }
+
     /* Add gids which where requested, but not mapped in cmap */
     for (hb_codepoint_t gid : *glyphs)
     {
@@ -639,9 +672,15 @@
   else
     plan->_glyphset->union_ (cur_glyphset);
 #ifndef HB_NO_SUBSET_CFF
-  if (cff.is_valid ())
-    for (hb_codepoint_t gid : cur_glyphset)
-      _add_cff_seac_components (cff, gid, plan->_glyphset);
+  if (!plan->accelerator || plan->accelerator->has_seac)
+  {
+    bool has_seac = false;
+    if (cff.is_valid ())
+      for (hb_codepoint_t gid : cur_glyphset)
+	if (_add_cff_seac_components (cff, gid, plan->_glyphset))
+	  has_seac = true;
+    plan->has_seac = has_seac;
+  }
 #endif
 
   _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
@@ -848,9 +887,28 @@
   plan->check_success (plan->vmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
   plan->check_success (plan->hmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
 
+#ifdef HB_EXPERIMENTAL_API
+  plan->check_success (plan->name_table_overrides = hb_hashmap_create<hb_ot_name_record_ids_t, hb_bytes_t> ());
+  if (plan->name_table_overrides && input->name_table_overrides)
+  {
+    for (auto _ : *input->name_table_overrides)
+    {
+      hb_bytes_t name_bytes = _.second;
+      unsigned len = name_bytes.length;
+      char *name_str = (char *) hb_malloc (len);
+      if (unlikely (!plan->check_success (name_str)))
+        break;
+
+      hb_memcpy (name_str, name_bytes.arrayZ, len);
+      plan->name_table_overrides->set (_.first, hb_bytes_t (name_str, len));
+    }
+  }
+#endif
+
   void* accel = hb_face_get_user_data(face, hb_subset_accelerator_t::user_data_key());
 
   plan->attach_accelerator_data = input->attach_accelerator_data;
+  plan->force_long_loca = input->force_long_loca;
   if (accel)
     plan->accelerator = (hb_subset_accelerator_t*) accel;
 
@@ -893,6 +951,28 @@
     hb_subset_plan_destroy (plan);
     return nullptr;
   }
+
+
+  if (plan->attach_accelerator_data)
+  {
+    hb_multimap_t gid_to_unicodes;
+
+    hb_map_t &unicode_to_gid = *plan->codepoint_to_glyph;
+
+    for (auto unicode : *plan->unicodes)
+    {
+      auto gid = unicode_to_gid[unicode];
+      gid_to_unicodes.add (gid, unicode);
+    }
+
+    plan->inprogress_accelerator =
+      hb_subset_accelerator_t::create (*plan->codepoint_to_glyph,
+				       gid_to_unicodes,
+                                       *plan->unicodes,
+				       plan->has_seac);
+  }
+
+
   return plan;
 }
 

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-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -87,6 +87,18 @@
     hb_hashmap_destroy (vmtx_map);
     hb_hashmap_destroy (layout_variation_idx_delta_map);
 
+#ifdef HB_EXPERIMENTAL_API
+    if (name_table_overrides)
+    {
+      for (auto _ : *name_table_overrides)
+        _.second.fini ();
+    }
+    hb_hashmap_destroy (name_table_overrides);
+#endif
+
+    if (inprogress_accelerator)
+      hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator);
+
     if (user_axes_location)
     {
       hb_object_destroy (user_axes_location);
@@ -99,10 +111,11 @@
   bool successful;
   unsigned flags;
   bool attach_accelerator_data = false;
+  bool force_long_loca = false;
 
   // For each cp that we'd like to retain maps to the corresponding gid.
   hb_set_t *unicodes;
-  hb_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list;
+  hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list;
 
   // name_ids we would like to retain
   hb_set_t *name_ids;
@@ -185,6 +198,7 @@
   hb_map_t *axes_old_index_tag_map;
   bool all_axes_pinned;
   bool pinned_at_default;
+  bool has_seac;
 
   //hmtx metrics map: new gid->(advance, lsb)
   hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *hmtx_map;
@@ -191,7 +205,14 @@
   //vmtx metrics map: new gid->(advance, lsb)
   hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *vmtx_map;
 
+#ifdef HB_EXPERIMENTAL_API
+  // name table overrides map: hb_ot_name_record_ids_t-> name string new value or
+  // None to indicate should remove
+  hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides;
+#endif
+
   const hb_subset_accelerator_t* accelerator;
+  hb_subset_accelerator_t* inprogress_accelerator;
 
  public:
 
@@ -198,18 +219,20 @@
   template<typename T>
   hb_blob_ptr_t<T> source_table()
   {
-    if (sanitized_table_cache
-        && !sanitized_table_cache->in_error ()
-        && sanitized_table_cache->has (T::tableTag)) {
-      return hb_blob_reference (sanitized_table_cache->get (T::tableTag).get ());
+    hb_lock_t (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
+
+    auto *cache = accelerator ? &accelerator->sanitized_table_cache : sanitized_table_cache;
+    if (cache
+        && !cache->in_error ()
+        && cache->has (+T::tableTag)) {
+      return hb_blob_reference (cache->get (+T::tableTag).get ());
     }
 
     hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (source)};
     hb_blob_t* ret = hb_blob_reference (table_blob.get ());
 
-    if (likely (sanitized_table_cache))
-      sanitized_table_cache->set (T::tableTag,
-                                  std::move (table_blob));
+    if (likely (cache))
+      cache->set (+T::tableTag, std::move (table_blob));
 
     return ret;
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -82,6 +82,10 @@
  * retain glyph ids option and configure the subset to pass through the layout tables untouched.
  */
 
+
+hb_user_data_key_t _hb_subset_accelerator_user_data_key = {};
+
+
 /*
  * The list of tables in the open type spec. Used to check for tables that may need handling
  * if we are unable to list the tables in a face.
@@ -409,20 +413,14 @@
 
 static bool
 _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag,
-                         hb_set_t &visited_set, hb_set_t &revisit_set)
+                         const hb_set_t &subsetted_tags,
+                         const hb_set_t &pending_subset_tags)
 {
   switch (tag)
   {
   case HB_OT_TAG_hmtx:
   case HB_OT_TAG_vmtx:
-    if (!plan->pinned_at_default &&
-        !visited_set.has (HB_OT_TAG_glyf))
-    {
-      revisit_set.add (tag);
-      return false;
-    }
-    return true;
-
+    return plan->pinned_at_default || !pending_subset_tags.has (HB_OT_TAG_glyf);
   default:
     return true;
   }
@@ -495,13 +493,15 @@
   }
 }
 
-static void _attach_accelerator_data (const hb_subset_plan_t* plan,
+static void _attach_accelerator_data (hb_subset_plan_t* plan,
                                       hb_face_t* face /* IN/OUT */)
 {
-  hb_subset_accelerator_t* accel =
-      hb_subset_accelerator_t::create (*plan->codepoint_to_glyph,
-                                       *plan->unicodes);
+  if (!plan->inprogress_accelerator) return;
 
+  // Transfer the accelerator from the plan to us.
+  hb_subset_accelerator_t* accel = plan->inprogress_accelerator;
+  plan->inprogress_accelerator = nullptr;
+
   if (accel->in_error ())
   {
     hb_subset_accelerator_t::destroy (accel);
@@ -508,6 +508,11 @@
     return;
   }
 
+  // Populate caches that need access to the final tables.
+  hb_blob_ptr_t<OT::cmap> cmap_ptr (hb_sanitize_context_t ().reference_table<OT::cmap> (face));
+  accel->cmap_cache = OT::cmap::create_filled_cache (cmap_ptr);
+  accel->destroy_cmap_cache = OT::SubtableUnicodesCache::destroy;
+
   if (!hb_face_set_user_data(face,
                              hb_subset_accelerator_t::user_data_key(),
                              accel,
@@ -561,41 +566,63 @@
     return nullptr;
   }
 
-  hb_set_t tags_set, revisit_set;
-  bool success = true;
   hb_tag_t table_tags[32];
   unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
-  hb_vector_t<char> buf;
-  buf.alloc (4096 - 16);
 
+  hb_set_t subsetted_tags, pending_subset_tags;
   while (((void) _get_table_tags (plan, offset, &num_tables, table_tags), num_tables))
   {
     for (unsigned i = 0; i < num_tables; ++i)
     {
       hb_tag_t tag = table_tags[i];
-      if (_should_drop_table (plan, tag) && !tags_set.has (tag)) continue;
-      if (!_dependencies_satisfied (plan, tag, tags_set, revisit_set)) continue;
-      tags_set.add (tag);
-      success = _subset_table (plan, buf, tag);
-      if (unlikely (!success)) goto end;
+      if (_should_drop_table (plan, tag)) continue;
+      pending_subset_tags.add (tag);
     }
 
-    /*delayed subsetting for some tables since they might have dependency on other tables in some cases:
-    e.g: during instantiating glyf tables, hmetrics/vmetrics are updated and saved in subset plan,
-    hmtx/vmtx subsetting need to use these updated metrics values*/
-    while (!revisit_set.is_empty ())
+    offset += num_tables;
+  }
+
+  hb_vector_t<char> buf;
+  buf.alloc (4096 - 16);
+
+
+  bool success = true;
+
+  while (!pending_subset_tags.is_empty ())
+  {
+    if (subsetted_tags.in_error ()
+        || pending_subset_tags.in_error ()) {
+      success = false;
+      goto end;
+    }
+
+    bool made_changes = false;
+    for (hb_tag_t tag : pending_subset_tags)
     {
-      hb_set_t revisit_temp;
-      for (hb_tag_t tag : revisit_set)
+      if (!_dependencies_satisfied (plan, tag,
+                                    subsetted_tags,
+                                    pending_subset_tags))
       {
-        if (!_dependencies_satisfied (plan, tag, tags_set, revisit_temp)) continue;
-        tags_set.add (tag);
-        success = _subset_table (plan, buf, tag);
-        if (unlikely (!success)) goto end;
+        // delayed subsetting for some tables since they might have dependency on other tables
+        // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated
+        // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values
+        continue;
       }
-      revisit_set = revisit_temp;
+
+      pending_subset_tags.del (tag);
+      subsetted_tags.add (tag);
+      made_changes = true;
+
+      success = _subset_table (plan, buf, tag);
+      if (unlikely (!success)) goto end;
     }
-    offset += num_tables;
+
+    if (!made_changes)
+    {
+      DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed.");
+      success = false;
+      goto end;
+    }
   }
 
   if (success && plan->attach_accelerator_data) {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2022-12-18 01:06:39 UTC (rev 65304)
@@ -28,6 +28,7 @@
 #define HB_SUBSET_H
 
 #include "hb.h"
+#include "hb-ot.h"
 
 HB_BEGIN_DECLS
 
@@ -164,8 +165,6 @@
 hb_subset_input_set_flags (hb_subset_input_t *input,
 			   unsigned value);
 
-#ifdef HB_EXPERIMENTAL_API
-#ifndef HB_NO_VAR
 HB_EXTERN hb_bool_t
 hb_subset_input_pin_axis_to_default (hb_subset_input_t  *input,
 				     hb_face_t          *face,
@@ -176,16 +175,22 @@
 				   hb_face_t          *face,
 				   hb_tag_t            axis_tag,
 				   float               axis_value);
-#endif
-#endif
 
 #ifdef HB_EXPERIMENTAL_API
+HB_EXTERN hb_bool_t
+hb_subset_input_override_name_table (hb_subset_input_t  *input,
+				     hb_ot_name_id_t     name_id,
+				     unsigned            platform_id,
+				     unsigned            encoding_id,
+				     unsigned            language_id,
+				     const char         *name_str,
+				     int                 str_len);
 
+#endif
+
 HB_EXTERN hb_face_t *
 hb_subset_preprocess (hb_face_t *source);
 
-#endif
-
 HB_EXTERN hb_face_t *
 hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -1069,7 +1069,7 @@
 #ifndef HB_OPTIMIZE_SIZE
 
 static const uint8_t
-_hb_ucd_u8[18260] =
+_hb_ucd_u8[17868] =
 {
     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  9, 10,  7,  7,  7,  7, 11, 12, 13, 13, 13, 14,
@@ -1535,191 +1535,166 @@
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0, 37,  0,  0,  0,  0,  0,  0,  0,
     0,  0, 38, 39,  0,  0,  0,  0,  0,  0, 40, 41, 42,  0, 43,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  0,  0,  0,  0,
-    0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  6,  7,  8,  0,
-    9,  0, 10, 11,  0,  0, 12, 13, 14, 15, 16,  0,  0,  0,  0, 17,
-   18, 19, 20,  0, 21,  0, 22, 23,  0, 24, 25,  0,  0, 24, 26, 27,
-    0, 24, 26,  0,  0, 24, 26,  0,  0, 24, 26,  0,  0,  0, 26,  0,
-    0, 24, 28,  0,  0, 24, 26,  0,  0, 29, 26,  0,  0,  0, 30,  0,
-    0, 31, 32,  0,  0, 33, 34,  0, 35, 36,  0, 37, 38,  0, 39,  0,
-    0, 40,  0,  0, 41,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 42,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 43, 44,  0,  0,  0,  0, 45,  0,
-    0,  0,  0,  0,  0, 46,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0,
-   48,  0,  0, 49,  0, 50, 51,  0,  0, 52, 53, 54,  0, 55,  0, 56,
-    0, 57,  0,  0,  0,  0, 58, 59,  0,  0,  0,  0,  0,  0, 60, 61,
-    0,  0,  0,  0,  0,  0, 62, 63,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 64,  0,  0,  0, 65,  0,  0,  0, 66,
-    0, 67,  0,  0, 68,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0, 69, 70,  0,  0, 71,  0,  0,  0,  0,  0,  0,  0,  0,
-   72, 73,  0,  0,  0,  0, 53, 74,  0, 75, 76,  0,  0, 77, 78,  0,
-    0,  0,  0,  0,  0, 79, 80, 81,  0,  0,  0,  0,  0,  0,  0, 26,
-    0,  0,  0,  0,  0,  0,  0,  0, 82,  0,  0,  0,  0,  0,  0,  0,
-    0, 83,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 84,
-    0,  0,  0,  0,  0,  0,  0, 85,  0,  0,  0, 86,  0,  0,  0,  0,
-   87, 88,  0,  0,  0,  0,  0, 89,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0, 90,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0, 91,  0, 92,  0,  0, 93,  0, 94,  0,  0,  0,
-    0,  0, 72, 95,  0, 96,  0,  0, 97, 98,  0, 77,  0,  0, 99,  0,
-    0,100,  0,  0,  0,  0,  0,101,  0,102, 26,103,  0,  0,  0,  0,
-    0,  0,104,  0,  0,  0,105,  0,  0,  0,  0,  0,  0, 65,106,  0,
-    0, 65,  0,  0,  0,107,  0,  0,  0,108,  0,  0,  0,  0,  0,  0,
-    0, 96,  0,  0,  0,  0,  0,  0,  0,109,110,  0,  0,  0,  0, 78,
-    0, 44,111,  0,112,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0, 65,  0,  0,  0,  0,  0,  0,  0,  0,113,  0,114,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,115,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,116,  0,117,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,118,
-    0,  0,  0,  0,119,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,120,121,122,  0,  0,
-    0,  0,123,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-  124,125,  0,  0,126,  0,  0,  0,  0,117,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,127,  0,128,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,129,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,130,  0,  0,  0,131,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  3,  4,
-    5,  6,  7,  4,  4,  8,  9, 10,  1, 11, 12, 13, 14, 15, 16, 17,
-   18,  1,  1,  1,  0,  0,  0,  0, 19,  1,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 20, 21, 22,  1, 23,  4, 21, 24, 25, 26, 27, 28,
-   29, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1, 31,  0,
-    0,  0, 32, 33, 34, 35,  1, 36,  0,  0,  0,  0, 37,  0,  0,  0,
-    0,  0,  0,  0,  0, 38,  1, 39, 14, 39, 40, 41,  0,  0,  0,  0,
-    0,  0,  0,  0, 42,  0,  0,  0,  0,  0,  0,  0, 43, 36, 44, 45,
-   21, 45, 46,  0,  0,  0,  0,  0,  0,  0, 19,  1, 21,  0,  0, 47,
-    0,  0,  0,  0,  0, 38, 48,  1,  1, 49, 49, 50,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 51,  0,  0,  0,  0,  0,  0,  0, 52,  1,
-    0,  0, 38, 14,  4,  1,  1,  1, 53, 21, 43, 52, 54, 21, 35,  1,
-    0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0, 56, 57, 58,  0,  0,
-    0,  0,  0, 56,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 59,
-    0,  0,  0, 56,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0, 61, 62,
-    0,  0, 63,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 64,  0,
-    0,  0, 65,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 66,  0,
-    0,  0, 67,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 68,  0,
-    0,  0,  0,  0,  0, 69, 70,  0,  0,  0,  0,  0, 71, 72, 73, 74,
-   75, 76,  0,  0,  0,  0,  0,  0,  0, 77,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0, 78, 79,  0,  0,  0,  0, 47,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 49,  0,  0,  0,  0,  0, 80,  0,  0,
-    0,  0,  0,  0,  0, 62,  0,  0,  0,  0,  0,  0, 63,  0,  0, 81,
-    0,  0, 82,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 83,  0,
-    0,  0,  0,  0,  0, 19, 84,  0, 62,  0,  0,  0,  0, 49,  1, 85,
-    0,  0,  0,  0,  1, 52, 15, 86, 36, 10, 21, 87,  0,  0,  0,  0,
-    0,  0,  0,  0,  0, 55,  0,  0,  0, 62,  0,  0,  0,  0,  0,  0,
-    0,  0, 19, 10,  1,  0,  0,  0,  0,  0, 88,  0,  0,  0,  0,  0,
-    0, 89,  0,  0, 88,  0,  0,  0,  0,  0,  0,  0,  0, 78,  0,  0,
-    0,  0,  0,  0, 87,  9, 12,  4, 90,  8, 91, 47,  0, 58, 50,  0,
-   21,  1, 21, 92, 93,  1,  1,  1,  1,  1,  1,  1,  1, 94, 95, 96,
-    0,  0,  0,  0, 97,  1, 98, 58, 81, 99,100,  4, 58,  0,  0,  0,
-    0,  0,  0, 19, 50,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 61,
-    1,  1,  1,  1,  1,  1,  1,  1,  0,  0,101,102,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,103,  0,  0,  0,  0, 19,  0,  1,  1, 50,
-    0,  0,  0,  0,  0,  0,  0, 38,  0,  0,  0,  0, 50,  0,  0,  0,
-    0, 63,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0,  0,
-    1,  1,  1,  1, 50,  0,  0,  0,  0,  0,104, 68,  0,  0,  0,  0,
-    0,  0,  0,  0, 61,  0,  0,  0,  0,  0,  0,  0, 78,  0,  0,  0,
-   62,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,106, 58, 38,
-   81,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 63,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,107,  1, 14,  4, 12,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 47, 84,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0, 38, 87,  0,  0,  0,  0,108,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,109, 61,  0,110,  0,  0,  0,  0,  0,  0,
-    0,  1,  0,  0,  0,  0,  0,  0,  0,  0, 19, 58,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 51,  0,111, 14, 52, 84,  0,  0,  0,
-  112, 41,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0, 61,
-    0,  0,  0,  0,  0,  0,113,  0, 87,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 61, 62,  0,  0, 62,  0, 89,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,113,  0,  0,  0,  0,114,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 78, 55,  0, 38,  1, 58,  1, 58,  0,  0,
-   63, 89,  0,  0,  0,  0,  0, 59,115,  0,  0,  0,  0,  0,  0,  0,
-   55,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,115,  0,  0,
-    0,  0, 61,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 79,
-   78,  0,  0,  0,  0,  0,  0,  0,  0, 61,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 56,  0, 89, 80,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0, 61,  0,  0, 79,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  8, 91,  0,  0,  0,  0,  0,  0,  1, 87,  0,  0,
-    0,  0,  0,  0,116,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,117,
-    0,118,119,120,121,  0,104,  4,122, 49, 23,  0,  0,  0,  0,  0,
-    0,  0, 38, 50,  0,  0,  0,  0, 38, 58,  0,  0,  0,  0,  0,  0,
-    1, 87,  1,  1,  1,  1, 39,  1, 48,105, 87,  0,  0,  0,  0,  0,
-    0,  0,  0, 19,  0,  0,  0,  0,  0,  0,  0, 59,  0,  0,  0,  0,
-    0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,123,  0,  0,  0,  0,
-    0,  0,  0,  0,  4,122,  0,  0,  0,  1,124,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,230,230,230,230,230,232,220,220,220,220,232,216,
-  220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,
-    1,  1,  1,  1,  1,220,220,220,220,230,230,230,230,240,230,220,
-  220,220,230,230,230,220,220,  0,230,230,230,220,220,220,220,230,
-  232,220,220,230,233,234,234,233,234,234,233,230,  0,  0,  0,230,
-    0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220,
-  230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
-   21, 22,  0, 23,  0, 24, 25,  0,230,220,  0, 18, 30, 31, 32,  0,
-    0,  0,  0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,
-  220,230,230,220, 35,  0,  0,  0,  0,  0,230,230,230,  0,  0,230,
-  230,  0,220,230,230,220,  0,  0,  0, 36,  0,  0,230,220,230,230,
-  220,220,230,220,220,230,220,230,220,230,230,  0,  0,220,  0,  0,
-  230,230,  0,230,  0,230,230,230,230,230,  0,  0,  0,220,220,220,
-  230,220,220,220,230,230,  0,220, 27, 28, 29,230,  7,  0,  0,  0,
-    0,  9,  0,  0,  0,230,220,230,230,  0,  0,  0,  0,  0,230,  0,
-    0, 84, 91,  0,  0,  0,  0,  9,  9,  0,  0,  0,  0,  0,  9,  0,
-  103,103,  9,  0,107,107,107,107,118,118,  9,  0,122,122,122,122,
-  220,220,  0,  0,  0,220,  0,220,  0,216,  0,  0,  0,129,130,  0,
-  132,  0,  0,  0,  0,  0,130,130,130,130,  0,  0,130,  0,230,230,
-    9,  0,230,230,  0,  0,220,  0,  0,  0,  0,  7,  0,  9,  9,  0,
-    9,  9,  0,  0,  0,230,  0,  0,  0,228,  0,  0,  0,222,230,220,
-  220,  0,  0,  0,230,  0,  0,220,230,220,  0,220,230,230,230,  0,
-    0,  0,  9,  9,  0,  0,  7,  0,230,  0,  1,  1,  1,  0,  0,  0,
-  230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230,
-  233,220,230,220,230,230,  1,  1,  1,  1,  1,230,  0,  1,  1,230,
-  220,230,  1,  1,  0,  0,218,228,232,222,224,224,  0,  8,  8,  0,
-    0,  0,  0,220,230,  0,230,230,220,  0,  0,230,  0,  0, 26,  0,
-    0,220,  0,230,230,  1,220,  0,  0,230,220,  0,  0,  0,220,220,
-    0,  0,230,220,  0,  9,  7,  0,  0,  7,  9,  0,  0,  0,  9,  7,
-    6,  6,  0,  0,  0,  0,  1,  0,  0,216,216,  1,  1,  1,  0,  0,
-    0,226,216,216,216,216,216,  0,220,220,220,  0,232,232,220,230,
-  230,230,  7,  0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19,
-   17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,
+    0,  0,  3,  0,  0,  0,  4,  5,  6,  7,  0,  8,  9, 10,  0, 11,
+   12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19,  0, 19,
+   16, 20, 16, 19, 21, 19,  0, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+   31,  0, 32,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 33,  0,  0,
+    0,  0,  0,  0, 34,  0,  0, 35,  0,  0, 36,  0, 37,  0,  0,  0,
+   38, 39, 40, 41, 42, 43, 44, 45, 46,  0,  0, 47,  0,  0,  0, 48,
+    0,  0,  0, 49,  0,  0,  0,  0,  0,  0,  0, 50,  0, 51,  0, 52,
+   53,  0, 54,  0,  0,  0,  0,  0,  0, 55, 56, 57,  0,  0,  0,  0,
+   58,  0,  0, 59, 60, 61, 62, 63,  0,  0, 64, 65,  0,  0,  0, 66,
+    0,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 69,  0,  0,  0, 70,  0, 71,  0,  0,
+   72,  0,  0, 73,  0,  0,  0,  0,  0,  0,  0,  0, 74,  0,  0,  0,
+    0,  0, 75, 76,  0, 77, 78,  0,  0, 79, 80,  0, 81, 62,  0, 82,
+   83,  0,  0, 84, 85, 86,  0,  0,  0, 87,  0, 88,  0,  0, 51, 89,
+   51,  0, 90,  0, 91,  0,  0,  0, 80,  0,  0,  0, 92, 93,  0, 94,
+   95, 96, 97,  0,  0,  0,  0,  0, 51,  0,  0,  0,  0, 98, 99,  0,
+    0,  0,  0,  0,  0,100,  0,  0,  0,  0,  0,101,102,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,103,  0,  0,104,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,105,106,  0,  0,107,  0,  0,  0,  0,  0,  0,
+  108,  0,109,  0,102,  0,  0,  0,  0,  0,110,111,  0,  0,  0,  0,
+    0,  0,  0,112,  0,  0,  0,  0,  0,  0,  0,113,  0,114,  0,  0,
+    0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  0,  8,  0,  0,  0,
+    0,  9, 10, 11, 12,  0,  0,  0,  0, 13,  0,  0, 14, 15,  0, 16,
+    0, 17, 18,  0,  0, 19,  0, 20, 21,  0,  0,  0,  0,  0, 22, 23,
+    0, 24, 25,  0,  0, 26,  0,  0,  0, 27,  0,  0, 28, 29, 30, 31,
+    0,  0,  0, 32, 33, 34,  0,  0, 33,  0,  0, 35, 33,  0,  0,  0,
+   33, 36,  0,  0,  0,  0,  0, 37, 38,  0,  0,  0,  0,  0,  0, 39,
+   40,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0, 43,  0, 44,
+    0,  0,  0, 45, 46,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0, 48,
+   49,  0,  0,  0,  0, 50,  0,  0,  0, 51,  0, 52,  0, 53,  0,  0,
+    0,  0, 54,  0,  0,  0,  0, 55,  0, 56,  0,  0,  0,  0, 57, 58,
+    0,  0,  0, 59, 60,  0,  0,  0,  0,  0,  0, 61, 52,  0, 62, 63,
+    0,  0, 64,  0,  0,  0, 65, 66,  0,  0,  0, 67,  0, 68, 69, 70,
+   71, 72,  1, 73,  0, 74, 75, 76,  0,  0, 77, 78,  0,  0,  0, 79,
+    0,  0,  1,  1,  0,  0, 80,  0,  0, 81,  0,  0,  0,  0, 77, 82,
+    0, 83,  0,  0,  0,  0,  0, 78, 84,  0, 85,  0, 52,  0,  1, 78,
+    0,  0, 86,  0,  0, 87,  0,  0,  0,  0,  0, 88, 57,  0,  0,  0,
+    0,  0,  0, 89, 90,  0,  0, 84,  0,  0, 33,  0,  0, 91,  0,  0,
+    0,  0, 92,  0,  0,  0,  0, 49,  0,  0, 93,  0,  0,  0,  0, 94,
+   95,  0,  0, 96,  0,  0, 97,  0,  0,  0, 98,  0,  0,  0, 99,  0,
+    0,  0,  0,100,101, 93,  0,  0,102,  0,  0,  0, 84,  0,  0,103,
+    0,  0,  0,104,105,  0,  0,106,107,  0,  0,  0,  0,  0,  0,108,
+    0,  0,109,  0,  0,  0,  0,110, 33,  0,111,112,113, 35,  0,  0,
+  114,  0,  0,  0,115,  0,  0,  0,  0,  0,  0,116,  0,  0,117,  0,
+    0,  0,  0,118, 88,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0, 52,
+  119,  0,  0,  0,  0,120,  0,  0,121,  0,  0,  0,  0,119,  0,  0,
+  122,  0,  0,  0,  0,  0,  0,123,  0,  0,  0,124,  0,  0,  0,125,
+    0,126,  0,  0,  0,  0,127,128,129,  0,130,  0,131,  0,  0,  0,
+  132,133,134,  0, 77,  0,  0,  0,  0,  0, 35,  0,  0,  0,135,  0,
+    0,  0,136,  0,  0,137,  0,  0,138,  0,  0,  0,  0,  0,  0,  0,
+    1,  1,  1,  1,  1,  2,  3,  4,  5,  6,  7,  4,  4,  8,  9, 10,
+    1, 11, 12, 13, 14, 15, 16, 17, 18,  1,  1,  1, 19,  1,  0,  0,
+   20, 21, 22,  1, 23,  4, 21, 24, 25, 26, 27, 28, 29, 30,  0,  0,
+    1,  1, 31,  0,  0,  0, 32, 33, 34, 35,  1, 36, 37,  0,  0,  0,
+    0, 38,  1, 39, 14, 39, 40, 41, 42,  0,  0,  0, 43, 36, 44, 45,
+   21, 45, 46,  0,  0,  0, 19,  1, 21,  0,  0, 47,  0, 38, 48,  1,
+    1, 49, 49, 50,  0,  0, 51,  0,  0,  0, 52,  1,  0,  0, 38, 14,
+    4,  1,  1,  1, 53, 21, 43, 52, 54, 21, 35,  1,  0,  0,  0, 55,
+    0,  0,  0, 56, 57, 58,  0,  0,  0,  0,  0, 59,  0, 60,  0,  0,
+    0,  0, 61, 62,  0,  0, 63,  0,  0,  0, 64,  0,  0,  0, 65,  0,
+    0,  0, 66,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0, 69, 70,  0,
+   71, 72, 73, 74, 75, 76,  0,  0,  0, 77,  0,  0,  0, 78, 79,  0,
+    0,  0,  0, 47,  0,  0,  0, 49,  0, 80,  0,  0,  0, 62,  0,  0,
+   63,  0,  0, 81,  0,  0, 82,  0,  0,  0, 83,  0,  0, 19, 84,  0,
+   62,  0,  0,  0,  0, 49,  1, 85,  1, 52, 15, 86, 36, 10, 21, 87,
+    0, 55,  0,  0,  0,  0, 19, 10,  1,  0,  0,  0,  0,  0, 88,  0,
+    0, 89,  0,  0, 88,  0,  0,  0,  0, 78,  0,  0, 87,  9, 12,  4,
+   90,  8, 91, 47,  0, 58, 50,  0, 21,  1, 21, 92, 93,  1,  1,  1,
+    1, 94, 95, 96, 97,  1, 98, 58, 81, 99,100,  4, 58,  0,  0,  0,
+    0,  0,  0, 19, 50,  0,  0,  0,  0,  0,  0, 61,  0,  0,101,102,
+    0,  0,103,  0,  0,  1,  1, 50,  0,  0,  0, 38,  0, 63,  0,  0,
+    0,  0,  0, 62,  0,  0,104, 68, 61,  0,  0,  0, 78,  0,  0,  0,
+  105,106, 58, 38, 81,  0,  0,  0,  0,  0,  0,107,  1, 14,  4, 12,
+   84,  0,  0,  0,  0, 38, 87,  0,  0,  0,  0,108,  0,  0,109, 61,
+    0,110,  0,  0,  0,  1,  0,  0,  0,  0, 19, 58,  0,  0,  0, 51,
+    0,111, 14, 52,112, 41,  0,  0, 62,  0,  0, 61,  0,  0,113,  0,
+   87,  0,  0,  0, 61, 62,  0,  0, 62,  0, 89,  0,  0,113,  0,  0,
+    0,  0,114,  0,  0,  0, 78, 55,  0, 38,  1, 58,  1, 58,  0,  0,
+   63, 89,  0,  0,115,  0,  0,  0, 55,  0,  0,  0,  0,115,  0,  0,
+    0,  0, 61,  0,  0,  0,  0, 79,  0, 61,  0,  0,  0,  0, 56,  0,
+   89, 80,  0,  0, 79,  0,  0,  0,  8, 91,  0,  0,  1, 87,  0,  0,
+  116,  0,  0,  0,  0,  0,  0,117,  0,118,119,120,121,  0,104,  4,
+  122, 49, 23,  0,  0,  0, 38, 50, 38, 58,  0,  0,  1, 87,  1,  1,
+    1,  1, 39,  1, 48,105, 87,  0,  0,  0,  0,  1,  0,  0,  0,123,
+    4,122,  0,  0,  0,  1,124,  0,  0,  0,  0,  0,230,230,230,230,
+  230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
+  220,220,220,202,202,220,220,220,  1,  1,  1,  1,  1,220,220,220,
+  220,230,230,230,230,240,230,220,220,220,230,230,230,220,220,  0,
+  230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
+  234,234,233,230,  0,  0,  0,230,  0,220,230,230,230,230,220,230,
+  230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
+   14, 15, 16, 17, 18, 19, 19, 20, 21, 22,  0, 23,  0, 24, 25,  0,
+  230,220,  0, 18, 30, 31, 32,  0,  0,  0,  0, 27, 28, 29, 30, 31,
+   32, 33, 34,230,230,220,220,230,220,230,230,220, 35,  0,  0,  0,
+    0,  0,230,230,230,  0,  0,230,230,  0,220,230,230,220,  0,  0,
+    0, 36,  0,  0,230,220,230,230,220,220,230,220,220,230,220,230,
+  220,230,230,  0,  0,220,  0,  0,230,230,  0,230,  0,230,230,230,
+  230,230,  0,  0,  0,220,220,220,230,220,220,220,230,230,  0,220,
+   27, 28, 29,230,  7,  0,  0,  0,  0,  9,  0,  0,  0,230,220,230,
+  230,  0,  0,  0,  0,  0,230,  0,  0, 84, 91,  0,  0,  0,  0,  9,
+    9,  0,  0,  0,  0,  0,  9,  0,103,103,  9,  0,107,107,107,107,
+  118,118,  9,  0,122,122,122,122,220,220,  0,  0,  0,220,  0,220,
+    0,216,  0,  0,  0,129,130,  0,132,  0,  0,  0,  0,  0,130,130,
+  130,130,  0,  0,130,  0,230,230,  9,  0,230,230,  0,  0,220,  0,
+    0,  0,  0,  7,  0,  9,  9,  0,  9,  9,  0,  0,  0,230,  0,  0,
+    0,228,  0,  0,  0,222,230,220,220,  0,  0,  0,230,  0,  0,220,
+  230,220,  0,220,230,230,230,  0,  0,  0,  9,  9,  0,  0,  7,  0,
+  230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,202,230,230,230,
+  230,230,232,228,228,220,218,230,233,220,230,220,230,230,  1,  1,
+    1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,  0,  0,218,228,
+  232,222,224,224,  0,  8,  8,  0,  0,  0,  0,220,230,  0,230,230,
+  220,  0,  0,230,  0,  0, 26,  0,  0,220,  0,230,230,  1,220,  0,
+    0,230,220,  0,  0,  0,220,220,  0,  0,230,220,  0,  9,  7,  0,
+    0,  7,  9,  0,  0,  0,  9,  7,  6,  6,  0,  0,  0,  0,  1,  0,
+    0,216,216,  1,  1,  1,  0,  0,  0,226,216,216,216,216,216,  0,
+  220,220,220,  0,232,232,220,230,230,230,  7,  0, 16, 17, 17, 17,
+   17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,
+  129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17,237,  0,  1,  2,  2,  0,  3,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    5,  0,  0,  0,  0,  6,  7,  8,  9,  0,  0,  0, 10, 11, 12, 13,
-   14, 15, 16, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,
-    0,  0, 21, 22,  0,  0,  0,  0, 23, 24, 25, 26,  0, 27,  0, 28,
-   29, 30, 31, 32,  0,  0,  0,  0,  0,  0,  0, 33, 34, 35, 36,  0,
-    0,  0,  0,  0, 37,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 39,
-    0,  0,  0,  0,  1,  2, 40, 41,  0,  1,  2,  2,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  2,  0,  0,  0,  0,
-    0,  0,  3,  4,  0,  0,  5,  0,  0,  0,  6,  0,  0,  0,  0,  0,
-    0,  0,  7,  1,  0,  0,  0,  0,  0,  0,  8,  9,  0,  0,  0,  0,
-    0,  0, 10,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0, 10,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0, 11, 12,
-    0, 13,  0, 14, 15, 16,  0,  0,  0,  0,  0,  1, 17, 18,  0, 19,
-    7,  1,  0,  0,  0, 20, 20,  7, 20, 20, 20, 20, 20, 20, 20,  8,
-   21,  0, 22,  0,  7, 23, 24,  0, 20, 20, 25,  0,  0,  0, 26, 27,
-    1,  7, 20, 20, 20, 20, 20,  1, 28, 29, 30, 31,  0,  0, 20,  0,
-    0,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0, 20, 20,
-   20,  1,  0,  0,  8, 21, 32,  4,  0, 10,  0, 33,  7, 20, 20, 20,
-    0,  0,  0,  0,  8, 34, 34, 35, 36, 34, 37,  0, 38,  1, 20, 20,
-    0,  0, 39,  0,  1,  1,  0,  8, 21,  1, 20,  0,  0,  0,  1,  0,
-    0, 40,  1,  1,  0,  0,  8, 21,  0,  1,  0,  1,  0,  1,  0,  0,
-    0,  0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21,  7, 20, 41,
-   34, 34, 34, 34, 34, 34, 34, 34, 34, 21,  0, 42, 43, 44,  0, 45,
-    0,  8, 21,  0,  0,  0,  0,  0,  0,  0,  0, 46,  7,  1, 10,  1,
-    0,  0,  0,  1, 20, 20,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0, 26, 34,  9,  0,  0, 20, 20,  1, 20, 20,  0,  0,  0,  0,  0,
-    0,  0, 26, 21,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  3, 47, 48,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,
-    4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-    9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
-   19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
-   13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36,  7,  7,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-   37,  7, 38, 39,  7, 40,  7,  7,  7, 41, 13, 42,  7,  7, 43,  7,
-   44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237,  0,  1,  2,  2,
+    0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  6,  7,  8,
+    9,  0,  0,  0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 20,  0,  0, 21, 22,  0,  0,  0,  0,
+   23, 24, 25, 26,  0, 27,  0, 28, 29, 30, 31, 32,  0,  0,  0,  0,
+    0,  0,  0, 33, 34, 35, 36,  0,  0,  0,  0,  0, 37,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,  1,  2, 40, 41,
+    0,  1,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,
+    0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  5,  0,
+    0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  7,  1,  0,  0,  0,  0,
+    0,  0,  8,  9,  0,  0,  0,  0,  0,  0, 10,  0,  0, 10,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0, 10,
+    0,  0,  0,  0,  0,  0, 11, 12,  0, 13,  0, 14, 15, 16,  0,  0,
+    0,  0,  0,  1, 17, 18,  0, 19,  7,  1,  0,  0,  0, 20, 20,  7,
+   20, 20, 20, 20, 20, 20, 20,  8, 21,  0, 22,  0,  7, 23, 24,  0,
+   20, 20, 25,  0,  0,  0, 26, 27,  1,  7, 20, 20, 20, 20, 20,  1,
+   28, 29, 30, 31,  0,  0, 20,  0,  0,  0,  0,  0,  0,  0, 10,  0,
+    0,  0,  0,  0,  0,  0, 20, 20, 20,  1,  0,  0,  8, 21, 32,  4,
+    0, 10,  0, 33,  7, 20, 20, 20,  0,  0,  0,  0,  8, 34, 34, 35,
+   36, 34, 37,  0, 38,  1, 20, 20,  0,  0, 39,  0,  1,  1,  0,  8,
+   21,  1, 20,  0,  0,  0,  1,  0,  0, 40,  1,  1,  0,  0,  8, 21,
+    0,  1,  0,  1,  0,  1,  0,  0,  0,  0, 26, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 21,  7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 21,  0, 42, 43, 44,  0, 45,  0,  8, 21,  0,  0,  0,  0,  0,
+    0,  0,  0, 46,  7,  1, 10,  1,  0,  0,  0,  1, 20, 20,  1,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0, 26, 34,  9,  0,  0, 20, 20,
+    1, 20, 20,  0,  0,  0,  0,  0,  0,  0, 26, 21,  0,  1,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, 47, 48,  0,  0,  0,
+    0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  9, 10, 11, 11, 11, 11, 12, 13,
+   13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13,
+   13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32,
+   33, 34, 35, 36,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7, 37,  7, 38, 39,  7, 40,  7,  7,
+    7, 41, 13, 42,  7,  7, 43,  7, 44, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
@@ -1740,419 +1715,420 @@
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45,  0,  0,  1,
-    2,  2,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-   32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
-   43, 44, 45, 46, 47, 48, 49, 50, 51, 52,  2,  2, 53, 54, 55, 56,
-   57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
-   59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
-   74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   13, 13, 13, 13, 45,  0,  0,  1,  2,  2,  2,  3,  4,  5,  6,  7,
+    8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37,
+   37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+   51, 52,  2,  2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59,
+   59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65,
+   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
-   80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
-   89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81,
+   82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101,
+  102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116,
+  117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131,
+  132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145,
+   96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158,
+  159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164,
+  167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171,
+  171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96,
+   96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182,
+  182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+  182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185,
+  186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194,
    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
-  110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
-  124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
-  139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
-  152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
-  164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
-  169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
-  173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
-  182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
-  182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
-  182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
-  190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
-  198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
-  208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
-  213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
-  219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
-   59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
-   59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
+   96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204,
+  205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96,
+   96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215,
+   96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221,
+  222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59,
+   59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96,
+   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
-   70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96,
-  246,247,  0,  1,  2,  2,  0,  1,  2,  2,  2,  3,  4,  5,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-   19, 19, 19, 19, 19, 19, 19, 19, 19,  0,  0,  0,  0,  0,  0,  0,
-   19,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19, 19, 19,  0, 19,  0,
-    0,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19,  0,  0,  0,  0,  0,
-   26, 26,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  9,  9,
-    9,  9,  0,  9,  9,  9,  2,  2,  9,  9,  9,  9,  0,  9,  2,  2,
-    2,  2,  9,  0,  9,  0,  9,  9,  9,  2,  9,  2,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,
-   55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,  6,  6,
-    6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  1,  1,  6,  2,  4,
-    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
-    4,  4,  4,  4,  4,  2,  4,  4,  4,  2,  2,  4,  4,  4,  2, 14,
-   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  2,  2,
-    2,  2,  2,  2,  2,  2, 14, 14, 14,  2,  2,  2,  2, 14, 14, 14,
-   14, 14, 14,  2,  2,  2,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,
-    3,  3,  0,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
-    3,  0,  3,  3,  3,  0,  0,  3,  3,  3,  3,  3,  3,  3,  3,  3,
-    3,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  3,  3,  1,  3,
-    3,  3,  3,  3,  3,  3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
-   37, 37, 37, 37,  2, 37, 37, 37, 37,  2,  2, 37, 37, 37, 38, 38,
-   38, 38, 38, 38, 38, 38, 38, 38,  2,  2,  2,  2,  2,  2, 64, 64,
-   64, 64, 64, 64, 64, 64, 64, 64, 64,  2,  2, 64, 64, 64, 90, 90,
-   90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,  2,  2, 90, 90,
-   90, 90, 90, 90, 90,  2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
-   95, 95,  2,  2, 95,  2, 37, 37, 37,  2,  2,  2,  2,  2,  3,  3,
-    3,  3,  3,  3,  3,  2,  3,  3,  2,  2,  2,  2,  2,  2,  3,  3,
-    0,  3,  3,  3,  3,  3,  7,  7,  7,  7,  7,  7,  7,  7,  7,  1,
-    1,  1,  1,  7,  7,  7,  7,  7,  7,  7,  0,  0,  7,  7,  5,  5,
-    5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2,  5,  5,  2,
-    2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,
-    5,  5,  5,  5,  5,  5,  5,  2,  5,  2,  2,  2,  5,  5,  5,  5,
-    2,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  2,  2,  2,
-    2,  2,  2,  2,  2,  5,  2,  2,  2,  2,  5,  5,  2,  5,  5,  5,
-    5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2, 11,
-   11, 11,  2, 11, 11, 11, 11, 11, 11,  2,  2,  2,  2, 11, 11,  2,
-    2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2,
-   11, 11, 11, 11, 11, 11, 11,  2, 11, 11,  2, 11, 11,  2, 11, 11,
-    2,  2, 11,  2, 11, 11, 11,  2,  2, 11, 11, 11,  2,  2,  2, 11,
-    2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,  2, 11,  2,  2,  2,
-    2,  2,  2,  2, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2,  2, 10,
-   10, 10,  2, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,
-    2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2,
-   10, 10, 10, 10, 10, 10, 10,  2, 10, 10,  2, 10, 10, 10, 10, 10,
-    2,  2, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,  2,  2, 10,  2,
-    2,  2,  2,  2,  2,  2, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10,
-    2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10,  2, 21,
-   21, 21,  2, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,
-    2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2,
-   21, 21, 21, 21, 21, 21, 21,  2, 21, 21,  2, 21, 21, 21, 21, 21,
-    2,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21,  2,  2,  2,  2,
-    2,  2,  2, 21, 21, 21,  2,  2,  2,  2, 21, 21,  2, 21, 21, 21,
-   21, 21,  2,  2, 21, 21,  2,  2, 22, 22,  2, 22, 22, 22, 22, 22,
-   22,  2,  2,  2, 22, 22, 22,  2, 22, 22, 22, 22,  2,  2,  2, 22,
-   22,  2, 22,  2, 22, 22,  2,  2,  2, 22, 22,  2,  2,  2, 22, 22,
-   22, 22, 22, 22, 22, 22, 22, 22,  2,  2,  2,  2, 22, 22, 22,  2,
-    2,  2,  2,  2,  2, 22,  2,  2,  2,  2,  2,  2, 22, 22, 22, 22,
-   22,  2,  2,  2,  2,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-   23, 23, 23,  2, 23, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23,
-    2,  2, 23, 23, 23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2,  2,
-    2,  2,  2, 23, 23,  2, 23, 23, 23,  2,  2, 23,  2,  2, 23, 23,
-   23, 23,  2,  2, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 16, 16,
-   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16,  2,
-   16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16, 16,
-    2,  2, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16,  2,  2,  2,  2,
-    2,  2,  2, 16, 16,  2, 16, 16, 16, 16,  2,  2, 16, 16,  2, 16,
-   16, 16,  2,  2,  2,  2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-   20, 20, 20,  2, 20, 20, 20,  2, 20, 20, 20, 20, 20, 20,  2,  2,
-    2,  2, 20, 20, 20, 20, 20, 20, 20, 20,  2,  2, 20, 20,  2, 36,
-   36, 36,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-   36, 36, 36, 36, 36,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36, 36,
-    2, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,  2,
-   36,  2,  2,  2,  2, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,
-    2,  2,  2,  2, 36, 36,  2,  2, 36, 36, 36,  2,  2,  2,  2, 24,
-   24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-   24,  2,  2,  2,  2,  0, 24, 24, 24, 24,  2,  2,  2,  2,  2, 18,
-   18,  2, 18,  2, 18, 18, 18, 18, 18,  2, 18, 18, 18, 18, 18, 18,
-   18, 18, 18, 18, 18, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18, 18,
-   18, 18, 18, 18,  2,  2, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18,
-   18, 18, 18, 18, 18,  2, 18, 18,  2,  2, 18, 18, 18, 18, 25, 25,
-   25, 25, 25, 25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-   25, 25, 25,  2,  2,  2, 25, 25, 25, 25, 25,  2, 25, 25, 25, 25,
-   25, 25, 25,  0,  0,  0,  0, 25, 25,  2,  2,  2,  2,  2, 33, 33,
-   33, 33, 33, 33, 33, 33,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-    8,  8,  8,  8,  2,  8,  2,  2,  2,  2,  2,  8,  2,  2,  8,  8,
-    8,  0,  8,  8,  8,  8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30,
-   30, 30, 30, 30, 30, 30, 30,  2, 30, 30, 30, 30,  2,  2, 30, 30,
-   30, 30, 30, 30, 30,  2, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30,
-   30, 30, 30,  2,  2,  2, 30, 30,  2,  2,  2,  2,  2,  2, 29, 29,
-   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,  2,  2, 28, 28,
-   28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 34, 34,  2,  2,  2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
-   35,  0,  0,  0, 35, 35, 35,  2,  2,  2,  2,  2,  2,  2, 45, 45,
-   45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,  2,  2,  2,  2,
-    2,  2,  2,  2,  2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
-   44, 44, 44,  0,  0,  2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
-   43, 43,  2,  2,  2,  2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
-   46, 46, 46,  2, 46, 46, 46,  2, 46, 46,  2,  2,  2,  2, 31, 31,
-   31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,  2,  2, 31, 31,
-    2,  2,  2,  2,  2,  2, 32, 32,  0,  0, 32,  0, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 32, 32, 32,  2,  2,  2,  2,  2,  2, 32,  2,
-    2,  2,  2,  2,  2,  2, 32, 32, 32,  2,  2,  2,  2,  2, 28, 28,
-   28, 28, 28, 28,  2,  2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
-   48, 48, 48, 48, 48,  2, 48, 48, 48, 48,  2,  2,  2,  2, 48,  2,
-    2,  2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
-   52, 52, 52, 52,  2,  2, 52, 52, 52, 52, 52,  2,  2,  2, 58, 58,
-   58, 58, 58, 58, 58, 58, 58, 58, 58, 58,  2,  2,  2,  2, 58, 58,
-    2,  2,  2,  2,  2,  2, 58, 58, 58,  2,  2,  2, 58, 58, 54, 54,
-   54, 54, 54, 54, 54, 54, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91,
-   91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,  2, 91, 91,
-   91, 91, 91,  2,  2, 91, 91, 91,  2,  2,  2,  2,  2,  2, 91, 91,
-   91, 91, 91, 91,  2,  2,  1,  1,  1,  1,  1,  1,  1,  2, 62, 62,
-   62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,  2,  2,  2, 62, 62,
-   62, 62, 62, 62, 62,  2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93,
-   93, 93, 93, 93, 93, 93, 93, 93, 93, 93,  2,  2,  2,  2,  2,  2,
-    2,  2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70,  2,  2,
-    2, 70, 70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 73, 73,
-   73, 73, 73, 73, 73, 73,  6,  2,  2,  2,  2,  2,  2,  2,  8,  8,
-    8,  2,  2,  8,  8,  8,  1,  1,  1,  0,  1,  1,  1,  1,  1,  0,
-    1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,  0,  0,  0,  0,
-    0,  0,  1,  0,  0,  0,  1,  1,  0,  2,  2,  2,  2,  2, 19, 19,
-   19, 19, 19, 19,  9,  9,  9,  9,  9,  6, 19, 19, 19, 19, 19, 19,
-   19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19,  9,  9,  9,  9,
-    9, 19, 19, 19, 19, 19,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-   19, 19, 19, 19, 19,  9,  9,  9,  9,  9,  9,  9,  2,  2,  2,  9,
-    2,  9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  9,
-    9,  9,  2,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  2,  2,
-    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  0,  0,
-    0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0, 19,
-    2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,
-    0,  0,  0,  0,  0,  2, 19, 19, 19, 19, 19,  2,  2,  2,  0,  2,
-    2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2,  2,  0,  0,
-    0,  0,  0,  0,  9,  0,  0,  0, 19, 19,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 19,  0, 19,  0,  0,  0,  2,  2,  2,  2,  0,  0,
-    0,  2,  2,  2,  2,  2, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,
-    0,  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0, 56, 56,
-   56, 56, 56, 56, 56, 56, 55, 55, 55, 55,  2,  2,  2,  2,  2, 55,
-   55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61,  2,  2,
-    2,  2,  2,  2,  2, 61, 61,  2,  2,  2,  2,  2,  2,  2,  0,  0,
-    0,  0,  0,  0,  2,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-    2, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  2, 13, 13,
-   13, 13, 13, 13,  2,  2,  0,  0,  0,  0,  2,  2,  2,  2,  0,  0,
-    0,  0,  0, 13,  0, 13,  0, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-    1,  1,  1,  1, 12, 12, 13, 13, 13, 13,  0,  0,  0,  0,  2, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15,  2,  2,  1,  1,  0,  0, 15, 15, 15,  0, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17,  0,  0, 17, 17, 17,  2,  2,  2,  2,  2, 26, 26, 26, 26, 26,
-   26, 26, 26, 26, 26, 26,  2, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-   12, 12, 12, 12, 12,  2, 12, 12, 12, 12, 12, 12, 12,  0, 17, 17,
-   17, 17, 17, 17, 17,  0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
-   39, 39, 39,  2,  2,  2, 39, 39, 39, 39, 39, 39, 39,  2, 86, 86,
-   86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
-   77, 77,  2,  2,  2,  2, 79, 79, 79, 79, 79, 79, 79, 79,  0,  0,
-   19, 19, 19, 19, 19, 19,  0,  0,  0, 19, 19, 19, 19, 19, 19, 19,
-   19,  2,  2,  2,  2,  2, 19, 19,  2, 19,  2, 19, 19, 19, 19, 19,
-    2,  2,  2,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19, 60, 60,
-   60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,  2,  2,  2,  0,  0,
-    2,  2,  2,  2,  2,  2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75,
-   75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,  2,  2,  2,  2,
-    2,  2,  2,  2, 75, 75, 75, 75,  2,  2,  2,  2,  2,  2, 69, 69,
-   69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,  0, 69, 74, 74,
-   74, 74, 74, 74, 74, 74, 74, 74, 74, 74,  2,  2,  2,  2,  2,  2,
-    2,  2,  2,  2,  2, 74, 12, 12, 12, 12, 12,  2,  2,  2, 84, 84,
-   84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,  2,  0, 84, 84,
-    2,  2,  2,  2, 84, 84, 33, 33, 33, 33, 33, 33, 33,  2, 68, 68,
-   68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,  2, 68, 68,
-   68, 68, 68, 68,  2,  2, 68, 68,  2,  2, 68, 68, 68, 68, 92, 92,
-   92, 92, 92, 92, 92, 92, 92, 92, 92,  2,  2,  2,  2,  2,  2,  2,
-    2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
-   87, 87, 87, 87, 87,  2,  2, 30, 30, 30, 30, 30, 30,  2, 19, 19,
-   19,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9, 19, 19, 19, 19,
-    0,  0,  2,  2,  2,  2, 87, 87, 87, 87, 87, 87,  2,  2, 87, 87,
-    2,  2,  2,  2,  2,  2, 12, 12, 12, 12,  2,  2,  2,  2,  2,  2,
-    2, 12, 12, 12, 12, 12, 13, 13,  2,  2,  2,  2,  2,  2, 19, 19,
-   19, 19, 19, 19, 19,  2,  2,  2,  2,  4,  4,  4,  4,  4,  2,  2,
-    2,  2,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  2, 14, 14,
-   14, 14, 14,  2, 14,  2, 14, 14,  2, 14, 14,  2, 14, 14,  3,  3,
-    3,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,
-    3,  3,  3,  3,  0,  0,  2,  2,  3,  3,  3,  3,  3,  3,  2,  2,
-    2,  2,  2,  2,  2,  3,  1,  1,  1,  1,  1,  1,  6,  6,  0,  0,
-    0,  2,  0,  0,  0,  0,  3,  3,  3,  3,  3,  2,  3,  3,  3,  3,
-    3,  3,  3,  2,  2,  0,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 17, 17, 17, 17, 17, 17, 17, 17,  0,  0,  2,  2,
-   12, 12, 12, 12, 12, 12,  2,  2, 12, 12, 12,  2,  2,  2,  2,  0,
-    0,  0,  0,  0,  2,  2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-   49, 49,  2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,  2, 49, 49,
-   49,  2, 49, 49,  2, 49, 49, 49, 49, 49, 49, 49,  2,  2, 49, 49,
-   49,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2,  0,  0,  0,
-    0,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  2,  2,  2,  9,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  1,  2,  2, 71, 71,
-   71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,  2,  2,  2, 67, 67,
-   67, 67, 67, 67, 67, 67, 67,  2,  2,  2,  2,  2,  2,  2,  1,  0,
-    0,  0,  0,  0,  0,  0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
-   42, 42,  2,  2,  2,  2,  2,  2,  2,  2,  2, 42, 42, 42, 41, 41,
-   41, 41, 41, 41, 41, 41, 41, 41, 41,  2,  2,  2,  2,  2,118,118,
-  118,118,118,118,118,118,118,118,118,  2,  2,  2,  2,  2, 53, 53,
-   53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,  2, 53, 59, 59,
-   59, 59, 59, 59, 59, 59, 59, 59, 59, 59,  2,  2,  2,  2, 59, 59,
-   59, 59, 59, 59,  2,  2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51,
-   51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
-   50, 50, 50, 50,  2,  2, 50, 50,  2,  2,  2,  2,  2,  2,135,135,
-  135,135,135,135,135,135,135,135,135,135,  2,  2,  2,  2,106,106,
-  106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104,
-  104,104,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,104,161,161,
-  161,161,161,161,161,161,161,161,161,  2,161,161,161,161,161,161,
-  161,  2,161,161,  2,161,161,161,  2,161,161,161,161,161,161,161,
-    2,161,161,  2,  2,  2,110,110,110,110,110,110,110,110,110,110,
-  110,110,110,110,110,  2,110,110,110,110,110,110,  2,  2, 19, 19,
-   19, 19, 19, 19,  2, 19, 19,  2, 19, 19, 19, 19, 19, 19, 47, 47,
-   47, 47, 47, 47,  2,  2, 47,  2, 47, 47, 47, 47, 47, 47, 47, 47,
-   47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,  2, 47, 47,  2,
-    2,  2, 47,  2,  2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
-   81, 81, 81, 81,  2, 81,120,120,120,120,120,120,120,120,116,116,
-  116,116,116,116,116,116,116,116,116,116,116,116,116,  2,  2,  2,
-    2,  2,  2,  2,  2,116,128,128,128,128,128,128,128,128,128,128,
-  128,  2,128,128,  2,  2,  2,  2,  2,128,128,128,128,128, 66, 66,
-   66, 66, 66, 66, 66, 66, 66, 66, 66, 66,  2,  2,  2, 66, 72, 72,
-   72, 72, 72, 72, 72, 72, 72, 72,  2,  2,  2,  2,  2, 72, 98, 98,
-   98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97,  2,  2,
-    2,  2, 97, 97, 97, 97,  2,  2, 97, 97, 97, 97, 97, 97, 57, 57,
-   57, 57,  2, 57, 57,  2,  2,  2,  2,  2, 57, 57, 57, 57, 57, 57,
-   57, 57,  2, 57, 57, 57,  2, 57, 57, 57, 57, 57, 57, 57, 57, 57,
-   57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,  2,  2, 57, 57,
-   57,  2,  2,  2,  2, 57, 57,  2,  2,  2,  2,  2,  2,  2, 88, 88,
-   88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112,
-  112,112,112,112,112,112,112,112,112,112,112,112,112,  2,  2,  2,
-    2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
-   78, 78, 78, 78,  2,  2,  2, 78, 78, 78, 78, 78, 78, 78, 83, 83,
-   83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,  2,  2, 82, 82,
-   82, 82, 82, 82, 82, 82, 82, 82, 82,  2,  2,  2,  2,  2,122,122,
-  122,122,122,122,122,122,122,122,  2,  2,  2,  2,  2,  2,  2,122,
-  122,122,122,  2,  2,  2,  2,122,122,122,122,122,122,122, 89, 89,
-   89, 89, 89, 89, 89, 89, 89,  2,  2,  2,  2,  2,  2,  2,130,130,
-  130,130,130,130,130,130,130,130,130,  2,  2,  2,  2,  2,  2,  2,
-  130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144,
-    2,  2,  2,  2,  2,  2,156,156,156,156,156,156,156,156,156,156,
-    2,156,156,156,  2,  2,156,156,  2,  2,  2,  2,  2,  2,  2,  2,
-    2,  2,  2,  3,  3,  3,147,147,147,147,147,147,147,147,148,148,
-  148,148,148,148,148,148,148,148,  2,  2,  2,  2,  2,  2,158,158,
-  158,158,158,158,158,158,158,158,  2,  2,  2,  2,  2,  2,153,153,
-  153,153,153,153,153,153,153,153,153,153,  2,  2,  2,  2,149,149,
-  149,149,149,149,149,149,149,149,149,149,149,149,149,  2, 94, 94,
-   94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,  2,  2,  2,  2,
-   94, 94, 94, 94, 94, 94,  2,  2,  2,  2,  2,  2,  2, 94, 85, 85,
-   85, 85, 85, 85, 85, 85, 85, 85, 85,  2,  2,  2,  2,  2,  2,  2,
-    2,  2,  2, 85,  2,  2,101,101,101,101,101,101,101,101,101,  2,
-    2,  2,  2,  2,  2,  2,101,101,  2,  2,  2,  2,  2,  2, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,  2, 96, 96,111,111,
-  111,111,111,111,111,111,111,111,111,111,111,111,111,  2,100,100,
-  100,100,100,100,100,100,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-   36, 36, 36,  2,  2,  2,108,108,108,108,108,108,108,108,108,108,
-    2,108,108,108,108,108,108,108,  2,  2,  2,  2,  2,  2,129,129,
-  129,129,129,129,129,  2,129,  2,129,129,129,129,  2,129,129,129,
-  129,129,129,129,129,129,129,129,129,129,129,129,  2,129,129,129,
-    2,  2,  2,  2,  2,  2,109,109,109,109,109,109,109,109,109,109,
-  109,  2,  2,  2,  2,  2,109,109,  2,  2,  2,  2,  2,  2,107,107,
-  107,107,  2,107,107,107,107,107,107,107,107,  2,  2,107,107,  2,
-    2,107,107,107,107,107,107,107,107,107,107,107,107,107,107,  2,
-  107,107,107,107,107,107,107,  2,107,107,  2,107,107,107,107,107,
-    2,  1,107,107,107,107,107,  2,  2,107,107,107,  2,  2,107,  2,
-    2,  2,  2,  2,  2,107,  2,  2,  2,  2,  2,107,107,107,107,107,
-  107,107,  2,  2,107,107,107,107,107,107,107,  2,  2,  2,137,137,
-  137,137,137,137,137,137,137,137,137,137,  2,137,137,137,137,137,
-    2,  2,  2,  2,  2,  2,124,124,124,124,124,124,124,124,124,124,
-    2,  2,  2,  2,  2,  2,123,123,123,123,123,123,123,123,123,123,
-  123,123,123,123,  2,  2,114,114,114,114,114,114,114,114,114,114,
-  114,114,114,  2,  2,  2,114,114,  2,  2,  2,  2,  2,  2, 32, 32,
-   32, 32, 32,  2,  2,  2,102,102,102,102,102,102,102,102,102,102,
-    2,  2,  2,  2,  2,  2,126,126,126,126,126,126,126,126,126,126,
-  126,  2,  2,126,126,126,126,126,126,126,  2,  2,  2,  2,126,126,
-  126,126,126,126,126,  2,142,142,142,142,142,142,142,142,142,142,
-  142,142,  2,  2,  2,  2,125,125,125,125,125,125,125,125,125,125,
-  125,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,125,154,154,
-  154,154,154,154,154,  2,  2,154,  2,  2,154,154,154,154,154,154,
-  154,154,  2,154,154,  2,154,154,154,154,154,154,154,154,154,154,
-  154,154,154,154,  2,154,154,  2,  2,154,154,154,154,154,154,154,
-    2,  2,  2,  2,  2,  2,150,150,150,150,150,150,150,150,  2,  2,
-  150,150,150,150,150,150,150,150,150,150,150,  2,  2,  2,141,141,
-  141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140,
-  140,  2,  2,  2,  2,  2,121,121,121,121,121,121,121,121,121,  2,
-    2,  2,  2,  2,  2,  2,  7,  7,  2,  2,  2,  2,  2,  2,133,133,
-  133,133,133,133,133,133,133,  2,133,133,133,133,133,133,133,133,
-  133,133,133,133,133,  2,133,133,133,133,133,133,  2,  2,133,133,
-  133,133,133,  2,  2,  2,134,134,134,134,134,134,134,134,  2,  2,
-  134,134,134,134,134,134,  2,134,134,134,134,134,134,134,134,134,
-  134,134,134,134,134,  2,138,138,138,138,138,138,138,  2,138,138,
-    2,138,138,138,138,138,138,138,138,138,138,138,138,138,  2,  2,
-  138,  2,138,138,  2,138,138,138,  2,  2,  2,  2,  2,  2,143,143,
-  143,143,143,143,  2,143,143,  2,143,143,143,143,143,143,143,143,
-  143,143,143,143,143,143,143,143,143,143,143,143,143,  2,143,143,
-    2,143,143,143,143,143,143,  2,  2,  2,  2,  2,  2,  2,143,143,
-    2,  2,  2,  2,  2,  2,145,145,145,145,145,145,145,145,145,  2,
-    2,  2,  2,  2,  2,  2,163,163,163,163,163,163,163,163,163,  2,
-  163,163,163,163,163,163,163,163,163,  2,  2,  2,163,163,163,163,
-    2,  2,  2,  2,  2,  2, 86,  2,  2,  2,  2,  2,  2,  2, 22, 22,
-    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 22, 63, 63,
-   63, 63, 63, 63, 63, 63, 63, 63,  2,  2,  2,  2,  2,  2, 63, 63,
-   63, 63, 63, 63, 63,  2, 63, 63, 63, 63, 63,  2,  2,  2, 63, 63,
-   63, 63,  2,  2,  2,  2,157,157,157,157,157,157,157,157,157,157,
-  157,  2,  2,  2,  2,  2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
-   80, 80, 80, 80,  2,  2,127,127,127,127,127,127,127,127,127,127,
-  127,127,127,127,127,  2, 79,  2,  2,  2,  2,  2,  2,  2,115,115,
-  115,115,115,115,115,115,115,115,115,115,115,115,115,  2,115,115,
-    2,  2,  2,  2,115,115,159,159,159,159,159,159,159,159,159,159,
-  159,159,159,159,159,  2,159,159,  2,  2,  2,  2,  2,  2,103,103,
-  103,103,103,103,103,103,103,103,103,103,103,103,  2,  2,119,119,
-  119,119,119,119,119,119,119,119,119,119,119,119,  2,  2,119,119,
-    2,119,119,119,119,119,  2,  2,  2,  2,  2,119,119,119,146,146,
-  146,146,146,146,146,146,146,146,146,  2,  2,  2,  2,  2, 99, 99,
-   99, 99, 99, 99, 99, 99, 99, 99, 99,  2,  2,  2,  2, 99,  2,  2,
-    2,  2,  2,  2,  2, 99,136,139, 13, 13,155,  2,  2,  2,136,136,
-  136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155,
-  155,155,155,155,  2,  2,136,  2,  2,  2,  2,  2,  2,  2, 17, 17,
-   17, 17,  2, 17, 17, 17, 17, 17, 17, 17,  2, 17, 17,  2, 17, 15,
-   15, 15, 15, 15, 15, 15, 17, 17, 17,  2,  2,  2,  2,  2,  2,  2,
-   15,  2,  2,  2,  2,  2, 15, 15, 15,  2,  2, 17,  2,  2,  2,  2,
-    2,  2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139,
-  139,139,  2,  2,  2,  2,105,105,105,105,105,105,105,105,105,105,
-  105,  2,  2,  2,  2,  2,105,105,105,105,105,  2,  2,  2,105,  2,
-    2,  2,  2,  2,  2,  2,105,105,  2,  2,105,105,105,105,  1,  1,
-    1,  1,  1,  1,  2,  2,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,
-    1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,
-    1,  1,  1,  1,  0,  0,  2,  2,  0,  2,  2,  0,  0,  2,  2,  0,
-    0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  2,  0,  0,  0,  0,  0,
-    0,  0,  2,  0,  0,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,  0,
-    2,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  2,  0,  2,  2,  2,
-    0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,131,131,
-  131,131,131,131,131,131,131,131,131,131,  2,  2,  2,  2,  2,  2,
-    2,131,131,131,131,131,  2,131,131,131,131,131,131,131,  2,  2,
-    2,  2,  2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56,  2, 56,  2,
-    2, 56, 56, 56, 56, 56, 56, 56,  2, 56, 56,  2, 56, 56, 56, 56,
-   56,  2,  2,  2,  2,  2,  6,  6,  6,  6,  6,  6,  2,  2,  2,  2,
-    2,  2,  2,  2,  2,  6,151,151,151,151,151,151,151,151,151,151,
-  151,151,151,  2,  2,  2,151,151,151,151,151,151,  2,  2,151,151,
-    2,  2,  2,  2,151,151,160,160,160,160,160,160,160,160,160,160,
-  160,160,160,160,160,  2,152,152,152,152,152,152,152,152,152,152,
-    2,  2,  2,  2,  2,152,164,164,164,164,164,164,164,164,164,164,
-    2,  2,  2,  2,  2,  2, 30, 30, 30, 30,  2, 30, 30,  2,113,113,
-  113,113,113,113,113,113,113,113,113,113,113,  2,  2,113,113,113,
-  113,113,113,113,113,  2,132,132,132,132,132,132,132,132,132,132,
-  132,132,  2,  2,  2,  2,132,132,  2,  2,  2,  2,132,132,  3,  3,
-    3,  3,  2,  3,  3,  3,  2,  3,  3,  2,  3,  2,  2,  3,  2,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,  3,  3,  2,  3,
-    2,  3,  2,  2,  2,  2,  2,  2,  3,  2,  2,  2,  2,  3,  2,  3,
-    2,  3,  2,  3,  3,  3,  2,  3,  2,  3,  2,  3,  2,  3,  2,  3,
-    3,  3,  3,  2,  3,  2,  3,  3,  2,  3,  3,  3,  3,  3,  3,  3,
-    3,  3,  2,  2,  2,  2,  2,  3,  3,  3,  2,  3,  3,  3,  2,  2,
-    2,  2,  2,  2,  0,  0, 15,  0,  0,  2,  2,  2,  2,  2,  2,  2,
-    2,  2,  0,  0,  0,  0,  2,  2,  2,  0,  0,  0,  0,  0, 13,  2,
-    2,  2,  2,  2,  2,  2, 13, 13, 13,  2,  2,  2,  2,  2,  2,  0,
-    2,  2,  2,  2,  2,  2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
-    9,  9,  9, 10,  9, 11, 12, 13,  9,  9,  9, 14,  9,  9, 15,  9,
+   70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 96, 96,
+   96, 96, 96, 96, 96, 96, 70, 70, 70, 70,242, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,243, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,244, 96, 96,
+   96, 96, 96, 96, 96, 96,245, 96,246,247,  0,  1,  2,  2,  0,  1,
+    2,  2,  2,  3,  4,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0, 19, 19,
+   19, 19, 19, 19, 19,  0, 19,  0,  0,  0,  0,  0,  0,  0, 19, 19,
+   19, 19, 19,  0,  0,  0,  0,  0, 26, 26,  0,  0,  0,  0,  1,  1,
+    1,  1,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,  2,  2,
+    9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,  9,  0,  9,  9,
+    9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    2,  9,  9,  9,  9,  9,  9,  9, 55, 55, 55, 55, 55, 55, 55, 55,
+   55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+    6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  4,  4,
+    4,  2,  2,  4,  4,  4,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14,  2,  2,  2,  2,  2,  2,  2,  2, 14, 14,
+   14,  2,  2,  2,  2, 14, 14, 14, 14, 14, 14,  2,  2,  2,  3,  3,
+    3,  3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  0,  0,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  1,  1,  1,  1,  1,  1,  1,
+    1,  1,  1,  1,  3,  3,  1,  3,  3,  3,  3,  3,  3,  3, 37, 37,
+   37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37,
+   37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+    2,  2,  2,  2,  2,  2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+   64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+   90, 90, 90, 90,  2,  2, 90, 90, 90, 90, 90, 90, 90,  2, 95, 95,
+   95, 95, 95, 95, 95, 95, 95, 95, 95, 95,  2,  2, 95,  2, 37, 37,
+   37,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,
+    2,  2,  2,  2,  2,  2,  3,  3,  0,  3,  3,  3,  3,  3,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  7,  7,
+    7,  7,  0,  0,  7,  7,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,
+    5,  5,  5,  2,  2,  5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  2,
+    5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  5,  2,
+    2,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,  2,  5,  2,  2,
+    2,  2,  5,  5,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  2,  2, 11, 11, 11,  2, 11, 11, 11, 11, 11,
+   11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11, 11, 11, 11, 11,  2, 11, 11, 11, 11, 11, 11, 11,  2,
+   11, 11,  2, 11, 11,  2, 11, 11,  2,  2, 11,  2, 11, 11, 11,  2,
+    2, 11, 11, 11,  2,  2,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11,
+   11, 11, 11,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,
+   11, 11, 11, 11, 11,  2,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10,
+   10, 10, 10, 10,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,
+   10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,  2,
+   10, 10,  2, 10, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10, 10, 10,
+    2, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,  2,  2, 10, 10,
+   10, 10,  2,  2, 10, 10, 10, 10,  2,  2,  2,  2,  2,  2,  2, 10,
+   10, 10, 10, 10, 10, 10,  2, 21, 21, 21,  2, 21, 21, 21, 21, 21,
+   21, 21, 21,  2,  2, 21, 21,  2,  2, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21,  2, 21, 21, 21, 21, 21, 21, 21,  2,
+   21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21, 21, 21,  2,
+    2, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2, 21, 21, 21,  2,  2,
+    2,  2, 21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,  2,
+   22, 22,  2, 22, 22, 22, 22, 22, 22,  2,  2,  2, 22, 22, 22,  2,
+   22, 22, 22, 22,  2,  2,  2, 22, 22,  2, 22,  2, 22, 22,  2,  2,
+    2, 22, 22,  2,  2,  2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+    2,  2,  2,  2, 22, 22, 22,  2,  2,  2,  2,  2,  2, 22,  2,  2,
+    2,  2,  2,  2, 22, 22, 22, 22, 22,  2,  2,  2,  2,  2, 23, 23,
+   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  2, 23, 23, 23,  2,
+   23, 23, 23, 23, 23, 23, 23, 23,  2,  2, 23, 23, 23, 23, 23,  2,
+   23, 23, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 23,  2, 23, 23,
+   23,  2,  2, 23,  2,  2, 23, 23, 23, 23,  2,  2, 23, 23,  2,  2,
+    2,  2,  2,  2,  2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+   16, 16, 16,  2, 16, 16, 16,  2, 16, 16, 16, 16, 16, 16, 16, 16,
+   16, 16,  2, 16, 16, 16, 16, 16,  2,  2, 16, 16, 16, 16, 16,  2,
+   16, 16, 16, 16,  2,  2,  2,  2,  2,  2,  2, 16, 16,  2, 16, 16,
+   16, 16,  2,  2, 16, 16,  2, 16, 16, 16,  2,  2,  2,  2, 20, 20,
+   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  2, 20, 20, 20,  2,
+   20, 20, 20, 20, 20, 20,  2,  2,  2,  2, 20, 20, 20, 20, 20, 20,
+   20, 20,  2,  2, 20, 20,  2, 36, 36, 36,  2, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2,
+   36, 36, 36, 36, 36, 36, 36, 36,  2, 36, 36, 36, 36, 36, 36, 36,
+   36, 36,  2, 36,  2,  2,  2,  2, 36,  2,  2,  2,  2, 36, 36, 36,
+   36, 36, 36,  2, 36,  2,  2,  2,  2,  2,  2,  2, 36, 36,  2,  2,
+   36, 36, 36,  2,  2,  2,  2, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0, 24, 24,
+   24, 24,  2,  2,  2,  2,  2, 18, 18,  2, 18,  2, 18, 18, 18, 18,
+   18,  2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+   18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2,  2, 18, 18,
+   18, 18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2, 18, 18,
+    2,  2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25,  2, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  2,  2,  2, 25, 25,
+   25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25,  0,  0,  0,  0, 25,
+   25,  2,  2,  2,  2,  2, 33, 33, 33, 33, 33, 33, 33, 33,  8,  8,
+    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  2,  8,  2,  2,
+    2,  2,  2,  8,  2,  2,  8,  8,  8,  0,  8,  8,  8,  8, 12, 12,
+   12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30,  2,
+   30, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30,  2, 30, 30,
+   30,  2,  2, 30, 30, 30, 30, 30, 30, 30, 30,  2,  2,  2, 30, 30,
+    2,  2,  2,  2,  2,  2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+   29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,  2,  2,  2, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0, 35, 35, 35,  2,
+    2,  2,  2,  2,  2,  2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+   45, 45, 45, 45,  2,  2,  2,  2,  2,  2,  2,  2,  2, 45, 44, 44,
+   44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43,
+   43, 43, 43, 43, 43, 43, 43, 43, 43, 43,  2,  2,  2,  2, 46, 46,
+   46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,  2, 46, 46, 46,  2,
+   46, 46,  2,  2,  2,  2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+   31, 31, 31, 31,  2,  2, 31, 31,  2,  2,  2,  2,  2,  2, 32, 32,
+    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+    2,  2,  2,  2,  2,  2, 32,  2,  2,  2,  2,  2,  2,  2, 32, 32,
+   32,  2,  2,  2,  2,  2, 28, 28, 28, 28, 28, 28,  2,  2, 48, 48,
+   48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,  2, 48, 48,
+   48, 48,  2,  2,  2,  2, 48,  2,  2,  2, 48, 48, 48, 48, 52, 52,
+   52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,  2,  2, 52, 52,
+   52, 52, 52,  2,  2,  2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58,  2,  2,  2,  2, 58, 58,  2,  2,  2,  2,  2,  2, 58, 58,
+   58,  2,  2,  2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+   54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+   91, 91, 91, 91, 91,  2, 91, 91, 91, 91, 91,  2,  2, 91, 91, 91,
+    2,  2,  2,  2,  2,  2, 91, 91, 91, 91, 91, 91,  2,  2,  1,  1,
+    1,  1,  1,  1,  1,  2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+   62, 62, 62,  2,  2,  2, 62, 62, 62, 62, 62, 62, 62,  2, 76, 76,
+   76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+   93, 93,  2,  2,  2,  2,  2,  2,  2,  2, 93, 93, 93, 93, 70, 70,
+   70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 70, 70, 70, 70,
+    2,  2,  2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73,  6,  2,
+    2,  2,  2,  2,  2,  2,  8,  8,  8,  2,  2,  8,  8,  8,  1,  1,
+    1,  0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  0,
+    0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  1,
+    0,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,
+    9,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,  9,
+   19, 19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19, 19,  6, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,
+    9,  9,  9,  9,  2,  2,  2,  9,  2,  9,  2,  9,  2,  9,  9,  9,
+    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,  9,
+    9,  9,  2,  9,  9,  9,  2,  2,  9,  9,  9,  2,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  2,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,
+    0,  0,  0,  2,  0,  0,  0, 19,  2,  2,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0,  0,  0,  2, 19, 19,
+   19, 19, 19,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,
+    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,
+   19, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0, 19,  0,
+    0,  0,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2,  2, 27, 27,
+   27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  2,  0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55,
+   55, 55,  2,  2,  2,  2,  2, 55, 55, 55, 55, 55, 55, 55, 61, 61,
+   61, 61, 61, 61, 61, 61,  2,  2,  2,  2,  2,  2,  2, 61, 61,  2,
+    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  2,  2, 13, 13,
+   13, 13, 13, 13, 13, 13, 13, 13,  2, 13, 13, 13, 13, 13, 13, 13,
+   13, 13,  2,  2,  2,  2, 13, 13, 13, 13, 13, 13,  2,  2,  0,  0,
+    0,  0,  2,  2,  2,  2,  0,  0,  0,  0,  0, 13,  0, 13,  0, 13,
+   13, 13, 13, 13, 13, 13, 13, 13,  1,  1,  1,  1, 12, 12, 13, 13,
+   13, 13,  0,  0,  0,  0,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  1,
+    1,  0,  0, 15, 15, 15,  0, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17,  0,  0, 17, 17, 17,  2,  2,
+    2,  2,  2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2, 12, 12,
+   12, 12, 12, 12, 12,  0, 17, 17, 17, 17, 17, 17, 17,  0, 39, 39,
+   39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39,
+   39, 39, 39, 39, 39,  2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77,
+   77, 77, 77, 77, 77, 77, 77, 77, 77, 77,  2,  2,  2,  2, 79, 79,
+   79, 79, 79, 79, 79, 79,  0,  0, 19, 19, 19, 19, 19, 19,  0,  0,
+    0, 19, 19, 19, 19, 19, 19, 19, 19,  2,  2,  2,  2,  2, 19, 19,
+    2, 19,  2, 19, 19, 19, 19, 19,  2,  2,  2,  2,  2,  2,  2,  2,
+   19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+   60, 60, 60,  2,  2,  2,  0,  0,  2,  2,  2,  2,  2,  2, 65, 65,
+   65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+   75, 75, 75, 75,  2,  2,  2,  2,  2,  2,  2,  2, 75, 75, 75, 75,
+    2,  2,  2,  2,  2,  2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+   69, 69, 69, 69,  0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+   74, 74,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 74, 12, 12,
+   12, 12, 12,  2,  2,  2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+   84, 84, 84, 84,  2,  0, 84, 84,  2,  2,  2,  2, 84, 84, 33, 33,
+   33, 33, 33, 33, 33,  2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+   68, 68, 68, 68, 68,  2, 68, 68, 68, 68, 68, 68,  2,  2, 68, 68,
+    2,  2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+   92,  2,  2,  2,  2,  2,  2,  2,  2, 92, 92, 92, 92, 92, 87, 87,
+   87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,  2,  2, 30,
+   30, 30, 30, 30, 30,  2, 19, 19, 19,  0, 19, 19, 19, 19, 19, 19,
+   19, 19, 19,  9, 19, 19, 19, 19,  0,  0,  2,  2,  2,  2, 87, 87,
+   87, 87, 87, 87,  2,  2, 87, 87,  2,  2,  2,  2,  2,  2, 12, 12,
+   12, 12,  2,  2,  2,  2,  2,  2,  2, 12, 12, 12, 12, 12, 13, 13,
+    2,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19, 19,  2,  2,  2,
+    2,  4,  4,  4,  4,  4,  2,  2,  2,  2,  2, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14,  2, 14, 14, 14, 14, 14,  2, 14,  2, 14, 14,
+    2, 14, 14,  2, 14, 14,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,
+    2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  0,  2,  2,
+    3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,  3,  1,  1,
+    1,  1,  1,  1,  6,  6,  0,  0,  0,  2,  0,  0,  0,  0,  3,  3,
+    3,  3,  3,  2,  3,  3,  3,  3,  3,  3,  3,  2,  2,  0,  2,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17, 17,
+   17, 17, 17, 17,  0,  0,  2,  2, 12, 12, 12, 12, 12, 12,  2,  2,
+   12, 12, 12,  2,  2,  2,  2,  0,  0,  0,  0,  0,  2,  2, 49, 49,
+   49, 49, 49, 49, 49, 49, 49, 49, 49, 49,  2, 49, 49, 49, 49, 49,
+   49, 49, 49, 49, 49,  2, 49, 49, 49,  2, 49, 49,  2, 49, 49, 49,
+   49, 49, 49, 49,  2,  2, 49, 49, 49,  2,  2,  2,  2,  2,  0,  0,
+    0,  2,  2,  2,  2,  0,  0,  0,  0,  0,  2,  2,  2,  0,  0,  0,
+    0,  0,  0,  2,  2,  2,  9,  2,  2,  2,  2,  2,  2,  2,  0,  0,
+    0,  0,  0,  1,  2,  2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+   71, 71, 71,  2,  2,  2, 67, 67, 67, 67, 67, 67, 67, 67, 67,  2,
+    2,  2,  2,  2,  2,  2,  1,  0,  0,  0,  0,  0,  0,  0, 42, 42,
+   42, 42, 42, 42, 42, 42, 42, 42, 42, 42,  2,  2,  2,  2,  2,  2,
+    2,  2,  2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+   41,  2,  2,  2,  2,  2,118,118,118,118,118,118,118,118,118,118,
+  118,  2,  2,  2,  2,  2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+   53, 53, 53, 53,  2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59,  2,  2,  2,  2, 59, 59, 59, 59, 59, 59,  2,  2, 40, 40,
+   40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50,
+   50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,  2,  2, 50, 50,
+    2,  2,  2,  2,  2,  2,135,135,135,135,135,135,135,135,135,135,
+  135,135,  2,  2,  2,  2,106,106,106,106,106,106,106,106,104,104,
+  104,104,104,104,104,104,104,104,104,104,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,104,161,161,161,161,161,161,161,161,161,161,
+  161,  2,161,161,161,161,161,161,161,  2,161,161,  2,161,161,161,
+    2,161,161,161,161,161,161,161,  2,161,161,  2,  2,  2,110,110,
+  110,110,110,110,110,110,110,110,110,110,110,110,110,  2,110,110,
+  110,110,110,110,  2,  2, 19, 19, 19, 19, 19, 19,  2, 19, 19,  2,
+   19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47,  2,  2, 47,  2,
+   47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+   47, 47, 47, 47,  2, 47, 47,  2,  2,  2, 47,  2,  2, 47, 81, 81,
+   81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,  2, 81,120,120,
+  120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116,
+  116,116,116,116,116,  2,  2,  2,  2,  2,  2,  2,  2,116,128,128,
+  128,128,128,128,128,128,128,128,128,  2,128,128,  2,  2,  2,  2,
+    2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+   66, 66,  2,  2,  2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+    2,  2,  2,  2,  2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97,
+   97, 97, 97, 97, 97, 97,  2,  2,  2,  2, 97, 97, 97, 97,  2,  2,
+   97, 97, 97, 97, 97, 97, 57, 57, 57, 57,  2, 57, 57,  2,  2,  2,
+    2,  2, 57, 57, 57, 57, 57, 57, 57, 57,  2, 57, 57, 57,  2, 57,
+   57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+   57, 57, 57, 57,  2,  2, 57, 57, 57,  2,  2,  2,  2, 57, 57,  2,
+    2,  2,  2,  2,  2,  2, 88, 88, 88, 88, 88, 88, 88, 88,117,117,
+  117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112,
+  112,112,112,112,112,  2,  2,  2,  2,112,112,112,112,112, 78, 78,
+   78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,  2,  2,  2, 78,
+   78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+   83, 83, 83, 83,  2,  2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+   82,  2,  2,  2,  2,  2,122,122,122,122,122,122,122,122,122,122,
+    2,  2,  2,  2,  2,  2,  2,122,122,122,122,  2,  2,  2,  2,122,
+  122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89,  2,
+    2,  2,  2,  2,  2,  2,130,130,130,130,130,130,130,130,130,130,
+  130,  2,  2,  2,  2,  2,  2,  2,130,130,130,130,130,130,144,144,
+  144,144,144,144,144,144,144,144,  2,  2,  2,  2,  2,  2,156,156,
+  156,156,156,156,156,156,156,156,  2,156,156,156,  2,  2,156,156,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,147,147,
+  147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148,
+    2,  2,  2,  2,  2,  2,158,158,158,158,158,158,158,158,158,158,
+    2,  2,  2,  2,  2,  2,153,153,153,153,153,153,153,153,153,153,
+  153,153,  2,  2,  2,  2,149,149,149,149,149,149,149,149,149,149,
+  149,149,149,149,149,  2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+   94, 94, 94, 94,  2,  2,  2,  2, 94, 94, 94, 94, 94, 94,  2,  2,
+    2,  2,  2,  2,  2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+   85,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 85,  2,  2,101,101,
+  101,101,101,101,101,101,101,  2,  2,  2,  2,  2,  2,  2,101,101,
+    2,  2,  2,  2,  2,  2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96,  2, 96, 96,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,  2,100,100,100,100,100,100,100,100,  2, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2,108,108,
+  108,108,108,108,108,108,108,108,  2,108,108,108,108,108,108,108,
+    2,  2,  2,  2,  2,  2,129,129,129,129,129,129,129,  2,129,  2,
+  129,129,129,129,  2,129,129,129,129,129,129,129,129,129,129,129,
+  129,129,129,129,  2,129,129,129,  2,  2,  2,  2,  2,  2,109,109,
+  109,109,109,109,109,109,109,109,109,  2,  2,  2,  2,  2,109,109,
+    2,  2,  2,  2,  2,  2,107,107,107,107,  2,107,107,107,107,107,
+  107,107,107,  2,  2,107,107,  2,  2,107,107,107,107,107,107,107,
+  107,107,107,107,107,107,107,  2,107,107,107,107,107,107,107,  2,
+  107,107,  2,107,107,107,107,107,  2,  1,107,107,107,107,107,  2,
+    2,107,107,107,  2,  2,107,  2,  2,  2,  2,  2,  2,107,  2,  2,
+    2,  2,  2,107,107,107,107,107,107,107,  2,  2,107,107,107,107,
+  107,107,107,  2,  2,  2,137,137,137,137,137,137,137,137,137,137,
+  137,137,  2,137,137,137,137,137,  2,  2,  2,  2,  2,  2,124,124,
+  124,124,124,124,124,124,124,124,  2,  2,  2,  2,  2,  2,123,123,
+  123,123,123,123,123,123,123,123,123,123,123,123,  2,  2,114,114,
+  114,114,114,114,114,114,114,114,114,114,114,  2,  2,  2,114,114,
+    2,  2,  2,  2,  2,  2, 32, 32, 32, 32, 32,  2,  2,  2,102,102,
+  102,102,102,102,102,102,102,102,  2,  2,  2,  2,  2,  2,126,126,
+  126,126,126,126,126,126,126,126,126,  2,  2,126,126,126,126,126,
+  126,126,  2,  2,  2,  2,126,126,126,126,126,126,126,  2,142,142,
+  142,142,142,142,142,142,142,142,142,142,  2,  2,  2,  2,125,125,
+  125,125,125,125,125,125,125,125,125,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,125,154,154,154,154,154,154,154,  2,  2,154,
+    2,  2,154,154,154,154,154,154,154,154,  2,154,154,  2,154,154,
+  154,154,154,154,154,154,154,154,154,154,154,154,  2,154,154,  2,
+    2,154,154,154,154,154,154,154,  2,  2,  2,  2,  2,  2,150,150,
+  150,150,150,150,150,150,  2,  2,150,150,150,150,150,150,150,150,
+  150,150,150,  2,  2,  2,141,141,141,141,141,141,141,141,140,140,
+  140,140,140,140,140,140,140,140,140,  2,  2,  2,  2,  2,121,121,
+  121,121,121,121,121,121,121,  2,  2,  2,  2,  2,  2,  2,  7,  7,
+    2,  2,  2,  2,  2,  2,133,133,133,133,133,133,133,133,133,  2,
+  133,133,133,133,133,133,133,133,133,133,133,133,133,  2,133,133,
+  133,133,133,133,  2,  2,133,133,133,133,133,  2,  2,  2,134,134,
+  134,134,134,134,134,134,  2,  2,134,134,134,134,134,134,  2,134,
+  134,134,134,134,134,134,134,134,134,134,134,134,134,  2,138,138,
+  138,138,138,138,138,  2,138,138,  2,138,138,138,138,138,138,138,
+  138,138,138,138,138,138,  2,  2,138,  2,138,138,  2,138,138,138,
+    2,  2,  2,  2,  2,  2,143,143,143,143,143,143,  2,143,143,  2,
+  143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+  143,143,143,143,143,  2,143,143,  2,143,143,143,143,143,143,  2,
+    2,  2,  2,  2,  2,  2,143,143,  2,  2,  2,  2,  2,  2,145,145,
+  145,145,145,145,145,145,145,  2,  2,  2,  2,  2,  2,  2,163,163,
+  163,163,163,163,163,163,163,  2,163,163,163,163,163,163,163,163,
+  163,  2,  2,  2,163,163,163,163,  2,  2,  2,  2,  2,  2, 86,  2,
+    2,  2,  2,  2,  2,  2, 22, 22,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+    2,  2,  2,  2,  2,  2, 63, 63, 63, 63, 63, 63, 63,  2, 63, 63,
+   63, 63, 63,  2,  2,  2, 63, 63, 63, 63,  2,  2,  2,  2,157,157,
+  157,157,157,157,157,157,157,157,157,  2,  2,  2,  2,  2, 80, 80,
+   80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,  2,  2,127,127,
+  127,127,127,127,127,127,127,127,127,127,127,127,127,  2, 79,  2,
+    2,  2,  2,  2,  2,  2,115,115,115,115,115,115,115,115,115,115,
+  115,115,115,115,115,  2,115,115,  2,  2,  2,  2,115,115,159,159,
+  159,159,159,159,159,159,159,159,159,159,159,159,159,  2,159,159,
+    2,  2,  2,  2,  2,  2,103,103,103,103,103,103,103,103,103,103,
+  103,103,103,103,  2,  2,119,119,119,119,119,119,119,119,119,119,
+  119,119,119,119,  2,  2,119,119,  2,119,119,119,119,119,  2,  2,
+    2,  2,  2,119,119,119,146,146,146,146,146,146,146,146,146,146,
+  146,  2,  2,  2,  2,  2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+   99,  2,  2,  2,  2, 99,  2,  2,  2,  2,  2,  2,  2, 99,136,139,
+   13, 13,155,  2,  2,  2,136,136,136,136,136,136,136,136,155,155,
+  155,155,155,155,155,155,155,155,155,155,155,155,  2,  2,136,  2,
+    2,  2,  2,  2,  2,  2, 17, 17, 17, 17,  2, 17, 17, 17, 17, 17,
+   17, 17,  2, 17, 17,  2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17,
+   17,  2,  2,  2,  2,  2,  2,  2, 15,  2,  2,  2,  2,  2, 15, 15,
+   15,  2,  2, 17,  2,  2,  2,  2,  2,  2, 17, 17, 17, 17,139,139,
+  139,139,139,139,139,139,139,139,139,139,  2,  2,  2,  2,105,105,
+  105,105,105,105,105,105,105,105,105,  2,  2,  2,  2,  2,105,105,
+  105,105,105,  2,  2,  2,105,  2,  2,  2,  2,  2,  2,  2,105,105,
+    2,  2,105,105,105,105,  1,  1,  1,  1,  1,  1,  2,  2,  0,  0,
+    0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,
+    1,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  2,  2,
+    0,  2,  2,  0,  0,  2,  2,  0,  0,  0,  0,  2,  0,  0,  0,  0,
+    2,  0,  2,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,
+    0,  2,  2,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  0,
+    0,  0,  0,  2,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  2,
+    0,  0,  0,  0,  0,  0,131,131,131,131,131,131,131,131,131,131,
+  131,131,  2,  2,  2,  2,  2,  2,  2,131,131,131,131,131,  2,131,
+  131,131,131,131,131,131,  2,  2,  2,  2,  2, 19, 19, 19, 56, 56,
+   56, 56, 56, 56, 56,  2, 56,  2,  2, 56, 56, 56, 56, 56, 56, 56,
+    2, 56, 56,  2, 56, 56, 56, 56, 56,  2,  2,  2,  2,  2,  6,  6,
+    6,  6,  6,  6,  2,  2,  2,  2,  2,  2,  2,  2,  2,  6,151,151,
+  151,151,151,151,151,151,151,151,151,151,151,  2,  2,  2,151,151,
+  151,151,151,151,  2,  2,151,151,  2,  2,  2,  2,151,151,160,160,
+  160,160,160,160,160,160,160,160,160,160,160,160,160,  2,152,152,
+  152,152,152,152,152,152,152,152,  2,  2,  2,  2,  2,152,164,164,
+  164,164,164,164,164,164,164,164,  2,  2,  2,  2,  2,  2, 30, 30,
+   30, 30,  2, 30, 30,  2,113,113,113,113,113,113,113,113,113,113,
+  113,113,113,  2,  2,113,113,113,113,113,113,113,113,  2,132,132,
+  132,132,132,132,132,132,132,132,132,132,  2,  2,  2,  2,132,132,
+    2,  2,  2,  2,132,132,  3,  3,  3,  3,  2,  3,  3,  3,  2,  3,
+    3,  2,  3,  2,  2,  3,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  2,  3,  3,  3,  3,  2,  3,  2,  3,  2,  2,  2,  2,  2,  2,
+    3,  2,  2,  2,  2,  3,  2,  3,  2,  3,  2,  3,  3,  3,  2,  3,
+    2,  3,  2,  3,  2,  3,  2,  3,  3,  3,  3,  2,  3,  2,  3,  3,
+    2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  3,
+    3,  3,  2,  3,  3,  3,  2,  2,  2,  2,  2,  2,  0,  0, 15,  0,
+    0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  2,  2,
+    2,  0,  0,  0,  0,  0, 13,  2,  2,  2,  2,  2,  2,  2, 13, 13,
+   13,  2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  0,  1,
+    2,  3,  4,  5,  6,  7,  8,  9,  9,  9,  9, 10,  9, 11, 12, 13,
+    9,  9,  9, 14,  9,  9, 15,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 16, 17,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9, 18, 19, 20,  9, 21,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9, 16, 17,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 18, 19,
-   20,  9, 21,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 22,  9,
+    9,  9,  9,  9,  9,  9, 22,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
@@ -2161,58 +2137,57 @@
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9, 23, 24,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,  0,  0, 13, 14,
-   15, 16, 17, 18, 19, 20, 21, 22,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 23,  0,  0, 24, 25, 26, 27, 28,
-   29, 30,  0,  0, 31, 32,  0, 33,  0, 34,  0, 35,  0,  0,  0,  0,
-   36, 37, 38, 39,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 40,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-   41, 42,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 23, 24,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,
+    9, 10, 11, 12,  0,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 43, 44,  0, 45,  0,  0,  0,  0,  0,  0,
-   46, 47,  0,  0,  0,  0,  0, 48,  0, 49,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 50, 51,  0,  0,  0, 52,  0,  0,
-   53,  0,  0,  0,  0,  0,  0,  0, 54,  0,  0,  0,  0,  0,  0,  0,
-   55,  0,  0,  0,  0,  0,  0,  0, 56,  0,  0,  0,  0,  0,  0,  0,
-    0, 57,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 58, 59, 60, 61, 62, 63, 64, 65,
-    0,  0,  0,  0,  0,  0, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   23,  0,  0, 24, 25, 26, 27, 28, 29, 30,  0,  0, 31, 32,  0, 33,
+    0, 34,  0, 35,  0,  0,  0,  0, 36, 37, 38, 39,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 40,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 43, 44,
+    0, 45,  0,  0,  0,  0,  0,  0, 46, 47,  0,  0,  0,  0,  0, 48,
+    0, 49,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   50, 51,  0,  0,  0, 52,  0,  0, 53,  0,  0,  0,  0,  0,  0,  0,
+   54,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,  0,  0,  0,  0,
+   56,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   58, 59, 60, 61, 62, 63, 64, 65,  0,  0,  0,  0,  0,  0, 66,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 67, 68,  0, 69, 70,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
-   83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
-   99,100,101,102,103,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,104,  0,  0,  0,  0,  0,  0,105,106,  0,
-  107,  0,  0,  0,108,  0,109,  0,110,  0,111,112,113,  0,114,  0,
-    0,  0,115,  0,  0,  0,116,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,117,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,118,119,120,121,  0,122,123,124,
-  125,126,  0,127,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,128,129,130,131,132,133,134,135,136,137,138,139,
-  140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,
-  156,157,  0,  0,  0,158,159,160,161,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,162,163,  0,
-    0,  0,  0,  0,  0,  0,164,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 67, 68,  0, 69,
+   70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 71, 72, 73, 74,
+   75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+   91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,104,  0,
+    0,  0,  0,  0,  0,105,106,  0,107,  0,  0,  0,108,  0,109,  0,
+  110,  0,111,112,113,  0,114,  0,  0,  0,115,  0,  0,  0,116,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,165,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,166,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,167,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,117,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,168,  0,  0,  0,  0,  0,  0,  0,  0,
+  118,119,120,121,  0,122,123,124,125,126,  0,127,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,169,170,  0,  0,  0,  0,171,
-  172,  0,  0,  0,173,174,175,176,177,178,179,180,181,182,183,184,
-  185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,
-  201,202,203,204,205,206,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,128,129,130,131,
+  132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,
+  148,149,150,151,152,153,154,155,156,157,  0,  0,  0,158,159,160,
+  161,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,162,163,  0,  0,  0,  0,  0,  0,  0,164,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    1,  2,  3,  4,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  165,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,166,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,167,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,168,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,169,170,  0,  0,  0,  0,171,172,  0,  0,  0,173,174,175,176,
+  177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,
+  193,194,195,196,197,198,199,200,201,202,203,204,205,206,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
 };
 static const uint16_t
 _hb_ucd_u16[9320] =
@@ -2827,7 +2802,7 @@
 static inline uint_fast8_t
 _hb_ucd_ccc (unsigned u)
 {
-  return u<125259u?_hb_ucd_u8[9184+(((_hb_ucd_u8[8128+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>3>>4)])<<4)+((u>>2>>3)&15u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u))]:0;
+  return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
 }
 static inline unsigned
 _hb_ucd_b4 (const uint8_t* a, unsigned i)
@@ -2837,17 +2812,17 @@
 static inline int_fast16_t
 _hb_ucd_bmg (unsigned u)
 {
-  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9932+(((_hb_ucd_u8[9812+(((_hb_ucd_b4(9684+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9540+(((_hb_ucd_u8[9420+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
 }
 static inline uint_fast8_t
 _hb_ucd_sc (unsigned u)
 {
-  return u<918000u?_hb_ucd_u8[11454+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10718+(((_hb_ucd_u8[10268+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
+  return u<918000u?_hb_ucd_u8[11062+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10326+(((_hb_ucd_u8[9876+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
 }
 static inline uint_fast16_t
 _hb_ucd_dm (unsigned u)
 {
-  return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17460+(((_hb_ucd_u8[17078+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+  return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17068+(((_hb_ucd_u8[16686+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
 }
 
 
@@ -2854,7 +2829,7 @@
 #elif !defined(HB_NO_UCD_UNASSIGNED)
 
 static const uint8_t
-_hb_ucd_u8[17868] =
+_hb_ucd_u8[14744] =
 {
     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  9, 10,  7,  7,  7,  7, 11, 12, 13, 13, 13, 14,
@@ -3436,50 +3411,54 @@
     0,230,220,  0,  0,  0,220,220,  0,  0,230,220,  0,  9,  7,  0,
     0,  7,  9,  0,  0,  0,  9,  7,  6,  6,  0,  0,  0,  0,  1,  0,
     0,216,216,  1,  1,  1,  0,  0,  0,226,216,216,216,216,216,  0,
-  220,220,220,  0,232,232,220,230,230,230,  7,  0, 16, 17, 17, 17,
-   17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,
-  129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+  220,220,220,  0,232,232,220,230,230,230,  7,  0, 16, 17, 17, 33,
+   17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237,  0,  1,  2,  2,
-    0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  6,  7,  8,
-    9,  0,  0,  0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 20,  0,  0, 21, 22,  0,  0,  0,  0,
-   23, 24, 25, 26,  0, 27,  0, 28, 29, 30, 31, 32,  0,  0,  0,  0,
-    0,  0,  0, 33, 34, 35, 36,  0,  0,  0,  0,  0, 37,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,  1,  2, 40, 41,
-    0,  1,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,
-    0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  5,  0,
-    0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  7,  1,  0,  0,  0,  0,
-    0,  0,  8,  9,  0,  0,  0,  0,  0,  0, 10,  0,  0, 10,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0, 10,
-    0,  0,  0,  0,  0,  0, 11, 12,  0, 13,  0, 14, 15, 16,  0,  0,
-    0,  0,  0,  1, 17, 18,  0, 19,  7,  1,  0,  0,  0, 20, 20,  7,
-   20, 20, 20, 20, 20, 20, 20,  8, 21,  0, 22,  0,  7, 23, 24,  0,
-   20, 20, 25,  0,  0,  0, 26, 27,  1,  7, 20, 20, 20, 20, 20,  1,
-   28, 29, 30, 31,  0,  0, 20,  0,  0,  0,  0,  0,  0,  0, 10,  0,
-    0,  0,  0,  0,  0,  0, 20, 20, 20,  1,  0,  0,  8, 21, 32,  4,
-    0, 10,  0, 33,  7, 20, 20, 20,  0,  0,  0,  0,  8, 34, 34, 35,
-   36, 34, 37,  0, 38,  1, 20, 20,  0,  0, 39,  0,  1,  1,  0,  8,
-   21,  1, 20,  0,  0,  0,  1,  0,  0, 40,  1,  1,  0,  0,  8, 21,
-    0,  1,  0,  1,  0,  1,  0,  0,  0,  0, 26, 34, 34, 34, 34, 34,
-   34, 34, 34, 34, 21,  7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 21,  0, 42, 43, 44,  0, 45,  0,  8, 21,  0,  0,  0,  0,  0,
-    0,  0,  0, 46,  7,  1, 10,  1,  0,  0,  0,  1, 20, 20,  1,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0, 26, 34,  9,  0,  0, 20, 20,
-    1, 20, 20,  0,  0,  0,  0,  0,  0,  0, 26, 21,  0,  1,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, 47, 48,  0,  0,  0,
-    0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7,  9, 10, 11, 11, 11, 11, 12, 13,
-   13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13,
-   13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32,
-   33, 34, 35, 36,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7, 37,  7, 38, 39,  7, 40,  7,  7,
-    7, 41, 13, 42,  7,  7, 43,  7, 44, 13, 13, 13, 13, 13, 13, 13,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177,  0,  1,  2,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    4,  3,  3,  3,  3,  3,  5,  3,  3,  3,  3,  3,  6,  7,  8,  3,
+    3,  3,  3,  3,  9, 10, 11, 12, 13,  3,  3,  3,  3,  3,  3,  3,
+    3, 14,  3, 15,  3,  3,  3,  3,  3,  3, 16, 17, 18, 19, 20, 21,
+    3,  3,  3, 22, 23, 24,  3,  3,  3,  3,  3,  3, 25,  3,  3,  3,
+    3,  3,  3,  3,  3, 26,  3,  3, 27, 28,  0,  1,  0,  0,  0,  0,
+    0,  1,  0,  2,  0,  0,  0,  3,  0,  0,  0,  3,  0,  0,  0,  0,
+    0,  4,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  6,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  8,  9,  0,  0,  0,  0,  0,  0,  9,  0,  9,  0,  0,
+    0,  0,  0,  0,  0, 10, 11, 12, 13,  0,  0, 14, 15, 16,  6,  0,
+   17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25,  0, 26, 27, 19,
+   19, 28, 29, 30,  0, 31,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,
+    0, 19, 28,  0, 32, 33,  9, 34, 35, 19,  0,  0, 36, 37, 38, 39,
+   40, 19,  0, 41, 42, 43, 44, 31,  0,  1, 45, 42,  0,  0,  0,  0,
+    0, 32, 14, 14,  0,  0,  0,  0, 14,  0,  0, 46, 47, 47, 47, 47,
+   48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21,  0,  0,  0,  0,
+    0,  0,  0, 54,  6, 55,  0, 14, 19,  1,  0,  0,  0,  0, 56, 57,
+    0,  0,  0,  0,  0, 19, 58, 31,  0,  0,  0,  0,  0,  0,  0, 59,
+   14,  0,  0,  0,  0,  1,  0,  2,  0,  0,  0,  3,  0,  0,  0, 60,
+   61,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  2,  3,
+    0,  4,  5,  0,  0,  6,  0,  0,  0,  7,  0,  0,  0,  1,  1,  0,
+    0,  8,  9,  0,  8,  9,  0,  0,  0,  0,  8,  9, 10, 11, 12,  0,
+    0,  0, 13,  0,  0,  0,  0, 14, 15, 16, 17,  0,  0,  0,  1,  0,
+    0, 18, 19,  0,  0,  0, 20,  0,  0,  0,  1,  1,  1,  1,  0,  1,
+    1,  1,  1,  1,  1,  1,  0,  8, 21,  9,  0,  0, 22,  0,  0,  0,
+    0,  1,  0, 23, 24, 25,  0,  0, 26,  0,  0,  0,  8, 21, 27,  0,
+    1,  0,  0,  1,  1,  1,  1,  0,  1, 28, 29, 30,  0, 31, 32, 20,
+    1,  1,  0,  0,  0,  8, 21,  9,  1,  4,  5,  0,  0,  0, 33,  9,
+    0,  1,  1,  1,  0,  8, 21, 21, 21, 21, 34,  1, 35, 21, 21, 21,
+    9, 36,  0,  0, 37, 38,  1,  0, 39,  0,  0,  0,  1,  0,  1,  0,
+    0,  0,  0,  8, 21,  9,  1,  0,  0,  0, 40,  0,  8, 21, 21, 21,
+   21, 21, 21, 21, 21,  9,  0,  1,  1,  1,  1,  8, 21, 21, 21,  9,
+    0,  0,  0, 41,  0, 42, 43,  0,  0,  0,  1, 44,  0,  0,  0, 45,
+    8,  9,  1,  0,  0,  0,  8, 21, 21, 21,  9,  0,  1,  0,  1,  1,
+    8, 21, 21,  9,  0,  4,  5,  8,  9,  1,  0,  0,  0,  1,  2,  3,
+    4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
+   19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
+   13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   37,  7, 38, 39,  7, 40,  7,  7,  7, 41, 13, 42,  7,  7, 43,  7,
+   44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
@@ -3500,420 +3479,221 @@
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 45,  0,  0,  1,  2,  2,  2,  3,  4,  5,  6,  7,
-    8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37,
-   37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
-   51, 52,  2,  2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59,
-   59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65,
-   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45,  0,  0,  1,
+    2,  2,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+   32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
+   43, 44, 45, 46, 47, 48, 49, 50, 51, 52,  2,  2, 53, 54, 55, 56,
+   57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
+   59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+   74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81,
-   82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
+   80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
+   89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101,
-  102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116,
-  117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131,
-  132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145,
-   96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158,
-  159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164,
-  167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171,
-  171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96,
-   96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
+  110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
+  124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
+  139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
+  152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
+  164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
+  169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
+  173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
   182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
-  182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185,
-  186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204,
-  205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96,
-   96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215,
-   96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221,
-  222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59,
-   59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+  182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
+  182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
+  190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
+  198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
+  208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
+  213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
+  219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
+   59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
+   59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70,242, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,243, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,244, 96, 96,
-   96, 96, 96, 96, 96, 96,245, 96,246,247,  0,  1,  2,  2,  0,  1,
-    2,  2,  2,  3,  4,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,
-   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-   19,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0, 19, 19,
-   19, 19, 19, 19, 19,  0, 19,  0,  0,  0,  0,  0,  0,  0, 19, 19,
-   19, 19, 19,  0,  0,  0,  0,  0, 26, 26,  0,  0,  0,  0,  1,  1,
-    1,  1,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,  2,  2,
-    9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,  9,  0,  9,  9,
-    9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    2,  9,  9,  9,  9,  9,  9,  9, 55, 55, 55, 55, 55, 55, 55, 55,
-   55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
-    6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,
-    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  4,  4,
-    4,  2,  2,  4,  4,  4,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-   14, 14, 14, 14, 14, 14,  2,  2,  2,  2,  2,  2,  2,  2, 14, 14,
-   14,  2,  2,  2,  2, 14, 14, 14, 14, 14, 14,  2,  2,  2,  3,  3,
-    3,  3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  0,  0,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  1,  1,  1,  1,  1,  1,  1,
-    1,  1,  1,  1,  3,  3,  1,  3,  3,  3,  3,  3,  3,  3, 37, 37,
-   37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37,
-   37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
-    2,  2,  2,  2,  2,  2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-   64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
-   90, 90, 90, 90,  2,  2, 90, 90, 90, 90, 90, 90, 90,  2, 95, 95,
-   95, 95, 95, 95, 95, 95, 95, 95, 95, 95,  2,  2, 95,  2, 37, 37,
-   37,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,
-    2,  2,  2,  2,  2,  2,  3,  3,  0,  3,  3,  3,  3,  3,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  7,  7,
-    7,  7,  0,  0,  7,  7,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,
-    5,  5,  5,  2,  2,  5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,
-    5,  5,  5,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  2,
-    5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  5,  2,
-    2,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,  2,  5,  2,  2,
-    2,  2,  5,  5,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,
-    5,  5,  5,  5,  5,  2,  2, 11, 11, 11,  2, 11, 11, 11, 11, 11,
-   11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11, 11, 11, 11, 11,
-   11, 11, 11, 11, 11, 11, 11,  2, 11, 11, 11, 11, 11, 11, 11,  2,
-   11, 11,  2, 11, 11,  2, 11, 11,  2,  2, 11,  2, 11, 11, 11,  2,
-    2, 11, 11, 11,  2,  2,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11,
-   11, 11, 11,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,
-   11, 11, 11, 11, 11,  2,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10,
-   10, 10, 10, 10,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,
-   10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,  2,
-   10, 10,  2, 10, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10, 10, 10,
-    2, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,  2,  2, 10, 10,
-   10, 10,  2,  2, 10, 10, 10, 10,  2,  2,  2,  2,  2,  2,  2, 10,
-   10, 10, 10, 10, 10, 10,  2, 21, 21, 21,  2, 21, 21, 21, 21, 21,
-   21, 21, 21,  2,  2, 21, 21,  2,  2, 21, 21, 21, 21, 21, 21, 21,
-   21, 21, 21, 21, 21, 21, 21,  2, 21, 21, 21, 21, 21, 21, 21,  2,
-   21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21, 21, 21,  2,
-    2, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2, 21, 21, 21,  2,  2,
-    2,  2, 21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,  2,
-   22, 22,  2, 22, 22, 22, 22, 22, 22,  2,  2,  2, 22, 22, 22,  2,
-   22, 22, 22, 22,  2,  2,  2, 22, 22,  2, 22,  2, 22, 22,  2,  2,
-    2, 22, 22,  2,  2,  2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-    2,  2,  2,  2, 22, 22, 22,  2,  2,  2,  2,  2,  2, 22,  2,  2,
-    2,  2,  2,  2, 22, 22, 22, 22, 22,  2,  2,  2,  2,  2, 23, 23,
-   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  2, 23, 23, 23,  2,
-   23, 23, 23, 23, 23, 23, 23, 23,  2,  2, 23, 23, 23, 23, 23,  2,
-   23, 23, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 23,  2, 23, 23,
-   23,  2,  2, 23,  2,  2, 23, 23, 23, 23,  2,  2, 23, 23,  2,  2,
-    2,  2,  2,  2,  2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-   16, 16, 16,  2, 16, 16, 16,  2, 16, 16, 16, 16, 16, 16, 16, 16,
-   16, 16,  2, 16, 16, 16, 16, 16,  2,  2, 16, 16, 16, 16, 16,  2,
-   16, 16, 16, 16,  2,  2,  2,  2,  2,  2,  2, 16, 16,  2, 16, 16,
-   16, 16,  2,  2, 16, 16,  2, 16, 16, 16,  2,  2,  2,  2, 20, 20,
-   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  2, 20, 20, 20,  2,
-   20, 20, 20, 20, 20, 20,  2,  2,  2,  2, 20, 20, 20, 20, 20, 20,
-   20, 20,  2,  2, 20, 20,  2, 36, 36, 36,  2, 36, 36, 36, 36, 36,
-   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2,
-   36, 36, 36, 36, 36, 36, 36, 36,  2, 36, 36, 36, 36, 36, 36, 36,
-   36, 36,  2, 36,  2,  2,  2,  2, 36,  2,  2,  2,  2, 36, 36, 36,
-   36, 36, 36,  2, 36,  2,  2,  2,  2,  2,  2,  2, 36, 36,  2,  2,
-   36, 36, 36,  2,  2,  2,  2, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-   24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0, 24, 24,
-   24, 24,  2,  2,  2,  2,  2, 18, 18,  2, 18,  2, 18, 18, 18, 18,
-   18,  2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-   18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2,  2, 18, 18,
-   18, 18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2, 18, 18,
-    2,  2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25,  2, 25,
-   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  2,  2,  2, 25, 25,
-   25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25,  0,  0,  0,  0, 25,
-   25,  2,  2,  2,  2,  2, 33, 33, 33, 33, 33, 33, 33, 33,  8,  8,
-    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  2,  8,  2,  2,
-    2,  2,  2,  8,  2,  2,  8,  8,  8,  0,  8,  8,  8,  8, 12, 12,
-   12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30,  2,
-   30, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30,  2, 30, 30,
-   30,  2,  2, 30, 30, 30, 30, 30, 30, 30, 30,  2,  2,  2, 30, 30,
-    2,  2,  2,  2,  2,  2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-   29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34,
-   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,  2,  2,  2, 35, 35,
-   35, 35, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0, 35, 35, 35,  2,
-    2,  2,  2,  2,  2,  2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-   45, 45, 45, 45,  2,  2,  2,  2,  2,  2,  2,  2,  2, 45, 44, 44,
-   44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43,
-   43, 43, 43, 43, 43, 43, 43, 43, 43, 43,  2,  2,  2,  2, 46, 46,
-   46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,  2, 46, 46, 46,  2,
-   46, 46,  2,  2,  2,  2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-   31, 31, 31, 31,  2,  2, 31, 31,  2,  2,  2,  2,  2,  2, 32, 32,
-    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    2,  2,  2,  2,  2,  2, 32,  2,  2,  2,  2,  2,  2,  2, 32, 32,
-   32,  2,  2,  2,  2,  2, 28, 28, 28, 28, 28, 28,  2,  2, 48, 48,
-   48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,  2, 48, 48,
-   48, 48,  2,  2,  2,  2, 48,  2,  2,  2, 48, 48, 48, 48, 52, 52,
-   52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,  2,  2, 52, 52,
-   52, 52, 52,  2,  2,  2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-   58, 58,  2,  2,  2,  2, 58, 58,  2,  2,  2,  2,  2,  2, 58, 58,
-   58,  2,  2,  2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
-   54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-   91, 91, 91, 91, 91,  2, 91, 91, 91, 91, 91,  2,  2, 91, 91, 91,
-    2,  2,  2,  2,  2,  2, 91, 91, 91, 91, 91, 91,  2,  2,  1,  1,
-    1,  1,  1,  1,  1,  2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
-   62, 62, 62,  2,  2,  2, 62, 62, 62, 62, 62, 62, 62,  2, 76, 76,
-   76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
-   93, 93,  2,  2,  2,  2,  2,  2,  2,  2, 93, 93, 93, 93, 70, 70,
-   70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 70, 70, 70, 70,
-    2,  2,  2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73,  6,  2,
-    2,  2,  2,  2,  2,  2,  8,  8,  8,  2,  2,  8,  8,  8,  1,  1,
-    1,  0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  0,
-    0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  1,
-    0,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,
-    9,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,  9,
-   19, 19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19, 19,  6, 19,
-   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,
-    9,  9,  9,  9,  2,  2,  2,  9,  2,  9,  2,  9,  2,  9,  9,  9,
-    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,  9,
-    9,  9,  2,  9,  9,  9,  2,  2,  9,  9,  9,  2,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  2,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,
-    0,  0,  0,  2,  0,  0,  0, 19,  2,  2,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0,  0,  0,  2, 19, 19,
-   19, 19, 19,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,
-   19, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0, 19,  0,
-    0,  0,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2,  2, 27, 27,
-   27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,
-    0,  0,  0,  0,  2,  0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55,
-   55, 55,  2,  2,  2,  2,  2, 55, 55, 55, 55, 55, 55, 55, 61, 61,
-   61, 61, 61, 61, 61, 61,  2,  2,  2,  2,  2,  2,  2, 61, 61,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  2,  2, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13,  2, 13, 13, 13, 13, 13, 13, 13,
-   13, 13,  2,  2,  2,  2, 13, 13, 13, 13, 13, 13,  2,  2,  0,  0,
-    0,  0,  2,  2,  2,  2,  0,  0,  0,  0,  0, 13,  0, 13,  0, 13,
-   13, 13, 13, 13, 13, 13, 13, 13,  1,  1,  1,  1, 12, 12, 13, 13,
-   13, 13,  0,  0,  0,  0,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  1,
-    1,  0,  0, 15, 15, 15,  0, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17,  0,  0, 17, 17, 17,  2,  2,
-    2,  2,  2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2, 12,
-   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2, 12, 12,
-   12, 12, 12, 12, 12,  0, 17, 17, 17, 17, 17, 17, 17,  0, 39, 39,
-   39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39,
-   39, 39, 39, 39, 39,  2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77,
-   77, 77, 77, 77, 77, 77, 77, 77, 77, 77,  2,  2,  2,  2, 79, 79,
-   79, 79, 79, 79, 79, 79,  0,  0, 19, 19, 19, 19, 19, 19,  0,  0,
-    0, 19, 19, 19, 19, 19, 19, 19, 19,  2,  2,  2,  2,  2, 19, 19,
-    2, 19,  2, 19, 19, 19, 19, 19,  2,  2,  2,  2,  2,  2,  2,  2,
-   19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-   60, 60, 60,  2,  2,  2,  0,  0,  2,  2,  2,  2,  2,  2, 65, 65,
-   65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
-   75, 75, 75, 75,  2,  2,  2,  2,  2,  2,  2,  2, 75, 75, 75, 75,
-    2,  2,  2,  2,  2,  2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
-   69, 69, 69, 69,  0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
-   74, 74,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 74, 12, 12,
-   12, 12, 12,  2,  2,  2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
-   84, 84, 84, 84,  2,  0, 84, 84,  2,  2,  2,  2, 84, 84, 33, 33,
-   33, 33, 33, 33, 33,  2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
-   68, 68, 68, 68, 68,  2, 68, 68, 68, 68, 68, 68,  2,  2, 68, 68,
-    2,  2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-   92,  2,  2,  2,  2,  2,  2,  2,  2, 92, 92, 92, 92, 92, 87, 87,
-   87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,  2,  2, 30,
-   30, 30, 30, 30, 30,  2, 19, 19, 19,  0, 19, 19, 19, 19, 19, 19,
-   19, 19, 19,  9, 19, 19, 19, 19,  0,  0,  2,  2,  2,  2, 87, 87,
-   87, 87, 87, 87,  2,  2, 87, 87,  2,  2,  2,  2,  2,  2, 12, 12,
-   12, 12,  2,  2,  2,  2,  2,  2,  2, 12, 12, 12, 12, 12, 13, 13,
-    2,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19, 19,  2,  2,  2,
-    2,  4,  4,  4,  4,  4,  2,  2,  2,  2,  2, 14, 14, 14, 14, 14,
-   14, 14, 14, 14, 14,  2, 14, 14, 14, 14, 14,  2, 14,  2, 14, 14,
-    2, 14, 14,  2, 14, 14,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,
-    2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  0,  2,  2,
-    3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,  3,  1,  1,
-    1,  1,  1,  1,  6,  6,  0,  0,  0,  2,  0,  0,  0,  0,  3,  3,
-    3,  3,  3,  2,  3,  3,  3,  3,  3,  3,  3,  2,  2,  0,  2,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17, 17,
-   17, 17, 17, 17,  0,  0,  2,  2, 12, 12, 12, 12, 12, 12,  2,  2,
-   12, 12, 12,  2,  2,  2,  2,  0,  0,  0,  0,  0,  2,  2, 49, 49,
-   49, 49, 49, 49, 49, 49, 49, 49, 49, 49,  2, 49, 49, 49, 49, 49,
-   49, 49, 49, 49, 49,  2, 49, 49, 49,  2, 49, 49,  2, 49, 49, 49,
-   49, 49, 49, 49,  2,  2, 49, 49, 49,  2,  2,  2,  2,  2,  0,  0,
-    0,  2,  2,  2,  2,  0,  0,  0,  0,  0,  2,  2,  2,  0,  0,  0,
-    0,  0,  0,  2,  2,  2,  9,  2,  2,  2,  2,  2,  2,  2,  0,  0,
-    0,  0,  0,  1,  2,  2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
-   71, 71, 71,  2,  2,  2, 67, 67, 67, 67, 67, 67, 67, 67, 67,  2,
-    2,  2,  2,  2,  2,  2,  1,  0,  0,  0,  0,  0,  0,  0, 42, 42,
-   42, 42, 42, 42, 42, 42, 42, 42, 42, 42,  2,  2,  2,  2,  2,  2,
-    2,  2,  2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
-   41,  2,  2,  2,  2,  2,118,118,118,118,118,118,118,118,118,118,
-  118,  2,  2,  2,  2,  2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
-   53, 53, 53, 53,  2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
-   59, 59,  2,  2,  2,  2, 59, 59, 59, 59, 59, 59,  2,  2, 40, 40,
-   40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50,
-   50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,  2,  2, 50, 50,
-    2,  2,  2,  2,  2,  2,135,135,135,135,135,135,135,135,135,135,
-  135,135,  2,  2,  2,  2,106,106,106,106,106,106,106,106,104,104,
-  104,104,104,104,104,104,104,104,104,104,  2,  2,  2,  2,  2,  2,
-    2,  2,  2,  2,  2,104,161,161,161,161,161,161,161,161,161,161,
-  161,  2,161,161,161,161,161,161,161,  2,161,161,  2,161,161,161,
-    2,161,161,161,161,161,161,161,  2,161,161,  2,  2,  2,110,110,
-  110,110,110,110,110,110,110,110,110,110,110,110,110,  2,110,110,
-  110,110,110,110,  2,  2, 19, 19, 19, 19, 19, 19,  2, 19, 19,  2,
-   19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47,  2,  2, 47,  2,
-   47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
-   47, 47, 47, 47,  2, 47, 47,  2,  2,  2, 47,  2,  2, 47, 81, 81,
-   81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,  2, 81,120,120,
-  120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116,
-  116,116,116,116,116,  2,  2,  2,  2,  2,  2,  2,  2,116,128,128,
-  128,128,128,128,128,128,128,128,128,  2,128,128,  2,  2,  2,  2,
-    2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
-   66, 66,  2,  2,  2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
-    2,  2,  2,  2,  2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97,
-   97, 97, 97, 97, 97, 97,  2,  2,  2,  2, 97, 97, 97, 97,  2,  2,
-   97, 97, 97, 97, 97, 97, 57, 57, 57, 57,  2, 57, 57,  2,  2,  2,
-    2,  2, 57, 57, 57, 57, 57, 57, 57, 57,  2, 57, 57, 57,  2, 57,
-   57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
-   57, 57, 57, 57,  2,  2, 57, 57, 57,  2,  2,  2,  2, 57, 57,  2,
-    2,  2,  2,  2,  2,  2, 88, 88, 88, 88, 88, 88, 88, 88,117,117,
-  117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112,
-  112,112,112,112,112,  2,  2,  2,  2,112,112,112,112,112, 78, 78,
-   78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,  2,  2,  2, 78,
-   78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
-   83, 83, 83, 83,  2,  2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
-   82,  2,  2,  2,  2,  2,122,122,122,122,122,122,122,122,122,122,
-    2,  2,  2,  2,  2,  2,  2,122,122,122,122,  2,  2,  2,  2,122,
-  122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89,  2,
-    2,  2,  2,  2,  2,  2,130,130,130,130,130,130,130,130,130,130,
-  130,  2,  2,  2,  2,  2,  2,  2,130,130,130,130,130,130,144,144,
-  144,144,144,144,144,144,144,144,  2,  2,  2,  2,  2,  2,156,156,
-  156,156,156,156,156,156,156,156,  2,156,156,156,  2,  2,156,156,
-    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,147,147,
-  147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148,
-    2,  2,  2,  2,  2,  2,158,158,158,158,158,158,158,158,158,158,
-    2,  2,  2,  2,  2,  2,153,153,153,153,153,153,153,153,153,153,
-  153,153,  2,  2,  2,  2,149,149,149,149,149,149,149,149,149,149,
-  149,149,149,149,149,  2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
-   94, 94, 94, 94,  2,  2,  2,  2, 94, 94, 94, 94, 94, 94,  2,  2,
-    2,  2,  2,  2,  2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
-   85,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 85,  2,  2,101,101,
-  101,101,101,101,101,101,101,  2,  2,  2,  2,  2,  2,  2,101,101,
-    2,  2,  2,  2,  2,  2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96,  2, 96, 96,111,111,111,111,111,111,111,111,111,111,
-  111,111,111,111,111,  2,100,100,100,100,100,100,100,100,  2, 36,
-   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2,108,108,
-  108,108,108,108,108,108,108,108,  2,108,108,108,108,108,108,108,
-    2,  2,  2,  2,  2,  2,129,129,129,129,129,129,129,  2,129,  2,
-  129,129,129,129,  2,129,129,129,129,129,129,129,129,129,129,129,
-  129,129,129,129,  2,129,129,129,  2,  2,  2,  2,  2,  2,109,109,
-  109,109,109,109,109,109,109,109,109,  2,  2,  2,  2,  2,109,109,
-    2,  2,  2,  2,  2,  2,107,107,107,107,  2,107,107,107,107,107,
-  107,107,107,  2,  2,107,107,  2,  2,107,107,107,107,107,107,107,
-  107,107,107,107,107,107,107,  2,107,107,107,107,107,107,107,  2,
-  107,107,  2,107,107,107,107,107,  2,  1,107,107,107,107,107,  2,
-    2,107,107,107,  2,  2,107,  2,  2,  2,  2,  2,  2,107,  2,  2,
-    2,  2,  2,107,107,107,107,107,107,107,  2,  2,107,107,107,107,
-  107,107,107,  2,  2,  2,137,137,137,137,137,137,137,137,137,137,
-  137,137,  2,137,137,137,137,137,  2,  2,  2,  2,  2,  2,124,124,
-  124,124,124,124,124,124,124,124,  2,  2,  2,  2,  2,  2,123,123,
-  123,123,123,123,123,123,123,123,123,123,123,123,  2,  2,114,114,
-  114,114,114,114,114,114,114,114,114,114,114,  2,  2,  2,114,114,
-    2,  2,  2,  2,  2,  2, 32, 32, 32, 32, 32,  2,  2,  2,102,102,
-  102,102,102,102,102,102,102,102,  2,  2,  2,  2,  2,  2,126,126,
-  126,126,126,126,126,126,126,126,126,  2,  2,126,126,126,126,126,
-  126,126,  2,  2,  2,  2,126,126,126,126,126,126,126,  2,142,142,
-  142,142,142,142,142,142,142,142,142,142,  2,  2,  2,  2,125,125,
-  125,125,125,125,125,125,125,125,125,  2,  2,  2,  2,  2,  2,  2,
-    2,  2,  2,  2,  2,125,154,154,154,154,154,154,154,  2,  2,154,
-    2,  2,154,154,154,154,154,154,154,154,  2,154,154,  2,154,154,
-  154,154,154,154,154,154,154,154,154,154,154,154,  2,154,154,  2,
-    2,154,154,154,154,154,154,154,  2,  2,  2,  2,  2,  2,150,150,
-  150,150,150,150,150,150,  2,  2,150,150,150,150,150,150,150,150,
-  150,150,150,  2,  2,  2,141,141,141,141,141,141,141,141,140,140,
-  140,140,140,140,140,140,140,140,140,  2,  2,  2,  2,  2,121,121,
-  121,121,121,121,121,121,121,  2,  2,  2,  2,  2,  2,  2,  7,  7,
-    2,  2,  2,  2,  2,  2,133,133,133,133,133,133,133,133,133,  2,
-  133,133,133,133,133,133,133,133,133,133,133,133,133,  2,133,133,
-  133,133,133,133,  2,  2,133,133,133,133,133,  2,  2,  2,134,134,
-  134,134,134,134,134,134,  2,  2,134,134,134,134,134,134,  2,134,
-  134,134,134,134,134,134,134,134,134,134,134,134,134,  2,138,138,
-  138,138,138,138,138,  2,138,138,  2,138,138,138,138,138,138,138,
-  138,138,138,138,138,138,  2,  2,138,  2,138,138,  2,138,138,138,
-    2,  2,  2,  2,  2,  2,143,143,143,143,143,143,  2,143,143,  2,
-  143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
-  143,143,143,143,143,  2,143,143,  2,143,143,143,143,143,143,  2,
-    2,  2,  2,  2,  2,  2,143,143,  2,  2,  2,  2,  2,  2,145,145,
-  145,145,145,145,145,145,145,  2,  2,  2,  2,  2,  2,  2,163,163,
-  163,163,163,163,163,163,163,  2,163,163,163,163,163,163,163,163,
-  163,  2,  2,  2,163,163,163,163,  2,  2,  2,  2,  2,  2, 86,  2,
-    2,  2,  2,  2,  2,  2, 22, 22,  2,  2,  2,  2,  2,  2,  2,  2,
-    2,  2,  2,  2,  2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
-    2,  2,  2,  2,  2,  2, 63, 63, 63, 63, 63, 63, 63,  2, 63, 63,
-   63, 63, 63,  2,  2,  2, 63, 63, 63, 63,  2,  2,  2,  2,157,157,
-  157,157,157,157,157,157,157,157,157,  2,  2,  2,  2,  2, 80, 80,
-   80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,  2,  2,127,127,
-  127,127,127,127,127,127,127,127,127,127,127,127,127,  2, 79,  2,
-    2,  2,  2,  2,  2,  2,115,115,115,115,115,115,115,115,115,115,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
+   70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+   70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+   70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96,
+  246,247,  0,  1,  2,  2,  0,  1,  2,  2,  2,  3,  4,  5,  0,  0,
+    0,  0,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  0,  0,  0,
+   19,  0, 19,  0,  0,  0,  0,  0, 26, 26,  1,  1,  1,  1,  9,  9,
+    9,  9,  0,  9,  9,  9,  2,  2,  9,  9,  9,  9,  0,  9,  2,  2,
+    2,  2,  9,  0,  9,  0,  9,  9,  9,  2,  9,  2,  9,  9,  9,  9,
+    2,  9,  9,  9, 55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  1,
+    1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14,  2,  2,  2,  2, 14, 14,  2,
+    2,  2,  3,  3,  3,  3,  3,  0,  3,  3,  0,  3,  3,  3,  3,  3,
+    3,  0,  3,  3,  3,  1,  1,  1,  3,  3,  1,  3,  3,  3, 37, 37,
+   37, 37, 37, 37,  2, 37, 37, 37, 37,  2,  2, 37, 37, 37, 38, 38,
+   38, 38, 38, 38,  2,  2, 64, 64, 64, 64, 64, 64, 64,  2,  2, 64,
+   64, 64, 90, 90, 90, 90, 90, 90,  2,  2, 90, 90, 90,  2, 95, 95,
+   95, 95,  2,  2, 95,  2,  3,  3,  3,  2,  3,  3,  2,  2,  3,  3,
+    0,  3,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  0,  0,
+    7,  7,  5,  5,  5,  5,  2,  5,  5,  5,  5,  2,  2,  5,  5,  2,
+    5,  5,  5,  2,  5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,
+    5,  2,  2,  2,  2,  5,  5,  5,  2,  5,  2, 11, 11, 11, 11, 11,
+   11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11, 11, 11, 11,  2,
+   11, 11,  2, 11, 11,  2, 11, 11,  2,  2,  2, 11,  2,  2, 11,  2,
+   11,  2,  2,  2, 11, 11,  2, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    2, 10, 10,  2, 10, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,
+   10, 10,  2, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,
+   21, 21, 21, 21,  2,  2, 21, 21,  2, 21,  2,  2, 21, 21,  2,  2,
+   22, 22,  2, 22, 22, 22, 22, 22, 22,  2, 22,  2, 22, 22, 22, 22,
+    2,  2,  2, 22, 22,  2,  2,  2,  2, 22, 22,  2,  2,  2, 22, 22,
+   22, 22, 23, 23, 23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2, 23,
+   23,  2, 23, 23, 23,  2,  2, 23,  2,  2,  2,  2, 23, 23,  2,  2,
+    2, 23, 16, 16, 16, 16, 16,  2, 16, 16,  2, 16, 16, 16, 16, 16,
+    2,  2,  2, 16, 16,  2,  2,  2, 16, 16, 20, 20, 20, 20, 20,  2,
+   20, 20,  2,  2, 20, 20,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36,  2,  2,  2, 36, 36, 36, 36,  2, 36,  2, 36,  2,  2,  2,  2,
+   36,  2,  2,  2,  2, 36, 36,  2, 36,  2, 36,  2,  2,  2,  2, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0,  2, 18,
+   18,  2, 18,  2, 18, 18, 18, 18, 18,  2, 18, 18, 18, 18,  2, 18,
+    2, 18, 18, 18,  2,  2, 18,  2, 18,  2, 25, 25, 25, 25,  2, 25,
+   25, 25, 25,  2,  2,  2, 25,  2, 25, 25, 25,  0,  0,  0,  0, 25,
+   25,  2, 33, 33, 33, 33,  8,  8,  8,  8,  8,  8,  2,  8,  2,  8,
+    2,  2,  8,  8,  8,  0, 12, 12, 12, 12, 30, 30, 30, 30, 30,  2,
+   30, 30, 30, 30,  2,  2, 30, 30, 30,  2,  2, 30, 30, 30, 30,  2,
+    2,  2, 29, 29, 29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 34, 34,
+   34, 34, 34,  2,  2,  2, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0,
+   35, 35, 35,  2,  2,  2, 45, 45, 45, 45, 45, 45,  2,  2,  2,  2,
+    2, 45, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43, 43, 43, 46, 46,
+   46, 46, 46,  2, 46, 46, 31, 31, 31, 31, 31, 31,  2,  2, 32, 32,
+    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32,  2,  2, 32,  2,
+    2,  2, 32, 32, 32,  2, 28, 28,  2,  2, 48, 48, 48, 48, 48, 48,
+   48,  2, 48,  2,  2,  2, 52, 52, 52, 52, 52, 52,  2,  2, 52,  2,
+    2,  2, 58, 58, 58, 58, 58, 58,  2,  2, 58, 58, 58,  2,  2,  2,
+   58, 58, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91,
+   91,  2, 91,  2,  2, 91, 91, 91,  2,  2,  1,  1,  1,  2, 62, 62,
+   62, 62, 62,  2,  2,  2, 62, 62, 62,  2, 76, 76, 76, 76, 93, 93,
+   93, 93, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70,  2,  2,  2, 70,
+   70, 70, 73, 73, 73, 73,  6,  2,  2,  2,  8,  8,  8,  2,  2,  8,
+    8,  8,  1,  1,  1,  0,  1,  0,  1,  1,  1,  0,  0,  0,  0,  1,
+    0,  0,  1,  1,  0,  2, 19, 19,  9,  9,  9,  9,  9,  6, 19,  9,
+    9,  9,  9,  9, 19, 19,  9,  9,  9, 19,  6, 19, 19, 19, 19, 19,
+   19,  9,  9,  9,  2,  2,  2,  9,  2,  9,  2,  9,  9,  9,  1,  1,
+    0,  0,  0,  2,  0,  0,  0, 19,  2,  2,  0,  0,  0, 19,  0,  0,
+    0,  2, 19,  2,  2,  2,  0,  2,  2,  2,  1,  2,  2,  2,  0,  0,
+    9,  0,  0,  0, 19, 19, 27, 27, 27, 27,  2,  2,  0,  0,  0,  0,
+    2,  0, 56, 56, 56, 56,  2, 55, 55, 55, 61, 61, 61, 61,  2,  2,
+    2, 61, 61,  2,  2,  2,  0,  0,  2,  2, 13, 13, 13, 13, 13, 13,
+    2, 13, 13, 13,  2,  2,  0, 13,  0, 13,  0, 13, 13, 13, 13, 13,
+    1,  1,  1,  1, 12, 12,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15,  2,  2,  1,  1,  0,  0, 15, 15, 15,  0, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17,  0,  2, 26, 26, 26, 26, 26, 26, 26,  2, 12,
+   12, 12, 12, 12, 12,  2, 12, 12, 12,  0, 39, 39, 39, 39, 39,  2,
+    2,  2, 39, 39, 39,  2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79,
+   79, 79, 19, 19, 19,  2, 19, 19,  2, 19,  2, 19, 19, 19, 19, 19,
+    2,  2,  2,  2, 19, 19, 60, 60, 60, 60, 60,  2,  2,  2, 65, 65,
+   65, 65, 75, 75, 75, 75, 75, 75,  2,  2,  2,  2, 75, 75, 69, 69,
+   69, 69, 69, 69,  0, 69, 74, 74, 74, 74,  2,  2,  2, 74, 12,  2,
+    2,  2, 84, 84, 84, 84, 84, 84,  2,  0, 84, 84,  2,  2,  2,  2,
+   84, 84, 33, 33, 33,  2, 68, 68, 68, 68, 68, 68, 68,  2, 68, 68,
+    2,  2, 92, 92, 92, 92, 92, 92, 92,  2,  2,  2,  2, 92, 87, 87,
+   87, 87, 87, 87, 87,  2, 19,  9, 19, 19, 19, 19,  0,  0, 87, 87,
+    2,  2,  2,  2,  2, 12,  2,  2,  2,  4, 14,  2, 14,  2, 14, 14,
+    2, 14, 14,  2, 14, 14,  2,  2,  2,  3,  3,  3,  0,  0,  2,  2,
+    3,  3,  1,  1,  6,  6,  3,  2,  3,  3,  3,  2,  2,  0,  2,  0,
+    0,  0,  0,  0, 17, 17, 17, 17,  0,  0,  2,  2, 12, 12, 49, 49,
+   49, 49,  2, 49, 49, 49, 49, 49, 49,  2, 49, 49,  2, 49, 49, 49,
+    2,  2,  9,  2,  2,  2,  0,  1,  2,  2, 71, 71, 71, 71, 71,  2,
+    2,  2, 67, 67, 67, 67, 67,  2,  2,  2, 42, 42, 42, 42,  2, 42,
+   42, 42, 41, 41, 41, 41, 41, 41, 41,  2,118,118,118,118,118,118,
+  118,  2, 53, 53, 53, 53, 53, 53,  2, 53, 59, 59, 59, 59, 59, 59,
+    2,  2, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50,
+    2,  2,135,135,135,135,106,106,106,106,104,104,104,104,  2,  2,
+    2,104,161,161,161,161,161,161,161,  2,161,161,  2,161,161,  2,
+    2,  2,110,110,110,110,110,110,110,  2,110,110,  2,  2, 19,  2,
+   19, 19, 47, 47, 47, 47, 47, 47,  2,  2, 47,  2, 47, 47, 47, 47,
+    2, 47, 47,  2,  2,  2, 47,  2,  2, 47, 81, 81, 81, 81, 81, 81,
+    2, 81,120,120,120,120,116,116,116,116,116,116,116,  2,  2,  2,
+    2,116,128,128,128,128,128,128,128,  2,128,128,  2,  2,  2,  2,
+    2,128, 66, 66, 66, 66,  2,  2,  2, 66, 72, 72, 72, 72, 72, 72,
+    2,  2,  2,  2,  2, 72, 98, 98, 98, 98, 97, 97, 97, 97,  2,  2,
+   97, 97, 57, 57, 57, 57,  2, 57, 57,  2,  2, 57, 57, 57, 57, 57,
+    2,  2, 57, 57, 57,  2,  2,  2,  2, 57, 57,  2,  2,  2, 88, 88,
+   88, 88,117,117,117,117,112,112,112,112,112,112,112,  2,  2,  2,
+    2,112, 78, 78, 78, 78, 78, 78,  2,  2,  2, 78, 78, 78, 83, 83,
+   83, 83, 83, 83,  2,  2, 82, 82, 82, 82, 82, 82, 82,  2,122,122,
+  122,122,122,122,  2,  2,  2,122,122,122,122,  2,  2,  2, 89, 89,
+   89, 89, 89,  2,  2,  2,130,130,130,130,130,130,130,  2,  2,  2,
+  130,130,144,144,144,144,144,144,  2,  2,156,156,156,156,156,156,
+    2,156,156,156,  2,  2,  2,  3,  3,  3,147,147,147,147,148,148,
+  148,148,148,148,  2,  2,158,158,158,158,158,158,  2,  2,153,153,
+  153,153,149,149,149,149,149,149,149,  2, 94, 94, 94, 94, 94, 94,
+    2,  2,  2,  2, 94, 94,  2,  2,  2, 94, 85, 85, 85, 85, 85, 85,
+   85,  2,  2, 85,  2,  2,101,101,101,101,101,  2,  2,  2,101,101,
+    2,  2, 96, 96, 96, 96, 96,  2, 96, 96,111,111,111,111,111,111,
+  111,  2,100,100,100,100,108,108,108,108,108,108,  2,108,108,108,
+    2,  2,129,129,129,129,129,129,129,  2,129,  2,129,129,129,129,
+    2,129,129,129,  2,  2,109,109,109,109,109,109,109,  2,109,109,
+    2,  2,107,107,107,107,  2,107,107,107,107,  2,  2,107,107,  2,
+  107,107,107,107,  2,  1,107,107,  2,  2,107,  2,  2,  2,  2,  2,
+    2,107,  2,  2,107,107,137,137,137,137,  2,137,137,137,137,137,
+    2,  2,124,124,124,124,124,124,  2,  2,123,123,123,123,123,123,
+    2,  2,114,114,114,114,114,  2,  2,  2,114,114,  2,  2,102,102,
+  102,102,102,102,  2,  2,126,126,126,126,126,126,126,  2,  2,126,
+  126,126,142,142,142,142,125,125,125,125,125,125,125,  2,  2,  2,
+    2,125,154,154,154,154,154,154,154,  2,  2,154,  2,  2,  2,154,
+  154,  2,154,154,  2,154,154,  2,  2,154,154,154,  2,  2,150,150,
+  150,150,  2,  2,150,150,150,  2,  2,  2,141,141,141,141,140,140,
+  140,140,140,140,140,  2,121,121,121,121,121,  2,  2,  2,  7,  7,
+    2,  2,133,133,133,133,133,  2,133,133,133,133,133,  2,133,133,
+    2,  2,133,  2,  2,  2,134,134,134,134,  2,  2,134,134,  2,134,
+  134,134,134,134,134,  2,138,138,138,138,138,138,138,  2,138,138,
+    2,138,  2,  2,138,  2,138,138,  2,  2,143,143,143,143,143,143,
+    2,143,143,  2,143,143,143,143,143,  2,143,  2,  2,  2,143,143,
+    2,  2,145,145,145,145,145,  2,  2,  2,163,163,163,163,163,  2,
+  163,163,163,163,163,  2,  2,  2,163,163,163,163,  2,  2, 86,  2,
+    2,  2, 63, 63, 63, 63, 63, 63,  2,  2, 63, 63, 63,  2, 63,  2,
+    2,  2,157,157,157,157,157,157,157,  2, 80, 80, 80, 80, 80, 80,
+    2,  2,127,127,127,127,127,127,127,  2, 79,  2,  2,  2,115,115,
   115,115,115,115,115,  2,115,115,  2,  2,  2,  2,115,115,159,159,
-  159,159,159,159,159,159,159,159,159,159,159,159,159,  2,159,159,
-    2,  2,  2,  2,  2,  2,103,103,103,103,103,103,103,103,103,103,
-  103,103,103,103,  2,  2,119,119,119,119,119,119,119,119,119,119,
-  119,119,119,119,  2,  2,119,119,  2,119,119,119,119,119,  2,  2,
-    2,  2,  2,119,119,119,146,146,146,146,146,146,146,146,146,146,
-  146,  2,  2,  2,  2,  2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
-   99,  2,  2,  2,  2, 99,  2,  2,  2,  2,  2,  2,  2, 99,136,139,
-   13, 13,155,  2,  2,  2,136,136,136,136,136,136,136,136,155,155,
-  155,155,155,155,155,155,155,155,155,155,155,155,  2,  2,136,  2,
-    2,  2,  2,  2,  2,  2, 17, 17, 17, 17,  2, 17, 17, 17, 17, 17,
-   17, 17,  2, 17, 17,  2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17,
-   17,  2,  2,  2,  2,  2,  2,  2, 15,  2,  2,  2,  2,  2, 15, 15,
-   15,  2,  2, 17,  2,  2,  2,  2,  2,  2, 17, 17, 17, 17,139,139,
-  139,139,139,139,139,139,139,139,139,139,  2,  2,  2,  2,105,105,
-  105,105,105,105,105,105,105,105,105,  2,  2,  2,  2,  2,105,105,
-  105,105,105,  2,  2,  2,105,  2,  2,  2,  2,  2,  2,  2,105,105,
-    2,  2,105,105,105,105,  1,  1,  1,  1,  1,  1,  2,  2,  0,  0,
-    0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,
-    1,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  2,  2,
-    0,  2,  2,  0,  0,  2,  2,  0,  0,  0,  0,  2,  0,  0,  0,  0,
-    2,  0,  2,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,
-    0,  2,  2,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  0,
-    0,  0,  0,  2,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  2,
-    0,  0,  0,  0,  0,  0,131,131,131,131,131,131,131,131,131,131,
-  131,131,  2,  2,  2,  2,  2,  2,  2,131,131,131,131,131,  2,131,
-  131,131,131,131,131,131,  2,  2,  2,  2,  2, 19, 19, 19, 56, 56,
-   56, 56, 56, 56, 56,  2, 56,  2,  2, 56, 56, 56, 56, 56, 56, 56,
-    2, 56, 56,  2, 56, 56, 56, 56, 56,  2,  2,  2,  2,  2,  6,  6,
-    6,  6,  6,  6,  2,  2,  2,  2,  2,  2,  2,  2,  2,  6,151,151,
-  151,151,151,151,151,151,151,151,151,151,151,  2,  2,  2,151,151,
-  151,151,151,151,  2,  2,151,151,  2,  2,  2,  2,151,151,160,160,
-  160,160,160,160,160,160,160,160,160,160,160,160,160,  2,152,152,
-  152,152,152,152,152,152,152,152,  2,  2,  2,  2,  2,152,164,164,
-  164,164,164,164,164,164,164,164,  2,  2,  2,  2,  2,  2, 30, 30,
-   30, 30,  2, 30, 30,  2,113,113,113,113,113,113,113,113,113,113,
-  113,113,113,  2,  2,113,113,113,113,113,113,113,113,  2,132,132,
-  132,132,132,132,132,132,132,132,132,132,  2,  2,  2,  2,132,132,
-    2,  2,  2,  2,132,132,  3,  3,  3,  3,  2,  3,  3,  3,  2,  3,
-    3,  2,  3,  2,  2,  3,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,
-    3,  2,  3,  3,  3,  3,  2,  3,  2,  3,  2,  2,  2,  2,  2,  2,
-    3,  2,  2,  2,  2,  3,  2,  3,  2,  3,  2,  3,  3,  3,  2,  3,
-    2,  3,  2,  3,  2,  3,  2,  3,  3,  3,  3,  2,  3,  2,  3,  3,
-    2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  3,
-    3,  3,  2,  3,  3,  3,  2,  2,  2,  2,  2,  2,  0,  0, 15,  0,
-    0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  2,  2,
-    2,  0,  0,  0,  0,  0, 13,  2,  2,  2,  2,  2,  2,  2, 13, 13,
-   13,  2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  0,  1,
-    2,  3,  4,  5,  6,  7,  8,  9,  9,  9,  9, 10,  9, 11, 12, 13,
-    9,  9,  9, 14,  9,  9, 15,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+  159,159,159,159,159,  2,159,159,  2,  2,103,103,103,103,103,103,
+    2,  2,119,119,119,119,119,119,  2,  2,119,119,  2,119,  2,119,
+  119,119,146,146,146,146,146,146,146,  2, 99, 99, 99, 99, 99, 99,
+   99,  2,  2,  2,  2, 99,136,139, 13, 13,155,  2,  2,  2,136,136,
+  136,136,155,155,155,155,155,155,  2,  2,136,  2,  2,  2,  2, 17,
+   17, 17,  2, 17, 17,  2, 17, 15, 15, 15, 17, 17, 17,  2,  2,  2,
+   15,  2,  2, 17,  2,  2,139,139,139,139,105,105,105,105,105,105,
+  105,  2,105,  2,  2,  2,105,105,  2,  2,  1,  1,  2,  2,  0,  0,
+    0,  1,  0,  1,  1,  1,  0,  0,  1,  1,  2,  2,  0,  2,  2,  0,
+    0,  2,  0,  2,  0,  2,131,131,131,131,  2,  2,  2,131,  2,131,
+  131,131, 56, 56, 56,  2, 56,  2,  2, 56, 56, 56,  2, 56, 56,  2,
+   56, 56,  6,  6,  2,  2,  2,  2,  2,  6,151,151,151,151,151,  2,
+    2,  2,151,151,  2,  2,  2,  2,151,151,160,160,160,160,160,160,
+  160,  2,152,152,152,152,152,152,  2,  2,  2,  2,  2,152,164,164,
+  164,164,164,164,  2,  2,  2, 30, 30,  2,113,113,113,113,113,  2,
+    2,113,113,113,113,  2,132,132,132,132,132,132,  2,  2,  2,  2,
+  132,132,  2,  3,  3,  2,  3,  2,  2,  3,  2,  3,  2,  3,  2,  2,
+    3,  2,  3,  2,  3,  2,  3,  3,  2,  3, 15,  0,  0,  2, 13,  2,
+    2,  2, 13, 13, 13,  2,  2,  0,  2,  2,  0,  1,  2,  3,  4,  5,
+    6,  7,  8,  9,  9,  9,  9, 10,  9, 11, 12, 13,  9,  9,  9, 14,
+    9,  9, 15,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 16, 17,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9, 18, 19, 20,  9, 21,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9, 16, 17,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9, 18, 19, 20,  9, 21,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9, 22,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9, 22,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
@@ -3922,60 +3702,60 @@
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 23, 24,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,
-    9, 10, 11, 12,  0,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+    9,  9,  9,  9,  9,  9, 23, 24,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
+    0,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0,  0, 24,
+   25, 26, 27, 28, 29, 30,  0,  0, 31, 32,  0, 33,  0, 34,  0, 35,
+    0,  0,  0,  0, 36, 37, 38, 39,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 40,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 41, 42,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-   23,  0,  0, 24, 25, 26, 27, 28, 29, 30,  0,  0, 31, 32,  0, 33,
-    0, 34,  0, 35,  0,  0,  0,  0, 36, 37, 38, 39,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 40,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 43, 44,  0, 45,  0,  0,
+    0,  0,  0,  0, 46, 47,  0,  0,  0,  0,  0, 48,  0, 49,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 50, 51,  0,  0,
+    0, 52,  0,  0, 53,  0,  0,  0,  0,  0,  0,  0, 54,  0,  0,  0,
+    0,  0,  0,  0, 55,  0,  0,  0,  0,  0,  0,  0, 56,  0,  0,  0,
+    0,  0,  0,  0,  0, 57,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 58, 59, 60, 61,
+   62, 63, 64, 65,  0,  0,  0,  0,  0,  0, 66,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 43, 44,
-    0, 45,  0,  0,  0,  0,  0,  0, 46, 47,  0,  0,  0,  0,  0, 48,
-    0, 49,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-   50, 51,  0,  0,  0, 52,  0,  0, 53,  0,  0,  0,  0,  0,  0,  0,
-   54,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,  0,  0,  0,  0,
-   56,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-   58, 59, 60, 61, 62, 63, 64, 65,  0,  0,  0,  0,  0,  0, 66,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 67, 68,  0, 69, 70,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 71, 72, 73, 74, 75, 76, 77, 78,
+   79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+   95, 96, 97, 98, 99,100,101,102,103,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,104,  0,  0,  0,  0,  0,
+    0,105,106,  0,107,  0,  0,  0,108,  0,109,  0,110,  0,111,112,
+  113,  0,114,  0,  0,  0,115,  0,  0,  0,116,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,117,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,118,119,120,121,
+    0,122,123,124,125,126,  0,127,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 67, 68,  0, 69,
-   70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 71, 72, 73, 74,
-   75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
-   91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,104,  0,
-    0,  0,  0,  0,  0,105,106,  0,107,  0,  0,  0,108,  0,109,  0,
-  110,  0,111,112,113,  0,114,  0,  0,  0,115,  0,  0,  0,116,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,128,129,130,131,132,133,134,135,
+  136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,
+  152,153,154,155,156,157,  0,  0,  0,158,159,160,161,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,117,  0,  0,  0,  0,  0,  0,
+    0,162,163,  0,  0,  0,  0,  0,  0,  0,164,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-  118,119,120,121,  0,122,123,124,125,126,  0,127,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,165,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,128,129,130,131,
-  132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,
-  148,149,150,151,152,153,154,155,156,157,  0,  0,  0,158,159,160,
-  161,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,162,163,  0,  0,  0,  0,  0,  0,  0,164,  0,
+    0,  0,  0,166,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,167,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,168,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,169,170,  0,
+    0,  0,  0,171,172,  0,  0,  0,173,174,175,176,177,178,179,180,
+  181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,
+  197,198,199,200,201,202,203,204,205,206,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-  165,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,166,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,167,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,168,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,169,170,  0,  0,  0,  0,171,172,  0,  0,  0,173,174,175,176,
-  177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,
-  193,194,195,196,197,198,199,200,201,202,203,204,205,206,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    0,  0,  0,  0,  1,  2,  3,  4,
 };
 static const uint16_t
-_hb_ucd_u16[9320] =
+_hb_ucd_u16[10040] =
 {
      0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
     13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
@@ -4104,255 +3884,300 @@
     48,  48,  48,  48,  71,  48,  48,  48,  48,  48,  48, 140, 140, 140, 140, 140,
    683, 140, 570, 570, 570, 570, 570, 570,  32,  32,  32,  32,  32,  32,  32,  32,
     32,  32,  32,  32,  32,  32,  32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
-   391, 391, 391, 391, 391, 391, 391, 685,   0,   0,   0,   0,   0,   0,   0,   0,
-     1,   2,   2,   3,   1,   2,   2,   3,   0,   0,   0,   0,   0,   4,   0,   4,
-     2,   2,   5,   2,   2,   2,   5,   2,   2,   2,   2,   2,   2,   2,   2,   2,
-     2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   6,
-     0,   0,   0,   0,   7,   8,   0,   0,   9,   9,   9,   9,   9,   9,   9,   9,
-     9,   9,   9,   9,   9,   9,  10,  11,  12,  13,  14,  14,  15,  14,  14,  14,
-    14,  14,  14,  14,  16,  17,  14,  14,  18,  18,  18,  18,  18,  18,  18,  18,
-    18,  18,  18,  18,  18,  18,  18,  18,  19,  18,  18,  18,  18,  18,  18,  18,
-    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  20,  21,
-    21,  21,  22,  20,  21,  21,  21,  21,  21,  23,  24,  25,  25,  25,  25,  25,
-    25,  26,  25,  25,  25,  27,  28,  26,  29,  30,  31,  32,  31,  31,  31,  31,
-    33,  34,  35,  31,  31,  31,  36,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  29,  31,  31,  31,  31,  37,  38,  37,  37,  37,  37,  37,  37,
-    37,  39,  31,  31,  31,  31,  31,  31,  40,  40,  40,  40,  40,  40,  41,  26,
-    42,  42,  42,  42,  42,  42,  42,  43,  44,  44,  44,  44,  44,  45,  44,  46,
-    47,  47,  47,  48,  37,  49,  31,  31,  31,  50,  51,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  52,  31,  31,  31,  53,  53,  53,  53,  53,  53,  53,  53,
-    53,  53,  54,  53,  55,  53,  53,  53,  56,  57,  58,  59,  59,  60,  61,  62,
-    57,  63,  64,  65,  66,  59,  59,  67,  68,  69,  70,  71,  71,  72,  73,  74,
-    69,  75,  76,  77,  78,  71,  79,  26,  80,  81,  82,  83,  83,  84,  85,  86,
-    81,  87,  88,  26,  89,  83,  90,  91,  92,  93,  94,  95,  95,  96,  97,  98,
-    93,  99, 100, 101, 102,  95,  95,  26, 103, 104, 105, 106, 107, 104, 108, 109,
-   104, 105, 110,  26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116,
-   114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126,
-   123, 127, 128, 128, 129, 122, 130,  26, 131, 132, 133, 131, 131, 131, 131, 131,
-   132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141,
-   138, 142, 143, 137, 144, 137, 145,  26, 146, 147, 147, 147, 147, 147, 147, 148,
-   147, 147, 147, 149,  26,  26,  26,  26, 150, 151, 152, 152, 153, 152, 152, 154,
-   155, 156, 152, 157,  26,  26,  26,  26, 158, 158, 158, 158, 158, 158, 158, 158,
-   158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161,
-   158, 161, 162, 163,  26,  26,  26,  26, 164, 164, 164, 164, 164, 164, 164, 164,
-   164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165,
-   166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169,
-   169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170,
-   170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172,
-   171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170,
-   170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176,
-   176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178,
-   178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181,
-   181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188,  26,
-   189, 189, 190,  26, 191, 192, 193,  26, 194, 194, 194, 194, 194, 194, 194, 194,
-   194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, 198, 198, 198, 198,
-   198, 198, 198, 198, 198, 198, 198, 200, 198, 198, 198, 198, 198, 201, 178, 178,
-   178, 178, 178, 178, 178, 178, 202,  26, 203, 203, 203, 204, 203, 205, 203, 205,
-   206, 203, 207, 207, 207, 208, 209,  26, 210, 210, 210, 210, 210, 211, 210, 210,
-   210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216,
-   216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220,   9,   9,
-     9, 221,  26,  26,  26,  26,  26,  26, 222, 222, 222, 222, 222, 222, 222, 222,
-   222, 223, 222, 222, 222, 222, 222, 224, 225, 225, 225, 225, 225, 225, 225, 225,
-   226, 226, 226, 226, 226, 226, 227, 228, 229, 229, 229, 229, 229, 229, 229, 230,
-   229, 231, 232, 232, 232, 232, 232, 232,  18, 233, 165, 165, 165, 165, 165, 234,
-   225,  26, 235,   9, 236, 237, 238, 239,   2,   2,   2,   2, 240, 241,   2,   2,
-     2,   2,   2, 242, 243, 244,   2, 245,   2,   2,   2,   2,   2,   2,   2, 246,
-     9,   9,   9,   9,   9,   9,   9,   9,  14,  14, 247, 247,  14,  14,  14,  14,
-   247, 247,  14, 248,  14,  14,  14, 247,  14,  14,  14,  14,  14,  14, 249,  14,
-   249,  14, 250, 251,  14,  14, 252, 253,   0, 254,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0, 255,   0, 256, 257,   0, 258,   2, 259,   0,   0,   0,   0,
-   260,  26,   9,   9,   9,   9, 261,  26,   0,   0,   0,   0, 262, 263,   4,   0,
-     0, 264,   0,   0,   2,   2,   2,   2,   2, 265,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 258,  26,  26,  26,
-     0, 266,  26,  26,   0,   0,   0,   0, 267, 267, 267, 267, 267, 267, 267, 267,
-   267, 267, 267, 267, 267, 267, 267, 267,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 268,   0,   0,   0, 269,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 270, 270, 270, 270, 270, 270, 270, 270,
-   270, 270, 270, 270,   2,   2,   2,   2,  17,  17,  17,  17,  17,  17,  17,  17,
-    17,  17,  17,  17,  17,  17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273,
-   273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172,  26, 172, 172, 172, 172,
-   172, 172, 172, 172,  18,  18,  18,  18,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 276,  26,  26,  26,  26, 277, 277, 277, 278, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 277, 279,  26, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 280,  26,  26,  26,   0, 281, 282,   0,   0,   0, 283, 284,   0, 285,
-   286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291,
-   291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169,
-   169, 169, 169, 169, 169, 169, 169, 169, 169, 296,   0,   0, 294, 294, 294, 294,
-     0,   0,   0,   0, 281,  26, 291, 291, 169, 169, 169, 296,   0,   0,   0,   0,
-     0,   0,   0,   0, 169, 169, 169, 297,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291,
-   291, 291, 291,   0,   0,   0,   0,   0, 277, 277, 277, 277, 277, 277, 277, 277,
-     0,   0,   0,   0,   0,   0,   0,   0, 299, 299, 299, 299, 299, 299, 299, 299,
-   299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299,
-   301,  26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303,
-   303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304,  26,  26,
-    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18, 305, 305, 305, 305,
-   305, 305, 305, 305, 305, 305, 305,  26,   0,   0,   0,   0, 306,   2,   2,   2,
-     2,   2,   2,   2,   2,   2,   2,   2,   2, 307,   2,   2,   2,   2,   2,   2,
-     2, 308, 309, 310,  26,  26, 311,   2, 312, 312, 312, 312, 312, 313,   0, 314,
-   315, 315, 315, 315, 315, 315, 315,  26, 316, 316, 316, 316, 316, 316, 316, 316,
-   317, 318, 316, 319,  53,  53,  53,  53, 320, 320, 320, 320, 320, 321, 322, 322,
-   322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326,
-   326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331,  26,
-   330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334,
-   335,  26,  26, 336, 337, 337, 338,  26, 339, 339, 339,  26, 172, 172,   2,   2,
-     2,   2,   2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
-   337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345,  26, 169, 169,
-   296, 346, 169, 169, 169, 169, 169, 345,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 347,  26,  26,  26,  26, 348,  26, 349, 350,  25,  25, 351, 352,
-   353,  25,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-   354,  26, 355,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 356,
-    31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 357,  31,  31,  31,  31,  31,
-    31, 358,  26,  26,  26,  26,  31,  31,   9,   9,   0, 314,   9, 359,   0,   0,
-     0,   0, 360,   0, 258, 281, 361,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  31,  31,  31, 362, 363,   0,   0,   0,   1,   2,   2,   3,
-     1,   2,   2,   3, 364, 291, 290, 291, 291, 291, 291, 365, 169, 169, 169, 296,
-   366, 366, 366, 367, 258, 258,  26, 368, 369, 370, 369, 369, 371, 369, 369, 372,
-   369, 373, 369, 373,  26,  26,  26,  26, 369, 369, 369, 369, 369, 369, 369, 369,
-   369, 369, 369, 369, 369, 369, 369, 374, 375,   0,   0,   0,   0,   0, 376,   0,
-    14,  14,  14,  14,  14,  14,  14,  14,  14, 253,   0, 377, 378,  26,  26,  26,
-    26,  26,   0,   0,   0,   0,   0, 379, 380, 380, 380, 381, 382, 382, 382, 382,
-   382, 382, 383,  26, 384,   0,   0, 281, 385, 385, 385, 385, 386, 387, 388, 388,
-   388, 389, 390, 390, 390, 390, 390, 391, 392, 392, 392, 393, 394, 394, 394, 394,
-   395, 394, 396,  26,  26,  26,  26,  26, 397, 397, 397, 397, 397, 397, 397, 397,
-   397, 397, 398, 398, 398, 398, 398, 398, 399, 399, 399, 400, 399, 401, 402, 402,
-   402, 402, 403, 402, 402, 402, 402, 403, 404, 404, 404, 404, 404,  26, 405, 405,
-   405, 405, 405, 405, 406, 407, 408, 409, 408, 409, 410, 408, 411, 408, 411, 412,
-    26,  26,  26,  26,  26,  26,  26,  26, 413, 413, 413, 413, 413, 413, 413, 413,
-   413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 414,  26,
-   413, 413, 415,  26, 413,  26,  26,  26, 416,   2,   2,   2,   2,   2, 417, 308,
-    26,  26,  26,  26,  26,  26,  26,  26, 418, 419, 420, 420, 420, 420, 421, 422,
-   423, 423, 424, 423, 425, 425, 425, 425, 426, 426, 426, 427, 428, 426,  26,  26,
-    26,  26,  26,  26, 429, 429, 430, 431, 432, 432, 432, 433, 434, 434, 434, 435,
-    26,  26,  26,  26,  26,  26,  26,  26, 436, 436, 436, 436, 437, 437, 437, 438,
-   437, 437, 439, 437, 437, 437, 437, 437, 440, 441, 442, 443, 444, 444, 445, 446,
-   444, 447, 444, 447, 448, 448, 448, 448, 449, 449, 449, 449,  26,  26,  26,  26,
-   450, 450, 450, 450, 451, 452, 451,  26, 453, 453, 453, 453, 453, 453, 454, 455,
-   456, 456, 457, 456, 458, 458, 459, 458, 460, 460, 461, 462,  26, 463,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 464, 464, 464, 464, 464, 464, 464, 464,
-   464, 465,  26,  26,  26,  26,  26,  26, 466, 466, 466, 466, 466, 466, 467,  26,
-   466, 466, 466, 466, 466, 466, 467, 468, 469, 469, 469, 469, 469,  26, 469, 470,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  31,  31,  31,  50, 471, 471, 471, 471, 471, 472, 473,  26,
-    26,  26,  26,  26,  26,  26,  26, 474, 475, 475, 475, 475, 475,  26, 476, 476,
-   476, 476, 476, 477,  26,  26, 478, 478, 478, 479,  26,  26,  26,  26, 480, 480,
-   480, 481,  26,  26, 482, 482, 483,  26, 484, 484, 484, 484, 484, 484, 484, 484,
-   484, 485, 486, 484, 484, 484, 485, 487, 488, 488, 488, 488, 488, 488, 488, 488,
-   489, 490, 491, 491, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 495, 494,
-   494,  26, 496, 496, 496, 496, 497,  26, 498, 498, 498, 498, 498, 498, 498, 498,
-   498, 498, 498, 498, 499, 137, 500,  26, 501, 501, 502, 501, 501, 501, 501, 501,
-   503,  26,  26,  26,  26,  26,  26,  26, 504, 505, 506, 507, 506, 508, 509, 509,
-   509, 509, 509, 509, 509, 510, 509, 511, 512, 513, 514, 515, 515, 516, 517, 518,
-   513, 519, 520, 521, 522, 523, 523,  26, 524, 524, 524, 524, 524, 524, 524, 524,
-   524, 524, 524, 525, 526,  26,  26,  26, 527, 527, 527, 527, 527, 527, 527, 527,
-   527,  26, 527, 528,  26,  26,  26,  26, 529, 529, 529, 529, 529, 529, 530, 529,
-   529, 529, 529, 530,  26,  26,  26,  26, 531, 531, 531, 531, 531, 531, 531, 531,
-   532,  26, 531, 533, 198, 534,  26,  26, 535, 535, 535, 535, 535, 535, 535, 536,
-   535, 536,  26,  26,  26,  26,  26,  26, 537, 537, 537, 538, 537, 539, 537, 537,
-   540,  26,  26,  26,  26,  26,  26,  26, 541, 541, 541, 541, 541, 541, 541, 542,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 543, 543, 543, 543,
-   543, 543, 543, 543, 543, 543, 544, 545, 546, 547, 548, 549, 549, 549, 550, 551,
-   546,  26, 549, 552,  26,  26,  26,  26,  26,  26,  26,  26, 553, 554, 553, 553,
-   553, 553, 553, 554, 555,  26,  26,  26, 556, 556, 556, 556, 556, 556, 556, 556,
-   556,  26, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558,  26, 178, 178,
-   559, 559, 559, 559, 559, 559, 559, 560,  53, 561,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 562, 563, 562, 562, 562, 562, 564, 562,
-   565,  26, 562, 562, 562, 566, 567, 567, 567, 567, 568, 567, 567, 569, 570,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 571, 572, 573, 573, 573, 573, 571, 574,
-   573,  26, 573, 575, 576, 577, 578, 578, 578, 579, 580, 581, 578, 582,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26, 583, 583, 583, 584, 585, 585, 586, 585, 585, 585, 585, 587,
-   585, 585, 585, 588,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 589,  26,
-   108, 108, 108, 108, 108, 108, 590, 591, 592, 592, 592, 592, 592, 592, 592, 592,
-   592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 593,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 592, 592, 592, 592, 592, 592, 592, 592,
-   592, 592, 592, 592, 592, 594, 595,  26, 592, 592, 592, 592, 592, 592, 592, 592,
-   596,  26,  26,  26,  26,  26,  26,  26,  26,  26, 597, 597, 597, 597, 597, 597,
-   597, 597, 597, 597, 597, 597, 598,  26, 599, 599, 599, 599, 599, 599, 599, 599,
-   599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599,
-   599, 599, 600,  26,  26,  26,  26,  26, 601, 601, 601, 601, 601, 601, 601, 601,
-   601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601,
-   602,  26,  26,  26,  26,  26,  26,  26, 305, 305, 305, 305, 305, 305, 305, 305,
-   305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 603,
-   604, 604, 604, 605, 604, 606, 607, 607, 607, 607, 607, 607, 607, 607, 607, 608,
-   607, 609, 610, 610, 610, 611, 611,  26, 612, 612, 612, 612, 612, 612, 612, 612,
-   613,  26, 612, 614, 614, 612, 612, 615, 612, 612,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-   616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 618, 618, 618, 618, 618, 618, 618, 618,
-   618, 619, 618, 618, 618, 618, 618, 618, 618, 620, 618, 618,  26,  26,  26,  26,
-    26,  26,  26,  26, 621,  26, 347,  26, 622, 622, 622, 622, 622, 622, 622, 622,
-   622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622,
-   622, 622, 622, 622, 622, 622, 622,  26, 623, 623, 623, 623, 623, 623, 623, 623,
-   623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
-   623, 623, 624,  26,  26,  26,  26,  26, 622, 625,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26, 626, 627, 628, 287, 287, 287, 287, 287, 287, 287,
-   287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287,
-   287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 629,  26, 630,  26,
-    26,  26, 631,  26, 632,  26, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
-   633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
-   633, 633, 633, 633, 633, 633, 633, 634, 635, 635, 635, 635, 635, 635, 635, 635,
-   635, 635, 635, 635, 635, 636, 635, 637, 635, 638, 635, 639, 281,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   9,   9,   9,   9,   9, 640,   9,   9,
-   221,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-   281,  26,  26,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 276,  26,   0,   0,   0,   0, 258, 363,   0,   0,
-     0,   0,   0,   0, 641, 642,   0, 643, 644, 645,   0,   0,   0, 646,   0,   0,
-     0,   0,   0,   0,   0, 266,  26,  26,  14,  14,  14,  14,  14,  14,  14,  14,
-   247,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-     0,   0, 281,  26,   0,   0, 281,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 258,  26,   0,   0,   0, 260,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 255,   0,   0,   0,   0,   0,   0,   0,   0, 255, 647, 648,   0, 649,
-   650,   0,   0,   0,   0,   0,   0,   0, 269, 651, 255, 255,   0,   0,   0, 652,
-   653, 654, 655,   0,   0,   0,   0,   0,   0,   0,   0,   0, 276,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0, 268,   0,   0,   0,   0,   0,   0, 656, 656, 656, 656, 656, 656, 656, 656,
-   656, 656, 656, 656, 656, 656, 656, 656, 656, 657,  26, 658, 659, 656,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   2,   2,   2, 348, 660, 308,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 661, 270, 270, 662, 663, 664,  18,  18,
-    18,  18,  18,  18,  18, 665,  26,  26,  26, 666,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 667, 667, 667, 667, 667, 668, 667, 669,
-   667, 670,  26,  26,  26,  26,  26,  26,  26,  26, 671, 671, 671, 672,  26,  26,
-   673, 673, 673, 673, 673, 673, 673, 674,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26, 675, 675, 675, 675, 675, 676,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26, 172, 677, 170, 172, 678, 678, 678, 678, 678, 678, 678, 678,
-   678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678,
-   679, 678, 680,  26,  26,  26,  26,  26, 681, 681, 681, 681, 681, 681, 681, 681,
-   681, 682, 681, 683,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26, 363,   0,   0,   0,   0,   0,   0,   0, 377,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 363,   0,   0,   0,   0,   0,   0, 276,
-    26,  26,  26,  26,  26,  26,  26,  26, 684,  31,  31,  31, 685, 686, 687, 688,
-   689, 690, 685, 691, 685, 687, 687, 692,  31, 693,  31, 694, 695, 693,  31, 694,
-    26,  26,  26,  26,  26,  26,  51,  26,   0,   0,   0,   0,   0, 281,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 281,  26,   0, 258, 363,   0,
-   363,   0, 363,   0,   0,   0, 276,  26,   0,   0,   0,   0,   0, 276,  26,  26,
-    26,  26,  26,  26, 696,   0,   0,   0, 697,  26,   0,   0,   0,   0,   0, 281,
-     0, 260, 314,  26, 276,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 698,   0, 377,   0, 377,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 258, 699,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 314,   0, 281, 260,  26,   0, 281,   0,   0,   0,   0,   0,   0,
-     0,  26,   0, 314,   0,   0,   0,   0,   0,  26,   0,   0,   0, 276, 314,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 281,  26,   0, 276,   0, 377,   0, 260,   0,   0,   0,   0,   0, 269,
-   276, 696,   0, 281,   0, 260,   0, 260,   0,   0, 360,   0,   0,   0,   0,   0,
-     0, 266,  26,  26,  26,  26,   0, 314, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 347,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347,  26, 277, 277,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277, 700,  26,  26,  26, 277, 277, 277, 280,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 701, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 702,  26,  26,  26,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   9,   9,   9,   9,   9,   9,   9,   9,
-     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,
-     9,   9,   9,   9,   9,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   391, 391, 391, 391, 391, 391, 391, 685,   0,   0,   0,   0,   1,   2,   1,   2,
+     0,   0,   3,   3,   4,   5,   4,   5,   4,   4,   4,   4,   4,   4,   4,   4,
+     4,   4,   4,   6,   0,   0,   7,   0,   8,   8,   8,   8,   8,   8,   8,   9,
+    10,  11,  12,  11,  11,  11,  13,  11,  14,  14,  14,  14,  14,  14,  14,  14,
+    15,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  16,  17,  18,  17,  17,
+    19,  20,  21,  21,  22,  21,  23,  24,  25,  26,  27,  27,  28,  29,  27,  30,
+    27,  27,  27,  27,  27,  31,  27,  27,  32,  33,  33,  33,  34,  27,  27,  27,
+    35,  35,  35,  36,  37,  37,  37,  38,  39,  39,  40,  41,  42,  43,  44,  27,
+    45,  46,  27,  27,  27,  27,  47,  27,  48,  48,  48,  48,  48,  49,  50,  48,
+    51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,
+    67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,
+    83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
+    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 109,
+   113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 122, 124, 125, 125,
+   126, 127, 128, 129, 130, 131, 125, 125, 132, 132, 132, 132, 133, 132, 134, 135,
+   132, 133, 132, 136, 136, 137, 125, 125, 138, 138, 138, 138, 138, 138, 138, 138,
+   138, 138, 139, 139, 140, 139, 139, 141, 142, 142, 142, 142, 142, 142, 142, 142,
+   143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143,
+   143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153,
+   154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159,
+   160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170,
+   171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176,
+   177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168,
+   188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194,   8, 195, 125, 125, 125,
+   196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201,
+   202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211,
+     4,   4, 212,   4,   4, 213, 214, 215,   4,   4,   4, 216,   8,   8,   8,   8,
+    11, 217,  11,  11, 217, 218,  11, 219,  11,  11,  11, 220, 220, 221,  11, 222,
+   223,   0,   0,   0,   0,   0, 224, 225, 226, 227,   0,   0, 228,   8,   8, 229,
+     0,   0, 230, 231, 232,   0,   4,   4, 233,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 234, 125, 235, 125,   0,   0,
+   236, 236, 236, 236, 236, 236, 236, 236,   0,   0,   0,   0,   0,   0,   0, 237,
+     0, 238,   0,   0,   0,   0,   0,   0, 239, 239, 239, 239, 239, 239,   4,   4,
+   240, 240, 240, 240, 240, 240, 240, 241, 139, 139, 140, 242, 242, 242, 243, 244,
+   143, 245, 246, 246, 246, 246,  14,  14,   0,   0,   0,   0,   0, 247, 125, 125,
+   248, 249, 248, 248, 248, 248, 248, 250, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 251, 125, 252, 253,   0, 254, 255, 256, 257, 257, 257,
+   257, 258, 259, 260, 260, 260, 260, 261, 262, 263, 263, 264, 142, 142, 142, 142,
+   265,   0, 263, 263,   0,   0, 266, 260, 142, 265,   0,   0,   0,   0, 142, 267,
+     0,   0,   0,   0,   0, 260, 260, 268, 260, 260, 260, 260, 260, 269,   0,   0,
+   248, 248, 248, 248,   0,   0,   0,   0, 270, 270, 270, 270, 270, 270, 270, 270,
+   271, 270, 270, 270, 272, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274,
+   274, 274, 275, 125,  14,  14,  14,  14,  14,  14, 276, 276, 276, 276, 276, 277,
+     0,   0, 278,   4,   4,   4,   4,   4, 279,   4,   4,   4, 280, 281, 125, 282,
+   283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290,  48,  48,
+   291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299,
+   300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308,
+   309, 310, 246,   4,   4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314,
+   142, 142, 315, 142, 316, 142, 142, 317, 125, 125, 125, 125, 125, 125, 125, 125,
+   248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125,
+   320, 321,  21, 322, 323,  27,  27,  27,  27,  27,  27,  27, 324, 325,  27,  27,
+    27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, 326,  27,  27,  27,  27,
+    27, 327,  27,  27, 328, 125, 125,  27,   8, 285, 329,   0,   0, 330, 331, 332,
+    27,  27,  27,  27,  27,  27,  27, 333, 334,   0,   1,   2,   1,   2, 335, 259,
+   260, 336, 142, 265, 337, 338, 339, 340, 341, 342, 343, 344, 345, 345, 125, 125,
+   342, 342, 342, 342, 342, 342, 342, 346, 347,   0,   0, 348,  11,  11,  11,  11,
+   349, 350, 351, 125, 125,   0,   0, 352, 353, 354, 355, 355, 355, 356, 357, 252,
+   358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125,
+   369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376,
+   377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125,
+   385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 387, 388, 125,
+   389,   4,   4, 390, 125, 125, 125, 125, 391, 392, 392, 393, 394, 395, 396, 396,
+   397, 398, 399, 125, 125, 125, 400, 401, 402, 403, 404, 405, 125, 125, 125, 125,
+   406, 406, 407, 408, 407, 409, 407, 407, 410, 411, 412, 413, 414, 414, 415, 415,
+   416, 416, 125, 125, 417, 417, 418, 419, 420, 420, 420, 421, 422, 423, 424, 425,
+   426, 427, 428, 125, 125, 125, 125, 125, 429, 429, 429, 429, 430, 125, 125, 125,
+   431, 431, 431, 432, 431, 431, 431, 433, 434, 434, 435, 436, 125, 125, 125, 125,
+   125, 125, 125, 125, 125, 125,  27,  45, 437, 437, 438, 439, 125, 125, 125, 440,
+   441, 441, 442, 443, 443, 444, 125, 445, 446, 125, 125, 447, 448, 125, 449, 450,
+   451, 451, 451, 451, 452, 453, 451, 454, 455, 455, 455, 455, 456, 457, 458, 459,
+   460, 460, 460, 461, 462, 463, 463, 464, 465, 465, 465, 465, 465, 465, 466, 467,
+   468, 469, 468, 468, 470, 125, 125, 125, 471, 472, 473, 474, 474, 474, 475, 476,
+   477, 478, 479, 480, 481, 482, 483, 484, 485, 485, 485, 485, 485, 486, 487, 125,
+   488, 488, 488, 488, 489, 490, 125, 125, 491, 491, 491, 492, 491, 493, 125, 125,
+   494, 494, 494, 494, 495, 496, 497, 125, 498, 498, 498, 499, 499, 125, 125, 125,
+   500, 501, 502, 500, 503, 125, 125, 125, 504, 504, 504, 505, 125, 125, 125, 125,
+   125, 125, 506, 506, 506, 506, 506, 507, 508, 509, 510, 511, 512, 513, 125, 125,
+   125, 125, 514, 515, 515, 514, 516, 125, 517, 517, 517, 517, 518, 519, 519, 519,
+   519, 519, 520, 154, 521, 521, 521, 522, 523, 125, 125, 125, 125, 125, 125, 125,
+   524, 525, 525, 526, 527, 525, 528, 529, 529, 530, 531, 532, 125, 125, 125, 125,
+   533, 534, 534, 535, 536, 537, 538, 539, 540, 541, 542, 125, 125, 125, 125, 125,
+   125, 125, 125, 125, 125, 125, 543, 544, 545, 546, 545, 547, 545, 548, 125, 125,
+   125, 125, 125, 549, 550, 550, 550, 551, 552, 552, 552, 552, 552, 552, 552, 552,
+   552, 553, 125, 125, 125, 125, 125, 125, 552, 552, 552, 552, 552, 552, 554, 555,
+   552, 552, 552, 552, 556, 125, 125, 125, 125, 557, 557, 557, 557, 557, 557, 558,
+   559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 560, 125, 125,
+   561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562, 125, 125, 125,
+   276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 563, 564, 565, 566, 567,
+   567, 567, 567, 568, 569, 570, 571, 572, 573, 573, 573, 573, 574, 575, 576, 577,
+   573, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 578, 578, 578, 578,
+   578, 579, 125, 125, 125, 125, 125, 125, 580, 580, 580, 580, 581, 580, 580, 580,
+   582, 580, 125, 125, 125, 125, 583, 584, 585, 585, 585, 585, 585, 585, 585, 585,
+   585, 585, 585, 585, 585, 585, 585, 586, 587, 587, 587, 587, 587, 587, 587, 587,
+   587, 587, 587, 587, 587, 588, 125, 125, 589, 125, 125, 125, 125, 125, 125, 125,
+   125, 125, 125, 125, 125, 125, 125, 590, 591, 257, 257, 257, 257, 257, 257, 257,
+   257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 592, 593, 125, 594, 595, 596,
+   596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597,
+   598, 598, 598, 598, 598, 598, 599, 600, 601, 602, 266, 125, 125, 125, 125, 125,
+     8,   8, 603,   8, 604,   0,   0,   0,   0,   0,   0,   0, 266, 125, 125, 125,
+     0,   0,   0,   0,   0,   0,   0, 605,   0,   0, 606,   0,   0,   0, 607, 608,
+   609,   0, 610,   0,   0,   0, 235, 125,  11,  11,  11,  11, 611, 125, 125, 125,
+   125, 125, 125, 125,   0, 266,   0, 266,   0,   0,   0,   0,   0, 234,   0, 612,
+     0,   0,   0,   0,   0, 224,   0,   0,   0, 613, 614, 615, 616,   0,   0,   0,
+   617, 618,   0, 619, 620, 621,   0,   0,   0,   0, 622,   0,   0,   0,   0,   0,
+     0,   0,   0,   0, 623,   0,   0,   0, 624, 624, 624, 624, 624, 624, 624, 624,
+   625, 626, 627, 125, 125, 125, 125, 125,   4, 628, 629, 125, 125, 125, 125, 125,
+   630, 631, 632,  14,  14,  14, 633, 125, 634, 125, 125, 125, 125, 125, 125, 125,
+   635, 635, 636, 637, 638, 125, 125, 125, 125, 639, 640, 125, 641, 641, 641, 642,
+   125, 125, 125, 125, 125, 643, 643, 644, 125, 125, 125, 125, 125, 125, 645, 646,
+   647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 648, 649, 125, 125,
+   650, 650, 650, 650, 651, 652, 125, 125, 125, 125, 125, 125, 125, 125, 125, 334,
+     0,   0,   0, 653, 125, 125, 125, 125, 334,   0,   0, 247, 125, 125, 125, 125,
+   654,  27, 655, 656, 657, 658, 659, 660, 661, 662, 663, 662, 125, 125, 125, 664,
+     0,   0, 252,   0,   0,   0,   0,   0,   0, 266, 226, 334, 334, 334,   0, 605,
+     0,   0, 247, 125, 125, 125, 665,   0, 666,   0,   0, 252, 612, 667, 605, 125,
+     0,   0,   0,   0,   0, 668, 350, 350,   0,   0,   0,   0,   0,   0,   0, 669,
+     0,   0,   0,   0,   0, 285, 252, 228, 252,   0,   0,   0, 670, 285,   0,   0,
+   670,   0, 247, 667, 125, 125, 125, 125,   0,   0,   0,   0,   0, 266, 247, 350,
+   612,   0,   0, 671, 672, 252, 612, 612,   0, 330,   0,   0, 235, 125, 125, 285,
+   248, 248, 248, 248, 248, 248, 125, 125, 248, 248, 248, 319, 248, 248, 248, 248,
+   248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 584, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 673, 125, 248, 318, 125, 125, 125, 125, 125, 125,
+   248, 248, 248, 248, 674, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125,
+   675, 125,   0,   0,   0,   0,   0,   0,   8,   8,   8,   8,   8,   8,   8,   8,
+     8,   8,   8,   8,   8,   8,   8,   0,   0,   0,   0,   0,   1,   2,   2,   2,
+     2,   2,   3,   0,   0,   0,   4,   0,   2,   2,   2,   2,   2,   3,   2,   2,
+     2,   2,   5,   0,   2,   5,   6,   0,   7,   7,   7,   7,   8,   9,  10,  11,
+    12,  13,  14,  15,   8,   8,   8,   8,  16,   8,   8,   8,  17,  18,  18,  18,
+    19,  19,  19,  19,  19,  20,  19,  19,  21,  22,  22,  22,  22,  22,  22,  22,
+    22,  23,  21,  22,  22,  22,  23,  21,  24,  25,  25,  25,  25,  25,  25,  25,
+    25,  25,  12,  12,  25,  25,  26,  27,  25,  28,  12,  12,  29,  30,  29,  31,
+    29,  29,  32,  32,  29,  29,  29,  29,  31,  29,  33,   7,   7,  34,  29,  29,
+    35,  29,  29,  29,  29,  29,  29,  30,  36,  36,  36,  37,  36,  36,  36,  36,
+    36,  36,  38,  39,  40,  40,  40,  40,  41,  12,  12,  12,  42,  42,  42,  42,
+    42,  42,  43,  44,  45,  45,  45,  45,  45,  45,  45,  46,  45,  45,  45,  47,
+    48,  48,  48,  48,  48,  48,  48,  49,  36,  36,  38,  12,  29,  29,  29,  50,
+    51,  12,  29,  29,  52,  29,  29,  29,  53,  53,  53,  53,  54,  55,  53,  53,
+    53,  56,  53,  53,  57,  58,  57,  59,  59,  57,  57,  57,  57,  57,  60,  57,
+    61,  62,  63,  57,  57,  59,  59,  64,  12,  65,  12,  66,  57,  62,  57,  57,
+    57,  57,  57,  64,  67,  67,  68,  69,  70,  71,  71,  71,  71,  71,  72,  71,
+    72,  73,  74,  72,  68,  69,  70,  74,  75,  12,  67,  76,  12,  77,  71,  71,
+    71,  68,  12,  12,  78,  78,  79,  80,  80,  79,  79,  79,  79,  79,  81,  79,
+    81,  78,  82,  79,  79,  80,  80,  82,  83,  12,  12,  12,  79,  84,  79,  79,
+    82,  12,  78,  79,  85,  85,  86,  87,  87,  86,  86,  86,  86,  86,  88,  86,
+    88,  85,  89,  86,  86,  87,  87,  89,  12,  85,  12,  90,  86,  91,  86,  86,
+    86,  86,  12,  12,  92,  93,  94,  92,  95,  96,  97,  95,  98,  99,  94,  92,
+   100, 100,  96,  92,  94,  92,  95,  96,  99,  98,  12,  12,  12,  92, 100, 100,
+   100, 100,  94,  12, 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101,
+   101, 101, 103, 101, 101, 102, 102, 103,  12, 104, 105, 106, 101, 107, 101, 101,
+    12, 108, 101, 101, 109, 109, 109, 110, 110, 109, 109, 109, 109, 109, 110, 109,
+   109, 111, 112, 109, 109, 110, 110, 112,  12, 113,  12, 113, 109, 114, 109, 109,
+   111,  12,  12,  12, 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115,
+   115, 116, 116, 115,  12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119,
+   119, 120, 121, 119, 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125,
+   119, 126, 119, 119,  12, 121, 119, 119, 121, 127,  12,  12, 128, 129, 129, 129,
+   129, 129, 129, 129, 129, 129, 130, 131, 129, 129, 129,  12,  12,  12,  12,  12,
+   132, 133, 134, 135, 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137,
+   135, 138, 135, 134, 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139,
+   139, 139, 139, 141, 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144,  12,
+   145, 145, 145, 145, 146, 146, 146, 146, 146, 147,  12, 148, 146, 146, 149, 146,
+   150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153,
+   152, 153, 151, 154, 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155,
+   151, 151, 151, 156, 151, 151, 153,  12, 157, 157, 157, 157, 157, 158, 157, 158,
+   159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162,
+   162, 162, 163, 164, 162, 162, 165,  12, 166, 166, 166, 166, 166, 167,  12, 168,
+   169, 169, 169, 169, 169, 170,  12,  12, 171, 171, 171, 171, 171,  12,  12,  12,
+   172, 172, 172, 173, 173,  12,  12,  12, 174, 174, 174, 174, 174, 174, 174, 175,
+   174, 174, 175,  12, 176, 177, 178, 178, 178, 178, 179,  12, 178, 178, 178, 178,
+   178, 178, 180,  12, 178, 178, 181,  12, 159, 182,  12,  12, 183, 183, 183, 183,
+   183, 183, 183, 184, 183, 183, 183,  12, 185, 183, 183, 183, 186, 186, 186, 186,
+   186, 186, 186, 187, 186, 188,  12,  12, 189, 189, 189, 189, 189, 189, 189,  12,
+   189, 189, 190,  12, 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194,
+   195, 195, 195, 195, 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198,  12,
+   195, 195, 195, 198,   7,   7,   7, 199, 200, 200, 200, 200, 200, 200, 200, 201,
+   200, 200, 200, 202, 203, 203, 203, 203, 204, 204, 204, 204, 204,  12,  12, 204,
+   205, 205, 205, 205, 205, 205, 206, 205, 205, 205, 207, 208, 209, 209, 209, 209,
+    19,  19, 210,  12, 146, 146, 211, 212, 203, 203,  12,  12, 213,   7,   7,   7,
+   214,   7, 215, 216,   0, 215, 217,  12,   2, 218, 219,   2,   2,   2,   2, 220,
+   221, 218, 222,   2,   2,   2, 223,   2,   2,   2,   2, 224,   8, 225,   8, 225,
+     8,   8, 226, 226,   8,   8,   8, 225,   8,  15,   8,   8,   8,  10,   8, 227,
+    10,  15,   8,  14,   0,   0,   0, 228,   0, 229,   0,   0, 230,   0,   0, 231,
+     0,   0,   0, 232,   2,   2,   2, 233, 234,  12,  12,  12, 235,  12,  12,  12,
+     0, 236, 237,   0,   4,   0,   0,   0,   0,   0,   0,   4,   2,   2,   5,  12,
+     0, 232,  12,  12,   0,   0, 232,  12, 238, 238, 238, 238,   0, 239,   0,   0,
+     0, 240,   0,   0, 241, 241, 241, 241,  18,  18,  18,  18,  18,  12, 242,  18,
+   243, 243, 243, 243, 243, 243,  12, 244, 245,  12,  12, 244, 151, 154,  12,  12,
+   151, 154, 151, 154,   0,   0,   0, 246, 247, 247, 247, 247, 247, 247, 248, 247,
+   247,  12,  12,  12, 247, 249,  12,  12,   0,   0,   0,  12,   0, 250,   0,   0,
+   251, 247, 252, 253,   0,   0, 247,   0, 254, 255, 255, 255, 255, 255, 255, 255,
+   255, 256, 257, 258, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259,
+    12, 262, 263, 263, 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265,
+     0,  12,  12,  12, 150, 150, 150, 266, 260, 260, 260, 261, 260, 260,   0,   0,
+   267, 267, 267, 267, 267, 267, 267, 268, 267, 269,  12,  12, 270, 270, 270, 270,
+   271, 271, 271, 271, 271, 271, 271,  12, 272, 272, 272, 272, 272, 272,  12,  12,
+   237,   2,   2,   2,   2,   2, 231,   2,   2,   2, 273,  12, 274, 275, 276,  12,
+   277,   2,   2,   2, 278, 278, 278, 278, 278, 278, 278, 279,   0,   0, 246,  12,
+   280, 280, 280, 280, 280, 280,  12,  12, 281, 281, 281, 281, 281, 282,  12, 283,
+   281, 281, 282,  12, 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286,
+   286,  12,  12, 287, 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290,
+   289, 289, 291, 292, 145, 145, 145, 293, 294, 294, 294, 294, 294, 295,  12,  12,
+   294, 294, 294, 296, 294, 294, 296, 294, 297, 297, 297, 297, 298,  12,  12,  12,
+    12,  12, 299, 297, 300, 300, 300, 300, 300, 301,  12,  12, 155, 154, 155, 154,
+   155, 154,  12,  12,   2,   2,   3,   2,   2, 302, 303,  12, 300, 300, 300, 304,
+   300, 300, 304,  12, 150,  12,  12,  12, 150, 265, 305, 150, 150, 150, 150,  12,
+   247, 247, 247, 249, 247, 247, 249,  12,   2, 273,  12,  12, 306,  22,  12,  24,
+    25,  26,  25, 307, 308, 309,  25,  25,  50,  12,  12,  12, 310,  29,  29,  29,
+    29,  29,  29, 311, 312,  29,  29,  29,  29,  29,  12, 310,   7,   7,   7, 313,
+   232,   0,   0,   0,   0, 232,   0,  12,  29, 314,  29,  29,  29,  29,  29, 315,
+   316,   0,   0,   0,   0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150,
+   319, 150, 319, 288,   0, 232,   0, 232,  12,  12, 316, 246, 320, 320, 320, 321,
+   320, 320, 320, 320, 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324,
+   320, 320, 322,  12, 232, 131,   0,   0,   0, 131,   0,   0,   8,   8,   8,  14,
+     0,   0,   0, 234, 325,  12,  12,  12,   0,   0,   0, 326, 327, 327, 327, 327,
+   327, 327, 327, 328, 329, 329, 329, 329, 330,  12,  12,  12, 215,   0,   0,   0,
+   331, 331, 331, 331, 331,  12,  12, 332, 333, 333, 333, 333, 333, 333, 334,  12,
+   335, 335, 335, 335, 335, 335, 336,  12, 337, 337, 337, 337, 337, 337, 337, 338,
+   339, 339, 339, 339, 339,  12, 339, 339, 339, 340,  12,  12, 341, 341, 341, 341,
+   342, 342, 342, 342, 343, 343, 343, 343, 343, 343, 343, 344, 343, 343, 344,  12,
+   345, 345, 345, 345, 345,  12, 345, 345, 345, 345, 345,  12, 346, 346, 346, 346,
+   346, 346,  12,  12, 347, 347, 347, 347, 347,  12,  12, 348, 349, 349, 350, 349,
+   350, 351, 349, 349, 351, 349, 349, 349, 351, 349, 351, 352, 353, 353, 353, 353,
+   353, 354,  12,  12, 353, 355,  12,  12, 353, 353,  12,  12,   2, 274,   2,   2,
+   356,   2, 273,  12, 357, 358, 359, 357, 357, 357, 357, 357, 357, 360, 361, 362,
+   363, 363, 363, 363, 363, 364, 363, 363, 365, 365, 365, 365, 366, 366, 366, 366,
+   366, 366, 366, 367,  12, 368, 366, 366, 369, 369, 369, 369, 370, 371, 372, 369,
+   373, 373, 373, 373, 373, 373, 373, 374, 375, 375, 375, 375, 375, 375, 376, 377,
+   378, 378, 378, 378, 379, 379, 379, 379, 379, 379,  12, 379, 380, 379, 379, 379,
+   381, 382,  12, 381, 381, 383, 383, 381, 381, 381, 381, 381, 381, 384, 385, 386,
+   381, 381, 387,  12, 388, 388, 388, 388, 389, 389, 389, 389, 390, 390, 390, 390,
+   390, 391, 392, 390, 390, 391,  12,  12, 393, 393, 393, 393, 393, 394, 395, 393,
+   396, 396, 396, 396, 396, 397, 396, 396, 398, 398, 398, 398, 399,  12, 398, 398,
+   400, 400, 400, 400, 401,  12, 402, 403,  12,  12, 402, 400, 404, 404, 404, 404,
+   404, 404, 405,  12, 406, 406, 406, 406, 407,  12,  12,  12, 407,  12, 408, 406,
+   409, 409, 409, 409, 409, 409,  12,  12, 409, 409, 410,  12, 411, 411, 411, 411,
+   411, 411, 412, 413, 413,  12,  12,  12,  12,  12,  12, 414, 415, 415, 415, 415,
+   415, 415,  12,  12, 416, 416, 416, 416, 416, 416, 417,  12, 418, 418, 418, 418,
+   418, 418, 419,  12, 420, 420, 420, 420, 420, 420, 420,  12, 421, 421, 421, 421,
+   421, 422,  12,  12, 423, 423, 423, 423, 423, 423, 423, 424, 425, 423, 423, 423,
+   423, 424,  12, 426, 427, 427, 427, 427, 428,  12,  12, 429, 430, 430, 430, 430,
+   430, 430, 431,  12, 430, 430, 432,  12, 433, 433, 433, 433, 433, 434, 433, 433,
+   433, 433,  12,  12, 435, 435, 435, 435, 435, 436,  12,  12, 437, 437, 437, 437,
+   118, 119, 119, 119, 119, 127,  12,  12, 438, 438, 438, 438, 439, 438, 438, 438,
+   440,  12,  12,  12, 441, 442, 443, 444, 441, 441, 441, 444, 441, 441, 445,  12,
+   446, 446, 446, 446, 446, 446, 447,  12, 446, 446, 448,  12, 449, 450, 449, 451,
+   451, 449, 449, 449, 449, 449, 452, 449, 452, 450, 453, 449, 449, 451, 451, 454,
+   455, 456,  12, 450, 449, 457, 449, 455, 449, 455,  12,  12, 458, 458, 458, 458,
+   458, 458, 458, 459, 460,  12,  12,  12, 461, 461, 461, 461, 461, 461,  12,  12,
+   461, 461, 462,  12, 463, 463, 463, 463, 463, 464, 463, 463, 463, 463, 463, 464,
+   465, 465, 465, 465, 465, 466,  12,  12, 465, 465, 467,  12, 178, 178, 178, 180,
+   468, 468, 468, 468, 468, 468, 469,  12, 470, 470, 470, 470, 470, 470, 471, 472,
+   470, 470, 470,  12, 470, 471,  12,  12, 473, 473, 473, 473, 473, 473, 473,  12,
+   474, 474, 474, 474, 475,  12,  12, 476, 477, 478, 479, 477, 477, 480, 477, 477,
+   477, 477, 477, 477, 477, 481, 482, 477, 477, 478,  12,  12, 477, 477, 483,  12,
+   484, 484, 485, 484, 484, 484, 484, 484, 484, 486,  12,  12, 487, 487, 487, 487,
+   487, 487,  12,  12, 488, 488, 488, 488, 489,  12,  12,  12, 490, 490, 490, 490,
+   490, 490, 491,  12,  53,  53, 492,  12, 493, 493, 494, 493, 493, 493, 493, 493,
+   493, 495, 493, 493, 493, 496,  12,  12, 493, 493, 493, 497, 498, 498, 498, 498,
+   499, 498, 498, 498, 498, 498, 500, 498, 498, 501,  12,  12, 502, 503, 504, 502,
+   502, 502, 502, 502, 502, 503, 505, 504, 502, 502,  12,  12, 502, 502, 506,  12,
+   507, 508, 509, 507, 507, 507, 507, 507, 507, 507, 507, 510, 508, 507, 511,  12,
+   507, 507, 512,  12, 513, 513, 513, 513, 513, 513, 514,  12, 515, 515, 515, 515,
+   516, 515, 515, 515, 515, 515, 517, 518, 515, 515, 519,  12, 520,  12,  12,  12,
+   100, 100, 100, 100,  96,  12,  12,  98, 521, 521, 521, 521, 521, 521, 522,  12,
+   521, 521, 521, 523, 521, 524,  12,  12, 521,  12,  12,  12, 525, 525, 525, 525,
+   526,  12,  12,  12, 527, 527, 527, 527, 527, 528,  12,  12, 529, 529, 529, 529,
+   529, 530,  12,  12, 272, 272, 531,  12, 532, 532, 532, 532, 532, 532, 532, 533,
+   532, 532, 534, 535, 536, 536, 536, 536, 536, 536, 536, 537, 536, 536, 538,  12,
+   539, 539, 539, 539, 539, 539, 539, 540, 539, 540,  12,  12, 541, 541, 541, 541,
+   541, 542,  12,  12, 541, 541, 543, 541, 543, 541, 541, 541, 541, 541,  12, 544,
+   545, 545, 545, 545, 545, 545, 546,  12, 547, 547, 547, 547, 547, 547, 548, 549,
+   547, 547,  12, 549, 550, 551,  12,  12, 249,  12,  12,  12, 552, 552, 552, 552,
+   552, 552,  12,  12, 553, 553, 553, 553, 553, 554,  12,  12, 552, 552, 555,  12,
+   260, 556, 260, 557, 558, 255, 255, 255, 559,  12,  12,  12, 560,  12,  12,  12,
+   256, 561,  12,  12,  12, 260,  12,  12, 562, 562, 562, 562, 562, 562, 562,  12,
+   563, 563, 563, 563, 563, 563, 564,  12, 563, 563, 563, 565, 563, 563, 565,  12,
+   563, 563, 566, 563,   7,   7,   7, 567,   7, 199,  12,  12,   0, 246,  12,  12,
+     0, 232, 316,   0,   0, 568, 228,   0,   0,   0, 568,   7, 213, 569,   7,   0,
+     0,   0, 570, 228,   8, 225,  12,  12,   0,   0, 234,  12,   0,   0,   0, 229,
+   571, 572, 316, 229,   0,   0, 240, 316,   0, 316,   0,   0,   0, 240, 232, 316,
+     0, 229,   0, 229,   0,   0, 240, 232,   0, 573, 239,   0, 229,   0,   0,   0,
+     0, 246,   0,   0,   0,   0,   0, 239, 574, 574, 574, 574, 574, 574, 574,  12,
+    12,  12, 575, 574, 576, 574, 574, 574,   2,   2,   2, 273,  12, 275, 273,  12,
+   241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577,  12,  19,  19,  19, 581,
+    12,  12,  12, 582, 583, 583, 583, 583, 583, 583, 583, 584, 583, 583, 583, 585,
+   583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, 589, 589, 589, 589,
+   589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593,  12, 151, 154, 151, 594,
+   151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, 595, 597,  12,  12,
+   598, 598, 598, 598, 598, 598, 598,  12, 598, 598, 599, 600,   0, 234,  12,  12,
+    29, 414,  29,  29, 601, 602, 414,  29,  50,  29, 603,  12, 604, 310, 603, 414,
+   601, 602, 603, 603, 601, 602,  50,  29,  50,  29, 414, 605,  29,  29, 606,  29,
+    29,  29,  29,  12, 414, 414, 606,  29,  51,  12,  12,  12,  12, 239,   0,   0,
+   607,  12,  12,  12, 246,  12,  12,  12,   0,   0,  12,   0,   0, 232, 131,   0,
+     0,   0,  12,  12,   0,   0,   0, 240,   0, 246,  12, 239, 608,  12,  12,  12,
+   247, 247, 609,  12, 610,  12,  12,  12,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0, 939, 940, 941, 942, 946, 948,   0, 962,
    969, 970, 971, 976,1001,1002,1003,1008,   0,1033,1040,1041,1042,1043,1047,   0,
      0,1080,1081,1082,1086,1110,   0,   0,1124,1125,1126,1127,1131,1133,   0,1147,
@@ -4562,21 +4387,14 @@
    817, 818, 819, 820, 821, 935,   0,   0,
 };
 static const int16_t
-_hb_ucd_i16[196] =
+_hb_ucd_i16[92] =
 {
-      0,    0,    0,    0,    1,   -1,    0,    0,    2,    0,   -2,    0,    0,    0,    0,    2,
-      0,   -2,    0,    0,    0,    0,    0,   16,    0,    0,    0,  -16,    0,    0,    1,   -1,
-      0,    0,    0,    1,   -1,    0,    0,    0,    0,    1,   -1,    0,    3,    3,    3,   -3,
-     -3,   -3,    0,    0,    0, 2016,    0,    0,    0,    0,    0, 2527, 1923, 1914, 1918,    0,
-   2250,    0,    0,    0,    0,    0,    0,  138,    0,    7,    0,    0,   -7,    0,    0,    0,
-      1,   -1,    1,   -1,   -1,    1,   -1,    0, 1824,    0,    0,    0,    0,    0, 2104,    0,
-   2108, 2106,    0, 2106, 1316,    0,    0,    0,    0,    1,   -1,    1,   -1, -138,    0,    0,
-      1,   -1,    8,    8,    8,    0,    7,    7,    0,    0,   -8,   -8,   -8,   -7,   -7,    0,
-      1,   -1,    0,    2,-1316,    1,   -1,    0,   -1,    1,   -1,    1,   -1,    3,    1,   -1,
-     -3,    1,   -1,    1,   -1,    0,    0,-1914,-1918,    0,    0,-1923,-1824,    0,    0,    0,
-      0,-2016,    0,    0,    1,   -1,    0,    1,    0,    0,-2104,    0,    0,    0,    0,-2106,
-  -2108,-2106,    0,    0,    1,   -1,-2250,    0,    0,    0,-2527,    0,    0,   -2,    0,    1,
-     -1,    0,    1,   -1,
+      0,    0,    1,   -1,    2,    0,   -2,    0,    0,    2,    0,   -2,    0,   16,    0,  -16,
+      0,    1,   -1,    0,    3,    3,    3,   -3,   -3,   -3,    0, 2016,    0, 2527, 1923, 1914,
+   1918,    0, 2250,    0,    0,  138,    0,    7,   -7,    0,   -1,    1, 1824,    0, 2104,    0,
+   2108, 2106,    0, 2106, 1316,    0,   -1, -138,    8,    8,    8,    0,    7,    7,   -8,   -8,
+     -8,   -7,-1316,    1,   -1,    3,   -3,    1,    0,-1914,-1918,    0,    0,-1923,-1824,    0,
+      0,-2016,-2104,    0,    0,-2106,-2108,-2106,-2250,    0,-2527,    0,
 };
 
 static inline uint_fast8_t
@@ -4597,17 +4415,17 @@
 static inline int_fast16_t
 _hb_ucd_bmg (unsigned u)
 {
-  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9540+(((_hb_ucd_u8[9420+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9684+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[9356+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
 }
 static inline uint_fast8_t
 _hb_ucd_sc (unsigned u)
 {
-  return u<918000u?_hb_ucd_u8[11062+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10326+(((_hb_ucd_u8[9876+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
+  return u<918000u?_hb_ucd_u8[11118+(((_hb_ucd_u16[4024+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10382+(((_hb_ucd_u8[9932+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
 }
 static inline uint_fast16_t
 _hb_ucd_dm (unsigned u)
 {
-  return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17068+(((_hb_ucd_u8[16686+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+  return u<195102u?_hb_ucd_u16[6728+(((_hb_ucd_u8[13944+(((_hb_ucd_u8[13562+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -129,6 +129,7 @@
 		hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
 		void *user_data HB_UNUSED)
 {
+  // Hangul is handled algorithmically.
   if (_hb_ucd_compose_hangul (a, b, ab)) return true;
 
   hb_codepoint_t u = 0;
@@ -135,6 +136,9 @@
 
   if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u)
   {
+    /* If "a" is small enough and "b" is in the U+0300 range,
+     * the composition data is encoded in a 32bit array sorted
+     * by "a,b" pair. */
     uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0);
     const uint32_t *v = hb_bsearch (k,
 				    _hb_ucd_dm2_u32_map,
@@ -146,6 +150,8 @@
   }
   else
   {
+    /* Otherwise it is stored in a 64bit array sorted by
+     * "a,b" pair. */
     uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0);
     const uint64_t *v = hb_bsearch (k,
 				    _hb_ucd_dm2_u64_map,
@@ -170,15 +176,22 @@
 
   unsigned i = _hb_ucd_dm (ab);
 
+  /* If no data, there's no decomposition. */
   if (likely (!i)) return false;
   i--;
 
+  /* Check if it's a single-character decomposition. */
   if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map))
   {
+    /* Single-character decompositions currently are only in plane 0 or plane 2. */
     if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map))
+    {
+      /* Plane 0. */
       *a = _hb_ucd_dm1_p0_map[i];
+    }
     else
     {
+      /* Plane 2. */
       i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map);
       *a = 0x20000 | _hb_ucd_dm1_p2_map[i];
     }
@@ -187,8 +200,10 @@
   }
   i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map);
 
+  /* Otherwise they are encoded either in a 32bit array or a 64bit array. */
   if (i < ARRAY_LENGTH (_hb_ucd_dm2_u32_map))
   {
+    /* 32bit array. */
     uint32_t v = _hb_ucd_dm2_u32_map[i];
     *a = HB_CODEPOINT_DECODE3_11_7_14_1 (v);
     *b = HB_CODEPOINT_DECODE3_11_7_14_2 (v);
@@ -196,6 +211,7 @@
   }
   i -= ARRAY_LENGTH (_hb_ucd_dm2_u32_map);
 
+  /* 64bit array. */
   uint64_t v = _hb_ucd_dm2_u64_map[i];
   *a = HB_CODEPOINT_DECODE3_1 (v);
   *b = HB_CODEPOINT_DECODE3_2 (v);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -377,20 +377,30 @@
 				    hb_destroy_func_t		    destroy)	\
 {										\
   if (hb_object_is_immutable (ufuncs))						\
-    return;									\
+    goto fail;									\
 										\
+  if (!func)									\
+  {										\
+    if (destroy)								\
+      destroy (user_data);							\
+    destroy = nullptr;								\
+    user_data = ufuncs->parent->user_data.name;					\
+  }										\
+										\
   if (ufuncs->destroy.name)							\
     ufuncs->destroy.name (ufuncs->user_data.name);				\
 										\
-  if (func) {									\
+  if (func)									\
     ufuncs->func.name = func;							\
-    ufuncs->user_data.name = user_data;						\
-    ufuncs->destroy.name = destroy;						\
-  } else {									\
+  else										\
     ufuncs->func.name = ufuncs->parent->func.name;				\
-    ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
-    ufuncs->destroy.name = nullptr;						\
-  }										\
+  ufuncs->user_data.name = user_data;						\
+  ufuncs->destroy.name = destroy;						\
+  return;									\
+										\
+fail:										\
+  if (destroy)									\
+    destroy (user_data);							\
 }
 
 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -355,7 +355,7 @@
     return nullptr;
   }
 
-  memcpy(new_sfnt_data, orig_sfnt_data, length);
+  hb_memcpy(new_sfnt_data, orig_sfnt_data, length);
 
   OT::name &name = StructAtOffset<OT::name> (new_sfnt_data, name_table_offset);
   name.format = 0;
@@ -478,11 +478,11 @@
 		   hb_font_t *font,
 		   unsigned int font_size)
 {
-  memset (lf, 0, sizeof (*lf));
+  hb_memset (lf, 0, sizeof (*lf));
   lf->lfHeight = - (int) font_size;
   lf->lfCharSet = DEFAULT_CHARSET;
 
-  memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName));
+  hb_memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName));
 
   return true;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -35,7 +35,7 @@
 
 template <typename Type,
 	  bool sorted=false>
-struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty_t>::type
+struct hb_vector_t
 {
   typedef Type item_t;
   static constexpr unsigned item_size = hb_static_size (Type);
@@ -53,9 +53,10 @@
 	    hb_requires (hb_is_iterable (Iterable))>
   hb_vector_t (const Iterable &o) : hb_vector_t ()
   {
-    if (hb_iter (o).is_random_access_iterator)
-      alloc (hb_len (hb_iter (o)));
-    hb_copy (o, *this);
+    auto iter = hb_iter (o);
+    if (iter.is_random_access_iterator)
+      alloc (hb_len (iter));
+    hb_copy (iter, *this);
   }
   hb_vector_t (const hb_vector_t &o) : hb_vector_t ()
   {
@@ -83,6 +84,9 @@
     allocated = length = 0;
     arrayZ = nullptr;
   }
+  void init0 ()
+  {
+  }
 
   void fini ()
   {
@@ -94,7 +98,11 @@
   void reset ()
   {
     if (unlikely (in_error ()))
-      allocated = length; // Big hack!
+      /* Big Hack! We don't know the true allocated size before
+       * an allocation failure happened. But we know it was at
+       * least as big as length. Restore it to that and continue
+       * as if error did not happen. */
+      allocated = length;
     resize (0);
   }
 
@@ -122,7 +130,7 @@
   }
 
   hb_bytes_t as_bytes () const
-  { return hb_bytes_t ((const char *) arrayZ, length * item_size); }
+  { return hb_bytes_t ((const char *) arrayZ, get_size ()); }
 
   bool operator == (const hb_vector_t &o) const { return as_array () == o.as_array (); }
   bool operator != (const hb_vector_t &o) const { return !(*this == o); }
@@ -164,15 +172,11 @@
   operator   iter_t () const { return   iter (); }
   operator writer_t ()       { return writer (); }
 
-  c_array_t sub_array (unsigned int start_offset, unsigned int count) const
-  { return as_array ().sub_array (start_offset, count); }
-  c_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
-  { return as_array ().sub_array (start_offset, count); }
-  array_t sub_array (unsigned int start_offset, unsigned int count)
-  { return as_array ().sub_array (start_offset, count); }
-  array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
-  { return as_array ().sub_array (start_offset, count); }
+  /* Faster range-based for loop. */
+  Type *begin () const { return arrayZ; }
+  Type *end () const { return arrayZ + length; }
 
+
   hb_sorted_array_t<Type> as_sorted_array ()
   { return hb_sorted_array (arrayZ, length); }
   hb_sorted_array_t<const Type> as_sorted_array () const
@@ -240,12 +244,11 @@
     if (likely (new_array))
     {
       for (unsigned i = 0; i < length; i++)
+      {
 	new (std::addressof (new_array[i])) Type ();
-      for (unsigned i = 0; i < (unsigned) length; i++)
 	new_array[i] = std::move (arrayZ[i]);
-      unsigned old_length = length;
-      shrink_vector (0);
-      length = old_length;
+	arrayZ[i].~Type ();
+      }
       hb_free (arrayZ);
     }
     return new_array;
@@ -277,7 +280,14 @@
   copy_vector (const hb_vector_t &other)
   {
     length = other.length;
-    hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
+#ifndef HB_OPTIMIZE_SIZE
+    if (sizeof (T) >= sizeof (long long))
+      /* This runs faster because of alignment. */
+      for (unsigned i = 0; i < length; i++)
+	arrayZ[i] = other.arrayZ[i];
+    else
+#endif
+       hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
   }
   template <typename T = Type,
 	    hb_enable_if (!hb_is_trivially_copyable (T) &&
@@ -309,18 +319,9 @@
     }
   }
 
-  template <typename T = Type,
-	    hb_enable_if (hb_is_trivially_destructible(T))>
   void
   shrink_vector (unsigned size)
   {
-    length = size;
-  }
-  template <typename T = Type,
-	    hb_enable_if (!hb_is_trivially_destructible(T))>
-  void
-  shrink_vector (unsigned size)
-  {
     while ((unsigned) length > size)
     {
       arrayZ[(unsigned) length - 1].~Type ();
@@ -328,20 +329,9 @@
     }
   }
 
-  template <typename T = Type,
-	    hb_enable_if (hb_is_trivially_copy_assignable(T))>
   void
   shift_down_vector (unsigned i)
   {
-    memmove (static_cast<void *> (&arrayZ[i - 1]),
-	     static_cast<void *> (&arrayZ[i]),
-	     (length - i) * sizeof (Type));
-  }
-  template <typename T = Type,
-	    hb_enable_if (!hb_is_trivially_copy_assignable(T))>
-  void
-  shift_down_vector (unsigned i)
-  {
     for (; i < length; i++)
       arrayZ[i - 1] = std::move (arrayZ[i]);
   }
@@ -381,7 +371,7 @@
     return true;
   }
 
-  bool resize (int size_)
+  bool resize (int size_, bool initialize = true)
   {
     unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
     if (!alloc (size))
@@ -388,9 +378,15 @@
       return false;
 
     if (size > length)
-      grow_vector (size);
+    {
+      if (initialize)
+	grow_vector (size);
+    }
     else if (size < length)
-      shrink_vector (size);
+    {
+      if (initialize)
+	shrink_vector (size);
+    }
 
     length = size;
     return true;
@@ -399,13 +395,13 @@
   Type pop ()
   {
     if (!length) return Null (Type);
-    Type v = arrayZ[length - 1];
+    Type v {std::move (arrayZ[length - 1])};
     arrayZ[length - 1].~Type ();
     length--;
     return v;
   }
 
-  void remove (unsigned int i)
+  void remove_ordered (unsigned int i)
   {
     if (unlikely (i >= length))
       return;
@@ -414,6 +410,18 @@
     length--;
   }
 
+  template <bool Sorted = sorted,
+	    hb_enable_if (!Sorted)>
+  void remove_unordered (unsigned int i)
+  {
+    if (unlikely (i >= length))
+      return;
+    if (i != length - 1)
+      arrayZ[i] = std::move (arrayZ[length - 1]);
+    arrayZ[length - 1].~Type ();
+    length--;
+  }
+
   void shrink (int size_)
   {
     unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
@@ -425,10 +433,8 @@
 
 
   /* Sorting API. */
-  void qsort (int (*cmp)(const void*, const void*))
+  void qsort (int (*cmp)(const void*, const void*) = Type::cmp)
   { as_array ().qsort (cmp); }
-  void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1)
-  { as_array ().qsort (start, end); }
 
   /* Unsorted search API. */
   template <typename T>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2022-12-18 01:06:39 UTC (rev 65304)
@@ -126,6 +126,7 @@
 /* Ignored intentionally. */
 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
 #pragma GCC diagnostic ignored "-Wclass-memaccess"
+#pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
 #pragma GCC diagnostic ignored "-Wformat-zero-length"
 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -58,7 +58,8 @@
     const char *data = hb_blob_get_data (blob, &length);
 
     char output_path[255];
-    sprintf (output_path, "out/svg-%u-%u.svg%s",
+    snprintf (output_path, sizeof output_path,
+	     "out/svg-%u-%u.svg%s",
 	     glyph_id,
 	     face_index,
 	     // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
@@ -112,7 +113,7 @@
 	const char *data = hb_blob_get_data (blob, &length);
 
 	char output_path[255];
-	sprintf (output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index);
+	snprintf (output_path, sizeof output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index);
 
 	FILE *f = fopen (output_path, "wb");
 	fwrite (data, 1, length, f);
@@ -224,7 +225,7 @@
 	}
 
 	char output_path[255];
-	sprintf (output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index);
+	snprintf (output_path, sizeof output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index);
 	FILE *f = fopen (output_path, "wb");
 	fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
 		    " viewBox=\"%d %d %d %d\">\n",
@@ -274,7 +275,7 @@
     }
 
     char output_path[255];
-    sprintf (output_path, "out/%u-%u.svg", face_index, gid);
+    snprintf (output_path, sizeof output_path, "out/%u-%u.svg", face_index, gid);
     FILE *f = fopen (output_path, "wb");
     fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
 		" viewBox=\"%d %d %d %d\"><path d=\"",

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2022-12-18 01:06:39 UTC (rev 65304)
@@ -56,6 +56,7 @@
   'hb-map.hh',
   'hb-meta.hh',
   'hb-ms-feature-ranges.hh',
+  'hb-multimap.hh',
   'hb-mutex.hh',
   'hb-null.hh',
   'hb-number.cc',
@@ -414,10 +415,13 @@
 
 libharfbuzz_link_language = 'c'
 
+hb_features = configuration_data()
+
 if conf.get('HAVE_FREETYPE', 0) == 1
   hb_sources += hb_ft_sources
   hb_headers += hb_ft_headers
   harfbuzz_deps += [freetype_dep]
+  hb_features.set('HB_HAS_FREETYPE', 1)
 endif
 
 if conf.get('HAVE_GDI', 0) == 1
@@ -424,6 +428,7 @@
   hb_sources += hb_gdi_sources
   hb_headers += hb_gdi_headers
   harfbuzz_deps += gdi_uniscribe_deps
+  hb_features.set('HB_HAS_GDI', 1)
 endif
 
 if conf.get('HAVE_GRAPHITE2', 0) == 1
@@ -430,6 +435,7 @@
   hb_sources += hb_graphite2_sources
   hb_headers += hb_graphite2_headers
   harfbuzz_deps += [graphite2_dep, graphite_dep]
+  hb_features.set('HB_HAS_GRAPHITE', 1)
 endif
 
 if conf.get('HAVE_GLIB', 0) == 1
@@ -436,11 +442,13 @@
   hb_sources += hb_glib_sources
   hb_headers += hb_glib_headers
   harfbuzz_deps += [glib_dep]
+  hb_features.set('HB_HAS_GLIB', 1)
 endif
 
 if conf.get('HAVE_UNISCRIBE', 0) == 1
   hb_sources += hb_uniscribe_sources
   hb_headers += hb_uniscribe_headers
+  hb_features.set('HB_HAS_UNISCRIBE', 1)
 endif
 
 if conf.get('HAVE_DIRECTWRITE', 0) == 1
@@ -448,6 +456,7 @@
   hb_headers += hb_directwrite_headers
   # hb-directwrite needs a C++ linker
   libharfbuzz_link_language = 'cpp'
+  hb_features.set('HB_HAS_DIRECTWRITE', 1)
 endif
 
 if conf.get('HAVE_CORETEXT', 0) == 1
@@ -454,6 +463,7 @@
   hb_sources += hb_coretext_sources
   hb_headers += hb_coretext_headers
   harfbuzz_deps += coretext_deps
+  hb_features.set('HB_HAS_CORETEXT', 1)
 endif
 
 have_icu = conf.get('HAVE_ICU', 0) == 1
@@ -463,8 +473,17 @@
   hb_sources += hb_icu_sources
   hb_headers += hb_icu_headers
   harfbuzz_deps += [icu_dep]
+  hb_features.set('HB_HAS_ICU', 1)
 endif
 
+hb_features_h = configure_file(input: 'hb-features.h.in',
+                               output: 'hb-features.h',
+                               configuration: hb_features,
+                               install: true,
+                               install_dir: get_option('includedir') / meson.project_name())
+
+# Base and default-included sources and headers
+
 # harfbuzz
 gen_def = find_program('gen-def.py')
 
@@ -580,6 +599,7 @@
     'test-iter': ['test-iter.cc', 'hb-static.cc'],
     'test-machinery': ['test-machinery.cc', 'hb-static.cc'],
     'test-map': ['test-map.cc', 'hb-static.cc'],
+    'test-multimap': ['test-multimap.cc', 'hb-static.cc'],
     'test-number': ['test-number.cc', 'hb-number.cc'],
     'test-ot-tag': ['hb-ot-tag.cc'],
     'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'],
@@ -657,8 +677,8 @@
 have_gobject = conf.get('HAVE_GOBJECT', 0) == 1
 
 cmake_config = configuration_data()
-cmake_config.set('libdir', '${prefix}/@0@'.format(get_option('libdir')))
-cmake_config.set('includedir', '${prefix}/@0@'.format(get_option('includedir')))
+cmake_config.set('libdir', get_option('prefix') / get_option('libdir'))
+cmake_config.set('includedir', get_option('prefix') / get_option('includedir'))
 cmake_config.set('HB_LIBTOOL_VERSION_INFO', hb_libtool_version_info)
 cmake_config.set('have_gobject', '@0@'.format(have_gobject))
 configure_file(input: 'harfbuzz-config.cmake.in',

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-array.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-array.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-array.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -70,6 +70,9 @@
 int
 main (int argc, char **argv)
 {
+  /* The following fails on MSVC. */
+  // assert (sizeof (hb_array_t<int>) == sizeof (hb_sorted_array_t<int>));
+
   test_reverse ();
   test_reverse_range ();
   test_reverse_invalid ();

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -43,10 +43,8 @@
 
 #ifndef HB_NO_BUFFER_SERIALIZE
 
-  if (argc != 2) {
-    fprintf (stderr, "usage: %s font-file\n", argv[0]);
-    exit (1);
-  }
+  if (argc < 2)
+    argv[1] = (char *) "/dev/null";
 
   hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]);
   assert (blob);
@@ -58,7 +56,7 @@
   hb_font_t *font = hb_font_create (face);
   hb_face_destroy (face);
   hb_font_set_scale (font, upem, upem);
-  hb_ot_font_set_funcs (font);
+  //hb_ot_font_set_funcs (font);
 #ifdef HAVE_FREETYPE
   //hb_ft_font_set_funcs (font);
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -319,13 +319,36 @@
   ;
   /* The result should be something like 0->10, 1->11, ..., 9->19 */
   assert (hb_map_get (result, 9) == 19);
+  hb_map_destroy (result);
 
+  /* Like above, but passing hb_set_t instead of hb_set_t * */
+  temp1 = 10;
+  temp2 = 0;
+  result =
+  + hb_iter (src)
+  | hb_map ([&] (int i) -> hb_set_t
+	    {
+	      hb_set_t set;
+	      for (unsigned int i = 0; i < temp1; ++i)
+		hb_set_add (&set, i);
+	      temp1++;
+	      return set;
+	    })
+  | hb_reduce ([&] (hb_map_t *acc, hb_set_t value) -> hb_map_t *
+	       {
+		 hb_map_set (acc, temp2++, hb_set_get_population (&value));
+		 return acc;
+	       }, hb_map_create ())
+  ;
+  /* The result should be something like 0->10, 1->11, ..., 9->19 */
+  assert (hb_map_get (result, 9) == 19);
+  hb_map_destroy (result);
+
   unsigned int temp3 = 0;
   + hb_iter(src)
   | hb_map([&] (int i) { return ++temp3; })
   | hb_reduce([&] (float acc, int value) { return acc + value; }, 0)
   ;
-  hb_map_destroy (result);
 
   + hb_iter (src)
   | hb_drain

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -179,20 +179,43 @@
 
     hb_hashmap_t<vector_t, vector_t> m1;
 
-    m1.set (vector_t (), vector_t ());
     m1.set (vector_t (), vector_t {1});
     m1.set (vector_t {1}, vector_t {2});
 
+    m1 << hb_pair_t<vector_t, vector_t> {vector_t {2}, vector_t ()};
+
     assert (m1.get (vector_t ()) == vector_t {1});
     assert (m1.get (vector_t {1}) == vector_t {2});
   }
 
+  /* Test moving values */
+  {
+    using vector_t = hb_vector_t<unsigned>;
+
+    hb_hashmap_t<vector_t, vector_t> m1;
+    vector_t v {3};
+    assert (v.length == 1);
+    m1 << hb_pair_t<vector_t, vector_t> {vector_t {3}, v};
+    assert (v.length == 1);
+    m1 << hb_pair_t<vector_t, vector_t&&> {vector_t {4}, std::move (v)};
+    assert (v.length == 0);
+    m1 << hb_pair_t<vector_t&&, vector_t> {vector_t {4}, vector_t {5}};
+    m1 << hb_pair_t<vector_t&&, vector_t&&> {vector_t {4}, vector_t {5}};
+
+    hb_hashmap_t<vector_t, vector_t> m2;
+    vector_t v2 {3};
+    m2.set (vector_t {4}, v2);
+    assert (v2.length == 1);
+    m2.set (vector_t {5}, std::move (v2));
+    assert (v2.length == 0);
+  }
+
   /* Test hb::shared_ptr. */
-  hb_hash (hb::shared_ptr<hb_set_t> ());
   {
     hb_hashmap_t<hb::shared_ptr<hb_set_t>, hb::shared_ptr<hb_set_t>> m;
 
-    m.get (hb::shared_ptr<hb_set_t> ());
+    m.set (hb::shared_ptr<hb_set_t> (hb_set_get_empty ()),
+	   hb::shared_ptr<hb_set_t> (hb_set_get_empty ()));
     m.get (hb::shared_ptr<hb_set_t> (hb_set_get_empty ()));
     m.iter ();
     m.keys ();
@@ -202,12 +225,14 @@
     m.values_ref ();
   }
   /* Test hb::unique_ptr. */
-  hb_hash (hb::unique_ptr<hb_set_t> ());
   {
     hb_hashmap_t<hb::unique_ptr<hb_set_t>, hb::unique_ptr<hb_set_t>> m;
 
-    m.get (hb::unique_ptr<hb_set_t> ());
+    m.set (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()),
+           hb::unique_ptr<hb_set_t> (hb_set_get_empty ()));
     m.get (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()));
+    hb::unique_ptr<hb_set_t> *v;
+    m.has (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()), &v);
     m.iter_ref ();
     m.keys_ref ();
     m.values_ref ();
@@ -234,11 +259,48 @@
     hb::shared_ptr<hb_map_t> p1 {m1};
     hb::shared_ptr<hb_map_t> p2 {m2};
     m.set (p1,1);
-    
+
     assert (m.has (p2));
 
     m1->set (2,4);
     assert (!m.has (p2));
   }
+  /* Test value type with hb_bytes_t. */
+  {
+    hb_hashmap_t<int, hb_bytes_t> m;
+    char c_str[] = "Test";
+    hb_bytes_t bytes (c_str);
+
+    m.set (1, bytes);
+    assert (m.has (1));
+  }
+  /* Test operators. */
+  {
+    hb_map_t m1, m2, m3;
+    m1.set (1, 2);
+    m1.set (2, 4);
+    m2.set (1, 2);
+    m2.set (2, 4);
+    m3.set (1, 3);
+    m3.set (3, 5);
+
+    assert (m1 == m2);
+    assert (m1 != m3);
+    assert (!(m2 == m3));
+
+    m2 = m3;
+    assert (m2.has (1));
+    assert (!m2.has (2));
+    assert (m2.has (3));
+
+    assert (m3.has (3));
+  }
+  /* Test reset. */
+  {
+    hb_hashmap_t<int, hb_set_t> m;
+    m.set (1, hb_set_t {1, 2, 3});
+    m.reset ();
+  }
+
   return 0;
 }

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-multimap.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-multimap.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-multimap.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2022  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb.hh"
+#include "hb-multimap.hh"
+
+int
+main (int argc, char **argv)
+{
+  hb_multimap_t m;
+
+  assert (m.get (10).length == 0);
+
+  m.add (10, 11);
+  assert (m.get (10).length == 1);
+
+  m.add (10, 12);
+  assert (m.get (10).length == 2);
+
+  m.add (10, 13);
+  assert (m.get (10).length == 3);
+  assert (m.get (10)[0] == 11);
+  assert (m.get (10)[1] == 12);
+  assert (m.get (10)[2] == 13);
+
+  assert (m.get (11).length == 0);
+  m.add (11, 14);
+  assert (m.get (10).length == 3);
+  assert (m.get (11).length == 1);
+  assert (m.get (12).length == 0);
+  assert (m.get (10)[0] == 11);
+  assert (m.get (10)[1] == 12);
+  assert (m.get (10)[2] == 13);
+  assert (m.get (11)[0] == 14);
+  assert (m.get (12)[0] == 0); // Array fallback value
+
+  return 0;
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -35,7 +35,7 @@
                     hb_serialize_context_t* c)
 {
   char* obj = c->allocate_size<char> (len);
-  memcpy (obj, value, len);
+  hb_memcpy (obj, value, len);
 }
 
 static void start_object(const char* tag,
@@ -1476,6 +1476,7 @@
 
   graph_t graph (c.object_graph ());
   graph.sort_shortest_distance ();
+  assert (!graph.in_error ());
 
   assert(strncmp (graph.object (4).head, "abc", 3) == 0);
   assert(graph.object (4).real_links.length == 3);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -34,6 +34,7 @@
     hb_set_t v1 {1, 2};
     hb_set_t v2 {v1};
     assert (v1.get_population () == 2);
+    assert (hb_len (hb_iter (v1)) == 2);
     assert (v2.get_population () == 2);
   }
 
@@ -51,6 +52,7 @@
     hb_set_t s {1, 2};
     hb_set_t v (std::move (s));
     assert (s.get_population () == 0);
+    assert (hb_len (hb_iter (s)) == 0);
     assert (v.get_population () == 2);
   }
 
@@ -86,11 +88,14 @@
     hb_set_t s;
 
     s.add (18);
-    s.add (12);
+    s << 12;
 
+    /* Sink a range. */
+    s << hb_pair_t<hb_codepoint_t, hb_codepoint_t> {1, 3};
+
     hb_set_t v (hb_iter (s));
 
-    assert (v.get_population () == 2);
+    assert (v.get_population () == 5);
   }
 
   /* Test initializing from initializer list and swapping. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc	2022-12-18 01:06:39 UTC (rev 65304)
@@ -26,6 +26,7 @@
 #include "hb.hh"
 #include "hb-vector.hh"
 #include "hb-set.hh"
+#include "hb-map.hh"
 #include <string>
 
 
@@ -32,6 +33,7 @@
 int
 main (int argc, char **argv)
 {
+  assert (sizeof (hb_vector_t<int>) == sizeof (hb_sorted_vector_t<int>));
 
   /* Test copy constructor. */
   {
@@ -160,8 +162,25 @@
 
     v2 = v;
 
-    v2.remove (50);
+    v2.remove_ordered (50);
+    v2.remove_unordered (50);
   }
 
+  {
+    hb_vector_t<hb_set_t> v;
+    hb_set_t s {1, 5, 7};
+    v.push (s);
+    v << s;
+    assert (s.get_population () == 3);
+    v << std::move (s);
+    assert (s.get_population () == 0);
+  }
+
+  {
+    hb_vector_t<hb_map_t> v;
+    hb_map_t m;
+    v.push (m);
+  }
+
   return 0;
 }

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2022-12-18 00:49:55 UTC (rev 65303)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2022-12-18 01:06:39 UTC (rev 65304)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [5.3.1])
+m4_define([harfbuzz_version], [6.0.0])



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