texlive[61999] Build/source/libs: harfbuzz 3.4.0

commits+kakuto at tug.org commits+kakuto at tug.org
Sun Feb 13 04:14:25 CET 2022


Revision: 61999
          http://tug.org/svn/texlive?view=revision&revision=61999
Author:   kakuto
Date:     2022-02-13 04:14:24 +0100 (Sun, 13 Feb 2022)
Log Message:
-----------
harfbuzz 3.4.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/configure
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-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-common.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.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-object.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-color-colrv1-closure.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-deprecated.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.cc
    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-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-complex-arabic-win1256.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-syllabic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-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-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-ot-var-hvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.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-plan.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/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.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/hb-buffer-verify.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-machinery.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-serialize.cc

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.cc

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/README	2022-02-13 03:14:24 UTC (rev 61999)
@@ -25,8 +25,8 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 3.2.0 - checked 13dec21
-  https://github.com/harfbuzz/harfbuzz/releases/download/3.2.0/
+harfbuzz 3.4.0 - checked 13feb22
+  https://github.com/harfbuzz/harfbuzz/releases/download/3.4.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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,3 +1,8 @@
+2022-02-13  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Import harfbuzz-3.4.0.
+	* version.ac, Makefile.am: Adjusted.
+
 2021-12-13  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Import harfbuzz-3.2.0.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2022-02-13 03:14:24 UTC (rev 61999)
@@ -44,6 +44,7 @@
 	@HARFBUZZ_TREE@/src/hb-blob.cc \
 	@HARFBUZZ_TREE@/src/hb-buffer.hh \
 	@HARFBUZZ_TREE@/src/hb-buffer-serialize.cc \
+	@HARFBUZZ_TREE@/src/hb-buffer-verify.cc \
 	@HARFBUZZ_TREE@/src/hb-buffer.cc \
 	@HARFBUZZ_TREE@/src/hb-cache.hh \
 	@HARFBUZZ_TREE@/src/hb-cff-interp-common.hh \
@@ -67,7 +68,6 @@
 	@HARFBUZZ_TREE@/src/hb-map.cc \
 	@HARFBUZZ_TREE@/src/hb-machinery.hh \
 	@HARFBUZZ_TREE@/src/hb-meta.hh \
-	@HARFBUZZ_TREE@/src/hb-ms-feature-ranges.cc \
 	@HARFBUZZ_TREE@/src/hb-ms-feature-ranges.hh \
 	@HARFBUZZ_TREE@/src/hb-mutex.hh \
 	@HARFBUZZ_TREE@/src/hb-null.hh \

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2022-02-13 03:14:24 UTC (rev 61999)
@@ -121,6 +121,7 @@
 am__dirstamp = $(am__leading_dot)dirstamp
 am_libharfbuzz_a_OBJECTS = @HARFBUZZ_TREE@/src/hb-blob.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-buffer-serialize.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-buffer-verify.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-buffer.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-common.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-draw.$(OBJEXT) \
@@ -127,7 +128,6 @@
 	@HARFBUZZ_TREE@/src/hb-face.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-font.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-map.$(OBJEXT) \
-	@HARFBUZZ_TREE@/src/hb-ms-feature-ranges.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-number.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-cff1-table.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-cff2-table.$(OBJEXT) \
@@ -200,6 +200,7 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-aat-map.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-blob.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-serialize.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-verify.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po \
@@ -208,7 +209,6 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-graphite2.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-map.Po \
-	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ms-feature-ranges.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-number.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-cff1-table.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-cff2-table.Po \
@@ -725,6 +725,7 @@
 	@HARFBUZZ_TREE@/src/hb-blob.hh @HARFBUZZ_TREE@/src/hb-blob.cc \
 	@HARFBUZZ_TREE@/src/hb-buffer.hh \
 	@HARFBUZZ_TREE@/src/hb-buffer-serialize.cc \
+	@HARFBUZZ_TREE@/src/hb-buffer-verify.cc \
 	@HARFBUZZ_TREE@/src/hb-buffer.cc \
 	@HARFBUZZ_TREE@/src/hb-cache.hh \
 	@HARFBUZZ_TREE@/src/hb-cff-interp-common.hh \
@@ -743,7 +744,6 @@
 	@HARFBUZZ_TREE@/src/hb-map.hh @HARFBUZZ_TREE@/src/hb-map.cc \
 	@HARFBUZZ_TREE@/src/hb-machinery.hh \
 	@HARFBUZZ_TREE@/src/hb-meta.hh \
-	@HARFBUZZ_TREE@/src/hb-ms-feature-ranges.cc \
 	@HARFBUZZ_TREE@/src/hb-ms-feature-ranges.hh \
 	@HARFBUZZ_TREE@/src/hb-mutex.hh @HARFBUZZ_TREE@/src/hb-null.hh \
 	@HARFBUZZ_TREE@/src/hb-number-parser.hh \
@@ -988,6 +988,9 @@
 @HARFBUZZ_TREE@/src/hb-buffer-serialize.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-buffer-verify.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-buffer.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1006,9 +1009,6 @@
 @HARFBUZZ_TREE@/src/hb-map.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
- at HARFBUZZ_TREE@/src/hb-ms-feature-ranges.$(OBJEXT):  \
-	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
-	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-number.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1164,6 +1164,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-aat-map.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-blob.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-serialize.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-verify.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po at am__quote@ # am--include-marker
@@ -1172,7 +1173,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-graphite2.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-map.Po at am__quote@ # am--include-marker
- at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ms-feature-ranges.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-number.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-cff1-table.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-cff2-table.Po at am__quote@ # am--include-marker
@@ -1815,6 +1815,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-aat-map.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-blob.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-serialize.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-verify.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po
@@ -1823,7 +1824,6 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-graphite2.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-map.Po
-	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ms-feature-ranges.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-number.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-cff1-table.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-cff2-table.Po
@@ -1917,6 +1917,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-aat-map.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-blob.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-serialize.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-verify.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po
@@ -1925,7 +1926,6 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-graphite2.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-map.Po
-	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ms-feature-ranges.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-number.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-cff1-table.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-cff2-table.Po

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,3 +1,8 @@
+2022-02-13  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Imported harfbuzz-3.4.0 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/3.4.0/
+
 2021-12-13  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Imported harfbuzz-3.2.0 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/configure	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 3.2.0.
+# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 3.4.0.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -611,8 +611,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='3.2.0'
-PACKAGE_STRING='harfbuzz (TeX Live) 3.2.0'
+PACKAGE_VERSION='3.4.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 3.4.0'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1346,7 +1346,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures harfbuzz (TeX Live) 3.2.0 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 3.4.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1418,7 +1418,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 3.2.0:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 3.4.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1523,7 +1523,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 3.2.0
+harfbuzz (TeX Live) configure 3.4.0
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2064,7 +2064,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by harfbuzz (TeX Live) $as_me 3.2.0, which was
+It was created by harfbuzz (TeX Live) $as_me 3.4.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4823,7 +4823,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='3.2.0'
+ VERSION='3.4.0'
 
 
 # Some tools Automake needs.
@@ -5034,9 +5034,9 @@
 
 
 HB_VERSION_MAJOR=3
-HB_VERSION_MINOR=2
+HB_VERSION_MINOR=4
 HB_VERSION_MICRO=0
-HB_VERSION=3.2.0
+HB_VERSION=3.4.0
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8817,7 +8817,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by harfbuzz (TeX Live) $as_me 3.2.0, which was
+This file was extended by harfbuzz (TeX Live) $as_me 3.4.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8885,7 +8885,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 3.2.0
+harfbuzz (TeX Live) config.status 3.4.0
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2022-02-13 03:14:24 UTC (rev 61999)
@@ -37,6 +37,10 @@
 option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
 option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
 option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
+if (TARGET freetype)
+  set (HB_HAVE_FREETYPE ON)
+  add_definitions(-DHAVE_FREETYPE=1)
+endif ()
 if (APPLE)
   option(HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON)
   set (CMAKE_MACOSX_RPATH ON)
@@ -184,7 +188,7 @@
 set (subset_project_headers ${HB_SUBSET_headers})
 
 ## Find and include needed header folders and libraries
-if (HB_HAVE_FREETYPE)
+if (HB_HAVE_FREETYPE AND NOT TARGET freetype)
   include (FindFreetype)
   if (NOT FREETYPE_FOUND)
     message(FATAL_ERROR "HB_HAVE_FREETYPE was set, but we failed to find it. Maybe add a CMAKE_PREFIX_PATH= to your Freetype2 install prefix")
@@ -421,7 +425,11 @@
 target_include_directories(harfbuzz PUBLIC
                            "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
                            "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz>")
+if (HB_HAVE_FREETYPE AND TARGET freetype)
+  target_link_libraries(harfbuzz PUBLIC freetype)
+endif ()
 
+
 ## Define harfbuzz-icu library
 if (HB_HAVE_ICU)
   add_library(harfbuzz-icu ${PROJECT_SOURCE_DIR}/src/hb-icu.cc ${PROJECT_SOURCE_DIR}/src/hb-icu.h)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,3 +1,2455 @@
+commit 0a129961341da370ec82bfccdd11ec9b1094b5a2
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Feb 13 00:30:50 2022 +0200
+
+    3.4.0
+
+ NEWS                   | 26 ++++++++++++++++++++++++++
+ configure.ac           |  2 +-
+ docs/harfbuzz-docs.xml |  1 +
+ meson.build            |  2 +-
+ src/hb-buffer.h        |  4 ++--
+ src/hb-common.h        |  4 ++--
+ src/hb-ot-deprecated.h |  2 +-
+ src/hb-ot-math.cc      |  2 +-
+ src/hb-ot-math.h       |  4 ++--
+ src/hb-version.h       |  6 +++---
+ 10 files changed, 40 insertions(+), 13 deletions(-)
+
+commit 41815a0d63512e11b2ff23f27e6906c44c0e9691
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Feb 13 00:00:01 2022 +0200
+
+    [name] Extraneous (out) annotation in return value
+
+ src/hb-ot-name.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b263371b0959a2021e68b210d6b73e27c6fe64b0
+Merge: b3f8288cc b47b3b997
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 12 15:06:47 2022 -0600
+
+    Merge pull request #3398 from harfbuzz/buffer-verify
+    
+    Add HB_BUFFER_FLAG_VERIFY
+
+commit b3f8288cca1951310928e3ba919c32b0c968249a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 12 14:52:42 2022 -0600
+
+    [test/subset] Don't hash files without reason
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3118#issuecomment-894021518
+
+ test/subset/run-tests.py | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 42b119edb5966793a51cdd9e7898fc90bd5036aa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 12 14:18:02 2022 -0600
+
+    [hmtx] Remove other subset-specific method from hmtx accelerator
+
+ src/hb-ot-hmtx-table.hh | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+commit 9ba520b5d1594f972c73eeb76d61d67255c07597
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 12 13:57:03 2022 -0600
+
+    [hmtx] Remove one subset-specific method from hmtx accelerator
+    
+    Looks ugly but is the right thing to do.
+
+ src/hb-ot-hmtx-table.hh | 18 +++---------------
+ 1 file changed, 3 insertions(+), 15 deletions(-)
+
+commit af407dd24d3f55ad279dfdbf21ec7c7c3cfb76ac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 12 13:53:16 2022 -0600
+
+    Add a fuzzer font
+
+ .../fonts/crash-d223bc42a8226c4d655c417d63d9a76760d05985  | Bin 0 -> 316 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 68937238791181b6172ea4cd3d127ff4f6bbdd98
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 11 13:16:25 2022 -0600
+
+    [machinery] Allow using lazy-loader with void*
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3427
+
+ src/Makefile.am       | 29 +++++++++++++++++------------
+ src/hb-common.cc      |  2 +-
+ src/hb-machinery.hh   |  3 ++-
+ src/meson.build       |  5 +++--
+ src/test-machinery.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 69 insertions(+), 16 deletions(-)
+
+commit 3d22dae5f854416939935f7cd913af7c21b4f490
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Thu Feb 10 16:30:36 2022 +0800
+
+    meson.build: Only use get_variable() on icu_dep with pkgconfig
+    
+    We might have found ICU via the .lib names, and get_variable() is only
+    available for pkg-config deps.
+
+ meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 52c536bb8d90cf0f09e13f5e9e21bf489cc08c23
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Thu Feb 10 16:39:40 2022 +0800
+
+    hb-algs.hh: Fix build on Visual Studio 2015
+    
+    The compiler does not recognize the std::hash call on
+    hb_decay<decltype (hb_deref (v)>, so give it a shove so that it is recognized
+    there.
+
+ src/hb-algs.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 81754a5a962ebefef848237ee218c019f85ef316
+Author: Alexis King <lexi.lambda at gmail.com>
+Date:   Wed Feb 9 12:00:47 2022 -0600
+
+    [ot-math] Add hb_ot_math_get_glyph_kernings
+    
+    closes #3396
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-ot-math-table.hh    | 78 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-math.cc          | 45 +++++++++++++++++++++++++
+ src/hb-ot-math.h           | 22 +++++++++++++
+ test/api/test-ot-face.c    |  1 +
+ test/api/test-ot-math.c    | 82 ++++++++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 230 insertions(+)
+
+commit 1bc4bad7a59e9d4d79d8faeb9e695df19aa494da
+Author: Alexis King <lexi.lambda at gmail.com>
+Date:   Mon Feb 7 19:57:25 2022 -0600
+
+    [ot-tag] Add HB_SCRIPT_MATH (Zmth) and map it to OT ‘math’ tag
+    
+    The ISO 15924 code for mathematical notation is ‘Zmth’, but the
+    OpenType script is ‘math’.
+
+ docs/harfbuzz-sections.txt |  3 ++-
+ src/hb-common.h            |  6 ++++++
+ src/hb-ot-deprecated.h     | 15 +++++++++++++++
+ src/hb-ot-math.h           | 14 +++++++++-----
+ src/hb-ot-tag.cc           |  3 +++
+ test/api/test-ot-tag.c     |  2 ++
+ 6 files changed, 37 insertions(+), 6 deletions(-)
+
+commit 76cd8a47373e924d146e641f377065d3929b8e51
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Feb 8 16:47:01 2022 +0200
+
+    [arabic] Update to AMTRA revision 6
+    
+    https://www.unicode.org/reports/tr53/tr53-6.html#Modifications
+
+ src/hb-ot-shape-complex-arabic.cc | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit c4cf5ddb272cb1c05a572db5b76629368f9054f5
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Feb 6 16:32:05 2022 +0200
+
+    [ci] Downgrade pip on MSVC jobs
+    
+    Turns out, pip 22.0 is the source of the breakage:
+    https://github.com/mesonbuild/meson/issues/9955#issuecomment-1030843844
+    https://github.com/pypa/pip/issues/10875
+
+ .github/workflows/msvc-ci.yml | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit ac46c3248e8b0316235943175c4d4a11c24dd4a9
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Feb 6 15:41:18 2022 +0200
+
+    3.3.2
+
+ NEWS             | 7 +++++++
+ configure.ac     | 2 +-
+ meson.build      | 2 +-
+ src/hb-version.h | 4 ++--
+ 4 files changed, 11 insertions(+), 4 deletions(-)
+
+commit 7657bdd91f93fb087c74b400e5864641317f91f5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 4 19:16:54 2022 -0600
+
+    Revert "Fix failing Mac test for previous commit"
+    
+    This reverts commit 070e30e6daba74fe62ea486dc97cd01a79f90541.
+
+ test/shape/data/in-house/tests/macos.tests | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 44da4e2a2751058bde1b2c465a1d2f3c5d617d93
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 4 19:16:47 2022 -0600
+
+    Revert "One more fix"
+    
+    This reverts commit cab943a015b1a3d4cd72f0c5dc4ff79e0aefa06f.
+
+ test/shape/data/in-house/tests/macos.tests | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 88798ee8bedcf464e4853fec67cf3648a3f39973
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 4 18:59:50 2022 -0600
+
+    [GPOS] Disable split-kerning
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3408
+    Reverts https://github.com/harfbuzz/harfbuzz/pull/3235
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
+
+ src/hb-ot-layout-gpos-table.hh                            | 10 +++++++++-
+ test/shape/data/aots/tests/gpos2_2.tests                  |  2 +-
+ test/shape/data/in-house/tests/positioning-features.tests |  2 +-
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+commit 9177953720e2d10e8db47c079563d8656d6f5553
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 4 12:38:45 2022 -0600
+
+    [atexit] Allow hb_atexit redefinition
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3412
+
+ src/hb.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 8670ffbf4ca809b954d69c52c27ab958c7d143ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 3 11:19:23 2022 -0600
+
+    [buffer] Comment
+
+ src/hb-buffer.hh | 37 ++++++++++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 17 deletions(-)
+
+commit e59da2871a83f1f68ff1d3228e4fa419d8a9e1d6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 1 16:32:39 2022 -0600
+
+    [glyf] Don't store face in accelerator
+
+ src/hb-ot-glyf-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 0fb8e22406fb9253da3da0d9f6d7fedc861fe148
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Jan 28 10:39:51 2022 -0800
+
+    [serialize] document how the serializer works.
+
+ docs/serializer.md | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 178 insertions(+)
+
+commit 45df259538c204540819d74456d30ffb40df488a
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Jan 31 23:06:10 2022 +0200
+
+    3.3.1
+
+ NEWS             | 23 +++++++++++++++--------
+ configure.ac     |  2 +-
+ meson.build      |  2 +-
+ src/hb-version.h |  4 ++--
+ 4 files changed, 19 insertions(+), 12 deletions(-)
+
+commit 4e2f409bce77b97de2d098365977beeeb4447b1e
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Jan 31 12:20:32 2022 -0800
+
+    [subset] Don't hold references to members of the active_glyph_stack.
+    
+    These references may get invalidated after the vector for the stack is resized. Fixes: https://oss-fuzz.com/testcase-detail/5422577634377728
+
+ src/hb-ot-layout-gsubgpos.hh                       |  54 +++++++++++++--------
+ ...ase-minimized-hb-subset-fuzzer-5422577634377728 | Bin 0 -> 1700 bytes
+ 2 files changed, 34 insertions(+), 20 deletions(-)
+
+commit 98da3306384044c6c73904d9a2a5996da16504ea
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Jan 31 18:12:01 2022 +0200
+
+    3.3.0
+
+ NEWS                   | 32 +++++++++++++++++++++++++++++++-
+ configure.ac           |  2 +-
+ docs/harfbuzz-docs.xml |  1 +
+ meson.build            |  2 +-
+ src/hb-buffer.cc       | 11 +++++------
+ src/hb-buffer.h        |  2 +-
+ src/hb-font.cc         | 19 ++++++++++++-------
+ src/hb-version.h       |  4 ++--
+ 8 files changed, 54 insertions(+), 19 deletions(-)
+
+commit 3e8742e37631e0570e6e635c02302e3df2b548a0
+Merge: bc899650c ae9afd977
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 30 17:19:46 2022 -0800
+
+    Merge pull request #3402 from harfbuzz/language-tags
+    
+    Make miscellaneous changes to hb-ot-tag-table.hh
+
+commit ae9afd9772e909476d28fb647d7f7aef6865f6cd
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sun Oct 3 20:09:33 2021 -0400
+
+    Let BCP 47 tag "mo" fall back to OT tag 'ROM '
+
+ src/gen-tag-table.py   |  5 ++++-
+ src/hb-ot-tag-table.hh | 13 +++++++++++--
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+commit a184c5f8518ab92b95947f23848ddde677e8cac1
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Sun Jan 30 13:28:23 2022 -0500
+
+    Don’t always inherit from macrolanguages
+    
+    If an OpenType tag maps to a BCP 47 macrolanguage, that is presumably to
+    support the use of the macrolanguage as a vague stand-in for one of its
+    individual languages. For example, "ar" and "zh" are often used for
+    "arb" and "cmn". When the OpenType tag maps to a macrolanguage and some
+    but not all of its individual languages, that indicates that the
+    OpenType tag only corresponds to the listed individual languages (which
+    may be referred to using the macrolanguage subtag) but not the missing
+    individual languages. In particular, INUK (Nunavik Inuktitut) is mapped
+    to "ike" (Eastern Canadian Inuktitut) and "iu" (Inuktitut) but not to
+    "ikt" (Inuinnaqtun), so "ikt" should not inherit the INUK mapping from
+    its macrolanguage "iu".
+
+ src/gen-tag-table.py   | 35 +++++++++++++++++++++++++++++++----
+ src/hb-ot-tag-table.hh | 12 ++----------
+ 2 files changed, 33 insertions(+), 14 deletions(-)
+
+commit b47b3b99725888fd27273d8d9b9ee3d5d6cf0400
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 29 10:24:38 2022 -0700
+
+    [fallback-kern] Move buffer message to correct position
+
+ src/hb-ot-shape-fallback.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit e986c12075a69300a5e114fe139ae5acd762ef1b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 29 09:08:48 2022 -0700
+
+    [verify] Show buffer input text when verification fails
+
+ src/hb-buffer-verify.cc | 50 ++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 41 insertions(+), 9 deletions(-)
+
+commit d35f380126830872611c85d664c3710deb46cd6b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 29 09:08:20 2022 -0700
+
+    [util] Change "All shapers failed." message to "Shaping failed."
+    
+    Since we now emit this when verification fails as well.
+
+ util/shape-options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3972e0a8f1504783a509096e069ca718d25af8d9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 29 08:22:19 2022 -0700
+
+    [buffer] Whitespace
+
+ src/hb-buffer.h | 38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+commit 0b1bf89cc2ee6a8782c007e2b7362a4485be249a
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Jan 28 22:27:51 2022 -0500
+
+    Replace “[family]” with “[collection]”
+    
+    Not all language collections are language families.
+
+ src/gen-tag-table.py   |  4 ++--
+ src/hb-ot-tag-table.hh | 58 +++++++++++++++++++++++++-------------------------
+ 2 files changed, 31 insertions(+), 31 deletions(-)
+
+commit 0e31595e0d2e214262c4cf0d4136215bc4c89a0a
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Jan 28 22:26:38 2022 -0500
+
+    Infer tag mappings for unregistered macrolanguages
+    
+    Every macrolanguage not mentioned in the OT language system tag registry
+    is mapped to every tag of its individual languages, if those have
+    registered tags.
+
+ src/gen-tag-table.py   | 34 +++++++++++++++++++---------------
+ src/hb-ot-tag-table.hh |  9 +++++++++
+ 2 files changed, 28 insertions(+), 15 deletions(-)
+
+commit 5a6545940ac0ed48bc8872424269e598388b7996
+Author: David Corbett <corbett.dav at northeastern.edu>
+Date:   Fri Jan 28 21:29:43 2022 -0500
+
+    Add the language system tag INUK
+
+ src/hb-ot-tag-table.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit bc899650c7976df7bc62ed55da5268f1d10b9a43
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Jan 28 13:54:10 2022 -0800
+
+    [subset] Fix for issue #3397.
+    
+    cur_intersected_glyphs gets modified during recursion leading to incorrect filtering of sub tables in some cases. So don't use cur_intersected_glyphs. Instead just add an additional entry onto the parent_active_glyphs () stack.
+    
+    Additionaly expands NotoNastaliqUrdu tests to include coverage of the issue from #3397.
+
+ src/hb-ot-layout-gsubgpos.hh                       |  59 +++++++++++++--------
+ src/hb-ot-layout.cc                                |   6 +--
+ .../NotoNastaliqUrdu-Bold.default.633,6D2.ttf      | Bin 0 -> 14048 bytes
+ .../NotoNastaliqUrdu-Bold.retain-gids.633,6D2.ttf  | Bin 0 -> 19948 bytes
+ ...ular.default.627,644,623,62D,644,627,645,2E.ttf | Bin 0 -> 17564 bytes
+ ...astaliqUrdu-Regular.default.627,644,62D,628.ttf | Bin 0 -> 24564 bytes
+ .../NotoNastaliqUrdu-Regular.default.627,644.ttf   | Bin 0 -> 7776 bytes
+ ...-Regular.default.633,645,627,621,20,644,627.ttf | Bin 0 -> 23232 bytes
+ .../NotoNastaliqUrdu-Regular.default.633,6D2.ttf   | Bin 0 -> 14296 bytes
+ ...otoNastaliqUrdu-Regular.default.63A,64A,631.ttf | Bin 0 -> 26152 bytes
+ ...iqUrdu-Regular.default.retain-all-codepoint.ttf | Bin 0 -> 542388 bytes
+ ....retain-gids.627,644,623,62D,644,627,645,2E.ttf | Bin 0 -> 24224 bytes
+ ...liqUrdu-Regular.retain-gids.627,644,62D,628.ttf | Bin 0 -> 30464 bytes
+ ...otoNastaliqUrdu-Regular.retain-gids.627,644.ttf | Bin 0 -> 13380 bytes
+ ...ular.retain-gids.633,645,627,621,20,644,627.ttf | Bin 0 -> 28888 bytes
+ ...otoNastaliqUrdu-Regular.retain-gids.633,6D2.ttf | Bin 0 -> 20140 bytes
+ ...astaliqUrdu-Regular.retain-gids.63A,64A,631.ttf | Bin 0 -> 32012 bytes
+ ...du-Regular.retain-gids.retain-all-codepoint.ttf | Bin 0 -> 542424 bytes
+ .../subset/data/fonts/NotoNastaliqUrdu-Regular.ttf | Bin 570552 -> 1060612 bytes
+ .../data/tests/layout.notonastaliqurdu.tests       |   2 +
+ 20 files changed, 40 insertions(+), 27 deletions(-)
+
+commit f3c1f4f0dae03bfd4521b3b8965891d45c49d02f
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Jan 28 11:50:22 2022 -0800
+
+    [subset] convert active_glyphs_stack to be a vector of hb_set_t instead of hb_set_t*.
+
+ src/hb-ot-layout-gsubgpos.hh | 63 ++++++++++++++++++++++----------------------
+ 1 file changed, 32 insertions(+), 31 deletions(-)
+
+commit 476a6377a574291025ce8acc0cecfc53408c8d3c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 28 15:05:10 2022 -0700
+
+    [buffer] Document HB_BUFFER_FLAG_VERIFY
+
+ src/hb-buffer.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit 61856359cb90f4d53eced1159b0810defa342ec6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 28 14:07:29 2022 -0700
+
+    [fuzz] Disable verification for now.
+
+ test/fuzzing/hb-shape-fuzzer.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 6596e42d160a0ae2cd2cd3b42a9f8823197cd716
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 28 13:55:24 2022 -0700
+
+    [fuzz] Verify shape results
+
+ test/fuzzing/hb-shape-fuzzer.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 5b1d813b698488fb86b4f20a596bb1c046e61eed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 28 13:49:21 2022 -0700
+
+    [config] Enable HB_NO_BUFFER_VERIFY in HB_LEAN
+
+ src/hb-config.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 61823838f9c3cdc93b2452451126dddcacfbe61d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 28 13:45:25 2022 -0700
+
+    [buffer] Add HB_BUFFER_FLAG_VERIFY
+    
+    Move buffer verification code inside the library, from util/.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/3010
+
+ src/Makefile.sources    |   1 +
+ src/harfbuzz.cc         |   1 +
+ src/hb-buffer-verify.cc | 389 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-buffer.h         |   3 +-
+ src/hb-buffer.hh        |  14 ++
+ src/hb-shape.cc         |  18 +++
+ src/meson.build         |   1 +
+ util/shape-options.hh   | 344 +-----------------------------------------
+ 8 files changed, 427 insertions(+), 344 deletions(-)
+
+commit 7c704d898210cd88f6fbf1096b9a75123d33cccd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 28 12:38:32 2022 -0700
+
+    [buffer] Make hb_buffer_append() take a const argument
+
+ src/hb-buffer.cc | 2 +-
+ src/hb-buffer.h  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 24650624c812368e3900e276aaca2dc94b737af8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 28 13:53:21 2022 -0700
+
+    [font] Fix build with no-var configs
+
+ src/hb-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 91b779e23cbaea5d9e3176f3a2c05b8ec10c89fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 28 13:52:15 2022 -0700
+
+    Avoid redefinition of HB_NO_SETLOCALE in certain configs
+
+ src/hb-common.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fa29006bfa3d5f84182b3a1c259ef4a3634da6b7
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Jan 27 01:57:45 2022 +0200
+
+    [doc] Fix generation of hb_glyph_flags_t docs
+    
+    GTK-Doc does not like the empty lines here, and interprets everything
+    after the first empty line as the description of the enum itself not a
+    specific member and the generated text makes no sense.
+    
+    Removing the empty lines makes the text harder to read (both in source
+    and HTML), but at least it is correctly organized.
+
+ src/hb-buffer.h | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+commit e9cc5f6cdb3e29f2e33e0f8a08cf821ebd654a8d
+Merge: bad5c9456 540af548d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 26 12:23:29 2022 -0800
+
+    Merge pull request #3297 from harfbuzz/unsafe-to-concat
+    
+    Implement UNSAFE_TO_CONCAT flag
+
+commit 540af548dc3926c4b9db059c9b20297df0802671
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 25 09:10:56 2022 -0700
+
+    [unsafe-to-concat] Clarify documentation as per feedback
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/3297#discussion_r754395825
+
+ src/hb-buffer.h | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+commit bad5c94562fa07c4c10f8b3663ca29cc5210c13c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 23 10:53:19 2022 -0700
+
+    [test] Remove HB_UNUSED
+
+ src/test-serialize.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6c09a8b5b0cc3ecef19f1c5a031481d831374b5d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 23 10:52:13 2022 -0700
+
+    [test-serialize] Assert len
+
+ src/test-serialize.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 76c6f4164f133e056bd75378a4a2e912d153550e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 23 10:43:37 2022 -0700
+
+    [test] Add test-serialize
+
+ src/Makefile.am       |  5 +++++
+ src/meson.build       |  1 +
+ src/test-serialize.cc | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 57 insertions(+)
+
+commit 332460649268844bf93e147cc0b86a82c449a980
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 15:46:13 2022 -0700
+
+    [buffer] Oops
+
+ src/hb-buffer.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 20031ddbb814d46f8c988242d2ee0bd9b198dbe2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 11:41:30 2022 -0700
+
+    [unsafe-to-concat] Mark in all other shapers
+    
+    unsafe_to_break() implies unsafe-to-concat; but setting the flag
+    manually wasn't.
+
+ src/hb-coretext.cc    | 3 ++-
+ src/hb-directwrite.cc | 3 ++-
+ src/hb-graphite2.cc   | 3 ++-
+ src/hb-uniscribe.cc   | 3 ++-
+ 4 files changed, 8 insertions(+), 4 deletions(-)
+
+commit 6e345f709d4888ab10ed22afffb6661d695e052f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 11:40:37 2022 -0700
+
+    Cosmetic
+
+ src/hb-buffer.hh | 16 ++++++++--------
+ src/hb-kern.hh   |  2 +-
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 374a6f186d7094370ffd6aed80688203c8f5a067
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 11:29:00 2022 -0700
+
+    [fallback-shape] Add buffer trace log
+
+ src/hb-kern.hh              |  5 +++++
+ src/hb-ot-shape-fallback.cc | 10 ++++++++++
+ 2 files changed, 15 insertions(+)
+
+commit bcdfedbc09c308965239c4b7a750a9cc20618542
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 11:19:05 2022 -0700
+
+    [unsafe-to-concat] Mark as unsafe in kern machine
+    
+    Fixes that last test. Yay!
+
+ src/hb-aat-layout-kerx-table.hh | 1 -
+ src/hb-kern.hh                  | 2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+commit 14d43d12359ba14e4bb95c24903be70808f66738
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 10:46:18 2022 -0700
+
+    [unsafe-to-concat] Adjust end conditions
+
+ src/hb-buffer.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 8663eda4fde11d360cca15936e9d2ae07c357958
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 10:35:05 2022 -0700
+
+    [unsafe-to-concat] More annotations for MarkMarkPos
+    
+    Failures down to one:
+    
+    265/401 harfbuzz:shaping+aots / lookupflag_ignore_attach         FAIL
+
+ src/hb-ot-layout-gpos-table.hh | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+commit 6a7d6d4b64dd0eff7d0e7191ad30268a2502db5f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 10:33:35 2022 -0700
+
+    [unsafe-to-concat] More annotations for MarkLigaturePos
+
+ src/hb-ot-layout-gpos-table.hh | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+commit a575992057bcfab2ee3a720ad321c907cf20ff22
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 10:30:39 2022 -0700
+
+    [unsafe-to-concat] Mark LigatureSubst
+    
+    Failures down to two:
+    
+    209/401 harfbuzz:shaping+aots / gpos6                            FAIL             0.06s   exit status 1
+    265/401 harfbuzz:shaping+aots / lookupflag_ignore_attach         FAIL             0.06s   exit status 1
+
+ src/hb-ot-layout-gsub-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit b443898cce2251ca2aaf332c13886577ab8db416
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 10:24:59 2022 -0700
+
+    [unsafe-to-concat] Adjust MarkBasePos
+    
+    A couple more aots tests down. Four failing:
+    
+    209/401 harfbuzz:shaping+aots / gpos6                            FAIL             0.06s   exit status 1
+    261/401 harfbuzz:shaping+aots / gsub4_1_multiple_ligatures       FAIL             0.07s   exit status 1
+    265/401 harfbuzz:shaping+aots / lookupflag_ignore_attach         FAIL             0.07s   exit status 1
+    267/401 harfbuzz:shaping+aots / lookupflag_ignore_combination    FAIL             0.07s   exit status 1
+
+ src/hb-ot-layout-gpos-table.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 95d052a791262ebccbfeb794b992525ba2cc0ffc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 10:16:23 2022 -0700
+
+    [unsafe-to-concat] Adjust GPOS lookbacks
+    
+    Fixes Cursive aots test, fails a couple new aots ones.
+
+ src/hb-ot-layout-gpos-table.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 909e34f68a969275bc9b14c63e03d5d131823d91
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 22 09:44:13 2022 -0700
+
+    [unsafe-to-concat] Adjust Arabic-joining start boundary condition more
+
+ src/hb-ot-shape-complex-arabic.cc                        |  14 ++++++++++++--
+ test/shape/data/in-house/Makefile.sources                |   1 +
+ .../fonts/34da9aab7bee86c4dfc3b85e423435822fdf4b62.ttf   | Bin 0 -> 1904 bytes
+ test/shape/data/in-house/meson.build                     |   1 +
+ test/shape/data/in-house/tests/unsafe-to-concat.tests    |   1 +
+ 5 files changed, 15 insertions(+), 2 deletions(-)
+
+commit 11bdd7a020d3e99c0ff43f34cf1724a95713b463
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 21 18:59:06 2022 -0700
+
+    [unsafe-to-concat] Adjust CursivePos
+    
+    Doesn't fix the test yet.
+
+ src/hb-ot-layout-gpos-table.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit ea1b32c8c198da4475941f459b16dc6d7e28148a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 21 18:58:33 2022 -0700
+
+    [unsafe-to-concat] Adjust "interior"ness of "from_out_buffer"
+
+ src/hb-buffer.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4f04baef17bf5b150c1594f6e80604974e6e95e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 21 18:26:54 2022 -0700
+
+    [unsafe-to-concat] Further adjust Arabic joining logic at boundary
+
+ src/hb-ot-shape-complex-arabic.cc | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 235c3a129581e96701fe055341e56699766df5fa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 21 15:17:40 2022 -0700
+
+    [unsafe-to-concat] Adjust Arabic joining logic
+    
+    Test failures done one more. Fixed the mongolian-variation-selector
+    test.  Another test case:
+    
+    $ util/hb-shape NotoSansArabic-Regular.ttf -u 628,200c,628 --show-flags --verify
+
+ src/hb-ot-shape-complex-arabic.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 48c5f26199808f40251cdaef7494456e9f23acb9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 21 12:18:50 2022 -0700
+
+    [unsafe-to-concat] Fix PairPos2 logic
+    
+    Test failures down from 8 to 6:
+    
+    113/400 harfbuzz:shaping+in-house / mongolian-variation-selector FAIL             0.06s   exit status 1
+    203/400 harfbuzz:shaping+aots / gpos3                            FAIL             0.06s   exit status 1
+    204/400 harfbuzz:shaping+aots / gpos4_lookupflag                 FAIL             0.06s   exit status 1
+    260/400 harfbuzz:shaping+aots / gsub4_1_multiple_ligatures       FAIL             0.06s   exit status 1
+    264/400 harfbuzz:shaping+aots / lookupflag_ignore_attach         FAIL             0.06s   exit status 1
+    266/400 harfbuzz:shaping+aots / lookupflag_ignore_combination    FAIL             0.06s   exit status 1
+
+ src/hb-ot-layout-gpos-table.hh | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+commit c0058892bec52e4f0346b1139ebb206c03e094e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 20 15:51:04 2022 -0700
+
+    [unsafe-to-concat] Mark entire buffer unsafe-to-concat if kerx format2
+
+ src/hb-aat-layout-kerx-table.hh |  1 +
+ src/hb-buffer.hh                | 21 ++++++++++++++-------
+ 2 files changed, 15 insertions(+), 7 deletions(-)
+
+commit 60006d368770982c6a0d3bf06eb937773343cf5b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 20 15:29:28 2022 -0700
+
+    [gsubgpos] Adjust chaining unsafe-to-concat application
+    
+    Fixes three tests.
+
+ src/hb-ot-layout-gsubgpos.hh | 46 ++++++++++++++++++++++++--------------------
+ 1 file changed, 25 insertions(+), 21 deletions(-)
+
+commit d98a0fc88e8bcf7993c92425212cd6c57a632a01
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 4 20:43:27 2021 -0800
+
+    [buffer] Consolidate glyph-flags implementation
+
+ src/hb-buffer.cc | 25 -------------------
+ src/hb-buffer.hh | 76 +++++++++++++++++++++++++++++++++++++++++++++-----------
+ 2 files changed, 62 insertions(+), 39 deletions(-)
+
+commit f91ce56e08ed9acdfaf5dfe994d950195dd10881
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 4 20:07:05 2021 -0800
+
+    [buffer] Add default cluster value in find_min_cluster
+
+ src/hb-buffer.cc | 6 ++----
+ src/hb-buffer.hh | 2 +-
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+commit 56d081955c768a4ed55354fe57577cb10706fb81
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 4 19:59:55 2021 -0800
+
+    [buffer] Rename _unsafe_to_break_set_mask to _infos_set_glyph_flags
+
+ src/hb-buffer.cc |  6 +++---
+ src/hb-buffer.hh | 27 +++++++++++++--------------
+ 2 files changed, 16 insertions(+), 17 deletions(-)
+
+commit 78481b32c0a14f0ee1c4baec4d5208b385be0b2e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 21 16:50:34 2021 -0700
+
+    [gsubgpos] Combine input/backtrack/lookahead unsafe-to-concat
+    
+    I feel like this is correct logic. Still have to prove.
+    
+    Errors unchanged at 10.
+
+ src/hb-ot-layout-gpos-table.hh |  2 +-
+ src/hb-ot-layout-gsub-table.hh | 15 ++++---
+ src/hb-ot-layout-gsubgpos.hh   | 93 +++++++++++++++++++++++-------------------
+ 3 files changed, 62 insertions(+), 48 deletions(-)
+
+commit 596bc7e939d927b4b211cdd847fbb1208789b999
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 20 12:02:47 2021 -0700
+
+    [unsafe-to-concat] Add to GPOS kerning
+
+ src/hb-ot-layout-gpos-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit e1cbd4539f392034899353f55daffa32e6d62c87
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 20 11:46:48 2021 -0700
+
+    [unsafe-to-concat] Add annotations to GPOS and kern
+    
+    Failures from 13 to 14.
+
+ src/hb-kern.hh                 |  4 +++-
+ src/hb-ot-layout-gpos-table.hh | 43 ++++++++++++++++++++++++++++++++++++------
+ 2 files changed, 40 insertions(+), 7 deletions(-)
+
+commit 36b1561715737ff6608bf2eb6c21b64348abb226
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 19 14:10:34 2021 -0700
+
+    Implement hb-shape --verify unsafe-to-concat flag
+    
+    15 tests failing. Those look like legit places that unsafe-to-concat
+    needs more implementation.
+
+ util/shape-options.hh | 198 +++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 189 insertions(+), 9 deletions(-)
+
+commit 3122c2cdc45a964efedad8953a2df67205c3e3a8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 4 19:50:33 2021 -0800
+
+    [buffer] Add HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1463
+
+ src/hb-buffer.cc             | 10 +++---
+ src/hb-buffer.h              | 76 ++++++++++++++++++++++++++++++++++++--------
+ src/hb-buffer.hh             | 33 +++++++++++--------
+ src/hb-ot-layout-gsubgpos.hh | 39 ++++++++++++++++++++---
+ src/hb-ot-shape.cc           |  8 ++---
+ 5 files changed, 124 insertions(+), 42 deletions(-)
+
+commit a8b7f1880412c7f0c9ecdada0a4935011816c7dc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 21 07:38:33 2022 -0700
+
+    [cff] Initialize accelerator members
+
+ src/hb-ot-cff1-table.hh | 24 ++++++++++++------------
+ src/hb-ot-cff2-table.hh | 16 ++++++++--------
+ 2 files changed, 20 insertions(+), 20 deletions(-)
+
+commit cce37a6f10e0c7b06b5ead1223e92c85d88242c0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 21 07:31:21 2022 -0700
+
+    [gpos] Fix conditional
+
+ src/hb-ot-layout-gpos-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 773cf4fdd30cf9d4b8a7139ce2992156dc86bc00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 21 07:30:09 2022 -0700
+
+    [post] Initialize variables
+
+ src/hb-ot-post-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit cab943a015b1a3d4cd72f0c5dc4ff79e0aefa06f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 20 14:32:30 2022 -0700
+
+    One more fix
+
+ test/shape/data/in-house/tests/macos.tests | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 070e30e6daba74fe62ea486dc97cd01a79f90541
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 20 14:31:31 2022 -0700
+
+    Fix failing Mac test for previous commit
+
+ test/shape/data/in-house/tests/macos.tests | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 84aa1a836c1440e862f58f0d5a23363825b5ac66
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 20 13:18:19 2022 -0800
+
+    [PairPos] Split GPOS kerning to both sides (#3235)
+
+ src/hb-ot-layout-gpos-table.hh                     | 66 +++++++++++++++++++++-
+ test/shape/data/aots/Makefile.sources              |  3 -
+ test/shape/data/aots/tests/gpos2_2.tests           |  2 +-
+ .../data/in-house/tests/positioning-features.tests |  2 +-
+ 4 files changed, 66 insertions(+), 7 deletions(-)
+
+commit ae9fc7f53335a42fe109ced01238fdaf2fc49b90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 20 12:37:21 2022 -0700
+
+    Clean accelerators a bit more
+
+ src/hb-ot-color-colr-table.hh  | 12 ++++++------
+ src/hb-ot-layout-gdef-table.hh | 10 +++++-----
+ src/hb-ot-name-table.hh        |  2 --
+ src/hb-ot-post-table.hh        |  3 ---
+ src/hb-subset-plan.cc          |  4 +---
+ 5 files changed, 12 insertions(+), 19 deletions(-)
+
+commit 0ae66593987c54e2d8a03b2c2c49c76d0ba1a4bb
+Merge: 112cb9fe6 ac1bb3e39
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 20 11:28:59 2022 -0800
+
+    Merge pull request #3392 from harfbuzz/auto-accelerators
+    
+    Auto accelerators
+
+commit ac1bb3e39e4c0be675bd0f8a230bc75b57d22e98
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 20 11:47:17 2022 -0700
+
+    [machinery] Move accelerators to constructor/destructor
+
+ src/hb-machinery.hh              |  6 +++---
+ src/hb-ot-cff1-table.hh          | 10 ++++++----
+ src/hb-ot-cff2-table.hh          | 43 +++++++++++++++++++++++++---------------
+ src/hb-ot-cmap-table.hh          | 17 ++++++++--------
+ src/hb-ot-color-cbdt-table.hh    | 14 +++++++------
+ src/hb-ot-color-sbix-table.hh    |  9 ++++++---
+ src/hb-ot-color-svg-table.hh     |  8 +++++---
+ src/hb-ot-glyf-table.hh          | 15 +++++++-------
+ src/hb-ot-hmtx-table.hh          | 20 +++++++++----------
+ src/hb-ot-layout-gdef-table.hh   |  9 +++++----
+ src/hb-ot-layout-gpos-table.hh   |  4 +++-
+ src/hb-ot-layout-gsub-table.hh   |  4 +++-
+ src/hb-ot-layout-gsubgpos.hh     |  5 ++---
+ src/hb-ot-meta-table.hh          |  8 +++++---
+ src/hb-ot-name-table.hh          |  9 +++++----
+ src/hb-ot-post-table-v2subset.hh |  7 ++-----
+ src/hb-ot-post-table.hh          | 10 +++++++---
+ src/hb-ot-var-gvar-table.hh      |  8 +++++---
+ src/hb-subset-cff2.cc            |  8 ++------
+ src/hb-subset-plan.cc            | 22 ++++----------------
+ 20 files changed, 123 insertions(+), 113 deletions(-)
+
+commit 112cb9fe6927600018c61cd92577e01dbd8ed601
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Jan 19 15:31:35 2022 -0800
+
+    [repacker] Fix missing initilization of obj in vertex_t.
+
+ src/hb-repacker.hh | 23 +++++------------------
+ 1 file changed, 5 insertions(+), 18 deletions(-)
+
+commit e062376ef1ce0e8e303eefd3bf449c20ba1f3607
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 17:09:34 2022 -0700
+
+    [machinery] Make accelerator lazy-loader call Xinit/Xfini
+    
+    Instead of init/fini. To isolate those functions. To be turned into
+    constructor/destructors, ideally one per commit (after some SFINAE
+    foo.)
+
+ src/hb-machinery.hh              |  6 +++---
+ src/hb-ot-cff1-table.hh          |  4 ++--
+ src/hb-ot-cff2-table.hh          | 28 ++++++++++++++--------------
+ src/hb-ot-cmap-table.hh          | 14 +++++++-------
+ src/hb-ot-color-cbdt-table.hh    |  4 ++--
+ src/hb-ot-color-sbix-table.hh    |  4 ++--
+ src/hb-ot-color-svg-table.hh     |  4 ++--
+ src/hb-ot-glyf-table.hh          |  8 ++++----
+ src/hb-ot-hmtx-table.hh          |  8 ++++----
+ src/hb-ot-layout-gdef-table.hh   |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh     |  4 ++--
+ src/hb-ot-meta-table.hh          |  4 ++--
+ src/hb-ot-name-table.hh          |  4 ++--
+ src/hb-ot-post-table-v2subset.hh |  4 ++--
+ src/hb-ot-post-table.hh          |  4 ++--
+ src/hb-ot-var-gvar-table.hh      |  4 ++--
+ src/hb-subset-cff2.cc            |  4 ++--
+ src/hb-subset-plan.cc            | 16 ++++++++--------
+ 18 files changed, 64 insertions(+), 64 deletions(-)
+
+commit 1522015bb2d140f199359c4e7cfcf342b93894a7
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Jan 19 23:13:50 2022 +0200
+
+    [test] Add --single-par to more places in hb-aots-tester [ci skip]
+
+ test/shape/data/aots/hb-aots-tester.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 2d12fc90a4b4d5b5ba847115c8ef76b16ec495ef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 14:01:20 2022 -0700
+
+    [ms-feature-ranges] Pass reference to cmp function
+
+ src/hb-ms-feature-ranges.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ac109c9353292bfa474f57efdb43f9e0f2f735f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 12:11:58 2022 -0700
+
+    [ms-feature-ranges] Inline code in header file
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3387
+
+ src/Makefile.sources        |   1 -
+ src/harfbuzz.cc             |   1 -
+ src/hb-ms-feature-ranges.cc | 177 --------------------------------------------
+ src/hb-ms-feature-ranges.hh | 141 ++++++++++++++++++++++++++++++++++-
+ src/meson.build             |   1 -
+ 5 files changed, 137 insertions(+), 184 deletions(-)
+
+commit cfa00238e40cc3c8d1aac557539fd746bc70124b
+Merge: 7e160dc34 376738d41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 11:10:22 2022 -0800
+
+    Merge pull request #3386 from harfbuzz/unify-sorted-vector
+    
+    Unify sorted vector
+
+commit 376738d41104dc10d483c8eb135d1befd5b18855
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 11:46:21 2022 -0700
+
+    [coretext] Fix lsearch
+
+ src/hb-coretext.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 106388e7665984b545b2b47b0fac63ab2484a4f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 11:38:37 2022 -0700
+
+    [vector] Merge sorted-vector into vector
+    
+    Was easier than I thought!
+    
+    Let's see what the bot gods think...
+
+ src/hb-vector.hh | 58 +++++++++++---------------------------------------------
+ 1 file changed, 11 insertions(+), 47 deletions(-)
+
+commit 294d50ff353f77be2b2f0a560a2a876e4a80d094
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 11:32:14 2022 -0700
+
+    [vector] Add sorted template argument
+
+ src/hb-vector.hh | 24 ++++++++++++++++++++++--
+ 1 file changed, 22 insertions(+), 2 deletions(-)
+
+commit cd9799784cc6deb8829a3c54a9dee654379cc03e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 11:14:25 2022 -0700
+
+    [vector] Remove old find() method
+
+ src/hb-algs.hh   | 12 +++++++++---
+ src/hb-object.hh |  6 +++---
+ src/hb-vector.hh | 17 -----------------
+ 3 files changed, 12 insertions(+), 23 deletions(-)
+
+commit 849e40b4db814bc6fe5defa5b802cc534aab209a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 11:06:33 2022 -0700
+
+    [ms-feature-ranges] Use preferred vector search API
+
+ src/hb-ms-feature-ranges.cc | 2 +-
+ src/hb-ms-feature-ranges.hh | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 7e160dc347a77dc36a9bd9df6cb686eff8252f7c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 09:26:53 2022 -0700
+
+    [gpos] Fix unsafe-to-break of mark-attachment
+    
+    This was undetected because most of the time marks were in same
+    cluster of their base already.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3093
+
+ src/hb-ot-layout-gpos-table.hh                | 2 +-
+ test/shape/data/aots/tests/gpos4_simple.tests | 2 +-
+ test/shape/data/aots/tests/gpos5.tests        | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+commit c8195dbc01f0b36f39ac6f087ee6891b09e31594
+Merge: 17cd4457b 282642311
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 19 06:56:05 2022 -0800
+
+    Merge pull request #3365 from harfbuzz/gdef-fix
+    
+    GDEF fix
+
+commit 17cd4457b7e456f3c99582a71c92b47ad572cd2f
+Author: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
+Date:   Wed Jan 19 11:53:02 2022 +0100
+
+    meson: Enable big objects support when building for windows
+    
+    Fix cross compilation when targetting win64
+
+ meson.build | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 282642311f1710d1b4ea223de21090211de57765
+Author: Simon Cozens <simon at simon-cozens.org>
+Date:   Wed Jul 8 14:39:31 2020 +0100
+
+    Test for #2140
+
+ test/shape/data/in-house/Makefile.sources                |   1 +
+ .../in-house/fonts/FallbackPlus-Javanese-no-GDEF.otf     | Bin 0 -> 4776 bytes
+ test/shape/data/in-house/meson.build                     |   1 +
+ test/shape/data/in-house/tests/glyph-props-no-gdef.tests |   1 +
+ 4 files changed, 3 insertions(+)
+
+commit fc5354c5e5e16105b46b7716065a9f1afac72e7b
+Author: Simon Cozens <simon at simon-cozens.org>
+Date:   Wed Jul 8 14:16:00 2020 +0100
+
+    Add test for #2516
+
+ test/shape/data/in-house/Makefile.sources              |   1 +
+ .../data/in-house/fonts/NotoNastaliqUrdu-Regular.ttf   | Bin 0 -> 457312 bytes
+ test/shape/data/in-house/meson.build                   |   1 +
+ .../in-house/tests/nested-mark-filtering-sets.tests    |   4 ++++
+ 4 files changed, 6 insertions(+)
+
+commit 94ba4d5a440c599694b0db73ab8e9344d83cb9ef
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Jan 18 16:35:30 2022 -0800
+
+    [subset] Fix bound check when setting overlap bit.
+    
+    length() shouldn't be used again as the end of instruction offset is already included in flags_offset.
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 10a20be397e47522f8d20f6247278a0770c5bf66
+Merge: daab4bf63 fe783ac09
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 13:46:35 2022 -0800
+
+    Merge pull request #3381 from harfbuzz/clean-vector-use
+    
+    Clean vector use
+
+commit fe783ac091b94ff6d0c9060fde229594b4e635e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 13:38:28 2022 -0700
+
+    [cff] Remove op_str_t nop init/fini
+
+ src/hb-cff-interp-common.hh | 3 ---
+ src/hb-subset-cff-common.hh | 3 ---
+ 2 files changed, 6 deletions(-)
+
+commit 8d24ac26623f5645783b8e36e39c9f5c635e0191
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 13:14:42 2022 -0700
+
+    [cff] Remove init/fini from number_t
+
+ src/hb-cff-interp-common.hh    | 7 +------
+ src/hb-cff-interp-cs-common.hh | 9 +--------
+ 2 files changed, 2 insertions(+), 14 deletions(-)
+
+commit 6ef83c2c31b4355f2eeee7d241e2c6bb52f6d6b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 13:08:34 2022 -0700
+
+    [vector] Remove .fini_deep()
+
+ src/hb-cff-interp-common.hh | 4 ++--
+ src/hb-vector.hh            | 7 -------
+ 2 files changed, 2 insertions(+), 9 deletions(-)
+
+commit daab4bf63a6ce1a519173aee5ddfbf17318cf2b8
+Author: James Hilliard <james.hilliard1 at gmail.com>
+Date:   Mon Jan 17 18:28:39 2022 -0700
+
+    [meson] add icu DEFS required for compilation
+    
+    In some cases we need to add additionl defs to build against icu if
+    icu has certain options configured.
+    
+    ICU warns about this when building:
+    
+    *** WARNING: You must set the following flags before code compiled against this ICU will function properly:
+    
+        -DU_DISABLE_RENAMING=1
+    
+    We can fetch these flags from the icu pkgconfig and add them if
+    required.
+    
+    This fixes symbol errors if ICU is built without renaming.
+
+ meson.build | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 4eb6e6ea16e0b4f6ac7271929849c3e8f52c8cc6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 12:07:05 2022 -0700
+
+    [cff] Remove some more fini_deep()
+
+ src/hb-ot-cff1-table.hh | 4 ++--
+ src/hb-ot-cff2-table.hh | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 29f60d1eaad663b8519930145e7f4c4d88429dce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 11:58:16 2022 -0700
+
+    [cff] Remove init/fini from blend_arg_t
+
+ src/hb-cff2-interp-cs.hh | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+commit 213e3f09b11cd6fb67295ad758beffd490d62ed6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 09:39:46 2022 -0700
+
+    [vector] Add TODO Emplace?
+
+ src/hb-vector.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit f1dc8b087cf08970c6c96b0052ec46a10892cc66
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Jan 18 10:29:04 2022 -0800
+
+    [subset-cff] Convert subr_closures_t to constructor/destructor instead of init/fini.
+
+ src/hb-subset-cff-common.hh | 50 ++++++++++++---------------------------------
+ 1 file changed, 13 insertions(+), 37 deletions(-)
+
+commit a48aa9850acf89a1ba36fa812195d6428f80b9a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 09:32:58 2022 -0700
+
+    [subset-cff] Remove another set of fini_deep
+
+ src/hb-subset-cff-common.hh | 30 ++++--------------------------
+ 1 file changed, 4 insertions(+), 26 deletions(-)
+
+commit 07474aa8c6f8a4d4bff92501e2e19143cfe8e91f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 09:29:43 2022 -0700
+
+    [subset-cff1] Remove a constructor/destructor pair
+
+ src/hb-subset-cff1.cc | 32 +++++---------------------------
+ 1 file changed, 5 insertions(+), 27 deletions(-)
+
+commit a1e9a276eb2dee1c1b0503072a0e6bbefc1dd62f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 09:27:32 2022 -0700
+
+    [subset-cff2] Drop an constructor/destructor pair
+
+ src/hb-subset-cff2.cc | 33 ++++++---------------------------
+ 1 file changed, 6 insertions(+), 27 deletions(-)
+
+commit 035f03346ddc673a3617822e45103d67a11cd62c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 09:26:30 2022 -0700
+
+    [str_buff_vec_t] Remove unused fini method
+
+ src/hb-ot-cff-common.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit de2cef42b4b6fba68d5b7baa53019af257ba2110
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 09:21:31 2022 -0700
+
+    [bimap] Remove init/fini
+
+ src/hb-bimap.hh             | 14 --------------
+ src/hb-ot-layout-common.hh  |  9 ---------
+ src/hb-ot-var-hvar-table.hh |  7 ++-----
+ src/hb-subset-cff-common.hh | 19 +------------------
+ src/hb-subset-cff1.cc       |  8 --------
+ src/hb-subset-cff2.cc       |  2 --
+ 6 files changed, 3 insertions(+), 56 deletions(-)
+
+commit c3dd21f11087f1e4cda82dcd6667cae508ca4543
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 09:11:08 2022 -0700
+
+    [cff] Remove unneeded init/fini
+
+ src/hb-subset-cff1.cc | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 0b54f924160204e895ae832a1244a3d98e3b5252
+Merge: 92f179075 15cceff3d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 18 07:28:07 2022 -0800
+
+    Merge pull request #3376 from harfbuzz/auto-vector
+    
+    [vector] Automatic item allocation / destruction
+
+commit 15cceff3d779c0cfb6b4d613ec7b39e81c962c7d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 17 15:53:01 2022 -0700
+
+    [repacker] Replace fini_deep() with fini()
+    
+    Vector calls destructor now.
+
+ src/hb-repacker.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 1198fb24686d1ea268f9923d3238fe6c2afb2d97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 16 06:29:35 2022 -0700
+
+    [vector] Adjust construction criteria
+
+ src/hb-vector.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit c58bfa35fb9d6d8bebad94c2c6e24eaf18d5d1d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 15 18:06:03 2022 -0700
+
+    [vector] Move semantics in vector remove()
+
+ src/hb-vector.hh | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+commit 5946e945d515bed8579caaac7fb79ee540fb22e8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 15 18:00:18 2022 -0700
+
+    [vector] Destruct in pop()
+
+ src/hb-vector.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 7171917b52880728b513168d946196331b7707d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 15 17:16:40 2022 -0700
+
+    [vector] Construct items when enlarging
+
+ src/hb-vector.hh | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+commit 813eaba6ea23544eea6bc6efcedada817b9c0b10
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 14 13:09:21 2022 -0700
+
+    [vector] Start adding destruction
+    
+    Now we need to remove manual destruction, ouch!
+
+ src/hb-vector.hh | 34 ++++++++++++++++++++++++++--------
+ 1 file changed, 26 insertions(+), 8 deletions(-)
+
+commit 65a22836f833c9ec0e5a3d11f3e5b9a2befaea54
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 14 12:55:48 2022 -0700
+
+    [vector] Add XXX markers for remaining places that need work
+
+ src/hb-vector.hh | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+commit 92f179075fc264c9d999c6316193b8ac3e76746c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 16 07:51:35 2022 -0700
+
+    Make hb_coerce static inline
+    
+    That's the pattern we follow.
+    
+    https://github.com/harfbuzz/harfbuzz/commit/985b63b3eeee5be1f5234fc7f13077eacf5e5b94#commitcomment-63973544
+
+ src/hb-algs.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 19793f333b14208daecc911f4f6979ff7d393391
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 16 07:49:40 2022 -0700
+
+    Better try at previous commit
+    
+    https://github.com/harfbuzz/harfbuzz/commit/985b63b3eeee5be1f5234fc7f13077eacf5e5b94#commitcomment-63973544
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1173ed1f7f401b0f21bacc0f35c4a18f6947a99d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 16 07:48:02 2022 -0700
+
+    Try fix Mac build
+    
+    https://github.com/harfbuzz/harfbuzz/commit/985b63b3eeee5be1f5234fc7f13077eacf5e5b94#commitcomment-63973544
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c0f57ccc88b56c023bbb683449bb6627b697ccc2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 16 06:59:24 2022 -0700
+
+    [algs] Add default-construtor to hb_pair_t
+
+ src/hb-algs.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit e2e305066a09b67670fff460d920d4a8aae81389
+Author: luz paz <luzpaz at users.noreply.github.com>
+Date:   Sun Jan 16 07:00:53 2022 -0500
+
+    Fix various typos
+    
+    Found via `codespell -q 3 -S ./perf/texts -L actualy,ba,beng,fo,gir,inout,nd,ot,pres,ro,te,teh,timne`
+
+ NEWS                                              |  6 +++---
+ RELEASING.md                                      |  2 +-
+ docs/Makefile.am                                  |  2 +-
+ docs/repacker.md                                  | 12 ++++++------
+ docs/usermanual-integration.xml                   |  4 ++--
+ src/gen-os2-unicode-ranges.py                     |  2 +-
+ src/hb-aat-layout-just-table.hh                   |  2 +-
+ src/hb-array.hh                                   |  2 +-
+ src/hb-cff2-interp-cs.hh                          |  2 +-
+ src/hb-draw.h                                     |  2 +-
+ src/hb-ot-color.cc                                |  2 +-
+ src/hb-ot-layout-common.hh                        |  2 +-
+ src/hb-ot-shape-complex-hangul.cc                 |  2 +-
+ src/hb-ot-shape.cc                                |  2 +-
+ src/hb-ot-var-gvar-table.hh                       |  2 +-
+ src/hb-ot-var.h                                   |  2 +-
+ src/hb-repacker.hh                                |  2 +-
+ src/hb-serialize.hh                               |  4 ++--
+ src/ms-use/IndicPositionalCategory-Additional.txt | 12 ++++++------
+ test/api/test-ot-math.c                           |  2 +-
+ test/fuzzing/hb-set-fuzzer.cc                     |  2 +-
+ util/ansi-print.hh                                |  2 +-
+ util/hb-subset.cc                                 |  2 +-
+ 23 files changed, 37 insertions(+), 37 deletions(-)
+
+commit 589bea15b790f36ec12c8f463ea1c333b6155958
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 15 17:55:10 2022 -0700
+
+    Fix previous commit
+
+ src/hb-common.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit b97e4f7084e3f2c3eea64163188da97734bbedef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 15 17:47:51 2022 -0700
+
+    Further adjust setlocale
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3375#issuecomment-1013783496
+
+ src/hb-common.cc | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+commit 63affc4eaea73a70667f346926a3a289c35773c5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 16:05:42 2022 -0700
+
+    [vector] Move semantics when resizing
+
+ src/hb-ot-color-cbdt-table.hh | 10 ++++++++++
+ src/hb-vector.hh              | 30 +++++++++++++++++++++++++++++-
+ src/test-vector.cc            | 14 ++++++++++++++
+ 3 files changed, 53 insertions(+), 1 deletion(-)
+
+commit 1c50106608cfa205fafa41e80c7f747e2e5b0730
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 15 13:08:21 2022 -0700
+
+    [meta] Include <memory>, for addressof
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3375
+
+ src/hb-meta.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 71e6f742a8159640fff6b9ddee0fd34f277ce0e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 16:19:44 2022 -0700
+
+    [meta] Remove unused hb_ref()
+
+ src/hb-meta.hh | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+commit e30511a8de700224a22163cf6f0c29e18aaeb4fb
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Jan 14 16:20:31 2022 -0800
+
+    [map] Correct previous commit, if (...) was reversed.
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ff4e8c7eac26f3183cb88a37dadb578362d44405
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Jan 14 16:20:31 2022 -0800
+
+    [map] Fix bad memory access if hb_map.fini() was called twice.
+
+ src/hb-map.hh   | 12 +++++++-----
+ src/test-map.cc |  8 ++++++++
+ 2 files changed, 15 insertions(+), 5 deletions(-)
+
+commit 8a69e0063936764cbd149985e0b57e1dc35935c2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 16:17:34 2022 -0700
+
+    [meta] Use std::addressof() instead of hb_addressof()
+
+ src/hb-algs.hh                    |  2 +-
+ src/hb-iter.hh                    |  2 +-
+ src/hb-map.hh                     |  4 ++--
+ src/hb-meta.hh                    | 20 ++------------------
+ src/hb-ot-cmap-table.hh           |  2 +-
+ src/hb-ot-color-colrv1-closure.hh |  2 +-
+ src/hb-ot-name-table.hh           |  2 +-
+ src/hb-serialize.hh               | 10 +++++-----
+ 8 files changed, 14 insertions(+), 30 deletions(-)
+
+commit b7b0a15f7eb8e753e6434c1fee66c2a2f75ea1bb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 15:33:27 2022 -0700
+
+    [meta] Remove hb_add_const
+
+ src/hb-iter.hh | 2 +-
+ src/hb-meta.hh | 1 -
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+commit 3b2e604237d5c818dc9b24158e18bc556c566dce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 15:32:46 2022 -0700
+
+    [meta] Use std::is_const instead of hb_is_const
+
+ src/hb-meta.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 909dde9df1b93a508258461ff8e00c5f6604f07b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 15:30:10 2022 -0700
+
+    [meta] Use std::is_reference instead of hb_is_reference
+
+ src/hb-iter.hh | 2 +-
+ src/hb-meta.hh | 5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit 47afb3ef04c97628d36a129e744b82303b1ca52a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 15:26:07 2022 -0700
+
+    [meta] Replace hb_is_pointer with std::is_pointer
+
+ src/hb-algs.hh | 2 +-
+ src/hb-map.hh  | 4 ++--
+ src/hb-meta.hh | 1 -
+ 3 files changed, 3 insertions(+), 4 deletions(-)
+
+commit 956e0a4d13c349ccaf64dd130211909fadc43637
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 15:06:58 2022 -0700
+
+    [map] Destruct objects
+
+ src/hb-map.hh   | 11 ++++++++---
+ src/test-map.cc |  2 --
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+commit 726b1a8b2d0ce980e51dc7404c49906b44e73076
+Author: Jussi Pakkanen <jpakkane at gmail.com>
+Date:   Thu Jan 13 18:30:52 2022 +0200
+
+    Convert fallback kwargs to [provide] entries.
+
+ meson.build                | 11 ++++-------
+ subprojects/cairo.wrap     |  3 +++
+ subprojects/freetype2.wrap |  3 +++
+ subprojects/glib.wrap      |  4 ++++
+ 4 files changed, 14 insertions(+), 7 deletions(-)
+
+commit bc0a5fdf43c7932c9ca39fa64a5cd405ebb43da5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 13:34:22 2022 -0700
+
+    [test-map] Add disabled tests with std::string
+
+ src/test-map.cc | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+commit 985b63b3eeee5be1f5234fc7f13077eacf5e5b94
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 13:33:07 2022 -0700
+
+    [map] Allow invalid items to be pointer to static object
+    
+    By derefencing them when necessary.
+    
+    Also, we do not rely on trivially-copyable, so remove that assertion.
+
+ src/hb-algs.hh |  7 +++++--
+ src/hb-map.hh  | 28 +++++++++++++---------------
+ 2 files changed, 18 insertions(+), 17 deletions(-)
+
+commit 98b26eedf5578b66f4ca1c173443942af831f195
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 13:12:10 2022 -0700
+
+    [check-static-inits] Only check library object files
+
+ src/check-static-inits.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1e27f95dc1e8c35c9b2acd60a3460d8c6f8edf31
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 13:10:47 2022 -0700
+
+    [algs] Add hb_coerce()
+
+ src/hb-algs.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 5a91db113507fa465f320438f1c68ca22bc0a2cd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 12:44:48 2022 -0700
+
+    [map] Remove constexpr invalid items
+    
+    These were non-workable in the general case, eg std::string.
+
+ src/hb-map.hh                | 3 ---
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 2 files changed, 1 insertion(+), 4 deletions(-)
+
+commit 114046dc27795514189f4af4e65be50238f3ca8e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 12:38:26 2022 -0700
+
+    [map] Construct objects
+
+ src/hb-map.hh | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+commit b15e497d4de5b04537217117137f7756dc535c2f
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Jan 13 14:10:23 2022 -0500
+
+    Fix the docs build
+    
+    This was inadvertendly broken in f956ecdbaffbb8643.
+    Sorry
+
+ docs/usermanual-object-model.xml | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit ca4f56bdc746d3d23f46898bd83c1b2c3d8250a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 11:48:34 2022 -0700
+
+    [map] Massage some more
+    
+    Towards being able to store arbitrary types.
+
+ src/hb-map.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit cfe2b66114fdbc2b61566bdc086ce41286a78aec
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 11:42:48 2022 -0700
+
+    [algs] Fix hash chaining to std::hash()
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 87496bf63ea7644733cdcc08f330a522597509a1
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Jan 13 11:03:45 2022 -0800
+
+    [subset] fix fuzzer timeout if visisted_paint goes into error.
+
+ src/hb-ot-color-colr-table.hh                             |   2 +-
+ ...z-testcase-minimized-hb-subset-fuzzer-4979711393005568 | Bin 0 -> 349 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 4ced2e8a8ad224f9a4abcc418632600af1194c11
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Jan 13 09:05:04 2022 -0500
+
+    docs: Add some details
+    
+    Mention immutability in the object model section.
+
+ docs/usermanual-object-model.xml | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit bb330c6aa6d56e29d08a3d6358aec70561defa49
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Jan 13 08:57:56 2022 -0500
+
+    docs: Fix a typo
+
+ docs/usermanual-object-model.xml | 42 ++++++++++++++++++++--------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+commit 16cfe34ae85c90754f5171428e4709ff784f8139
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 13 11:01:22 2022 -0700
+
+    [git.mk] Update
+
+ git.mk | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 0acf466c44143de2e9b9cc0375cb25ec67cb132f
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Jan 13 01:29:22 2022 +0200
+
+    [doc] Fix hb_font_set_synthetic_slant param name
+
+ src/hb-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fa12f1ae25014a8da9f1b8bef871f60460e27a6b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 12 15:08:34 2022 -0700
+
+    Rename method
+
+ src/hb-ot-layout-gsubgpos.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 9408e0d6d1a046fc6175eeca833852e86deb5d17
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 12 15:07:34 2022 -0700
+
+    Rename variable
+
+ src/hb-ot-layout-gsubgpos.hh | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit 96c969c82046560859df5cdebddb91d0488c6919
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 12 15:06:40 2022 -0700
+
+    Preserve glyph props
+
+ src/hb-ot-layout-gsubgpos.hh | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+commit 0b2c514fb48b26e2c8fc915b3702ba1b2c8b2b5e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 12 11:20:58 2022 -0700
+
+    More macro cleanup
+
+ src/hb-ot-shape-complex-arabic-win1256.hh | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+commit 0a42f46ce974bcc01b935f400ee2cdd9e3363e30
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 12 11:16:02 2022 -0700
+
+    Fix compiler warning
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3364
+
+ src/hb-ot-shape-complex-arabic-win1256.hh | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit 72f0b24ee3b138bc955430c5a7d71de669b219f0
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Wed Jan 12 13:08:02 2022 -0500
+
+    docs: Clarify variation apis (#3363)
+    
+    Make it explicit that the variations setters
+    replace all existing variations, even if
+    not all axes are included in the provided
+    values.
+    
+    Co-authored-by: Matthias Clasen <mclasen at redhat.com>
+
+ src/hb-font.cc | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit befe3b5d5ac4a88ffb880ca16ad1f3fbb225ae28
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Wed Jan 12 13:07:25 2022 -0500
+
+    color: Document empty returns (#3362)
+    
+    Document that the SVG and PNG getters return
+    the singleton empty blob if the glyph has no
+    color.
+    
+    Fixes: #1413
+    
+    Co-authored-by: Matthias Clasen <mclasen at redhat.com>
+
+ src/hb-ot-color.cc | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit 13643934aa9c957831ae76dfad3a2a00ee85c42a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 12 10:54:28 2022 -0700
+
+    Clean up HB_NO_SETLOCALE
+    
+    https://github.com/harfbuzz/harfbuzz/pull/3358#pullrequestreview-850500143
+
+ src/hb-common.cc | 47 +++++++++++++++++++++++++++--------------------
+ 1 file changed, 27 insertions(+), 20 deletions(-)
+
+commit 53847dba92d59b0c457bd1b468751d20cbbe105b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 10 15:04:47 2022 -0700
+
+    [algs] Call std::hash from hb_hash()
+
+ src/hb-algs.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 74811c501d7876dc72d1ee821c1ce26cdaa0750e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 10 14:57:38 2022 -0700
+
+    [map] Map == / != use correct types
+
+ src/hb-map.hh | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+commit b8c2c1ab3778755a23ea449ba334959693388687
+Author: Timo Suoranta <tksuoran at gmail.com>
+Date:   Tue Jan 11 13:14:44 2022 +0100
+
+    Use freetype from CMake target when present (#3361)
+    
+    Add check for Freetype CMake target. If it is found:
+    - enable HB_HAVE_FREETYPE option
+    - add HAVE_FREETYPE=1 define
+    - bypass finding Freetype as cmake package
+    - add Freetype CMake target as dependency to harfbuzz
+
+ CMakeLists.txt | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+commit ce7f19a2ccb04181b015005f9aa12381da606c63
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 10 14:40:27 2022 -0700
+
+    Revert "[map] Actually use k/v invalid types for declaration!"
+    
+    This reverts commit 6f559346ac70fd188cb22d41f4b03ec227feee25.
+    
+    Err. My bad.
+
+ src/hb-map.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 6f559346ac70fd188cb22d41f4b03ec227feee25
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 10 14:29:36 2022 -0700
+
+    [map] Actually use k/v invalid types for declaration!
+
+ src/hb-map.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a45a630539edb1d8554608e76a7a03160ecbd3a8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 8 15:47:33 2022 -0800
+
+    Fix unintentional locale dependency (#3358)
+    
+    Avoid unintentional locale dependency
+    
+    hb_variation_to_string uses sprintf with %g, which will produce
+    a locale-dependent decimal point, which is not desired here.
+    
+    The output is supposed to be compatible with CSS syntax, and
+    that always uses '.' for the decimal point.
+    
+    Fix this by changing the per-thread locale to "C" around sprintf call.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3355
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/3357
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/3358
+    
+    Co-authored-by: Matthias Clasen <mclasen at redhat.com>
+
+ configure.ac     |  4 ++--
+ meson.build      |  3 +++
+ src/hb-common.cc | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 3 files changed, 66 insertions(+), 5 deletions(-)
+
+commit d70825a6d18a4240876a75f107ef566f61bddf58
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 2 11:28:28 2022 -0500
+
+    docs: Add some details about coordinates
+    
+    Mention what the effective values are when
+    coordinates have not been set.
+
+ src/hb-font.cc | 29 ++++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 11 deletions(-)
+
+commit 0a5c1c970581fb8639d45a6f5a12443af89b7e12
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 4 14:18:38 2022 -0700
+
+    [failing-alloc] Make it compile as C++ as well
+
+ src/failing-alloc.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit bea5369c6d8f138c1d3113a1b60e1c6ea097a6e3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 4 10:52:05 2022 -0700
+
+    [buffer] Rename swap_buffers() to sync()
+
+ src/gen-vowel-constraints.py                 | 2 +-
+ src/hb-aat-layout-common.hh                  | 2 +-
+ src/hb-buffer.cc                             | 6 +++---
+ src/hb-buffer.hh                             | 2 +-
+ src/hb-ot-layout.cc                          | 2 +-
+ src/hb-ot-shape-complex-hangul.cc            | 2 +-
+ src/hb-ot-shape-complex-syllabic.cc          | 2 +-
+ src/hb-ot-shape-complex-thai.cc              | 2 +-
+ src/hb-ot-shape-complex-vowel-constraints.cc | 2 +-
+ src/hb-ot-shape-normalize.cc                 | 4 ++--
+ src/hb-ot-shape.cc                           | 2 +-
+ 11 files changed, 14 insertions(+), 14 deletions(-)
+
+commit c5e5d5e0bcdeb9256b445fe6378bd503083d5204
+Merge: 165a6073f d1e7df5c3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 4 07:33:59 2022 -0700
+
+    Merge pull request #3353 from harfbuzz/buffer-create-similar
+    
+    Add `hb_buffer_create_similar()`; use it in util
+
+commit d1e7df5c3f214b0f199fc2aff3e5645281fc5caa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 4 07:32:04 2022 -0700
+
+    [buffer] Add enter()/leave() pair around shape()
+
+ src/hb-buffer.cc   | 27 +++++++++++++++++++++++++++
+ src/hb-buffer.hh   | 13 +++++++++++--
+ src/hb-ot-shape.cc | 19 ++-----------------
+ 3 files changed, 40 insertions(+), 19 deletions(-)
+
+commit 43be5ba442548528c89ad31c0927cc68515b736e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 4 07:26:53 2022 -0700
+
+    [buffer] Group shape-related members together
+
+ src/hb-buffer.cc    |  5 ++---
+ src/hb-buffer.hh    | 14 ++++++--------
+ src/hb-ot-layout.hh |  5 ++---
+ src/hb-ot-shape.cc  |  2 ++
+ 4 files changed, 12 insertions(+), 14 deletions(-)
+
+commit 52f5711ed0354b0c5d396255886f03048997bbd9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 3 11:57:42 2022 -0700
+
+    [buffer] Add hb_buffer_create_similar()
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1555
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-buffer.cc           | 73 ++++++++++++++++++++++++++++++++++------------
+ src/hb-buffer.h            | 12 ++++++--
+ src/hb-buffer.hh           |  1 +
+ util/shape-options.hh      | 13 ++-------
+ 5 files changed, 68 insertions(+), 32 deletions(-)
+
+commit f643b81ffc4d4dd6a100f83ff7bc618dfb7f5b69
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 3 11:45:31 2022 -0700
+
+    [buffer] Clean up internal state bookkeeping
+    
+    hb_buffer_reset() was NOT resetting cluster_level. Ouch! Fix that.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1555
+
+ src/hb-buffer.cc | 15 ++++++++-------
+ src/hb-buffer.hh | 25 ++++++++++++++++++-------
+ 2 files changed, 26 insertions(+), 14 deletions(-)
+
+commit d0c3515ce423f689123f96111b105e7e4141a6b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 3 11:26:41 2022 -0700
+
+    [util] Copy unicode_funcs in copy_buffer_properties()
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1555
+
+ util/shape-options.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 34f5b855aa39cc5ac59fb7cd3e9e3a48507e1a08
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 3 11:25:06 2022 -0700
+
+    [util] Simplify copy_buffer_properties()
+    
+    Now that hb_buffer_append() overlays segment_properties we can do this.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1555
+
+ util/shape-options.hh | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 101d07efd9a11b1f215b913205d2560ee0df9135
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 3 11:24:07 2022 -0700
+
+    [util] Move copy_buffer_properties() out of loop
+    
+    Now that hb_buffer_append() overlays properties, we can do this.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1555
+
+ util/shape-options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 36e9f467a43d18f5b040e2bd47c87f271916a73f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 3 11:23:14 2022 -0700
+
+    [buffer] Overlay segment-properties in hb_buffer_append()
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1555
+
+ src/hb-buffer.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 6a66992842dea6e3ad9c717a3fa047341ab50af6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 3 11:21:29 2022 -0700
+
+    Add hb_segment_properties_overlay()
+    
+    New API:
+    + hb_segment_properties_overlay()
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-buffer.cc           | 39 +++++++++++++++++++++++++++++++++++++++
+ src/hb-buffer.h            |  3 +++
+ 3 files changed, 43 insertions(+)
+
+commit 165a6073faf347bb2d622472f1f104b7865398e5
+Merge: a3265e1e0 3fc2e654c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 12:02:20 2022 -0700
+
+    Merge pull request #3338 from harfbuzz/slant
+    
+    [font] Add public API for synthetic slant
+
+commit 3fc2e654c0eca9566b184fd64c682114f99b2093
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 11:56:45 2022 -0700
+
+    [metrics] Fix slant calc
+
+ src/hb-ot-metrics.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a7751277e9e8982093928e762ac9eecc42820444
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 11:50:02 2022 -0700
+
+    [docs] Add hb_font_[gs]et_synthetic_slant()
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-font.cc             | 14 ++++++++++----
+ 2 files changed, 12 insertions(+), 4 deletions(-)
+
+commit 4ab94443bbe80a354daa2d94e496c13f096501ad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 11:26:45 2022 -0700
+
+    [metrics] Ouch. Fix slant code
+
+ src/hb-ot-metrics.cc | 27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+commit f7d49d9c2b9899f9caeeff766714631918129d2c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 11:16:33 2022 -0700
+
+    [metrics] Simplify
+
+ src/hb-ot-metrics.cc | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit f1ba1f940f407efd192cb2d6bd4b7eee20aedf96
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 10:58:25 2022 -0700
+
+    [metrics] Only scale caret rise/run if font is slanted
+
+ src/hb-ot-metrics.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 45c2b6e384e3359a54f40e4b02df9fffe27b0def
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 10:55:11 2022 -0700
+
+    [metrics] Harden math
+
+ src/hb-ot-metrics.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fa008a021fbd3c432499ac9316fa75a7f5a4ea02
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 10:46:38 2022 -0700
+
+    [metrics] Implement synthetic slant for caret slope
+    
+    Part of https://github.com/harfbuzz/harfbuzz/pull/3338
+
+ src/hb-ot-metrics.cc | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+commit fc329f665fab56c2983ababf2ebc71088b2ecfcc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 10:41:41 2022 -0700
+
+    [metrics] Scale up horizontal caret rise/run
+    
+    Eg. if rise/run are 1/0, we now return upem/0. This is equivalent.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/pull/3338
+
+ src/hb-ot-metrics.cc | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+commit a3265e1e07f8d00e5dbd5ae89e0b500b1469575a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 10:02:41 2022 -0700
+
+    Typo
+
+ docs/harfbuzz-sections.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0df83f52a126aa1c89e4dd8478f3a535805bd6ac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 08:01:11 2022 -0700
+
+    Fix test
+
+ src/gen-def.py | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 6356da88ee4b0926b4fb2bc3b70352633124d05f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 07:55:56 2022 -0700
+
+    [docs] Update
+
+ docs/harfbuzz-sections.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 5b87c30d6b192092008e578fb5f3148fb96ab09a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 07:53:45 2022 -0700
+
+    [font] Mark hb_font_get_var_coords_design() non-experimental
+    
+    Any remaining issue with the API will address later by deprecating it.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1865
+
+ src/hb-font.cc | 4 +---
+ src/hb-font.h  | 2 --
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+commit 2d42fc9fbb9ddb7c9bd53b06a7ef70ef6f459399
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 2 07:45:10 2022 -0700
+
+    [font] Load named-instance if face index top bits are set
+    
+    This matches FreeType behavior.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3348
+
+ src/hb-face.cc |  4 ++++
+ src/hb-font.cc | 10 ++++++++++
+ 2 files changed, 14 insertions(+)
+
+commit da7dba0002616eab73b7dd1621274992ce6eb2aa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 1 11:20:20 2022 -0700
+
+    [face] Clarify face_index handling
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3347
+
+ src/hb-face.cc | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+commit 6da4b80e5f303bf40c295c4888ba3dc48bd28f4b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 22 21:51:03 2021 -0700
+
+    [hb-ot-var] Specify normalized 2.14 docs
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3345
+
+ src/hb-ot-var.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 1b51be57dcd3f964ab7503b5261294e673892991
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 22 21:43:48 2021 -0700
+
+    [hb-ot-var] Actually set in/out argument
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/3344
+
+ src/hb-ot-var-fvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 06ee40213cb98fe1589c1712d80380c19d2bbc50
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 21 14:14:09 2021 -0700
+
+    Use invisible-glyph for spaces if font has no ASCII space
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3340
+    
+    Should add tests ideally.
+
+ src/hb-ot-shape-fallback.cc  | 9 +++++++++
+ src/hb-ot-shape-normalize.cc | 3 ++-
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+commit 602bd39680e6c337309516d6b5086834a35a7609
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 19 21:40:25 2021 -0800
+
+    [style] Adjust font slant angle for synthetic slant value
+    
+    Part of https://github.com/harfbuzz/harfbuzz/pull/3338
+
+ src/hb-style.cc | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+commit ff697debd8e55d8858a2f199ae06f7a9f33a5991
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 19 07:25:37 2021 -0700
+
+    [GPOS] Apply font synthetic slant
+    
+    Part of fixing https://github.com/harfbuzz/harfbuzz/issues/3196
+
+ src/hb-font.cc                 |  1 +
+ src/hb-font.hh                 |  2 ++
+ src/hb-ot-layout-gpos-table.hh | 11 +++++++++--
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+commit 810f5d71c71ab59f4b1257e18b81551de49f3ee5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 18 15:12:26 2021 -0700
+
+    [font] Add public API for slant
+    
+    Not hooked up internally to anything.
+    
+    New API:
+    
+    + hb_font_set_synthetic_slant()
+    + hb_font_get_synthetic_slant()
+    
+    Part of fixing https://github.com/harfbuzz/harfbuzz/issues/3196
+
+ src/hb-font.cc | 41 ++++++++++++++++++++++++++++++++++++++++-
+ src/hb-font.h  |  6 ++++++
+ src/hb-font.hh |  1 +
+ 3 files changed, 47 insertions(+), 1 deletion(-)
+
+commit 067f90a82087a5feb1cf76625c54c60a10946fe1
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Dec 14 16:24:38 2021 -0800
+
+    [subset] Fix for fuzzer timeout.
+    
+    Fixes https://oss-fuzz.com/testcase-detail/5549945449480192
+    
+    In prune_langsys: move LangSys visited check up before any work is done for a LangSys. In this particular case the compare() method is responsible for the majority of the time spent and wasn't being guarded with a visisted check.
+
+ src/hb-ot-layout-common.hh                             |  10 +++++++---
+ ...estcase-minimized-hb-subset-fuzzer-5549945449480192 | Bin 0 -> 562733 bytes
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+commit c4573c2ec793dc9a124654f0d0d349df7787fa45
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Dec 14 14:49:15 2021 -0800
+
+    [repacker] don't infinite loop if visited or roots is in error.
+    
+    Fixes https://oss-fuzz.com/testcase-detail/5205038086094848
+
+ src/hb-repacker.hh                                     |   7 +++++++
+ ...estcase-minimized-hb-subset-fuzzer-5205038086094848 | Bin 0 -> 129192 bytes
+ 2 files changed, 7 insertions(+)
+
+commit 449c4296a11a8b3d3882d4a4d6705281f5ff52e5
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Dec 12 07:50:06 2021 +0200
+
+    [ci] Try harder to fix this randomly failing job
+    
+    The default --num-processes is the number of CPUs multiplied by 5,
+    which seems to give this VM a hard-time. Even the number of CPUs is too
+    much, so lets use half of that (I’m adding one just in case the division
+    gives zero).
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 52a33a15a409550fdc6496cfcb16168b371e2aaf
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Dec 12 07:43:58 2021 +0200
+
+    [ci] Try to fix the randomly failing valgrind job
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit be91d2917d9860326cb5fd1d03ffe1042a72f6d3
 Author: Khaled Hosny <khaled at aliftype.com>
 Date:   Sun Dec 12 04:45:54 2021 +0200

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,7 +1,77 @@
+Overview of changes leading to 3.4.0
+Sunday, February 13, 2022
+====================================
+- Perform sanity checks on shaping results is now part of “harfbuzz” library
+  and can be enabled by setting the buffer flag HB_BUFFER_FLAG_VERIFY.
+  (Behdad Esfahbod)
+- Arabic Mark Transient Reordering Algorithm have been updated to revision 6.
+  (Khaled Hosny)
+- ISO 15924 code for mathematical notation, ‘Zmth’, now maps to the OpenType
+  ‘math’ tag. (Alexis King)
+- It is now possible to get at once all math kerning values for a given glyph
+  at a given corner. (Alexis King)
+- Fix locale_t portability issues on systems the typdef’s it to a void pointer.
+  (Behdad Esfahbod)
+
+- New API:
++HB_BUFFER_FLAG_VERIFY
++HB_OT_TAG_MATH_SCRIPT
++HB_SCRIPT_MATH
++hb_ot_math_kern_entry_t
++hb_ot_math_get_glyph_kernings
+
+- Deprecated API
++HB_OT_MATH_SCRIPT
+
+
+Overview of changes leading to 3.3.2
+Sunday, February 6, 2022
+====================================
+- Revert splitting of pair positioning values introduced in 3.3.0 as it proved
+  problematic. (Behdad Esfahbod)
+
+
+Overview of changes leading to 3.3.1
+Monday, January 31, 2022
+====================================
+- Fix heap-use-after-free in harfbuzz-subset introduced in previous release.
+  (Garret Rieger)
+
+
+Overview of changes leading to 3.3.0
+Monday, January 31, 2022
+====================================
+- Improved documentation. (Matthias Clasen)
+- Internal code cleanup, using C++ standard library more. (Behdad Esfahbod)
+- The low 16-bits of face index will be used by hb_face_create() to select a
+  face inside a font collection file format, while the high 16-bits will be
+  used by hb_font_create() to load the named instance. (Behdad Esfahbod)
+- Glyph positions and other font metrics now apply synthetic slant set by
+  hb_font_set_synthetic_slant(), for improved positioning for synthetically
+  slanted fonts. (Behdad Esfahbod)
+- Fixed unintentional locale dependency in hb_variation_to_string() for decimal
+  point representation. (Matthias Clasen)
+- When applying pair positioning (kerning) the positioning value is split
+  between the two sides of the pair for improved cursor positioning between
+  such pairs. (Behdad Esfahbod)
+- Introduced new HB_GLYPH_FLAG_UNSAFE_TO_CONCAT, to be used in conjunction
+  with HB_GLYPH_FLAG_UNSAFE_TO_BREAK for optimizing re-shaping during line
+  breaking. Check the documentation for further details. (Behdad Esfahbod)
+- Improved handling of macrolanguages when mapping BCP 47 codes to OpenType
+  tags. (David Corbett)
+
+- New API:
++HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
++hb_segment_properties_overlay()
++hb_buffer_create_similar()
++hb_font_set_synthetic_slant()
++hb_font_get_synthetic_slant()
++hb_font_get_var_coords_design()
+
+
 Overview of changes leading to 3.2.0
 Friday, November 26, 2021
 ====================================
-
 “harfbuzz” library improvements:
 - Fixed shaping of Apple Color Emoji flags in right-to-left context. (Behdad Esfahbod)
 - Fixed positioning of CFF fonts in HB_TINY profile. (Behdad Esfahbod)
@@ -384,7 +454,7 @@
   code-base changes.  We now require C++11.  Support for gcc 4.8 and earlier has been
   dropped.
 - New hb-config.hh facility for compiling smaller library for embedded and web usecases.
-- New Unicode Character Databse implementation that is half the size of previously-used
+- New Unicode Character Database implementation that is half the size of previously-used
   UCDN.
 - Subsetter improvements.
 - Improved documentation, thanks to Nathan Willis.
@@ -1232,7 +1302,7 @@
   due to bug in glyph class of ASCII double-quote character.  This should
   address "regression" introduced in 1.2.0 when we switched mark zeroing
   in most shapers from BY_UNICODE_LATE to BY_GDEF_LATE.
-  This fourth release in a week should finally stablize things...
+  This fourth release in a week should finally stabilize things...
 
 - hb-ot-font's get_glyph() implementation saw some optimizations.  Though,
   might be really hard to measure in real-world situations.
@@ -2280,7 +2350,7 @@
   - hb_buffer_create() takes zero arguments now.
     Use hb_buffer_pre_allocate() to pre-allocate.
 
-  - hb_buffer_add_utf*() now accept -1 for length parameteres,
+  - hb_buffer_add_utf*() now accept -1 for length parameters,
     meaning "nul-terminated".
 
   - hb_direction_t enum values changed.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md	2022-02-13 03:14:24 UTC (rev 61999)
@@ -28,7 +28,7 @@
 - [ ] Commit NEWS, meson.build, configure.ac, and src/hb-version.h, as well as any REPLACEME changes you made.
         The commit message is simply the release number, e. g. "1.4.7"
 
-- [ ] Do a `meson dist -Cbuild` that runs the tests against the latest commited changes.
+- [ ] Do a `meson dist -Cbuild` that runs the tests against the latest committed changes.
    If doesn't pass, something fishy is going on, reset the repo and start over.
 
 - [ ] Tag the release and sign it: e.g. `git tag -s 1.4.7 -m 1.4.7`.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2022-02-13 03:14:24 UTC (rev 61999)
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the `mprotect' function. */
 #undef HAVE_MPROTECT
 
+/* Define to 1 if you have the `newlocale' function. */
+#undef HAVE_NEWLOCALE
+
 /* Have POSIX threads */
 #undef HAVE_PTHREAD
 
@@ -117,6 +120,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the `uselocale' function. */
+#undef HAVE_USELOCALE
+
 /* Define to 1 if you have the <usp10.h> header file. */
 #undef HAVE_USP10_H
 
@@ -123,6 +129,9 @@
 /* Define to 1 if you have the <windows.h> header file. */
 #undef HAVE_WINDOWS_H
 
+/* Define to 1 if you have the <xlocale.h> header file. */
+#undef HAVE_XLOCALE_H
+
 /* Define to the sub-directory where libtool stores uninstalled libraries. */
 #undef LT_OBJDIR
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [3.2.0],
+        [3.4.0],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
@@ -68,8 +68,8 @@
 ])
 
 # Functions and headers
-AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty)
-AC_CHECK_HEADERS(unistd.h sys/mman.h stdbool.h)
+AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale uselocale)
+AC_CHECK_HEADERS(unistd.h sys/mman.h stdbool.h xlocale.h)
 
 # Compiler flags
 AC_CANONICAL_HOST

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,6 +1,6 @@
 project('harfbuzz', 'c', 'cpp',
   meson_version: '>= 0.55.0',
-  version: '3.2.0',
+  version: '3.4.0',
   default_options: [
     'cpp_rtti=false',       # Just to support msvc, we are passing -fno-exceptions also anyway
     'cpp_std=c++11',
@@ -57,10 +57,17 @@
   endif
 endif
 
+if host_machine.system() == 'windows'
+  add_project_arguments(cpp.get_supported_arguments([
+    '-Wa,-mbig-obj'
+  ]), language : 'cpp')
+endif
+
 check_headers = [
   ['unistd.h'],
   ['sys/mman.h'],
   ['stdbool.h'],
+  ['xlocale.h'],
 ]
 
 check_funcs = [
@@ -70,6 +77,8 @@
   ['getpagesize'],
   ['mmap'],
   ['isatty'],
+  ['uselocale'],
+  ['newlocale'],
 ]
 
 m_dep = cpp.find_library('m', required: false)
@@ -87,15 +96,12 @@
   if not freetype_dep.found()
     # https://github.com/harfbuzz/harfbuzz/pull/2498
     freetype_dep = dependency('freetype2', required: get_option('freetype'),
-                              fallback: ['freetype2', 'freetype_dep'],
                               default_options: ['harfbuzz=disabled'])
   endif
 endif
 
-glib_dep = dependency('glib-2.0', required: get_option('glib'),
-                      fallback: ['glib', 'libglib_dep'])
-gobject_dep = dependency('gobject-2.0', required: get_option('gobject'),
-                         fallback: ['glib', 'libgobject_dep'])
+glib_dep = dependency('glib-2.0', required: get_option('glib'))
+gobject_dep = dependency('gobject-2.0', required: get_option('gobject'))
 graphite2_dep = dependency('graphite2', required: get_option('graphite2'))
 graphite_dep = dependency('graphite2', required: get_option('graphite'))
 
@@ -123,6 +129,13 @@
   endif
 endif
 
+if icu_dep.found() and icu_dep.type_name() == 'pkgconfig'
+  icu_defs = icu_dep.get_variable(pkgconfig: 'DEFS', default_value: '')
+  if icu_defs != ''
+    add_project_arguments(icu_defs, language: ['c', 'cpp'])
+  endif
+endif
+
 cairo_dep = null_dep
 cairo_ft_dep = null_dep
 if not get_option('cairo').disabled()
@@ -145,8 +158,8 @@
     # dependency cycle here because we have configured freetype2 above with
     # harfbuzz support disabled, so when cairo will lookup freetype2 dependency
     # it will be forced to use that one.
-    cairo_dep = dependency('cairo', fallback: 'cairo', required: get_option('cairo'))
-    cairo_ft_dep = dependency('cairo-ft', fallback: 'cairo', required: get_option('cairo'))
+    cairo_dep = dependency('cairo', required: get_option('cairo'))
+    cairo_ft_dep = dependency('cairo-ft', required: get_option('cairo'))
   endif
 endif
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2022-02-13 03:14:24 UTC (rev 61999)
@@ -345,15 +345,17 @@
 COMPILED_TESTS = \
 	test-algs \
 	test-array \
+	test-bimap \
 	test-iter \
+	test-machinery \
 	test-map \
 	test-number \
 	test-ot-tag \
 	test-priority-queue \
 	test-set \
+	test-serialize \
 	test-unicode-ranges \
 	test-vector \
-	test-bimap \
 	test-repacker \
 	$(NULL)
 COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
@@ -369,18 +371,18 @@
 test_array_CPPFLAGS = $(HBCFLAGS)
 test_array_LDADD = libharfbuzz.la $(HBLIBS)
 
-test_priority_queue_SOURCES = test-priority-queue.cc hb-static.cc
-test_priority_queue_CPPFLAGS = $(HBCFLAGS)
-test_priority_queue_LDADD = libharfbuzz.la $(HBLIBS)
+test_bimap_SOURCES = test-bimap.cc hb-static.cc
+test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_bimap_LDADD = $(COMPILED_TESTS_LDADD)
 
-test_repacker_SOURCES = test-repacker.cc hb-static.cc
-test_repacker_CPPFLAGS = $(HBCFLAGS)
-test_repacker_LDADD = libharfbuzz.la libharfbuzz-subset.la $(HBLIBS)
-
 test_iter_SOURCES = test-iter.cc hb-static.cc
 test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_iter_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_machinery_SOURCES = test-machinery.cc hb-static.cc
+test_machinery_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_machinery_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_map_SOURCES = test-map.cc hb-static.cc
 test_map_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_map_LDADD = $(COMPILED_TESTS_LDADD)
@@ -393,10 +395,22 @@
 test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_priority_queue_SOURCES = test-priority-queue.cc hb-static.cc
+test_priority_queue_CPPFLAGS = $(HBCFLAGS)
+test_priority_queue_LDADD = libharfbuzz.la $(HBLIBS)
+
+test_repacker_SOURCES = test-repacker.cc hb-static.cc
+test_repacker_CPPFLAGS = $(HBCFLAGS)
+test_repacker_LDADD = libharfbuzz.la libharfbuzz-subset.la $(HBLIBS)
+
 test_set_SOURCES = test-set.cc hb-static.cc
 test_set_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_set_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_serialize_SOURCES = test-serialize.cc hb-static.cc
+test_serialize_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_serialize_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_unicode_ranges_SOURCES = test-unicode-ranges.cc
 test_unicode_ranges_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_unicode_ranges_LDADD = $(COMPILED_TESTS_LDADD)
@@ -405,10 +419,6 @@
 test_vector_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_vector_LDADD = $(COMPILED_TESTS_LDADD)
 
-test_bimap_SOURCES = test-bimap.cc hb-static.cc
-test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
-test_bimap_LDADD = $(COMPILED_TESTS_LDADD)
-
 dist_check_SCRIPTS = \
 	check-c-linkage-decls.py \
 	check-externs.py \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2022-02-13 03:14:24 UTC (rev 61999)
@@ -25,6 +25,7 @@
 	hb-blob.cc \
 	hb-blob.hh \
 	hb-buffer-serialize.cc \
+	hb-buffer-verify.cc \
 	hb-buffer.cc \
 	hb-buffer.hh \
 	hb-cache.hh \
@@ -50,7 +51,6 @@
 	hb-map.cc \
 	hb-map.hh \
 	hb-meta.hh \
-	hb-ms-feature-ranges.cc \
 	hb-ms-feature-ranges.hh \
 	hb-mutex.hh \
 	hb-null.hh \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.py	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.py	2022-02-13 03:14:24 UTC (rev 61999)
@@ -14,7 +14,7 @@
 	print ('check-static-inits.py: needs python 3.5 for recursive support in glob')
 	sys.exit (77)
 
-OBJS = glob.glob (os.path.join (builddir, libs, '**', '*.o'), recursive=True)
+OBJS = glob.glob (os.path.join (builddir, libs, '**', 'hb*.o'), recursive=True)
 if not OBJS:
 	print ('check-static-inits.py: object files not found; skipping test')
 	sys.exit (77)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py	2022-02-13 03:14:24 UTC (rev 61999)
@@ -35,8 +35,7 @@
 hb_draw_funcs_set_cubic_to_func
 hb_draw_funcs_set_line_to_func
 hb_draw_funcs_set_move_to_func
-hb_draw_funcs_set_quadratic_to_func
-hb_font_get_var_coords_design""".splitlines ()
+hb_draw_funcs_set_quadratic_to_func""".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-os2-unicode-ranges.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 """Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh
-Input is a tab seperated list of unicode ranges from the otspec
+Input is a tab separated list of unicode ranges from the otspec
 (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur).
 """
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	2022-02-13 03:14:24 UTC (rev 61999)
@@ -329,6 +329,10 @@
 		from_bcp_47 (DefaultDict[str, AbstractSet[str]]): ``to_bcp_47``
 			inverted. Its values start as unsorted sets;
 			``sort_languages`` converts them to sorted lists.
+		from_bcp_47_uninherited (Optional[Dict[str, AbstractSet[str]]]):
+			A copy of ``from_bcp_47``. It starts as ``None`` and is
+			populated at the beginning of the first call to
+			``inherit_from_macrolanguages``.
 
 	"""
 	def __init__ (self):
@@ -338,6 +342,7 @@
 		self.ranks = collections.defaultdict (int)
 		self.to_bcp_47 = collections.defaultdict (set)
 		self.from_bcp_47 = collections.defaultdict (set)
+		self.from_bcp_47_uninherited = None
 		# Whether the parser is in a <td> element
 		self._td = False
 		# Whether the parser is after a <br> element within the current <tr> element
@@ -462,30 +467,51 @@
 		explicit mapping, so it inherits from sq (Albanian) the mapping
 		to SQI.
 
+		However, if an OpenType tag maps to a BCP 47 macrolanguage and
+		some but not all of its individual languages, the mapping is not
+		inherited from the macrolanguage to the missing individual
+		languages. For example, INUK (Nunavik Inuktitut) is mapped to
+		ike (Eastern Canadian Inuktitut) and iu (Inuktitut) but not to
+		ikt (Inuinnaqtun, which is an individual language of iu), so
+		this method does not add a mapping from ikt to INUK.
+
 		If a BCP 47 tag for a macrolanguage has no OpenType mapping but
-		all of its individual languages do and they all map to the same
-		tags, the mapping is copied to the macrolanguage.
+		some of its individual languages do, their mappings are copied
+		to the macrolanguage.
 		"""
 		global bcp_47
-		original_ot_from_bcp_47 = dict (self.from_bcp_47)
+		first_time = self.from_bcp_47_uninherited is None
+		if first_time:
+			self.from_bcp_47_uninherited = dict (self.from_bcp_47)
 		for macrolanguage, languages in dict (bcp_47.macrolanguages).items ():
-			ot_macrolanguages = set (original_ot_from_bcp_47.get (macrolanguage, set ()))
+			ot_macrolanguages = {
+				ot_macrolanguage for ot_macrolanguage in self.from_bcp_47_uninherited.get (macrolanguage, set ())
+			}
+			blocked_ot_macrolanguages = set ()
+			if 'retired code' not in bcp_47.scopes.get (macrolanguage, ''):
+				for ot_macrolanguage in ot_macrolanguages:
+					round_trip_macrolanguages = {
+						l for l in self.to_bcp_47[ot_macrolanguage]
+						if 'retired code' not in bcp_47.scopes.get (l, '')
+					}
+					round_trip_languages = {
+						l for l in languages
+						if 'retired code' not in bcp_47.scopes.get (l, '')
+					}
+					intersection = round_trip_macrolanguages & round_trip_languages
+					if intersection and intersection != round_trip_languages:
+						blocked_ot_macrolanguages.add (ot_macrolanguage)
 			if ot_macrolanguages:
 				for ot_macrolanguage in ot_macrolanguages:
-					for language in languages:
-						self.add_language (language, ot_macrolanguage)
-						self.ranks[ot_macrolanguage] += 1
-			else:
+					if ot_macrolanguage not in blocked_ot_macrolanguages:
+						for language in languages:
+							self.add_language (language, ot_macrolanguage)
+							if not blocked_ot_macrolanguages:
+								self.ranks[ot_macrolanguage] += 1
+			elif first_time:
 				for language in languages:
-					if language in original_ot_from_bcp_47:
-						if ot_macrolanguages:
-							ml = original_ot_from_bcp_47[language]
-							if ml:
-								ot_macrolanguages &= ml
-							else:
-								pass
-						else:
-							ot_macrolanguages |= original_ot_from_bcp_47[language]
+					if language in self.from_bcp_47_uninherited:
+						ot_macrolanguages |= self.from_bcp_47_uninherited[language]
 					else:
 						ot_macrolanguages.clear ()
 					if not ot_macrolanguages:
@@ -570,7 +596,7 @@
 						if scope == 'macrolanguage':
 							scope = ' [macrolanguage]'
 						elif scope == 'collection':
-							scope = ' [family]'
+							scope = ' [collection]'
 						else:
 							continue
 						self.scopes[subtag] = scope
@@ -715,6 +741,7 @@
 
 ot.add_language ('oc-provenc', 'PRO')
 
+ot.remove_language_ot ('QUZ')
 ot.add_language ('qu', 'QUZ')
 ot.add_language ('qub', 'QWH')
 ot.add_language ('qud', 'QVI')
@@ -747,7 +774,6 @@
 ot.add_language ('qxt', 'QWH')
 ot.add_language ('qxw', 'QWH')
 
-bcp_47.macrolanguages['ro'].remove ('mo')
 bcp_47.macrolanguages['ro-MD'].add ('mo')
 
 ot.remove_language_ot ('SYRE')
@@ -987,6 +1013,8 @@
 	if initial != 'und':
 		continue
 	for lt, tags in items:
+		if not tags:
+			continue
 		if lt.variant in bcp_47.prefixes:
 			expect (next (iter (bcp_47.prefixes[lt.variant])) == lt.language,
 					'%s is not a valid prefix of %s' % (lt.language, lt.variant))
@@ -1021,6 +1049,8 @@
 		continue
 	print ("  case '%s':" % initial)
 	for lt, tags in items:
+		if not tags:
+			continue
 		print ('    if (', end='')
 		script = lt.script
 		region = lt.region
@@ -1121,9 +1151,13 @@
 		elif len (primary_tags) == 0:
 			expect (ot_tag not in disambiguation, 'There is no possible valid disambiguation for %s' % ot_tag)
 		else:
-			macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [macrolanguage]')
+			original_languages = [t for t in primary_tags if t in ot.from_bcp_47_uninherited and 'retired code' not in bcp_47.scopes.get (t, '')]
+			if len (original_languages) == 1:
+				macrolanguages = original_languages
+			else:
+				macrolanguages = [t for t in primary_tags if bcp_47.scopes.get (t) == ' [macrolanguage]']
 			if len (macrolanguages) != 1:
-				macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [family]')
+				macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [collection]')
 			if len (macrolanguages) != 1:
 				macrolanguages = list (t for t in primary_tags if 'retired code' not in bcp_47.scopes.get (t, ''))
 			if len (macrolanguages) != 1:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py	2022-02-13 03:14:24 UTC (rev 61999)
@@ -220,7 +220,7 @@
 print ('    default:')
 print ('      break;')
 print ('  }')
-print ('  buffer->swap_buffers ();')
+print ('  buffer->sync ();')
 print ('}')
 
 print ()

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -2,6 +2,7 @@
 #include "hb-aat-map.cc"
 #include "hb-blob.cc"
 #include "hb-buffer-serialize.cc"
+#include "hb-buffer-verify.cc"
 #include "hb-buffer.cc"
 #include "hb-common.cc"
 #include "hb-draw.cc"
@@ -9,7 +10,6 @@
 #include "hb-fallback-shape.cc"
 #include "hb-font.cc"
 #include "hb-map.cc"
-#include "hb-ms-feature-ranges.cc"
 #include "hb-number.cc"
 #include "hb-ot-cff1-table.cc"
 #include "hb-ot-cff2-table.cc"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -839,7 +839,7 @@
     }
 
     if (!c->in_place)
-      buffer->swap_buffers ();
+      buffer->sync ();
   }
 
   public:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -146,7 +146,7 @@
   HBUINT32	variationAxis;	/* The 4-byte tag identifying the ductile axis.
 				 * This would normally be 0x64756374 ('duct'),
 				 * but you may use any axis the font contains. */
-  HBFixed	minimumLimit;	/* The lowest value for the ductility axis tha
+  HBFixed	minimumLimit;	/* The lowest value for the ductility axis that
 				 * still yields an acceptable appearance. Normally
 				 * this will be 1.0. */
   HBFixed	noStretchValue; /* This is the default value that corresponds to

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -36,6 +36,7 @@
 
 #include <algorithm>
 #include <initializer_list>
+#include <functional>
 #include <new>
 
 /*
@@ -210,13 +211,30 @@
 }
 HB_FUNCOBJ (hb_bool);
 
+template <typename T>
+static inline
+T hb_coerce (const T v) { return v; }
+template <typename T, typename V,
+	  hb_enable_if (!hb_is_same (hb_decay<T>, hb_decay<V>) && std::is_pointer<V>::value)>
+static inline
+T hb_coerce (const V v) { return *v; }
+
 struct
 {
   private:
 
   template <typename T> constexpr auto
-  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+  impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
 
+/* Sadly, we must give further hints to VS2015 to build the following template item */
+#if !defined (_MSC_VER) || defined (__clang__) || (_MSC_VER >= 1910)
+  template <typename T> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
+#else
+  template <typename T> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v).hash ())>>{} (hb_deref (v)))
+#endif
+
   template <typename T,
 	    hb_enable_if (std::is_integral<T>::value)> constexpr auto
   impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
@@ -435,23 +453,29 @@
   private:
 
   template <typename T1, typename T2> auto
-  impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
+  impl (T1&& v1, T2 &&v2, hb_priority<3>) const HB_AUTO_RETURN
   (
     std::forward<T2> (v2).cmp (std::forward<T1> (v1)) == 0
   )
 
   template <typename T1, typename T2> auto
-  impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
+  impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
   (
     std::forward<T1> (v1).cmp (std::forward<T2> (v2)) == 0
   )
 
   template <typename T1, typename T2> auto
-  impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
+  impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
   (
     std::forward<T1> (v1) == std::forward<T2> (v2)
   )
 
+  template <typename T1, typename T2> auto
+  impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    std::forward<T2> (v2) == std::forward<T1> (v1)
+  )
+
   public:
 
   template <typename T1, typename T2> auto
@@ -472,6 +496,10 @@
   typedef T2 second_t;
   typedef hb_pair_t<T1, T2> pair_t;
 
+  template <typename U1 = T1, typename U2 = T2,
+	    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) {}
 
   template <typename Q1, typename Q2,
@@ -870,7 +898,7 @@
 #pragma GCC diagnostic ignored "-Wcast-align"
     V* p = (V*) (((const char *) base) + (mid * stride));
 #pragma GCC diagnostic pop
-    int c = compar ((const void *) hb_addressof (key), (const void *) p, ds...);
+    int c = compar ((const void *) std::addressof (key), (const void *) p, ds...);
     if (c < 0)
       max = mid - 1;
     else if (c > 0)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -412,7 +412,7 @@
   return true;
 }
 
-/* TODO Specialize opeator== for hb_bytes_t and hb_ubytes_t. */
+/* TODO Specialize operator== for hb_bytes_t and hb_ubytes_t. */
 
 template <>
 inline uint32_t hb_array_t<const char>::hash () const {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -33,20 +33,6 @@
 /* Bi-directional map */
 struct hb_bimap_t
 {
-  /* XXX(remove) */
-  void init ()
-  {
-    forw_map.init ();
-    back_map.init ();
-  }
-
-  /* XXX(remove) */
-  void fini ()
-  {
-    forw_map.fini ();
-    back_map.fini ();
-  }
-
   void reset ()
   {
     forw_map.reset ();

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -0,0 +1,421 @@
+/*
+ * 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.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb.hh"
+
+#ifndef HB_NO_BUFFER_VERIFY
+
+#include "hb-buffer.hh"
+
+
+#define BUFFER_VERIFY_ERROR "buffer verify error: "
+static inline void
+buffer_verify_error (hb_buffer_t *buffer,
+		     hb_font_t *font,
+		     const char *fmt,
+		     ...) HB_PRINTF_FUNC(3, 4);
+
+static inline void
+buffer_verify_error (hb_buffer_t *buffer,
+		     hb_font_t *font,
+		     const char *fmt,
+		     ...)
+{
+  va_list ap;
+  va_start (ap, fmt);
+  if (buffer->messaging ())
+  {
+    buffer->message_impl (font, fmt, ap);
+  }
+  else
+  {
+    fprintf (stderr, "harfbuzz ");
+    vfprintf (stderr, fmt, ap);
+    fprintf (stderr, "\n");
+  }
+  va_end (ap);
+}
+
+static bool
+buffer_verify_monotone (hb_buffer_t *buffer,
+			hb_font_t   *font)
+{
+  /* Check that clusters are monotone. */
+  if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES ||
+      buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
+  {
+    bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer));
+
+    unsigned int num_glyphs;
+    hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs);
+
+    for (unsigned int i = 1; i < num_glyphs; i++)
+      if (info[i-1].cluster != info[i].cluster &&
+	  (info[i-1].cluster < info[i].cluster) != is_forward)
+      {
+	buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "clusters are not monotone.");
+	return false;
+      }
+  }
+
+  return true;
+}
+
+static bool
+buffer_verify_unsafe_to_break (hb_buffer_t  *buffer,
+			       hb_buffer_t  *text_buffer,
+			       hb_font_t          *font,
+			       const hb_feature_t *features,
+			       unsigned int        num_features,
+			       const char * const *shapers)
+{
+  if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES &&
+      buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
+  {
+    /* Cannot perform this check without monotone clusters. */
+    return true;
+  }
+
+  /* Check that breaking up shaping at safe-to-break is indeed safe. */
+
+  hb_buffer_t *fragment = hb_buffer_create_similar (buffer);
+  hb_buffer_set_flags (fragment, hb_buffer_get_flags (fragment) & ~HB_BUFFER_FLAG_VERIFY);
+  hb_buffer_t *reconstruction = hb_buffer_create_similar (buffer);
+  hb_buffer_set_flags (reconstruction, hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY);
+
+  unsigned int num_glyphs;
+  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs);
+
+  unsigned int num_chars;
+  hb_glyph_info_t *text = hb_buffer_get_glyph_infos (text_buffer, &num_chars);
+
+  /* Chop text and shape fragments. */
+  bool forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer));
+  unsigned int start = 0;
+  unsigned int text_start = forward ? 0 : num_chars;
+  unsigned int text_end = text_start;
+  for (unsigned int end = 1; end < num_glyphs + 1; end++)
+  {
+    if (end < num_glyphs &&
+	(info[end].cluster == info[end-1].cluster ||
+	 info[end-(forward?0:1)].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK))
+	continue;
+
+    /* Shape segment corresponding to glyphs start..end. */
+    if (end == num_glyphs)
+    {
+      if (forward)
+	text_end = num_chars;
+      else
+	text_start = 0;
+    }
+    else
+    {
+      if (forward)
+      {
+	unsigned int cluster = info[end].cluster;
+	while (text_end < num_chars && text[text_end].cluster < cluster)
+	  text_end++;
+      }
+      else
+      {
+	unsigned int cluster = info[end - 1].cluster;
+	while (text_start && text[text_start - 1].cluster >= cluster)
+	  text_start--;
+      }
+    }
+    assert (text_start < text_end);
+
+    if (0)
+      printf("start %d end %d text start %d end %d\n", start, end, text_start, text_end);
+
+    hb_buffer_clear_contents (fragment);
+
+    hb_buffer_flags_t flags = hb_buffer_get_flags (fragment);
+    if (0 < text_start)
+      flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_BOT);
+    if (text_end < num_chars)
+      flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_EOT);
+    hb_buffer_set_flags (fragment, flags);
+
+    hb_buffer_append (fragment, text_buffer, text_start, text_end);
+    if (!hb_shape_full (font, fragment, features, num_features, shapers))
+    {
+      buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
+      hb_buffer_destroy (reconstruction);
+      hb_buffer_destroy (fragment);
+      return false;
+    }
+    hb_buffer_append (reconstruction, fragment, 0, -1);
+
+    start = end;
+    if (forward)
+      text_start = text_end;
+    else
+      text_end = text_start;
+  }
+
+  bool ret = true;
+  hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
+  if (diff)
+  {
+    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed.");
+    ret = false;
+
+    /* Return the reconstructed result instead so it can be inspected. */
+    hb_buffer_set_length (buffer, 0);
+    hb_buffer_append (buffer, reconstruction, 0, -1);
+  }
+
+  hb_buffer_destroy (reconstruction);
+  hb_buffer_destroy (fragment);
+
+  return ret;
+}
+
+static bool
+buffer_verify_unsafe_to_concat (hb_buffer_t        *buffer,
+				hb_buffer_t        *text_buffer,
+				hb_font_t          *font,
+				const hb_feature_t *features,
+				unsigned int        num_features,
+				const char * const *shapers)
+{
+  if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES &&
+      buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
+  {
+    /* Cannot perform this check without monotone clusters. */
+    return true;
+  }
+
+  /* Check that shuffling up text before shaping at safe-to-concat points
+   * is indeed safe. */
+
+  /* This is what we do:
+   *
+   * 1. We shape text once. Then segment the text at all the safe-to-concat
+   *    points;
+   *
+   * 2. Then we create two buffers, one containing all the even segments and
+   *    one all the odd segments.
+   *
+   * 3. Because all these segments were safe-to-concat at both ends, we
+   *    expect that concatenating them and shaping should NOT change the
+   *    shaping results of each segment.  As such, we expect that after
+   *    shaping the two buffers, we still get cluster boundaries at the
+   *    segment boundaries, and that those all are safe-to-concat points.
+   *    Moreover, that there are NOT any safe-to-concat points within the
+   *    segments.
+   *
+   * 4. Finally, we reconstruct the shaping results of the original text by
+   *    simply interleaving the shaping results of the segments from the two
+   *    buffers, and assert that the total shaping results is the same as
+   *    the one from original buffer in step 1.
+   */
+
+  hb_buffer_t *fragments[2] {hb_buffer_create_similar (buffer),
+			     hb_buffer_create_similar (buffer)};
+  hb_buffer_set_flags (fragments[0], hb_buffer_get_flags (fragments[0]) & ~HB_BUFFER_FLAG_VERIFY);
+  hb_buffer_set_flags (fragments[1], hb_buffer_get_flags (fragments[1]) & ~HB_BUFFER_FLAG_VERIFY);
+  hb_buffer_t *reconstruction = hb_buffer_create_similar (buffer);
+  hb_buffer_set_flags (reconstruction, hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY);
+  hb_segment_properties_t props;
+  hb_buffer_get_segment_properties (buffer, &props);
+  hb_buffer_set_segment_properties (fragments[0], &props);
+  hb_buffer_set_segment_properties (fragments[1], &props);
+  hb_buffer_set_segment_properties (reconstruction, &props);
+
+  unsigned num_glyphs;
+  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs);
+
+  unsigned num_chars;
+  hb_glyph_info_t *text = hb_buffer_get_glyph_infos (text_buffer, &num_chars);
+
+  bool forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer));
+
+  if (!forward)
+    hb_buffer_reverse (buffer);
+
+  /*
+   * Split text into segments and collect into to fragment streams.
+   */
+  {
+    unsigned fragment_idx = 0;
+    unsigned start = 0;
+    unsigned text_start = 0;
+    unsigned text_end = 0;
+    for (unsigned end = 1; end < num_glyphs + 1; end++)
+    {
+      if (end < num_glyphs &&
+	  (info[end].cluster == info[end-1].cluster ||
+	   info[end].mask & HB_GLYPH_FLAG_UNSAFE_TO_CONCAT))
+	  continue;
+
+      /* Accumulate segment corresponding to glyphs start..end. */
+      if (end == num_glyphs)
+	text_end = num_chars;
+      else
+      {
+	unsigned cluster = info[end].cluster;
+	while (text_end < num_chars && text[text_end].cluster < cluster)
+	  text_end++;
+      }
+      assert (text_start < text_end);
+
+      if (0)
+	printf("start %d end %d text start %d end %d\n", start, end, text_start, text_end);
+
+#if 0
+      hb_buffer_flags_t flags = hb_buffer_get_flags (fragment);
+      if (0 < text_start)
+	flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_BOT);
+      if (text_end < num_chars)
+	flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_EOT);
+      hb_buffer_set_flags (fragment, flags);
+#endif
+
+      hb_buffer_append (fragments[fragment_idx], text_buffer, text_start, text_end);
+
+      start = end;
+      text_start = text_end;
+      fragment_idx = 1 - fragment_idx;
+    }
+  }
+
+  bool ret = true;
+  hb_buffer_diff_flags_t diff;
+
+  /*
+   * Shape the two fragment streams.
+   */
+  if (!hb_shape_full (font, fragments[0], features, num_features, shapers))
+  {
+    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
+    ret = false;
+    goto out;
+  }
+  if (!hb_shape_full (font, fragments[1], features, num_features, shapers))
+  {
+    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
+    ret = false;
+    goto out;
+  }
+
+  if (!forward)
+  {
+    hb_buffer_reverse (fragments[0]);
+    hb_buffer_reverse (fragments[1]);
+  }
+
+  /*
+   * Reconstruct results.
+   */
+  {
+    unsigned fragment_idx = 0;
+    unsigned fragment_start[2] {0, 0};
+    unsigned fragment_num_glyphs[2];
+    hb_glyph_info_t *fragment_info[2];
+    for (unsigned i = 0; i < 2; i++)
+      fragment_info[i] = hb_buffer_get_glyph_infos (fragments[i], &fragment_num_glyphs[i]);
+    while (fragment_start[0] < fragment_num_glyphs[0] ||
+	   fragment_start[1] < fragment_num_glyphs[1])
+    {
+      unsigned fragment_end = fragment_start[fragment_idx] + 1;
+      while (fragment_end < fragment_num_glyphs[fragment_idx] &&
+	     (fragment_info[fragment_idx][fragment_end].cluster == fragment_info[fragment_idx][fragment_end - 1].cluster ||
+	      fragment_info[fragment_idx][fragment_end].mask & HB_GLYPH_FLAG_UNSAFE_TO_CONCAT))
+	fragment_end++;
+
+      hb_buffer_append (reconstruction, fragments[fragment_idx], fragment_start[fragment_idx], fragment_end);
+
+      fragment_start[fragment_idx] = fragment_end;
+      fragment_idx = 1 - fragment_idx;
+    }
+  }
+
+  if (!forward)
+  {
+    hb_buffer_reverse (buffer);
+    hb_buffer_reverse (reconstruction);
+  }
+
+  /*
+   * Diff results.
+   */
+  diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
+  if (diff)
+  {
+    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed.");
+    ret = false;
+
+    /* Return the reconstructed result instead so it can be inspected. */
+    hb_buffer_set_length (buffer, 0);
+    hb_buffer_append (buffer, reconstruction, 0, -1);
+  }
+
+
+out:
+  hb_buffer_destroy (reconstruction);
+  hb_buffer_destroy (fragments[0]);
+  hb_buffer_destroy (fragments[1]);
+
+  return ret;
+}
+
+bool
+hb_buffer_t::verify (hb_buffer_t        *text_buffer,
+		     hb_font_t          *font,
+		     const hb_feature_t *features,
+		     unsigned int        num_features,
+		     const char * const *shapers)
+{
+  bool ret = true;
+  if (!buffer_verify_monotone (this, font))
+    ret = false;
+  if (!buffer_verify_unsafe_to_break (this, text_buffer, font, features, num_features, shapers))
+    ret = false;
+  if (!buffer_verify_unsafe_to_concat (this, text_buffer, font, features, num_features, shapers))
+    ret = false;
+  if (!ret)
+  {
+    unsigned len = text_buffer->len;
+    hb_vector_t<char> bytes;
+    if (likely (bytes.resize (len * 10 + 16)))
+    {
+      hb_buffer_serialize_unicode (text_buffer,
+				   0, len,
+				   bytes.arrayZ, bytes.length,
+				   &len,
+				   HB_BUFFER_SERIALIZE_FORMAT_TEXT,
+				   HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS);
+      buffer_verify_error (this, font, BUFFER_VERIFY_ERROR "text was: %s.", bytes.arrayZ);
+    }
+  }
+  return ret;
+}
+
+
+#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -86,8 +86,47 @@
 	 (intptr_t) (p->language);
 }
 
+/**
+ * hb_segment_properties_overlay:
+ * @p: #hb_segment_properties_t to fill in.
+ * @src: #hb_segment_properties_t to fill in from.
+ *
+ * Fills in missing fields of @p from @src in a considered manner.
+ *
+ * First, if @p does not have direction set, direction is copied from @src.
+ *
+ * Next, if @p and @src have the same direction (which can be unset), if @p
+ * does not have script set, script is copied from @src.
+ *
+ * Finally, if @p and @src have the same direction and script (which either
+ * can be unset), if @p does not have language set, language is copied from
+ * @src.
+ *
+ * Since: 3.3.0
+ **/
+void
+hb_segment_properties_overlay (hb_segment_properties_t *p,
+			       const hb_segment_properties_t *src)
+{
+  if (unlikely (!p || !src))
+    return;
 
+  if (!p->direction)
+    p->direction = src->direction;
 
+  if (p->direction != src->direction)
+    return;
+
+  if (!p->script)
+    p->script = src->script;
+
+  if (p->script != src->script)
+    return;
+
+  if (!p->language)
+    p->language = src->language;
+}
+
 /* Here is how the buffer works internally:
  *
  * There are two info pointers: info and out_info.  They always have
@@ -96,7 +135,7 @@
  * As an optimization, both info and out_info may point to the
  * same piece of memory, which is owned by info.  This remains the
  * case as long as out_len doesn't exceed i at any time.
- * In that case, swap_buffers() is mostly no-op and the glyph operations
+ * In that case, sync() is mostly no-op and the glyph operations
  * operate mostly in-place.
  *
  * As soon as out_info gets longer than info, out_info is moved over
@@ -103,7 +142,7 @@
  * to an alternate buffer (which we reuse the pos buffer for), and its
  * current contents (out_len entries) are copied to the new place.
  *
- * This should all remain transparent to the user.  swap_buffers() then
+ * This should all remain transparent to the user.  sync() then
  * switches info over to out_info and does housekeeping.
  */
 
@@ -217,11 +256,24 @@
 /* HarfBuzz-Internal API */
 
 void
+hb_buffer_t::similar (const hb_buffer_t &src)
+{
+  hb_unicode_funcs_destroy (unicode);
+  unicode = hb_unicode_funcs_reference (src.unicode);
+  flags = src.flags;
+  cluster_level = src.cluster_level;
+  replacement = src.invisible;
+  invisible = src.invisible;
+  not_found = src.not_found;
+}
+
+void
 hb_buffer_t::reset ()
 {
   hb_unicode_funcs_destroy (unicode);
   unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ());
   flags = HB_BUFFER_FLAG_DEFAULT;
+  cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT;
   replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
   invisible = 0;
   not_found = 0;
@@ -232,11 +284,10 @@
 void
 hb_buffer_t::clear ()
 {
+  content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
   hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
   props = default_props;
-  scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
 
-  content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
   successful = true;
   have_output = false;
   have_positions = false;
@@ -244,17 +295,45 @@
   idx = 0;
   len = 0;
   out_len = 0;
+
   out_info = info;
 
-  serial = 0;
-
   memset (context, 0, sizeof context);
   memset (context_len, 0, sizeof context_len);
 
   deallocate_var_all ();
+  serial = 0;
+  scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
 }
 
 void
+hb_buffer_t::enter ()
+{
+  deallocate_var_all ();
+  serial = 0;
+  scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
+  if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR)))
+  {
+    max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR,
+		      (unsigned) HB_BUFFER_MAX_LEN_MIN);
+  }
+  if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR)))
+  {
+    max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR,
+		      (unsigned) HB_BUFFER_MAX_OPS_MIN);
+  }
+}
+void
+hb_buffer_t::leave ()
+{
+  max_len = HB_BUFFER_MAX_LEN_DEFAULT;
+  max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
+  deallocate_var_all ();
+  serial = 0;
+}
+
+
+void
 hb_buffer_t::add (hb_codepoint_t  codepoint,
 		  unsigned int    cluster)
 {
@@ -307,7 +386,7 @@
 }
 
 void
-hb_buffer_t::swap_buffers ()
+hb_buffer_t::sync ()
 {
   assert (have_output);
 
@@ -494,33 +573,6 @@
 }
 
 void
-hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
-{
-  unsigned int cluster = UINT_MAX;
-  cluster = _infos_find_min_cluster (info, start, end, cluster);
-  _unsafe_to_break_set_mask (info, start, end, cluster);
-}
-void
-hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end)
-{
-  if (!have_output)
-  {
-    unsafe_to_break_impl (start, end);
-    return;
-  }
-
-  assert (start <= out_len);
-  assert (idx <= end);
-
-  unsigned int cluster = UINT_MAX;
-  cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
-  cluster = _infos_find_min_cluster (info, idx, end, cluster);
-
-  _unsafe_to_break_set_mask (out_info, start, out_len, cluster);
-  _unsafe_to_break_set_mask (info, idx, end, cluster);
-}
-
-void
 hb_buffer_t::guess_segment_properties ()
 {
   assert_unicode ();
@@ -565,12 +617,11 @@
   HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
   0, /* invisible */
   0, /* not_found */
-  HB_BUFFER_SCRATCH_FLAG_DEFAULT,
-  HB_BUFFER_MAX_LEN_DEFAULT,
-  HB_BUFFER_MAX_OPS_DEFAULT,
 
+
   HB_BUFFER_CONTENT_TYPE_INVALID,
   HB_SEGMENT_PROPERTIES_DEFAULT,
+
   false, /* successful */
   false, /* have_output */
   true  /* have_positions */
@@ -610,6 +661,46 @@
 }
 
 /**
+ * hb_buffer_create_similar:
+ * @src: An #hb_buffer_t
+ *
+ * Creates a new #hb_buffer_t, similar to hb_buffer_create(). The only
+ * difference is that the buffer is configured similarly to @src.
+ *
+ * Return value: (transfer full):
+ * A newly allocated #hb_buffer_t, similar to hb_buffer_create().
+ *
+ * Since: 3.3.0
+ **/
+hb_buffer_t *
+hb_buffer_create_similar (const hb_buffer_t *src)
+{
+  hb_buffer_t *buffer = hb_buffer_create ();
+
+  buffer->similar (*src);
+
+  return buffer;
+}
+
+/**
+ * hb_buffer_reset:
+ * @buffer: An #hb_buffer_t
+ *
+ * Resets the buffer to its initial status, as if it was just newly created
+ * with hb_buffer_create().
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_reset (hb_buffer_t *buffer)
+{
+  if (unlikely (hb_object_is_immutable (buffer)))
+    return;
+
+  buffer->reset ();
+}
+
+/**
  * hb_buffer_get_empty:
  *
  * Fetches an empty #hb_buffer_t.
@@ -1157,24 +1248,6 @@
 
 
 /**
- * hb_buffer_reset:
- * @buffer: An #hb_buffer_t
- *
- * Resets the buffer to its initial status, as if it was just newly created
- * with hb_buffer_create().
- *
- * Since: 0.9.2
- **/
-void
-hb_buffer_reset (hb_buffer_t *buffer)
-{
-  if (unlikely (hb_object_is_immutable (buffer)))
-    return;
-
-  buffer->reset ();
-}
-
-/**
  * hb_buffer_clear_contents:
  * @buffer: An #hb_buffer_t
  *
@@ -1716,7 +1789,7 @@
  **/
 HB_EXTERN void
 hb_buffer_append (hb_buffer_t *buffer,
-		  hb_buffer_t *source,
+		  const hb_buffer_t *source,
 		  unsigned int start,
 		  unsigned int end)
 {
@@ -1749,6 +1822,8 @@
   if (!buffer->have_positions && source->have_positions)
     buffer->clear_positions ();
 
+  hb_segment_properties_overlay (&buffer->props, &source->props);
+
   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]));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2022-02-13 03:14:24 UTC (rev 61999)
@@ -76,18 +76,68 @@
  * @HB_GLYPH_FLAG_UNSAFE_TO_BREAK: Indicates that if input text is broken at the
  * 				   beginning of the cluster this glyph is part of,
  * 				   then both sides need to be re-shaped, as the
- * 				   result might be different.  On the flip side,
- * 				   it means that when this flag is not present,
- * 				   then it's safe to break the glyph-run at the
- * 				   beginning of this cluster, and the two sides
- * 				   represent the exact same result one would get
- * 				   if breaking input text at the beginning of
- * 				   this cluster and shaping the two sides
- * 				   separately.  This can be used to optimize
- * 				   paragraph layout, by avoiding re-shaping
- * 				   of each line after line-breaking, or limiting
- * 				   the reshaping to a small piece around the
- * 				   breaking point only.
+ * 				   result might be different.
+ * 				   On the flip side, it means that when this
+ * 				   flag is not present, then it is safe to break
+ * 				   the glyph-run at the beginning of this
+ * 				   cluster, and the two sides will represent the
+ * 				   exact same result one would get if breaking
+ * 				   input text at the beginning of this cluster
+ * 				   and shaping the two sides separately.
+ * 				   This can be used to optimize paragraph
+ * 				   layout, by avoiding re-shaping of each line
+ * 				   after line-breaking.
+ * @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT: Indicates that if input text is changed on one
+ * 				   side of the beginning of the cluster this glyph
+ * 				   is part of, then the shaping results for the
+ * 				   other side might change.
+ * 				   Note that the absence of this flag will NOT by
+ * 				   itself mean that it IS safe to concat text.
+ * 				   Only two pieces of text both of which clear of
+ * 				   this flag can be concatenated safely.
+ * 				   This can be used to optimize paragraph
+ * 				   layout, by avoiding re-shaping of each line
+ * 				   after line-breaking, by limiting the
+ * 				   reshaping to a small piece around the
+ * 				   breaking positin only, even if the breaking
+ * 				   position carries the
+ * 				   #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when
+ * 				   hyphenation or other text transformation
+ * 				   happens at line-break position, in the following
+ * 				   way:
+ * 				   1. Iterate back from the line-break position
+ * 				   until the first cluster start position that is
+ * 				   NOT unsafe-to-concat, 2. shape the segment from
+ * 				   there till the end of line, 3. check whether the
+ * 				   resulting glyph-run also is clear of the
+ * 				   unsafe-to-concat at its start-of-text position;
+ * 				   if it is, just splice it into place and the line
+ * 				   is shaped; If not, move on to a position further
+ * 				   back that is clear of unsafe-to-concat and retry
+ * 				   from there, and repeat.
+ * 				   At the start of next line a similar algorithm can
+ * 				   be implemented. That is: 1. Iterate forward from
+ * 				   the line-break position untill the first cluster
+ * 				   start position that is NOT unsafe-to-concat, 2.
+ * 				   shape the segment from beginning of the line to
+ * 				   that position, 3. check whether the resulting
+ * 				   glyph-run also is clear of the unsafe-to-concat
+ * 				   at its end-of-text position; if it is, just splice
+ * 				   it into place and the beginning is shaped; If not,
+ * 				   move on to a position further forward that is clear
+ * 				   of unsafe-to-concat and retry up to there, and repeat.
+ * 				   A slight complication will arise in the
+ * 				   implementation of the algorithm above,
+ * 				   because while our buffer API has a way to
+ * 				   return flags for position corresponding to
+ * 				   start-of-text, there is currently no position
+ * 				   corresponding to end-of-text.  This limitation
+ * 				   can be alleviated by shaping more text than needed
+ * 				   and looking for unsafe-to-concat flag within text
+ * 				   clusters.
+ * 				   The #HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag will
+ * 				   always imply this flag.
+ * 				   Since: 3.3.0
  * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags.
  *
  * Flags for #hb_glyph_info_t.
@@ -96,8 +146,9 @@
  */
 typedef enum { /*< flags >*/
   HB_GLYPH_FLAG_UNSAFE_TO_BREAK		= 0x00000001,
+  HB_GLYPH_FLAG_UNSAFE_TO_CONCAT	= 0x00000002,
 
-  HB_GLYPH_FLAG_DEFINED			= 0x00000001 /* OR of all defined flags */
+  HB_GLYPH_FLAG_DEFINED			= 0x00000003 /* OR of all defined flags */
 } hb_glyph_flags_t;
 
 HB_EXTERN hb_glyph_flags_t
@@ -170,6 +221,9 @@
 HB_EXTERN unsigned int
 hb_segment_properties_hash (const hb_segment_properties_t *p);
 
+HB_EXTERN void
+hb_segment_properties_overlay (hb_segment_properties_t *p,
+			       const hb_segment_properties_t *src);
 
 
 /**
@@ -185,6 +239,13 @@
 hb_buffer_create (void);
 
 HB_EXTERN hb_buffer_t *
+hb_buffer_create_similar (const hb_buffer_t *src);
+
+HB_EXTERN void
+hb_buffer_reset (hb_buffer_t *buffer);
+
+
+HB_EXTERN hb_buffer_t *
 hb_buffer_get_empty (void);
 
 HB_EXTERN hb_buffer_t *
@@ -295,7 +356,15 @@
  * @HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE:
  *                      flag indicating that a dotted circle should
  *                      not be inserted in the rendering of incorrect
- *                      character sequences (such at <0905 093E>). Since: 2.4
+ *                      character sequences (such at <0905 093E>). Since: 2.4.0
+ * @HB_BUFFER_FLAG_VERIFY:
+ *                      flag indicating that the hb_shape() call and its variants
+ *                      should perform various verification processes on the results
+ *                      of the shaping operation on the buffer.  If the verification
+ *                      fails, then either a buffer message is sent, if a message
+ *                      handler is installed on the buffer, or a message is written
+ *                      to standard error.  In either case, the shaping result might
+ *                      be modified to show the failed output. Since: 3.4.0
  *
  * Flags for #hb_buffer_t.
  *
@@ -307,7 +376,8 @@
   HB_BUFFER_FLAG_EOT				= 0x00000002u, /* End-of-text */
   HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES	= 0x00000004u,
   HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES	= 0x00000008u,
-  HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE	= 0x00000010u
+  HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE	= 0x00000010u,
+  HB_BUFFER_FLAG_VERIFY				= 0x00000020u
 } hb_buffer_flags_t;
 
 HB_EXTERN void
@@ -391,8 +461,9 @@
 hb_buffer_get_not_found_glyph (hb_buffer_t    *buffer);
 
 
-HB_EXTERN void
-hb_buffer_reset (hb_buffer_t *buffer);
+/*
+ * Content API.
+ */
 
 HB_EXTERN void
 hb_buffer_clear_contents (hb_buffer_t *buffer);
@@ -460,7 +531,7 @@
 
 HB_EXTERN void
 hb_buffer_append (hb_buffer_t *buffer,
-		  hb_buffer_t *source,
+		  const hb_buffer_t *source,
 		  unsigned int start,
 		  unsigned int end);
 
@@ -557,24 +628,24 @@
 
 HB_EXTERN unsigned int
 hb_buffer_serialize_unicode (hb_buffer_t *buffer,
-					unsigned int start,
-					unsigned int end,
-					char *buf,
-					unsigned int buf_size,
-					unsigned int *buf_consumed,
-					hb_buffer_serialize_format_t format,
-					hb_buffer_serialize_flags_t flags);
+			     unsigned int start,
+			     unsigned int end,
+			     char *buf,
+			     unsigned int buf_size,
+			     unsigned int *buf_consumed,
+			     hb_buffer_serialize_format_t format,
+			     hb_buffer_serialize_flags_t flags);
 
 HB_EXTERN unsigned int
 hb_buffer_serialize (hb_buffer_t *buffer,
-					unsigned int start,
-					unsigned int end,
-					char *buf,
-					unsigned int buf_size,
-					unsigned int *buf_consumed,
-					hb_font_t *font,
-					hb_buffer_serialize_format_t format,
-					hb_buffer_serialize_flags_t flags);
+		     unsigned int start,
+		     unsigned int end,
+		     char *buf,
+		     unsigned int buf_size,
+		     unsigned int *buf_consumed,
+		     hb_font_t *font,
+		     hb_buffer_serialize_format_t format,
+		     hb_buffer_serialize_flags_t flags);
 
 HB_EXTERN hb_bool_t
 hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
@@ -586,10 +657,10 @@
 
 HB_EXTERN hb_bool_t
 hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
-            const char *buf,
-            int buf_len,
-            const char **end_ptr,
-            hb_buffer_serialize_format_t format);
+			       const char *buf,
+			       int buf_len,
+			       const char **end_ptr,
+			       hb_buffer_serialize_format_t format);
 
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -67,8 +67,8 @@
   HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES		= 0x00000002u,
   HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK		= 0x00000004u,
   HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT		= 0x00000008u,
-  HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK		= 0x00000010u,
-  HB_BUFFER_SCRATCH_FLAG_HAS_CGJ			= 0x00000020u,
+  HB_BUFFER_SCRATCH_FLAG_HAS_CGJ			= 0x00000010u,
+  HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS		= 0x00000020u,
 
   /* Reserved for complex shapers' internal use. */
   HB_BUFFER_SCRATCH_FLAG_COMPLEX0			= 0x01000000u,
@@ -87,7 +87,10 @@
 {
   hb_object_header_t header;
 
-  /* Information about how the text in the buffer should be treated */
+  /*
+   * Information about how the text in the buffer should be treated.
+   */
+
   hb_unicode_funcs_t *unicode; /* Unicode functions */
   hb_buffer_flags_t flags; /* BOT / EOT / etc. */
   hb_buffer_cluster_level_t cluster_level;
@@ -94,11 +97,11 @@
   hb_codepoint_t replacement; /* U+FFFD or something else. */
   hb_codepoint_t invisible; /* 0 or something else. */
   hb_codepoint_t not_found; /* 0 or something else. */
-  hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
-  unsigned int max_len; /* Maximum allowed len. */
-  int max_ops; /* Maximum allowed operations. */
 
-  /* Buffer contents */
+  /*
+   * Buffer contents
+   */
+
   hb_buffer_content_type_t content_type;
   hb_segment_properties_t props; /* Script, language, direction */
 
@@ -115,8 +118,6 @@
   hb_glyph_info_t     *out_info;
   hb_glyph_position_t *pos;
 
-  unsigned int serial;
-
   /* Text before / after the main buffer contents.
    * Always in Unicode, and ordered outward.
    * Index 0 is for "pre-context", 1 for "post-context". */
@@ -124,7 +125,25 @@
   hb_codepoint_t context[2][CONTEXT_LENGTH];
   unsigned int context_len[2];
 
-  /* Debugging API */
+
+  /*
+   * Managed by enter / leave
+   */
+
+#ifndef HB_NDEBUG
+  uint8_t allocated_var_bits;
+#endif
+  uint8_t serial;
+  hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
+  unsigned int max_len; /* Maximum allowed len. */
+  int max_ops; /* Maximum allowed operations. */
+  /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
+
+
+  /*
+   * Messaging callback
+   */
+
 #ifndef HB_NO_BUFFER_MESSAGE
   hb_buffer_message_func_t message_func;
   void *message_data;
@@ -134,11 +153,6 @@
   static constexpr unsigned message_depth = 0u;
 #endif
 
-  /* Internal debugging. */
-  /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
-#ifndef HB_NDEBUG
-  uint8_t allocated_var_bits;
-#endif
 
 
   /* Methods */
@@ -190,12 +204,31 @@
   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_INTERNAL void similar (const hb_buffer_t &src);
   HB_INTERNAL void reset ();
   HB_INTERNAL void clear ();
 
+  /* Called around shape() */
+  HB_INTERNAL void enter ();
+  HB_INTERNAL void leave ();
+
+#ifndef HB_NO_BUFFER_VERIFY
+  HB_INTERNAL
+#endif
+  bool verify (hb_buffer_t        *text_buffer,
+	       hb_font_t          *font,
+	       const hb_feature_t *features,
+	       unsigned int        num_features,
+	       const char * const *shapers)
+#ifndef HB_NO_BUFFER_VERIFY
+  ;
+#else
+  { return true; }
+#endif
+
   unsigned int backtrack_len () const { return have_output ? out_len : idx; }
   unsigned int lookahead_len () const { return len - idx; }
-  unsigned int next_serial () { return serial++; }
+  uint8_t next_serial () { return ++serial ? serial : ++serial; }
 
   HB_INTERNAL void add (hb_codepoint_t  codepoint,
 			unsigned int    cluster);
@@ -252,7 +285,7 @@
 
   HB_INTERNAL void guess_segment_properties ();
 
-  HB_INTERNAL void swap_buffers ();
+  HB_INTERNAL void sync ();
   HB_INTERNAL void clear_output ();
   HB_INTERNAL void clear_positions ();
 
@@ -366,17 +399,85 @@
   /* Merge clusters for deleting current glyph, and skip it. */
   HB_INTERNAL void delete_glyph ();
 
-  void unsafe_to_break (unsigned int start,
-			unsigned int end)
+
+  /* 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. */
+  void _set_glyph_flags (hb_mask_t mask,
+			 unsigned start = 0,
+			 unsigned end = (unsigned) -1,
+			 bool interior = false,
+			 bool from_out_buffer = false)
   {
-    if (end - start < 2)
+    end = hb_min (end, len);
+
+    if (interior && !from_out_buffer && end - start < 2)
       return;
-    unsafe_to_break_impl (start, end);
+
+    scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
+
+    if (!from_out_buffer || !have_output)
+    {
+      if (!interior)
+      {
+	for (unsigned i = start; i < end; i++)
+	  info[i].mask |= mask;
+      }
+      else
+      {
+	unsigned cluster = _infos_find_min_cluster (info, start, end);
+	_infos_set_glyph_flags (info, start, end, cluster, mask);
+      }
+    }
+    else
+    {
+      assert (start <= out_len);
+      assert (idx <= end);
+
+      if (!interior)
+      {
+	for (unsigned i = start; i < out_len; i++)
+	  out_info[i].mask |= mask;
+	for (unsigned i = idx; i < end; i++)
+	  info[i].mask |= mask;
+      }
+      else
+      {
+	unsigned cluster = _infos_find_min_cluster (info, idx, end);
+	cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
+
+	_infos_set_glyph_flags (out_info, start, out_len, cluster, mask);
+	_infos_set_glyph_flags (info, idx, end, cluster, mask);
+      }
+    }
   }
-  HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end);
-  HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end);
 
+  void unsafe_to_break (unsigned int start = 0, unsigned int end = -1)
+  {
+    _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
+		      start, end,
+		      true);
+  }
+  void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
+  {
+    _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
+		      start, end,
+		      true);
+  }
+  void unsafe_to_break_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
+  {
+    _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
+		      start, end,
+		      true, true);
+  }
+  void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
+  {
+    _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
+		      start, end,
+		      false, true);
+  }
 
+
   /* Internal methods */
   HB_NODISCARD HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
 
@@ -465,36 +566,31 @@
   set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
   {
     if (inf.cluster != cluster)
-    {
-      if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
-	inf.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
-      else
-	inf.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
-    }
+      inf.mask = (inf.mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
     inf.cluster = cluster;
   }
-
+  void
+  _infos_set_glyph_flags (hb_glyph_info_t *infos,
+			  unsigned int start, unsigned int end,
+			  unsigned int cluster,
+			  hb_mask_t mask)
+  {
+    for (unsigned int i = start; i < end; i++)
+      if (cluster != infos[i].cluster)
+      {
+	scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
+	infos[i].mask |= mask;
+      }
+  }
   static unsigned
   _infos_find_min_cluster (const hb_glyph_info_t *infos,
 			   unsigned start, unsigned end,
-			   unsigned cluster)
+			   unsigned cluster = UINT_MAX)
   {
     for (unsigned int i = start; i < end; i++)
       cluster = hb_min (cluster, infos[i].cluster);
     return cluster;
   }
-  void
-  _unsafe_to_break_set_mask (hb_glyph_info_t *infos,
-			     unsigned int start, unsigned int end,
-			     unsigned int cluster)
-  {
-    for (unsigned int i = start; i < end; i++)
-      if (cluster != infos[i].cluster)
-      {
-	scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK;
-	infos[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
-      }
-  }
 
   void clear_glyph_flags (hb_mask_t mask = 0)
   {

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -217,9 +217,6 @@
 
 struct number_t
 {
-  void init () { set_real (0.0); }
-  void fini () {}
-
   void set_int (int v)       { value = v; }
   int to_int () const        { return value; }
 
@@ -245,7 +242,7 @@
   }
 
   protected:
-  double value;
+  double value = 0.;
 };
 
 /* byte string */
@@ -380,10 +377,8 @@
     count = 0;
     elements.init ();
     elements.resize (kSizeLimit);
-    for (unsigned int i = 0; i < elements.length; i++)
-      elements[i].init ();
   }
-  void fini () { elements.fini_deep (); }
+  void fini () { elements.fini (); }
 
   ELEM& operator [] (unsigned int i)
   {
@@ -523,9 +518,6 @@
 /* an operator prefixed by its operands in a byte string */
 struct op_str_t
 {
-  void init () {}
-  void fini () {}
-
   op_code_t  op;
   byte_str_t str;
 };
@@ -553,7 +545,7 @@
     opStart = 0;
     values.init ();
   }
-  void fini () { values.fini_deep (); }
+  void fini () { values.fini (); }
 
   void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t ())
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -94,12 +94,6 @@
 
 struct point_t
 {
-  void init ()
-  {
-    x.init ();
-    y.init ();
-  }
-
   void set_int (int _x, int _y)
   {
     x.set_int (_x);
@@ -128,7 +122,7 @@
     hstem_count = 0;
     vstem_count = 0;
     hintmask_size = 0;
-    pt.init ();
+    pt.set_int (0, 0);
     callStack.init ();
     globalSubrs.init (globalSubrs_);
     localSubrs.init (localSubrs_);
@@ -841,7 +835,6 @@
     if (likely (env.argStack.get_count () == 11))
     {
       point_t d;
-      d.init ();
       for (unsigned int i = 0; i < 10; i += 2)
 	d.move (env.eval_arg (i), env.eval_arg (i+1));
 

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -35,18 +35,6 @@
 
 struct blend_arg_t : number_t
 {
-  void init ()
-  {
-    number_t::init ();
-    deltas.init ();
-  }
-
-  void fini ()
-  {
-    number_t::fini ();
-    deltas.fini_deep ();
-  }
-
   void set_int (int v) { reset_blends (); number_t::set_int (v); }
   void set_fixed (int32_t v) { reset_blends (); number_t::set_fixed (v); }
   void set_real (double v) { reset_blends (); number_t::set_real (v); }
@@ -202,7 +190,7 @@
     switch (op) {
       case OpCode_callsubr:
       case OpCode_callgsubr:
-	/* a subroutine number shoudln't be a blended value */
+	/* a subroutine number shouldn't be a blended value */
 	if (unlikely (env.argStack.peek ().blending ()))
 	{
 	  env.set_error ();

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -29,12 +29,33 @@
 #include "hb.hh"
 #include "hb-machinery.hh"
 
+#if !defined(HB_NO_SETLOCALE) && (!defined(HAVE_NEWLOCALE) || !defined(HAVE_USELOCALE))
+#define HB_NO_SETLOCALE 1
+#endif
+
+#ifndef HB_NO_SETLOCALE
+
 #include <locale.h>
+#ifdef HAVE_XLOCALE_H
+#include <xlocale.h> // Needed on BSD/OS X for uselocale
+#endif
 
-#ifdef HB_NO_SETLOCALE
-#define setlocale(Category, Locale) "C"
+#ifdef WIN32
+#define hb_locale_t _locale_t
+#else
+#define hb_locale_t locale_t
 #endif
+#define hb_setlocale setlocale
+#define hb_uselocale uselocale
 
+#else
+
+#define hb_locale_t void *
+#define hb_setlocale(Category, Locale) "C"
+#define hb_uselocale(Locale) ((hb_locale_t) 0)
+
+#endif
+
 /**
  * SECTION:hb-common
  * @title: hb-common
@@ -122,7 +143,7 @@
  * @tag: #hb_tag_t to convert
  * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): Converted string
  *
- * Converts an #hb_tag_t to a string and returns it in @buf. 
+ * Converts an #hb_tag_t to a string and returns it in @buf.
  * Strings will be four characters long.
  *
  * Since: 0.9.5
@@ -151,13 +172,13 @@
  * @str: (array length=len) (element-type uint8_t): String to convert
  * @len: Length of @str, or -1 if it is %NULL-terminated
  *
- * Converts a string to an #hb_direction_t. 
+ * Converts a string to an #hb_direction_t.
  *
  * Matching is loose and applies only to the first letter. For
  * examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR.
  *
  * Unmatched strings will return #HB_DIRECTION_INVALID.
- * 
+ *
  * Return value: The #hb_direction_t matching @str
  *
  * Since: 0.9.2
@@ -413,7 +434,7 @@
   hb_language_t language = default_language;
   if (unlikely (language == HB_LANGUAGE_INVALID))
   {
-    language = hb_language_from_string (setlocale (LC_CTYPE, nullptr), -1);
+    language = hb_language_from_string (hb_setlocale (LC_CTYPE, nullptr), -1);
     (void) default_language.cmpexch (HB_LANGUAGE_INVALID, language);
   }
 
@@ -1039,6 +1060,47 @@
   return false;
 }
 
+#ifndef HB_NO_SETLOCALE
+
+static inline void free_static_C_locale ();
+
+static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<hb_locale_t>,
+							   hb_C_locale_lazy_loader_t>
+{
+  static hb_locale_t create ()
+  {
+    hb_locale_t l = newlocale (LC_ALL_MASK, "C", NULL);
+    if (!l)
+      return l;
+
+    hb_atexit (free_static_C_locale);
+
+    return l;
+  }
+  static void destroy (hb_locale_t l)
+  {
+    freelocale (l);
+  }
+  static hb_locale_t get_null ()
+  {
+    return (hb_locale_t) 0;
+  }
+} static_C_locale;
+
+static inline
+void free_static_C_locale ()
+{
+  static_C_locale.free_instance ();
+}
+
+static hb_locale_t
+get_C_locale ()
+{
+  return static_C_locale.get_unconst ();
+}
+
+#endif
+
 /**
  * hb_variation_to_string:
  * @variation: an #hb_variation_t to convert
@@ -1064,7 +1126,11 @@
   while (len && s[len - 1] == ' ')
     len--;
   s[len++] = '=';
+
+  hb_locale_t oldlocale HB_UNUSED;
+  oldlocale = hb_uselocale (get_C_locale ());
   len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
+  (void) hb_uselocale (oldlocale);
 
   assert (len < ARRAY_LENGTH (s));
   len = hb_min (len, size - 1);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2022-02-13 03:14:24 UTC (rev 61999)
@@ -481,6 +481,7 @@
  * @HB_SCRIPT_TANGSA: `Tnsa`, Since: 3.0.0
  * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0
  * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0
+ * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0
  * @HB_SCRIPT_INVALID: No script set
  *
  * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding
@@ -697,6 +698,11 @@
   HB_SCRIPT_TOTO			= HB_TAG ('T','o','t','o'), /*14.0*/
   HB_SCRIPT_VITHKUQI			= HB_TAG ('V','i','t','h'), /*14.0*/
 
+  /*
+   * Since 3.4.0
+   */
+  HB_SCRIPT_MATH			= HB_TAG ('Z','m','t','h'),
+
   /* No script set. */
   HB_SCRIPT_INVALID			= HB_TAG_NONE,
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -55,6 +55,7 @@
 #define HB_NO_ATEXIT
 #define HB_NO_BUFFER_MESSAGE
 #define HB_NO_BUFFER_SERIALIZE
+#define HB_NO_BUFFER_VERIFY
 #define HB_NO_BITMAP
 #define HB_NO_CFF
 #define HB_NO_COLOR

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -481,8 +481,8 @@
 	   a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
 	   0;
   }
-  bool operator== (const active_feature_t *f) {
-    return cmp (this, f) == 0;
+  bool operator== (const active_feature_t& f) const {
+    return cmp (this, &f) == 0;
   }
 };
 
@@ -677,7 +677,7 @@
       {
 	active_features.push (event->feature);
       } else {
-	active_feature_t *feature = active_features.find (&event->feature);
+	active_feature_t *feature = active_features.lsearch (event->feature);
 	if (feature)
 	  active_features.remove (feature - active_features.arrayZ);
       }
@@ -1213,7 +1213,8 @@
     }
   }
 
-  buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+  buffer->clear_glyph_flags ();
+  buffer->unsafe_to_break ();
 
 #undef FAIL
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -762,7 +762,8 @@
 
   if (isRightToLeft) hb_buffer_reverse (buffer);
 
-  buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+  buffer->clear_glyph_flags ();
+  buffer->unsafe_to_break ();
 
   delete [] clusterMap;
   delete [] glyphIndices;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2022-02-13 03:14:24 UTC (rev 61999)
@@ -50,7 +50,7 @@
  *
  * Glyph draw callbacks.
  *
- * _move_to, _line_to and _cubic_to calls are nessecary to be defined but we
+ * _move_to, _line_to and _cubic_to calls are necessary to be defined but we
  * translate _quadratic_to calls to _cubic_to if the callback isn't defined.
  *
  * Since: EXPERIMENTAL

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -143,7 +143,7 @@
 
 typedef struct hb_face_for_data_closure_t {
   hb_blob_t *blob;
-  unsigned int  index;
+  uint16_t  index;
 } hb_face_for_data_closure_t;
 
 static hb_face_for_data_closure_t *
@@ -156,7 +156,7 @@
     return nullptr;
 
   closure->blob = blob;
-  closure->index = index;
+  closure->index = (uint16_t) (index & 0xFFFFu);
 
   return closure;
 }
@@ -195,10 +195,20 @@
  * @index: The index of the face within @blob
  *
  * Constructs a new face object from the specified blob and
- * a face index into that blob. This is used for blobs of
- * file formats such as Dfont and TTC that can contain more
- * than one face.
+ * a face index into that blob.
  *
+ * The face index is used for blobs of file formats such as TTC and
+ * and DFont that can contain more than one face.  Face indices within
+ * such collections are zero-based.
+ *
+ * <note>Note: If the blob font format is not a collection, @index
+ * is ignored.  Otherwise, only the lower 16-bits of @index are used.
+ * The unmodified @index can be accessed via hb_face_get_index().</note>
+ *
+ * <note>Note: The high 16-bits of @index, if non-zero, are used by
+ * hb_font_create() to load named-instances in variable fonts.  See
+ * hb_font_create() for details.</note>
+ *
  * Return value: (transfer full): The new face object
  *
  * Since: 0.9.2
@@ -420,7 +430,8 @@
  * Assigns the specified face-index to @face. Fails if the
  * face is immutable.
  *
- * <note>Note: face indices within a collection are zero-based.</note>
+ * <note>Note: changing the index has no effect on the face itself
+ * This only changes the value returned by hb_face_get_index().</note>
  *
  * Since: 0.9.2
  **/

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -631,7 +631,7 @@
  * @destroy: (nullable): A callback to call when @data is not needed anymore
  * @replace: Whether to replace an existing data with the same key
  *
- * Attaches a user-data key/data pair to the specified font-functions structure. 
+ * Attaches a user-data key/data pair to the specified font-functions structure.
  *
  * Return value: %true if success, %false otherwise
  *
@@ -821,7 +821,7 @@
  * @glyph: (out): The glyph ID retrieved
  *
  * Fetches the nominal glyph ID for a Unicode code point in the
- * specified font. 
+ * specified font.
  *
  * This version of the function should not be used to fetch glyph IDs
  * for code points modified by variation selectors. For variation-selector
@@ -940,7 +940,7 @@
  * @advance_stride: The stride between successive advances
  *
  * Fetches the advances for a sequence of glyph IDs in the specified
- * font, for horizontal text segments. 
+ * font, for horizontal text segments.
  *
  * Since: 1.8.6
  **/
@@ -964,7 +964,7 @@
  * @advance_stride: (out): The stride between successive advances
  *
  * Fetches the advances for a sequence of glyph IDs in the specified
- * font, for vertical text segments.  
+ * font, for vertical text segments.
  *
  * Since: 1.8.6
  **/
@@ -1278,7 +1278,7 @@
  * @font: #hb_font_t to work upon
  * @glyph: The glyph ID to query
  * @direction: The direction of the text segment
- * @x: (inout): Input = The original X coordinate 
+ * @x: (inout): Input = The original X coordinate
  *     Output = The X coordinate plus the X-coordinate of the origin
  * @y: (inout): Input = The original Y coordinate
  *     Output = The Y coordinate plus the Y-coordinate of the origin
@@ -1306,7 +1306,7 @@
  * @font: #hb_font_t to work upon
  * @glyph: The glyph ID to query
  * @direction: The direction of the text segment
- * @x: (inout): Input = The original X coordinate 
+ * @x: (inout): Input = The original X coordinate
  *     Output = The X coordinate minus the X-coordinate of the origin
  * @y: (inout): Input = The original Y coordinate
  *     Output = The Y coordinate minus the Y-coordinate of the origin
@@ -1477,6 +1477,8 @@
 
   1000, /* x_scale */
   1000, /* y_scale */
+  0., /* slant */
+  0., /* slant_xy; */
   1<<16, /* x_mult */
   1<<16, /* y_mult */
 
@@ -1521,6 +1523,13 @@
  *
  * Constructs a new font object from the specified face.
  *
+ * <note>Note: If @face's index value (as passed to hb_face_create()
+ * has non-zero top 16-bits, those bits minus one are passed to
+ * hb_font_set_var_named_instance(), effectively loading a named-instance
+ * of a variable font, instead of the default-instance.  This allows
+ * specifying which named-instance to load by default when creating the
+ * face.</note>
+ *
  * Return value: (transfer full): The new font object
  *
  * Since: 0.9.2
@@ -1535,6 +1544,11 @@
   hb_ot_font_set_funcs (font);
 #endif
 
+#ifndef HB_NO_VAR
+  if (face && face->index >> 16)
+    hb_font_set_var_named_instance (font, (face->index >> 16) - 1);
+#endif
+
   return font;
 }
 
@@ -1578,6 +1592,7 @@
 
   font->x_scale = parent->x_scale;
   font->y_scale = parent->y_scale;
+  font->slant = parent->slant;
   font->mults_changed ();
   font->x_ppem = parent->x_ppem;
   font->y_ppem = parent->y_ppem;
@@ -1668,12 +1683,12 @@
 /**
  * hb_font_set_user_data: (skip)
  * @font: #hb_font_t to work upon
- * @key: The user-data key 
+ * @key: The user-data key
  * @data: A pointer to the user data
  * @destroy: (nullable): A callback to call when @data is not needed anymore
  * @replace: Whether to replace an existing data with the same key
  *
- * Attaches a user-data key/data pair to the specified font object. 
+ * Attaches a user-data key/data pair to the specified font object.
  *
  * Return value: %true if success, %false otherwise
  *
@@ -1875,7 +1890,7 @@
  * @font_data: (destroy destroy) (scope notified): Data to attach to @font
  * @destroy: (nullable): The function to call when @font_data is not needed anymore
  *
- * Replaces the user data attached to a font, updating the font's 
+ * Replaces the user data attached to a font, updating the font's
  * @destroy callback.
  *
  * Since: 0.9.2
@@ -1949,7 +1964,7 @@
  * @x_ppem: Horizontal ppem value to assign
  * @y_ppem: Vertical ppem value to assign
  *
- * Sets the horizontal and vertical pixels-per-em (ppem) of a font. 
+ * Sets the horizontal and vertical pixels-per-em (ppem) of a font.
  *
  * Since: 0.9.2
  **/
@@ -1971,7 +1986,7 @@
  * @x_ppem: (out): Horizontal ppem value
  * @y_ppem: (out): Vertical ppem value
  *
- * Fetches the horizontal and vertical points-per-em (ppem) of a font. 
+ * Fetches the horizontal and vertical points-per-em (ppem) of a font.
  *
  * Since: 0.9.2
  **/
@@ -2015,7 +2030,7 @@
  *
  * Return value: Point size.  A value of zero means "not set."
  *
- * Since: 0.9.2
+ * Since: 1.6.0
  **/
 float
 hb_font_get_ptem (hb_font_t *font)
@@ -2023,6 +2038,49 @@
   return font->ptem;
 }
 
+/**
+ * hb_font_set_synthetic_slant:
+ * @font: #hb_font_t to work upon
+ * @slant: synthetic slant value.
+ *
+ * Sets the "synthetic slant" of a font.  By default is zero.
+ * Synthetic slant is the graphical skew that the renderer
+ * applies to the font at rendering time.
+ *
+ * HarfBuzz needs to know this value to adjust shaping results,
+ * metrics, and style values to match the slanted rendering.
+ *
+ * <note>Note: The slant value is a ratio.  For example, a
+ * 20% slant would be represented as a 0.2 value.</note>
+ *
+ * Since: 3.3.0
+ **/
+HB_EXTERN void
+hb_font_set_synthetic_slant (hb_font_t *font, float slant)
+{
+  if (hb_object_is_immutable (font))
+    return;
+
+  font->slant = slant;
+  font->mults_changed ();
+}
+
+/**
+ * hb_font_get_synthetic_slant:
+ * @font: #hb_font_t to work upon
+ *
+ * Fetches the "synthetic slant" of a font.
+ *
+ * Return value: Synthetic slant.  By default is zero.
+ *
+ * Since: 3.3.0
+ **/
+HB_EXTERN float
+hb_font_get_synthetic_slant (hb_font_t *font)
+{
+  return font->slant;
+}
+
 #ifndef HB_NO_VAR
 /*
  * Variations
@@ -2036,6 +2094,10 @@
  *
  * Applies a list of font-variation settings to a font.
  *
+ * Note that this overrides all existing variations set on @font.
+ * Axes not included in @variations will be effectively set to their
+ * default values.
+ *
  * Since: 1.4.2
  */
 void
@@ -2091,6 +2153,10 @@
  * Applies a list of variation coordinates (in design-space units)
  * to a font.
  *
+ * Note that this overrides all existing variations set on @font.
+ * Axes not included in @coords will be effectively set to their
+ * default values.
+ *
  * Since: 1.4.2
  */
 void
@@ -2154,6 +2220,10 @@
  * Applies a list of variation coordinates (in normalized units)
  * to a font.
  *
+ * Note that this overrides all existing variations set on @font.
+ * Axes not included in @coords will be effectively set to their
+ * default values.
+ *
  * <note>Note: Coordinates should be normalized to 2.14.</note>
  *
  * Since: 1.4.2
@@ -2196,14 +2266,19 @@
 /**
  * hb_font_get_var_coords_normalized:
  * @font: #hb_font_t to work upon
- * @length: Number of coordinates retrieved
+ * @length: (out): Number of coordinates retrieved
  *
  * Fetches the list of normalized variation coordinates currently
  * set on a font.
  *
+ * Note that this returned array may only contain values for some
+ * (or none) of the axes; omitted axes effectively have zero values.
+ *
  * Return value is valid as long as variation coordinates of the font
  * are not modified.
  *
+ * Return value: coordinates array
+ *
  * Since: 1.4.2
  */
 const int *
@@ -2216,18 +2291,24 @@
   return font->coords;
 }
 
-#ifdef HB_EXPERIMENTAL_API
 /**
  * hb_font_get_var_coords_design:
  * @font: #hb_font_t to work upon
- * @length: (out): number of coordinates
+ * @length: (out): Number of coordinates retrieved
  *
+ * Fetches the list of variation coordinates (in design-space units) currently
+ * set on a font.
+ *
+ * Note that this returned array may only contain values for some
+ * (or none) of the axes; omitted axes effectively have their default
+ * values.
+ *
  * Return value is valid as long as variation coordinates of the font
  * are not modified.
  *
  * Return value: coordinates array
  *
- * Since: EXPERIMENTAL
+ * Since: 3.3.0
  */
 const float *
 hb_font_get_var_coords_design (hb_font_t *font,
@@ -2239,7 +2320,6 @@
   return font->design_coords;
 }
 #endif
-#endif
 
 #ifndef HB_DISABLE_DEPRECATED
 /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1024,6 +1024,12 @@
 hb_font_get_ptem (hb_font_t *font);
 
 HB_EXTERN void
+hb_font_set_synthetic_slant (hb_font_t *font, float slant);
+
+HB_EXTERN float
+hb_font_get_synthetic_slant (hb_font_t *font);
+
+HB_EXTERN void
 hb_font_set_variations (hb_font_t *font,
 			const hb_variation_t *variations,
 			unsigned int variations_length);
@@ -1033,11 +1039,9 @@
 			       const float *coords,
 			       unsigned int coords_length);
 
-#ifdef HB_EXPERIMENTAL_API
 HB_EXTERN const float *
 hb_font_get_var_coords_design (hb_font_t *font,
 			       unsigned int *length);
-#endif
 
 HB_EXTERN void
 hb_font_set_var_coords_normalized (hb_font_t *font,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -109,6 +109,8 @@
 
   int32_t x_scale;
   int32_t y_scale;
+  float slant;
+  float slant_xy;
   int64_t x_mult;
   int64_t y_mult;
 
@@ -617,6 +619,7 @@
     signed upem = face->get_upem ();
     x_mult = ((int64_t) x_scale << 16) / upem;
     y_mult = ((int64_t) y_scale << 16) / upem;
+    slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
   }
 
   hb_position_t em_mult (int16_t v, int64_t mult)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -439,7 +439,8 @@
   if (feats) gr_featureval_destroy (feats);
   gr_seg_destroy (seg);
 
-  buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+  buffer->clear_glyph_flags ();
+  buffer->unsafe_to_break ();
 
   return true;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -90,8 +90,8 @@
    * it will be returning pointer to temporary rvalue.
    * TODO Use a wrapper return type to fix for non-reference type. */
   template <typename T = item_t,
-	    hb_enable_if (hb_is_reference (T))>
-  hb_remove_reference<item_t>* operator -> () const { return hb_addressof (**thiz()); }
+	    hb_enable_if (std::is_reference<T>::value)>
+  hb_remove_reference<item_t>* operator -> () const { return std::addressof (**thiz()); }
   item_t operator * () const { return thiz()->__item__ (); }
   item_t operator * () { return thiz()->__item__ (); }
   item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); }
@@ -289,7 +289,7 @@
 {
   private:
   template <typename Iter2 = Iter,
-	    hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<hb_add_const<Item>>))>
+	    hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<const Item>))>
   static hb_true_type impl (hb_priority<2>);
   template <typename Iter2 = Iter>
   static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_type ());

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -49,6 +49,10 @@
 	     hb_mask_t    kern_mask,
 	     bool         scale = true) const
   {
+    if (!buffer->message (font, "start kern"))
+      return;
+
+    buffer->unsafe_to_concat ();
     OT::hb_ot_apply_context_t c (1, font, buffer);
     c.set_lookup_mask (kern_mask);
     c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
@@ -67,7 +71,8 @@
       }
 
       skippy_iter.reset (idx, 1);
-      if (!skippy_iter.next ())
+      unsigned unsafe_to;
+      if (!skippy_iter.next (&unsafe_to))
       {
 	idx++;
 	continue;
@@ -125,6 +130,8 @@
     skip:
       idx = skippy_iter.idx;
     }
+
+    (void) buffer->message (font, "end kern");
   }
 
   const Driver &driver;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -194,7 +194,8 @@
   }
 
   const Returned * operator -> () const { return get (); }
-  const Returned & operator * () const  { return *get (); }
+  template <typename U = Returned, hb_enable_if (!hb_is_same (U, void))>
+  const U & operator * () const  { return *get (); }
   explicit operator bool () const
   { return get_stored () != Funcs::get_null (); }
   template <typename C> operator const C * () const { return get (); }
@@ -244,7 +245,7 @@
   {
     Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
     if (likely (p))
-      p->init (data);
+      p = new (p) Stored (data);
     return p;
   }
   static Stored *create ()
@@ -251,12 +252,12 @@
   {
     Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
     if (likely (p))
-      p->init ();
+      p = new (p) Stored ();
     return p;
   }
   static void destroy (Stored *p)
   {
-    p->fini ();
+    p->~Stored ();
     hb_free (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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -37,13 +37,10 @@
 template <typename K, typename V,
 	  typename k_invalid_t = K,
 	  typename v_invalid_t = V,
-	  k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
-	  v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
+	  k_invalid_t kINVALID = std::is_pointer<K>::value ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
+	  v_invalid_t vINVALID = std::is_pointer<V>::value ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
 struct hb_hashmap_t
 {
-  static constexpr K INVALID_KEY   = kINVALID;
-  static constexpr V INVALID_VALUE = vINVALID;
-
   hb_hashmap_t ()  { init (); }
   ~hb_hashmap_t () { fini (); }
 
@@ -64,11 +61,6 @@
     hb_copy (o, *this);
   }
 
-  static_assert (std::is_trivially_copyable<K>::value, "");
-  static_assert (std::is_trivially_copyable<V>::value, "");
-  static_assert (std::is_trivially_destructible<K>::value, "");
-  static_assert (std::is_trivially_destructible<V>::value, "");
-
   struct item_t
   {
     K key;
@@ -75,13 +67,34 @@
     V value;
     uint32_t hash;
 
-    void clear () { key = kINVALID; value = vINVALID; hash = 0; }
+    void clear ()
+    {
+      new (std::addressof (key)) K ();
+      key = hb_coerce<K> (kINVALID);
+      new (std::addressof (value)) V ();
+      value = hb_coerce<V> (vINVALID);
+      hash = 0;
+    }
 
     bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); }
     bool operator == (const item_t &o) { return *this == o.key; }
-    bool is_unused () const    { return key == kINVALID; }
-    bool is_tombstone () const { return key != kINVALID && value == vINVALID; }
-    bool is_real () const { return key != kINVALID && value != vINVALID; }
+    bool is_unused () const
+    {
+      const K inv = hb_coerce<K> (kINVALID);
+      return key == inv;
+    }
+    bool is_tombstone () const
+    {
+      const K kinv = hb_coerce<K> (kINVALID);
+      const V vinv = hb_coerce<V> (vINVALID);
+      return key != kinv && value == vinv;
+    }
+    bool is_real () const
+    {
+      const K kinv = hb_coerce<K> (kINVALID);
+      const V vinv = hb_coerce<V> (vINVALID);
+      return key != kinv && value != vinv;
+    }
     hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
   };
 
@@ -118,8 +131,13 @@
   }
   void fini_shallow ()
   {
-    hb_free (items);
-    items = nullptr;
+    if (likely (items)) {
+      unsigned size = mask + 1;
+      for (unsigned i = 0; i < size; i++)
+        items[i].~item_t ();
+      hb_free (items);
+      items = nullptr;
+    }
     population = occupancy = 0;
   }
   void fini ()
@@ -163,10 +181,15 @@
     /* Insert back old items. */
     if (old_items)
       for (unsigned int i = 0; i < old_size; i++)
+      {
 	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 ();
+      }
 
     hb_free (old_items);
 
@@ -178,15 +201,14 @@
 
   V get (K key) const
   {
-    if (unlikely (!items)) return vINVALID;
+    if (unlikely (!items)) return hb_coerce<V> (vINVALID);
     unsigned int i = bucket_for (key);
-    return items[i].is_real () && items[i] == key ? items[i].value : vINVALID;
+    return items[i].is_real () && items[i] == key ? items[i].value : hb_coerce<V> (vINVALID);
   }
 
-  void del (K key) { set (key, vINVALID); }
+  void del (K key) { set (key, hb_coerce<V> (vINVALID)); }
 
   /* Has interface. */
-  static constexpr V SENTINEL = vINVALID;
   typedef V value_t;
   value_t operator [] (K k) const { return get (k); }
   bool has (K k, V *vp = nullptr) const
@@ -193,7 +215,8 @@
   {
     V v = (*this)[k];
     if (vp) *vp = v;
-    return v != SENTINEL;
+    const V vinv = hb_coerce<V> (vINVALID);
+    return v != vinv;
   }
   /* Projection. */
   V operator () (K k) const { return get (k); }
@@ -248,11 +271,13 @@
   bool set_with_hash (K key, uint32_t hash, VV&& value)
   {
     if (unlikely (!successful)) return false;
-    if (unlikely (key == kINVALID)) return true;
+    const K kinv = hb_coerce<K> (kINVALID);
+    if (unlikely (key == kinv)) return true;
     if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
     unsigned int i = bucket_for_hash (key, hash);
 
-    if (value == vINVALID && items[i].key != key)
+    const V vinv = hb_coerce<V> (vINVALID);
+    if (value == vinv && items[i].key != key)
       return true; /* Trying to delete non-existent key. */
 
     if (!items[i].is_unused ())

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -29,6 +29,7 @@
 
 #include "hb.hh"
 
+#include <memory>
 #include <type_traits>
 #include <utility>
 
@@ -85,22 +86,6 @@
 template <typename T> struct hb_type_identity_t { typedef T type; };
 template <typename T> using hb_type_identity = typename hb_type_identity_t<T>::type;
 
-struct
-{
-  template <typename T> constexpr T*
-  operator () (T& arg) const
-  {
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
-    /* https://en.cppreference.com/w/cpp/memory/addressof */
-    return reinterpret_cast<T*> (
-	     &const_cast<char&> (
-		reinterpret_cast<const volatile char&> (arg)));
-#pragma GCC diagnostic pop
-  }
-}
-HB_FUNCOBJ (hb_addressof);
-
 template <typename T> static inline T hb_declval ();
 #define hb_declval(T) (hb_declval<T> ())
 
@@ -107,8 +92,7 @@
 template <typename T> struct hb_match_const		: hb_type_identity_t<T>, hb_false_type	{};
 template <typename T> struct hb_match_const<const T>	: hb_type_identity_t<T>, hb_true_type	{};
 template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
-template <typename T> using hb_add_const = const T;
-#define hb_is_const(T) hb_match_const<T>::value
+
 template <typename T> struct hb_match_reference		: hb_type_identity_t<T>, hb_false_type	{};
 template <typename T> struct hb_match_reference<T &>	: hb_type_identity_t<T>, hb_true_type	{};
 template <typename T> struct hb_match_reference<T &&>	: hb_type_identity_t<T>, hb_true_type	{};
@@ -119,7 +103,7 @@
 template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_type_identity<T&&>;
 template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
 template <typename T> using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference<T> (hb_prioritize));
-#define hb_is_reference(T) hb_match_reference<T>::value
+
 template <typename T> struct hb_match_pointer		: hb_type_identity_t<T>, hb_false_type	{};
 template <typename T> struct hb_match_pointer<T *>	: hb_type_identity_t<T>, hb_true_type	{};
 template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
@@ -126,7 +110,6 @@
 template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<hb_remove_reference<T>*>;
 template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<T>;
 template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
-#define hb_is_pointer(T) hb_match_pointer<T>::value
 
 
 /* TODO Add feature-parity to std::decay. */
@@ -137,8 +120,8 @@
 template <typename From, typename To>
 using hb_is_cr_convertible = hb_bool_constant<
   hb_is_same (hb_decay<From>, hb_decay<To>) &&
-  (!hb_is_const (From) || hb_is_const (To)) &&
-  (!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To))
+  (!std::is_const<From>::value || std::is_const<To>::value) &&
+  (!std::is_reference<To>::value || std::is_const<To>::value || std::is_reference<To>::value)
 >;
 #define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
 
@@ -153,16 +136,6 @@
 }
 HB_FUNCOBJ (hb_deref);
 
-struct
-{
-  template <typename T> constexpr auto
-  operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v))
-
-  template <typename T> constexpr auto
-  operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
-}
-HB_FUNCOBJ (hb_ref);
-
 template <typename T>
 struct hb_reference_wrapper
 {
@@ -176,7 +149,7 @@
 template <typename T>
 struct hb_reference_wrapper<T&>
 {
-  hb_reference_wrapper (T& v) : v (hb_addressof (v)) {}
+  hb_reference_wrapper (T& v) : v (std::addressof (v)) {}
   bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
   bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
   operator T& () const { return *v; }

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1,177 +0,0 @@
-/*
- * Copyright © 2011,2012,2013  Google, Inc.
- * Copyright © 2021  Khaled Hosny
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb-ms-feature-ranges.hh"
-
-bool
-hb_ms_setup_features (const hb_feature_t                *features,
-		      unsigned int                       num_features,
-		      hb_vector_t<hb_ms_feature_t>      &feature_records, /* OUT */
-		      hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */)
-{
-  feature_records.shrink(0);
-  range_records.shrink(0);
-
-  /* Sort features by start/end events. */
-  hb_vector_t<hb_ms_feature_event_t> feature_events;
-  for (unsigned int i = 0; i < num_features; i++)
-  {
-    hb_ms_active_feature_t feature;
-    feature.fea.tag_le = hb_uint32_swap (features[i].tag);
-    feature.fea.value = features[i].value;
-    feature.order = i;
-
-    hb_ms_feature_event_t *event;
-
-    event = feature_events.push ();
-    event->index = features[i].start;
-    event->start = true;
-    event->feature = feature;
-
-    event = feature_events.push ();
-    event->index = features[i].end;
-    event->start = false;
-    event->feature = feature;
-  }
-  feature_events.qsort ();
-  /* Add a strategic final event. */
-  {
-    hb_ms_active_feature_t feature;
-    feature.fea.tag_le = 0;
-    feature.fea.value = 0;
-    feature.order = num_features + 1;
-
-    auto *event = feature_events.push ();
-    event->index = 0; /* This value does magic. */
-    event->start = false;
-    event->feature = feature;
-  }
-
-  /* Scan events and save features for each range. */
-  hb_vector_t<hb_ms_active_feature_t> active_features;
-  unsigned int last_index = 0;
-  for (unsigned int i = 0; i < feature_events.length; i++)
-  {
-    auto *event = &feature_events[i];
-
-    if (event->index != last_index)
-    {
-      /* Save a snapshot of active features and the range. */
-      auto *range = range_records.push ();
-      auto offset = feature_records.length;
-
-      active_features.qsort ();
-      for (unsigned int j = 0; j < active_features.length; j++)
-      {
-        if (!j || active_features[j].fea.tag_le != feature_records[feature_records.length - 1].tag_le)
-        {
-          feature_records.push (active_features[j].fea);
-        }
-        else
-        {
-          /* Overrides value for existing feature. */
-          feature_records[feature_records.length - 1].value = active_features[j].fea.value;
-        }
-      }
-
-      /* Will convert to pointer after all is ready, since feature_records.array
-       * may move as we grow it. */
-      range->features.features = reinterpret_cast<hb_ms_feature_t *> (offset);
-      range->features.num_features = feature_records.length - offset;
-      range->index_first = last_index;
-      range->index_last  = event->index - 1;
-
-      last_index = event->index;
-    }
-
-    if (event->start)
-    {
-      active_features.push (event->feature);
-    }
-    else
-    {
-      auto *feature = active_features.find (&event->feature);
-      if (feature)
-        active_features.remove (feature - active_features.arrayZ);
-    }
-  }
-
-  if (!range_records.length) /* No active feature found. */
-    num_features = 0;
-
-  /* Fixup the pointers. */
-  for (unsigned int i = 0; i < range_records.length; i++)
-  {
-    auto *range = &range_records[i];
-    range->features.features = (hb_ms_feature_t *) feature_records + reinterpret_cast<uintptr_t> (range->features.features);
-  }
-
-  return !!num_features;
-}
-
-void
-hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t>      &feature_records,
-			   hb_vector_t<hb_ms_range_record_t> &range_records,
-			   unsigned int                       chars_offset,
-			   unsigned int                       chars_len,
-			   uint16_t                          *log_clusters,
-			   hb_vector_t<hb_ms_features_t*>    &range_features, /* OUT */
-			   hb_vector_t<uint32_t>             &range_counts /* OUT */)
-{
-  range_features.shrink (0);
-  range_counts.shrink (0);
-
-  auto *last_range = &range_records[0];
-  for (unsigned int i = chars_offset; i < chars_len; i++)
-  {
-    auto *range = last_range;
-    while (log_clusters[i] < range->index_first)
-      range--;
-    while (log_clusters[i] > range->index_last)
-      range++;
-    if (!range_features.length ||
-        &range->features != range_features[range_features.length - 1])
-    {
-      auto **features = range_features.push ();
-      auto *c = range_counts.push ();
-      if (unlikely (!features || !c))
-      {
-        range_features.shrink (0);
-        range_counts.shrink (0);
-        break;
-      }
-      *features = &range->features;
-      *c = 1;
-    }
-    else
-    {
-      range_counts[range_counts.length - 1]++;
-    }
-
-    last_range = range;
-  }
-}

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -52,8 +52,8 @@
 	   a->fea.value < b->fea.value ? -1 : a->fea.value > b->fea.value ? 1 :
 	   0;
   }
-  bool operator== (const hb_ms_active_feature_t *f)
-  { return cmp (this, f) == 0; }
+  bool operator== (const hb_ms_active_feature_t& f) const
+  { return cmp (this, &f) == 0; }
 };
 
 struct hb_ms_feature_event_t {
@@ -77,14 +77,113 @@
   unsigned int index_last;  /* == end - 1 */
 };
 
-HB_INTERNAL bool
+static inline bool
 hb_ms_setup_features (const hb_feature_t                *features,
 		      unsigned int                       num_features,
 		      hb_vector_t<hb_ms_feature_t>      &feature_records, /* OUT */
-		      hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */);
+		      hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */)
+{
+  feature_records.shrink(0);
+  range_records.shrink(0);
 
+  /* Sort features by start/end events. */
+  hb_vector_t<hb_ms_feature_event_t> feature_events;
+  for (unsigned int i = 0; i < num_features; i++)
+  {
+    hb_ms_active_feature_t feature;
+    feature.fea.tag_le = hb_uint32_swap (features[i].tag);
+    feature.fea.value = features[i].value;
+    feature.order = i;
 
-HB_INTERNAL void
+    hb_ms_feature_event_t *event;
+
+    event = feature_events.push ();
+    event->index = features[i].start;
+    event->start = true;
+    event->feature = feature;
+
+    event = feature_events.push ();
+    event->index = features[i].end;
+    event->start = false;
+    event->feature = feature;
+  }
+  feature_events.qsort ();
+  /* Add a strategic final event. */
+  {
+    hb_ms_active_feature_t feature;
+    feature.fea.tag_le = 0;
+    feature.fea.value = 0;
+    feature.order = num_features + 1;
+
+    auto *event = feature_events.push ();
+    event->index = 0; /* This value does magic. */
+    event->start = false;
+    event->feature = feature;
+  }
+
+  /* Scan events and save features for each range. */
+  hb_vector_t<hb_ms_active_feature_t> active_features;
+  unsigned int last_index = 0;
+  for (unsigned int i = 0; i < feature_events.length; i++)
+  {
+    auto *event = &feature_events[i];
+
+    if (event->index != last_index)
+    {
+      /* Save a snapshot of active features and the range. */
+      auto *range = range_records.push ();
+      auto offset = feature_records.length;
+
+      active_features.qsort ();
+      for (unsigned int j = 0; j < active_features.length; j++)
+      {
+        if (!j || active_features[j].fea.tag_le != feature_records[feature_records.length - 1].tag_le)
+        {
+          feature_records.push (active_features[j].fea);
+        }
+        else
+        {
+          /* Overrides value for existing feature. */
+          feature_records[feature_records.length - 1].value = active_features[j].fea.value;
+        }
+      }
+
+      /* Will convert to pointer after all is ready, since feature_records.array
+       * may move as we grow it. */
+      range->features.features = reinterpret_cast<hb_ms_feature_t *> (offset);
+      range->features.num_features = feature_records.length - offset;
+      range->index_first = last_index;
+      range->index_last  = event->index - 1;
+
+      last_index = event->index;
+    }
+
+    if (event->start)
+    {
+      active_features.push (event->feature);
+    }
+    else
+    {
+      auto *feature = active_features.lsearch (event->feature);
+      if (feature)
+        active_features.remove (feature - active_features.arrayZ);
+    }
+  }
+
+  if (!range_records.length) /* No active feature found. */
+    num_features = 0;
+
+  /* Fixup the pointers. */
+  for (unsigned int i = 0; i < range_records.length; i++)
+  {
+    auto *range = &range_records[i];
+    range->features.features = (hb_ms_feature_t *) feature_records + reinterpret_cast<uintptr_t> (range->features.features);
+  }
+
+  return !!num_features;
+}
+
+static inline void
 hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t>      &feature_records,
 			   hb_vector_t<hb_ms_range_record_t> &range_records,
 			   unsigned int                       chars_offset,
@@ -91,6 +190,40 @@
 			   unsigned int                       chars_len,
 			   uint16_t                          *log_clusters,
 			   hb_vector_t<hb_ms_features_t*>    &range_features, /* OUT */
-			   hb_vector_t<uint32_t>             &range_counts /* OUT */);
+			   hb_vector_t<uint32_t>             &range_counts /* OUT */)
+{
+  range_features.shrink (0);
+  range_counts.shrink (0);
 
+  auto *last_range = &range_records[0];
+  for (unsigned int i = chars_offset; i < chars_len; i++)
+  {
+    auto *range = last_range;
+    while (log_clusters[i] < range->index_first)
+      range--;
+    while (log_clusters[i] > range->index_last)
+      range++;
+    if (!range_features.length ||
+        &range->features != range_features[range_features.length - 1])
+    {
+      auto **features = range_features.push ();
+      auto *c = range_counts.push ();
+      if (unlikely (!features || !c))
+      {
+        range_features.shrink (0);
+        range_counts.shrink (0);
+        break;
+      }
+      *features = &range->features;
+      *c = 1;
+    }
+    else
+    {
+      range_counts[range_counts.length - 1]++;
+    }
+
+    last_range = range;
+  }
+}
+
 #endif /* HB_MS_FEATURE_RANGES_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -53,7 +53,7 @@
   item_t *replace_or_insert (T v, lock_t &l, bool replace)
   {
     l.lock ();
-    item_t *item = items.find (v);
+    item_t *item = items.lsearch (v);
     if (item) {
       if (replace) {
 	item_t old = *item;
@@ -76,7 +76,7 @@
   void remove (T v, lock_t &l)
   {
     l.lock ();
-    item_t *item = items.find (v);
+    item_t *item = items.lsearch (v);
     if (item)
     {
       item_t old = *item;
@@ -93,7 +93,7 @@
   bool find (T v, item_t *i, lock_t &l)
   {
     l.lock ();
-    item_t *item = items.find (v);
+    item_t *item = items.lsearch (v);
     if (item)
       *i = *item;
     l.unlock ();

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -68,8 +68,6 @@
 typedef hb_vector_t<unsigned char> str_buff_t;
 struct str_buff_vec_t : hb_vector_t<str_buff_t>
 {
-  void fini () { SUPER::fini_deep (); }
-
   unsigned int total_size () const
   {
     unsigned int size = 0;

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1144,8 +1144,8 @@
     {
       sc.end_processing ();
       topDict.fini ();
-      fontDicts.fini_deep ();
-      privateDicts.fini_deep ();
+      fontDicts.fini ();
+      privateDicts.fini ();
       hb_blob_destroy (blob);
       blob = nullptr;
     }
@@ -1245,20 +1245,20 @@
     }
 
     protected:
-    hb_blob_t	           *blob;
+    hb_blob_t	           *blob = nullptr;
     hb_sanitize_context_t   sc;
 
     public:
-    const Encoding	    *encoding;
-    const Charset	    *charset;
-    const CFF1NameIndex     *nameIndex;
-    const CFF1TopDictIndex  *topDictIndex;
-    const CFF1StringIndex   *stringIndex;
-    const CFF1Subrs	    *globalSubrs;
-    const CFF1CharStrings   *charStrings;
-    const CFF1FDArray       *fdArray;
-    const CFF1FDSelect      *fdSelect;
-    unsigned int	     fdCount;
+    const Encoding	    *encoding = nullptr;
+    const Charset	    *charset = nullptr;
+    const CFF1NameIndex     *nameIndex = nullptr;
+    const CFF1TopDictIndex  *topDictIndex = nullptr;
+    const CFF1StringIndex   *stringIndex = nullptr;
+    const CFF1Subrs	    *globalSubrs = nullptr;
+    const CFF1CharStrings   *charStrings = nullptr;
+    const CFF1FDArray       *fdArray = nullptr;
+    const CFF1FDSelect      *fdSelect = nullptr;
+    unsigned int	     fdCount = 0;
 
     cff1_top_dict_values_t   topDict;
     hb_vector_t<cff1_font_dict_values_t>
@@ -1265,12 +1265,12 @@
 			     fontDicts;
     hb_vector_t<PRIVDICTVAL> privateDicts;
 
-    unsigned int	     num_glyphs;
+    unsigned int	     num_glyphs = 0;
   };
 
   struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     {
       SUPER::init (face);
 
@@ -1295,8 +1295,7 @@
       }
       glyph_names.qsort ();
     }
-
-    void fini ()
+    ~accelerator_t ()
     {
       glyph_names.fini ();
 
@@ -1398,7 +1397,10 @@
   DEFINE_SIZE_STATIC (4);
 };
 
-struct cff1_accelerator_t : cff1::accelerator_t {};
+struct cff1_accelerator_t : cff1::accelerator_t {
+  cff1_accelerator_t (hb_face_t *face) : cff1::accelerator_t (face) {}
+};
+
 } /* namespace OT */
 
 #endif /* HB_OT_CFF1_TABLE_HH */

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -397,7 +397,7 @@
   template <typename PRIVOPSET, typename PRIVDICTVAL>
   struct accelerator_templ_t
   {
-    void init (hb_face_t *face)
+    accelerator_templ_t (hb_face_t *face)
     {
       topDict.init ();
       fontDicts.init ();
@@ -412,15 +412,15 @@
       const OT::cff2 *cff2 = this->blob->template as<OT::cff2> ();
 
       if (cff2 == &Null (OT::cff2))
-      { fini (); return; }
+        goto fail;
 
       { /* parse top dict */
 	byte_str_t topDictStr (cff2 + cff2->topDict, cff2->topDictSize);
-	if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
+	if (unlikely (!topDictStr.sanitize (&sc))) goto fail;
 	cff2_top_dict_interpreter_t top_interp;
 	top_interp.env.init (topDictStr);
 	topDict.init ();
-	if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
+	if (unlikely (!top_interp.interpret (topDict))) goto fail;
       }
 
       globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize);
@@ -434,49 +434,55 @@
 	  (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) ||
 	  (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) ||
 	  (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count)))))
-      { fini (); return; }
+        goto fail;
 
       num_glyphs = charStrings->count;
       if (num_glyphs != sc.get_num_glyphs ())
-      { fini (); return; }
+        goto fail;
 
       fdCount = fdArray->count;
       if (!privateDicts.resize (fdCount))
-      { fini (); return; }
+        goto fail;
 
       /* parse font dicts and gather private dicts */
       for (unsigned int i = 0; i < fdCount; i++)
       {
 	const byte_str_t fontDictStr = (*fdArray)[i];
-	if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
+	if (unlikely (!fontDictStr.sanitize (&sc))) goto fail;
 	cff2_font_dict_values_t  *font;
 	cff2_font_dict_interpreter_t font_interp;
 	font_interp.env.init (fontDictStr);
 	font = fontDicts.push ();
-	if (unlikely (font == &Crap (cff2_font_dict_values_t))) { fini (); return; }
+	if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail;
 	font->init ();
-	if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
+	if (unlikely (!font_interp.interpret (*font))) goto fail;
 
 	const byte_str_t privDictStr (StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset), font->privateDictInfo.size);
-	if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
+	if (unlikely (!privDictStr.sanitize (&sc))) goto fail;
 	dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t>  priv_interp;
 	priv_interp.env.init(privDictStr);
 	privateDicts[i].init ();
-	if (unlikely (!priv_interp.interpret (privateDicts[i]))) { fini (); return; }
+	if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail;
 
 	privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset);
 	if (privateDicts[i].localSubrs != &Null (CFF2Subrs) &&
 	  unlikely (!privateDicts[i].localSubrs->sanitize (&sc)))
-	{ fini (); return; }
+	  goto fail;
       }
+
+
+      return;
+
+      fail:
+        _fini ();
     }
-
-    void fini ()
+    ~accelerator_templ_t () { _fini (); }
+    void _fini ()
     {
       sc.end_processing ();
       topDict.fini ();
-      fontDicts.fini_deep ();
-      privateDicts.fini_deep ();
+      fontDicts.fini ();
+      privateDicts.fini ();
       hb_blob_destroy (blob);
       blob = nullptr;
     }
@@ -484,26 +490,28 @@
     bool is_valid () const { return blob; }
 
     protected:
-    hb_blob_t			*blob;
+    hb_blob_t			*blob = nullptr;
     hb_sanitize_context_t	sc;
 
     public:
     cff2_top_dict_values_t	topDict;
-    const CFF2Subrs		*globalSubrs;
-    const CFF2VariationStore	*varStore;
-    const CFF2CharStrings	*charStrings;
-    const CFF2FDArray		*fdArray;
-    const CFF2FDSelect		*fdSelect;
-    unsigned int		fdCount;
+    const CFF2Subrs		*globalSubrs = nullptr;
+    const CFF2VariationStore	*varStore = nullptr;
+    const CFF2CharStrings	*charStrings = nullptr;
+    const CFF2FDArray		*fdArray = nullptr;
+    const CFF2FDSelect		*fdSelect = nullptr;
+    unsigned int		fdCount = 0;
 
     hb_vector_t<cff2_font_dict_values_t>     fontDicts;
     hb_vector_t<PRIVDICTVAL>  privateDicts;
 
-    unsigned int	      num_glyphs;
+    unsigned int	      num_glyphs = 0;
   };
 
   struct accelerator_t : accelerator_templ_t<cff2_private_dict_opset_t, cff2_private_dict_values_t>
   {
+    accelerator_t (hb_face_t *face) : accelerator_templ_t (face) {}
+
     HB_INTERNAL bool get_extents (hb_font_t *font,
 				  hb_codepoint_t glyph,
 				  hb_glyph_extents_t *extents) const;
@@ -525,7 +533,10 @@
   DEFINE_SIZE_STATIC (5);
 };
 
-struct cff2_accelerator_t : cff2::accelerator_t {};
+struct cff2_accelerator_t : cff2::accelerator_t {
+  cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {}
+};
+
 } /* namespace OT */
 
 #endif /* HB_OT_CFF2_TABLE_HH */

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -369,7 +369,6 @@
   {
     accelerator_t () {}
     accelerator_t (const CmapSubtableFormat4 *subtable) { init (subtable); }
-    ~accelerator_t () { fini (); }
 
     void init (const CmapSubtableFormat4 *subtable)
     {
@@ -381,7 +380,6 @@
       glyphIdArray = idRangeOffset + segCount;
       glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2;
     }
-    void fini () {}
 
     bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
     {
@@ -1607,7 +1605,7 @@
       unsigned format = (this + _.subtable).u.format;
       if (format == 12) has_format12 = true;
 
-      const EncodingRecord *table = hb_addressof (_);
+      const EncodingRecord *table = std::addressof (_);
       if      (_.platformID == 0 && _.encodingID ==  3) unicode_bmp = table;
       else if (_.platformID == 0 && _.encodingID ==  4) unicode_ucs4 = table;
       else if (_.platformID == 3 && _.encodingID ==  1) ms_bmp = table;
@@ -1665,7 +1663,7 @@
 
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     {
       this->table = hb_sanitize_context_t ().reference_table<cmap> (face);
       bool symbol;
@@ -1700,9 +1698,8 @@
 	}
       }
     }
+    ~accelerator_t () { this->table.destroy (); }
 
-    void fini () { this->table.destroy (); }
-
     bool get_nominal_glyph (hb_codepoint_t  unicode,
 			    hb_codepoint_t *glyph) const
     {
@@ -1863,7 +1860,9 @@
   DEFINE_SIZE_ARRAY (4, encodingRecord);
 };
 
-struct cmap_accelerator_t : cmap::accelerator_t {};
+struct cmap_accelerator_t : cmap::accelerator_t {
+  cmap_accelerator_t (hb_face_t *face) : cmap::accelerator_t (face) {}
+};
 
 } /* namespace OT */
 

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -360,6 +360,16 @@
 
 struct IndexSubtableRecord
 {
+  /* XXX Remove this and fix by not inserting it into vector. */
+  IndexSubtableRecord& operator = (const IndexSubtableRecord &o)
+  {
+    firstGlyphIndex = o.firstGlyphIndex;
+    lastGlyphIndex = o.lastGlyphIndex;
+    offsetToSubtable = (unsigned) o.offsetToSubtable;
+    assert (offsetToSubtable.is_null ());
+    return *this;
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -809,15 +819,14 @@
 
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     {
-      cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
-      cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
+      this->cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
+      this->cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
 
       upem = hb_face_get_upem (face);
     }
-
-    void fini ()
+    ~accelerator_t ()
     {
       this->cblc.destroy ();
       this->cbdt.destroy ();
@@ -978,8 +987,11 @@
   return_trace (CBLC::sink_cbdt (c, &cbdt_prime));
 }
 
-struct CBDT_accelerator_t : CBDT::accelerator_t {};
+struct CBDT_accelerator_t : CBDT::accelerator_t {
+  CBDT_accelerator_t (hb_face_t *face) : CBDT::accelerator_t (face) {}
+};
 
+
 } /* namespace OT */
 
 #endif /* HB_OT_COLOR_CBDT_TABLE_HH */

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -71,7 +71,7 @@
   bool paint_visited (const void *paint)
   {
     hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base);
-     if (visited_paint.has (delta))
+    if (visited_paint.in_error() || visited_paint.has (delta))
       return true;
 
     visited_paint.add (delta);
@@ -1270,14 +1270,10 @@
 
   struct accelerator_t
   {
-    accelerator_t () {}
-    ~accelerator_t () { fini (); }
-
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     { colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
+    ~accelerator_t () { this->colr.destroy (); }
 
-    void fini () { this->colr.destroy (); }
-
     bool is_valid () { return colr.get_blob ()->length; }
 
     void closure_glyphs (hb_codepoint_t glyph,
@@ -1535,6 +1531,10 @@
   DEFINE_SIZE_MIN (14);
 };
 
+struct COLR_accelerator_t : COLR::accelerator_t {
+  COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {}
+};
+
 } /* namespace OT */
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -43,7 +43,7 @@
   const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
   for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
   {
-    const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i];
+    const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i];
     paint.dispatch (c);
   }
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -202,12 +202,12 @@
 
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     {
       table = hb_sanitize_context_t ().reference_table<sbix> (face);
       num_glyphs = face->get_num_glyphs ();
     }
-    void fini () { table.destroy (); }
+    ~accelerator_t () { table.destroy (); }
 
     bool has_data () const { return table->has_data (); }
 
@@ -407,8 +407,11 @@
   DEFINE_SIZE_ARRAY (8, strikes);
 };
 
-struct sbix_accelerator_t : sbix::accelerator_t {};
+struct sbix_accelerator_t : sbix::accelerator_t {
+  sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {}
+};
 
+
 } /* namespace OT */
 
 #endif /* HB_OT_COLOR_SBIX_TABLE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -79,9 +79,9 @@
 
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     { table = hb_sanitize_context_t ().reference_table<SVG> (face); }
-    void fini () { table.destroy (); }
+    ~accelerator_t () { table.destroy (); }
 
     hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
     {
@@ -116,7 +116,9 @@
   DEFINE_SIZE_STATIC (10);
 };
 
-struct SVG_accelerator_t : SVG::accelerator_t {};
+struct SVG_accelerator_t : SVG::accelerator_t {
+  SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {}
+};
 
 } /* namespace OT */
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -90,15 +90,15 @@
 /**
  * hb_ot_color_palette_get_name_id:
  * @face: #hb_face_t to work upon
- * @palette_index: The index of the color palette 
+ * @palette_index: The index of the color palette
  *
  * Fetches the `name` table Name ID that provides display names for
- * a `CPAL` color palette. 
+ * a `CPAL` color palette.
  *
  * Palette display names can be generic (e.g., "Default") or provide
  * specific, themed names (e.g., "Spring", "Summer", "Fall", and "Winter").
  *
- * Return value: the Named ID found for the palette. 
+ * Return value: the Named ID found for the palette.
  * If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID.
  *
  * Since: 2.1.0
@@ -116,7 +116,7 @@
  * @color_index: The index of the color
  *
  * Fetches the `name` table Name ID that provides display names for
- * the specificed color in a face's `CPAL` color palette. 
+ * the specified color in a face's `CPAL` color palette.
  *
  * Display names can be generic (e.g., "Background") or specific
  * (e.g., "Eye color").
@@ -256,6 +256,8 @@
  *
  * Fetches the SVG document for a glyph. The blob may be either plain text or gzip-encoded.
  *
+ * If the glyph has no SVG document, the singleton empty blob is returned.
+ *
  * Return value: (transfer full): An #hb_blob_t containing the SVG document of the glyph, if available
  *
  * Since: 2.1.0
@@ -296,6 +298,8 @@
  * as input. To get an optimally sized PNG blob, the UPEM value must be set on the @font
  * object. If UPEM is unset, the blob returned will be the largest PNG available.
  *
+ * If the glyph has no PNG image, the singleton empty blob is returned.
+ *
  * Return value: (transfer full): An #hb_blob_t containing the PNG image for the glyph, if available
  *
  * Since: 2.1.0

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-deprecated.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-deprecated.h	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-deprecated.h	2022-02-13 03:14:24 UTC (rev 61999)
@@ -50,7 +50,22 @@
  */
 #define HB_MATH_GLYPH_PART_FLAG_EXTENDER HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER
 
+/* https://github.com/harfbuzz/harfbuzz/pull/3417 */
+/**
+ * HB_OT_MATH_SCRIPT:
+ *
+ * Use #HB_SCRIPT_MATH or #HB_OT_TAG_MATH_SCRIPT instead.
+ *
+ * <note>Previous versions of this documentation recommended passing
+ * #HB_OT_MATH_SCRIPT to hb_buffer_set_script() to enable math shaping, but this
+ * usage is no longer supported. Use #HB_SCRIPT_MATH instead.</note>
+ *
+ * Since: 1.3.3
+ * Deprecated: 3.4.0
+ */
+#define HB_OT_MATH_SCRIPT HB_OT_TAG_MATH_SCRIPT
 
+
 /* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */
 HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) hb_bool_t
 hb_ot_layout_table_choose_script (hb_face_t      *face,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -207,8 +207,7 @@
   _populate_subset_glyphs (const hb_subset_plan_t   *plan,
 			   hb_vector_t<SubsetGlyph> *glyphs /* OUT */) const
   {
-    OT::glyf::accelerator_t glyf;
-    glyf.init (plan->source);
+    OT::glyf::accelerator_t glyf (plan->source);
 
     + hb_range (plan->num_output_glyphs ())
     | hb_map ([&] (hb_codepoint_t new_gid)
@@ -233,8 +232,6 @@
 	      })
     | hb_sink (glyphs)
     ;
-
-    glyf.fini ();
   }
 
   static bool
@@ -595,7 +592,7 @@
         if (unlikely (!header.numberOfContours)) return;
 
         unsigned flags_offset = length (instructions_length ());
-        if (unlikely (length (flags_offset + 1) > bytes.length)) return;
+        if (unlikely (flags_offset + 1 > bytes.length)) return;
 
 	HBUINT8 &first_flag = (HBUINT8 &) StructAtOffset<HBUINT16> (&bytes, flags_offset);
         first_flag = (uint8_t) first_flag | FLAG_OVERLAP_SIMPLE;
@@ -920,7 +917,7 @@
 
   struct accelerator_t
   {
-    void init (hb_face_t *face_)
+    accelerator_t (hb_face_t *face)
     {
       short_offset = false;
       num_glyphs = 0;
@@ -933,7 +930,6 @@
 #ifndef HB_NO_VERTICAL
       vmtx = nullptr;
 #endif
-      face = face_;
       const OT::head &head = *face->table.head;
       if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
 	/* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
@@ -953,8 +949,7 @@
       num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
       num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
     }
-
-    void fini ()
+    ~accelerator_t ()
     {
       loca_table.destroy ();
       glyf_table.destroy ();
@@ -1291,7 +1286,6 @@
     unsigned int num_glyphs;
     hb_blob_ptr_t<loca> loca_table;
     hb_blob_ptr_t<glyf> glyf_table;
-    hb_face_t *face;
   };
 
   struct SubsetGlyph
@@ -1358,8 +1352,11 @@
 			 * defining it _MIN instead. */
 };
 
-struct glyf_accelerator_t : glyf::accelerator_t {};
+struct glyf_accelerator_t : glyf::accelerator_t {
+  glyf_accelerator_t (hb_face_t *face) : glyf::accelerator_t (face) {}
+};
 
+
 } /* namespace OT */
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -127,9 +127,20 @@
     T *table_prime = c->serializer->start_embed <T> ();
     if (unlikely (!table_prime)) return_trace (false);
 
-    accelerator_t _mtx;
-    _mtx.init (c->plan->source);
-    unsigned num_advances = _mtx.num_advances_for_subset (c->plan);
+    accelerator_t _mtx (c->plan->source);
+    unsigned num_advances;
+    {
+      /* Determine num_advances to encode. */
+      auto& plan = c->plan;
+      num_advances = plan->num_output_glyphs ();
+      hb_codepoint_t old_gid = 0;
+      unsigned int last_advance = plan->old_gid_for_new_gid (num_advances - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0;
+      while (num_advances > 1 &&
+	     last_advance == (plan->old_gid_for_new_gid (num_advances - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0))
+      {
+	num_advances--;
+      }
+    }
 
     auto it =
     + hb_range (c->plan->num_output_glyphs ())
@@ -144,8 +155,6 @@
 
     table_prime->serialize (c->serializer, it, num_advances);
 
-    _mtx.fini ();
-
     if (unlikely (c->serializer->in_error ()))
       return_trace (false);
 
@@ -160,8 +169,8 @@
   {
     friend struct hmtxvmtx;
 
-    void init (hb_face_t *face,
-	       unsigned int default_advance_ = 0)
+    accelerator_t (hb_face_t *face,
+		   unsigned int default_advance_ = 0)
     {
       default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
 
@@ -193,8 +202,7 @@
 
       var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag);
     }
-
-    void fini ()
+    ~accelerator_t ()
     {
       table.destroy ();
       var_table.destroy ();
@@ -263,32 +271,6 @@
 #endif
     }
 
-    unsigned int num_advances_for_subset (const hb_subset_plan_t *plan) const
-    {
-      unsigned int num_advances = plan->num_output_glyphs ();
-      unsigned int last_advance = _advance_for_new_gid (plan,
-							num_advances - 1);
-      while (num_advances > 1 &&
-	     last_advance == _advance_for_new_gid (plan,
-						   num_advances - 2))
-      {
-	num_advances--;
-      }
-
-      return num_advances;
-    }
-
-    private:
-    unsigned int _advance_for_new_gid (const hb_subset_plan_t *plan,
-				       hb_codepoint_t new_gid) const
-    {
-      hb_codepoint_t old_gid;
-      if (!plan->old_gid_for_new_gid (new_gid, &old_gid))
-	return 0;
-
-      return get_advance (old_gid);
-    }
-
     protected:
     unsigned int num_metrics;
     unsigned int num_advances;
@@ -338,8 +320,12 @@
   static constexpr bool is_horizontal = false;
 };
 
-struct hmtx_accelerator_t : hmtx::accelerator_t {};
-struct vmtx_accelerator_t : vmtx::accelerator_t {};
+struct hmtx_accelerator_t : hmtx::accelerator_t {
+  hmtx_accelerator_t (hb_face_t *face) : hmtx::accelerator_t (face) {}
+};
+struct vmtx_accelerator_t : vmtx::accelerator_t {
+  vmtx_accelerator_t (hb_face_t *face) : vmtx::accelerator_t (face) {}
+};
 
 } /* namespace OT */
 

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -128,7 +128,7 @@
   bool visited (const T *p, hb_set_t &visited_set)
   {
     hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) p - (uintptr_t) table);
-     if (visited_set.has (delta))
+    if (visited_set.in_error () || visited_set.has (delta))
       return true;
 
     visited_set.add (delta);
@@ -655,7 +655,6 @@
   void collect_features (hb_prune_langsys_context_t *c) const
   {
     if (!has_required_feature () && !get_feature_count ()) return;
-    if (c->visitedLangsys (this)) return;
     if (has_required_feature () &&
         c->duplicate_feature_map->has (reqFeatureIndex))
       c->new_feature_indexes->add (get_required_feature_index ());
@@ -750,11 +749,15 @@
     {
       //only collect features from non-redundant langsys
       const LangSys& d = get_default_lang_sys ();
-      d.collect_features (c);
+      if (!c->visitedLangsys (&d)) {
+        d.collect_features (c);
+      }
 
       for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
       {
+
         const LangSys& l = this+_.first.offset;
+        if (c->visitedLangsys (&l)) continue;
         if (l.compare (d, c->duplicate_feature_map)) continue;
 
         l.collect_features (c);
@@ -766,6 +769,7 @@
       for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
       {
         const LangSys& l = this+_.first.offset;
+        if (c->visitedLangsys (&l)) continue;
         l.collect_features (c);
         c->script_langsys_map->get (script_index)->add (_.second);
       }
@@ -845,7 +849,7 @@
     if (unlikely (!c->check_struct (this))) return_trace (false);
 
     /* This subtable has some "history", if you will.  Some earlier versions of
-     * Adobe tools calculated the offset of the FeatureParams sutable from the
+     * Adobe tools calculated the offset of the FeatureParams subtable from the
      * beginning of the FeatureList table!  Now, that is dealt with in the
      * Feature implementation.  But we still need to be able to tell junk from
      * real data.  Note: We don't check that the nameID actually exists.
@@ -2926,8 +2930,6 @@
 
     hb_vector_t<hb_inc_bimap_t> inner_maps;
     inner_maps.resize ((unsigned) dataSets.len);
-    for (unsigned i = 0; i < inner_maps.length; i++)
-      inner_maps[i].init ();
 
     for (unsigned idx : c->plan->layout_variation_indices->iter ())
     {
@@ -2935,18 +2937,11 @@
       uint16_t minor = idx & 0xFFFF;
 
       if (major >= inner_maps.length)
-      {
-	for (unsigned i = 0; i < inner_maps.length; i++)
-	  inner_maps[i].fini ();
 	return_trace (false);
-      }
       inner_maps[major].add (minor);
     }
     varstore_prime->serialize (c->serializer, this, inner_maps.as_array ());
 
-    for (unsigned i = 0; i < inner_maps.length; i++)
-      inner_maps[i].fini ();
-
     return_trace (
         !c->serializer->in_error()
         && varstore_prime->dataSets);

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -585,18 +585,17 @@
 
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     {
-      this->table = hb_sanitize_context_t ().reference_table<GDEF> (face);
-      if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
+      table = hb_sanitize_context_t ().reference_table<GDEF> (face);
+      if (unlikely (table->is_blocklisted (table.get_blob (), face)))
       {
-	hb_blob_destroy (this->table.get_blob ());
-	this->table = hb_blob_get_empty ();
+	hb_blob_destroy (table.get_blob ());
+	table = hb_blob_get_empty ();
       }
     }
+    ~accelerator_t () { table.destroy (); }
 
-    void fini () { this->table.destroy (); }
-
     hb_blob_ptr_t<GDEF> table;
   };
 
@@ -715,7 +714,9 @@
   DEFINE_SIZE_MIN (12);
 };
 
-struct GDEF_accelerator_t : GDEF::accelerator_t {};
+struct GDEF_accelerator_t : GDEF::accelerator_t {
+  GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
+};
 
 } /* namespace OT */
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -706,7 +706,7 @@
 
     float mark_x, mark_y, base_x, base_y;
 
-    buffer->unsafe_to_break (glyph_pos, buffer->idx);
+    buffer->unsafe_to_break (glyph_pos, buffer->idx + 1);
     mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
     glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
 
@@ -1235,6 +1235,7 @@
       buffer->idx = pos;
       return_trace (true);
     }
+    buffer->unsafe_to_concat (buffer->idx, pos + 1);
     return_trace (false);
   }
 
@@ -1362,7 +1363,12 @@
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
-    if (!skippy_iter.next ()) return_trace (false);
+    unsigned unsafe_to;
+    if (!skippy_iter.next (&unsafe_to))
+    {
+      buffer->unsafe_to_concat (buffer->idx, unsafe_to);
+      return_trace (false);
+    }
 
     return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx));
   }
@@ -1555,7 +1561,12 @@
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
-    if (!skippy_iter.next ()) return_trace (false);
+    unsigned unsafe_to;
+    if (!skippy_iter.next (&unsafe_to))
+    {
+      buffer->unsafe_to_concat (buffer->idx, unsafe_to);
+      return_trace (false);
+    }
 
     unsigned int len1 = valueFormat1.get_len ();
     unsigned int len2 = valueFormat2.get_len ();
@@ -1563,14 +1574,90 @@
 
     unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
     unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
-    if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
+    if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
+    {
+      buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
+      return_trace (false);
+    }
 
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
-    bool applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
-    bool applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+
+    bool applied_first = false, applied_second = false;
+
+
+    /* Isolate simple kerning and apply it half to each side.
+     * Results in better cursor positinoing / underline drawing.
+     *
+     * Disabled, because causes issues... :-(
+     * https://github.com/harfbuzz/harfbuzz/issues/3408
+     * https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
+     */
+#ifndef HB_SPLIT_KERN
+    if (0)
+#endif
+    {
+      if (!len2)
+      {
+	const hb_direction_t dir = buffer->props.direction;
+	const bool horizontal = HB_DIRECTION_IS_HORIZONTAL (dir);
+	const bool backward = HB_DIRECTION_IS_BACKWARD (dir);
+	unsigned mask = horizontal ? ValueFormat::xAdvance : ValueFormat::yAdvance;
+	if (backward)
+	  mask |= mask >> 2; /* Add eg. xPlacement in RTL. */
+	/* Add Devices. */
+	mask |= mask << 4;
+
+	if (valueFormat1 & ~mask)
+	  goto bail;
+
+	/* Is simple kern. Apply value on an empty position slot,
+	 * then split it between sides. */
+
+	hb_glyph_position_t pos{};
+	if (valueFormat1.apply_value (c, this, v, pos))
+	{
+	  hb_position_t *src  = &pos.x_advance;
+	  hb_position_t *dst1 = &buffer->cur_pos().x_advance;
+	  hb_position_t *dst2 = &buffer->pos[skippy_iter.idx].x_advance;
+	  unsigned i = horizontal ? 0 : 1;
+
+	  hb_position_t kern  = src[i];
+	  hb_position_t kern1 = kern >> 1;
+	  hb_position_t kern2 = kern - kern1;
+
+	  if (!backward)
+	  {
+	    dst1[i] += kern1;
+	    dst2[i] += kern2;
+	    dst2[i + 2] += kern2;
+	  }
+	  else
+	  {
+	    dst1[i] += kern1;
+	    dst1[i + 2] += src[i + 2] - kern2;
+	    dst2[i] += kern2;
+	  }
+
+	  applied_first = applied_second = kern != 0;
+	  goto success;
+	}
+	goto boring;
+      }
+    }
+    bail:
+
+
+    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]);
+
+    success:
     if (applied_first || applied_second)
       buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
+    else
+    boring:
+      buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
 
+
     buffer->idx = skippy_iter.idx;
     if (len2)
       buffer->idx++;
@@ -1799,10 +1886,19 @@
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
-    if (!skippy_iter.prev ()) return_trace (false);
+    unsigned unsafe_from;
+    if (!skippy_iter.prev (&unsafe_from))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+      return_trace (false);
+    }
 
     const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint)];
-    if (!prev_record.exitAnchor) return_trace (false);
+    if (!prev_record.exitAnchor)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
 
     unsigned int i = skippy_iter.idx;
     unsigned int j = buffer->idx;
@@ -2066,7 +2162,13 @@
     skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
     do {
-      if (!skippy_iter.prev ()) return_trace (false);
+      unsigned unsafe_from;
+      if (!skippy_iter.prev (&unsafe_from))
+      {
+	buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+	return_trace (false);
+      }
+
       /* We only want to attach to the first of a MultipleSubst sequence.
        * https://github.com/harfbuzz/harfbuzz/issues/740
        * Reject others...
@@ -2089,7 +2191,11 @@
     //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); }
 
     unsigned int base_index = (this+baseCoverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint);
-    if (base_index == NOT_COVERED) return_trace (false);
+    if (base_index == NOT_COVERED)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
 
     return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
   }
@@ -2320,7 +2426,12 @@
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
-    if (!skippy_iter.prev ()) return_trace (false);
+    unsigned unsafe_from;
+    if (!skippy_iter.prev (&unsafe_from))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+      return_trace (false);
+    }
 
     /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
     //if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); }
@@ -2327,7 +2438,11 @@
 
     unsigned int j = skippy_iter.idx;
     unsigned int lig_index = (this+ligatureCoverage).get_coverage  (buffer->info[j].codepoint);
-    if (lig_index == NOT_COVERED) return_trace (false);
+    if (lig_index == NOT_COVERED)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
 
     const LigatureArray& lig_array = this+ligatureArray;
     const LigatureAttach& lig_attach = lig_array[lig_index];
@@ -2334,7 +2449,11 @@
 
     /* Find component to attach to */
     unsigned int comp_count = lig_attach.rows;
-    if (unlikely (!comp_count)) return_trace (false);
+    if (unlikely (!comp_count))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
 
     /* We must now check whether the ligature ID of the current mark glyph
      * is identical to the ligature ID of the found ligature.  If yes, we
@@ -2517,9 +2636,18 @@
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
-    if (!skippy_iter.prev ()) return_trace (false);
+    unsigned unsafe_from;
+    if (!skippy_iter.prev (&unsafe_from))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+      return_trace (false);
+    }
 
-    if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); }
+    if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
 
     unsigned int j = skippy_iter.idx;
 
@@ -2544,11 +2672,16 @@
     }
 
     /* Didn't match. */
+    buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
     return_trace (false);
 
     good:
     unsigned int mark2_index = (this+mark2Coverage).get_coverage  (buffer->info[j].codepoint);
-    if (mark2_index == NOT_COVERED) return_trace (false);
+    if (mark2_index == NOT_COVERED)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
 
     return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
   }
@@ -2951,7 +3084,7 @@
 }
 
 void
-GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
 {
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
@@ -2961,12 +3094,21 @@
 
   /* Handle attachments */
   if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
-    for (unsigned int i = 0; i < len; i++)
+    for (unsigned i = 0; i < len; i++)
       propagate_attachment_offsets (pos, len, i, direction);
+
+  if (unlikely (font->slant))
+  {
+    for (unsigned i = 0; i < len; i++)
+      if (unlikely (pos[i].y_offset))
+        pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
+  }
 }
 
 
-struct GPOS_accelerator_t : GPOS::accelerator_t {};
+struct GPOS_accelerator_t : GPOS::accelerator_t {
+  GPOS_accelerator_t (hb_face_t *face) : GPOS::accelerator_t (face) {}
+};
 
 
 /* Out-of-class implementation for methods recursing */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -826,7 +826,7 @@
 
     unsigned int total_component_count = 0;
 
-    unsigned int match_length = 0;
+    unsigned int match_end = 0;
     unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
 
     if (likely (!match_input (c, count,
@@ -833,15 +833,18 @@
 			      &component[1],
 			      match_glyph,
 			      nullptr,
-			      &match_length,
+			      &match_end,
 			      match_positions,
 			      &total_component_count)))
+    {
+      c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
       return_trace (false);
+    }
 
     ligate_input (c,
 		  count,
 		  match_positions,
-		  match_length,
+		  match_end,
 		  ligGlyph,
 		  total_component_count);
 
@@ -1296,7 +1299,7 @@
 	match_lookahead (c,
 			 lookahead.len, (HBUINT16 *) lookahead.arrayZ,
 			 match_coverage, this,
-			 1, &end_index))
+			 c->buffer->idx + 1, &end_index))
     {
       c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
       c->replace_glyph_inplace (substitute[index]);
@@ -1305,8 +1308,11 @@
        * calls us through a Context lookup. */
       return_trace (true);
     }
-
-    return_trace (false);
+    else
+    {
+      c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
+      return_trace (false);
+    }
   }
 
   template<typename Iterator,
@@ -1739,7 +1745,9 @@
 };
 
 
-struct GSUB_accelerator_t : GSUB::accelerator_t {};
+struct GSUB_accelerator_t : GSUB::accelerator_t {
+  GSUB_accelerator_t (hb_face_t *face) : GSUB::accelerator_t (face) {}
+};
 
 
 /* Out-of-class implementation for methods recursing */

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -125,24 +125,31 @@
     hb_set_t *covered_glyph_set = done_lookups_glyph_set->get (lookup_index);
     if (unlikely (covered_glyph_set->in_error ()))
       return true;
-    if (parent_active_glyphs ()->is_subset (*covered_glyph_set))
+    if (parent_active_glyphs ().is_subset (*covered_glyph_set))
       return true;
 
-    hb_set_union (covered_glyph_set, parent_active_glyphs ());
+    covered_glyph_set->union_ (parent_active_glyphs ());
     return false;
   }
 
-  hb_set_t* parent_active_glyphs ()
+  const hb_set_t& previous_parent_active_glyphs () {
+    if (active_glyphs_stack.length <= 1)
+      return *glyphs;
+
+    return active_glyphs_stack[active_glyphs_stack.length - 2];
+  }
+
+  const hb_set_t& parent_active_glyphs ()
   {
-    if (active_glyphs_stack.length < 1)
-      return glyphs;
+    if (!active_glyphs_stack)
+      return *glyphs;
 
     return active_glyphs_stack.tail ();
   }
 
-  void push_cur_active_glyphs (hb_set_t* cur_active_glyph_set)
+  hb_set_t& push_cur_active_glyphs ()
   {
-    active_glyphs_stack.push (cur_active_glyph_set);
+    return *active_glyphs_stack.push ();
   }
 
   bool pop_cur_done_glyphs ()
@@ -156,29 +163,24 @@
 
   hb_face_t *face;
   hb_set_t *glyphs;
-  hb_set_t *cur_intersected_glyphs;
   hb_set_t output[1];
-  hb_vector_t<hb_set_t *> active_glyphs_stack;
+  hb_vector_t<hb_set_t> active_glyphs_stack;
   recurse_func_t recurse_func;
   unsigned int nesting_level_left;
 
   hb_closure_context_t (hb_face_t *face_,
 			hb_set_t *glyphs_,
-			hb_set_t *cur_intersected_glyphs_,
 			hb_map_t *done_lookups_glyph_count_,
 			hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_,
 			unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
 			  face (face_),
 			  glyphs (glyphs_),
-			  cur_intersected_glyphs (cur_intersected_glyphs_),
 			  recurse_func (nullptr),
 			  nesting_level_left (nesting_level_left_),
 			  done_lookups_glyph_count (done_lookups_glyph_count_),
 			  done_lookups_glyph_set (done_lookups_glyph_set_),
 			  lookup_count (0)
-  {
-    push_cur_active_glyphs (glyphs_);
-  }
+  {}
 
   ~hb_closure_context_t () { flush (); }
 
@@ -186,11 +188,11 @@
 
   void flush ()
   {
-    hb_set_del_range (output, face->get_num_glyphs (), HB_SET_VALUE_INVALID);	/* Remove invalid glyphs. */
-    hb_set_union (glyphs, output);
-    hb_set_clear (output);
+    output->del_range (face->get_num_glyphs (), HB_SET_VALUE_INVALID);	/* Remove invalid glyphs. */
+    glyphs->union_ (*output);
+    output->clear ();
     active_glyphs_stack.pop ();
-    active_glyphs_stack.fini ();
+    active_glyphs_stack.reset ();
   }
 
   private:
@@ -520,7 +522,7 @@
     may_skip (const hb_glyph_info_t &info) const
     { return matcher.may_skip (c, info); }
 
-    bool next ()
+    bool next (unsigned *unsafe_to = nullptr)
     {
       assert (num_items > 0);
       while (idx + num_items < end)
@@ -543,11 +545,17 @@
 	}
 
 	if (skip == matcher_t::SKIP_NO)
+	{
+	  if (unsafe_to)
+	    *unsafe_to = idx + 1;
 	  return false;
+	}
       }
+      if (unsafe_to)
+        *unsafe_to = end;
       return false;
     }
-    bool prev ()
+    bool prev (unsigned *unsafe_from = nullptr)
     {
       assert (num_items > 0);
       while (idx > num_items - 1)
@@ -570,8 +578,14 @@
 	}
 
 	if (skip == matcher_t::SKIP_NO)
+	{
+	  if (unsafe_from)
+	    *unsafe_from = hb_max (1u, idx) - 1u;
 	  return false;
+	}
       }
+      if (unsafe_from)
+        *unsafe_from = 0;
       return false;
     }
 
@@ -712,17 +726,16 @@
     return true;
   }
 
-  void _set_glyph_props (hb_codepoint_t glyph_index,
+  void _set_glyph_class (hb_codepoint_t glyph_index,
 			  unsigned int class_guess = 0,
 			  bool ligature = false,
 			  bool component = false) const
   {
-    unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
-			  HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
-    add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+    unsigned int props = _hb_glyph_info_get_glyph_props (&buffer->cur());
+    props |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
     if (ligature)
     {
-      add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
+      props |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
       /* In the only place that the MULTIPLIED bit is used, Uniscribe
        * seems to only care about the "last" transformation between
        * Ligature and Multiple substitutions.  Ie. if you ligate, expand,
@@ -729,36 +742,44 @@
        * and ligate again, it forgives the multiplication and acts as
        * if only ligation happened.  As such, clear MULTIPLIED bit.
        */
-      add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+      props &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
     }
     if (component)
-      add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+      props |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
     if (likely (has_glyph_classes))
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
+    {
+      props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef.get_glyph_props (glyph_index));
+    }
     else if (class_guess)
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
+    {
+      props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), props | class_guess);
+    }
+    else
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), props);
   }
 
   void replace_glyph (hb_codepoint_t glyph_index) const
   {
-    _set_glyph_props (glyph_index);
+    _set_glyph_class (glyph_index);
     (void) buffer->replace_glyph (glyph_index);
   }
   void replace_glyph_inplace (hb_codepoint_t glyph_index) const
   {
-    _set_glyph_props (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
   {
-    _set_glyph_props (glyph_index, class_guess, true);
+    _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
   {
-    _set_glyph_props (glyph_index, class_guess, false, true);
+    _set_glyph_class (glyph_index, class_guess, false, true);
     (void) buffer->output_glyph (glyph_index);
   }
 };
@@ -948,7 +969,7 @@
 				const HBUINT16 input[], /* Array of input values--start with second glyph */
 				match_func_t match_func,
 				const void *match_data,
-				unsigned int *end_offset,
+				unsigned int *end_position,
 				unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
 				unsigned int *p_total_component_count = nullptr)
 {
@@ -1001,7 +1022,12 @@
   match_positions[0] = buffer->idx;
   for (unsigned int i = 1; i < count; i++)
   {
-    if (!skippy_iter.next ()) return_trace (false);
+    unsigned unsafe_to;
+    if (!skippy_iter.next (&unsafe_to))
+    {
+      *end_position = unsafe_to;
+      return_trace (false);
+    }
 
     match_positions[i] = skippy_iter.idx;
 
@@ -1055,7 +1081,7 @@
     total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
   }
 
-  *end_offset = skippy_iter.idx - buffer->idx + 1;
+  *end_position = skippy_iter.idx + 1;
 
   if (p_total_component_count)
     *p_total_component_count = total_component_count;
@@ -1065,7 +1091,7 @@
 static inline bool ligate_input (hb_ot_apply_context_t *c,
 				 unsigned int count, /* Including the first glyph */
 				 const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
-				 unsigned int match_length,
+				 unsigned int match_end,
 				 hb_codepoint_t lig_glyph,
 				 unsigned int total_component_count)
 {
@@ -1073,7 +1099,7 @@
 
   hb_buffer_t *buffer = c->buffer;
 
-  buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
+  buffer->merge_clusters (buffer->idx, match_end);
 
   /* - If a base and one or more marks ligate, consider that as a base, NOT
    *   ligature, such that all following marks can still attach to it.
@@ -1190,11 +1216,16 @@
   skippy_iter.set_match_func (match_func, match_data, backtrack);
 
   for (unsigned int i = 0; i < count; i++)
-    if (!skippy_iter.prev ())
+  {
+    unsigned unsafe_from;
+    if (!skippy_iter.prev (&unsafe_from))
+    {
+      *match_start = unsafe_from;
       return_trace (false);
+    }
+  }
 
   *match_start = skippy_iter.idx;
-
   return_trace (true);
 }
 
@@ -1203,21 +1234,26 @@
 				    const HBUINT16 lookahead[],
 				    match_func_t match_func,
 				    const void *match_data,
-				    unsigned int offset,
+				    unsigned int start_index,
 				    unsigned int *end_index)
 {
   TRACE_APPLY (nullptr);
 
   hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
-  skippy_iter.reset (c->buffer->idx + offset - 1, count);
+  skippy_iter.reset (start_index - 1, count);
   skippy_iter.set_match_func (match_func, match_data, lookahead);
 
   for (unsigned int i = 0; i < count; i++)
-    if (!skippy_iter.next ())
+  {
+    unsigned unsafe_to;
+    if (!skippy_iter.next (&unsafe_to))
+    {
+      *end_index = unsafe_to;
       return_trace (false);
+    }
+  }
 
   *end_index = skippy_iter.idx + 1;
-
   return_trace (true);
 }
 
@@ -1284,22 +1320,23 @@
     unsigned seqIndex = lookupRecord[i].sequenceIndex;
     if (seqIndex >= inputCount) continue;
 
-    hb_set_t *pos_glyphs = nullptr;
+    bool has_pos_glyphs = false;
+    hb_set_t pos_glyphs;
 
     if (hb_set_is_empty (covered_seq_indicies) || !hb_set_has (covered_seq_indicies, seqIndex))
     {
-      pos_glyphs = hb_set_create ();
+      has_pos_glyphs = true;
       if (seqIndex == 0)
       {
         switch (context_format) {
         case ContextFormat::SimpleContext:
-          pos_glyphs->add (value);
+          pos_glyphs.add (value);
           break;
         case ContextFormat::ClassBasedContext:
-          intersected_glyphs_func (c->cur_intersected_glyphs, data, value, pos_glyphs);
+          intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs);
           break;
         case ContextFormat::CoverageBasedContext:
-          hb_set_set (pos_glyphs, c->cur_intersected_glyphs);
+          pos_glyphs.set (c->parent_active_glyphs ());
           break;
         }
       }
@@ -1313,12 +1350,16 @@
           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);
       }
     }
 
-    hb_set_add (covered_seq_indicies, seqIndex);
-    c->push_cur_active_glyphs (pos_glyphs ? pos_glyphs : c->glyphs);
+    covered_seq_indicies->add (seqIndex);
+    if (has_pos_glyphs) {
+      c->push_cur_active_glyphs () = pos_glyphs;
+    } else {
+      c->push_cur_active_glyphs ().set (*c->glyphs);
+    }
 
     unsigned endIndex = inputCount;
     if (context_format == ContextFormat::CoverageBasedContext)
@@ -1327,8 +1368,6 @@
     c->recurse (lookupRecord[i].lookupListIndex, covered_seq_indicies, seqIndex, endIndex);
 
     c->pop_cur_done_glyphs ();
-    if (pos_glyphs)
-      hb_set_destroy (pos_glyphs);
   }
 
   hb_set_destroy (covered_seq_indicies);
@@ -1343,15 +1382,13 @@
     c->recurse (lookupRecord[i].lookupListIndex);
 }
 
-static inline bool apply_lookup (hb_ot_apply_context_t *c,
+static inline void apply_lookup (hb_ot_apply_context_t *c,
 				 unsigned int count, /* Including the first glyph */
 				 unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
 				 unsigned int lookupCount,
 				 const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
-				 unsigned int match_length)
+				 unsigned int match_end)
 {
-  TRACE_APPLY (nullptr);
-
   hb_buffer_t *buffer = c->buffer;
   int end;
 
@@ -1359,7 +1396,7 @@
    * Adjust. */
   {
     unsigned int bl = buffer->backtrack_len ();
-    end = bl + match_length;
+    end = bl + match_end - buffer->idx;
 
     int delta = bl - buffer->idx;
     /* Convert positions to new indexing. */
@@ -1461,8 +1498,6 @@
   }
 
   (void) buffer->move_to (end);
-
-  return_trace (true);
 }
 
 
@@ -1550,17 +1585,25 @@
 					 const LookupRecord lookupRecord[],
 					 ContextApplyLookupContext &lookup_context)
 {
-  unsigned int match_length = 0;
-  unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
-  return match_input (c,
-		      inputCount, input,
-		      lookup_context.funcs.match, lookup_context.match_data,
-		      &match_length, match_positions)
-      && (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length),
-	  apply_lookup (c,
-		       inputCount, match_positions,
-		       lookupCount, lookupRecord,
-		       match_length));
+  unsigned match_end = 0;
+  unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
+  if (match_input (c,
+		   inputCount, input,
+		   lookup_context.funcs.match, lookup_context.match_data,
+		   &match_end, match_positions))
+  {
+    c->buffer->unsafe_to_break (c->buffer->idx, match_end);
+    apply_lookup (c,
+		  inputCount, match_positions,
+		  lookupCount, lookupRecord,
+		  match_end);
+    return true;
+  }
+  else
+  {
+    c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
+    return false;
+  }
 }
 
 struct Rule
@@ -1828,8 +1871,9 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    c->cur_intersected_glyphs->clear ();
-    get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+    hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+    get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+                                                 cur_active_glyphs);
 
     struct ContextClosureLookupContext lookup_context = {
       {intersects_glyph, intersected_glyph},
@@ -1838,10 +1882,14 @@
     };
 
     + hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
-    | hb_filter (c->parent_active_glyphs (), hb_first)
+    | hb_filter ([&] (hb_codepoint_t _) {
+      return c->previous_parent_active_glyphs ().has (_);
+    }, hb_first)
     | hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const RuleSet&> (_.first, this+ruleSet[_.second]); })
     | hb_apply ([&] (const hb_pair_t<unsigned, const RuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
     ;
+
+    c->pop_cur_done_glyphs ();
   }
 
   void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -1989,8 +2037,9 @@
     if (!(this+coverage).intersects (c->glyphs))
       return;
 
-    c->cur_intersected_glyphs->clear ();
-    get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+    hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+    get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+                                                 cur_active_glyphs);
 
     const ClassDef &class_def = this+classDef;
 
@@ -2000,10 +2049,9 @@
       &class_def
     };
 
-    return
     + hb_enumerate (ruleSet)
     | hb_filter ([&] (unsigned _)
-		 { return class_def.intersects_class (c->cur_intersected_glyphs, _); },
+    { return class_def.intersects_class (&c->parent_active_glyphs (), _); },
 		 hb_first)
     | hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<RuleSet>&> _)
                 {
@@ -2011,6 +2059,8 @@
                   rule_set.closure (c, _.first, lookup_context);
                 })
     ;
+
+    c->pop_cur_done_glyphs ();
   }
 
   void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -2183,9 +2233,11 @@
     if (!(this+coverageZ[0]).intersects (c->glyphs))
       return;
 
-    c->cur_intersected_glyphs->clear ();
-    get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+    hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+    get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+                                                 cur_active_glyphs);
 
+
     const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
     struct ContextClosureLookupContext lookup_context = {
       {intersects_coverage, intersected_coverage_glyphs},
@@ -2196,6 +2248,8 @@
 			    glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
 			    lookupCount, lookupRecord,
 			    0, lookup_context);
+
+    c->pop_cur_done_glyphs ();
   }
 
   void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -2452,25 +2506,38 @@
 					       const LookupRecord lookupRecord[],
 					       ChainContextApplyLookupContext &lookup_context)
 {
-  unsigned int start_index = 0, match_length = 0, end_index = 0;
-  unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
-  return match_input (c,
-		      inputCount, input,
-		      lookup_context.funcs.match, lookup_context.match_data[1],
-		      &match_length, match_positions)
-      && match_backtrack (c,
-			  backtrackCount, backtrack,
-			  lookup_context.funcs.match, lookup_context.match_data[0],
-			  &start_index)
-      && match_lookahead (c,
-			  lookaheadCount, lookahead,
-			  lookup_context.funcs.match, lookup_context.match_data[2],
-			  match_length, &end_index)
-      && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index),
-	  apply_lookup (c,
-			inputCount, match_positions,
-			lookupCount, lookupRecord,
-			match_length));
+  unsigned end_index = c->buffer->idx;
+  unsigned match_end = 0;
+  unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
+  if (!(match_input (c,
+		     inputCount, input,
+		     lookup_context.funcs.match, lookup_context.match_data[1],
+		     &match_end, match_positions) && (end_index = match_end)
+       && match_lookahead (c,
+			   lookaheadCount, lookahead,
+			   lookup_context.funcs.match, lookup_context.match_data[2],
+			   match_end, &end_index)))
+  {
+    c->buffer->unsafe_to_concat (c->buffer->idx, end_index);
+    return false;
+  }
+
+  unsigned start_index = c->buffer->out_len;
+  if (!match_backtrack (c,
+			backtrackCount, backtrack,
+			lookup_context.funcs.match, lookup_context.match_data[0],
+			&start_index))
+  {
+    c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
+    return false;
+  }
+
+  c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
+  apply_lookup (c,
+		inputCount, match_positions,
+		lookupCount, lookupRecord,
+		match_end);
+  return true;
 }
 
 struct ChainRule
@@ -2802,8 +2869,9 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    c->cur_intersected_glyphs->clear ();
-    get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+    hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+    get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+                                                 cur_active_glyphs);
 
     struct ChainContextClosureLookupContext lookup_context = {
       {intersects_glyph, intersected_glyph},
@@ -2812,10 +2880,14 @@
     };
 
     + hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
-    | hb_filter (c->parent_active_glyphs (), hb_first)
+    | hb_filter ([&] (hb_codepoint_t _) {
+      return c->previous_parent_active_glyphs ().has (_);
+    }, hb_first)
     | hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const ChainRuleSet&> (_.first, this+ruleSet[_.second]); })
     | hb_apply ([&] (const hb_pair_t<unsigned, const ChainRuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
     ;
+
+    c->pop_cur_done_glyphs ();
   }
 
   void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -2964,9 +3036,11 @@
     if (!(this+coverage).intersects (c->glyphs))
       return;
 
-    c->cur_intersected_glyphs->clear ();
-    get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+    hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+    get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+                                                 cur_active_glyphs);
 
+
     const ClassDef &backtrack_class_def = this+backtrackClassDef;
     const ClassDef &input_class_def = this+inputClassDef;
     const ClassDef &lookahead_class_def = this+lookaheadClassDef;
@@ -2979,10 +3053,9 @@
        &lookahead_class_def}
     };
 
-    return
     + hb_enumerate (ruleSet)
     | hb_filter ([&] (unsigned _)
-		 { return input_class_def.intersects_class (c->cur_intersected_glyphs, _); },
+    { return input_class_def.intersects_class (&c->parent_active_glyphs (), _); },
 		 hb_first)
     | hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<ChainRuleSet>&> _)
                 {
@@ -2990,6 +3063,8 @@
                   chainrule_set.closure (c, _.first, lookup_context);
                 })
     ;
+
+    c->pop_cur_done_glyphs ();
   }
 
   void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -3216,9 +3291,11 @@
     if (!(this+input[0]).intersects (c->glyphs))
       return;
 
-    c->cur_intersected_glyphs->clear ();
-    get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+    hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+    get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+                                                 cur_active_glyphs);
 
+
     const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input);
     const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead);
     struct ChainContextClosureLookupContext lookup_context = {
@@ -3232,6 +3309,8 @@
 				  lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
 				  lookup.len, lookup.arrayZ,
 				  0, lookup_context);
+
+    c->pop_cur_done_glyphs ();
   }
 
   void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -3706,7 +3785,7 @@
     for (unsigned i : feature_indices->iter ())
     {
       hb_tag_t t = get_feature_tag (i);
-      if (t == unique_features.INVALID_KEY) continue;
+      if (t == HB_MAP_VALUE_INVALID) continue;
       if (!unique_features.has (t))
       {
         hb_set_t* indices = hb_set_create ();
@@ -3839,7 +3918,7 @@
   template <typename T>
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     {
       this->table = hb_sanitize_context_t ().reference_table<T> (face);
       if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
@@ -3861,8 +3940,7 @@
       for (unsigned int i = 0; i < this->lookup_count; i++)
 	this->accels[i].init (table->get_lookup (i));
     }
-
-    void fini ()
+    ~accelerator_t ()
     {
       for (unsigned int i = 0; i < this->lookup_count; i++)
 	this->accels[i].fini ();

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -1491,10 +1491,9 @@
 					unsigned int  lookup_index,
 					hb_set_t     *glyphs /* OUT */)
 {
-  hb_set_t cur_intersected_glyphs;
   hb_map_t done_lookups_glyph_count;
   hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
-  OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
+  OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
 
   const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
 
@@ -1520,10 +1519,9 @@
 					 const hb_set_t *lookups,
 					 hb_set_t       *glyphs /* OUT */)
 {
-  hb_set_t cur_intersected_glyphs;
   hb_map_t done_lookups_glyph_count;
   hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
-  OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
+  OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
   const OT::GSUB& gsub = *face->table.GSUB->table;
 
   unsigned int iteration_count = 0;
@@ -1890,7 +1888,7 @@
     apply_forward (c, accel);
 
     if (!Proxy::inplace)
-      buffer->swap_buffers ();
+      buffer->sync ();
   }
   else
   {

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -482,10 +482,9 @@
 }
 
 static inline uint8_t
-_hb_allocate_lig_id (hb_buffer_t *buffer) {
+_hb_allocate_lig_id (hb_buffer_t *buffer)
+{
   uint8_t lig_id = buffer->next_serial () & 0x07;
-  if (unlikely (!lig_id))
-    lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
   return lig_id;
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -369,6 +369,37 @@
     return kernValue[i].get_x_value (font, this);
   }
 
+  unsigned int get_entries (unsigned int start_offset,
+			    unsigned int *entries_count, /* IN/OUT */
+			    hb_ot_math_kern_entry_t *kern_entries, /* OUT */
+			    hb_font_t *font) const
+  {
+    const MathValueRecord* correctionHeight = mathValueRecordsZ.arrayZ;
+    const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount;
+    const unsigned int entriesCount = heightCount + 1;
+
+    if (entries_count)
+    {
+      unsigned int start = hb_min (start_offset, entriesCount);
+      unsigned int end = hb_min (start + *entries_count, entriesCount);
+      *entries_count = end - start;
+
+      for (unsigned int i = 0; i < *entries_count; i++) {
+	unsigned int j = start + i;
+
+	hb_position_t max_height;
+	if (j == heightCount) {
+	  max_height = INT32_MAX;
+	} else {
+	  max_height = correctionHeight[j].get_y_value (font, this);
+	}
+
+	kern_entries[i] = {max_height, kernValue[j].get_x_value (font, this)};
+      }
+    }
+    return entriesCount;
+  }
+
   protected:
   HBUINT16	heightCount;
   UnsizedArrayOf<MathValueRecord>
@@ -423,6 +454,24 @@
     return (base+mathKern[idx]).get_value (correction_height, font);
   }
 
+  unsigned int get_kernings (hb_ot_math_kern_t kern,
+			     unsigned int start_offset,
+			     unsigned int *entries_count, /* IN/OUT */
+			     hb_ot_math_kern_entry_t *kern_entries, /* OUT */
+			     hb_font_t *font,
+			     const void *base) const
+  {
+    unsigned int idx = kern;
+    if (unlikely (idx >= ARRAY_LENGTH (mathKern)) || !mathKern[idx]) {
+      if (entries_count) *entries_count = 0;
+      return 0;
+    }
+    return (base+mathKern[idx]).get_entries (start_offset,
+					     entries_count,
+					     kern_entries,
+					     font);
+  }
+
   protected:
   /* Offset to MathKern table for each corner -
    * from the beginning of MathKernInfo table.  May be NULL. */
@@ -473,6 +522,22 @@
     return mathKernInfoRecords[index].get_kerning (kern, correction_height, font, this);
   }
 
+  unsigned int get_kernings (hb_codepoint_t glyph,
+			     hb_ot_math_kern_t kern,
+			     unsigned int start_offset,
+			     unsigned int *entries_count, /* IN/OUT */
+			     hb_ot_math_kern_entry_t *kern_entries, /* OUT */
+			     hb_font_t *font) const
+  {
+    unsigned int index = (this+mathKernCoverage).get_coverage (glyph);
+    return mathKernInfoRecords[index].get_kernings (kern,
+						    start_offset,
+						    entries_count,
+						    kern_entries,
+						    font,
+						    this);
+  }
+
   protected:
   Offset16To<Coverage>
 		mathKernCoverage;
@@ -545,6 +610,19 @@
 			     hb_font_t *font) const
   { return (this+mathKernInfo).get_kerning (glyph, kern, correction_height, font); }
 
+  hb_position_t get_kernings (hb_codepoint_t glyph,
+			      hb_ot_math_kern_t kern,
+			      unsigned int start_offset,
+			      unsigned int *entries_count, /* IN/OUT */
+			      hb_ot_math_kern_entry_t *kern_entries, /* OUT */
+			      hb_font_t *font) const
+  { return (this+mathKernInfo).get_kernings (glyph,
+					     kern,
+					     start_offset,
+					     entries_count,
+					     kern_entries,
+					     font); }
+
   protected:
   /* Offset to MathItalicsCorrectionInfo table -
    * from the beginning of MathGlyphInfo table. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -185,6 +185,51 @@
 }
 
 /**
+ * hb_ot_math_get_glyph_kernings:
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph index from which to retrieve the kernings
+ * @kern: The #hb_ot_math_kern_t from which to retrieve the kernings
+ * @start_offset: offset of the first kern entry to retrieve
+ * @entries_count: (inout) (optional): Input = the maximum number of kern entries to return;
+ *                                     Output = the actual number of kern entries returned
+ * @kern_entries: (out caller-allocates) (array length=entries_count): array of kern entries returned
+ *
+ * Fetches the raw MathKern (cut-in) data for the specified font, glyph index,
+ * and @kern. The corresponding list of kern values and correction heights is
+ * returned as a list of #hb_ot_math_kern_entry_t structs.
+ *
+ * See also #hb_ot_math_get_glyph_kerning, which handles selecting the
+ * appropriate kern value for a given correction height.
+ *
+ * <note>For a glyph with @n defined kern values (where @n > 0), there are only
+ * @n−1 defined correction heights, as each correction height defines a boundary
+ * past which the next kern value should be selected. Therefore, only the
+ * #hb_ot_math_kern_entry_t.kern_value of the uppermost #hb_ot_math_kern_entry_t
+ * actually comes from the font; its corresponding
+ * #hb_ot_math_kern_entry_t.max_correction_height is always set to
+ * <code>INT32_MAX</code>.</note>
+ *
+ * Return value: the total number of kern values available or zero
+ *
+ * Since: 3.4.0
+ **/
+unsigned int
+hb_ot_math_get_glyph_kernings (hb_font_t *font,
+			       hb_codepoint_t glyph,
+			       hb_ot_math_kern_t kern,
+			       unsigned int start_offset,
+			       unsigned int *entries_count, /* IN/OUT */
+			       hb_ot_math_kern_entry_t *kern_entries /* OUT */)
+{
+  return font->face->table.MATH->get_glyph_info().get_kernings (glyph,
+								kern,
+								start_offset,
+								entries_count,
+								kern_entries,
+								font);
+}
+
+/**
  * hb_ot_math_get_glyph_variants:
  * @font: #hb_font_t to work upon
  * @glyph: The index of the glyph to stretch

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.h	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.h	2022-02-13 03:14:24 UTC (rev 61999)
@@ -50,14 +50,18 @@
 #define HB_OT_TAG_MATH HB_TAG('M','A','T','H')
 
 /**
- * HB_OT_MATH_SCRIPT:
+ * HB_OT_TAG_MATH_SCRIPT:
  *
- * OpenType script tag for math shaping, for use with
- * Use with hb_buffer_set_script().
+ * OpenType script tag, `math`, for features specific to math shaping.
  *
- * Since: 1.3.3
+ * <note>#HB_OT_TAG_MATH_SCRIPT is not a valid #hb_script_t and should only be
+ * used with functions that accept raw OpenType script tags, such as
+ * #hb_ot_layout_collect_features. In other cases, #HB_SCRIPT_MATH should be
+ * used instead.</note>
+ *
+ * Since: 3.4.0
  */
-#define HB_OT_MATH_SCRIPT HB_TAG('m','a','t','h')
+#define HB_OT_TAG_MATH_SCRIPT HB_TAG('m','a','t','h')
 
 /* Types */
 
@@ -205,6 +209,20 @@
 } hb_ot_math_kern_t;
 
 /**
+ * hb_ot_math_kern_entry_t:
+ * @max_correction_height: The maximum height at which this entry should be used
+ * @kern_value: The kern value of the entry
+ *
+ * Data type to hold math kerning (cut-in) information for a glyph.
+ *
+ * Since: 3.4.0
+ */
+typedef struct {
+  hb_position_t max_correction_height;
+  hb_position_t kern_value;
+} hb_ot_math_kern_entry_t;
+
+/**
  * hb_ot_math_glyph_variant_t:
  * @glyph: The glyph index of the variant
  * @advance: The advance width of the variant
@@ -281,6 +299,14 @@
 			      hb_position_t correction_height);
 
 HB_EXTERN unsigned int
+hb_ot_math_get_glyph_kernings (hb_font_t *font,
+			       hb_codepoint_t glyph,
+			       hb_ot_math_kern_t kern,
+			       unsigned int start_offset,
+			       unsigned int *entries_count, /* IN/OUT */
+			       hb_ot_math_kern_entry_t *kern_entries /* OUT */);
+
+HB_EXTERN unsigned int
 hb_ot_math_get_glyph_variants (hb_font_t *font,
 			       hb_codepoint_t glyph,
 			       hb_direction_t direction,

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -71,9 +71,9 @@
 
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     { table = hb_sanitize_context_t ().reference_table<meta> (face); }
-    void fini () { table.destroy (); }
+    ~accelerator_t () { table.destroy (); }
 
     hb_blob_t *reference_entry (hb_tag_t tag) const
     { return table->dataMaps.lsearch (tag).reference_entry (table.get_blob ()); }
@@ -119,7 +119,9 @@
   DEFINE_SIZE_ARRAY (16, dataMaps);
 };
 
-struct meta_accelerator_t : meta::accelerator_t {};
+struct meta_accelerator_t : meta::accelerator_t {
+  meta_accelerator_t (hb_face_t *face) : meta::accelerator_t (face) {}
+};
 
 } /* namespace OT */
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-metrics.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -160,9 +160,50 @@
     (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true))
   case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT:  return GET_METRIC_Y (OS2, usWinAscent);
   case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
-  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:       return GET_METRIC_Y (hhea, caretSlopeRise);
-  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:        return GET_METRIC_X (hhea, caretSlopeRun);
+
+  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:
+  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:
+  {
+    unsigned mult = 1u;
+
+    if (font->slant)
+    {
+      unsigned rise = face->table.hhea->caretSlopeRise;
+      unsigned upem = face->get_upem ();
+      mult = (rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u;
+    }
+
+    if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE)
+    {
+      bool ret = GET_METRIC_Y (hhea, caretSlopeRise);
+
+      if (position)
+	*position *= mult;
+
+      return ret;
+    }
+    else
+    {
+      hb_position_t rise = 0;
+
+      if (font->slant && position && GET_METRIC_Y (hhea, caretSlopeRise))
+	rise = *position;
+
+      bool ret = GET_METRIC_X (hhea, caretSlopeRun);
+
+      if (position)
+      {
+	*position *= mult;
+
+	if (font->slant)
+	  *position += _hb_roundf (mult * font->slant_xy * rise);
+      }
+
+      return ret;
+    }
+  }
   case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET:     return GET_METRIC_X (hhea, caretOffset);
+
 #ifndef HB_NO_VERTICAL
   case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE:         return GET_METRIC_X (vhea, caretSlopeRise);
   case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN:          return GET_METRIC_Y (vhea, caretSlopeRun);

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -256,7 +256,7 @@
     })
     ;
 
-    name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset));
+    name_prime->serialize (c->serializer, it, std::addressof (this + stringOffset));
     return_trace (name_prime->count);
   }
 
@@ -279,7 +279,7 @@
 
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     {
       this->table = hb_sanitize_context_t ().reference_table<name> (face);
       assert (this->table.get_length () >= this->table->stringOffset);
@@ -288,7 +288,6 @@
       const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
 						    this->table->count);
 
-      this->names.init ();
       this->names.alloc (all_names.length);
 
       for (unsigned int i = 0; i < all_names.length; i++)
@@ -318,10 +317,8 @@
       }
       this->names.resize (j);
     }
-
-    void fini ()
+    ~accelerator_t ()
     {
-      this->names.fini ();
       this->table.destroy ();
     }
 
@@ -373,7 +370,9 @@
 #undef entry_index
 #undef entry_score
 
-struct name_accelerator_t : name::accelerator_t {};
+struct name_accelerator_t : name::accelerator_t {
+  name_accelerator_t (hb_face_t *face) : name::accelerator_t (face) {}
+};
 
 } /* namespace OT */
 

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -52,7 +52,7 @@
  * array is owned by the @face and should not be modified.  It can be
  * used as long as @face is alive.
  *
- * Returns: (out) (transfer none) (array length=num_entries): Array of available name entries.
+ * Returns: (transfer none) (array length=num_entries): Array of available name entries.
  * Since: 2.1.0
  **/
 const hb_ot_name_entry_t *

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table-v2subset.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -76,8 +76,7 @@
   hb_map_t old_new_index_map, old_gid_new_index_map;
   unsigned i = 0;
 
-  post::accelerator_t _post;
-  _post.init (c->plan->source);
+  post::accelerator_t _post (c->plan->source);
 
   hb_hashmap_t<hb_bytes_t, unsigned, std::nullptr_t, unsigned, nullptr, (unsigned)-1> glyph_name_to_new_index;
   for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
@@ -128,9 +127,7 @@
                             })
   ;
 
-  bool ret = serialize (c->serializer, index_iter, &_post);
-  _post.fini ();
-  return_trace (ret);
+  return_trace (serialize (c->serializer, index_iter, &_post));
 }
 
 } /* namespace OT */

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -111,10 +111,9 @@
   struct accelerator_t
   {
     friend struct postV2Tail;
-    void init (hb_face_t *face)
+
+    accelerator_t (hb_face_t *face)
     {
-      index_to_offset.init ();
-
       table = hb_sanitize_context_t ().reference_table<post> (face);
       unsigned int table_length = table.get_length ();
 
@@ -132,9 +131,8 @@
 	   data += 1 + *data)
 	index_to_offset.push (data - pool);
     }
-    void fini ()
+    ~accelerator_t ()
     {
-      index_to_offset.fini ();
       hb_free (gids_sorted_by_name.get ());
       table.destroy ();
     }
@@ -254,9 +252,9 @@
 
     private:
     uint32_t version;
-    const Array16Of<HBUINT16> *glyphNameIndex;
+    const Array16Of<HBUINT16> *glyphNameIndex = nullptr;
     hb_vector_t<uint32_t> index_to_offset;
-    const uint8_t *pool;
+    const uint8_t *pool = nullptr;
     hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
   };
 
@@ -307,8 +305,11 @@
   DEFINE_SIZE_MIN (32);
 };
 
-struct post_accelerator_t : post::accelerator_t {};
+struct post_accelerator_t : post::accelerator_t {
+  post_accelerator_t (hb_face_t *face) : post::accelerator_t (face) {}
+};
 
+
 } /* namespace OT */
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-win1256.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-win1256.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-win1256.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -87,6 +87,8 @@
 
 #define OT_GLYPHID /* GlyphID */ \
 	OT_UINT16
+/* Shorthand. */
+#define G	OT_GLYPHID
 
 #define OT_UARRAY(Name, Items) \
 	OT_LABEL_START(Name) \
@@ -183,8 +185,6 @@
 	Tag \
 	OT_OFFSET(manifest, Name)
 
-/* Shorthand. */
-#define G	OT_GLYPHID
 
 /*
  * Table Start
@@ -300,6 +300,10 @@
 /*
  * Clean up
  */
+
+#undef MANIFEST
+#undef MANIFEST_LOOKUP
+
 #undef OT_TABLE_START
 #undef OT_TABLE_END
 #undef OT_LABEL_START
@@ -306,9 +310,31 @@
 #undef OT_LABEL_END
 #undef OT_UINT8
 #undef OT_UINT16
+#undef OT_COUNT
 #undef OT_DISTANCE
-#undef OT_COUNT
 
+#undef OT_LABEL
+#undef OT_LIST
+
+#undef OT_TAG
+#undef OT_OFFSET
+#undef OT_GLYPHID
+#undef G
+#undef OT_UARRAY
+#undef OT_UHEADLESSARRAY
+
+#undef OT_LOOKUP_FLAG_IGNORE_MARKS
+#undef OT_LOOKUP
+#undef OT_SUBLOOKUP
+#undef OT_COVERAGE1
+#undef OT_LOOKUP_TYPE_SUBST_SINGLE
+#undef OT_LOOKUP_TYPE_SUBST_LIGATURE
+#undef OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2
+#undef OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1
+#undef OT_LIGATURE_SET
+#undef OT_LIGATURE
+
+
 /*
  * Include a second time to get the table data...
  */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -321,6 +321,20 @@
       info[prev].arabic_shaping_action() = entry->prev_action;
       buffer->unsafe_to_break (prev, i + 1);
     }
+    else
+    {
+      if (prev == UINT_MAX)
+      {
+        if (this_type >= JOINING_TYPE_R)
+	  buffer->unsafe_to_concat_from_outbuffer (0, i + 1);
+      }
+      else
+      {
+	if (this_type >= JOINING_TYPE_R ||
+	    (2 <= state && state <= 5) /* States that have a possible prev_action. */)
+	  buffer->unsafe_to_concat (prev, i + 1);
+      }
+    }
 
     info[i].arabic_shaping_action() = entry->curr_action;
 
@@ -337,7 +351,14 @@
 
     const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
     if (entry->prev_action != NONE && prev != UINT_MAX)
+    {
       info[prev].arabic_shaping_action() = entry->prev_action;
+      buffer->unsafe_to_break (prev, buffer->len);
+    }
+    else if (2 <= state && state <= 5) /* States that have a possible prev_action. */
+    {
+      buffer->unsafe_to_concat (prev, buffer->len);
+    }
     break;
   }
 }
@@ -614,6 +635,11 @@
   0x06E3u, /* ARABIC SMALL LOW SEEN */
   0x06E7u, /* ARABIC SMALL HIGH YEH */
   0x06E8u, /* ARABIC SMALL HIGH NOON */
+  0x08CAu, /* ARABIC SMALL HIGH FARSI YEH */
+  0x08CBu, /* ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW */
+  0x08CDu, /* ARABIC SMALL HIGH ZAH */
+  0x08CEu, /* ARABIC LARGE ROUND DOT ABOVE */
+  0x08CFu, /* ARABIC LARGE ROUND DOT BELOW */
   0x08D3u, /* ARABIC SMALL LOW WAW */
   0x08F3u, /* ARABIC SMALL HIGH WAW */
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -140,7 +140,7 @@
    *
    *   - LV can be precomposed, or decomposed.  Lets call those
    *     <LV> and <L,V>,
-   *   - LVT can be fully precomposed, partically precomposed, or
+   *   - LVT can be fully precomposed, partially precomposed, or
    *     fully decomposed.  Ie. <LVT>, <LV,T>, or <L,V,T>.
    *
    * The composition / decomposition is mechanical.  However, not
@@ -392,7 +392,7 @@
      */
     (void) buffer->next_glyph ();
   }
-  buffer->swap_buffers ();
+  buffer->sync ();
 }
 
 static void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-syllabic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-syllabic.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-syllabic.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -96,7 +96,7 @@
     else
       (void) buffer->next_glyph ();
   }
-  buffer->swap_buffers ();
+  buffer->sync ();
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -364,7 +364,7 @@
 	buffer->merge_out_clusters (start - 1, end);
     }
   }
-  buffer->swap_buffers ();
+  buffer->sync ();
 
   /* If font has Thai GSUB, we are done. */
   if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -435,7 +435,7 @@
     default:
       break;
   }
-  buffer->swap_buffers ();
+  buffer->sync ();
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -446,6 +446,9 @@
   return;
 #endif
 
+  if (!buffer->message (font, "start fallback mark"))
+    return;
+
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
   unsigned int start = 0;
@@ -457,6 +460,8 @@
       start = i;
     }
   position_cluster (plan, font, buffer, start, count, adjust_offsets_when_zeroing);
+
+  (void) buffer->message (font, "end fallback mark");
 }
 
 
@@ -497,6 +502,9 @@
       !font->has_glyph_v_kerning_func ())
     return;
 
+  if (!buffer->message (font, "start fallback kern"))
+    return;
+
   bool reverse = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
 
   if (reverse)
@@ -508,6 +516,8 @@
 
   if (reverse)
     buffer->reverse ();
+
+  (void) buffer->message (font, "end fallback kern");
 #endif
 }
 
@@ -525,6 +535,15 @@
   for (unsigned int i = 0; i < count; i++)
     if (_hb_glyph_info_is_unicode_space (&info[i]) && !_hb_glyph_info_ligated (&info[i]))
     {
+      /* If font had no ASCII space and we used the invisible glyph, give it a 1/4 EM default advance. */
+      if (buffer->invisible && info[i].codepoint == buffer->invisible)
+      {
+        if (horizontal)
+	  pos[i].x_advance = +font->x_scale / 4;
+        else
+	  pos[i].y_advance = -font->y_scale / 4;
+      }
+
       hb_unicode_funcs_t::space_t space_type = _hb_glyph_info_get_unicode_space_fallback_type (&info[i]);
       hb_codepoint_t glyph;
       typedef hb_unicode_funcs_t t;

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -193,7 +193,8 @@
   {
     hb_codepoint_t space_glyph;
     hb_unicode_funcs_t::space_t space_type = buffer->unicode->space_fallback_type (u);
-    if (space_type != hb_unicode_funcs_t::NOT_SPACE && c->font->get_nominal_glyph (0x0020u, &space_glyph))
+    if (space_type != hb_unicode_funcs_t::NOT_SPACE &&
+	(c->font->get_nominal_glyph (0x0020, &space_glyph) || (space_glyph = buffer->invisible)))
     {
       _hb_glyph_info_set_unicode_space_fallback_type (&buffer->cur(), space_type);
       next_char (buffer, space_glyph);
@@ -374,7 +375,7 @@
       decompose_multi_char_cluster (&c, end, always_short_circuit);
     }
     while (buffer->idx < count && buffer->successful);
-    buffer->swap_buffers ();
+    buffer->sync ();
   }
 
 
@@ -477,7 +478,7 @@
       if (info_cc (buffer->prev()) == 0)
 	starter = buffer->out_len - 1;
     }
-    buffer->swap_buffers ();
+    buffer->sync ();
   }
 }
 

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -566,7 +566,7 @@
   info.mask = buffer->cur().mask;
   (void) buffer->output_info (info);
 
-  buffer->swap_buffers ();
+  buffer->sync ();
 }
 
 static void
@@ -1034,7 +1034,7 @@
    * hanging over the next glyph after the final reordering.
    *
    * Note: If fallback positinoing happens, we don't care about
-   * this as it will be overriden.
+   * this as it will be overridden.
    */
   bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing &&
 				     HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
@@ -1120,7 +1120,7 @@
   /* Propagate cluster-level glyph flags to be the same on all cluster glyphs.
    * Simplifies using them. */
 
-  if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK))
+  if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS))
     return;
 
   hb_glyph_info_t *info = buffer->info;
@@ -1129,11 +1129,7 @@
   {
     unsigned int mask = 0;
     for (unsigned int i = start; i < end; i++)
-      if (info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
-      {
-	 mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
-	 break;
-      }
+      mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED;
     if (mask)
       for (unsigned int i = start; i < end; i++)
 	info[i].mask |= mask;
@@ -1145,18 +1141,7 @@
 static void
 hb_ot_shape_internal (hb_ot_shape_context_t *c)
 {
-  c->buffer->deallocate_var_all ();
-  c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
-  if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR)))
-  {
-    c->buffer->max_len = hb_max (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR,
-				 (unsigned) HB_BUFFER_MAX_LEN_MIN);
-  }
-  if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR)))
-  {
-    c->buffer->max_ops = hb_max (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR,
-				 (unsigned) HB_BUFFER_MAX_OPS_MIN);
-  }
+  c->buffer->enter ();
 
   /* Save the original direction, we use it later. */
   c->target_direction = c->buffer->props.direction;
@@ -1188,9 +1173,7 @@
 
   c->buffer->props.direction = c->target_direction;
 
-  c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
-  c->buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
-  c->buffer->deallocate_var_all ();
+  c->buffer->leave ();
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -6,8 +6,8 @@
  *
  * on files with these headers:
  *
- * <meta name="updated_at" content="2021-12-09 12:01 AM" />
- * File-Date: 2021-08-06
+ * <meta name="updated_at" content="2022-01-28 10:00 PM" />
+ * File-Date: 2021-12-29
  */
 
 #ifndef HB_OT_TAG_TABLE_HH
@@ -66,7 +66,7 @@
   {"an",	HB_TAG('A','R','G',' ')},	/* Aragonese */
 /*{"ang",	HB_TAG('A','N','G',' ')},*/	/* Old English (ca. 450-1100) -> Anglo-Saxon */
   {"aoa",	HB_TAG('C','P','P',' ')},	/* Angolar -> Creoles */
-  {"apa",	HB_TAG('A','T','H',' ')},	/* Apache [family] -> Athapaskan */
+  {"apa",	HB_TAG('A','T','H',' ')},	/* Apache [collection] -> Athapaskan */
   {"apc",	HB_TAG('A','R','A',' ')},	/* North Levantine Arabic -> Arabic */
   {"apd",	HB_TAG('A','R','A',' ')},	/* Sudanese Arabic -> Arabic */
   {"apj",	HB_TAG('A','T','H',' ')},	/* Jicarilla Apache -> Athapaskan */
@@ -86,7 +86,7 @@
   {"arz",	HB_TAG('A','R','A',' ')},	/* Egyptian Arabic -> Arabic */
   {"as",	HB_TAG('A','S','M',' ')},	/* Assamese */
 /*{"ast",	HB_TAG('A','S','T',' ')},*/	/* Asturian */
-/*{"ath",	HB_TAG('A','T','H',' ')},*/	/* Athapascan [family] -> Athapaskan */
+/*{"ath",	HB_TAG('A','T','H',' ')},*/	/* Athapascan [collection] -> Athapaskan */
   {"atj",	HB_TAG('R','C','R',' ')},	/* Atikamekw -> R-Cree */
   {"atv",	HB_TAG('A','L','T',' ')},	/* Northern Altai -> Altai */
   {"auj",	HB_TAG('B','B','R',' ')},	/* Awjilah -> Berber */
@@ -110,10 +110,10 @@
   {"azn",	HB_TAG('N','A','H',' ')},	/* Western Durango Nahuatl -> Nahuatl */
   {"azz",	HB_TAG('N','A','H',' ')},	/* Highland Puebla Nahuatl -> Nahuatl */
   {"ba",	HB_TAG('B','S','H',' ')},	/* Bashkir */
-  {"bad",	HB_TAG('B','A','D','0')},	/* Banda [family] */
+  {"bad",	HB_TAG('B','A','D','0')},	/* Banda [collection] */
   {"bag",	HB_TAG_NONE	       },	/* Tuki != Baghelkhandi */
   {"bah",	HB_TAG('C','P','P',' ')},	/* Bahamas Creole English -> Creoles */
-  {"bai",	HB_TAG('B','M','L',' ')},	/* Bamileke [family] */
+  {"bai",	HB_TAG('B','M','L',' ')},	/* Bamileke [collection] */
   {"bal",	HB_TAG('B','L','I',' ')},	/* Baluchi [macrolanguage] */
 /*{"ban",	HB_TAG('B','A','N',' ')},*/	/* Balinese */
 /*{"bar",	HB_TAG('B','A','R',' ')},*/	/* Bavarian */
@@ -135,7 +135,7 @@
   {"bea",	HB_TAG('A','T','H',' ')},	/* Beaver -> Athapaskan */
   {"beb",	HB_TAG('B','T','I',' ')},	/* Bebele -> Beti */
 /*{"bem",	HB_TAG('B','E','M',' ')},*/	/* Bemba (Zambia) */
-  {"ber",	HB_TAG('B','B','R',' ')},	/* Berber [family] */
+  {"ber",	HB_TAG('B','B','R',' ')},	/* Berber [collection] */
   {"bew",	HB_TAG('C','P','P',' ')},	/* Betawi -> Creoles */
   {"bfl",	HB_TAG('B','A','D','0')},	/* Banda-Ndélé -> Banda */
   {"bfq",	HB_TAG('B','A','D',' ')},	/* Badaga */
@@ -203,7 +203,7 @@
   {"btd",	HB_TAG('B','T','K',' ')},	/* Batak Dairi -> Batak */
   {"bti",	HB_TAG_NONE	       },	/* Burate != Beti */
   {"btj",	HB_TAG('M','L','Y',' ')},	/* Bacanese Malay -> Malay */
-/*{"btk",	HB_TAG('B','T','K',' ')},*/	/* Batak [family] */
+/*{"btk",	HB_TAG('B','T','K',' ')},*/	/* Batak [collection] */
   {"btm",	HB_TAG('B','T','M',' ')},	/* Batak Mandailing */
   {"btm",	HB_TAG('B','T','K',' ')},	/* Batak Mandailing -> Batak */
   {"bto",	HB_TAG('B','I','K',' ')},	/* Rinconada Bikol -> Bikol */
@@ -256,6 +256,8 @@
   {"chh",	HB_TAG_NONE	       },	/* Chinook != Chattisgarhi */
   {"chj",	HB_TAG('C','C','H','N')},	/* Ojitlán Chinantec -> Chinantec */
   {"chk",	HB_TAG('C','H','K','0')},	/* Chuukese */
+  {"chm",	HB_TAG('H','M','A',' ')},	/* Mari (Russia) [macrolanguage] -> High Mari */
+  {"chm",	HB_TAG('L','M','A',' ')},	/* Mari (Russia) [macrolanguage] -> Low Mari */
   {"chn",	HB_TAG('C','P','P',' ')},	/* Chinook jargon -> Creoles */
 /*{"cho",	HB_TAG('C','H','O',' ')},*/	/* Choctaw */
   {"chp",	HB_TAG('C','H','P',' ')},	/* Chipewyan */
@@ -297,10 +299,10 @@
 /*{"cop",	HB_TAG('C','O','P',' ')},*/	/* Coptic */
   {"coq",	HB_TAG('A','T','H',' ')},	/* Coquille -> Athapaskan */
   {"cpa",	HB_TAG('C','C','H','N')},	/* Palantla Chinantec -> Chinantec */
-  {"cpe",	HB_TAG('C','P','P',' ')},	/* English-based creoles and pidgins [family] -> Creoles */
-  {"cpf",	HB_TAG('C','P','P',' ')},	/* French-based creoles and pidgins [family] -> Creoles */
+  {"cpe",	HB_TAG('C','P','P',' ')},	/* English-based creoles and pidgins [collection] -> Creoles */
+  {"cpf",	HB_TAG('C','P','P',' ')},	/* French-based creoles and pidgins [collection] -> Creoles */
   {"cpi",	HB_TAG('C','P','P',' ')},	/* Chinese Pidgin English -> Creoles */
-/*{"cpp",	HB_TAG('C','P','P',' ')},*/	/* Portuguese-based creoles and pidgins [family] -> Creoles */
+/*{"cpp",	HB_TAG('C','P','P',' ')},*/	/* Portuguese-based creoles and pidgins [collection] -> Creoles */
   {"cpx",	HB_TAG('Z','H','S',' ')},	/* Pu-Xian Chinese -> Chinese, Simplified */
   {"cqd",	HB_TAG('H','M','N',' ')},	/* Chuanqiandian Cluster Miao -> Hmong */
   {"cqu",	HB_TAG('Q','U','H',' ')},	/* Chilean Quechua (retired code) -> Quechua (Bolivia) */
@@ -320,7 +322,7 @@
   {"crm",	HB_TAG('M','C','R',' ')},	/* Moose Cree */
   {"crm",	HB_TAG('L','C','R',' ')},	/* Moose Cree -> L-Cree */
   {"crm",	HB_TAG('C','R','E',' ')},	/* Moose Cree -> Cree */
-  {"crp",	HB_TAG('C','P','P',' ')},	/* Creoles and pidgins [family] -> Creoles */
+  {"crp",	HB_TAG('C','P','P',' ')},	/* Creoles and pidgins [collection] -> Creoles */
   {"crr",	HB_TAG_NONE	       },	/* Carolina Algonquian != Carrier */
   {"crs",	HB_TAG('C','P','P',' ')},	/* Seselwa Creole French -> Creoles */
   {"crt",	HB_TAG_NONE	       },	/* Iyojwa'ja Chorote != Crimean Tatar */
@@ -431,7 +433,7 @@
   {"et",	HB_TAG('E','T','I',' ')},	/* Estonian [macrolanguage] */
   {"eto",	HB_TAG('B','T','I',' ')},	/* Eton (Cameroon) -> Beti */
   {"eu",	HB_TAG('E','U','Q',' ')},	/* Basque */
-  {"euq",	HB_TAG_NONE	       },	/* Basque [family] != Basque */
+  {"euq",	HB_TAG_NONE	       },	/* Basque [collection] != Basque */
   {"eve",	HB_TAG('E','V','N',' ')},	/* Even */
   {"evn",	HB_TAG('E','V','K',' ')},	/* Evenki */
   {"ewo",	HB_TAG('B','T','I',' ')},	/* Ewondo -> Beti */
@@ -620,10 +622,11 @@
   {"ijc",	HB_TAG('I','J','O',' ')},	/* Izon -> Ijo */
   {"ije",	HB_TAG('I','J','O',' ')},	/* Biseni -> Ijo */
   {"ijn",	HB_TAG('I','J','O',' ')},	/* Kalabari -> Ijo */
-/*{"ijo",	HB_TAG('I','J','O',' ')},*/	/* Ijo [family] */
+/*{"ijo",	HB_TAG('I','J','O',' ')},*/	/* Ijo [collection] */
   {"ijs",	HB_TAG('I','J','O',' ')},	/* Southeast Ijo -> Ijo */
   {"ik",	HB_TAG('I','P','K',' ')},	/* Inupiaq [macrolanguage] -> Inupiat */
   {"ike",	HB_TAG('I','N','U',' ')},	/* Eastern Canadian Inuktitut -> Inuktitut */
+  {"ike",	HB_TAG('I','N','U','K')},	/* Eastern Canadian Inuktitut -> Nunavik Inuktitut */
   {"ikt",	HB_TAG('I','N','U',' ')},	/* Inuinnaqtun -> Inuktitut */
 /*{"ilo",	HB_TAG('I','L','O',' ')},*/	/* Iloko -> Ilokano */
   {"in",	HB_TAG('I','N','D',' ')},	/* Indonesian (retired code) */
@@ -638,6 +641,7 @@
   {"it",	HB_TAG('I','T','A',' ')},	/* Italian */
   {"itz",	HB_TAG('M','Y','N',' ')},	/* Itzá -> Mayan */
   {"iu",	HB_TAG('I','N','U',' ')},	/* Inuktitut [macrolanguage] */
+  {"iu",	HB_TAG('I','N','U','K')},	/* Inuktitut [macrolanguage] -> Nunavik Inuktitut */
   {"iw",	HB_TAG('I','W','R',' ')},	/* Hebrew (retired code) */
   {"ixl",	HB_TAG('M','Y','N',' ')},	/* Ixil -> Mayan */
   {"ja",	HB_TAG('J','A','N',' ')},	/* Japanese */
@@ -667,7 +671,7 @@
   {"kab",	HB_TAG('B','B','R',' ')},	/* Kabyle -> Berber */
   {"kac",	HB_TAG_NONE	       },	/* Kachin != Kachchi */
   {"kam",	HB_TAG('K','M','B',' ')},	/* Kamba (Kenya) */
-  {"kar",	HB_TAG('K','R','N',' ')},	/* Karen [family] */
+  {"kar",	HB_TAG('K','R','N',' ')},	/* Karen [collection] */
 /*{"kaw",	HB_TAG('K','A','W',' ')},*/	/* Kawi (Old Javanese) */
   {"kbd",	HB_TAG('K','A','B',' ')},	/* Kabardian */
   {"kby",	HB_TAG('K','N','R',' ')},	/* Manga Kanuri -> Kanuri */
@@ -876,7 +880,7 @@
   {"mam",	HB_TAG('M','A','M',' ')},	/* Mam */
   {"mam",	HB_TAG('M','Y','N',' ')},	/* Mam -> Mayan */
   {"man",	HB_TAG('M','N','K',' ')},	/* Mandingo [macrolanguage] -> Maninka */
-  {"map",	HB_TAG_NONE	       },	/* Austronesian [family] != Mapudungun */
+  {"map",	HB_TAG_NONE	       },	/* Austronesian [collection] != Mapudungun */
   {"maw",	HB_TAG_NONE	       },	/* Mampruli != Marwari */
   {"max",	HB_TAG('M','L','Y',' ')},	/* North Moluccan Malay -> Malay */
   {"max",	HB_TAG('C','P','P',' ')},	/* North Moluccan Malay -> Creoles */
@@ -936,6 +940,7 @@
   {"mnw",	HB_TAG('M','O','N','T')},	/* Mon -> Thailand Mon */
   {"mnx",	HB_TAG_NONE	       },	/* Manikion != Manx */
   {"mo",	HB_TAG('M','O','L',' ')},	/* Moldavian (retired code) */
+  {"mo",	HB_TAG('R','O','M',' ')},	/* Moldavian (retired code) -> Romanian */
   {"mod",	HB_TAG('C','P','P',' ')},	/* Mobilian -> Creoles */
 /*{"moh",	HB_TAG('M','O','H',' ')},*/	/* Mohawk */
   {"mok",	HB_TAG_NONE	       },	/* Morori != Moksha */
@@ -958,7 +963,7 @@
   {"mts",	HB_TAG_NONE	       },	/* Yora != Maltese */
   {"mud",	HB_TAG('C','P','P',' ')},	/* Mednyj Aleut -> Creoles */
   {"mui",	HB_TAG('M','L','Y',' ')},	/* Musi -> Malay */
-  {"mun",	HB_TAG_NONE	       },	/* Munda [family] != Mundari */
+  {"mun",	HB_TAG_NONE	       },	/* Munda [collection] != Mundari */
   {"mup",	HB_TAG('R','A','J',' ')},	/* Malvi -> Rajasthani */
   {"muq",	HB_TAG('H','M','N',' ')},	/* Eastern Xiangxi Miao -> Hmong */
 /*{"mus",	HB_TAG('M','U','S',' ')},*/	/* Creek -> Muscogee */
@@ -973,7 +978,7 @@
   {"mww",	HB_TAG('H','M','N',' ')},	/* Hmong Daw -> Hmong */
   {"my",	HB_TAG('B','R','M',' ')},	/* Burmese */
   {"mym",	HB_TAG('M','E','N',' ')},	/* Me’en */
-/*{"myn",	HB_TAG('M','Y','N',' ')},*/	/* Mayan [family] */
+/*{"myn",	HB_TAG('M','Y','N',' ')},*/	/* Mayan [collection] */
   {"myq",	HB_TAG('M','N','K',' ')},	/* Forest Maninka (retired code) -> Maninka */
   {"myv",	HB_TAG('E','R','Z',' ')},	/* Erzya */
   {"mzb",	HB_TAG('B','B','R',' ')},	/* Tumzabt -> Berber */
@@ -982,7 +987,7 @@
   {"na",	HB_TAG('N','A','U',' ')},	/* Nauru -> Nauruan */
   {"nag",	HB_TAG('N','A','G',' ')},	/* Naga Pidgin -> Naga-Assamese */
   {"nag",	HB_TAG('C','P','P',' ')},	/* Naga Pidgin -> Creoles */
-/*{"nah",	HB_TAG('N','A','H',' ')},*/	/* Nahuatl [family] */
+/*{"nah",	HB_TAG('N','A','H',' ')},*/	/* Nahuatl [collection] */
   {"nan",	HB_TAG('Z','H','S',' ')},	/* Min Nan Chinese -> Chinese, Simplified */
 /*{"nap",	HB_TAG('N','A','P',' ')},*/	/* Neapolitan */
   {"nas",	HB_TAG_NONE	       },	/* Naasioi != Naskapi */
@@ -1039,7 +1044,6 @@
   {"nln",	HB_TAG('N','A','H',' ')},	/* Durango Nahuatl (retired code) -> Nahuatl */
   {"nlv",	HB_TAG('N','A','H',' ')},	/* Orizaba Nahuatl -> Nahuatl */
   {"nn",	HB_TAG('N','Y','N',' ')},	/* Norwegian Nynorsk (Nynorsk, Norwegian) */
-  {"nn",	HB_TAG('N','O','R',' ')},	/* Norwegian Nynorsk -> Norwegian */
   {"nnh",	HB_TAG('B','M','L',' ')},	/* Ngiemboon -> Bamileke */
   {"nnz",	HB_TAG('B','M','L',' ')},	/* Nda'nda' -> Bamileke */
   {"no",	HB_TAG('N','O','R',' ')},	/* Norwegian [macrolanguage] */
@@ -1093,7 +1097,7 @@
   {"otw",	HB_TAG('O','J','B',' ')},	/* Ottawa -> Ojibway */
   {"oua",	HB_TAG('B','B','R',' ')},	/* Tagargrent -> Berber */
   {"pa",	HB_TAG('P','A','N',' ')},	/* Punjabi */
-  {"paa",	HB_TAG_NONE	       },	/* Papuan [family] != Palestinian Aramaic */
+  {"paa",	HB_TAG_NONE	       },	/* Papuan [collection] != Palestinian Aramaic */
 /*{"pag",	HB_TAG('P','A','G',' ')},*/	/* Pangasinan */
   {"pal",	HB_TAG_NONE	       },	/* Pahlavi != Pali */
 /*{"pam",	HB_TAG('P','A','M',' ')},*/	/* Pampanga -> Pampangan */
@@ -1308,6 +1312,9 @@
   {"sgo",	HB_TAG_NONE	       },	/* Songa (retired code) != Sango */
 /*{"sgs",	HB_TAG('S','G','S',' ')},*/	/* Samogitian */
   {"sgw",	HB_TAG('C','H','G',' ')},	/* Sebat Bet Gurage -> Chaha Gurage */
+  {"sh",	HB_TAG('B','O','S',' ')},	/* Serbo-Croatian [macrolanguage] -> Bosnian */
+  {"sh",	HB_TAG('H','R','V',' ')},	/* Serbo-Croatian [macrolanguage] -> Croatian */
+  {"sh",	HB_TAG('S','R','B',' ')},	/* Serbo-Croatian [macrolanguage] -> Serbian */
   {"shi",	HB_TAG('S','H','I',' ')},	/* Tachelhit */
   {"shi",	HB_TAG('B','B','R',' ')},	/* Tachelhit -> Berber */
   {"shl",	HB_TAG('Q','I','N',' ')},	/* Shendu -> Chin */
@@ -1329,7 +1336,7 @@
   {"skw",	HB_TAG('C','P','P',' ')},	/* Skepi Creole Dutch -> Creoles */
   {"sky",	HB_TAG_NONE	       },	/* Sikaiana != Slovak */
   {"sl",	HB_TAG('S','L','V',' ')},	/* Slovenian */
-  {"sla",	HB_TAG_NONE	       },	/* Slavic [family] != Slavey */
+  {"sla",	HB_TAG_NONE	       },	/* Slavic [collection] != Slavey */
   {"sm",	HB_TAG('S','M','O',' ')},	/* Samoan */
   {"sma",	HB_TAG('S','S','M',' ')},	/* Southern Sami */
   {"smj",	HB_TAG('L','S','M',' ')},	/* Lule Sami */
@@ -1451,7 +1458,7 @@
   {"tpi",	HB_TAG('C','P','P',' ')},	/* Tok Pisin -> Creoles */
   {"tr",	HB_TAG('T','R','K',' ')},	/* Turkish */
   {"trf",	HB_TAG('C','P','P',' ')},	/* Trinidadian Creole English -> Creoles */
-  {"trk",	HB_TAG_NONE	       },	/* Turkic [family] != Turkish */
+  {"trk",	HB_TAG_NONE	       },	/* Turkic [collection] != Turkish */
   {"tru",	HB_TAG('T','U','A',' ')},	/* Turoyo -> Turoyo Aramaic */
   {"tru",	HB_TAG('S','Y','R',' ')},	/* Turoyo -> Syriac */
   {"ts",	HB_TAG('T','S','G',' ')},	/* Tsonga */
@@ -1593,7 +1600,7 @@
   {"zlq",	HB_TAG('Z','H','A',' ')},	/* Liuqian Zhuang -> Zhuang */
   {"zmi",	HB_TAG('M','L','Y',' ')},	/* Negeri Sembilan Malay -> Malay */
   {"zmz",	HB_TAG('B','A','D','0')},	/* Mbandja -> Banda */
-  {"znd",	HB_TAG_NONE	       },	/* Zande [family] != Zande */
+  {"znd",	HB_TAG_NONE	       },	/* Zande [collection] != Zande */
   {"zne",	HB_TAG('Z','N','D',' ')},	/* Zande */
   {"zom",	HB_TAG('Q','I','N',' ')},	/* Zou -> Chin */
   {"zqe",	HB_TAG('Z','H','A',' ')},	/* Qiubei Zhuang -> Zhuang */
@@ -2607,14 +2614,8 @@
     if (0 == strcmp (&lang_str[1], "o-nyn"))
     {
       /* Norwegian Nynorsk (retired code) */
-      unsigned int i;
-      hb_tag_t possible_tags[] = {
-	HB_TAG('N','Y','N',' '),  /* Norwegian Nynorsk (Nynorsk, Norwegian) */
-	HB_TAG('N','O','R',' '),  /* Norwegian */
-      };
-      for (i = 0; i < 2 && i < *count; i++)
-	tags[i] = possible_tags[i];
-      *count = i;
+      tags[0] = HB_TAG('N','Y','N',' ');  /* Norwegian Nynorsk (Nynorsk, Norwegian) */
+      *count = 1;
       return true;
     }
     break;
@@ -2623,8 +2624,14 @@
 	&& subtag_matches (lang_str, limit, "-md"))
     {
       /* Romanian; Moldova */
-      tags[0] = HB_TAG('M','O','L',' ');  /* Moldavian */
-      *count = 1;
+      unsigned int i;
+      hb_tag_t possible_tags[] = {
+	HB_TAG('M','O','L',' '),  /* Moldavian */
+	HB_TAG('R','O','M',' '),  /* Romanian */
+      };
+      for (i = 0; i < 2 && i < *count; i++)
+	tags[i] = possible_tags[i];
+      *count = i;
       return true;
     }
     break;
@@ -2813,15 +2820,15 @@
   case HB_TAG('A','R','K',' '):  /* Rakhine */
     return hb_language_from_string ("rki", -1);  /* Rakhine */
   case HB_TAG('A','T','H',' '):  /* Athapaskan */
-    return hb_language_from_string ("ath", -1);  /* Athapascan [family] */
+    return hb_language_from_string ("ath", -1);  /* Athapascan [collection] */
   case HB_TAG('B','B','R',' '):  /* Berber */
-    return hb_language_from_string ("ber", -1);  /* Berber [family] */
+    return hb_language_from_string ("ber", -1);  /* Berber [collection] */
   case HB_TAG('B','I','K',' '):  /* Bikol */
     return hb_language_from_string ("bik", -1);  /* Bikol [macrolanguage] */
   case HB_TAG('B','T','K',' '):  /* Batak */
-    return hb_language_from_string ("btk", -1);  /* Batak [family] */
+    return hb_language_from_string ("btk", -1);  /* Batak [collection] */
   case HB_TAG('C','P','P',' '):  /* Creoles */
-    return hb_language_from_string ("crp", -1);  /* Creoles and pidgins [family] */
+    return hb_language_from_string ("crp", -1);  /* Creoles and pidgins [collection] */
   case HB_TAG('C','R','R',' '):  /* Carrier */
     return hb_language_from_string ("crx", -1);  /* Carrier */
   case HB_TAG('D','G','R',' '):  /* Dogri (macrolanguage) */
@@ -2838,6 +2845,8 @@
     return hb_language_from_string ("fa", -1);  /* Persian [macrolanguage] */
   case HB_TAG('G','O','N',' '):  /* Gondi */
     return hb_language_from_string ("gon", -1);  /* Gondi [macrolanguage] */
+  case HB_TAG('H','M','A',' '):  /* High Mari */
+    return hb_language_from_string ("mrj", -1);  /* Western Mari */
   case HB_TAG('H','M','N',' '):  /* Hmong */
     return hb_language_from_string ("hmn", -1);  /* Hmong [macrolanguage] */
   case HB_TAG('H','N','D',' '):  /* Hindko */
@@ -2847,7 +2856,7 @@
   case HB_TAG('I','B','A',' '):  /* Iban */
     return hb_language_from_string ("iba", -1);  /* Iban */
   case HB_TAG('I','J','O',' '):  /* Ijo */
-    return hb_language_from_string ("ijo", -1);  /* Ijo [family] */
+    return hb_language_from_string ("ijo", -1);  /* Ijo [collection] */
   case HB_TAG('I','N','U',' '):  /* Inuktitut */
     return hb_language_from_string ("iu", -1);  /* Inuktitut [macrolanguage] */
   case HB_TAG('I','P','K',' '):  /* Inupiat */
@@ -2873,11 +2882,13 @@
   case HB_TAG('K','P','L',' '):  /* Kpelle */
     return hb_language_from_string ("kpe", -1);  /* Kpelle [macrolanguage] */
   case HB_TAG('K','R','N',' '):  /* Karen */
-    return hb_language_from_string ("kar", -1);  /* Karen [family] */
+    return hb_language_from_string ("kar", -1);  /* Karen [collection] */
   case HB_TAG('K','U','I',' '):  /* Kui */
     return hb_language_from_string ("uki", -1);  /* Kui (India) */
   case HB_TAG('K','U','R',' '):  /* Kurdish */
     return hb_language_from_string ("ku", -1);  /* Kurdish [macrolanguage] */
+  case HB_TAG('L','M','A',' '):  /* Low Mari */
+    return hb_language_from_string ("mhr", -1);  /* Eastern Mari */
   case HB_TAG('L','U','H',' '):  /* Luyia */
     return hb_language_from_string ("luy", -1);  /* Luyia [macrolanguage] */
   case HB_TAG('L','V','I',' '):  /* Latvian */
@@ -2897,9 +2908,9 @@
   case HB_TAG('M','O','N','T'):  /* Thailand Mon */
     return hb_language_from_string ("mnw-TH", -1);  /* Mon; Thailand */
   case HB_TAG('M','Y','N',' '):  /* Mayan */
-    return hb_language_from_string ("myn", -1);  /* Mayan [family] */
+    return hb_language_from_string ("myn", -1);  /* Mayan [collection] */
   case HB_TAG('N','A','H',' '):  /* Nahuatl */
-    return hb_language_from_string ("nah", -1);  /* Nahuatl [family] */
+    return hb_language_from_string ("nah", -1);  /* Nahuatl [collection] */
   case HB_TAG('N','E','P',' '):  /* Nepali */
     return hb_language_from_string ("ne", -1);  /* Nepali [macrolanguage] */
   case HB_TAG('N','I','S',' '):  /* Nisi */
@@ -2926,6 +2937,8 @@
     return hb_language_from_string ("qwh", -1);  /* Huaylas Ancash Quechua */
   case HB_TAG('R','A','J',' '):  /* Rajasthani */
     return hb_language_from_string ("raj", -1);  /* Rajasthani [macrolanguage] */
+  case HB_TAG('R','O','M',' '):  /* Romanian */
+    return hb_language_from_string ("ro", -1);  /* Romanian */
   case HB_TAG('R','O','Y',' '):  /* Romany */
     return hb_language_from_string ("rom", -1);  /* Romany [macrolanguage] */
   case HB_TAG('S','Q','I',' '):  /* Albanian */

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -41,6 +41,7 @@
   switch ((hb_tag_t) script)
   {
     case HB_SCRIPT_INVALID:		return HB_OT_TAG_DEFAULT_SCRIPT;
+    case HB_SCRIPT_MATH:		return HB_OT_TAG_MATH_SCRIPT;
 
     /* KATAKANA and HIRAGANA both map to 'kana' */
     case HB_SCRIPT_HIRAGANA:		return HB_TAG('k','a','n','a');
@@ -63,6 +64,8 @@
 {
   if (unlikely (tag == HB_OT_TAG_DEFAULT_SCRIPT))
     return HB_SCRIPT_INVALID;
+  if (unlikely (tag == HB_OT_TAG_MATH_SCRIPT))
+    return HB_SCRIPT_MATH;
 
   /* This side of the conversion is fully algorithmic. */
 

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -263,7 +263,7 @@
     if (coords_length && *coords_length)
     {
       hb_array_t<const HBFixed> instanceCoords = instance->get_coordinates (axisCount)
-							 .sub_array (0, *coords_length);
+							 .sub_array (0, coords_length);
       for (unsigned int i = 0; i < instanceCoords.length; i++)
 	coords[i] = instanceCoords.arrayZ[i].to_float ();
     }

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -399,7 +399,7 @@
 				  get_offset (glyphCount) - get_offset (0)));
   }
 
-  /* GlyphVariationData not sanitized here; must be checked while accessing each glyph varation data */
+  /* GlyphVariationData not sanitized here; must be checked while accessing each glyph variation data */
   bool sanitize (hb_sanitize_context_t *c) const
   { return sanitize_shallow (c); }
 
@@ -498,9 +498,9 @@
   public:
   struct accelerator_t
   {
-    void init (hb_face_t *face)
+    accelerator_t (hb_face_t *face)
     { table = hb_sanitize_context_t ().reference_table<gvar> (face); }
-    void fini () { table.destroy (); }
+    ~accelerator_t () { table.destroy (); }
 
     private:
     struct x_getter { static float get (const contour_point_t &p) { return p.x; } };
@@ -698,7 +698,9 @@
   DEFINE_SIZE_MIN (20);
 };
 
-struct gvar_accelerator_t : gvar::accelerator_t {};
+struct gvar_accelerator_t : gvar::accelerator_t {
+  gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {}
+};
 
 } /* namespace OT */
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -177,9 +177,6 @@
 
     inner_maps.resize (var_store->get_sub_table_count ());
 
-    for (unsigned int i = 0; i < inner_maps.length; i++)
-      inner_maps[i].init ();
-
     if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return;
 
     bool retain_adv_map = false;
@@ -229,8 +226,8 @@
     for (unsigned int i = 0; i < inner_sets.length; i++)
       hb_set_destroy (inner_sets[i]);
     hb_set_destroy (adv_set);
-    inner_maps.fini_deep ();
-    index_map_plans.fini_deep ();
+    inner_maps.fini ();
+    index_map_plans.fini ();
   }
 
   hb_inc_bimap_t outer_map;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -303,6 +303,9 @@
  * values for the axis are mapped to the interval [-1,1], with the default
  * axis value mapped to 0.
  *
+ * The normalized values have 14 bits of fixed-point sub-integer precision as per
+ * OpenType specification.
+ *
  * Any additional scaling defined in the face's `avar` table is also
  * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.h	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.h	2022-02-13 03:14:24 UTC (rev 61999)
@@ -109,7 +109,7 @@
  * @tag: The #hb_tag_t tag identifying the design variation of the axis
  * @name_id: The `name` table Name ID that provides display names for the axis
  * @flags: The #hb_ot_var_axis_flags_t flags for the axis
- * @min_value: The mininum value on the variation axis that the font covers
+ * @min_value: The minimum value on the variation axis that the font covers
  * @default_value: The position on the variation axis corresponding to the font's defaults
  * @max_value: The maximum value on the variation axis that the font covers
  * 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -42,26 +42,13 @@
 {
   struct vertex_t
   {
-    vertex_t () :
-        distance (0),
-        space (0),
-        parents (),
-        start (0),
-        end (0),
-        priority(0) {}
-
-    void fini () {
-      obj.fini ();
-      parents.fini ();
-    }
-
     hb_serialize_context_t::object_t obj;
-    int64_t distance;
-    int64_t space;
+    int64_t distance = 0 ;
+    int64_t space = 0 ;
     hb_vector_t<unsigned> parents;
-    unsigned start;
-    unsigned end;
-    unsigned priority;
+    unsigned start = 0;
+    unsigned end = 0;
+    unsigned priority = 0;
 
     bool is_shared () const
     {
@@ -186,7 +173,7 @@
 
   ~graph_t ()
   {
-    vertices_.fini_deep ();
+    vertices_.fini ();
   }
 
   bool in_error () const
@@ -309,7 +296,7 @@
     remap_all_obj_indices (id_map, &sorted_graph);
 
     hb_swap (vertices_, sorted_graph);
-    sorted_graph.fini_deep ();
+    sorted_graph.fini ();
   }
 
   /*
@@ -369,7 +356,7 @@
     remap_all_obj_indices (id_map, &sorted_graph);
 
     hb_swap (vertices_, sorted_graph);
-    sorted_graph.fini_deep ();
+    sorted_graph.fini ();
   }
 
   /*
@@ -402,11 +389,15 @@
     while (roots)
     {
       unsigned next = HB_SET_VALUE_INVALID;
+      if (unlikely (!check_success (!roots.in_error ()))) break;
       if (!roots.next (&next)) break;
 
       hb_set_t connected_roots;
       find_connected_nodes (next, roots, visited, connected_roots);
+      if (unlikely (!check_success (!connected_roots.in_error ()))) break;
+
       isolate_subgraph (connected_roots);
+      if (unlikely (!check_success (!connected_roots.in_error ()))) break;
 
       unsigned next_space = this->next_space ();
       num_roots_for_space_.push (0);
@@ -423,6 +414,8 @@
       //                into the 32 bit space as needed, instead of using isolation.
     }
 
+
+
     return true;
   }
 
@@ -865,7 +858,7 @@
     // Redundant ones are filtered out later on by the visited set.
     // According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf
     // for practical performance this is faster then using a more advanced queue
-    // (such as a fibonaacci queue) with a fast decrease priority.
+    // (such as a fibonacci queue) with a fast decrease priority.
     for (unsigned i = 0; i < vertices_.length; i++)
     {
       if (i == vertices_.length - 1)
@@ -1074,6 +1067,7 @@
                              hb_set_t& visited,
                              hb_set_t& connected)
   {
+    if (unlikely (!check_success (!visited.in_error ()))) return;
     if (visited.has (start_idx)) return;
     visited.add (start_idx);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -279,7 +279,7 @@
     object_pool.release (obj);
   }
 
-  /* Set share to false when an object is unlikely sharable with others
+  /* Set share to false when an object is unlikely shareable with others
    * so not worth an attempt, or a contiguous table is serialized as
    * multiple consecutive objects in the reverse order so can't be shared.
    */
@@ -381,7 +381,7 @@
   // Adding a virtual link from object a to object b will ensure that object b is always packed after
   // object a in the final serialized order.
   //
-  // This is useful in certain situtations where there needs to be a specific ordering in the
+  // This is useful in certain situations where there needs to be a specific ordering in the
   // final serialization. Such as when platform bugs require certain orderings, or to provide
   //  guidance to the repacker for better offset overflow resolution.
   void add_virtual_link (objidx_t objidx)
@@ -510,7 +510,7 @@
   { return reinterpret_cast<Type *> (this->head); }
   template <typename Type>
   Type *start_embed (const Type &obj) const
-  { return start_embed (hb_addressof (obj)); }
+  { return start_embed (std::addressof (obj)); }
 
   bool err (hb_serialize_error_t err_type)
   {
@@ -548,7 +548,7 @@
   }
   template <typename Type>
   Type *embed (const Type &obj)
-  { return embed (hb_addressof (obj)); }
+  { return embed (std::addressof (obj)); }
 
   template <typename Type, typename ...Ts> auto
   _copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
@@ -595,12 +595,12 @@
   }
   template <typename Type>
   Type *extend_size (Type &obj, size_t size)
-  { return extend_size (hb_addressof (obj), size); }
+  { return extend_size (std::addressof (obj), size); }
 
   template <typename Type>
   Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); }
   template <typename Type>
-  Type *extend_min (Type &obj) { return extend_min (hb_addressof (obj)); }
+  Type *extend_min (Type &obj) { return extend_min (std::addressof (obj)); }
 
   template <typename Type, typename ...Ts>
   Type *extend (Type *obj, Ts&&... ds)
@@ -607,7 +607,7 @@
   { return extend_size (obj, obj->get_size (std::forward<Ts> (ds)...)); }
   template <typename Type, typename ...Ts>
   Type *extend (Type &obj, Ts&&... ds)
-  { return extend (hb_addressof (obj), std::forward<Ts> (ds)...); }
+  { return extend (std::addressof (obj), std::forward<Ts> (ds)...); }
 
   /* Output routines. */
   hb_bytes_t copy_bytes () const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -126,6 +126,13 @@
 	       unsigned int        num_features,
 	       const char * const *shaper_list)
 {
+  hb_buffer_t *text_buffer = nullptr;
+  if (buffer->flags & HB_BUFFER_FLAG_VERIFY)
+  {
+    text_buffer = hb_buffer_create ();
+    hb_buffer_append (text_buffer, buffer, 0, -1);
+  }
+
   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached2 (font->face, &buffer->props,
 							      features, num_features,
 							      font->coords, font->num_coords,
@@ -133,6 +140,17 @@
   hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
   hb_shape_plan_destroy (shape_plan);
 
+  if (text_buffer)
+  {
+    if (res && !buffer->verify (text_buffer,
+				font,
+				features,
+				num_features,
+				shaper_list))
+      res = false;
+    hb_buffer_destroy (text_buffer);
+  }
+
   return res;
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -48,13 +48,12 @@
 {
   return tanf (a * float (M_PI / 180.));
 }
-#if 0
+
 static inline float
 _hb_ratio_to_angle (float r)
 {
   return atanf (r) * float (180. / M_PI);
 }
-#endif
 
 /**
  * hb_style_get_value:
@@ -73,7 +72,8 @@
 hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
 {
   if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO))
-    return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE));
+    return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE))
+	 + font->slant;
 
   hb_face_t *face = font->face;
 
@@ -109,7 +109,14 @@
 	   : 12.f;
   }
   case HB_STYLE_TAG_SLANT_ANGLE:
-    return face->table.post->table->italicAngle.to_float ();
+  {
+    float angle = face->table.post->table->italicAngle.to_float ();
+
+    if (font->slant)
+      angle = _hb_ratio_to_angle (font->slant + _hb_angle_to_ratio (angle));
+
+    return angle;
+  }
   case HB_STYLE_TAG_WIDTH:
     return face->table.OS2->has_data ()
 	   ? face->table.OS2->get_width ()

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -275,45 +275,24 @@
 
 struct subr_closures_t
 {
-  subr_closures_t () : valid (false), global_closure (nullptr)
-  { local_closures.init (); }
-
-  void init (unsigned int fd_count)
+  subr_closures_t (unsigned int fd_count) : valid (false), global_closure (), local_closures ()
   {
     valid = true;
-    global_closure = hb_set_create ();
-    if (global_closure == hb_set_get_empty ())
-      valid = false;
     if (!local_closures.resize (fd_count))
       valid = false;
-
-    for (unsigned int i = 0; i < local_closures.length; i++)
-    {
-      local_closures[i] = hb_set_create ();
-      if (local_closures[i] == hb_set_get_empty ())
-	valid = false;
-    }
   }
 
-  void fini ()
-  {
-    hb_set_destroy (global_closure);
-    for (unsigned int i = 0; i < local_closures.length; i++)
-      hb_set_destroy (local_closures[i]);
-    local_closures.fini ();
-  }
-
   void reset ()
   {
-    hb_set_clear (global_closure);
+    global_closure.clear();
     for (unsigned int i = 0; i < local_closures.length; i++)
-      hb_set_clear (local_closures[i]);
+      local_closures[i].clear();
   }
 
   bool is_valid () const { return valid; }
   bool  valid;
-  hb_set_t  *global_closure;
-  hb_vector_t<hb_set_t *> local_closures;
+  hb_set_t  global_closure;
+  hb_vector_t<hb_set_t> local_closures;
 };
 
 struct parsed_cs_op_t : op_str_t
@@ -320,7 +299,6 @@
 {
   void init (unsigned int subr_num_ = 0)
   {
-    op_str_t::init ();
     subr_num = subr_num_;
     drop_flag = false;
     keep_flag = false;
@@ -327,8 +305,6 @@
     skip_flag = false;
   }
 
-  void fini () { op_str_t::fini (); }
-
   bool for_drop () const { return drop_flag; }
   void set_drop ()       { if (!for_keep ()) drop_flag = true; }
 
@@ -416,16 +392,6 @@
 
 struct parsed_cs_str_vec_t : hb_vector_t<parsed_cs_str_t>
 {
-  void init (unsigned int len_ = 0)
-  {
-    SUPER::init ();
-    if (unlikely (!resize (len_)))
-      return;
-    for (unsigned int i = 0; i < length; i++)
-      (*this)[i].init ();
-  }
-  void fini () { SUPER::fini_deep (); }
-
   private:
   typedef hb_vector_t<parsed_cs_str_t> SUPER;
 };
@@ -496,7 +462,7 @@
 
 struct subr_remap_t : hb_inc_bimap_t
 {
-  void create (hb_set_t *closure)
+  void create (const hb_set_t *closure)
   {
     /* create a remapping of subroutine numbers from old to new.
      * no optimization based on usage counts. fonttools doesn't appear doing that either.
@@ -526,21 +492,11 @@
 
 struct subr_remaps_t
 {
-  subr_remaps_t ()
+  subr_remaps_t (unsigned int fdCount)
   {
-    global_remap.init ();
-    local_remaps.init ();
+    local_remaps.resize (fdCount);
   }
 
-  ~subr_remaps_t () { fini (); }
-
-  void init (unsigned int fdCount)
-  {
-    if (unlikely (!local_remaps.resize (fdCount))) return;
-    for (unsigned int i = 0; i < fdCount; i++)
-      local_remaps[i].init ();
-  }
-
   bool in_error()
   {
     return local_remaps.in_error ();
@@ -548,17 +504,11 @@
 
   void create (subr_closures_t& closures)
   {
-    global_remap.create (closures.global_closure);
+    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[i].create (&closures.local_closures[i]);
   }
 
-  void fini ()
-  {
-    global_remap.fini ();
-    local_remaps.fini_deep ();
-  }
-
   subr_remap_t	       global_remap;
   hb_vector_t<subr_remap_t>  local_remaps;
 };
@@ -567,22 +517,9 @@
 struct subr_subsetter_t
 {
   subr_subsetter_t (ACC &acc_, const hb_subset_plan_t *plan_)
-    : acc (acc_), plan (plan_)
-  {
-    parsed_charstrings.init ();
-    parsed_global_subrs.init ();
-    parsed_local_subrs.init ();
-  }
+      : acc (acc_), plan (plan_), closures(acc_.fdCount), remaps(acc_.fdCount)
+  {}
 
-  ~subr_subsetter_t ()
-  {
-    closures.fini ();
-    remaps.fini ();
-    parsed_charstrings.fini_deep ();
-    parsed_global_subrs.fini_deep ();
-    parsed_local_subrs.fini_deep ();
-  }
-
   /* Subroutine subsetting with --no-desubroutinize runs in phases:
    *
    * 1. execute charstrings/subroutines to determine subroutine closures
@@ -599,12 +536,9 @@
    */
   bool subset (void)
   {
-    closures.init (acc.fdCount);
-    remaps.init (acc.fdCount);
+    parsed_charstrings.resize (plan->num_output_glyphs ());
+    parsed_global_subrs.resize (acc.globalSubrs->count);
 
-    parsed_charstrings.init (plan->num_output_glyphs ());
-    parsed_global_subrs.init (acc.globalSubrs->count);
-
     if (unlikely (remaps.in_error()
                   || parsed_charstrings.in_error ()
                   || parsed_global_subrs.in_error ())) {
@@ -615,7 +549,7 @@
 
     for (unsigned int i = 0; i < acc.fdCount; i++)
     {
-      parsed_local_subrs[i].init (acc.privateDicts[i].localSubrs->count);
+      parsed_local_subrs[i].resize (acc.privateDicts[i].localSubrs->count);
       if (unlikely (parsed_local_subrs[i].in_error ())) return false;
     }
     if (unlikely (!closures.valid))
@@ -638,7 +572,7 @@
       subr_subset_param_t  param;
       param.init (&parsed_charstrings[i],
 		  &parsed_global_subrs,  &parsed_local_subrs[fd],
-		  closures.global_closure, closures.local_closures[fd],
+		  &closures.global_closure, &closures.local_closures[fd],
 		  plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
 
       if (unlikely (!interp.interpret (param)))
@@ -662,7 +596,7 @@
 	subr_subset_param_t  param;
 	param.init (&parsed_charstrings[i],
 		    &parsed_global_subrs,  &parsed_local_subrs[fd],
-		    closures.global_closure, closures.local_closures[fd],
+		    &closures.global_closure, &closures.local_closures[fd],
                     plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
 
 	drop_hints_param_t  drop;
@@ -687,7 +621,7 @@
 	subr_subset_param_t  param;
 	param.init (&parsed_charstrings[i],
 		    &parsed_global_subrs,  &parsed_local_subrs[fd],
-		    closures.global_closure, closures.local_closures[fd],
+		    &closures.global_closure, &closures.local_closures[fd],
                     plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
 	collect_subr_refs_in_str (parsed_charstrings[i], param);
       }

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -362,43 +362,11 @@
 
 struct cff_subset_plan {
   cff_subset_plan ()
-    : info (),
-      orig_fdcount (0),
-      subset_fdcount (1),
-      subset_fdselect_format (0),
-      drop_hints (false),
-      desubroutinize(false)
   {
-    topdict_mod.init ();
-    subset_fdselect_ranges.init ();
-    fdmap.init ();
-    subset_charstrings.init ();
-    subset_globalsubrs.init ();
-    subset_localsubrs.init ();
-    fontdicts_mod.init ();
-    subset_enc_code_ranges.init ();
-    subset_enc_supp_codes.init ();
-    subset_charset_ranges.init ();
-    sidmap.init ();
     for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
       topDictModSIDs[i] = CFF_UNDEF_SID;
   }
 
-  ~cff_subset_plan ()
-  {
-    topdict_mod.fini ();
-    subset_fdselect_ranges.fini ();
-    fdmap.fini ();
-    subset_charstrings.fini_deep ();
-    subset_globalsubrs.fini_deep ();
-    subset_localsubrs.fini_deep ();
-    fontdicts_mod.fini ();
-    subset_enc_code_ranges.fini ();
-    subset_enc_supp_codes.fini ();
-    subset_charset_ranges.fini ();
-    sidmap.fini ();
-  }
-
   void plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
   {
     const Encoding *encoding = acc.encoding;
@@ -672,9 +640,9 @@
   cff1_sub_table_info_t		info;
 
   unsigned int    num_glyphs;
-  unsigned int    orig_fdcount;
-  unsigned int    subset_fdcount;
-  unsigned int    subset_fdselect_format;
+  unsigned int    orig_fdcount = 0;
+  unsigned int    subset_fdcount = 1;
+  unsigned int    subset_fdselect_format = 0;
   hb_vector_t<code_pair_t>   subset_fdselect_ranges;
 
   /* font dict index remap table from fullset FDArray to subset FDArray.
@@ -686,7 +654,7 @@
   hb_vector_t<str_buff_vec_t>	subset_localsubrs;
   hb_vector_t<cff1_font_dict_values_mod_t>  fontdicts_mod;
 
-  bool		drop_hints;
+  bool		drop_hints = false;
 
   bool		gid_renum;
   bool		subset_encoding;
@@ -702,7 +670,7 @@
   remap_sid_t	sidmap;
   unsigned int	topDictModSIDs[name_dict_values_t::ValCount];
 
-  bool		desubroutinize;
+  bool		desubroutinize = false;
 };
 
 static bool _serialize_cff1 (hb_serialize_context_t *c,

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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -233,30 +233,7 @@
 };
 
 struct cff2_subset_plan {
-  cff2_subset_plan ()
-    : orig_fdcount (0),
-      subset_fdcount(1),
-      subset_fdselect_size (0),
-      subset_fdselect_format (0),
-      drop_hints (false),
-      desubroutinize (false)
-  {
-    subset_fdselect_ranges.init ();
-    fdmap.init ();
-    subset_charstrings.init ();
-    subset_globalsubrs.init ();
-    subset_localsubrs.init ();
-  }
 
-  ~cff2_subset_plan ()
-  {
-    subset_fdselect_ranges.fini ();
-    fdmap.fini ();
-    subset_charstrings.fini_deep ();
-    subset_globalsubrs.fini_deep ();
-    subset_localsubrs.fini_deep ();
-  }
-
   bool create (const OT::cff2::accelerator_subset_t &acc,
 	      hb_subset_plan_t *plan)
   {
@@ -320,10 +297,10 @@
 
   cff2_sub_table_info_t info;
 
-  unsigned int    orig_fdcount;
-  unsigned int    subset_fdcount;
-  unsigned int	  subset_fdselect_size;
-  unsigned int    subset_fdselect_format;
+  unsigned int    orig_fdcount = 0;
+  unsigned int    subset_fdcount = 1;
+  unsigned int	  subset_fdselect_size = 0;
+  unsigned int    subset_fdselect_format = 0;
   hb_vector_t<code_pair_t>   subset_fdselect_ranges;
 
   hb_inc_bimap_t   fdmap;
@@ -332,8 +309,8 @@
   str_buff_vec_t	    subset_globalsubrs;
   hb_vector_t<str_buff_vec_t> subset_localsubrs;
 
-  bool	    drop_hints;
-  bool	    desubroutinize;
+  bool	    drop_hints = false;
+  bool	    desubroutinize = false;
 };
 
 static bool _serialize_cff2 (hb_serialize_context_t *c,
@@ -473,12 +450,8 @@
 bool
 hb_subset_cff2 (hb_subset_context_t *c)
 {
-  OT::cff2::accelerator_subset_t acc;
-  acc.init (c->plan->source);
-  bool result = likely (acc.is_valid ()) && _hb_subset_cff2 (acc, c);
-  acc.fini ();
-
-  return result;
+  OT::cff2::accelerator_subset_t acc (c->plan->source);
+  return acc.is_valid () && _hb_subset_cff2 (acc, c);
 }
 
 #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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -228,10 +228,8 @@
 	       const hb_set_t	   *unicodes,
 	       hb_set_t		   *glyphset)
 {
-  OT::cmap::accelerator_t cmap;
-  cmap.init (face);
+  OT::cmap::accelerator_t cmap (face);
   cmap.table->closure_glyphs (unicodes, glyphset);
-  cmap.fini ();
 }
 
 static void _colr_closure (hb_face_t *face,
@@ -239,8 +237,7 @@
                            hb_map_t *palettes_map,
                            hb_set_t *glyphs_colred)
 {
-  OT::COLR::accelerator_t colr;
-  colr.init (face);
+  OT::COLR::accelerator_t colr (face);
   if (!colr.is_valid ()) return;
 
   unsigned iteration_count = 0;
@@ -263,7 +260,6 @@
   colr.closure_V0palette_indices (glyphs_colred, &palette_indices);
   _remap_indexes (&layer_indices, layers_map);
   _remap_palette_indexes (&palette_indices, palettes_map);
-  colr.fini ();
 }
 
 static inline void
@@ -294,8 +290,7 @@
                               const hb_set_t *glyphs,
                               hb_subset_plan_t *plan)
 {
-  OT::cmap::accelerator_t cmap;
-  cmap.init (plan->source);
+  OT::cmap::accelerator_t cmap (plan->source);
 
   constexpr static const int size_threshold = 4096;
 
@@ -343,8 +338,6 @@
 
   + plan->codepoint_to_glyph->keys ()   | hb_sink (plan->unicodes);
   + plan->codepoint_to_glyph->values () | hb_sink (plan->_glyphset_gsub);
-
-  cmap.fini ();
 }
 
 static void
@@ -353,14 +346,10 @@
 			  bool close_over_gpos,
 			  bool close_over_gdef)
 {
-  OT::glyf::accelerator_t glyf;
+  OT::glyf::accelerator_t glyf (plan->source);
 #ifndef HB_NO_SUBSET_CFF
-  OT::cff1::accelerator_t cff;
+  OT::cff1::accelerator_t cff (plan->source);
 #endif
-  glyf.init (plan->source);
-#ifndef HB_NO_SUBSET_CFF
-  cff.init (plan->source);
-#endif
 
   plan->_glyphset_gsub->add (0); // Not-def
 
@@ -419,11 +408,6 @@
 				       plan->layout_variation_indices,
 				       plan->layout_variation_idx_map);
 #endif
-
-#ifndef HB_NO_SUBSET_CFF
-  cff.fini ();
-#endif
-  glyf.fini ();
 }
 
 static void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -878,7 +878,8 @@
   if (backward)
     hb_buffer_reverse (buffer);
 
-  buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+  buffer->clear_glyph_flags ();
+  buffer->unsafe_to_break ();
 
   /* Wow, done! */
   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-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -32,11 +32,14 @@
 #include "hb-null.hh"
 
 
-template <typename Type>
-struct hb_vector_t
+template <typename Type,
+	  bool sorted=false>
+struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty_t>::type
 {
   typedef Type item_t;
   static constexpr unsigned item_size = hb_static_size (Type);
+  using array_t = typename std::conditional<sorted, hb_sorted_array_t<Type>, hb_array_t<Type>>::type;
+  using c_array_t = typename std::conditional<sorted, hb_sorted_array_t<const Type>, hb_array_t<const Type>>::type;
 
   hb_vector_t () = default;
   hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t ()
@@ -82,16 +85,10 @@
 
   void fini ()
   {
+    shrink_vector (0);
     hb_free (arrayZ);
     init ();
   }
-  void fini_deep ()
-  {
-    unsigned int count = length;
-    for (unsigned int i = 0; i < count; i++)
-      arrayZ[i].fini ();
-    fini ();
-  }
 
   void reset ()
   {
@@ -152,24 +149,24 @@
   template <typename T>
   hb_vector_t& operator << (T&& v) { push (std::forward<T> (v)); return *this; }
 
-  hb_array_t<      Type> as_array ()       { return hb_array (arrayZ, length); }
-  hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); }
+  array_t   as_array ()       { return hb_array (arrayZ, length); }
+  c_array_t as_array () const { return hb_array (arrayZ, length); }
 
   /* Iterator. */
-  typedef hb_array_t<const Type>   iter_t;
-  typedef hb_array_t<      Type> writer_t;
+  typedef c_array_t   iter_t;
+  typedef array_t   writer_t;
     iter_t   iter () const { return as_array (); }
   writer_t writer ()       { return as_array (); }
   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
+  c_array_t 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
+  c_array_t 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)
+  array_t 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 */)
+  array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
   { return as_array ().sub_array (start_offset, count); }
 
   hb_sorted_array_t<Type> as_sorted_array ()
@@ -192,6 +189,7 @@
   template <typename T>
   Type *push (T&& v)
   {
+    /* TODO Emplace? */
     Type *p = push ();
     if (p == &Crap (Type))
       // If push failed to allocate then don't copy v, since this may cause
@@ -204,6 +202,92 @@
 
   bool in_error () const { return allocated < 0; }
 
+  template <typename T = Type,
+	    hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
+  Type *
+  realloc_vector (unsigned new_allocated)
+  {
+    return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
+  }
+  template <typename T = Type,
+	    hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
+  Type *
+  realloc_vector (unsigned new_allocated)
+  {
+    Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type));
+    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;
+      hb_free (arrayZ);
+    }
+    return new_array;
+  }
+
+  template <typename T = Type,
+	    hb_enable_if (std::is_trivially_constructible<T>::value ||
+			  !std::is_default_constructible<T>::value)>
+  void
+  grow_vector (unsigned size)
+  {
+    memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
+    length = size;
+  }
+  template <typename T = Type,
+	    hb_enable_if (!std::is_trivially_constructible<T>::value &&
+			   std::is_default_constructible<T>::value)>
+  void
+  grow_vector (unsigned size)
+  {
+    while (length < size)
+    {
+      length++;
+      new (std::addressof (arrayZ[length - 1])) Type ();
+    }
+  }
+
+  template <typename T = Type,
+	    hb_enable_if (std::is_trivially_destructible<T>::value)>
+  void
+  shrink_vector (unsigned size)
+  {
+    length = size;
+  }
+  template <typename T = Type,
+	    hb_enable_if (!std::is_trivially_destructible<T>::value)>
+  void
+  shrink_vector (unsigned size)
+  {
+    while ((unsigned) length > size)
+    {
+      arrayZ[(unsigned) length - 1].~Type ();
+      length--;
+    }
+  }
+
+  template <typename T = Type,
+	    hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
+  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 (!std::is_trivially_copy_assignable<T>::value)>
+  void
+  shift_down_vector (unsigned i)
+  {
+    for (; i < length; i++)
+      arrayZ[i - 1] = std::move (arrayZ[i]);
+  }
+
   /* Allocate for size but don't adjust length. */
   bool alloc (unsigned int size)
   {
@@ -225,7 +309,7 @@
       (new_allocated < (unsigned) allocated) ||
       hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
     if (likely (!overflows))
-      new_array = (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
+      new_array = realloc_vector (new_allocated);
 
     if (unlikely (!new_array))
     {
@@ -246,7 +330,9 @@
       return false;
 
     if (size > length)
-      memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
+      grow_vector (size);
+    else if (size < length)
+      shrink_vector (size);
 
     length = size;
     return true;
@@ -255,7 +341,10 @@
   Type pop ()
   {
     if (!length) return Null (Type);
-    return std::move (arrayZ[--length]); /* Does this move actually work? */
+    Type v = std::move (arrayZ[length - 1]);
+    arrayZ[length - 1].~Type ();
+    length--;
+    return v;
   }
 
   void remove (unsigned int i)
@@ -262,9 +351,8 @@
   {
     if (unlikely (i >= length))
       return;
-    memmove (static_cast<void *> (&arrayZ[i]),
-	     static_cast<void *> (&arrayZ[i + 1]),
-	     (length - i - 1) * sizeof (Type));
+    arrayZ[i].~Type ();
+    shift_down_vector (i + 1);
     length--;
   }
 
@@ -271,32 +359,20 @@
   void shrink (int size_)
   {
     unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
-     if (size < length)
-       length = size;
-  }
+    if (size >= length)
+      return;
 
-  template <typename T>
-  Type *find (T v)
-  {
-    for (unsigned int i = 0; i < length; i++)
-      if (arrayZ[i] == v)
-	return &arrayZ[i];
-    return nullptr;
+    shrink_vector (size);
   }
-  template <typename T>
-  const Type *find (T v) const
-  {
-    for (unsigned int i = 0; i < length; i++)
-      if (arrayZ[i] == v)
-	return &arrayZ[i];
-    return nullptr;
-  }
 
+
+  /* Sorting API. */
   void qsort (int (*cmp)(const void*, const void*))
   { 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>
   Type *lsearch (const T &x, Type *not_found = nullptr)
   { return as_array ().lsearch (x, not_found); }
@@ -306,43 +382,18 @@
   template <typename T>
   bool lfind (const T &x, unsigned *pos = nullptr) const
   { return as_array ().lfind (x, pos); }
-};
 
-template <typename Type>
-struct hb_sorted_vector_t : hb_vector_t<Type>
-{
-  hb_sorted_vector_t () = default;
-  ~hb_sorted_vector_t () = default;
-  hb_sorted_vector_t (hb_sorted_vector_t& o) = default;
-  hb_sorted_vector_t (hb_sorted_vector_t &&o) = default;
-  hb_sorted_vector_t (std::initializer_list<Type> lst) : hb_vector_t<Type> (lst) {}
-  template <typename Iterable,
-	    hb_requires (hb_is_iterable (Iterable))>
-  hb_sorted_vector_t (const Iterable &o) : hb_vector_t<Type> (o) {}
-  hb_sorted_vector_t& operator = (const hb_sorted_vector_t &o) = default;
-  hb_sorted_vector_t& operator = (hb_sorted_vector_t &&o) = default;
-  friend void swap (hb_sorted_vector_t& a, hb_sorted_vector_t& b)
-  { hb_swap ((hb_vector_t<Type>&) (a), (hb_vector_t<Type>&) (b)); }
-
-  hb_sorted_array_t<      Type> as_array ()       { return hb_sorted_array (this->arrayZ, this->length); }
-  hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); }
-
-  /* Iterator. */
-  typedef hb_sorted_array_t<const Type> const_iter_t;
-  typedef hb_sorted_array_t<      Type>       iter_t;
-  const_iter_t  iter () const { return as_array (); }
-  const_iter_t citer () const { return as_array (); }
-	iter_t  iter ()       { return as_array (); }
-  operator       iter_t ()       { return iter (); }
-  operator const_iter_t () const { return iter (); }
-
-  template <typename T>
+  /* Sorted search API. */
+  template <typename T,
+	    bool Sorted=sorted, hb_enable_if (Sorted)>
   Type *bsearch (const T &x, Type *not_found = nullptr)
   { return as_array ().bsearch (x, not_found); }
-  template <typename T>
+  template <typename T,
+	    bool Sorted=sorted, hb_enable_if (Sorted)>
   const Type *bsearch (const T &x, const Type *not_found = nullptr) const
   { return as_array ().bsearch (x, not_found); }
-  template <typename T>
+  template <typename T,
+	    bool Sorted=sorted, hb_enable_if (Sorted)>
   bool bfind (const T &x, unsigned int *i = nullptr,
 	      hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
 	      unsigned int to_store = (unsigned int) -1) const
@@ -349,4 +400,7 @@
   { return as_array ().bfind (x, i, not_found, to_store); }
 };
 
+template <typename Type>
+using hb_sorted_vector_t = hb_vector_t<Type, true>;
+
 #endif /* HB_VECTOR_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2022-02-13 03:14:24 UTC (rev 61999)
@@ -447,6 +447,7 @@
 #ifndef HB_USE_ATEXIT
 #  define HB_USE_ATEXIT 0
 #endif
+#ifndef hb_atexit
 #if !HB_USE_ATEXIT
 #  define hb_atexit(_) HB_STMT_START { if (0) (_) (); } HB_STMT_END
 #else /* HB_USE_ATEXIT */
@@ -457,6 +458,7 @@
 #    define hb_atexit(f) static hb_atexit_t<f> _hb_atexit_##__LINE__;
 #  endif
 #endif
+#endif
 
 /* Lets assert int types.  Saves trouble down the road. */
 static_assert ((sizeof (hb_codepoint_t) == 4), "");

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2022-02-13 03:14:24 UTC (rev 61999)
@@ -29,6 +29,7 @@
   'hb-blob.cc',
   'hb-blob.hh',
   'hb-buffer-serialize.cc',
+  'hb-buffer-verify.cc',
   'hb-buffer.cc',
   'hb-buffer.hh',
   'hb-cache.hh',
@@ -54,7 +55,6 @@
   'hb-map.cc',
   'hb-map.hh',
   'hb-meta.hh',
-  'hb-ms-feature-ranges.cc',
   'hb-ms-feature-ranges.hh',
   'hb-mutex.hh',
   'hb-null.hh',
@@ -486,13 +486,15 @@
   compiled_tests = {
     'test-algs': ['test-algs.cc', 'hb-static.cc'],
     'test-array': ['test-array.cc'],
-    'test-repacker': ['test-repacker.cc', 'hb-static.cc'],
-    'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'],
     'test-iter': ['test-iter.cc', 'hb-static.cc'],
+    'test-machinery': ['test-machinery.cc', 'hb-static.cc'],
     'test-map': ['test-map.cc', 'hb-static.cc'],
     'test-number': ['test-number.cc', 'hb-number.cc'],
     'test-ot-tag': ['hb-ot-tag.cc'],
+    'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'],
+    'test-repacker': ['test-repacker.cc', 'hb-static.cc'],
     'test-set': ['test-set.cc', 'hb-static.cc'],
+    'test-serialize': ['test-serialize.cc', 'hb-static.cc'],
     'test-unicode-ranges': ['test-unicode-ranges.cc'],
     'test-vector': ['test-vector.cc', 'hb-static.cc'],
     'test-bimap': ['test-bimap.cc', 'hb-static.cc'],

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-machinery.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-machinery.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-machinery.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -0,0 +1,46 @@
+/*
+ * 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-machinery.hh"
+
+struct hb_intp_lazy_loader_t : hb_lazy_loader_t<int, hb_intp_lazy_loader_t>
+{
+  static int* create () { return nullptr; }
+  static void destroy (int* l) {}
+  static int* get_null () { return nullptr; }
+};
+
+struct hb_void_lazy_loader_t : hb_lazy_loader_t<void, hb_void_lazy_loader_t>
+{
+  static void* create () { return nullptr; }
+  static void destroy (void* l) {}
+  static void* get_null () { return nullptr; }
+};
+
+int
+main (int argc, char **argv)
+{
+  return 0;
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -25,7 +25,9 @@
 
 #include "hb.hh"
 #include "hb-map.hh"
+#include <string>
 
+static const std::string invalid{"invalid"};
 
 int
 main (int argc, char **argv)
@@ -76,6 +78,14 @@
     assert (v.get_population () == 2);
   }
 
+  /* Test call fini() twice. */
+  {
+    hb_map_t s;
+    for (int i = 0; i < 16; i++)
+      s.set(i, i+1);
+    s.fini();
+  }
+
   /* Test initializing from iterator. */
   {
     hb_map_t s;
@@ -108,5 +118,22 @@
     assert (m3.get_population () == 0);
   }
 
+  {
+    hb_hashmap_t<int, int, int, int, 0, 0> m0;
+    hb_hashmap_t<std::string, int, const std::string*, int, &invalid, 0> m1;
+    hb_hashmap_t<int, std::string, int, const std::string*, 0, &invalid> m2;
+    hb_hashmap_t<std::string, std::string, const std::string*, const std::string*, &invalid, &invalid> m3;
+
+    std::string s;
+    for (unsigned i = 1; i < 1000; i++)
+    {
+      s += "x";
+      m0.set (i, i);
+      m1.set (s, i);
+      m2.set (i, s);
+      m3.set (s, s);
+    }
+  }
+
   return 0;
 }

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-serialize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-serialize.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-serialize.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -0,0 +1,51 @@
+/*
+ * 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-serialize.hh"
+#include "hb-ot-layout-common.hh"
+
+
+int
+main (int argc, char **argv)
+{
+  char buf[16384];
+
+  hb_serialize_context_t s (buf, sizeof (buf));
+
+  hb_sorted_vector_t<hb_codepoint_t> v{1, 2, 5};
+
+  auto c = s.start_serialize<OT::Coverage> ();
+
+  c->serialize (&s, hb_iter (v));
+
+  s.end_serialize ();
+
+  hb_bytes_t bytes = s.copy_bytes ();
+  assert (bytes.length == 10);
+  bytes.fini ();
+
+  return 0;
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-vector.cc	2022-02-13 03:14:24 UTC (rev 61999)
@@ -26,6 +26,7 @@
 #include "hb.hh"
 #include "hb-vector.hh"
 #include "hb-set.hh"
+#include <string>
 
 
 int
@@ -136,5 +137,18 @@
     assert (v2[2] == 3);
   }
 
+#if 0
+  {
+    hb_vector_t<std::string> v;
+
+    std::string s;
+    for (unsigned i = 1; i < 100; i++)
+    {
+      s += "x";
+      v.push (s);
+    }
+  }
+#endif
+
   return 0;
 }

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2022-02-13 00:49:39 UTC (rev 61998)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2022-02-13 03:14:24 UTC (rev 61999)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [3.2.0])
+m4_define([harfbuzz_version], [3.4.0])



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