texlive[51218] Build/source/libs: harfbuzz-2.5.0

commits+kakuto at tug.org commits+kakuto at tug.org
Sat May 25 01:03:55 CEST 2019


Revision: 51218
          http://tug.org/svn/texlive?view=revision&revision=51218
Author:   kakuto
Date:     2019-05-25 01:03:55 +0200 (Sat, 25 May 2019)
Log Message:
-----------
harfbuzz-2.5.0

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/harfbuzz/ChangeLog
    trunk/Build/source/libs/harfbuzz/Makefile.am
    trunk/Build/source/libs/harfbuzz/Makefile.in
    trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
    trunk/Build/source/libs/harfbuzz/config.h.in
    trunk/Build/source/libs/harfbuzz/configure
    trunk/Build/source/libs/harfbuzz/configure.ac
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/README
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/THANKS
    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/src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh
    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-use-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-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-cff1-interp-cs.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-coretext.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-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-cpal-table.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-color.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-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-kern-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh
    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.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh
    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-warning.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dispatch.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-algs.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-gpos-size-params.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-gsub-would-substitute.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-name.cc

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-name-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-size-params.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-would-substitute.cc

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/README	2019-05-24 23:03:55 UTC (rev 51218)
@@ -25,7 +25,7 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 2.4.0 - checked 03may19
+harfbuzz 2.5.0 - checked 25may19
   http://www.freedesktop.org/software/harfbuzz/release/
 
 icu 63.1 - checked 8jan19

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,3 +1,8 @@
+2019-05-25  Akira Kakuto  <kakuto at w32tex.org>
+
+	Import harfbuzz-2.5.0.
+	* version.ac, configure.ac, Makefile.am: Adjusted.
+
 2019-05-03  Akira Kakuto  <kakuto at w32tex.org>
 
 	Import harfbuzz-2.4.0.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2019-05-24 23:03:55 UTC (rev 51218)
@@ -31,6 +31,7 @@
 	-I$(top_srcdir)/$(HARFBUZZ_SRC)
 libharfbuzz_dependencies =
 libharfbuzz_a_SOURCES =  \
+	@HARFBUZZ_TREE@/src/hb-algs.hh \
 	@HARFBUZZ_TREE@/src/hb-atomic.hh \
 	@HARFBUZZ_TREE@/src/hb-blob.hh \
 	@HARFBUZZ_TREE@/src/hb-blob.cc \
@@ -44,8 +45,9 @@
 	@HARFBUZZ_TREE@/src/hb-cff1-interp-cs.hh \
 	@HARFBUZZ_TREE@/src/hb-cff2-interp-cs.hh \
 	@HARFBUZZ_TREE@/src/hb-common.cc \
+	@HARFBUZZ_TREE@/src/hb-config.hh \
 	@HARFBUZZ_TREE@/src/hb-debug.hh \
-	@HARFBUZZ_TREE@/src/hb-dsalgs.hh \
+	@HARFBUZZ_TREE@/src/hb-dispatch.hh \
 	@HARFBUZZ_TREE@/src/hb-face.hh \
 	@HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font.hh \
@@ -55,6 +57,7 @@
 	@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-mutex.hh \
 	@HARFBUZZ_TREE@/src/hb-null.hh \
 	@HARFBUZZ_TREE@/src/hb-object.hh \
@@ -77,17 +80,20 @@
 	@HARFBUZZ_TREE@/src/hb-ot-hmtx-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-kern-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-maxp-table.hh \
+	@HARFBUZZ_TREE@/src/hb-ot-name-language-static.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-stat-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-name-language.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-name-language.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-os2-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-os2-unicode-ranges.hh \
+	@HARFBUZZ_TREE@/src/hb-pool.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-post-macroman.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-post-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-tag.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-tag-table.hh \
+	@HARFBUZZ_TREE@/src/hb-sanitize.hh \
+	@HARFBUZZ_TREE@/src/hb-serialize.hh \
 	@HARFBUZZ_TREE@/src/hb-set-digest.hh \
 	@HARFBUZZ_TREE@/src/hb-set.hh \
 	@HARFBUZZ_TREE@/src/hb-set.cc \
@@ -108,6 +114,8 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.hh \
 	@HARFBUZZ_TREE@/src/hb-subset-input.hh \
 	@HARFBUZZ_TREE@/src/hb-subset.hh \
+	@HARFBUZZ_TREE@/src/hb-ucd-table.hh \
+	@HARFBUZZ_TREE@/src/hb-ucd.cc \
 	@HARFBUZZ_TREE@/src/hb-unicode.hh \
 	@HARFBUZZ_TREE@/src/hb-unicode.cc \
 	@HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2019-05-24 23:03:55 UTC (rev 51218)
@@ -130,7 +130,6 @@
 	@HARFBUZZ_TREE@/src/hb-ot-cff1-table.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-cff2-table.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-face.$(OBJEXT) \
-	@HARFBUZZ_TREE@/src/hb-ot-name-language.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-name.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-tag.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-set.$(OBJEXT) \
@@ -141,6 +140,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff-common.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-subset-cff1.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-ucd.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-unicode.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-warning.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-fallback-shape.$(OBJEXT) \
@@ -214,7 +214,6 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-layout.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-map.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-math.Po \
-	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-name-language.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-name.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-arabic.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-default.Po \
@@ -241,6 +240,7 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-warning.Po
 am__mv = mv -f
@@ -714,7 +714,8 @@
 	-I$(top_srcdir)/$(HARFBUZZ_SRC) $(ICU_INCLUDES) \
 	$(GRAPHITE2_INCLUDES)
 libharfbuzz_dependencies = $(ICU_DEPEND) $(GRAPHITE2_DEPEND)
-libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-atomic.hh \
+libharfbuzz_a_SOURCES = @HARFBUZZ_TREE@/src/hb-algs.hh \
+	@HARFBUZZ_TREE@/src/hb-atomic.hh \
 	@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 \
@@ -726,14 +727,16 @@
 	@HARFBUZZ_TREE@/src/hb-cff1-interp-cs.hh \
 	@HARFBUZZ_TREE@/src/hb-cff2-interp-cs.hh \
 	@HARFBUZZ_TREE@/src/hb-common.cc \
+	@HARFBUZZ_TREE@/src/hb-config.hh \
 	@HARFBUZZ_TREE@/src/hb-debug.hh \
-	@HARFBUZZ_TREE@/src/hb-dsalgs.hh \
+	@HARFBUZZ_TREE@/src/hb-dispatch.hh \
 	@HARFBUZZ_TREE@/src/hb-face.hh @HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font.hh @HARFBUZZ_TREE@/src/hb-font.cc \
 	@HARFBUZZ_TREE@/src/hb-iter.hh @HARFBUZZ_TREE@/src/hb-kern.hh \
 	@HARFBUZZ_TREE@/src/hb-map.hh @HARFBUZZ_TREE@/src/hb-map.cc \
 	@HARFBUZZ_TREE@/src/hb-machinery.hh \
-	@HARFBUZZ_TREE@/src/hb-mutex.hh @HARFBUZZ_TREE@/src/hb-null.hh \
+	@HARFBUZZ_TREE@/src/hb-meta.hh @HARFBUZZ_TREE@/src/hb-mutex.hh \
+	@HARFBUZZ_TREE@/src/hb-null.hh \
 	@HARFBUZZ_TREE@/src/hb-object.hh \
 	@HARFBUZZ_TREE@/src/hb-open-file.hh \
 	@HARFBUZZ_TREE@/src/hb-open-type.hh \
@@ -754,17 +757,20 @@
 	@HARFBUZZ_TREE@/src/hb-ot-hmtx-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-kern-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-maxp-table.hh \
+	@HARFBUZZ_TREE@/src/hb-ot-name-language-static.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-stat-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-name-language.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-name-language.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-os2-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-os2-unicode-ranges.hh \
+	@HARFBUZZ_TREE@/src/hb-pool.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-post-macroman.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-post-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-tag.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-tag-table.hh \
+	@HARFBUZZ_TREE@/src/hb-sanitize.hh \
+	@HARFBUZZ_TREE@/src/hb-serialize.hh \
 	@HARFBUZZ_TREE@/src/hb-set-digest.hh \
 	@HARFBUZZ_TREE@/src/hb-set.hh @HARFBUZZ_TREE@/src/hb-set.cc \
 	@HARFBUZZ_TREE@/src/hb-shape.cc \
@@ -784,6 +790,8 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.hh \
 	@HARFBUZZ_TREE@/src/hb-subset-input.hh \
 	@HARFBUZZ_TREE@/src/hb-subset.hh \
+	@HARFBUZZ_TREE@/src/hb-ucd-table.hh \
+	@HARFBUZZ_TREE@/src/hb-ucd.cc \
 	@HARFBUZZ_TREE@/src/hb-unicode.hh \
 	@HARFBUZZ_TREE@/src/hb-unicode.cc \
 	@HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \
@@ -983,9 +991,6 @@
 @HARFBUZZ_TREE@/src/hb-ot-face.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
- at HARFBUZZ_TREE@/src/hb-ot-name-language.$(OBJEXT):  \
-	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
-	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-ot-name.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1016,6 +1021,9 @@
 @HARFBUZZ_TREE@/src/hb-subset-cff2.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-ucd.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-unicode.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1139,7 +1147,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-layout.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-map.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-math.Po at am__quote@ # am--include-marker
- at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-name-language.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-name.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-arabic.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-default.Po at am__quote@ # am--include-marker
@@ -1166,6 +1173,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-warning.Po at am__quote@ # am--include-marker
 
@@ -1781,7 +1789,6 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-layout.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-map.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-math.Po
-	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-name-language.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-name.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-arabic.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-default.Po
@@ -1808,6 +1815,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-warning.Po
 	-rm -f Makefile
@@ -1879,7 +1887,6 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-layout.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-map.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-math.Po
-	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-name-language.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-name.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-arabic.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-default.Po
@@ -1906,6 +1913,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-warning.Po
 	-rm -f Makefile

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,3 +1,8 @@
+2019-05-25  Akira Kakuto  <kakuto at w32tex.org>
+
+	Imported harfbuzz-2.5.0 source tree from:
+	  http://www.freedesktop.org/software/harfbuzz/release/
+
 2019-05-03  Akira Kakuto  <kakuto at w32tex.org>
 
 	Imported harfbuzz-2.4.0 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,4 +1,4 @@
-Changes applied to the harfbuzz-2.4.0/ tree as obtained from:
+Changes applied to the harfbuzz-2.5.0/ tree as obtained from:
 	http://www.freedesktop.org/software/harfbuzz/release/
 
 Removed:
@@ -24,4 +24,3 @@
 	m4
 	test
 	util
-	src/hb-ucdn

Modified: trunk/Build/source/libs/harfbuzz/config.h.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/config.h.in	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/config.h.in	2019-05-24 23:03:55 UTC (rev 51218)
@@ -106,9 +106,6 @@
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 
-/* Use UCDN Unicode functions */
-#undef HAVE_UCDN
-
 /* Use Uniscribe backend */
 #undef HAVE_UNISCRIBE
 

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/configure	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.4.0.
+# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.5.0.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -580,8 +580,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='2.4.0'
-PACKAGE_STRING='harfbuzz (TeX Live) 2.4.0'
+PACKAGE_VERSION='2.5.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 2.5.0'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1317,7 +1317,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) 2.4.0 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 2.5.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1388,7 +1388,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.4.0:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.5.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1495,7 +1495,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 2.4.0
+harfbuzz (TeX Live) configure 2.5.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2131,7 +2131,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 2.4.0, which was
+It was created by harfbuzz (TeX Live) $as_me 2.5.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4055,7 +4055,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='2.4.0'
+ VERSION='2.5.0'
 
 
 # Some tools Automake needs.
@@ -4248,9 +4248,9 @@
 
 
 HB_VERSION_MAJOR=2
-HB_VERSION_MINOR=4
+HB_VERSION_MINOR=5
 HB_VERSION_MICRO=0
-HB_VERSION=2.4.0
+HB_VERSION=2.5.0
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -7567,9 +7567,6 @@
 $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
 
 
-$as_echo "#define HAVE_UCDN 1" >>confdefs.h
-
-
 $as_echo "#define HAVE_GLIB 1" >>confdefs.h
 
 
@@ -8155,7 +8152,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 2.4.0, which was
+This file was extended by harfbuzz (TeX Live) $as_me 2.5.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8221,7 +8218,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 2.4.0
+harfbuzz (TeX Live) config.status 2.5.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure.ac	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/configure.ac	2019-05-24 23:03:55 UTC (rev 51218)
@@ -90,7 +90,6 @@
 else
 dnl add all these to config.h.in but do not define them in config.h
   AC_DEFINE([HAVE_PTHREAD], 1, [Use POSIX threads])
-  AC_DEFINE([HAVE_UCDN], 1, [Use UCDN Unicode functions])
   AC_DEFINE([HAVE_GLIB], 1, [Use glib2 library])
   AC_DEFINE([HAVE_GTHREAD], 1, [Use gthread2 library])
   AC_DEFINE([HAVE_GOBJECT], 1, [Use gobject2 library])

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,11 +1,14 @@
 Behdad Esfahbod
+David Corbett
 David Turner
 Ebrahim Byagowi
+Garret Rieger
 Jonathan Kew
 Khaled Hosny
 Lars Knoll
 Martin Hosken
 Owen Taylor
+Roderick Sheeter
 Roozbeh Pournader
 Simon Hausmann
 Werner Lemberg

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2019-05-24 23:03:55 UTC (rev 51218)
@@ -35,7 +35,6 @@
 ## HarfBuzz build configurations
 option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF)
 option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
-option(HB_BUILTIN_UCDN "Use HarfBuzz provided UCDN" ON)
 option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
 option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
 if (APPLE)
@@ -70,7 +69,6 @@
 if (HB_CHECK)
   set (BUILD_SHARED_LIBS ON)
   set (HB_BUILD_UTILS ON)
-  set (HB_BUILTIN_UCDN ON)
   set (HB_HAVE_ICU)
   set (HB_HAVE_GLIB ON)
   #set (HB_HAVE_GOBJECT ON)
@@ -160,7 +158,6 @@
 
 file(READ ${PROJECT_SOURCE_DIR}/src/Makefile.sources SRCSOURCES)
 file(READ ${PROJECT_SOURCE_DIR}/util/Makefile.sources UTILSOURCES)
-file(READ ${PROJECT_SOURCE_DIR}/src/hb-ucdn/Makefile.sources UCDNSOURCES)
 
 extract_make_variable(HB_BASE_sources ${SRCSOURCES})
 add_prefix_to_list(HB_BASE_sources "${PROJECT_SOURCE_DIR}/src/")
@@ -191,10 +188,7 @@
 extract_make_variable(HB_OT_SHAPE_CLOSURE_sources ${UTILSOURCES})
 add_prefix_to_list(HB_OT_SHAPE_CLOSURE_sources "${PROJECT_SOURCE_DIR}/util/")
 
-extract_make_variable(LIBHB_UCDN_sources ${UCDNSOURCES})
-add_prefix_to_list(LIBHB_UCDN_sources "${PROJECT_SOURCE_DIR}/src/hb-ucdn/")
 
-
 file(READ configure.ac CONFIGUREAC)
 string(REGEX MATCH "\\[(([0-9]+)\\.([0-9]+)\\.([0-9]+))\\]" HB_VERSION_MATCH ${CONFIGUREAC})
 set (HB_VERSION ${CMAKE_MATCH_1})
@@ -295,14 +289,6 @@
   mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
 endif ()
 
-if (HB_BUILTIN_UCDN)
-  include_directories(src/hb-ucdn)
-  add_definitions(-DHAVE_UCDN)
-
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ucdn.cc)
-  list(APPEND project_extra_sources ${LIBHB_UCDN_sources})
-endif ()
-
 if (HB_HAVE_GLIB)
   add_definitions(-DHAVE_GLIB)
 
@@ -844,7 +830,7 @@
 
 if (HB_BUILD_TESTS)
   ## src/ executables
-  foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
+  foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
     set (prog_name ${prog})
     if (${prog_name} STREQUAL "test")
       # test can not be used as a valid executable name on cmake, lets special case it

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,3 +1,7067 @@
+commit 5fd3ece5237ac6a4ee95b2665b5e20102ed176bb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 24 15:56:15 2019 -0400
+
+    2.5.0
+
+ Makefile.am      |  2 +-
+ NEWS             | 14 ++++++++++++++
+ configure.ac     |  2 +-
+ src/hb-version.h |  4 ++--
+ 4 files changed, 18 insertions(+), 4 deletions(-)
+
+commit 1da089179b9bd06f071f967d128819e85998b809
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 24 15:41:34 2019 -0400
+
+    Put back Since: tags for hb_color_get_*
+
+ src/hb-common.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit e1a5ce6aa661251e998df7b3612a1d5d39e28827
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri May 24 10:58:52 2019 -0700
+
+    Fix fuzzer crash testcase
+    
+    Add a check for stringOffSet(uint16) overflow,
+    return early if overflow happens
+
+ src/hb-ot-name-table.hh                                |   2 +-
+ ...estcase-minimized-hb-subset-fuzzer-5077547978588160 | Bin 0 -> 339602 bytes
+ ...estcase-minimized-hb-subset-fuzzer-5761434614497280 | Bin 0 -> 532 bytes
+ 3 files changed, 1 insertion(+), 1 deletion(-)
+
+commit d100ccad02b038719472b2cc733940ffb0374cd1
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Sun May 19 10:01:20 2019 -0400
+
+    [use] Allow multiple FMs in a cluster
+
+ src/gen-use-table.py                   |  12 +-
+ src/hb-ot-shape-complex-use-machine.hh | 567 ++++++++++++++++-----------------
+ src/hb-ot-shape-complex-use-machine.rl |  14 +-
+ src/hb-ot-shape-complex-use-table.cc   |  38 ++-
+ src/hb-ot-shape-complex-use.hh         |  11 +-
+ 5 files changed, 315 insertions(+), 327 deletions(-)
+
+commit 487879e013758aef2c7f824033a40cd56361d240
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 24 12:37:53 2019 -0400
+
+    Don't compile in UCD if HB_NO_UCD defined
+
+ src/hb-ucd.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 1fffe51a295b6106a442bed8107d305c325bef05
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 24 10:52:09 2019 -0400
+
+    [blob] Shuffle
+
+ src/hb-blob.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 96de94768b08287325be8947255917502368c337
+Merge: c96c6b28 1197bef2
+Author: rsheeter <rsheeter at google.com>
+Date:   Fri May 24 11:22:41 2019 -0700
+
+    Merge pull request #1722 from googlefonts/glyf
+    
+    [subset] Use iterators in glyf/loca subsetting
+
+commit 1197bef26c63ee896bea3fab5788635cb0fc9d18
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Fri May 24 10:52:49 2019 -0700
+
+    [subset] Per code review, use hb_array to avoid duplicated type name
+
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e66253283385aa67eb9c5ab627139a56f9ae5a71
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Fri May 24 10:39:56 2019 -0700
+
+    [subset] Cppcheck complaints
+
+ test/api/hb-test.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 13b3cd307e7dedea3b419fb06d81a008e49ccff6
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Fri May 24 10:10:12 2019 -0700
+
+    [subset] Address @behdad review feedback
+
+ src/hb-ot-glyf-table.hh | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+commit c96c6b287ff1d96da6a50a8cb3f641fe8705e5f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 23 21:37:17 2019 -0400
+
+    One more
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b567d4ea14cc6ec0e8efc64a4993a9b0461adb20
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 23 21:36:42 2019 -0400
+
+    Fix build after UCDN -> UCD
+
+ CMakeLists.txt                       | 14 --------------
+ configure.ac                         | 18 +-----------------
+ docs/usermanual-install-harfbuzz.xml | 34 ++++++++--------------------------
+ 3 files changed, 9 insertions(+), 57 deletions(-)
+
+commit 226ab06ec110f4cbd56b39ce0d05d349dfec35b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 23 20:39:04 2019 -0400
+
+    [ucd] Add URL to dependencies
+
+ src/gen-ucd-table.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 65392b734e38668b870b1ffcbfb4b42ec289ef58
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 22 16:21:21 2019 -0400
+
+    [ucdn] Replace UCDN with a new UCD implementation
+    
+    UCDN was ~120kb of data.  New implementatoin is 69kb in default builds,
+    and 49kb if built with HB_OPTIMIZE_SIZE or __OPTIMIZE_SIZE__.  The
+    latter automatically enabled if built with -Os or -Oz.
+    
+    There's room to shave off another 10kb or 20kb.  That will follow later.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/Makefile.am              |   11 -
+ src/Makefile.sources         |    5 +-
+ src/gen-ucd-table.py         |   11 +-
+ src/hb-algs.hh               |    8 +
+ src/hb-ot-layout.cc          |   76 +-
+ src/hb-ucd-table.hh          | 5160 +++++++++++++++++++++++++++++++++++++
+ src/hb-ucd.cc                |  209 ++
+ src/hb-ucdn.cc               |  272 --
+ src/hb-ucdn/COPYING          |   13 -
+ src/hb-ucdn/Makefile.am      |   16 -
+ src/hb-ucdn/Makefile.sources |    7 -
+ src/hb-ucdn/README           |   40 -
+ src/hb-ucdn/ucdn.c           |  361 ---
+ src/hb-ucdn/ucdn.h           |  472 ----
+ src/hb-ucdn/ucdn_db.h        | 5790 ------------------------------------------
+ src/hb-unicode.cc            |    8 +-
+ 16 files changed, 5427 insertions(+), 7032 deletions(-)
+
+commit 12c59f6c40401c8221facc5d0aed63f510a77dd7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 23 13:33:21 2019 -0400
+
+    [deprecated] Minor
+
+ src/hb-deprecated.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 36dee9221f8de3a2a6a23f0548460aab4982b594
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 22 15:51:53 2019 -0400
+
+    [gen-ucd] Rename
+
+ src/Makefile.am                      | 1 +
+ src/{gen-ucd.py => gen-ucd-table.py} | 0
+ 2 files changed, 1 insertion(+)
+
+commit 831c213501fc38229755be7958b2952fe0cdff0e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 22 15:46:19 2019 -0400
+
+    [gen-ucd] Minor
+
+ src/gen-ucd.py | 30 +++++++++++++++++++++++++++---
+ 1 file changed, 27 insertions(+), 3 deletions(-)
+
+commit 15a9e32b566fbf6f4a2c6fd488d8cc3865234b17
+Merge: 993d81b9 ff7fc6d4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu May 23 11:02:15 2019 +0430
+
+    Merge pull request #1723 from googlefonts/drop_tables
+    
+    [subset] Add morx, mort, kern, and kernx to the default layout tables…
+
+commit ff7fc6d488f37e3faaca4986cde35836f013b03f
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed May 22 17:36:16 2019 -0700
+
+    [subset] Add morx, mort, kern, and kernx to the default layout tables drop list.
+
+ src/hb-subset-input.cc | 4 ++++
+ src/hb-subset.cc       | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+commit 993d81b9c57f2e27d80d276953b0430821129425
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue May 14 13:55:11 2019 -0700
+
+    [subset] Add one ttf file with fvar/STAT tables to integration test
+    Ignore gvar/MVAR/HVAR table
+    add support for --nameIDs=* option
+
+ src/hb-ot-cmap-table.hh                            |  27 +++++++++++++++++----
+ src/hb-ot-stat-table.hh                            |   2 +-
+ src/hb-subset-input.cc                             |   1 +
+ src/hb-subset-plan.cc                              |   6 +----
+ test/api/hb-subset-test.h                          |   2 +-
+ .../Comfortaa-Regular-new.default.61,62,63.ttf     | Bin 0 -> 6492 bytes
+ .../basics/Comfortaa-Regular-new.default.61,63.ttf | Bin 0 -> 6316 bytes
+ .../basics/Comfortaa-Regular-new.default.61.ttf    | Bin 0 -> 6148 bytes
+ .../basics/Comfortaa-Regular-new.default.62.ttf    | Bin 0 -> 6088 bytes
+ .../basics/Comfortaa-Regular-new.default.63.ttf    | Bin 0 -> 6068 bytes
+ ...Regular-new.drop-hints-retain-gids.61,62,63.ttf | Bin 0 -> 3284 bytes
+ ...aa-Regular-new.drop-hints-retain-gids.61,63.ttf | Bin 0 -> 3164 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.61.ttf | Bin 0 -> 2868 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.62.ttf | Bin 0 -> 3020 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.63.ttf | Bin 0 -> 3024 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,62,63.ttf  | Bin 0 -> 1952 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,63.ttf     | Bin 0 -> 1832 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.61.ttf | Bin 0 -> 1704 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.62.ttf | Bin 0 -> 1688 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.63.ttf | Bin 0 -> 1688 bytes
+ .../Comfortaa-Regular-new.name-ids.61,62,63.ttf    | Bin 0 -> 6236 bytes
+ .../Comfortaa-Regular-new.name-ids.61,63.ttf       | Bin 0 -> 6060 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.61.ttf   | Bin 0 -> 5892 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.62.ttf   | Bin 0 -> 5832 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.63.ttf   | Bin 0 -> 5812 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,62,63.ttf | Bin 0 -> 7824 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,63.ttf    | Bin 0 -> 7648 bytes
+ .../Comfortaa-Regular-new.retain-gids.61.ttf       | Bin 0 -> 7312 bytes
+ .../Comfortaa-Regular-new.retain-gids.62.ttf       | Bin 0 -> 7420 bytes
+ .../Comfortaa-Regular-new.retain-gids.63.ttf       | Bin 0 -> 7404 bytes
+ ...eSansPro-Regular.default.1FC,21,41,20,62,63.otf | Bin 3784 -> 2384 bytes
+ .../SourceSansPro-Regular.default.61,62,63.otf     | Bin 3496 -> 2096 bytes
+ ...ourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf | Bin 3612 -> 2212 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 33516 -> 32124 bytes
+ ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin 31080 -> 29688 bytes
+ ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 34708 -> 33316 bytes
+ ...o-Regular.desubroutinize.1FC,21,41,20,62,63.otf | Bin 3640 -> 2240 bytes
+ ...urceSansPro-Regular.desubroutinize.61,62,63.otf | Bin 3400 -> 2000 bytes
+ ...nsPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf | Bin 3596 -> 2196 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 33352 -> 31960 bytes
+ ...p-hints-desubroutinize-retain-gids.61,62,63.otf | Bin 30956 -> 29564 bytes
+ ...s-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 34560 -> 33168 bytes
+ ...rop-hints-desubroutinize.1FC,21,41,20,62,63.otf | Bin 3480 -> 2080 bytes
+ ...-Regular.drop-hints-desubroutinize.61,62,63.otf | Bin 3288 -> 1876 bytes
+ ...ar.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf | Bin 3448 -> 2048 bytes
+ ...r.drop-hints-retain-gids.1FC,21,41,20,62,63.otf | Bin 33448 -> 32052 bytes
+ ...Pro-Regular.drop-hints-retain-gids.61,62,63.otf | Bin 31028 -> 29632 bytes
+ ...gular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf | Bin 34576 -> 33180 bytes
+ ...nsPro-Regular.drop-hints.1FC,21,41,20,62,63.otf | Bin 3564 -> 2164 bytes
+ .../SourceSansPro-Regular.drop-hints.61,62,63.otf  | Bin 3340 -> 1940 bytes
+ ...ceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf | Bin 3464 -> 2064 bytes
+ ...sPro-Regular.retain-gids.1FC,21,41,20,62,63.otf | Bin 33668 -> 32276 bytes
+ .../SourceSansPro-Regular.retain-gids.61,62,63.otf | Bin 31180 -> 29788 bytes
+ ...eSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf | Bin 34724 -> 33332 bytes
+ .../Roboto-Regular.default.1FC,21,41,20,62,63.ttf  | Bin 3772 -> 3164 bytes
+ .../full-font/Roboto-Regular.default.61,62,63.ttf  | Bin 3368 -> 2760 bytes
+ .../Roboto-Regular.default.D7,D8,D9,DA,DE.ttf      | Bin 3732 -> 3124 bytes
+ ...oboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf | Bin 2224 -> 1616 bytes
+ .../Roboto-Regular.drop-hints.61,62,63.ttf         | Bin 2016 -> 1408 bytes
+ .../Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf   | Bin 2252 -> 1644 bytes
+ ...gular.default.3042,3044,3046,3048,304A,304B.ttf | Bin 3112 -> 2684 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 3356 -> 2928 bytes
+ .../Mplus1p-Regular.default.61,63,65,6B.ttf        | Bin 2656 -> 2228 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3652 -> 3224 bytes
+ .../japanese/Mplus1p-Regular.default.660E.ttf      | Bin 2396 -> 1968 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 2384 -> 1956 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2628 -> 2200 bytes
+ .../Mplus1p-Regular.drop-hints.61,63,65,6B.ttf     | Bin 1928 -> 1500 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 2924 -> 2496 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.660E.ttf   | Bin 1668 -> 1240 bytes
+ test/subset/data/fonts/Comfortaa-Regular-new.ttf   | Bin 0 -> 230316 bytes
+ test/subset/data/tests/basics.tests                |   1 +
+ test/subset/generate-expected-outputs.py           |   3 +--
+ test/subset/run-tests.py                           |   3 ++-
+ util/options-subset.cc                             |  23 +++++++++++++++---
+ 75 files changed, 50 insertions(+), 18 deletions(-)
+
+commit 58ce477ac170969430310750b78dcb5f9e3b06a3
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Tue May 21 20:22:40 2019 -0700
+
+    [subset] Report failure more often
+
+ src/hb-ot-glyf-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 51a0129f7322e97825455df4eb6eecfea14980f5
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Tue May 21 20:12:19 2019 -0700
+
+    [subset] Thar be comparison of integers of different signs
+
+ test/api/hb-test.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 14e3b0cf41d9657c39f1f921f7e09a1418fa3278
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Tue May 21 20:09:36 2019 -0700
+
+    [subset] Code review feedback
+
+ src/hb-ot-glyf-table.hh | 53 +++++++++++++++++++++++++------------------------
+ 1 file changed, 27 insertions(+), 26 deletions(-)
+
+commit a03ed95e7d50b9dd947e8982c7730de969795b05
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 21 16:43:14 2019 -0400
+
+    [gen-ucd] Generate decomposition tables
+    
+    Code is ugly.  Ugh.
+
+ src/gen-ucd.py | 40 ++++++++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+commit 8a48c88fa9fe047a83ba4a45dbd6399412ca3302
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 21 13:02:54 2019 -0400
+
+    [gen-ucd] Comment
+
+ src/gen-ucd.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit b71d353cee89a6654810f75e7a1d7fd156b76faa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 17:33:55 2019 -0400
+
+    [gen-ucd] Remove some code
+
+ src/gen-ucd.py | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit 4ea44112b5163591ce0b086e0d13ec368f4f6ddc
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Tue May 21 13:07:43 2019 -0700
+
+    [subset] Remove missed reference to hb-subset-glyf, was deleted
+
+ src/Makefile.sources | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit b928de91a755788fd0fad9fa0f5f03c5670ac6a3
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue May 21 11:23:26 2019 -0700
+
+    [subset] Add test/subset/data/expected/layout to dist list.
+
+ test/subset/data/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 0af9de13b78ddd35f58ee02ce8ffeffd99509ec5
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon May 20 15:04:20 2019 -0700
+
+    [subset] For gsub subsetting only consider glyphs reachable via gsub closure.
+
+ src/hb-ot-layout-gsub-table.hh |  4 +--
+ src/hb-subset-plan.cc          | 55 ++++++++++++++++++++----------------------
+ src/hb-subset-plan.hh          | 10 ++++++++
+ 3 files changed, 38 insertions(+), 31 deletions(-)
+
+commit c740c8636b48b1790bba42445a301e8e1cf8f749
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu May 16 10:57:33 2019 -0700
+
+    [subset] Add integration tests for SingleSubst.
+
+ test/subset/data/Makefile.sources                      |   1 +
+ ...ular.smallcaps.keep-layout-retain-gids.41,42,43.ttf | Bin 0 -> 6780 bytes
+ ...Regular.smallcaps.keep-layout-retain-gids.41,43.ttf | Bin 0 -> 6396 bytes
+ ...to-Regular.smallcaps.keep-layout-retain-gids.41.ttf | Bin 0 -> 6032 bytes
+ ...to-Regular.smallcaps.keep-layout-retain-gids.43.ttf | Bin 0 -> 6088 bytes
+ ...Regular.smallcaps.keep-layout-retain-gids.CA,CB.ttf | Bin 0 -> 7932 bytes
+ .../Roboto-Regular.smallcaps.keep-layout.41,42,43.ttf  | Bin 0 -> 2972 bytes
+ .../Roboto-Regular.smallcaps.keep-layout.41,43.ttf     | Bin 0 -> 2572 bytes
+ .../layout/Roboto-Regular.smallcaps.keep-layout.41.ttf | Bin 0 -> 2196 bytes
+ .../layout/Roboto-Regular.smallcaps.keep-layout.43.ttf | Bin 0 -> 2268 bytes
+ .../Roboto-Regular.smallcaps.keep-layout.CA,CB.ttf     | Bin 0 -> 2612 bytes
+ test/subset/data/fonts/Roboto-Regular.smallcaps.ttf    | Bin 0 -> 131632 bytes
+ test/subset/data/profiles/keep-layout-retain-gids.txt  |   2 ++
+ test/subset/data/profiles/keep-layout.txt              |   1 +
+ test/subset/data/tests/full-font.tests                 |   1 -
+ test/subset/data/tests/layout.tests                    |  13 +++++++++++++
+ test/subset/generate-expected-outputs.py               |   3 ++-
+ 17 files changed, 19 insertions(+), 2 deletions(-)
+
+commit 349d692b0ee45330220fd3ec9267979d73acd149
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Tue May 21 12:38:53 2019 -0700
+
+    [subset] Iter in and out for loca
+
+ src/hb-ot-glyf-table.hh | 31 ++++++++++++++++---------------
+ test/api/hb-test.h      |  7 ++-----
+ 2 files changed, 18 insertions(+), 20 deletions(-)
+
+commit 95445d79be0a79e6e2d384d46819730146d397d8
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Tue May 21 11:14:31 2019 -0700
+
+    [subset] Write loca using more idiomatic harfbuzzese
+
+ src/hb-ot-glyf-table.hh | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+commit d1b12a546561a78ae3c3e9d6bffa057caf82dbee
+Merge: 3a43603e f49a5bec
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Mon May 20 21:29:54 2019 -0700
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf
+
+commit 3a43603ecea2c349f58396e103a52948776681e0
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Mon May 20 20:40:55 2019 -0700
+
+    [subset] Fix memory leak caused by failure to cleanup glyf accelerator
+
+ src/hb-ot-glyf-table.hh | 42 ++++++++++++++++++++++++++----------------
+ 1 file changed, 26 insertions(+), 16 deletions(-)
+
+commit 5cedda5e4a3f726168b87d357aee723e6fd919cd
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Thu May 16 19:16:52 2019 -0700
+
+    [subset] Fix null pointer deref, tidy up a bit
+
+ src/hb-ot-glyf-table.hh     | 282 +++++++++++++++++++++++++-------------------
+ test/api/test-subset-glyf.c |  18 +--
+ 2 files changed, 167 insertions(+), 133 deletions(-)
+
+commit 8a84b540c7b850c1fb30d5bc1ffdeb43033be173
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Thu May 16 19:14:16 2019 -0700
+
+    [subset] Tests passing using iterator based glyf
+
+ src/hb-ot-glyf-table.hh     | 117 +++++++++++++++++++++++++++++++-------------
+ test/api/test-subset-glyf.c |   4 +-
+ 2 files changed, 86 insertions(+), 35 deletions(-)
+
+commit 82bbec306376d61b6700461c4038c6789e60a998
+Merge: 9d09ac13 b7be5931
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Thu May 16 15:14:01 2019 -0700
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf
+
+commit 9d09ac13a114967576284d0b006a0ac7965d928a
+Author: rsheeter <rsheeter at google.com>
+Date:   Sat May 11 23:16:40 2019 -0700
+
+    [subset] Tweak hint stripping
+
+ src/hb-ot-glyf-table.hh | 46 +++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 33 insertions(+), 13 deletions(-)
+
+commit 3a4c928fcfce5a8c7a56907b9945e87b0ce8e327
+Author: rsheeter <rsheeter at google.com>
+Date:   Sat May 11 22:06:46 2019 -0700
+
+    [subset] Fix glyf tests except hint stripping & local test asan
+
+ src/hb-ot-glyf-table.hh     | 93 +++++++++++++++++++++++++++++++++------------
+ test/api/hb-subset-test.h   |  2 +-
+ test/api/hb-test.h          | 13 +++++++
+ test/api/test-subset-glyf.c |  8 ++--
+ 4 files changed, 86 insertions(+), 30 deletions(-)
+
+commit b77dde8f138442935e5ca99460a520a4117d6dd2
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Fri May 10 16:52:19 2019 -0700
+
+    [subset] Destroy blob
+
+ src/hb-ot-glyf-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 14db6512f8dca80a575f468708949346b005834a
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Fri May 10 09:32:43 2019 -0700
+
+    [subset] Correct flipped use short computation
+
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ab3fe5de2bbe10fdc13711537f824b62d091f995
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Thu May 9 22:12:20 2019 -0700
+
+    [subset] Glyf by iter now runs but fails tests
+
+ src/hb-ot-glyf-table.hh | 88 +++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 59 insertions(+), 29 deletions(-)
+
+commit f8de063b48c243d551c8892bdd2a799606fda3f4
+Merge: 0d7fef2d 8f174870
+Author: Rod Sheeter <rsheeter at google.com>
+Date:   Thu May 9 20:02:38 2019 -0700
+
+    Merge branch 'glyf' of github.com:googlefonts/harfbuzz into glyf
+
+commit 0d7fef2d50bba714815c0c13f3b3dd6464710a1d
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 16:52:00 2019 -0700
+
+    [subset] Dinner time, checkpoint
+
+ src/hb-ot-glyf-table.hh | 97 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 58 insertions(+), 39 deletions(-)
+
+commit 240bc86e3a0b177ee84ec9c60723304a0cf4c405
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 14:59:03 2019 -0700
+
+    [subset] Remove subset-glyf; want everything to point to new iter-based edition. Some of the code will resurface as impl builds out.
+
+ src/Makefile.sources    |   2 -
+ src/hb-ot-glyf-table.hh |   9 +-
+ src/hb-subset-glyf.cc   | 346 ------------------------------------------------
+ src/hb-subset-glyf.hh   |  40 ------
+ src/hb-subset.cc        |   1 -
+ 5 files changed, 6 insertions(+), 392 deletions(-)
+
+commit 02d4d4f3e67dcc37915bc386d506bb272455ff1e
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 14:43:18 2019 -0700
+
+    [subset] Starting to sketch glyf as iter
+
+ src/hb-ot-glyf-table.hh | 60 ++++++++++++++++++++++++++++++++++++-------------
+ src/hb-subset-plan.hh   |  2 ++
+ src/hb-subset.cc        |  2 +-
+ 3 files changed, 47 insertions(+), 17 deletions(-)
+
+commit 8f174870e9eed4c47463fdb0d4fe3e22a6f5fdc8
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 16:52:00 2019 -0700
+
+    [subset] Dinner time, checkpoint
+
+ src/hb-ot-glyf-table.hh | 97 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 58 insertions(+), 39 deletions(-)
+
+commit 723d054dcb6ad44e9eab4dc8cc55f8d480d2ff16
+Merge: ed727d4b e2a51ff7
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 16:45:35 2019 -0700
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf
+
+commit ed727d4bb74860c126675e94f87f65ff7874dbb6
+Merge: fb9bff95 e8b45c19
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 16:39:45 2019 -0700
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf
+
+commit fb9bff955a9356b053c5c9bcd7aa9101edb55767
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 14:59:03 2019 -0700
+
+    [subset] Remove subset-glyf; want everything to point to new iter-based edition. Some of the code will resurface as impl builds out.
+
+ src/Makefile.sources    |   2 -
+ src/hb-ot-glyf-table.hh |   9 +-
+ src/hb-subset-glyf.cc   | 346 ------------------------------------------------
+ src/hb-subset-glyf.hh   |  40 ------
+ src/hb-subset.cc        |   1 -
+ 5 files changed, 6 insertions(+), 392 deletions(-)
+
+commit f9b089b695edc89023e3d62700ae68d5648f8494
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 14:43:18 2019 -0700
+
+    [subset] Starting to sketch glyf as iter
+
+ src/hb-ot-glyf-table.hh | 60 ++++++++++++++++++++++++++++++++++++-------------
+ src/hb-subset-plan.hh   |  2 ++
+ src/hb-subset.cc        |  2 +-
+ 3 files changed, 47 insertions(+), 17 deletions(-)
+
+commit f49a5bec9fc241c098be5a49233aa83cd5dc098e
+Author: rsheeter <rsheeter at google.com>
+Date:   Mon May 20 20:45:11 2019 -0700
+
+    [docs] Tweak fuzzer doc
+
+ TESTING.md | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 1aadd1449c65c50d5f35191f43136841c64ad399
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 17:29:13 2019 -0400
+
+    [gen-ucd] Generate script order table
+
+ src/gen-ucd.py | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit be8de188671c04ddd8ec4d7af38b313322189136
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 17:17:38 2019 -0400
+
+    [gen-ucd] Start adding script-order
+
+ src/gen-ucd.py | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+commit 4a0eb066fdceb0cab48107f17670d6943ec0d61e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 16:57:04 2019 -0400
+
+    [gen-ucd] Add gc order
+
+ src/gen-ucd.py | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit d1f9b2f961c71e5218ee359e8fb20cfbdb894c7e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 15:47:49 2019 -0400
+
+    [gen-ucd] Flesh out a bit more
+
+ src/gen-ucd.py | 52 ++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 40 insertions(+), 12 deletions(-)
+
+commit d6de4659aa7edb991507f8838dc566874e5b6a61
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 15:33:23 2019 -0400
+
+    Add HB_OPTIMIZE_SIZE
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit 0ff3618c2d841d16cce9ba2d73321048e7ca6a2d
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri May 17 15:30:01 2019 -0700
+
+    [subset] Use hb_subset_input_t inside of subset_options_t so that input defaults are shared between the library and cli.
+
+ src/hb-subset-input.cc           |  42 ++++++++-----
+ src/hb-subset-input.hh           |   7 +--
+ src/hb-subset-plan.cc            |   3 +-
+ src/hb-subset-plan.hh            |   1 -
+ src/hb-subset.cc                 |  23 +------
+ src/hb-subset.h                  |   6 --
+ test/api/test-subset-glyf.c      |   8 ++-
+ test/fuzzing/hb-subset-fuzzer.cc |   8 ++-
+ util/Makefile.am                 |   5 +-
+ util/Makefile.sources            |   1 +
+ util/hb-subset.cc                |   9 +--
+ util/options-subset.cc           | 127 +++++++++++++++++++++++++++++++++++++++
+ util/options.cc                  | 101 -------------------------------
+ util/options.hh                  |  20 ++----
+ 14 files changed, 182 insertions(+), 179 deletions(-)
+
+commit 67064294a0c521550f5277b51b8c7e5d6bb27e68
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu May 16 15:13:39 2019 -0700
+
+    [subset] Add drop-tables option to hb-subset util.
+
+ util/hb-subset.cc |  1 +
+ util/options.cc   | 45 ++++++++++++++++++++++++++++++++++++++++++---
+ util/options.hh   |  3 +++
+ 3 files changed, 46 insertions(+), 3 deletions(-)
+
+commit 3be0ffe45d1ba32ddd8d3af25ff2c420be85da76
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu May 16 11:29:15 2019 -0700
+
+    [subset] Add drop tables to subset input.
+
+ src/hb-subset-input.cc             |  8 +++++
+ src/hb-subset-input.hh             |  1 +
+ src/hb-subset-plan.cc              |  3 ++
+ src/hb-subset-plan.hh              |  5 ++-
+ src/hb-subset.cc                   |  3 ++
+ src/hb-subset.h                    |  3 ++
+ test/api/Makefile.am               |  2 ++
+ test/api/test-subset-drop-tables.c | 71 ++++++++++++++++++++++++++++++++++++++
+ 8 files changed, 95 insertions(+), 1 deletion(-)
+
+commit 0ca7ad4352eff357cbb5cc1dfe62aa15b440de84
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 11:39:07 2019 -0400
+
+    [cff] Fix unlikely invocations
+
+ src/hb-ot-cff-common.hh | 8 ++++----
+ src/hb-ot-cff1-table.hh | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 9ef241cd409b7ad4eeb8259cbf1a7a01358a766e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 11:38:02 2019 -0400
+
+    [test] Add one more
+
+ ...-testcase-minimized-hb-subset-fuzzer-5634197349203968 | Bin 0 -> 5791 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 3efb7af7e28061f8cd138eb2ed5261bf521abc63
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 20 11:37:16 2019 -0400
+
+    [STAT] Fix sanitize condition
+    
+    Oops!
+    
+    Fixes https://oss-fuzz.com/testcase-detail/5696825891225600
+
+ src/hb-ot-stat-table.hh                                    |   2 +-
+ ...zz-testcase-minimized-hb-subset-fuzzer-5696825891225600 | Bin 0 -> 69 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit e66eb21a46b2374bfb51f86ed9f5eec35ba87a61
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat May 18 07:44:48 2019 -0700
+
+    Don't set _POSIX_C_SOURCE in NetBSD
+    
+    According to a harfbuzz package patch on NetBSD project
+    https://github.com/NetBSD/pkgsrc/blob/trunk/fonts/harfbuzz/patches/patch-src_hb-blob.cc
+
+ src/hb-blob.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 08c3648c6e18a0969a64284337dbd5b435d40f37
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 17 16:21:34 2019 -0700
+
+    Oops, fix include
+
+ src/hb-set.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 24958b8868a8003936e872d8fda873c52d528bcf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 17 16:20:36 2019 -0700
+
+    [set] Use StructAtOffsetUnaligned
+
+ src/hb-set.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a0febbac439ac4cc58af674f676e473d2f6d726f
+Author: rsheeter <rsheeter at google.com>
+Date:   Thu May 16 15:58:49 2019 -0700
+
+    Update TESTING.md
+
+ TESTING.md | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit b7be59311f27112791e9b9c6356464e1c3ff92c1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 16 13:32:56 2019 -0700
+
+    Fix msan issue
+    
+    The fact that HB_AUTO_RETURN will return rvalue-references for rvalues
+    is very disturbing.
+    
+    Even apart from that, I'm totally lost re any hb_move needs or
+    hb_forward'ing to functions/templates where the type is fixed by
+    explicitly specifying template parameters.
+    
+    ==1==ERROR: AddressSanitizer: stack-use-after-return on address 0x7f6ad65e51e0 at pc 0x0000005da240 bp 0x7ffc104ab670 sp 0x7ffc104ab668
+    READ of size 4 at 0x7f6ad65e51e0 thread T0
+    SCARINESS: 55 (4-byte-read-stack-use-after-return)
+         #0 0x5da23f in bool OT::Coverage::serialize<hb_map_iter_t<hb_map_iter_t<hb_filter_iter_t<OT::Coverage::iter_t, hb_set_t const&, $_7&, (void*)0>, OT::SingleSubstFormat1::subset(hb_subset_context_t*) const::'lambda'(unsigned int), (hb_function_sortedness_t)1, (void*)0>, $_20&, (hb_function_sortedness_t)1, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_map_iter_t<hb_map_iter_t<hb_filter_iter_t<OT::Coverage::iter_t, hb_set_t const&, $_7&, (void*)0>, OT::SingleSubstFormat1::subset(hb_subset_context_t*) const::'lambda'(unsigned int), (hb_function_sortedness_t)1, (void*)0>, $_20&, (hb_function_sortedness_t)1, (void*)0>) harfbuzz/src/hb-ot-layout-common.hh:1055:16
+         #1 0x5d88f9 in bool OT::SingleSubstFormat1::serialize<hb_map_iter_t<hb_map_iter_t<hb_filter_iter_t<OT::Coverage::iter_t, hb_set_t const&, $_7&, (void*)0>, OT::SingleSubstFormat1::subset(hb_subset_context_t*) const::'lambda'(unsigned int), (hb_function_sortedness_t)1, (void*)0>, $_20&, (hb_function_sortedness_t)1, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_map_iter_t<hb_map_iter_t<hb_filter_iter_t<OT::Coverage::iter_t, hb_set_t const&, $_7&, (void*)0>, OT::SingleSubstFormat1::subset(hb_subset_context_t*) const::'lambda'(unsigned int), (hb_function_sortedness_t)1, (void*)0>, $_20&, (hb_function_sortedness_t)1, (void*)0>, unsigned int) harfbuzz/src/hb-ot-layout-gsub-table.hh:98:9
+
+ src/hb-algs.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit bcd3ffc948f63f59a709923a3ba6dc9d591aae6b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 16 13:22:09 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+commit 05bc5f96fb0818531404174b71c6ff497d5e2738
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 16 13:05:58 2019 -0700
+
+    [subset] Remove extra iteration
+
+ src/hb-ot-layout-gsub-table.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 6555f209586886a4b2562412363cf152d7837d5c
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed May 15 09:42:38 2019 -0700
+
+    [subset] Truncate empty gids at the end in retain-gids mode.
+
+ src/hb-subset-plan.cc                              |   8 ++++---
+ test/api/fonts/Roboto-Regular.a.retaingids.ttf     | Bin 0 -> 2068 bytes
+ .../SourceHanSans-Regular.41,4C2E.retaingids.otf   | Bin 2736 -> 2656 bytes
+ test/api/test-subset-glyf.c                        |  25 +++++++++++++++++++++
+ ...oboto-Regular.abc.drop-hints-retain-gids.61.ttf | Bin 744 -> 732 bytes
+ ...oboto-Regular.abc.drop-hints-retain-gids.62.ttf | Bin 712 -> 704 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.61.ttf   | Bin 1808 -> 1792 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.62.ttf   | Bin 1756 -> 1748 bytes
+ 8 files changed, 30 insertions(+), 3 deletions(-)
+
+commit 2376867649f97d25e4319f45845525ec207887f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 21:57:26 2019 -0700
+
+    Use hb_map(hb_add(this)) to dereference OffsetTo<>'s
+
+ src/hb-ot-layout-gsub-table.hh | 30 ++++++++++++++-------
+ src/hb-ot-layout-gsubgpos.hh   | 60 ++++++++++++++++++++++++++++--------------
+ src/hb-ot-stat-table.hh        |  2 +-
+ 3 files changed, 61 insertions(+), 31 deletions(-)
+
+commit 6f51e5552477125480f764a6af763dad9f8e3e1b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 21:41:12 2019 -0700
+
+    [algs] Rename hb_bind to hb_partial
+    
+    Since our API is the invers of what std::bind is, and closer to Python
+    functools.partial().
+
+ src/hb-algs.hh   | 12 ++++++------
+ src/test-algs.cc |  6 +++---
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 0888e7bc86454020db45f78ee1136d6f3a1b9527
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 21:36:42 2019 -0700
+
+    [algs] Change hb_bind parameter number to be from one
+    
+    To match std:;bind, even though our interfaces are very different.
+
+ src/hb-algs.hh   | 24 +++++++++++++-----------
+ src/test-algs.cc |  6 +++---
+ 2 files changed, 16 insertions(+), 14 deletions(-)
+
+commit dfa5e4297147b52f0ed2f569c9b90a0c68c003c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 21:18:14 2019 -0700
+
+    Add back symmetric OffsetTo<>::friend operator+
+    
+    Finally seems to be working now.
+
+ src/hb-open-type.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit a06a236891611da9db601ddbc2b1513380ad12e6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 21:12:22 2019 -0700
+
+    [algs] Partialize all operators
+
+ src/hb-algs.hh   | 66 +++++++++++++++++++++++++++++++++++---------------------
+ src/test-algs.cc |  4 ++--
+ 2 files changed, 44 insertions(+), 26 deletions(-)
+
+commit edc69ec935511d1993240fb68b54b2cfd6afa888
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 21:09:56 2019 -0700
+
+    [algs] Rewrite bind API
+    
+    And add a partialization API use example to hb_add()
+
+ src/hb-algs.hh   | 45 ++++++++++++++++++++-------------------------
+ src/test-algs.cc |  9 ++++++---
+ 2 files changed, 26 insertions(+), 28 deletions(-)
+
+commit 16a3540ea4257a19b9bfd9d5300a280e18b423a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 20:48:20 2019 -0700
+
+    [algs] Add hb_bind0 and hb_bind1
+
+ src/hb-algs.hh   | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/test-algs.cc |  7 +++++++
+ 2 files changed, 61 insertions(+)
+
+commit d214b07883a626f3ecebb027797e8bb994e174a4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 19:07:39 2019 -0700
+
+    Fix clang build
+    
+    Ugh.
+    
+    In file included from hb-ot-face.cc:41:
+    ./hb-ot-layout-gsub-table.hh:293:7: error: template parameter redefines default argument
+             hb_requires (hb_is_sorted_source_of (Iterator,
+             ^
+    ./hb-meta.hh:59:27: note: expanded from macro 'hb_requires'
+     define hb_requires(Cond) hb_enable_if((Cond))
+                              ^
+    ./hb-meta.hh:57:67: note: expanded from macro 'hb_enable_if'
+     define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+                                                                      ^
+    ./hb-ot-layout-gsub-table.hh:40:5: note: previous default template argument defined here
+        hb_requires (hb_is_sorted_source_of (Iterator,
+        ^
+    ./hb-meta.hh:59:27: note: expanded from macro 'hb_requires'
+     define hb_requires(Cond) hb_enable_if((Cond))
+                              ^
+    ./hb-meta.hh:57:67: note: expanded from macro 'hb_enable_if'
+     define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+                                                                      ^
+
+ src/hb-ot-layout-gsub-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 371b55c7a0c718fcaca0330edfeacf610797cf7a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 18:54:07 2019 -0700
+
+    Fix clang build
+    
+    In file included from hb-ot-face.cc:41:
+    ./hb-ot-layout-gsub-table.hh:293:7: error: template parameter redefines default argument
+             hb_requires (hb_is_sorted_source_of (Iterator,
+             ^
+    ./hb-meta.hh:59:27: note: expanded from macro 'hb_requires'
+     define hb_requires(Cond) hb_enable_if((Cond))
+                              ^
+    ./hb-meta.hh:57:67: note: expanded from macro 'hb_enable_if'
+     define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+                                                                      ^
+    ./hb-ot-layout-gsub-table.hh:40:5: note: previous default template argument defined here
+        hb_requires (hb_is_sorted_source_of (Iterator,
+        ^
+    ./hb-meta.hh:59:27: note: expanded from macro 'hb_requires'
+     define hb_requires(Cond) hb_enable_if((Cond))
+                              ^
+    ./hb-meta.hh:57:67: note: expanded from macro 'hb_enable_if'
+     define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+                                                                      ^
+    1 error generated.
+
+ src/hb-ot-layout-gsub-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 243a5a6af2565937705d6bc20e65a62b686bb664
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 19:03:59 2019 -0700
+
+    [algs] Remove pair copy constructor
+    
+    Use default.
+
+ src/hb-algs.hh   | 1 -
+ src/test-algs.cc | 1 +
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit f92d188d7703184d04e8f205ae46ca3081d3e048
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 18:52:57 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 962f95cf802404dafadf2f999772d3f9fc949d63
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu May 9 13:04:11 2019 -0700
+
+    [subset] Switch SingleSubst to use iterators in serialize.
+
+ src/hb-ot-layout-common.hh     |  6 +--
+ src/hb-ot-layout-gsub-table.hh | 97 +++++++++++++++++++++++++-----------------
+ 2 files changed, 62 insertions(+), 41 deletions(-)
+
+commit 78d35f0e780dd811ae103c96f3b1060d49046a7a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 18:15:05 2019 -0700
+
+    Reduce captures of lambdas
+
+ src/hb-ot-hdmx-table.hh        |  4 ++--
+ src/hb-ot-layout-gpos-table.hh |  2 +-
+ src/hb-ot-layout-gsub-table.hh | 29 +++++++++++++++--------------
+ src/hb-ot-layout-gsubgpos.hh   | 12 ++++++------
+ src/hb-ot-name-table.hh        |  2 +-
+ src/hb-ot-stat-table.hh        |  2 +-
+ src/hb-ot-var-fvar-table.hh    |  4 ++--
+ src/hb-subset-plan.cc          |  2 +-
+ src/test-iter.cc               |  4 ++--
+ 9 files changed, 31 insertions(+), 30 deletions(-)
+
+commit 5266ca86b633b84850492b7982334fb63271ccbc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 17:59:00 2019 -0700
+
+    Fix tests
+    
+    Oops.
+
+ src/test-algs.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 5da8a3a90db5e5ccaaf68de2ac312108af911821
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 17:11:18 2019 -0700
+
+    Remove variadic form of hb_min/hb_max
+    
+    Unused, and why here and not in other functions...
+
+ src/hb-algs.hh | 22 ++--------------------
+ 1 file changed, 2 insertions(+), 20 deletions(-)
+
+commit e5cfe9d582d86281eda2bcb85d3d1cbd4afbb5bb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 16:59:36 2019 -0700
+
+    Add arithmetic operators
+
+ src/hb-algs.hh | 44 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 30 insertions(+), 14 deletions(-)
+
+commit f7a458510d9c34d1c52579985ded5082ad0f3458
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 16:49:35 2019 -0700
+
+    Add hb_bitwise_* ops
+
+ src/hb-algs.hh | 56 +++++++++++++++++++++++++++++++++++---------------------
+ src/hb-set.hh  | 14 +++++++-------
+ 2 files changed, 42 insertions(+), 28 deletions(-)
+
+commit d822e0a16f914ec6a7e629d21ed972d009a88561
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 16:30:08 2019 -0700
+
+    [array] Adjust operator!=
+    
+    See comments.
+
+ src/hb-array.hh  | 7 ++++++-
+ src/hb-vector.hh | 1 +
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+commit 203ea58bf67b3df3e376f94cdfb37382dd3858a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 16:14:40 2019 -0700
+
+    More adjustment to OffsetTo<>::friend opeator+
+    
+    Let's see if I break any bots.  But yeah, it wasn't accepting a
+    non-const pointer.  It just happens that we don't use that in the
+    code it seems.
+
+ src/hb-open-type.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit ebf47a95f29dd959319feb7f8728f7c0162a181e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 15:14:26 2019 -0700
+
+    [iter] Simplify operator!= of iterator filters
+    
+    Both to save ops, and also because lambdas don't implement operator!=,
+    so this was failing in range-based for loop if a lambda was passed to
+    hb_map() or hb_filter().  Just check end-condition assuming that we
+    are comparing to .end() or iterators that are otherwise derived from
+    current iterator.  Ie. don't compare things that are expected to be
+    in common.
+
+ src/hb-iter.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit d3e1d5044f23a2dc910f4253c3f4976bf08f93ab
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 14:25:54 2019 -0700
+
+    Add all pair_t comparison operators
+
+ src/hb-algs.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit f244224dbb5ee8929af109a0c4e23d2d993c8df8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 14:19:20 2019 -0700
+
+    [iter] Use default operators instead of redefining empty ones
+
+ src/hb-iter.hh | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+commit 125c45ed368ae61a74e2c558b9c884cfde6295e1
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Wed May 15 17:02:32 2019 -0400
+
+    Convert Consonant_Initial_Postfixed to CONS_MED
+
+ src/gen-use-table.py                                     |   6 +++---
+ src/hb-ot-shape-complex-use-table.cc                     |   2 +-
+ .../fonts/fd565cabd5208d345d0ed4fda7ae742917d846a5.ttf   | Bin 0 -> 1056 bytes
+ test/shaping/data/in-house/tests/use-syllable.tests      |   1 +
+ 4 files changed, 5 insertions(+), 4 deletions(-)
+
+commit 99ca956c131563b57d490b1ec3c8de920645e53f
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Wed May 15 16:29:51 2019 -0400
+
+    Fix record-test.sh on machines without sha1sum
+
+ test/shaping/record-test.sh | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+commit e2767e438c56b8ee0bc2f2040c10b13b34d37f95
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed May 15 13:14:09 2019 +0430
+
+    [ci][test] Ignore other gcov symbols also
+    
+    To fix https://travis-ci.org/harfbuzz/harfbuzz/jobs/532693197
+
+ src/check-symbols.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 397cbbd5ff25c9796ecd56b8270e83de1eb322ac
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed May 15 13:03:28 2019 +0430
+
+    [ci][travis] Update its distribution
+    
+    It may break things, lets see
+
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 763ea4224bf612f3efb80d5744d1e8852682683e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 01:15:11 2019 -0700
+
+    Another try
+
+ src/hb-open-type.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit e1b2edb04af7bd2b4eecb59392f75abcc72cd8a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 01:12:04 2019 -0700
+
+    Completely revert the thing back
+
+ src/hb-open-type.hh | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+commit c58eeb5fb35ec6a8d0a4394fd83cb2571cd5af4f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 01:10:31 2019 -0700
+
+    Another try at fix
+    
+    Fails locally.  Trying to understand.  Sigh
+
+ src/hb-open-type.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 004edf3bdac77564d39516b51b0666de60e65ece
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 01:02:50 2019 -0700
+
+    Ugh.  How was the Travis bot happy before, but isn't now?! :(
+
+ src/hb-open-type.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit e01c7b1648dbbb76966b3bd4437bcf7699e77c35
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 00:52:17 2019 -0700
+
+    Move OffsetTo operator+ back out of class
+    
+    Apparently there's different overload resolution rules that apply, at
+    least with some (older?) version of gcc.
+    
+    hb-ot-name-table.hh: In member function ‘void OT::name::accelerator_t::init(hb_face_t*)’:
+    hb-ot-name-table.hh:244:62: error: ambiguous overload for ‘operator+’ (operand types are ‘hb_blob_ptr_t<OT::name>’ and ‘OT::NNOffsetTo<OT::UnsizedArrayOf<OT::IntType<unsigned char, 1u> > > {aka const OT::OffsetTo<OT::UnsizedArrayOf<OT::IntType<unsigned char, 1u> >, OT::IntType<short unsigned int, 2u>, false>}’)
+           this->pool = (const char *) (const void *) (this->table+this->table->stringOffset);
+                                                                  ^
+    hb-ot-name-table.hh:244:62: note: candidates are:
+    hb-ot-name-table.hh:244:62: note: operator+(const C*, long int) <built-in>
+    hb-ot-name-table.hh:244:62: note: operator+(const char*, long int) <built-in>
+
+ src/hb-open-type.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit b213042f87dd736bad7a852fe98269f84cbff493
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 00:50:48 2019 -0700
+
+    Revert "Revert symmetric OffsetTo overloads"
+    
+    This reverts commit 01912efb74fc554a81c8cfe572145ce45b8fa58b.
+    
+    Actually this didn't break things.  Fixing
+
+ src/hb-open-type.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 01912efb74fc554a81c8cfe572145ce45b8fa58b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 00:42:47 2019 -0700
+
+    Revert symmetric OffsetTo overloads
+    
+    Reverts 57f65ae9355004044325dd6441cde761bca5e0a3
+    
+    Caused ambiguous-overload on some gcc...
+
+ src/hb-open-type.hh | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit d0df996cdc249a245c9dad1fa6503213c84dbcd2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 15 00:32:41 2019 -0700
+
+    Use implicit lambda return type
+
+ src/hb-array.hh                |  4 ++--
+ src/hb-ot-layout-gsub-table.hh |  8 ++++----
+ src/hb-ot-layout-gsubgpos.hh   | 18 +++++++++---------
+ src/hb-ot-stat-table.hh        |  2 +-
+ src/hb-ot-var-fvar-table.hh    |  4 ++--
+ src/test-iter.cc               |  8 ++++----
+ src/test-meta.cc               |  1 -
+ 7 files changed, 22 insertions(+), 23 deletions(-)
+
+commit 57f65ae9355004044325dd6441cde761bca5e0a3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 14 22:52:59 2019 -0700
+
+    Add symmetric friend operator+ for OffsetTo
+
+ src/hb-open-type.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 71208e5047c71108dec7361fd7c3e594c8b6c2d8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 14 22:51:59 2019 -0700
+
+    Move OffsetTo<> deref operators in-class as friends
+
+ src/hb-open-type.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit e6d6f4b96dd5517406265093cd57834c00850d41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 14 22:45:03 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-stat-table.hh     | 2 +-
+ src/hb-ot-var-fvar-table.hh | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 889dc1eb06a80ea9be4223a19011e47a52abebdd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 14 22:28:07 2019 -0700
+
+    [iter] Remove sort categorization
+    
+    See comments.
+
+ src/hb-array.hh            |  2 +-
+ src/hb-iter.hh             | 48 ++++++++++++++++++++++++++++++----------------
+ src/hb-ot-layout-common.hh |  2 +-
+ src/hb-set.hh              |  2 +-
+ 4 files changed, 35 insertions(+), 19 deletions(-)
+
+commit b4eff38397c2a4e475f426df38e040dddf94a4fa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 14 09:07:20 2019 -0700
+
+    Start of gen-ucd.py, to replace UCDN
+
+ src/gen-ucd.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+commit 02e5e5d939be36d8f108029601a1ce1f533e5ccb
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon May 13 09:38:42 2019 -0700
+
+    [subset] retian nameids from STAT and fvar tables
+
+ src/hb-ot-stat-table.hh     | 76 +++++++++++++++++++++++++++++++++++++++++----
+ src/hb-ot-var-fvar-table.hh | 21 +++++++++++++
+ src/hb-subset-plan.cc       | 26 ++++++++++++++++
+ 3 files changed, 117 insertions(+), 6 deletions(-)
+
+commit ff7995200e706f3161b9fc5c27bb950e3d87e8e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 14 07:44:03 2019 -0700
+
+    Hopefully last warning fix
+
+ src/hb-subset-cff2.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d1baf99697d215584b2ecb8d2d38ba5b9045955c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue May 14 16:16:46 2019 +0430
+
+    [ci] add HB_TINY to asmjs builder
+
+ .circleci/config.yml | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+commit 9e7c9c3adb33b06610951be38f3c820342333092
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue May 14 15:58:51 2019 +0430
+
+    Fix -Wunused-function on HB_NO_SHAPE_AAT
+    
+    We should add a bot for it
+    Part of #1652
+
+ src/hb-ot-shape.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit c73d7ba75d4556d9b8e05b10d6572f74f4814f7a
+Author: Dominik Röttsches <drott at chromium.org>
+Date:   Tue May 14 13:26:18 2019 +0300
+
+    Fix building with HB_NO_SUBSET_LAYOUT
+    
+    Fixes an unused function warning when building with HB_NO_SUBSET_LAYOUT
+    as part of the Chrome build.
+
+ src/hb-subset-plan.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit f39934983f459c992e27075cd2c45ac0025183d0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 14 00:13:21 2019 -0700
+
+    [ucdn] Fix Hangul composition
+    
+    https://github.com/grigorig/ucdn/issues/23
+
+ src/hb-ucdn/ucdn.c      | 3 ++-
+ test/api/test-unicode.c | 4 ++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit b2ab15a78c219016e20389582716e0ac0ee8aeb5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 23:47:28 2019 -0700
+
+    Fix more warnings
+
+ src/hb-ot-cff1-table.hh | 8 ++++----
+ src/hb-subset-cff1.cc   | 4 ++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 42ae468a8a76e1e4e6a8121eec5dc118f52086ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 23:43:45 2019 -0700
+
+    [config] Add NDEBUG and HB_NDEBUG
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 10 ++++++++++
+ src/hb.hh        | 10 ----------
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+commit 0a01deb76fa582afa83da70a09478299d8080827
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 18:04:09 2019 -0700
+
+    One more warning fix
+    
+    No idea where these appear from...
+
+ src/hb-ot-cff-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f76e9f2ede76a189d48ddd4f2275442d8e849815
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 17:39:46 2019 -0700
+
+    [icu] Comment
+
+ src/hb-icu.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 70fe9e73555f3354238f7cda5ff0f0c0b75e1d62
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 17:35:02 2019 -0700
+
+    Fix moreeeeeeeeeee
+
+ src/hb-icu.cc         | 28 +++++++++++++++-------------
+ src/hb-subset-plan.cc |  2 +-
+ 2 files changed, 16 insertions(+), 14 deletions(-)
+
+commit 68e12e68f813bfd22dda040463d042cc06b958ec
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 17:28:59 2019 -0700
+
+    Fix more semi-colon issues
+
+ src/hb-coretext.cc    | 4 ++--
+ src/hb-directwrite.cc | 4 ++--
+ src/hb-graphite2.cc   | 4 ++--
+ src/hb-uniscribe.cc   | 4 ++--
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 4d3cf2adb669c345cc43832d11689271995e160a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 17:25:07 2019 -0700
+
+    [iter] Fix zip iterator sortedness classification logic
+
+ src/hb-iter.hh | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+commit c572732f29787d1cf7ff39b8160b3935d4b13ba4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 15:41:09 2019 -0700
+
+    Fix more excess semi-colon errors
+
+ src/hb-common.cc                 | 2 +-
+ src/hb-ot-name.cc                | 4 ++--
+ src/hb-ot-shape-complex-indic.hh | 2 +-
+ src/hb-ot-shape-complex-khmer.hh | 2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 513762849a683914fc266a17ddf38f133cccf072
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 15:36:14 2019 -0700
+
+    [iter] Track strictly-sorted iterators
+    
+    This make output of hb_enumerate() sorted regardless of input iterator.
+
+ src/hb-array.hh            |  2 +-
+ src/hb-iter.hh             | 30 +++++++++++++++++++++---------
+ src/hb-ot-layout-common.hh |  2 +-
+ src/hb-set.hh              |  2 +-
+ 4 files changed, 24 insertions(+), 12 deletions(-)
+
+commit 7e02063f3202712b4e5fbddac0354adadb924f72
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 15:26:00 2019 -0700
+
+    [iter] Minor
+
+ src/hb-iter.hh | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+commit a5fb44a8cbbaad194ddf6d02a6b6c98b0b637149
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon May 13 14:57:40 2019 -0700
+
+    [subset] Fix shadowed 'groups' param in cmap.
+
+ src/hb-ot-cmap-table.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 73943bdf21a96f4e12cb9efd8458a2711de0d870
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 14:48:31 2019 -0700
+
+    Adjust uniscribe_bug_compatible mode
+    
+    More correct behavior.  We were commenting out some legit conditions
+    before.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-indic.cc | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+commit 809c58708359bcc22bb1273069886f2cbf68be65
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 14:45:51 2019 -0700
+
+    [config] Better compile away morx/kerx/trak
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape.cc | 38 ++++++++++++++------------------------
+ src/hb-ot-shape.hh | 12 +++++++++++-
+ 2 files changed, 25 insertions(+), 25 deletions(-)
+
+commit b1d3e54bd3c881794b05831e811b1a77a7d427c5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 14:35:04 2019 -0700
+
+    [indic] Don't constrain how many C, M, ... occur
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1709
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-indic-machine.hh | 1225 ++++++++----------------------
+ src/hb-ot-shape-complex-indic-machine.rl |    8 +-
+ 2 files changed, 305 insertions(+), 928 deletions(-)
+
+commit 148d88368013ba9bf70a7dd275b1a0f9c64fd45c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 14:33:06 2019 -0700
+
+    [test] Don't call deprecated API
+
+ test/api/test-font.c  |  3 ---
+ test/api/test-shape.c | 16 ++--------------
+ 2 files changed, 2 insertions(+), 17 deletions(-)
+
+commit a487fc33248ea2f934ff4cb857cb556065c11841
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 14:16:33 2019 -0700
+
+    Another extra semi-colon
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8461ade7832110d28001dc641342d3f9461e03b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 14:10:48 2019 -0700
+
+    Revert "[ragel] Regenerate ragel-generated files using ragel 7.0.0.11 May 2018"
+    
+    This reverts commit 9b05db33b54e6e5f0b4658f4c06e7fe563f8923b.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1708
+
+ src/hb-buffer-deserialize-json.hh          | 1051 ++++++-----
+ src/hb-buffer-deserialize-text.hh          | 1009 ++++++-----
+ src/hb-ot-shape-complex-indic-machine.hh   | 2678 ++++++++++++----------------
+ src/hb-ot-shape-complex-khmer-machine.hh   |  709 ++++----
+ src/hb-ot-shape-complex-myanmar-machine.hh |  820 ++++-----
+ src/hb-ot-shape-complex-use-machine.hh     | 1144 ++++++------
+ 6 files changed, 3452 insertions(+), 3959 deletions(-)
+
+commit 52c15b053aec06d351404a4c15609384946b26e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 14:10:28 2019 -0700
+
+    Revert "[ragel] Switch to -T1 output instead of -F1"
+    
+    This reverts commit ae8719eb596485ebff07dd5016256015cd0cf86b.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1708
+
+ src/Makefile.am                            |    2 +-
+ src/hb-buffer-deserialize-json.hh          |  381 ++-
+ src/hb-buffer-deserialize-text.hh          |  308 +--
+ src/hb-ot-shape-complex-indic-machine.hh   | 3527 +++++++---------------------
+ src/hb-ot-shape-complex-khmer-machine.hh   |  396 +---
+ src/hb-ot-shape-complex-myanmar-machine.hh |  742 ++----
+ src/hb-ot-shape-complex-use-machine.hh     | 1011 ++------
+ 7 files changed, 1658 insertions(+), 4709 deletions(-)
+
+commit e98f0ddd6373f64ef4b542daa36b5841399170af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 13:53:06 2019 -0700
+
+    Fix extra semi-colon
+
+ src/hb-iter.hh | 2 +-
+ src/hb.hh      | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit ae8719eb596485ebff07dd5016256015cd0cf86b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 13 12:27:10 2019 -0700
+
+    [ragel] Switch to -T1 output instead of -F1
+    
+    Fedora upgraded to ragel 7, which is buggy if char is signed.
+    Switching to -G2 output fails with sign-compare error:
+    
+    ../../src/hb-buffer-deserialize-json.hh:107:12: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘const char’ [-Werror=sign-compare]
+        if ( 9u <= ( (*( p))) && ( (*( p))) <= 13u ) {
+             ~~~^~~~~~~~~~~~~
+    
+    Switching to -T1 for now.  It actually results in smaller code,
+    at the expense of some binary searching instead of flat tables.
+    In the not distant future, we might actually generate two different
+    outputs and choose between depending on size-optimize options.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1708
+
+ src/Makefile.am                            |    2 +-
+ src/hb-buffer-deserialize-json.hh          |  381 ++--
+ src/hb-buffer-deserialize-text.hh          |  308 ++-
+ src/hb-ot-shape-complex-indic-machine.hh   | 3401 +++++++++++++++++++++-------
+ src/hb-ot-shape-complex-khmer-machine.hh   |  396 +++-
+ src/hb-ot-shape-complex-myanmar-machine.hh |  742 ++++--
+ src/hb-ot-shape-complex-use-machine.hh     | 1011 ++++++---
+ 7 files changed, 4646 insertions(+), 1595 deletions(-)
+
+commit df3f36f0bb7aeed0554843f24f6542852e40f6cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 12 20:56:36 2019 -0700
+
+    Minor
+
+ src/gen-os2-unicode-ranges.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit ccc88e98f34453100830d6408fdabfe90e6b47b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 12 16:12:06 2019 -0700
+
+    Fix MSVC build
+
+ src/hb-ot-shape-complex-indic.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f8f9cb93b7166b0d8c816610596da486443c7391
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 12 15:56:25 2019 -0700
+
+    [config] Define HB_NO_SUBSET_LAYOUT in HB_LEAN
+    
+    Assumning subsetter would be used for printing-like uses in that case,
+    which don't need GSUB/GPOS.
+
+ src/hb-config.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit a1394a28fc4b3d15ef45481f3147f0685d343acb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 12 15:47:46 2019 -0700
+
+    [config] Add HB_NO_UNISCRIBE_BUG_COMPATIBLE
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh                 |  4 ++++
+ src/hb-ot-shape-complex-indic.cc | 24 ++++++++++++++++++------
+ 2 files changed, 22 insertions(+), 6 deletions(-)
+
+commit dba1ac1b0e8f5f96974fc1119b318ae6127daa82
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 12 15:33:31 2019 -0700
+
+    [config] Disable buffer serialize routines in HB_TINY
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-buffer-serialize.cc | 14 +++++++++++++-
+ src/hb-config.hh           |  1 +
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+commit 3d9be2ad5036aaf02b69095faaf9c18705c2c5bc
+Merge: a20db496 1a850abd
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sun May 12 20:03:29 2019 +0100
+
+    Merge pull request #1665 from n8willis/docs-gtkdoc-colormath
+    
+    [Docs] Add gtk-doc comments for OT color and OT math
+
+commit a20db496f090abc5b937857b7c5f077161b6ffe4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 12 11:08:45 2019 -0700
+
+    Fix builds
+
+ src/hb-subset-plan.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 8694d6082901661e90e2ffcf732e9985a215063f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 12 11:05:24 2019 -0700
+
+    [config] Enable HB_NO_MT in HB_TINY
+    
+    Now that user can override it if needed...
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7f6fca4ef78cf3c9384bf835def14219b2ce8791
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 12 10:29:47 2019 -0700
+
+    Force-disable CFF code under disabling conditions
+    
+    Subsetter size goes down from 190kb to 119kb.  Main library about 7kb.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-cff1-table.cc | 4 ++++
+ src/hb-ot-cff2-table.cc | 4 ++++
+ src/hb-subset-cff1.cc   | 4 ++++
+ src/hb-subset-cff2.cc   | 4 ++++
+ 4 files changed, 16 insertions(+)
+
+commit 5249eee43748db32b40ad2602b3243d2491642b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 16:12:07 2019 -0700
+
+    [config] Allow overriding chosen config
+
+ src/hb-config.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 30c059a978c91fcd38d47f1ac4a03295f887a7da
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat May 11 18:48:41 2019 -0400
+
+    [test] minor, fix -Weverything bot
+
+ test/fuzzing/main.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 25531a30394c451a7a2aee77928e0a550015b803
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat May 11 19:50:42 2019 +0000
+
+    [test] minor
+    
+    style fix and add return statement
+
+ test/fuzzing/main.cc | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+commit 1a850abd66999707b6f4795050e748fc879b92ef
+Merge: 8a544171 a6048e4c
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 20:16:57 2019 +0100
+
+    Merge branch 'master' into docs-gtkdoc-colormath
+
+commit 8a544171d15bb36c15ca7bf679643b2b14f94b45
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sat May 11 20:11:49 2019 +0100
+
+    Corrections to OT Color gtk-doc comments.
+
+ src/hb-ot-color.cc | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 301f5091f6663cc8a1fff848bf5285aa15cc0598
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sat May 11 20:11:36 2019 +0100
+
+    Corrections to OT Math gtk-doc comments.
+
+ src/hb-ot-math.cc | 33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+commit a6048e4cd013987ecb846e0683a7cf6f0caa65f9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 12:11:22 2019 -0700
+
+    Fix build
+
+ src/hb-ot-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 32d3c06b61f2f4252f4403b55c6ba07fbb572149
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 11:59:18 2019 -0700
+
+    Disable sbix if no-color or no-ot-font-bitmap
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-font.cc | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+commit 606841b07017ac80dea2fc5ada25b5976f2f9192
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 11:54:30 2019 -0700
+
+    [iter] Check for more before forwarding/rewinding past ends
+
+ src/hb-iter.hh   | 4 ++--
+ src/test-iter.cc | 6 ++----
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+commit c1c122e7b3f60dc7b5a224c68d2acb106fda8b49
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Sat May 11 11:38:06 2019 -0400
+
+    [iter] Fix filter rewinding
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b854d4ff46602104343201361919f30169144cf1
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri May 10 22:51:49 2019 -0400
+
+    [array] Fix rewinding
+
+ src/hb-array.hh | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+commit 76e80c5ca5e820e955438e4c727929ddd99e695e
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 19:51:24 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny at eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 79126df3070f00193fe3caefe9deb62c4520e048
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 11:23:31 2019 -0700
+
+    [iter] Add hb_map_sorted() and hb_map_retains_sorting()
+
+ src/hb-iter.hh | 38 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 31 insertions(+), 7 deletions(-)
+
+commit bcd81932f0bcb2258276ae313709780e90e9b0f6
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 14:10:32 2019 +0100
+
+    Update src/hb-ot-math.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny at eglug.org>
+
+ src/hb-ot-math.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ddc6dd42f753a20204898e41cc711b0100638330
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 14:10:11 2019 +0100
+
+    Update src/hb-ot-math.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny at eglug.org>
+
+ src/hb-ot-math.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 46e05ecca16e561a0ff4ca60bb064f480374590a
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 14:09:52 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny at eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6d9870b4799f20a6c58a2c071713e56aa93b0221
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 14:09:26 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny at eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 12ea4a24c40c7ac28d058e9721479347951e3482
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 14:08:40 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny at eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3535f2d31efe1ebe44ba63f980882ba23cdcde3b
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 14:07:38 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny at eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 12d2c472fe8ec3268a4b39a57603dcc734ab7b88
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sat May 11 14:06:56 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny at eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7f45ce42dbf11366e904f48db45cf5405e4e94df
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 01:28:31 2019 -0700
+
+    [config] Rename
+
+ src/hb-config.hh    | 2 +-
+ src/hb-ot-layout.cc | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 0e78d4ddaec5f29d6652cc4185cbcca98c3a2927
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 01:27:50 2019 -0700
+
+    [config] Add HB_NO_NAME
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh  |  6 +++++-
+ src/hb-ot-name.cc | 20 ++++++++++++++++++++
+ 2 files changed, 25 insertions(+), 1 deletion(-)
+
+commit 1fc077211771c752768f63f178116d2b8f2f7d03
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 01:24:23 2019 -0700
+
+    [config] HB_NO_OT_NAME_LANGUAGE AAT
+
+ src/hb-config.hh                  | 4 ++--
+ src/hb-ot-name-language-static.hh | 3 +++
+ src/hb-ot-name-table.hh           | 4 +++-
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
+commit 4381bb2de7a554a148302836b86a5d73264abeae
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 01:14:04 2019 -0700
+
+    [config] Comment
+
+ src/hb-config.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 9c921e6c32ab5ac4c524f554b7a7841eeeb0908f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 01:08:51 2019 -0700
+
+    [config] Enable HB_NO_NAME_TABLE_AAT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 81b79dfc397599182f43d63bf9346eee28e2d220
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:53:52 2019 -0700
+
+    [config] Add HB_NO_COLOR to HB_LEAN
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh   |  1 +
+ src/hb-ot-color.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++----
+ src/hb-ot-color.h  |  2 +-
+ src/hb-ot-layout.h |  2 +-
+ 4 files changed, 48 insertions(+), 6 deletions(-)
+
+commit b63a8e173cbc5a81f2ca4a0a82f20b9dafaedb30
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:47:20 2019 -0700
+
+    [config Add HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS to LEAN
+    
+    Already I don't like the inflexibility of this approach :(.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 42a21284778f3203d96133f74b0f846cd1567958
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:44:22 2019 -0700
+
+    [config] Disbale getenv() and atexit() if HB_LEAN
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit fca27860417812d51e40f040de97c10177b1250e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:37:01 2019 -0700
+
+    [config] Make HB_DISABLE_DEPRECATED actually compile
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh            |  7 +++++++
+ src/hb-font.cc              |  8 ++++++++
+ src/hb-font.hh              | 12 ++++++++++--
+ src/hb-graphite2.cc         |  2 ++
+ src/hb-icu.cc               |  2 +-
+ src/hb-ot-layout.cc         |  7 ++++++-
+ src/hb-ot-shape-fallback.cc |  4 ++++
+ src/hb-ot-tag.cc            |  4 ++++
+ src/hb-ot-var-fvar-table.hh |  6 ++++++
+ src/hb-ot-var.cc            |  2 ++
+ src/hb-set.cc               |  2 ++
+ src/hb-unicode.cc           |  6 ++++++
+ src/hb-unicode.hh           | 10 +++++++---
+ 13 files changed, 65 insertions(+), 7 deletions(-)
+
+commit 5a48611ccd045de5782ad2fd5f6718357fe232a2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:19:03 2019 -0700
+
+    [config] Add HB_NO_OT_LAYOUT_UNUSED
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh    |  1 +
+ src/hb-ot-layout.cc | 12 ++++++++++++
+ 2 files changed, 13 insertions(+)
+
+commit 771f1b21d1d7128440d6b4488705456d43dbc0e7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:16:18 2019 -0700
+
+    [config] Adjust
+
+ src/hb-config.hh | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit 484f6e8215038006a945da67d245f14db3eeeb2e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:13:35 2019 -0700
+
+    [config] Add HB_LEAN
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh  |  5 +++++
+ src/hb-ot-math.cc | 40 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 45 insertions(+)
+
+commit 0bfd14c0ed2f95f00d0b94d396c777399afa4d68
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:06:57 2019 -0700
+
+    [config] Fix tests
+
+ src/hb-config.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 784df8eba1aaf20d2db464f8b3ea0984f7ea1308
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat May 11 00:04:59 2019 -0700
+
+    [config] Flesh out more
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit 799c6a5081e5058260199eeeb2091ee2c1dfefff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 23:55:22 2019 -0700
+
+    [config] Add some
+
+ src/hb-aat-layout.cc    | 26 +++++++++++++-------------
+ src/hb-aat-map.cc       |  4 ++--
+ src/hb-config.hh        | 18 ++++++++++++++++++
+ src/hb-ot-kern-table.hh | 14 +++++++-------
+ src/hb-ot-shape.cc      | 22 +++++++++++-----------
+ 5 files changed, 51 insertions(+), 33 deletions(-)
+
+commit e6582de12f1af9ab5e3122d762a3e12438a66b6b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 23:53:38 2019 -0700
+
+    Add hb-config.hh
+
+ src/Makefile.sources |  1 +
+ src/hb-config.hh     | 36 ++++++++++++++++++++++++++++++++++++
+ src/hb.hh            |  7 ++++---
+ 3 files changed, 41 insertions(+), 3 deletions(-)
+
+commit d43af339e7a7f5dab1690703a78d2690baefbd59
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 23:46:22 2019 -0700
+
+    [subset] More HB_NO_SUBSET_LAYOUT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-subset-plan.cc | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit 31c591d69f6a7605088883db59149e83c80d019c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 23:39:53 2019 -0700
+
+    [cff] Prune more code if HB_NO_OT_FONT_CFF
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-cff1-table.cc | 5 +++++
+ src/hb-ot-cff2-table.cc | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+commit 5ea8ad5c48f9baabc4ccf81dce4aee1067c401f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 23:36:42 2019 -0700
+
+    [subset] Add HB_NO_SUBSET_CFF
+    
+    Doesn't fully prune all the relevant code.  To be fixed later.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-subset.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 2c93f0dee31b2277567ccbee041539732b9bd26d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 23:31:05 2019 -0700
+
+    Add HB_NO_AAT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-aat-layout.cc    | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-aat-map.cc       |  8 +++++++
+ src/hb-ot-kern-table.hh | 14 ++++++++++++
+ src/hb-ot-shape.cc      | 28 +++++++++++++++++++++++-
+ 4 files changed, 107 insertions(+), 1 deletion(-)
+
+commit 62dfe7aea23c95f4550543085071990e20ee4d54
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 23:17:15 2019 -0700
+
+    [cff] Minor
+
+ src/hb-subset-cff1.cc | 2 +-
+ src/hb-subset-cff2.cc | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 227d85e138d4c785c2d658e225ed35f5acd1235f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 23:15:58 2019 -0700
+
+    Minor
+
+ src/hb-atomic.hh                             |  2 +-
+ src/hb-debug.hh                              |  2 +-
+ src/hb-font.cc                               |  2 +-
+ src/hb-ot-font.cc                            |  4 ++--
+ src/hb-ot-layout.cc                          |  6 +++---
+ src/hb-ot-name-table.hh                      |  2 +-
+ src/hb-ot-shape-complex-arabic.cc            |  2 +-
+ src/hb-ot-shape-complex-hebrew.cc            |  2 +-
+ src/hb-ot-shape-complex-thai.cc              |  2 +-
+ src/hb-ot-shape-complex-vowel-constraints.cc |  2 +-
+ src/hb-ot-shape-fallback.cc                  |  6 +++---
+ src/hb-subset.cc                             |  4 ++--
+ src/hb-warning.cc                            |  4 ++--
+ src/hb.hh                                    | 10 +++++-----
+ 14 files changed, 25 insertions(+), 25 deletions(-)
+
+commit 9bfe22af6113ee8cd24cb9ee091f0841c27bbf98
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 22:44:19 2019 -0700
+
+    [sanitize] Fix previous commit
+
+ src/hb-open-type.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 4dcf65328f04a11594fc190fd7e976afa54455e9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 22:23:24 2019 -0700
+
+    [sanitize] Simplify
+
+ src/hb-open-type.hh | 45 ++++++++++-----------------------------------
+ 1 file changed, 10 insertions(+), 35 deletions(-)
+
+commit 23168c3981f7c80883663fa69c608caee98d3d99
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 22:11:51 2019 -0700
+
+    [sanitize] Use hb_is_trivially_copyable()
+
+ src/hb-open-type.hh | 64 +++++++----------------------------------------------
+ 1 file changed, 8 insertions(+), 56 deletions(-)
+
+commit 0ff7954f9f09f80654ac91c16712154744a0dd2d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 22:04:40 2019 -0700
+
+    [meta] Add hb_is_trivial
+
+ src/hb-meta.hh   | 7 +++++++
+ src/test-meta.cc | 4 ++++
+ 2 files changed, 11 insertions(+)
+
+commit 7162a97bca6e0dde3d277701a3bf15688deef61d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 22:03:03 2019 -0700
+
+    [meta] Add hb_is_trivially_copyable()
+
+ src/hb-meta.hh   | 11 +++++++++++
+ src/test-meta.cc |  4 ++++
+ 2 files changed, 15 insertions(+)
+
+commit f2398f34c019a55d4f0e1a7031961714afadf2b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 21:59:57 2019 -0700
+
+    [meta] Add is_trivially_destructible
+
+ src/hb-meta.hh   | 6 +++---
+ src/test-meta.cc | 7 +++++--
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+commit 72cb5b8e52b7103c18adcb82cbcd4b91a2c85474
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 21:50:15 2019 -0700
+
+    Remove accidentally included include
+
+ src/test-meta.cc | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 086772e409759e8f1edd0e34f6f25374e51e9e10
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 21:49:25 2019 -0700
+
+    [meta] Add is_destructible
+
+ src/hb-meta.hh | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit b14745278ad16fe7f4e838b685029e3fdda516ca
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 21:42:59 2019 -0700
+
+    [met]a Add is_constructible, ...
+
+ src/hb-meta.hh   | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/test-meta.cc | 23 ++++++++++++++++++
+ 2 files changed, 96 insertions(+)
+
+commit 19e08a146712dacd11359370c91a7bad55bc6f62
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 21:25:07 2019 -0700
+
+    [iter] Adjust source_of/sink_of
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c0485e32a320e17dd0634b2cc8b4dd8c4fdc65e0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 21:03:14 2019 -0700
+
+    Use hb_void_t<> the way it's supposed to be used
+
+ src/hb-null.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 40fb36a39de5dd3ee9a4c84f1f76205b6bb68660
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 21:01:19 2019 -0700
+
+    [meta] Minor
+
+ src/hb-meta.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit f9a96a0a97f59a0b31ee0f901d1c21dde6b3cfaf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:56:16 2019 -0700
+
+    [meta] More rewrites
+
+ src/hb-meta.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 5252677e53ff4473701172bbbd4e953ac6b08e6f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:49:52 2019 -0700
+
+    [meta] Rewrite hb_int_min/max
+
+ src/hb-meta.hh | 44 ++++++++++++++++++++++----------------------
+ 1 file changed, 22 insertions(+), 22 deletions(-)
+
+commit caa3f92e91062ff78b657aec23569b099de48640
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:43:51 2019 -0700
+
+    [meta] void_tt -> void_t
+
+ src/hb-meta.hh | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+commit 7df3ecfb4069d275cd277c71165962bb5769364a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:43:26 2019 -0700
+
+    [meta] hb_void_t -> hb_empty_t
+
+ src/hb-debug.hh                |  6 +++---
+ src/hb-meta.hh                 |  2 +-
+ src/hb-ot-layout-gsub-table.hh |  2 +-
+ src/hb-ot-layout-gsubgpos.hh   | 18 +++++++++---------
+ 4 files changed, 14 insertions(+), 14 deletions(-)
+
+commit 149c3db8a2d41894b5d65f4c4b7c20757f6de6dd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:34:52 2019 -0700
+
+    [meta] Minor
+
+ src/hb-meta.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 707ff5b59d3903b60312a028f2ba5d74c18db101
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:31:20 2019 -0700
+
+    Minor
+
+ src/hb-meta.hh      | 5 -----
+ src/hb-open-type.hh | 2 +-
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+commit ce300f4fb68a25d46d165e8b0a4825482c83a966
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:26:29 2019 -0700
+
+    [meta] Rewrite is_signed, add is_unsigned
+
+ src/hb-meta.hh | 29 ++++++++++++-----------------
+ 1 file changed, 12 insertions(+), 17 deletions(-)
+
+commit e939d88bd72e0db0ebe357649b7a0fa3447c0bf4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:20:51 2019 -0700
+
+    [meta] Rewrite is_integral / is_floating_point, add is_arithmetic
+
+ src/hb-meta.hh | 49 +++++++++++++++++++++++++++++++------------------
+ 1 file changed, 31 insertions(+), 18 deletions(-)
+
+commit c3a456a26e8e5f8bc483b326f1928e9c603a7216
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:17:30 2019 -0700
+
+    [meta] Rewrite is_cr_convertible
+
+ src/hb-meta.hh | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+commit b4ad6af9c4ec30c462078bd93ae12653619c5fea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:15:03 2019 -0700
+
+    [meta] Rewrite is_base_of
+
+ src/hb-meta.hh | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+commit 5a171ed3a69313e10df6e42a03affb5e8bfe8e95
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:11:29 2019 -0700
+
+    [null] Modernize template work
+
+ src/hb-null.hh | 19 ++++++-------------
+ 1 file changed, 6 insertions(+), 13 deletions(-)
+
+commit 61d150c916d181cc3f333d0378108e08210370ad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:06:31 2019 -0700
+
+    [meta] Add integral_constant, true_t -> true_type, false_t -> false_type
+
+ src/hb-iter.hh | 20 ++++++++++----------
+ src/hb-meta.hh | 17 ++++++++---------
+ src/hb-null.hh |  4 ++--
+ 3 files changed, 20 insertions(+), 21 deletions(-)
+
+commit 38e3a8bd531ef3d35ca0fbcfad09db3f83345038
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 20:03:14 2019 -0700
+
+    [meta] bool_tt -> bool_constant
+
+ src/hb-meta.hh | 6 +++---
+ src/hb-null.hh | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 3919ca41b5e657764c7f75dfdc21cf8ca20bd66f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 19:56:36 2019 -0700
+
+    [meta] Add is_floating_point
+
+ src/hb-meta.hh | 33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+commit 25bb7e005d96c367731fd8d129d764d101b1200f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 19:49:26 2019 -0700
+
+    [meta] Add is_signed for floating point types
+
+ src/hb-meta.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit e0315b4aadb3fbc6b618de56d643471e8d1f7859
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 19:48:02 2019 -0700
+
+    [meta] is_integer -> is_integral
+
+ src/hb-algs.hh |  2 +-
+ src/hb-map.hh  |  4 ++--
+ src/hb-meta.hh | 26 +++++++++++++-------------
+ 3 files changed, 16 insertions(+), 16 deletions(-)
+
+commit 9574de7a3e763b9c5eacf65b4b8c148724c00b82
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 19:29:32 2019 -0700
+
+    [meta] Add add_const, add_pointer, add_lvalue_reference, add_rvalue_reference
+
+ src/hb-meta.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 2fb3a8327ab35248a0c7877c48422718cfbe375d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 18:40:29 2019 -0700
+
+    [vector] Simplify arrayZ
+    
+    Was turned into function when we had static ones and wanted to be
+    move-safe...  Not the case anymore.
+
+ src/hb-coretext.cc      |  2 +-
+ src/hb-ot-cff-common.hh |  2 +-
+ src/hb-uniscribe.cc     | 10 +++----
+ src/hb-vector.hh        | 71 ++++++++++++++++++++++---------------------------
+ 4 files changed, 39 insertions(+), 46 deletions(-)
+
+commit 4d67743ffd99ed9f2278ab21adfac7eb314c0df0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 16:35:31 2019 -0700
+
+    [subset] Use more auto typing
+
+ src/hb-ot-layout-common.hh     | 8 ++++----
+ src/hb-ot-layout-gdef-table.hh | 2 +-
+ src/hb-ot-layout-gsubgpos.hh   | 4 ++--
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+commit a27a31b9ee2601a05575cb581dc227caa73742c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 16:26:19 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2ade0086286963ae2c65d44b94e63cb3836ce36b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 16:21:03 2019 -0700
+
+    [serialize] More rewrite
+
+ src/hb-ot-layout-common.hh | 42 ++++++++++++++++++++++++------------------
+ 1 file changed, 24 insertions(+), 18 deletions(-)
+
+commit 99ed6e29d86bbf391c12ee1f980b8af9dc35615e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 16:07:51 2019 -0700
+
+    [serialize] Fix a TODO
+
+ src/hb-ot-layout-common.hh | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+commit d8a49b53e3676ad742bdb8edf0ec3ca6f7a7cac9
+Author: rsheeter <rsheeter at google.com>
+Date:   Fri May 10 16:52:43 2019 -0700
+
+    Update TESTING.md
+
+ TESTING.md | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+commit 25a5b287f220802728cd3312692f368c45d22862
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 16:01:39 2019 -0700
+
+    Fix sanitize fail of extension sublookups
+    
+    Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=960331
+
+ src/hb-ot-layout-common.hh                                 |  10 ++++++++--
+ src/hb-sanitize.hh                                         |   2 ++
+ ...uzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296 | Bin 0 -> 94 bytes
+ 3 files changed, 10 insertions(+), 2 deletions(-)
+
+commit 9c0c3589f31106d1898f8922cc9a2e18cb054989
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 13:56:50 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 5d773ec60029e1a6edec45c27ea918d9be4ea806
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 13:53:15 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ac737f8c9e7cbc81cdb5a0542a2494671f236895
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 13:51:12 2019 -0700
+
+    Minor again
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5d4437fad0f99508ebd5c026a3d927f5d649615e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 13:43:29 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit cd9bc732a75c716121a86e39ab588d2e0af58eba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 13:17:41 2019 -0700
+
+    [gsubgpos] Minor
+
+ src/hb-ot-layout-gsubgpos.hh | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+commit 6d63e27ca41b12ba2e8fb22fd6bc44417651c518
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 11:53:02 2019 -0700
+
+    Generate tarball in .xz instead of .bz2
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1662
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1d870cce68f7033f6d3967ce4e9ba622a6fafe79
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 11:32:59 2019 -0700
+
+    Fix bot
+    
+    Any way to catch these?
+
+ src/test-meta.cc | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit 30e4ae6bd19bf297b029205b5f86c1a0ae14943d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 11:26:39 2019 -0700
+
+    [meta] Add hb_is_base_of
+
+ src/hb-meta.hh   |  7 +++++++
+ src/test-meta.cc | 16 ++++++++++++++++
+ 2 files changed, 23 insertions(+)
+
+commit 98974ac16f5caf282c9c7cf0c417b494efd6af1d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 10 11:18:52 2019 -0700
+
+    [iter] Adjust is_source_of / is_sink_of
+    
+    There are two cases that we accept.  Encode both.
+
+ src/hb-iter.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 1b58bf22ca70908bb578910757795ee32d48b65a
+Author: rsheeter <rsheeter at google.com>
+Date:   Thu May 9 20:06:29 2019 -0700
+
+    Update TESTING.md
+
+ TESTING.md | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit ed972d5d73ba0592e1ba92426adf2a8f67acf9c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 16:58:28 2019 -0700
+
+    [iter] Rewrite test functions
+    
+    Notably, add hb_is_source_of(,) and hb_is_sink_of(,) to replace most
+    uses of hb_is_iterator_of(,).
+
+ src/hb-iter.hh             | 65 +++++++++++++++++++++++++++++-----------------
+ src/hb-open-type.hh        |  7 +++--
+ src/hb-ot-layout-common.hh |  6 ++---
+ src/hb-ot-name-table.hh    |  2 +-
+ src/test-iter.cc           |  2 +-
+ 5 files changed, 49 insertions(+), 33 deletions(-)
+
+commit 42901d7af91b4c5cffee9752f653447e4f4bd4f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 16:22:08 2019 -0700
+
+    Minor
+
+ src/hb-meta.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 322627ae1daa16f62f7a91c3c3ed02eb5b708ca5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 16:08:10 2019 -0700
+
+    Whitespace
+
+ src/hb-array.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 489f3c35bddb22cfe40c45d3a5c1cb6d88ccaf1f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 15:39:32 2019 -0700
+
+    Fix bot
+
+ src/test-meta.cc | 70 ++++++++++++++++++++++++++++----------------------------
+ 1 file changed, 35 insertions(+), 35 deletions(-)
+
+commit 790315e0dbc0ce796f0081a60953f74bd3fbdb63
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 15:31:24 2019 -0700
+
+    [algs] Implement implicit casting between compatible pair types
+
+ src/hb-algs.hh   | 5 +++++
+ src/test-algs.cc | 3 +++
+ 2 files changed, 8 insertions(+)
+
+commit 69d9114b5372c1fcea5f20e75a187158c31c52f8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 15:24:14 2019 -0700
+
+    [meta] Rewrite hb_is_cr_converitble
+
+ src/hb-meta.hh | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+commit ceda1f03b7b06248ffd056eb7b2400088bb4a121
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 15:19:42 2019 -0700
+
+    Fix compile
+    
+    NameRecord is not copy-constructible, so should be iterator of
+    const-reference.
+
+ src/hb-meta.hh          |  2 --
+ src/hb-ot-name-table.hh |  2 +-
+ src/test-meta.cc        | 12 ++++++++++++
+ 3 files changed, 13 insertions(+), 3 deletions(-)
+
+commit 3686c3b65c017cf8689b67db440b4cddd399538b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 15:09:07 2019 -0700
+
+    Adjust is_cr_convertible
+    
+    If To is const& then From doesn't need to be &.
+
+ src/hb-meta.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit 726002a6a615e2d213186d402cca4e8d7e7a7f58
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 14:53:02 2019 -0700
+
+    [iter] Make hb_is_iterator_of() check is_convertible
+    
+    Instead of is_cr_convertible.
+
+ src/hb-array.hh | 8 ++++----
+ src/hb-iter.hh  | 2 +-
+ src/hb-meta.hh  | 8 ++++----
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 70a49f2e4a9ab05fe04d1949bbf7a128d14a1284
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 14:35:15 2019 -0700
+
+    [meta] Add hb_conditional<> and hb_is_convertible()
+
+ src/Makefile.am  |  6 ++++-
+ src/hb-meta.hh   | 56 +++++++++++++++++++++++++++++++++++++--------
+ src/test-meta.cc | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 121 insertions(+), 11 deletions(-)
+
+commit 5e3cbed048b19ee579277ab4c56167a15d13104e
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed May 8 16:33:03 2019 -0700
+
+    [subset] Switch building of glyph maps in subset plan to use iterators.
+
+ src/hb-algs.hh        |  4 +---
+ src/hb-subset-plan.cc | 52 +++++++++++++++++++++++++--------------------------
+ 2 files changed, 27 insertions(+), 29 deletions(-)
+
+commit 971020eca7c5d576816b93431607f1e63e9584a4
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed May 8 16:31:52 2019 -0700
+
+    Add sink support for hb_hashmap_t and a reverse call to hb_pair_t.
+
+ src/hb-algs.hh | 5 +++++
+ src/hb-map.hh  | 4 ++++
+ 2 files changed, 9 insertions(+)
+
+commit 98eec3dd5f527cc562d98784429db0c7269e82a8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 13:15:36 2019 -0700
+
+    Add hb_pair_t(,) macro as alternative to hb_pair_t<,>
+    
+    Just so it's easier to use it in other macros.
+
+ src/hb-algs.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c9b287a867d6130a0cc745d7fd3ccfa4dcb4c32e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 12:43:57 2019 -0700
+
+    Add hb_lidentity(), and rename hb_rvalue() to hb_ridentity()
+
+ src/hb-algs.hh   | 13 ++++++++++++-
+ src/hb-map.hh    |  4 ++--
+ src/test-iter.cc |  2 +-
+ 3 files changed, 15 insertions(+), 4 deletions(-)
+
+commit 00195a22ce5198345cb39825a45863cef7d8f7fc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 12:14:36 2019 -0700
+
+    [hdmx] Adjust to hb_iota() behavior change
+    
+    Use hb_range() instead.
+
+ src/hb-ot-hdmx-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4f2ad75a839708de71e7341f23c2d4b72059fc58
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 12:07:45 2019 -0700
+
+    [enumerate] Fix hb_enumerate() len for step=0
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5da3c9c33f02010a3fc57cf0e1d07955af681e7c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:30:31 2019 -0700
+
+    [iter] Fix hb_zip() end condition
+    
+    We should compare-equal to end if either iterator's end reaches,
+    not if both reach at the same time.  Fixes infinite-loop in test
+    which was happening after hb_enumerate() switched to using hb_zip().
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 57a5256fbcef6e5d29fc40cf019cc4b2c29c9dcf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:30:27 2019 -0700
+
+    [iter] Minor
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 12dd56f8573cb86169580d5ac31b986208805c03
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:25:02 2019 -0700
+
+    [iter] Minor
+
+ src/hb-iter.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 57d545932f539d06c52862310ecdfe79c143bb6b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:23:41 2019 -0700
+
+    [test-iter] Don't walk past end
+    
+    That's not legal.
+
+ src/test-iter.cc | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 46837910e628248edc09e45e212532a3493905da
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:20:41 2019 -0700
+
+    [iter] Allow negative step in hb_iota()
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 087327af1eac8c3a16115904557cbf3ab0f28072
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:14:06 2019 -0700
+
+    [iter] Minor
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 64f0899a9f5e5aff65c5a78fa796ceae6f35c008
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:10:31 2019 -0700
+
+    [iter] Bug fix
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5d263556b95047bced88e4a6252178d2fc0f9a19
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:08:25 2019 -0700
+
+    [iter] Fix
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2c24ea37b1ef63f79fcc24752dd180ce53540eda
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:07:38 2019 -0700
+
+    [iter] Take start value in hb_enumerate()
+    
+    Also rewrite it via composition.
+
+ src/hb-iter.hh   | 61 ++++++++++++--------------------------------------------
+ src/test-iter.cc |  1 +
+ 2 files changed, 14 insertions(+), 48 deletions(-)
+
+commit 7675d0d3a6cc13ade1a2047019ef7fac8c373a3c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:02:56 2019 -0700
+
+    [iter] Add hb_range()
+    
+    hb_range() is like Python range.  hb_iota() has slightly different API.
+    Ie. it takes a start, instead of end.
+
+ src/hb-iter.hh   | 29 ++++++++++++++++++-----------
+ src/test-iter.cc | 19 +++++++++++--------
+ 2 files changed, 29 insertions(+), 19 deletions(-)
+
+commit 05867d9f5315c7e4f49e5873a5aba6bba7121f04
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 11:00:43 2019 -0700
+
+    [meta] Add hb_int_max()
+
+ src/hb-meta.hh | 91 ++++++++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 56 insertions(+), 35 deletions(-)
+
+commit 71537f93e0ce27121012bf1e81270b6b03b22224
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 9 10:46:49 2019 -0700
+
+    [iota] end -> end_ to not shadow
+
+ src/hb-iter.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 6bc82579100992e3f04c11f36b9c2f0014d880f2
+Merge: 34764454 6d9a86ae
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Thu May 9 14:39:05 2019 +0100
+
+    Merge pull request #1680 from n8willis/usermanual-obj
+    
+    Usermanual: object-model chapter
+
+commit 3476445420d0e6432c09710b6667205453799129
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 21:14:01 2019 -0700
+
+    Remove unnecessary template keyword
+    
+    Should fix MSVC.
+
+ src/hb-array.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e2a51ff7264940312197184318f5ad4ec971492f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 16:41:39 2019 -0700
+
+    Remove unused var
+
+ src/hb-open-type.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit e8b45c19330d8718cd6d7aef0ca2db0539a53294
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 16:37:38 2019 -0700
+
+    [array] Add .copy()
+
+ src/hb-array.hh     | 11 +++++++++++
+ src/hb-open-type.hh | 10 ++++------
+ src/hb-serialize.hh |  2 +-
+ 3 files changed, 16 insertions(+), 7 deletions(-)
+
+commit afb013f350b0022ae6c05f140aeba23d5de34101
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 16:16:43 2019 -0700
+
+    Fix msan issue
+    
+    hb_identity returns rvalue-reference if input is rvalue.  That, can leak
+    the reference and cause in bad access to temporaries after they are
+    destructed.  This is unfortunately unfixable given the desired
+    transparency of hb_identity :(.  Just don't use it with hb_map().
+
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c94bc63d914fac7e11940eb165b6cf1039ba5a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 15:57:33 2019 -0700
+
+    Move hb_invoke() back to hb-algs.hh
+
+ src/hb-algs.hh | 32 ++++++++++++++++++++++++++++++++
+ src/hb-meta.hh | 32 --------------------------------
+ 2 files changed, 32 insertions(+), 32 deletions(-)
+
+commit b710176ce28e863a01797987d7ce37d19aaf2fd3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 15:46:51 2019 -0700
+
+    [hdmx] Touch up
+
+ src/hb-ot-hdmx-table.hh | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+commit e8ef0e627c493af700e254bdd2767f8955f2d03f
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue May 7 17:23:02 2019 -0700
+
+    [subset] WIP convert hdmx subsetting to use iterators.
+
+ src/hb-ot-hdmx-table.hh     | 121 +++++++++++++++++++-------------------------
+ test/api/test-subset-hdmx.c |  23 ---------
+ 2 files changed, 51 insertions(+), 93 deletions(-)
+
+commit d5decf9bf77db914b67ffc446379df621516e362
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue May 7 15:47:38 2019 -0700
+
+    [subset] Move hdmx to subset2.
+
+ src/hb-ot-hdmx-table.hh | 36 ++++++------------------------------
+ src/hb-subset.cc        |  2 +-
+ 2 files changed, 7 insertions(+), 31 deletions(-)
+
+commit 27b2093009745b6c30663605f45ac95deb1562cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 15:32:57 2019 -0700
+
+    [map] Return rvalues from keys()/values()
+
+ src/hb-algs.hh | 7 +++++++
+ src/hb-map.hh  | 2 ++
+ 2 files changed, 9 insertions(+)
+
+commit 372c5b97bfa3b744de1d017cf662607eb8a2fa6e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 15:28:39 2019 -0700
+
+    [map] Fix bots
+    
+    Older compilers don't like calling iter() from return-type decltype()
+    
+    ../src/hb-map.hh:226:12: error: cannot call member function 'decltype ((((+ hb_array(((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::items, (((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::mask ? (((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::mask + 1) : 0))) | hb_filter((& hb_hashmap_t<K, V, kINVALID, vINVALID>::item_t:: is_real))) | hb_map((& hb_hashmap_t<K, V, kINVALID, vINVALID>::item_t:: get_pair)))) hb_hashmap_t<K, V, kINVALID, vINVALID>::iter() const [with K = const hb_serialize_context_t::object_t*; V = unsigned int; K kINVALID = 0u; V vINVALID = 0u; decltype ((((+ hb_array(((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::items, (((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::mask ? (((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::mask + 1) : 0))) | hb_filter((& hb_hashmap_t<K, V, kINVALID, vINVALID>::item_t:: is_real))) | hb_map((& hb_hashmap_t<K, V, kINVALID, vINVALID>::item_t:: get_pair)))) = hb_map_iter_t<hb_filter_iter_t<hb_array_t<hb_hashmap_t<const hb_serialize_context_t::object_t*, unsigned int, 0u, 0u>::item_t>, bool (hb_hashmap_t<const hb_serialize_context_t::object_t*, unsigned int, 0u, 0u>::item_t::*)() const, const<anonymous struct>&, 0u>, hb_pair_t<const hb_serialize_context_t::object_t*, unsigned int> (hb_hashmap_t<const hb_serialize_context_t::object_t*, unsigned int, 0u, 0u>::item_t::*)() const, 0u>]' without object
+         + iter()
+                ^
+    ../src/hb-meta.hh:58:41: note: in definition of macro 'HB_AUTO_RETURN'
+     #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
+                                             ^
+
+ src/hb-map.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit a30482718491e3455365167e1c85981c8c0f542b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 15:08:10 2019 -0700
+
+    [map] Add .values() iterator
+
+ src/hb-map.hh    | 6 +++++-
+ src/test-iter.cc | 8 ++++++++
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+commit 3c69505b3a7850b68a931849a2badb84b6b36d51
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 15:05:10 2019 -0700
+
+    [map] Fix iter
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5ceaafa5de8dff51fe91f7008a12ec9c304a1376
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 14:59:25 2019 -0700
+
+    [algs] Fix identity return type
+
+ src/hb-algs.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit f5705d7656817cbfdbc4479b1cb0be3af6f4abdf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 14:46:55 2019 -0700
+
+    Whitespace
+
+ src/hb-map.hh    | 10 +++++-----
+ src/test-iter.cc | 11 +++++++----
+ 2 files changed, 12 insertions(+), 9 deletions(-)
+
+commit a17f0fa3a10a25959561582ae63ef2e5208647e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 14:44:11 2019 -0700
+
+    [meta] Capture rvalue-references in is_reference / remove_reference
+
+ src/hb-meta.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 7166bd563447a64eda05c66668bd4a178292bd79
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 14:24:57 2019 -0700
+
+    Minor
+
+ src/hb-open-type.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit b827181ba1f539c990e1bd8fdd3559f1589c8d28
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 13:51:11 2019 -0700
+
+    [map] tweak test-iter.cc
+
+ src/hb-map.hh    | 1 -
+ src/test-iter.cc | 2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+commit 492af0f1bf1d7198b474fda2faca451908af267f
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 12:47:18 2019 -0700
+
+    [map] add keys()
+
+ src/hb-map.hh    | 9 ++++++++-
+ src/test-iter.cc | 4 ++++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+commit ba60512813caafc2006b26214e95bbfe1c0e460a
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 12:09:10 2019 -0700
+
+    [map] add a test for iteration
+
+ src/hb-map.hh    | 2 +-
+ src/test-iter.cc | 4 ++++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 183b8094b577dcb7f40b7fcd64b60d405845897a
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 11:40:31 2019 -0700
+
+    [map] add iteration
+
+ src/hb-map.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit df237d2fe78086ad16bdbd2cc60639ae9ce909d6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed May 8 14:17:14 2019 -0700
+
+    [test] Add https://crbug.com/oss-fuzz/14641 testcase
+    
+    As 503748d fix
+
+ ...-testcase-minimized-hb-subset-fuzzer-5676773460672512 | Bin 0 -> 2172 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 02ae2591d930563cec8c3c63086afb0a3a12c4aa
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed May 8 13:44:03 2019 -0700
+
+    initialize return param subr_num in popSubrNum
+    
+    also snake_cased popSubrtNum and other surrounding function names
+
+ src/hb-cff-interp-cs-common.hh | 15 ++++++++-------
+ src/hb-subset-cff1.cc          |  4 ++--
+ src/hb-subset-cff2.cc          |  4 ++--
+ 3 files changed, 12 insertions(+), 11 deletions(-)
+
+commit 503748d8a80dd5db450c8c4dc109f2b97049d989
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 12:45:02 2019 -0700
+
+    [name] Sanitize records for reals
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14641
+
+ src/hb-ot-name-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5875d775e1253c0e14b900539c28c2de881da7aa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 12:25:34 2019 -0700
+
+    [iter] Rename hb_iter_t() to hb_iter_type<> and add hb_item_type<>
+
+ src/hb-iter.hh | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+commit bad16066392e4dbdd8490a4b1c70d1dcddcc8ec8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 12:11:52 2019 -0700
+
+    [map] Make .has() optionally return value
+
+ src/hb-map.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 750d5af48e38627c3c84a2f3857a7ee602221e24
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 12:01:55 2019 -0700
+
+    Make compiler happy with -Og
+
+ src/hb-cff-interp-cs-common.hh | 2 +-
+ src/hb-ot-cmap-table.hh        | 6 +++---
+ src/hb-ot-glyf-table.hh        | 2 +-
+ src/hb-subset-glyf.cc          | 4 ++--
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+commit cdb61eb0431d426f7152f975e89ee3ba4431083f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 11:00:18 2019 -0700
+
+    [iter] Accept pointer in hb_iter() and hb_iter_t()
+
+ src/hb-iter.hh   | 4 ++--
+ src/test-iter.cc | 3 +++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+commit c93eeba9b21cb8f8ba64ebaf284bf9c8a8544886
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 10:56:09 2019 -0700
+
+    [iter] Accept pointer in hb_map()
+
+ src/hb-iter.hh   | 4 ++--
+ src/test-iter.cc | 7 ++++++-
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+commit 4c9e0c37a34e8355d752af39507b310f473bffa5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 10:40:39 2019 -0700
+
+    [serialize] LangSys subset->copy
+
+ src/hb-ot-layout-common.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 50dc3e7d9f4f290c7353313c5e5f888cb7c4846d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 10:35:02 2019 -0700
+
+    Add hb_iota()
+
+ src/hb-iter.hh   | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/test-iter.cc | 10 ++++++++++
+ 2 files changed, 61 insertions(+)
+
+commit aa4ac13f0be34bba66b00d04fd7806c474ff59c0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 10:02:30 2019 -0700
+
+    [iter] Actually fix previous commit
+    
+    The iter objects shouldn't not be const.  D'oh.
+
+ src/hb-iter.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit a66598e0306fe80063c5d6a678bbca4a931bc4d4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 09:56:29 2019 -0700
+
+    [iter] For ref-qualified variants
+
+ src/hb-iter.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit fa576ce1874fd886688bf3f16b714d86aebb07ec
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 09:53:58 2019 -0700
+
+    Update README.md
+
+ README.md | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit d109c9e767ff3198d51e23a7ac8931d0bc4d5d72
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 09:53:29 2019 -0700
+
+    Update README.md
+
+ README.md | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 4063181791d6b3efb35e7c748dee12273e64ebd4
+Author: rsheeter <rsheeter at google.com>
+Date:   Wed May 8 09:47:34 2019 -0700
+
+    [docs] add fuzzer instructions (courtesy of Garret)
+
+ TESTING.md | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 00946ca3aa45f109c455871ce89c5872fd243624
+Author: Roderick Sheeter <rsheeter at rsheeter-macbookpro2.roam.corp.google.com>
+Date:   Wed May 8 09:42:35 2019 -0700
+
+    [docs] add sample commands for test exec
+
+ README.md  |  4 ++++
+ TESTING.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+)
+
+commit 8479eb5955c93cbc8951d0319b2fe43ff19cc403
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 09:48:55 2019 -0700
+
+    [iter] Fix hb_sink() to accept rvalue
+
+ src/hb-iter.hh   | 2 +-
+ src/test-iter.cc | 4 ++++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 710d459acac88fd784d4ead0ba75b9aa623c48d4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 09:33:09 2019 -0700
+
+    [iter] Default predicates to hb_identity instead of hb_bool
+    
+    The bool conversion happens after predicate is called automatically.
+
+ src/hb-iter.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit fe14a4000a58528878bcc75fde0972de2b779316
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 09:32:19 2019 -0700
+
+    Adjust hb_all/any/none
+
+ src/hb-iter.hh   | 18 +++++++++---------
+ src/test-iter.cc | 10 ++++++----
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+commit 4a101d8ffccd6f907f16ef190125ded5e27e0d8b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 09:16:33 2019 -0700
+
+    Add hb_match
+
+ src/hb-algs.hh | 30 +++++++++++++++++++++++++++++-
+ 1 file changed, 29 insertions(+), 1 deletion(-)
+
+commit 26adefd9eaf4bc1d80b1ffececf0d86f3308f9ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 09:14:44 2019 -0700
+
+    [algs] Try f[v] in hb_get() as last resort
+
+ src/hb-algs.hh | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+commit 0601a19d38b2b0fc5dd36fd821af634a49322ebf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed May 8 07:47:36 2019 -0700
+
+    Fix a few more double-pomotion errors
+
+ src/hb-coretext.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 2ba984fcbbef4561d35c3a2c502610c38b26f4fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 23:28:22 2019 -0700
+
+    Fix signed comparison on 32bit
+
+ src/hb-sanitize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dfc57802450360f06026668b7b61495aaa2d1943
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 23:26:09 2019 -0700
+
+    Fix more double-promotion errors
+    
+    WHy do only some of the clang bots catch this I have no idea :(.
+
+ src/hb-aat-layout-trak-table.hh |  4 ++--
+ src/hb-font.hh                  |  2 +-
+ src/hb-open-type.hh             |  4 ++--
+ src/hb-ot-color-cbdt-table.hh   | 12 ++++++------
+ src/hb-ot-color-sbix-table.hh   | 10 +++++-----
+ src/hb-ot-layout-gpos-table.hh  | 20 ++++++++++----------
+ 6 files changed, 26 insertions(+), 26 deletions(-)
+
+commit c2c9d204fa5c2189e369726276a1c0e92e09a9ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 23:13:38 2019 -0700
+
+    Fix double-promotion warnings
+    
+    Make it an error.
+
+ src/hb-ot-var-fvar-table.hh | 12 ++++++------
+ src/hb.hh                   |  1 +
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+commit 2c7093ed01f417828d5521d983eae63042363197
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 23:10:59 2019 -0700
+
+    More tests
+
+ src/test-algs.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 56d2d0294b836ea1e2dea9e242ae72c99387d00a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 23:08:49 2019 -0700
+
+    [algs] Sprinkle hb_min/max with hb-forward salad
+    
+    Let's see if fixes MSVC fail.  Though, the error doesn't make sense to me.
+    
+      hb-blob.cc
+    c:\projects\harfbuzz\src\hb-algs.hh(166): error C2440: 'return': cannot convert from 'unsigned int' to 'unsigned int &&' [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+      c:\projects\harfbuzz\src\hb-algs.hh(166): note: You cannot bind an lvalue to an rvalue reference
+      c:\projects\harfbuzz\src\hb-algs.hh(174): note: see reference to function template instantiation 'T &&<unnamed-type-hb_min>::impl<T,unsigned int&>(T &&,T2) const' being compiled
+              with
+              [
+                  T=unsigned int,
+                  T2=unsigned int &
+              ]
+
+ src/hb-algs.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit bdbfdc92b58d5c9f8654e430075dab543d1ba394
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 22:52:43 2019 -0700
+
+    [iter] Add value and projection to hb_all/any/none
+    
+    Allows for eg, checking all values equal 2: hb_all (it, 2).
+
+ src/hb-iter.hh   | 24 ++++++++++++++++++------
+ src/test-iter.cc | 10 +++++++++-
+ 2 files changed, 27 insertions(+), 7 deletions(-)
+
+commit cf61acb9eaa2bb3fe479a9050116b4b96934e3ed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 22:45:01 2019 -0700
+
+    [iter] Accept rvalues to hb_enumerate()
+
+ src/hb-iter.hh   | 2 +-
+ src/test-iter.cc | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit e8bd5fc3fa2cc5c5f8f254629553902aed3496ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 22:29:40 2019 -0700
+
+    [meta] Move hb_invoke from algs to meta
+
+ src/hb-algs.hh | 31 -------------------------------
+ src/hb-meta.hh | 32 ++++++++++++++++++++++++++++++++
+ 2 files changed, 32 insertions(+), 31 deletions(-)
+
+commit af571dbffc12e6bb7a3146762d12bb4ac3f19bdc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 21:39:20 2019 -0700
+
+    [meta] Replace most hb_enable_if with hb_requires
+    
+    They do absolutely same thing.  hb_requires is to encode constraints,
+    whereas hb_enable_if is for more conditional enabling.
+
+ src/hb-iter.hh             | 63 +++++++++++++++++++++-------------------------
+ src/hb-open-type.hh        |  6 ++---
+ src/hb-ot-layout-common.hh |  6 ++---
+ src/test-iter.cc           |  6 ++---
+ 4 files changed, 37 insertions(+), 44 deletions(-)
+
+commit 6fa1f38070e710b2f80a836bd633b6ab33e1bc80
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 21:33:26 2019 -0700
+
+    [algs] Accept varargs in hb_min/max
+
+ src/hb-algs.hh   | 24 +++++++++++++++++++++---
+ src/test-algs.cc |  8 ++++++++
+ 2 files changed, 29 insertions(+), 3 deletions(-)
+
+commit 1ad07080c3ea7f6a1b3cb247529ec0c78575a6d3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 21:00:23 2019 -0700
+
+    Rename
+
+ src/hb-algs.hh | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+commit 83e3eabd84e2b53c696768d1357a6a259bcd3576
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 20:58:43 2019 -0700
+
+    Whitespace
+
+ src/hb-aat-layout-common.hh     |  2 +-
+ src/hb-aat-layout-kerx-table.hh |  2 +-
+ src/hb-aat-layout-morx-table.hh |  2 +-
+ src/hb-algs.hh                  |  6 +++---
+ src/hb-dispatch.hh              |  2 +-
+ src/hb-open-type.hh             | 18 +++++++++---------
+ src/hb-ot-kern-table.hh         |  4 ++--
+ src/hb-ot-layout-common.hh      |  2 +-
+ src/hb-ot-layout-gpos-table.hh  | 16 ++++++++--------
+ src/hb-ot-layout-gsub-table.hh  | 14 +++++++-------
+ src/hb-ot-layout-gsubgpos.hh    |  8 ++++----
+ src/hb-sanitize.hh              |  6 +++---
+ src/hb-serialize.hh             | 12 ++++++------
+ src/hb-subset.hh                |  6 +++---
+ 14 files changed, 50 insertions(+), 50 deletions(-)
+
+commit 2b9402a86a4e37e6386f8028bdf3789ae262a4c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 20:55:33 2019 -0700
+
+    Use universal references in hb_min/max
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 41248cce0e32653227a83eb4e42ccf793f040fc2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 20:54:31 2019 -0700
+
+    Remove MIN/MAX in favor of hb_min/hb_max
+
+ src/hb-aat-layout-common.hh      |  8 ++++----
+ src/hb-aat-layout-feat-table.hh  |  2 +-
+ src/hb-aat-layout-kerx-table.hh  |  2 +-
+ src/hb-aat-layout-morx-table.hh  | 18 +++++++++---------
+ src/hb-algs.hh                   | 14 +++++---------
+ src/hb-array.hh                  |  4 ++--
+ src/hb-blob.cc                   |  2 +-
+ src/hb-buffer-serialize.cc       | 32 ++++++++++++++++----------------
+ src/hb-buffer.cc                 |  4 ++--
+ src/hb-buffer.hh                 |  2 +-
+ src/hb-common.cc                 | 20 ++++++++++----------
+ src/hb-coretext.cc               |  6 +++---
+ src/hb-debug.hh                  |  2 +-
+ src/hb-directwrite.cc            |  2 +-
+ src/hb-ft.cc                     |  2 +-
+ src/hb-iter.hh                   |  2 +-
+ src/hb-open-file.hh              |  2 +-
+ src/hb-open-type.hh              |  2 +-
+ src/hb-ot-cmap-table.hh          |  8 ++++----
+ src/hb-ot-color-cbdt-table.hh    |  6 +++---
+ src/hb-ot-color-cpal-table.hh    |  2 +-
+ src/hb-ot-color-sbix-table.hh    |  2 +-
+ src/hb-ot-glyf-table.hh          | 14 +++++++-------
+ src/hb-ot-hmtx-table.hh          |  2 +-
+ src/hb-ot-layout-gpos-table.hh   |  2 +-
+ src/hb-ot-layout-gsub-table.hh   |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh     |  6 +++---
+ src/hb-ot-layout.cc              |  2 +-
+ src/hb-ot-map.cc                 |  8 ++++----
+ src/hb-ot-post-table.hh          |  2 +-
+ src/hb-ot-shape-complex-indic.cc |  8 ++++----
+ src/hb-ot-shape-complex-use.cc   |  2 +-
+ src/hb-ot-shape.cc               |  4 ++--
+ src/hb-ot-tag.cc                 |  2 +-
+ src/hb-ot-var-avar-table.hh      |  2 +-
+ src/hb-ot-var-fvar-table.hh      | 18 +++++++++---------
+ src/hb-sanitize.hh               |  4 ++--
+ src/hb-uniscribe.cc              |  2 +-
+ 38 files changed, 111 insertions(+), 115 deletions(-)
+
+commit 5c0f62adc969696b46c1ceb57cd3c2fa408eb94f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 17:23:46 2019 -0700
+
+    [serializer] Accept pointer & reference in more methods
+
+ src/hb-serialize.hh | 39 ++++++++++++++++++++++++---------------
+ 1 file changed, 24 insertions(+), 15 deletions(-)
+
+commit 839618de3b3da285e8753b6ca6d767e9a483bfde
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 17:21:27 2019 -0700
+
+    [serializer] Minor
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 035b818e34bbd2d5c1f65328c9847c845d74d919
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 17:21:18 2019 -0700
+
+    [meta] Fix addressof()
+
+ src/hb-meta.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7654ebe3a51c98b4d3bf6fb11779024f1c770962
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 16:53:03 2019 -0700
+
+    Whitespace
+
+ src/hb-algs.hh | 30 ++++++++++++++++++++----------
+ src/hb-iter.hh | 39 ++++++++++++++++++++++++++-------------
+ src/hb-meta.hh | 11 ++++++-----
+ 3 files changed, 52 insertions(+), 28 deletions(-)
+
+commit 95426ea983bde01fadf4681926cb77e3b3c0d40a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 15:56:51 2019 -0700
+
+    Add comment
+
+ src/hb-open-type.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit e33ad252222481a6078a8bb423505e713b081313
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 15:46:24 2019 -0700
+
+    [serialize] FeatureVariations subset->copy
+
+ src/hb-ot-layout-common.hh   | 6 +++---
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit fa8c4ba81175f671c3f39f1586d0a1d9067d9f89
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 14:26:03 2019 -0700
+
+    Minor
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c09d6c58e99dba50f29a569e4c53916b5b507ef1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 14:09:00 2019 -0700
+
+    [iter] Require lvalue in operators that return reference
+
+ src/hb-iter.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 52f6c04c1e0eab2aaa0c7d817b212c01ba993fe9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 13:45:48 2019 -0700
+
+    Minor
+
+ src/hb-serialize.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 7c037bd2be2e794dfd882b806f684ad74c56dbb8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 13:37:43 2019 -0700
+
+    [name] Clean up some more
+
+ src/hb-meta.hh          |  2 ++
+ src/hb-ot-name-table.hh | 30 ++++++++++++++----------------
+ 2 files changed, 16 insertions(+), 16 deletions(-)
+
+commit f982b9d9f8d6b61efd2a3e89cc3d34923c1914b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 13:29:01 2019 -0700
+
+    [name] Clean up serialize() API
+
+ src/hb-ot-name-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 59ee61fddc76cd18f19f351bca7dd293eb610333
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 13:26:15 2019 -0700
+
+    [name] Use iterators more
+
+ src/hb-ot-name-table.hh | 46 +++++++++++++++-------------------------------
+ src/hb-subset-plan.cc   |  3 +++
+ 2 files changed, 18 insertions(+), 31 deletions(-)
+
+commit 2eb7e0e0e923d096d2598133cacd6e5ee04a6a04
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 12:45:38 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-serialize.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 1c81cff2d3f9df2c18ffbdfff02ed418560480c1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 11:51:10 2019 -0700
+
+    Fix signed-comparison error on 32bit
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 938de315756e08bd2b5fa816c7951640e5835b2e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 11:47:02 2019 -0700
+
+    Comment
+
+ src/hb-subset-glyf.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 159fe962e90dd3b758ad10046b9d75cf87c1d4f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 11:46:11 2019 -0700
+
+    [doc] Make header search more resilient
+    
+    How stupid to scan all files... Sigh.
+
+ docs/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9b05db33b54e6e5f0b4658f4c06e7fe563f8923b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 11:39:44 2019 -0700
+
+    [ragel] Regenerate ragel-generated files using ragel 7.0.0.11 May 2018
+
+ src/hb-buffer-deserialize-json.hh          | 1051 +++++------
+ src/hb-buffer-deserialize-text.hh          | 1009 +++++------
+ src/hb-ot-shape-complex-indic-machine.hh   | 2678 ++++++++++++++++------------
+ src/hb-ot-shape-complex-khmer-machine.hh   |  709 ++++----
+ src/hb-ot-shape-complex-myanmar-machine.hh |  820 +++++----
+ src/hb-ot-shape-complex-use-machine.hh     | 1144 ++++++------
+ 6 files changed, 3959 insertions(+), 3452 deletions(-)
+
+commit 521262b236dacf7b2b64e0a1d3c79d6a10b07063
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 11:08:08 2019 -0700
+
+    [subset] Add TODO
+
+ src/hb-subset.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit e6a622b5b202533d64f83e71d7ff8a8104d46e26
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 11:06:43 2019 -0700
+
+    [serialize] Enable bias assertion
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 530ddbbc320bd24b4902ee6d49bf80242a591794
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 11:05:51 2019 -0700
+
+    [serialize] Use range-based loop
+
+ src/hb-serialize.hh | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+commit 0987c4204fae66f80224c6f01d9c5dc3abe809e0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 11:01:02 2019 -0700
+
+    [name] Remove dead code
+
+ src/hb-ot-name-table.hh | 88 +------------------------------------------------
+ 1 file changed, 1 insertion(+), 87 deletions(-)
+
+commit 5ac4ab686809be9352e91bc3213e1edf3ba66a93
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:29:07 2019 -0700
+
+    [subset] fix for name table serializing with new serializer machinery
+
+ src/hb-ot-name-table.hh            |   8 ++++++--
+ test/api/fonts/nameID.expected.ttf | Bin 170696 -> 2388 bytes
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit c548fcedc404c03442c042059a71194d97d23bb6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:29:07 2019 -0700
+
+    [WIP] [name] Port to fancy serializer machinery
+
+ src/hb-ot-name-table.hh | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+commit fa2d97161f8b7de3d7a70e06d41b6f7e154012ad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 00:34:50 2019 -0700
+
+    Remove use of deprecated implicit copy/move assignment operators
+    
+    By removing custom copy constructor.
+
+ src/hb-meta.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 45f5e56236912359d0ac72310dcdba9259cfee66
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 00:33:32 2019 -0700
+
+    Warn on -Wdeprecated
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c3e0eafc80481f8c16516fdae1841c563e7253d4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue May 7 12:04:00 2019 +0430
+
+    [ci] Upgrade Ubuntu 17.10 bots to 19.04
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 8903040fcd09e7d7ad5112ac2a583718bb85795d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 00:13:11 2019 -0700
+
+    Actually make it work
+
+ src/hb-iter.hh | 2 ++
+ src/hb-meta.hh | 6 ++++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit 025eaa3c81214cdb20f2f588bab665512d21507c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 00:05:37 2019 -0700
+
+    [iter] Make filter/map copyable
+
+ src/hb-iter.hh   | 18 +++++++++---------
+ src/test-iter.cc |  4 ++--
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+commit 03a68165d8296ed5cc0eb2434500381419409e79
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue May 7 00:03:35 2019 -0700
+
+    [meta] Add hb_reference_wrapper<>
+    
+    Functionality kinda superset of std:: counterpart.
+
+ src/hb-meta.hh | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+commit 0bf86d9c5dcb0de206b38c3cf1824d2254376f37
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 6 23:39:26 2019 -0700
+
+    Whitespace
+
+ src/hb-meta.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 72eb91deb9eb7a08e38e100a3234518651fe4cb8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 6 23:39:13 2019 -0700
+
+    Add hb_ref()
+    
+    Unused.
+
+ src/hb-meta.hh | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 240f57e58d3b0161feb90621d5db9e2fc4d99b27
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 6 23:17:39 2019 -0700
+
+    Rename hb_deref_pointer() to hb_deref()
+
+ src/hb-algs.hh      | 12 ++++++------
+ src/hb-map.hh       |  2 +-
+ src/hb-meta.hh      |  2 +-
+ src/hb-serialize.hh |  2 +-
+ 4 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 0b1ca5a13b6921cb4d00f8651bb99fc7c7037ec2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 6 23:04:32 2019 -0700
+
+    [iter] Adjust hb_filter
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c2fd05ca5fa34303b986c34948b512d770ab8fe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 6 19:57:15 2019 -0700
+
+    [iter] Implement range-based for loops
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1648
+
+ src/hb-array.hh            |  6 ++++
+ src/hb-iter.hh             | 74 ++++++++++++++++++++++++++++++++++++++++++++--
+ src/hb-ot-layout-common.hh | 14 +++++++++
+ src/hb-set.hh              |  3 ++
+ src/test-iter.cc           | 28 ++++++++++++++----
+ 5 files changed, 118 insertions(+), 7 deletions(-)
+
+commit e261dc3a4043230ae1b4f56e2cc7d3133b7da4ca
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue May 7 01:24:55 2019 +0430
+
+    Ignore -Wc++11-compat as we require C++11 actually
+    
+    pollutes gcc bots logs https://circleci.com/gh/harfbuzz/harfbuzz/85395
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 9f9890e9e82c620e733d123f421f7c63d91ce8e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon May 6 12:16:51 2019 -0700
+
+    Remove HB_NO_OPTIONS in favor of HB_NO_GETENV
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-debug.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 36bb24f7b4dbbe171b945639bac749c46785e17c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 5 10:14:17 2019 -0700
+
+    [dispatch] Forward arguments in all dispatch multiplexers
+
+ src/hb-aat-layout-kerx-table.hh | 14 ++++-----
+ src/hb-aat-layout-morx-table.hh | 14 ++++-----
+ src/hb-ot-kern-table.hh         | 16 +++++-----
+ src/hb-ot-layout-common.hh      |  6 ++--
+ src/hb-ot-layout-gpos-table.hh  | 68 ++++++++++++++++++++---------------------
+ src/hb-ot-layout-gsub-table.hh  | 58 +++++++++++++++++------------------
+ src/hb-ot-layout-gsubgpos.hh    | 32 +++++++++----------
+ 7 files changed, 104 insertions(+), 104 deletions(-)
+
+commit c14efb8e68e31fb7537bcfe5eea779c0830a0b0c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 5 09:54:58 2019 -0700
+
+    Fix previous commit
+    
+    Priority should be given to specific over dispatch.  Broke sanitize before.
+    This fixes it, by moving prioritization to the context implementation, since
+    the correct priority cannot be done in the dispatch implementation.  Done
+    for subset and sanitize only, which need it.
+
+ src/hb-aat-layout-common.hh  |  2 +-
+ src/hb-dispatch.hh           | 10 +---------
+ src/hb-ot-layout-gsubgpos.hh | 14 +++++++-------
+ src/hb-sanitize.hh           | 16 +++++++++++++---
+ src/hb-subset.hh             | 15 ++++++++++++---
+ 5 files changed, 34 insertions(+), 23 deletions(-)
+
+commit b10f65933a77434bf8d68058793037f38a8ed5a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 5 09:23:35 2019 -0700
+
+    [dispatch] Use functionality from previous commit
+    
+    To remove a couple of unwanted wrapper methods
+
+ src/hb-dispatch.hh             | 15 +++++++++------
+ src/hb-open-type.hh            | 10 +++++-----
+ src/hb-ot-layout-gpos-table.hh |  6 ------
+ src/hb-ot-layout-gsub-table.hh |  6 ------
+ src/hb-sanitize.hh             |  5 +++--
+ src/hb-subset.hh               |  5 +++--
+ 6 files changed, 20 insertions(+), 27 deletions(-)
+
+commit ac350c92fd6b04845c6240a5f3b77ceaf29e51d0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun May 5 09:10:46 2019 -0700
+
+    [dispatch] Try obj.dispatch(c) before trying c->dispatch(obj)
+
+ src/hb-aat-layout-common.hh  |  2 +-
+ src/hb-dispatch.hh           | 13 +++++++++++++
+ src/hb-ot-layout-gsubgpos.hh | 14 +++++++-------
+ src/hb-sanitize.hh           |  2 +-
+ src/hb-subset.hh             |  4 ++--
+ 5 files changed, 24 insertions(+), 11 deletions(-)
+
+commit 0d5fd168f8e3c1202358a82161a28e407149b1b4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri May 3 10:37:32 2019 -0700
+
+    Revert "[WIP] [name] Port to fancy serializer machinery"
+    
+    This reverts commit c7f366fbbb208d0a9103ac4ee4ac00ff726c31e4.
+    
+    Don't know how it got to master!
+
+ src/hb-ot-name-table.hh | 18 +++++++-----------
+ 1 file changed, 7 insertions(+), 11 deletions(-)
+
+commit 72e3eba8f87e2a8b145a4f98e24499f0aafe099b
+Author: Cody Planteen <planteen at gmail.com>
+Date:   Thu May 2 13:03:15 2019 -0600
+
+    Add configuration option HB_NO_GETENV to disable use of getenv()
+
+ src/hb.hh | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+commit c7f366fbbb208d0a9103ac4ee4ac00ff726c31e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:29:07 2019 -0700
+
+    [WIP] [name] Port to fancy serializer machinery
+
+ src/hb-ot-name-table.hh | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+commit 8855af38a8497d7788924d368baa9eeae4916940
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:26:06 2019 -0700
+
+    [name] Add NameRecord::copy()
+
+ src/hb-ot-name-table.hh | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 097bb3f0af391dbb5d498df548b769f165f35c8a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:25:00 2019 -0700
+
+    [name] Minor changes
+
+ src/hb-ot-name-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 431b6e1c449582619169722e16b472e872b02d58
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:22:32 2019 -0700
+
+    [serialize] Disable assertion for now
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8a32c9eecbdc907415195eca9ebad47c8acf2df5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:20:18 2019 -0700
+
+    [serialize] Misc getting copy() to work
+
+ src/hb-open-type.hh | 16 +++++++++-------
+ src/hb-serialize.hh | 26 ++++++++++++++++----------
+ 2 files changed, 25 insertions(+), 17 deletions(-)
+
+commit 7d497a3a92973d4cec14888b932091f49de1d190
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:20:03 2019 -0700
+
+    [debug] Allow return_trace() to return any type
+
+ src/hb-debug.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 49b1c763a0459d586b7f0aa86eadd13d21b24867
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 16:19:34 2019 -0700
+
+    [test] Run "fonttools ttx" instead of "ttx"
+
+ test/subset/run-tests.py | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 91176d5b778b44172591e82ba84127e5eff1372d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 15:12:07 2019 -0700
+
+    [serialize] Check offset base is within (possibly end of) object
+
+ src/hb-serialize.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 0f1a6ce8268b197732aab40069bbda57eddac2e0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 15:03:41 2019 -0700
+
+    [name] Fix format of susbetted table to 0
+
+ src/hb-ot-name-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 87810fc958e28d0c5e05097b1b3fe78d962fdc62
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 14:45:57 2019 -0700
+
+    [name] Use variable forwarding to simplify sanitize()
+
+ src/hb-ot-name-table.hh | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit bf91b418b0e988619c230156f5f062c5d2802dd8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 14:42:37 2019 -0700
+
+    [name]
+
+ src/hb-ot-name-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 998b0b68ac2eafd1d5bca51b3723fa753e4db7c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 14:39:52 2019 -0700
+
+    [serializer] Add copy() to (Unsized)ArrayOf
+
+ src/hb-open-type.hh | 41 +++++++++++++++++++++++++++++++++++++++++
+ src/hb-serialize.hh |  4 ++--
+ 2 files changed, 43 insertions(+), 2 deletions(-)
+
+commit 88a41472404a8e7754e1099ca4a5b2146dae5298
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 14:22:31 2019 -0700
+
+    [serializer] Accept exact type in serialize_subset/copy()
+
+ src/hb-open-type.hh            | 12 ++++++------
+ src/hb-ot-layout-common.hh     | 33 ++-------------------------------
+ src/hb-ot-layout-gpos-table.hh |  6 ++++++
+ src/hb-ot-layout-gsub-table.hh |  6 ++++++
+ 4 files changed, 20 insertions(+), 37 deletions(-)
+
+commit 88fdeeecc0ef57e41219d92c90f35f13cbd3a35e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 14:14:33 2019 -0700
+
+    [serialize] Take arguments in copy()
+
+ src/hb-open-type.hh |  6 +++---
+ src/hb-serialize.hh | 10 ++++++----
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+commit 273ed6127bd9471fd11b3c1c7f232638f1ff1dba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 14:04:51 2019 -0700
+
+    [serializer] Add serialize_copy()
+
+ src/hb-open-type.hh | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit bf22338f49fb1711f7cbcad2d9949d7962cdc0bc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu May 2 13:51:52 2019 -0700
+
+    Remove dead code
+
+ src/hb-algs.hh | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 14e1fabc41a9a5ead3d91d560773050469982f54
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Wed May 1 21:29:06 2019 -0400
+
+    Sync gen-vowel-constraints.py with current output
+
+ src/gen-vowel-constraints.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 026ab825c8e41980e286be911cc6fbb958dd7cd3
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Wed May 1 16:15:58 2019 -0400
+
+    Add dotted circles to more broken clusters
+
+ src/gen-use-table.py                       |   9 +
+ src/hb-ot-shape-complex-myanmar-machine.hh | 196 +++++-----
+ src/hb-ot-shape-complex-myanmar-machine.rl |   4 +-
+ src/hb-ot-shape-complex-use-machine.hh     | 602 +++++++++++++++--------------
+ src/hb-ot-shape-complex-use-machine.rl     |  11 +-
+ src/hb-ot-shape-complex-use-table.cc       |   2 +-
+ 6 files changed, 433 insertions(+), 391 deletions(-)
+
+commit 92588782d7a45e0c023c5f48cbd19b11cfa8f0d2
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 30 13:05:10 2019 -0700
+
+    Remove space between right angle brackets now that we have C++11 (#1689)
+
+ src/hb-aat-layout-ankr-table.hh |  2 +-
+ src/hb-aat-layout-common.hh     | 14 +++----
+ src/hb-aat-layout-just-table.hh |  4 +-
+ src/hb-aat-layout-kerx-table.hh | 14 +++----
+ src/hb-aat-layout-lcar-table.hh |  2 +-
+ src/hb-aat-layout-morx-table.hh | 14 +++----
+ src/hb-aat-layout-trak-table.hh |  2 +-
+ src/hb-aat-ltag-table.hh        |  2 +-
+ src/hb-cff-interp-cs-common.hh  |  2 +-
+ src/hb-cff1-interp-cs.hh        |  2 +-
+ src/hb-cff2-interp-cs.hh        |  2 +-
+ src/hb-iter.hh                  |  4 +-
+ src/hb-null.hh                  |  8 ++--
+ src/hb-open-file.hh             |  8 ++--
+ src/hb-open-type.hh             |  8 ++--
+ src/hb-ot-color-cbdt-table.hh   |  2 +-
+ src/hb-ot-color-colr-table.hh   |  4 +-
+ src/hb-ot-color-cpal-table.hh   |  8 ++--
+ src/hb-ot-color-sbix-table.hh   |  2 +-
+ src/hb-ot-color-svg-table.hh    |  4 +-
+ src/hb-ot-kern-table.hh         |  6 +--
+ src/hb-ot-layout-base-table.hh  |  2 +-
+ src/hb-ot-layout-common.hh      | 10 ++---
+ src/hb-ot-layout-gdef-table.hh  |  4 +-
+ src/hb-ot-layout-gpos-table.hh  |  6 +--
+ src/hb-ot-layout-gsub-table.hh  | 18 ++++-----
+ src/hb-ot-layout-gsubgpos.hh    | 86 ++++++++++++++++++++---------------------
+ src/hb-ot-math-table.hh         |  2 +-
+ src/hb-ot-name-table.hh         | 10 ++---
+ src/hb-ot-stat-table.hh         |  4 +-
+ src/hb-subset-cff1.cc           |  2 +-
+ src/test-iter.cc                | 10 ++---
+ 32 files changed, 134 insertions(+), 134 deletions(-)
+
+commit f27fdca4aa438ec366ee17370fbc9fdeb962c397
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 30 13:01:04 2019 -0700
+
+    [doc] Add documentation to hb_color_get_* and hb_directwrite_face_* (#1690)
+
+ src/hb-common.cc      | 12 ++++++++----
+ src/hb-directwrite.cc |  8 ++++++--
+ 2 files changed, 14 insertions(+), 6 deletions(-)
+
+commit fe4a0ac707802b5bb36787723f8d55a58c2946a5
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Tue Apr 30 13:35:50 2019 -0400
+
+    Fix some dead links
+
+ src/gen-os2-unicode-ranges.py      | 2 +-
+ src/gen-use-table.py               | 6 +++---
+ src/hb-ot-shape-complex-myanmar.hh | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 6d9a86ae7535ea8e3c108a49c6da877a78cdac26
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Tue Apr 30 16:09:01 2019 +0100
+
+    [Docs] Usermanual; fixes to Object Model chapter
+
+ docs/usermanual-object-model.xml | 35 ++++++++++++++++++++++-------------
+ 1 file changed, 22 insertions(+), 13 deletions(-)
+
+commit 9542bdd0ed2d581cdb4bd950ac3cd7e3bf899478
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Apr 29 14:52:28 2019 -0700
+
+    Add color channels getters ABI (#1513)
+    
+    So can be used with language wrappers
+
+ src/hb-common.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-common.h  | 40 +++++++++++-----------------------------
+ 2 files changed, 64 insertions(+), 29 deletions(-)
+
+commit e200d165a4e8a5f901165c705d617b6e457ec595
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 30 02:10:50 2019 +0430
+
+    [ci] Remove crosscompile-notest-freebsd9 bot
+    
+    It was testing an old version of freebsd and now it's image is gone.
+    We really like to test the environment.
+
+ .circleci/config.yml | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+commit 4aa546b70ad7b11154b901e67f98c1ec6bc5c364
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Mon Apr 29 14:16:51 2019 -0400
+
+    Allow some Balinese Po & So as aksara modre bases
+
+ src/gen-use-table.py                 | 10 ++++++++--
+ src/hb-ot-shape-complex-use-table.cc |  4 ++--
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+commit 6d6edc8b25395c87477181a647a8e6d02f2cad4f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Apr 28 11:54:07 2019 -0700
+
+    [valgrind] Use libtool and support run-subset-fuzzer-tests (#1668)
+
+ test/fuzzing/Makefile.am                |  4 +-
+ test/fuzzing/run-shape-fuzzer-tests.py  | 28 ++++++------
+ test/fuzzing/run-subset-fuzzer-tests.py | 75 ++++++++++++++++++++++++++++++---
+ 3 files changed, 85 insertions(+), 22 deletions(-)
+
+commit 62c6e170728303f4225aaa25523675fc260ae1ab
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Apr 28 10:55:07 2019 -0700
+
+    [test] Add crbug.com/oss-fuzz/14474 testcase
+    
+    Fixed at 6977a95f
+
+ ...testcase-minimized-hb-subset-fuzzer-5716947896893440 | Bin 0 -> 65833 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 6977a95fed8a35d6e915ed3fc3a3ea8709f3d4a4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Apr 27 10:05:25 2019 -0700
+
+    [subset] Don't crash if subsetting GSUB/GPOS fails
+    
+    Fixes fuzzer issue.
+
+ src/hb-subset.cc | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+commit 2b051e7aa147c78cfbf953b6f0eb18c25b732eb2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Apr 27 10:01:11 2019 -0700
+
+    [subset] Check error after calling serializer end
+
+ src/hb-subset.cc | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 750b65e9a980efc13e50ea5d0388ecf06e7a93b1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 26 17:14:25 2019 -0700
+
+    [meta] Add hb_type_identity<>
+    
+    To block template argument deduction.
+
+ src/hb-meta.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 8c8922a019eb1ceb8beffc05ca638ee0ca25b565
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Apr 25 09:17:58 2019 -0700
+
+    [subset] Updates due to changes in resolve_links() on master branch
+
+ src/Makefile.sources    | 1 +
+ src/hb-ot-name-table.hh | 7 +++++--
+ src/hb-static.cc        | 3 +--
+ 3 files changed, 7 insertions(+), 4 deletions(-)
+
+commit 2f6ec35344db08d0c892152bc7a7eaa67e7c03f0
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Apr 24 15:15:36 2019 -0700
+
+    Move implementations of hb-ot-name-language.cc into a hb-static.cc
+
+ src/hb-aat-layout.hh              |   1 -
+ src/hb-ot-name-language-static.hh | 462 ++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-name-language.hh        | 432 +----------------------------------
+ src/hb-static.cc                  |   2 +
+ 4 files changed, 468 insertions(+), 429 deletions(-)
+
+commit 19afd25004487cfaa7b487b1768b4dae1ab37296
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Apr 24 14:02:29 2019 -0700
+
+    [subset] Update to use _subset2() for name table
+
+ src/hb-ot-name-table.hh | 47 ++++++++++-------------------------------------
+ src/hb-subset.cc        |  4 ++--
+ 2 files changed, 12 insertions(+), 39 deletions(-)
+
+commit 1ca4b5c77012ed586413f39e730b03bf965e1305
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Apr 22 11:31:23 2019 -0700
+
+    [subset] Add unit test for str de-dup
+    Also move the implementation of some methods from the .cc to the .hh
+
+ src/Makefile.sources                   |   1 -
+ src/hb-aat-layout.cc                   |   8 -
+ src/hb-aat-layout.hh                   |   9 +-
+ src/hb-ot-name-language.cc             | 457 ---------------------------------
+ src/hb-ot-name-language.hh             | 432 ++++++++++++++++++++++++++++++-
+ test/api/fonts/nameID.dup.expected.ttf | Bin 0 -> 2340 bytes
+ test/api/fonts/nameID.dup.origin.ttf   | Bin 0 -> 170680 bytes
+ test/api/test-subset-nameids.c         |  21 ++
+ 8 files changed, 456 insertions(+), 472 deletions(-)
+
+commit 9ad14f56b6cf2a345104b3a897b52a1f4c0f33a5
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Apr 16 11:20:58 2019 -0700
+
+    [subset] update name table subsetting with new serializer
+
+ src/hb-ot-name-table.hh | 126 ++++++++++++++++++++++++++++--------------------
+ 1 file changed, 75 insertions(+), 51 deletions(-)
+
+commit 6faac8df83bb59f08e5d329e76435ba438b2ea54
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Apr 10 16:38:35 2019 -0700
+
+    [subset] Subsetting Name Table Step 4
+    Add unit test and integration test
+
+ test/api/Makefile.am                               |   2 +
+ test/api/fonts/nameID.expected.ttf                 | Bin 0 -> 170696 bytes
+ test/api/fonts/nameID.origin.ttf                   | Bin 0 -> 170976 bytes
+ test/api/hb-subset-test.h                          |   9 ++++
+ test/api/test-subset-nameids.c                     |  58 +++++++++++++++++++++
+ .../Roboto-Regular.abc.name-ids.61,62,63.ttf       | Bin 0 -> 2168 bytes
+ .../basics/Roboto-Regular.abc.name-ids.61,63.ttf   | Bin 0 -> 1988 bytes
+ .../basics/Roboto-Regular.abc.name-ids.61.ttf      | Bin 0 -> 1792 bytes
+ .../basics/Roboto-Regular.abc.name-ids.62.ttf      | Bin 0 -> 1740 bytes
+ .../basics/Roboto-Regular.abc.name-ids.63.ttf      | Bin 0 -> 1716 bytes
+ test/subset/data/profiles/name-ids.txt             |   1 +
+ test/subset/data/tests/basics.tests                |   1 +
+ 12 files changed, 71 insertions(+)
+
+commit e501ea143d1e63974903cdb41932c50f4222ff4e
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Apr 5 10:05:55 2019 -0700
+
+    [subset] Subset name table step 3, add --nameids option to guide the
+    selection of which name records to keep in the subset method.
+
+ src/hb-ot-name-table.hh | 28 ++++++++++++++++------------
+ src/hb-subset-input.cc  |  8 ++++++++
+ src/hb-subset-input.hh  |  3 ++-
+ src/hb-subset-plan.cc   | 10 ++++++----
+ src/hb-subset-plan.hh   |  3 +++
+ src/hb-subset.h         |  3 +++
+ util/hb-subset.cc       |  1 +
+ util/options.cc         | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ util/options.hh         |  8 ++++++++
+ 9 files changed, 92 insertions(+), 17 deletions(-)
+
+commit 2637a81615c80443911a603cbd161ade525c79f1
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Apr 2 13:38:27 2019 -0700
+
+    [subset] subset name table step 2, add implementation for collecting subset
+    elements and serialize method
+
+ src/hb-ot-name-table.hh | 131 ++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 109 insertions(+), 22 deletions(-)
+
+commit 408c1daeb4ff86d2204ed1bdd059513357ada392
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Mar 29 10:34:32 2019 -0700
+
+    [subset] subset name table step 1,  write out table unmodified, use accelerator to access
+    string
+
+ src/hb-ot-name-table.hh | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-subset.cc        |  4 ++++
+ 2 files changed, 57 insertions(+)
+
+commit 3a7f5bdd18314676425ec811199767a5f8e65a40
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 26 14:40:01 2019 -0700
+
+    Rewrite hb_is_signed()
+
+ src/hb-meta.hh | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+commit 73c82f2301a52cf2111296b34691bc898a7a6363
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 26 13:16:48 2019 -0700
+
+    [iter] Fix hb_is_iterator_of() to actually check item type
+
+ src/hb-iter.hh | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+commit c51f15ddfcae8578483693b761b81ceaebf05f2a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 26 13:03:41 2019 -0700
+
+    [array] Adjust hb_sorted_array_t copy constructor/assignment to match hb_array_t
+
+ src/hb-array.hh | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+commit b2758c360cc08d7a0334aae11845d0c5d50c46af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 26 12:58:06 2019 -0700
+
+    [array] Use hb_is_cr_convertible_to()
+
+ src/hb-array.hh | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+commit 8ecae793aa79056a312d3c8518106cfeca42390e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 26 12:57:56 2019 -0700
+
+    [meta] Add hb_is_cr_convertible_to()
+
+ src/hb-meta.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 52bb0346d319c322f117567a096fafa1bc804e26
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 26 12:52:28 2019 -0700
+
+    [meta] Add hb_decay<>
+
+ src/hb-meta.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 474f3587cd18fdaf86b2068647fa03b107557d8c
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Apr 26 10:12:38 2019 -0700
+
+    copy retain_gids from input to plan
+
+ src/hb-subset-plan.cc | 1 +
+ src/hb-subset-plan.hh | 1 +
+ 2 files changed, 2 insertions(+)
+
+commit 3fc066314ac19005ea8157a6541412cfd24abbc2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 16:41:57 2019 -0700
+
+    Another try at fixing cmake build
+
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c69f02784ac53a7fd13eee559559b38d8224ef59
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 16:31:37 2019 -0700
+
+    Fix sign-compare error on 32-bit systems
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f2d20dd9d3b52f434f5fe9dbef82bd95eb499edf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 15:08:27 2019 -0700
+
+    [THANKS] Add Ivan Kuckir <https://photopea.com/>
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1633#issuecomment-485764140
+
+ THANKS | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0ca358f21a2a6e86a3d5c145a70bb84ab6e2db32
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 16:36:29 2019 -0400
+
+    Try fixing cmake build
+
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 59a8fa53533b10b9c25458d9ba2d68b7b01c3ff0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 12:19:13 2019 -0400
+
+    [iter] Add tests for casting to hb_iter_t<> base class for hb_sorted_array_t<>
+    
+    Something's phishy about hb_sorted_array_t<>.  Can't get it work nicely with
+    change I'm making.  Ugh..
+
+ src/test-iter.cc | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 714307cc437f375f128e17e5ab01eba0c57aaf01
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:56:12 2019 -0400
+
+    [iter] Remove fixed TODO
+
+ src/hb-iter.hh | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 22da12318a3e9fd9955f24fd0092de1a4a1a940d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:53:16 2019 -0400
+
+    [map] Fix TODO
+
+ src/hb-map.hh           | 6 ++----
+ src/hb-meta.hh          | 6 ++++++
+ src/hb-ot-cff1-table.cc | 1 -
+ src/hb-ot-cff2-table.cc | 1 -
+ src/hb.hh               | 3 +--
+ 5 files changed, 9 insertions(+), 8 deletions(-)
+
+commit 4c6136e976af4f7332f703f5a7625505ffc296b6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:44:24 2019 -0400
+
+    [mutex] Remove TODO
+
+ src/hb-mutex.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 0268db11965d022883d5ef2ef828c0635165b7bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:43:40 2019 -0400
+
+    [map] Use hb_invoke() with pointer-to-method
+
+ src/hb-algs.hh   | 5 ++++-
+ src/hb-map.hh    | 4 ++--
+ src/test-algs.cc | 8 ++++++++
+ 3 files changed, 14 insertions(+), 3 deletions(-)
+
+commit 8f79a5750e8982f9ab73c0dc6a8534dffef74610
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:32:49 2019 -0400
+
+    [algs] Add more hb_forward<>()'s
+
+ src/hb-algs.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 42526d1697e2449fa23741f84721dcf2ce688af7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:24:33 2019 -0400
+
+    [serialize] Fix SingleSubstFormat1 failure
+
+ src/hb-ot-layout-gsub-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 6cc9707c9c0885a3133b7844f615cdcdaeccec18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:22:06 2019 -0400
+
+    [serialize] Rename
+
+ src/hb-serialize.hh | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+commit 085793d6cd35a1590a66712f39260030367490db
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:15:59 2019 -0400
+
+    Remove wrong TODOs
+
+ src/hb-ot-layout-gsubgpos.hh       | 2 +-
+ src/hb-ot-shape-complex-indic.cc   | 1 -
+ src/hb-ot-shape-complex-khmer.cc   | 4 ++--
+ src/hb-ot-shape-complex-myanmar.cc | 3 ++-
+ src/hb-ot-shape-complex-use.cc     | 4 ++--
+ 5 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 915b9ea5f48d56df21419761477b2d4ba2843b54
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:07:19 2019 -0400
+
+    [serialize] Add c->check_assign()
+    
+    To check for assignment overflows.
+
+ src/hb-open-type.hh            |  7 +++----
+ src/hb-ot-layout-gsub-table.hh |  2 +-
+ src/hb-serialize.hh            | 20 +++++++++++++-------
+ 3 files changed, 17 insertions(+), 12 deletions(-)
+
+commit 00a00bc1f23c681d64fbd4df33582ec0165e337a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 10:01:30 2019 -0400
+
+    Fix two TODOs
+
+ src/hb-ot-layout-gsub-table.hh | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit 11ab889a8d743304c8ec17920e209a514f46739d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 09:55:24 2019 -0400
+
+    Rename a few test programs
+
+ src/Makefile.am                                    | 24 +++++++++++-----------
+ ...est-size-params.cc => test-gpos-size-params.cc} |  0
+ ...substitute.cc => test-gsub-would-substitute.cc} |  0
+ src/{test-name-table.cc => test-ot-name.cc}        |  0
+ 4 files changed, 12 insertions(+), 12 deletions(-)
+
+commit 12017db0bfe62e7777e1ab6ba5b14729dcd4c351
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 09:24:38 2019 -0400
+
+    Move test code around
+
+ src/test-algs.cc | 8 ++++++++
+ src/test-iter.cc | 9 ---------
+ 2 files changed, 8 insertions(+), 9 deletions(-)
+
+commit 27377a7e287dd39e3f7caad5c1e0691ae381ccf8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 09:22:14 2019 -0400
+
+    Rely on variadic parameter pack more
+
+ src/hb-open-type.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 3ad20c38ade76aca8aed024014977ecb5f2b636e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 24 09:09:00 2019 -0400
+
+    [serialize] Fix a few overflow TODO items
+
+ src/hb-open-type.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 175bdad8bff5b0e9732ab1fb97617a9293680fd4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 23 23:57:11 2019 -0400
+
+    One more variadic parameter pack use
+
+ src/hb-aat-layout-common.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 441cca235477a5399af214c9ac85320d4de69f0b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 23 23:49:21 2019 -0400
+
+    Use hb_forward() when forwarding parameter pack
+
+ src/hb-open-type.hh | 32 ++++++++++++++++----------------
+ src/hb-serialize.hh |  3 ++-
+ 2 files changed, 18 insertions(+), 17 deletions(-)
+
+commit 20f3134789f65b10f301c4635c9f80c2dda0fb97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 23 12:58:52 2019 -0400
+
+    Use variadic templates in OffsetTo<> and various ArrayOf<>s
+
+ src/hb-open-type.hh | 145 ++++++++++++++++++----------------------------------
+ 1 file changed, 49 insertions(+), 96 deletions(-)
+
+commit aa6692cb0079bbe1e003f211a321e8fe6a18ea94
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Tue Apr 23 17:56:44 2019 +0100
+
+    Usermanual: update Makefile SGML list. Again.
+
+ docs/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 98c54cdef8b0615a95382bdba4ecd008789f8c9e
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Tue Apr 23 17:48:42 2019 +0100
+
+    Usermanual: add chapter on object model.
+
+ docs/harfbuzz-docs.xml           |   1 +
+ docs/usermanual-object-model.xml | 249 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 250 insertions(+)
+
+commit 64ca2ffa4c88b961dcbd9d06be8ac7dd80ad8182
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 23 01:10:46 2019 -0700
+
+    Fix clang's -Wmain complain (#1678)
+
+ src/test-iter.cc | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 7c218351ab45c41e48147b2196393357f7b551d4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 23 12:40:29 2019 +0430
+
+    .editorconfig, minor
+    
+    still doesn't work with vscode
+
+ .editorconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 25dd88efc6521b972babe1067c0de1b9d4f5dbe5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 22 17:45:23 2019 -0400
+
+    Err, fix hb_invoke() variadic
+
+ src/hb-algs.hh   | 6 +++---
+ src/test-iter.cc | 5 ++++-
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+commit c862a532df0bc3ce0b47f3fde9bf1dd300ff8bee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 22 17:32:19 2019 -0400
+
+    Add variadic arguments to hb_invoke()
+
+ src/hb-algs.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 9c724e48a2f5d61c31c79f0b4660f08e5d07db10
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 22 15:37:10 2019 -0400
+
+    [serializer] Add err_propagaged_error()
+
+ src/hb-serialize.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit ae8da4b61b4cc3b55242b85fe7c63393d65bd6cf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 22 15:25:11 2019 -0400
+
+    Minor
+
+ src/hb-iter.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 24da1d08603a7fe262ae88d687986efc0343956f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 22 15:20:25 2019 -0400
+
+    Use variadic template args for propagate_error()
+    
+    Let's see if bots happy.
+    
+    Not sure where else we can use these.  Mm.  Maybe in hb_invoke().
+
+ src/hb-serialize.hh | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit 9bab398462fa598047f34fd6d23e07a91305b1b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 22 15:16:35 2019 -0400
+
+    Simplify propagate_error()
+
+ src/hb-serialize.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit ecac94ca763e80d217ba5db429745e8882b38464
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Apr 21 12:27:32 2019 -0400
+
+    [docs] Remove fdo repo
+    
+    Has not been updated.
+
+ docs/harfbuzz-docs.xml | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+commit 8ed7655be89c658219ab702e34a79734ba0efb73
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Apr 21 12:25:19 2019 -0400
+
+    Update AUTHORS / COPYING
+
+ AUTHORS | 3 +++
+ COPYING | 3 ++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit a464cbeecea73aeaa03c262f49fed8584057d9bb
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 19 12:14:09 2019 -0700
+
+    Revert "Add harfbuzzjs build configuration (#1636)" (#1675)
+    
+    This reverts commit 694cb1beeefe1c54b2e613d2d566a21e248a2c9c.
+
+ CMakeLists.txt | 35 -----------------------------------
+ 1 file changed, 35 deletions(-)
+
+commit 694cb1beeefe1c54b2e613d2d566a21e248a2c9c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 19 07:51:04 2019 -0700
+
+    Add harfbuzzjs build configuration (#1636)
+
+ CMakeLists.txt | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+commit 42f4bd6b801f96fc33a365db8ab6390e74cef05a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 18 19:04:59 2019 -0400
+
+    Minor warning fix again
+
+ src/hb-ot-map.cc        | 20 ++++++++++----------
+ test/api/test-ot-face.c |  2 +-
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+commit 267fb9c7163e61c9cdbafbb16005bc659ec5a4a2
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Apr 18 15:17:10 2019 -0700
+
+    add spaces
+
+ src/hb-ot-cff1-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ba0386060d92dffcde2d14f9e523a46ea8713de2
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Apr 18 14:53:35 2019 -0700
+
+    fix oss-fuzz issue 14345
+
+ src/hb-ot-cff1-table.hh                                 |   3 ++-
+ ...testcase-minimized-hb-subset-fuzzer-5923632099885056 | Bin 0 -> 25847 bytes
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit 63a2108480cca2d9c1a2f61d6642d70496f1a5e3
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Apr 18 13:54:58 2019 -0700
+
+    silence MVC warnings 3rd attempt
+
+ src/hb-ot-cff1-table.cc | 5 +++--
+ src/hb-ot-cff2-table.cc | 9 +++++----
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+commit 705dde57fe7bd5aafe93f284db2aa809aad932dc
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Apr 18 11:32:10 2019 -0700
+
+    silence MVC warnings 2nd attempt
+
+ src/hb-ot-cff1-table.cc | 4 ++--
+ src/hb-ot-cff2-table.cc | 8 ++++----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit dd4c37529bcecee33d43015a852a3fcf9e978b7f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Apr 18 10:38:57 2019 -0700
+
+    silence MVC warnings
+
+ src/hb-cff-interp-common.hh | 2 +-
+ src/hb-ot-cff1-table.cc     | 4 ++--
+ src/hb-ot-cff2-table.cc     | 8 ++++----
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 518e6e07f29d9bb7e532313fb0af6177d8022ea5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 18 12:21:25 2019 -0400
+
+    Minor
+
+ src/hb-ot-map.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 91d958acc08cb99ddd3b656922e13497b9d1595d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 18 10:04:10 2019 -0400
+
+    [array] Simplify copy assignment/constructor
+    
+    To fix bogus MSVC warnings:
+    
+      c:\projects\harfbuzz\src\hb-array.hh(189): warning C4521: 'hb_array_t<Type>': multiple copy constructors specified [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+      c:\projects\harfbuzz\src\hb-array.hh(189): warning C4522: 'hb_array_t<Type>': multiple assignment operators specified [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+
+ src/hb-array.hh | 29 +++++++++++++++++++----------
+ 1 file changed, 19 insertions(+), 10 deletions(-)
+
+commit 693d91cd49fda3e728b59e6885bea8d7b01958ef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 17 17:59:39 2019 -0400
+
+    [serialize] Fix offset calculation
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit db0c9a1485ae6ca7ca9af38a43504f1ae4ea09c8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 17 17:58:13 2019 -0400
+
+    [subset] Assert offsets are zero during relocation
+    
+    If they're not, it's a bug in our subsetting logic somewhere.  So check.
+
+ src/hb-serialize.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit efbba7ad26dda5930f5d1bd5292304835432f504
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 17 11:00:08 2019 -0400
+
+    [serializer] Add copy()
+    
+    Calls obj.copy() or obj.operator=() in that order.
+
+ src/hb-serialize.hh | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+commit c67a0d581fcc50df5563c23060b4fcd9dac4c87c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 17 10:20:02 2019 -0400
+
+    Add HB_RETURN
+
+ src/hb-algs.hh | 13 ++++++-------
+ src/hb-meta.hh | 34 ++++++++++++++++++++--------------
+ 2 files changed, 26 insertions(+), 21 deletions(-)
+
+commit 6745a600bfec13b3f5468b3d31bab7d82b1e61ce
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Tue Apr 16 17:29:34 2019 -0400
+
+    Comment out ot_languages where fallback suffices
+
+ src/gen-tag-table.py   |  15 +-
+ src/hb-ot-tag-table.hh | 443 +++++++++++++++++++++++++------------------------
+ src/hb-ot-tag.cc       |  19 ++-
+ test/api/test-ot-tag.c |   5 +-
+ 4 files changed, 255 insertions(+), 227 deletions(-)
+
+commit 5daeff3e68e4e202effb152f52702a044c09f386
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Wed Apr 17 09:11:44 2019 -0400
+
+    Fix "hb_script_" doc typo
+
+ src/hb-common.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6916b77863cd5ce492a274eb85f196f2152fbb96
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 18:33:51 2019 -0400
+
+    One more auto return type
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5b33427f2c4d596a12f05ffebebfd68655fd63eb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 18:28:17 2019 -0400
+
+    Rename HB_AUTO_RETURN_EXPR to HB_AUTO_RETURN
+
+ src/hb-algs.hh | 34 +++++++++++++++++-----------------
+ src/hb-meta.hh |  8 ++++----
+ 2 files changed, 21 insertions(+), 21 deletions(-)
+
+commit da293b0e59a0d6c47e9b3a7807115a168a0a5c94
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 18:27:25 2019 -0400
+
+    Use HB_AUTO_RETURN_EXPR in hb_min/max
+
+ src/hb-algs.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 0241a40f2aff43aba045fb7de4a2c3e5f1e9626a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 18:26:30 2019 -0400
+
+    Use auto return type for hb_first/hb_second
+
+ src/hb-algs.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit fe30fcd228ff95be1f169f580b30184c8511d1c3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 17:34:06 2019 -0400
+
+    Use hb_deref_pointer() to reduce number of overloads
+
+ src/hb-algs.hh | 27 ++++++++++-----------------
+ src/hb-meta.hh | 36 +++++++++++++++++++-----------------
+ 2 files changed, 29 insertions(+), 34 deletions(-)
+
+commit c918a6706fa759696569ad6dcaae03fed76306bc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 17:28:18 2019 -0400
+
+    Properly prioritize hb_hash()
+
+ src/hb-algs.hh | 46 +++++++++++++++++++++++-----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+commit 75fd845a4abccc2596f0e1fe2294f936199e61f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 17:22:29 2019 -0400
+
+    Move around
+
+ src/hb-algs.hh | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+commit 973717175d46d62471772318bb0b607070c53ec7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 16:50:07 2019 -0400
+
+    Fix priorities
+
+ src/hb-algs.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 54ece299bcb3436763cc4f3b6b0ca11de8133b28
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 16:45:53 2019 -0400
+
+    Use type aliasing for meta-functions, ie. those returning a type
+
+ src/hb-algs.hh   |  3 ++-
+ src/hb-array.hh  |  6 +++---
+ src/hb-atomic.hh |  2 +-
+ src/hb-blob.hh   |  2 +-
+ src/hb-common.cc |  2 +-
+ src/hb-ft.cc     |  2 +-
+ src/hb-iter.hh   |  2 +-
+ src/hb-meta.hh   | 12 ++++++------
+ src/hb-null.hh   |  6 +++---
+ 9 files changed, 19 insertions(+), 18 deletions(-)
+
+commit 1ce11b44375dae74e8984ace1db4f08c51ac9c38
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Tue Apr 16 10:04:45 2019 -0400
+
+    Reduce LangTag from 3 language system tags to 1
+
+ src/gen-tag-table.py   |   13 +-
+ src/hb-ot-tag-table.hh | 2078 ++++++++++++++++++++++++------------------------
+ src/hb-ot-tag.cc       |   22 +-
+ 3 files changed, 1053 insertions(+), 1060 deletions(-)
+
+commit 155e92f25908830bef192304a2039853f6f5d4b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 11:35:09 2019 -0400
+
+    Reduce NullPool size
+
+ src/hb-null.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4fc2d2d7248171c386c39630aa2612f240669a58
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 11:24:42 2019 -0400
+
+    [meta] Flesh out hb_invoke()
+
+ src/hb-algs.hh | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+commit e03d9395aa79a29d731607bfd46533b700dc1a37
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 11:20:16 2019 -0400
+
+    Comment
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b8e763fd7140b3e298863e04053ec0f3c73a6a70
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 10:50:22 2019 -0400
+
+    [meta] Add hb_invoke()
+
+ src/hb-algs.hh | 34 ++++++++++++++++++++++++++++++++--
+ src/hb-iter.hh |  2 +-
+ 2 files changed, 33 insertions(+), 3 deletions(-)
+
+commit a3fcb9a370ad7a3c205342f831d8529c81660466
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 10:45:20 2019 -0400
+
+    [meta] Add HB_AUTO_RETURN_EXPR, HB_VOID_RETURN_EXPR, hb_priority, hb_has(), hb_get()
+    
+    The first three based on range-v3.
+
+ src/hb-algs.hh | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-iter.hh |  7 ++++---
+ src/hb-meta.hh | 32 +++++++++++++++-----------------
+ src/hb.hh      |  2 +-
+ 4 files changed, 66 insertions(+), 21 deletions(-)
+
+commit ff68be31bf2ea82bf6bfcc6f993fb6806a895f97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 16 09:59:08 2019 -0400
+
+    Add hb_void_tt<> ala std::void_t
+
+ src/hb-meta.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 89fea21697adfbba5057dd1d69c9806ee86e5ca8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 17:36:09 2019 -0400
+
+    Fix copyright
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b7384c89e2685cec1b6761c918ec7d91e8ae3af8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 16:53:10 2019 -0400
+
+    [fuzzing] Run valgrind with --leak-check=full
+
+ test/fuzzing/run-shape-fuzzer-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3ff66c00292b20325b0d991dfd5eee80284cb9a8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 16:52:21 2019 -0400
+
+    [fuzzing] Fail if valgrind is requested but not found
+
+ test/fuzzing/run-shape-fuzzer-tests.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 07776b60965d503dfb7fb5c611397e40759b0bdc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 16:43:34 2019 -0400
+
+    More tweaks to previous commit
+    
+    Delete assignment operator of OffsetTo<> instead of Offset<>.
+    
+    In simple ArrayOf<>::sanitize() assert that Type has assignment operator.
+    Ideally we should SFINAE this and fallback to calling Type::sanitize()
+    if assignment operator is not available.  But we don't have a case of
+    that in the codebase.
+
+ src/hb-open-file.hh |  4 ++--
+ src/hb-open-type.hh | 16 +++++++++++-----
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+commit 699de689e9aa2246ba9207c07140ccd564f5ec20
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 16:00:20 2019 -0400
+
+    Delete default assignment operator Offset<>
+
+ src/hb-open-type.hh        |  3 +++
+ src/hb-ot-cmap-table.hh    |  2 +-
+ src/hb-ot-layout-common.hh | 14 +++++++-------
+ 3 files changed, 11 insertions(+), 8 deletions(-)
+
+commit 02d864aa26359b7f057e2aa81404309e17180d47
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 15:39:03 2019 -0400
+
+    Add HB_FUNCOBJ()
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1651
+
+ src/hb-algs.hh | 28 +++++++++++++++-------------
+ src/hb-iter.hh | 56 ++++++++++++++++++++++++++++----------------------------
+ src/hb-meta.hh | 22 +++++++++++++---------
+ src/hb.hh      |  7 +++++++
+ 4 files changed, 63 insertions(+), 50 deletions(-)
+
+commit 60be1450ad04612a6c2a6116036dbf3e436018de
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon Apr 15 18:05:14 2019 +0100
+
+    [Usermanual]: fix Tamil error in Why-do-I-need-a-shaping-engine section.
+
+ docs/usermanual-what-is-harfbuzz.xml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 38b1d0b9b2e798dd808a816a397323ed7ba697ab
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 12:44:31 2019 -0400
+
+    Move static const to post-struct for a function object
+    
+    Just sending this to bots to see if all happy, then turn it into macro and
+    apply everywhere.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1651
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 19e800c9d881ec016ab2e5fcaadab55ab5188398
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 12:07:00 2019 -0400
+
+    Ugh.  Another try, to unbreak gcc this time!
+    
+    Jenga.
+
+ src/hb-subset.cc | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit 3a88f55c15b625a0ad10fbfadf4562bcbb41ae53
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 11:59:57 2019 -0400
+
+    Move location of HB_UNUSED to make MSVC happy
+
+ src/hb-subset.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1ae265888e144328dbf1df796d379bf742c4151a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 15 11:31:40 2019 -0400
+
+    Fix gcc warning
+
+ src/hb-array.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit c0ea37b557f53b50094042f11fe2611b1b30d725
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Apr 15 00:34:04 2019 +0430
+
+    [ci] Fix macOS glib issue
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ad126036643e44a98c4c42d2a2a4a3b4a3649937
+Merge: 341b70a3 47e538a3
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sun Apr 14 15:42:42 2019 +0100
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz
+
+commit cd9889cac3ac3b271f7335f3e94acc4667a59b40
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sun Apr 14 15:33:56 2019 +0100
+
+    Docs: update and extended GTK-Doc comments for hb-ot-math.
+
+ src/hb-ot-math.cc | 133 ++++++++++++++++++++++++++++++++----------------------
+ src/hb-ot-math.h  |  21 +++++++++
+ 2 files changed, 99 insertions(+), 55 deletions(-)
+
+commit 3f74b7a14bffb8e91cd98edd0c3ddf0b0ddc169a
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sun Apr 14 15:20:56 2019 +0100
+
+    Docs: Regularize GTK-Doc comments for hb-ot-color.
+
+ src/hb-ot-color.cc | 136 ++++++++++++++++++++++++++++++-----------------------
+ src/hb-ot-color.h  |   6 +--
+ 2 files changed, 80 insertions(+), 62 deletions(-)
+
+commit 47e538a35f9072e5775a65e2bf110ae895818321
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 22:50:22 2019 -0400
+
+    Add HB_NO_SUBSET_LAYOUT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-subset.cc | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+commit a98e4068e76d50bd9562d85a452b56e681f1d62b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 22:42:44 2019 -0400
+
+    Revert "Hide symbols in hb-iter"
+    
+    This reverts commit 98f14c4cdb837a962083a6702f401d41b4c1ec5c.
+    
+    Same as previous commit.
+
+ src/hb-iter.hh | 88 +++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 44 insertions(+), 44 deletions(-)
+
+commit dab92bdd4623aa7dac8eb00b14131566d75d095e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 22:39:38 2019 -0400
+
+    Revert "Hide more symbols"
+    
+    This reverts commit 2e86d50915cf1a791da9acb95245aa820a3d70f4.
+    
+    I think the setup that caused me to do this is faulty and not hiding inlines.
+
+ src/hb-blob.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 98f14c4cdb837a962083a6702f401d41b4c1ec5c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 18:11:18 2019 -0400
+
+    Hide symbols in hb-iter
+    
+    Painful.  All template methods need to be explicitly hidden :(.
+    
+    Maybe we should switch to -fvisibility=hidden pragma.
+    
+    A LOT more to go.
+
+ src/hb-iter.hh | 88 +++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 44 insertions(+), 44 deletions(-)
+
+commit 2e86d50915cf1a791da9acb95245aa820a3d70f4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 18:07:42 2019 -0400
+
+    Hide more symbols
+    
+    Exposed by:
+    
+    $ make -j5 CPPFLAGS="-O0" CXXFLAGS=-flto=thin LDFLAGS=-lc++ && ./check-symbols.sh
+
+ src/hb-blob.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit caa20e4ef9dff61a86312daec5d5a1df27d95ff7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 17:59:18 2019 -0400
+
+    Hide a few more symbols
+    
+    Exposed by:
+    
+    $ make CPPFLAGS=-O0
+
+ src/hb-array.hh | 4 ++--
+ src/hb-meta.hh  | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 95df00aec1996d521acdff6deff063ba98214fb9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 17:50:03 2019 -0400
+
+    Hide a few static methods
+    
+    Looks like static methods that do not get inlined end up exported.
+    We have a lot more.  Need to protect all at some point.  Wish there
+    was an easier way, like the visibility flag we pass that automatically
+    hides all inline methods.
+    
+    Was exposed by check-symbols.sh when compiling on OS X 10.14 with:
+    
+    $ make CPPFLAGS=-Oz CXXFLAGS=-flto=thin LDFLAGS=-lc++
+
+ src/hb-aat-layout.hh           |  2 +-
+ src/hb-aat-map.hh              |  2 +-
+ src/hb-array.hh                |  2 +-
+ src/hb-coretext.cc             |  4 ++--
+ src/hb-open-file.hh            |  2 +-
+ src/hb-open-type.hh            |  3 ++-
+ src/hb-ot-cmap-table.hh        | 14 +++++++-------
+ src/hb-ot-layout-base-table.hh |  6 +++---
+ src/hb-ot-layout-gpos-table.hh |  8 ++++----
+ src/hb-ot-layout-gsub-table.hh |  8 ++++----
+ src/hb-ot-layout-gsubgpos.hh   |  2 +-
+ src/hb-ot-map.hh               |  4 ++--
+ src/hb-uniscribe.cc            |  4 ++--
+ 13 files changed, 31 insertions(+), 30 deletions(-)
+
+commit 2f4be4ba54b539fbadc31fc53bdcfca81d7db77a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 16:21:58 2019 -0400
+
+    Add HB_NO_OPTIONS
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-debug.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 079d2dcbb2607cda3daa497199090c5813a51de5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 15:00:37 2019 -0400
+
+    Add HB_NO_NAME_TABLE_AAT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-name-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 60a58aa61c09cafd12c432fdc1f7325f2a6d44bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 14:58:53 2019 -0400
+
+    Add HB_NO_OT_FONT_BITMAP
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 160c4d8b2d9f6c205b713236f043081e6dd532ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 14:57:49 2019 -0400
+
+    Add HB_NO_OT_FONT_CFF
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 35f3b97fac3b106d345a06a4970f6adce182797b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 10:16:12 2019 -0400
+
+    Add HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-hebrew.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 414c5de26b34c0c53f6f4b5f00ddc8e1a3b62ac2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 10:12:11 2019 -0400
+
+    Add HB_NO_OT_SHAPE_FALLBACK
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-fallback.cc | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit fe0018f7ef804acefa729e888f5a9935e571079d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 09:35:29 2019 -0400
+
+    Add HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-thai.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 9ddbfa006d752f6ddd3610ff968f84cf18dec031
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 12 09:33:25 2019 -0400
+
+    Add HB_NO_OT_LAYOUT_BLACKLIST
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-layout.cc | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 571fad4cf17d90434562d1b6f5d08b6f27343c7a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 11 17:54:38 2019 -0400
+
+    Add HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-vowel-constraints.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 3db227265bc0790ffd718bf265d245c78598a49d
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Tue Apr 2 18:49:40 2019 +0100
+
+    Update gtk-doc annotations for inout counts on various getter functions.
+
+ src/hb-ot-layout.cc | 122 ++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 70 insertions(+), 52 deletions(-)
+
+commit c08ddbd91b7f0fffe761638a2ee4893304b012db
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sun Mar 24 15:07:07 2019 +0000
+
+    [Docs] Minor edits to gtk-doc inline comment review.
+
+ src/hb-ot-layout.cc | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+commit af5230bce39020cf6fc87ee5e21cca3ba201a417
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon Mar 18 14:03:16 2019 +0000
+
+    [Docs] Minor; fix formatting for gtk-doc multiple-annotations.
+
+ src/hb-ot-layout.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 6c0a1e8cd67144d20c8b5fcad23953910eeeea51
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sun Mar 17 14:50:47 2019 +0000
+
+    [Docs] Annotate gtk-doc formatting with some un-annotated (out)s.
+
+ src/hb-ot-layout.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 5122805c740961d4fdfbff440ed68792b63d50ed
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sun Mar 17 14:43:06 2019 +0000
+
+    [Docs] Fix gtk-doc formatting for (out) and (inout).
+
+ src/hb-ot-layout.cc | 108 ++++++++++++++++++++++++++--------------------------
+ 1 file changed, 54 insertions(+), 54 deletions(-)
+
+commit d3178aa52ae822ac6af606027ac8150ded0a2966
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sun Mar 17 14:27:27 2019 +0000
+
+    [Docs] Fix gtk-doc references to 'kern' table functions, clarifying that GPOS is not examined.
+
+ src/hb-ot-layout.cc | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+commit 3449031fad9dff7acedde7dceb0e47db708fc025
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sat Mar 16 15:38:08 2019 +0000
+
+    [Docs] Add inline gtk-doc documentation of GDEF glyph classes.
+
+ src/hb-ot-layout.h | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 930f6fc3da04ce1897e65862fccb03afa9d3a780
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Sat Mar 16 15:10:21 2019 +0000
+
+    [Docs] Add inlind gtk-doc comments for hb-ot-layout functions.
+
+ src/hb-ot-layout.cc | 456 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-ot-layout.h  |  11 ++
+ 2 files changed, 462 insertions(+), 5 deletions(-)
+
+commit b52c0e54b9855a1f3d400e4dbcd0372520f2c2fc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 11 11:20:10 2019 -0400
+
+    Use injected class name to simplify macros
+
+ src/hb-open-type.hh | 10 +++++-----
+ src/hb.hh           | 14 --------------
+ 2 files changed, 5 insertions(+), 19 deletions(-)
+
+commit baf1e79075b0f917b79484446cd2ca47b58f50aa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 11 11:18:04 2019 -0400
+
+    [C++11] Use deleted methods
+
+ src/hb.hh | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+commit 824fd342d5d66584a5ed88951e05975f33c55617
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 11 11:16:01 2019 -0400
+
+    Rename a few macros
+
+ src/hb-map.hh       |  2 +-
+ src/hb-open-type.hh | 10 +++++-----
+ src/hb-set.hh       |  2 +-
+ src/hb.hh           | 12 ++++++------
+ 4 files changed, 13 insertions(+), 13 deletions(-)
+
+commit edfc6be4a0362efa5c1d39f4792a28b5726c3ce5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 10 15:53:48 2019 -0400
+
+    [arabic] Disable fallback shaping if HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK defined
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-arabic-fallback.hh | 1 -
+ src/hb-ot-shape-complex-arabic.cc          | 4 ++++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit 4d31662b5da20790f6f860cec8f5fdabf48210f0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 10 15:40:03 2019 -0400
+
+    Don't install ot-font funcs on new fonts if HB_NO_OT_FONT defined
+    
+    Currently linker cannot GC hb-ot-font completely because we install
+    it on fonts by default.  Don't do that if HB_NO_OT_FONT defined.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit b111b3de020cde6fb0686efc224cace4608f2e45
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 10 15:38:15 2019 -0400
+
+    Don't use any default unicode funcs if HB_NO_UNICODE_FUNCS is defined
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-unicode.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit c5509be93a351177724f2891dd5e9ddb02553452
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 8 14:50:58 2019 -0400
+
+    [coretext] Fix unused-variable error
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1659
+
+ src/hb-coretext.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c19aa26204d0dc2f08b6e4a824e9088301f68d8
+Author: Maks Naumov <maksqwe1 at ukr.net>
+Date:   Fri Apr 5 21:46:27 2019 +0300
+
+    Fix MSVC C4068 warning (#1656)
+
+ src/hb-blob.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e44b83aac0443bd23df15b505a3d638883621b0e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Apr 5 10:15:08 2019 -0700
+
+    replace test font SourceHanSans with its subet
+
+ ...gular.default.3042,3044,3046,3048,304A,304B.otf |    Bin 6356 -> 0 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6564 -> 0 bytes
+ .../SourceHanSans-Regular.default.61,63,65,6B.otf  |    Bin 5532 -> 0 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6780 -> 0 bytes
+ .../SourceHanSans-Regular.default.660E.otf         |    Bin 5248 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 537992 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 692312 -> 0 bytes
+ ...ular.desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 531624 -> 0 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 692496 -> 0 bytes
+ ...ans-Regular.desubroutinize-retain-gids.660E.otf |    Bin 613836 -> 0 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 6272 -> 0 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6456 -> 0 bytes
+ ...eHanSans-Regular.desubroutinize.61,63,65,6B.otf |    Bin 5460 -> 0 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6572 -> 0 bytes
+ .../SourceHanSans-Regular.desubroutinize.660E.otf  |    Bin 5224 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 537424 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 691692 -> 0 bytes
+ ...ints-desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 531124 -> 0 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 691808 -> 0 bytes
+ ....drop-hints-desubroutinize-retain-gids.660E.otf |    Bin 613348 -> 0 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 6096 -> 0 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6204 -> 0 bytes
+ ...gular.drop-hints-desubroutinize.61,63,65,6B.otf |    Bin 5344 -> 0 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6268 -> 0 bytes
+ ...Sans-Regular.drop-hints-desubroutinize.660E.otf |    Bin 5120 -> 0 bytes
+ ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 537492 -> 0 bytes
+ ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 691788 -> 0 bytes
+ ...-Regular.drop-hints-retain-gids.61,63,65,6B.otf |    Bin 531164 -> 0 bytes
+ ...-Regular.drop-hints-retain-gids.61,63,65,6B.ttx | 393879 ------------------
+ ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 692008 -> 0 bytes
+ ...HanSans-Regular.drop-hints-retain-gids.660E.otf |    Bin 613368 -> 0 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.otf |    Bin 6164 -> 0 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6300 -> 0 bytes
+ ...ourceHanSans-Regular.drop-hints.61,63,65,6B.otf |    Bin 5376 -> 0 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6472 -> 0 bytes
+ .../SourceHanSans-Regular.drop-hints.660E.otf      |    Bin 5140 -> 0 bytes
+ ...r.retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 538076 -> 0 bytes
+ ...r.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 692420 -> 0 bytes
+ ...urceHanSans-Regular.retain-gids.61,63,65,6B.otf |    Bin 531704 -> 0 bytes
+ ...r.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 692700 -> 0 bytes
+ .../SourceHanSans-Regular.retain-gids.660E.otf     |    Bin 613860 -> 0 bytes
+ ...ubset.default.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 3028 bytes
+ ...ubset.default.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 3240 bytes
+ ...eHanSans-Regular_subset.default.61,63,65,6B.otf |    Bin 0 -> 2200 bytes
+ ...ubset.default.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 3460 bytes
+ .../SourceHanSans-Regular_subset.default.660E.otf  |    Bin 0 -> 1920 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 90956 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 125820 bytes
+ ...bset.desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 0 -> 88392 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 126004 bytes
+ ...ular_subset.desubroutinize-retain-gids.660E.otf |    Bin 0 -> 103780 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 2952 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 3136 bytes
+ ...s-Regular_subset.desubroutinize.61,63,65,6B.otf |    Bin 0 -> 2132 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 3256 bytes
+ ...eHanSans-Regular_subset.desubroutinize.660E.otf |    Bin 0 -> 1896 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 90656 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 125468 bytes
+ ...ints-desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 0 -> 88156 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 125584 bytes
+ ....drop-hints-desubroutinize-retain-gids.660E.otf |    Bin 0 -> 103556 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 2792 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 2896 bytes
+ ...ubset.drop-hints-desubroutinize.61,63,65,6B.otf |    Bin 0 -> 2028 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 2964 bytes
+ ...gular_subset.drop-hints-desubroutinize.660E.otf |    Bin 0 -> 1804 bytes
+ ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 90724 bytes
+ ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 125560 bytes
+ ...r_subset.drop-hints-retain-gids.61,63,65,6B.otf |    Bin 0 -> 88196 bytes
+ ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 125780 bytes
+ ...-Regular_subset.drop-hints-retain-gids.660E.otf |    Bin 0 -> 103572 bytes
+ ...et.drop-hints.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 2848 bytes
+ ...et.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 2988 bytes
+ ...nSans-Regular_subset.drop-hints.61,63,65,6B.otf |    Bin 0 -> 2060 bytes
+ ...et.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 3164 bytes
+ ...ourceHanSans-Regular_subset.drop-hints.660E.otf |    Bin 0 -> 1824 bytes
+ ...t.retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 91040 bytes
+ ...t.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 125924 bytes
+ ...Sans-Regular_subset.retain-gids.61,63,65,6B.otf |    Bin 0 -> 88468 bytes
+ ...t.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 126208 bytes
+ ...urceHanSans-Regular_subset.retain-gids.660E.otf |    Bin 0 -> 103800 bytes
+ test/subset/data/fonts/SourceHanSans-Regular.otf   |    Bin 16427580 -> 0 bytes
+ .../data/fonts/SourceHanSans-Regular_subset.otf    |    Bin 0 -> 2707728 bytes
+ test/subset/data/tests/cff-japanese.tests          |      2 +-
+ 84 files changed, 1 insertion(+), 393880 deletions(-)
+
+commit a96d003d6ec4212fadad4f5b9058c9f8b07bcf89
+Author: Maks Naumov <maksqwe1 at ukr.net>
+Date:   Fri Apr 5 12:29:56 2019 +0300
+
+    Fix MSVC C4138 warning (#1657)
+
+ src/hb-ot-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c68eb7002f1c2b847d955797e27f5403199e3d9d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 16:24:12 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 85adf4ad5c76172514f281bfbe3850ef35473cc7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 16:06:55 2019 -0700
+
+    [GDEF] Don't assume glyphlist is sorted
+    
+    As was hit by the fuzzer.
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14032
+
+ src/hb-ot-layout-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit ecabdffc61cb0b71424f4845aeda8cd0a6d25a29
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 16:06:34 2019 -0700
+
+    [algs] Add hb_min() and hb_max()
+
+ src/hb-algs.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 7b863142ceb82fc2fd23802f19f7379aa2f152e5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 15:48:27 2019 -0700
+
+    [serialize] Make putting breakpoint on out-of-memory easier
+
+ src/hb-serialize.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 2bd275023405b6a669d59ad4cdcb2e8cb410d593
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 15:31:53 2019 -0700
+
+    [iter] Tweak SFINAE again
+    
+    Don't think we need hb_is_same().
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f02ebc89ec89e78a348f9b67d613a2024feabc18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 15:23:06 2019 -0700
+
+    [array] Add compy assignment operator since copy constructor is explicit
+
+ src/hb-array.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 20a73da2c9227a0f9bc943a3d766eedeb5bed3b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 14:32:15 2019 -0700
+
+    [array] Add default copy constructor
+    
+    MSVC seems to need it.
+
+ src/hb-array.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit d419a9a4376de7b2ae1dec7df09f8d034cc2d039
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 14:18:19 2019 -0700
+
+    [iter] Use different SFINAE scheme to make MSVC happy
+    
+    From Orvid King: TLDR; MSVC has some issues using sizeof(declval<T>()) for
+    SFINAE of templated types, so I just used SFINAE in a different context where
+    MSVC doesn't have the issue.
+
+ src/hb-iter.hh | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+commit 2778df7972f537192b51cd0719adf2ab4d1f3397
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 3 14:15:01 2019 -0700
+
+    [meta] Add hb_is_same()
+
+ src/hb-meta.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 6215fb8e68bdf69f4af9f7f4959ad55a70723774
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 23:10:03 2019 -0700
+
+    [serialize] Actually reclaim storage from duplicate objects
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3305a2cad24f878f5d8773c2acae491ebd5a9059
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 22:42:22 2019 -0700
+
+    [serialize] Port to use object pool
+    
+    Tested, but feels fragile :(.
+
+ src/hb-pool.hh      |   5 +-
+ src/hb-serialize.hh | 141 ++++++++++++++++++++++++++++++++--------------------
+ 2 files changed, 91 insertions(+), 55 deletions(-)
+
+commit 5efbc01174127bede4d533866acac239e5a0cfd5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 22:41:06 2019 -0700
+
+    [pool] Uses memset() instead of assigning Null()
+    
+    Assignment is invalid on invalid object.
+
+ src/hb-pool.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 434d78bf91ac5204ffbf2144f199eb7a0f65c421
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 21:46:40 2019 -0700
+
+    Add hb_pool_t<> for pooled memory allocation
+
+ src/Makefile.sources |  1 +
+ src/hb-pool.hh       | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 99 insertions(+)
+
+commit 8e4df1a152f3916613594fa1bac308efdb61d512
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 20:20:53 2019 -0700
+
+    [serialize] Disable packed_map again
+    
+    Ugh.  Need to think of something else.
+
+ src/hb-serialize.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 31c1a83899147310b27bd40fac755c629cb59cef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 20:17:27 2019 -0700
+
+    [map] Protect more against pointer deref
+
+ src/hb-map.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 5bffa9e375fe294718452ad51e4c5ff017a046b4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 20:13:16 2019 -0700
+
+    More
+
+ src/hb-map.hh    | 5 +++++
+ src/hb-set.hh    | 9 ++++++++-
+ src/hb-vector.hh | 8 ++++----
+ 3 files changed, 17 insertions(+), 5 deletions(-)
+
+commit 5b66b033fd2cd9c95284d283f08d6789c7ec985d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 19:27:02 2019 -0700
+
+    [serialize] Fix hb_hashmap_t<> for pointers and use in packed_map
+
+ src/hb-array.hh     | 12 +++++++++++-
+ src/hb-map.hh       | 22 ++++++++++++++--------
+ src/hb-serialize.hh |  8 +++-----
+ src/hb-vector.hh    |  1 +
+ 4 files changed, 29 insertions(+), 14 deletions(-)
+
+commit 42ab32cbbaf8b403c351953f091c0fbe8464c4cb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 18:41:33 2019 -0700
+
+    [iter] Remove passing pointer to hb_iter()
+    
+    While doable with hb_deref_pointer() as well, we also would then
+    need to do it in a ton of places.  Not worth it / messy.
+
+ src/hb-array.hh  | 2 +-
+ src/hb-iter.hh   | 5 -----
+ src/test-iter.cc | 3 ---
+ 3 files changed, 1 insertion(+), 9 deletions(-)
+
+commit d0da547b3741323493398eed8975a76f4a5742c2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 18:22:39 2019 -0700
+
+    [array] Use dagger for hashing array
+    
+    Also switch to better mixing.
+
+ src/hb-array.hh | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit b6f29bf14153cac51b218e3aaba9e1b3aa747a8c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 18:12:01 2019 -0700
+
+    [iter] Accept pointers in hb_iter()
+    
+    No idea how to avoid dupicating code.  Was hoping hb_deref_pointer()
+    would do it, but looks like a pointer can't bind to a universal
+    reference T&&.  Humm.
+
+ src/hb-iter.hh   | 5 +++++
+ src/test-iter.cc | 3 +++
+ 2 files changed, 8 insertions(+)
+
+commit fc24bb9046e7e39d52a245bdc3480a30095cb6ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 17:49:52 2019 -0700
+
+    [serialize] Towards maintaining packed_map
+
+ src/hb-serialize.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit aa2293a55eaa39f4e77b60851bbdee56b1120225
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 17:42:10 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-open-type.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit e42b82c828ecec6f534040dae5518e04643b5f10
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 17:21:54 2019 -0700
+
+    [serialize] Handle non-nullable offsets
+
+ src/hb-open-type.hh | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+commit e04518bafc66224887bf7f478e1affb54bc7acd0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 17:20:04 2019 -0700
+
+    [serialize] Movce empty-object handling earlier
+
+ src/hb-serialize.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 7f73c9744e6c0e8dd37a208b75a4bc299bccbd4d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 17:12:24 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-open-type.hh | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+commit 5a3de4f4f8791139d2c04a66244001aba192ef6b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 2 16:53:05 2019 -0700
+
+    [serialize] Allow offset links that have base offset from the object base
+    
+    Rarely used, but used, in name table or similar constructs.
+
+ src/hb-serialize.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit edad6b2c450e22e67ae86c5f2328cca3c29aaad2
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Apr 3 00:48:59 2019 +0430
+
+    [test][iter] minor, fix double promotion warning
+
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 062f5d6e7aa061358eb5874a8f3a3f3bd6e9f16f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 2 20:27:00 2019 +0430
+
+    [test] minor, c style comments
+
+ src/test-iter.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit afdbf960d6147ec607ddb2c780d3a83068f61357
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 2 20:25:06 2019 +0430
+
+    [iter][test] Add another test for hb_reduce
+    
+    Different initial and accumulator types
+
+ src/test-iter.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit bfa02bef4546f448e048288c1162988c8c39322a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 1 21:36:13 2019 -0700
+
+    [serialize] Switch to tetris-packing
+
+ src/hb-open-type.hh | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+commit f0ea3ac17bef98409d302b9f285e94015e069823
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 1 21:36:03 2019 -0700
+
+    [serialize] Fix linking
+
+ src/hb-serialize.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 7c0e2054e0799ed89cdc5de8c1416d009c0029b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 1 21:32:29 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 64d0f0893812fa1cb2746071d8b021560969526d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 1 16:50:28 2019 -0700
+
+    [cmap] Minor
+
+ src/hb-ot-cmap-table.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 2e675cc7b50b5a57ceddf799d63811801ffcfe94
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 1 16:45:50 2019 -0700
+
+    [subset] Call serialize start/end around it
+    
+    To be cleaned up.
+
+ src/hb-subset.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit abe33c6149719eb371c5f2b0d8c143550938129e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 1 16:45:40 2019 -0700
+
+    [serialize] Assert stack
+
+ src/hb-serialize.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 72e9b2c16cd1bc183226ca0aa8a58a5b1222573d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 1 16:17:30 2019 -0700
+
+    [serialize] Add add_link() to add link
+
+ src/hb-serialize.hh | 26 +++++++++++++++++++++++---
+ 1 file changed, 23 insertions(+), 3 deletions(-)
+
+commit 74addbecac3b8be699ac90b3853970f6c7efd0eb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 1 14:17:09 2019 -0700
+
+    [serialize] Add default template type to push()
+
+ src/hb-serialize.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit b8642087e6c2ec96dc70fcef617128b6ce353a7e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 2 00:30:06 2019 +0430
+
+    [iter] hb_reduce, accumulator with a different type
+
+ src/hb-iter.hh   | 22 ++++++++++++----------
+ src/test-iter.cc | 26 +++++++++++++++++++++++++-
+ 2 files changed, 37 insertions(+), 11 deletions(-)
+
+commit e526414c759ebca82f1071cdeafe1160bcaa9637
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Mar 31 12:41:58 2019 +0430
+
+    [iter] Implement hb_reduce
+
+ src/hb-iter.hh   | 28 ++++++++++++++++++++++++++++
+ src/test-iter.cc |  5 +++++
+ 2 files changed, 33 insertions(+)
+
+commit f3aca6aa267f7687a0406c7c545aefb5eed300b2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Mar 31 21:37:14 2019 -0700
+
+    [serialize] Implement linking
+    
+    Untested!
+
+ src/hb-serialize.hh | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+commit 17f0cfa7ea3a5f0946d8800b98c1582c05dad853
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Mar 31 21:34:19 2019 -0700
+
+    Move BEInt to hb.hh
+    
+    I knows...
+
+ src/hb-machinery.hh | 88 ----------------------------------------------------
+ src/hb.hh           | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 89 insertions(+), 88 deletions(-)
+
+commit 78fc43f2930064cd6cf4229c1e4cb76edb8ed7f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Mar 31 19:17:07 2019 -0700
+
+    [iter] Fix up build, ouch
+    
+    Yeah, some things not very clear...
+
+ src/hb-iter.hh   | 8 ++++++--
+ src/test-iter.cc | 4 ++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+commit e5d6fe9782a9fcde0786392c075c6c0b85c24829
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Sun Mar 31 19:17:32 2019 +0100
+
+    Don't skip setting the .end field of the first range
+    
+    Fixes a bug in CoverageFormat2::serialize whereby the first range
+    was not serialized correctly if it consists of only a single glyph ID.
+    This broke shaping of U+0626 in the Arabic fallback shaper, because it
+    is not found in the coverage table of the 'init' and 'medi' lookups.
+    
+    Also fix similar bug in ClassDefFormat2::serialize, noted during code
+    inspection (I haven't observed a case that was actually affected by
+    this, but it looks broken).
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1504
+
+ src/hb-ot-layout-common.hh | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit 8a8d45b924cdb4343b4b11a7ef14e2d1fabb6f82
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Mar 31 19:00:09 2019 -0700
+
+    [iter] Adjust hb_copy() and use it
+    
+    Untested.
+
+ src/hb-iter.hh   | 11 ++++-------
+ src/hb-vector.hh |  4 ++--
+ 2 files changed, 6 insertions(+), 9 deletions(-)
+
+commit ba4b7be45523e88c26f763f8a329cc43c13b98a1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Mar 31 01:32:30 2019 -0700
+
+    Remove coretext_aat shaper (#1581)
+    
+    coretext_aat was a temporary shaper to redirect shaping of AAT fonts
+    to CoreText and leaving the rest for HarfBuzz.  As HarfBuzz now supports
+    AAT and Chrome now actually ships that on a stable version on macOS,
+    we no longer care about such use-case.  If a client really wants 100%
+    metrics compatibility with CoreText better to use it directly or through
+    our API.  Replicating the same behavior still is possible using
+    hb_shape_full, something we don't care or like to offer anymore.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1478
+
+ src/hb-coretext.cc    | 56 ---------------------------------------------------
+ src/hb-shaper-list.hh |  4 ----
+ 2 files changed, 60 deletions(-)
+
+commit d6005b49b32410543a8dfa93ce2a213223cf8f01
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:49:56 2019 -0700
+
+    [serialize] Start implementing linking
+
+ src/hb-serialize.hh | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+commit 313b3057c335da6baa4cd447bac95812992413b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:46:35 2019 -0700
+
+    [serializer] Implement dedup!
+
+ src/hb-serialize.hh | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+commit b189bbc48fb4b7c251d30b26a57ad84d1cb6dbe4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:41:48 2019 -0700
+
+    Implement hashing of objects
+    
+    Should be improved for hb_bytes_t.
+
+ src/hb-algs.hh      |  2 +-
+ src/hb-array.hh     | 13 +++++++++++++
+ src/hb-serialize.hh |  5 +++++
+ src/hb-vector.hh    |  5 +++++
+ 4 files changed, 24 insertions(+), 1 deletion(-)
+
+commit d6b28057a5cc636138cd453947d3a2008f18729f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:31:51 2019 -0700
+
+    Fix hb_hash(pointer)
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d74dc3ef65a159fe585e906deccdb32b570433aa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:26:37 2019 -0700
+
+    [serialize] Don't insert empty object into tree
+
+ src/hb-serialize.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 7fd82283263f8caded4870d6e12f74c7e660fa8d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:16:20 2019 -0700
+
+    [serialize] Towards maintaining hashmap
+
+ src/hb-algs.hh      |  2 +-
+ src/hb-serialize.hh | 16 ++++++++++++++--
+ src/hb-vector.hh    |  1 +
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+commit f254f45a1e6b1de6d83c97033773d20408772763
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:05:51 2019 -0700
+
+    [serialize] Only pack main object if there are other objects
+    
+    Avoids a memmove for tables that don't use the object packing mechanism.
+
+ src/hb-serialize.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit 946d446f9b795f657d56ca443edbc0b77d660a50
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:03:55 2019 -0700
+
+    [serialize] Copy both sides of the buffer
+
+ src/hb-serialize.hh | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+commit 8512dc565d310e9fd80d831282736284cc3ecd2e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 19:01:23 2019 -0700
+
+    [serialize] Simplify copy
+
+ src/hb-serialize.hh | 22 +++++++---------------
+ 1 file changed, 7 insertions(+), 15 deletions(-)
+
+commit 0b1fe7b716628f7b7b4098da9ef544e1518008f5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 18:48:26 2019 -0700
+
+    [serializer] Unbreak for now
+
+ src/hb-serialize.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 10f062234eb7c762a36cf750e75fe6f74ee89a3d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 18:44:01 2019 -0700
+
+    [map] Shuffle fini code
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e6b78003efbe02ba4542cadcc13bc1dd0b1d57b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 18:33:30 2019 -0700
+
+    [vector] Add move semantics
+
+ src/hb-vector.hh | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit 4c4d3c3ed55a8f1eea20593c08322e61fe1cdd3c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 18:30:50 2019 -0700
+
+    [vector] Add some move and forwarding
+
+ src/hb-serialize.hh | 2 +-
+ src/hb-vector.hh    | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 7c9ceabcef426ca6fc54b70db9dd8cb63937710b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 18:19:36 2019 -0700
+
+    [meta] Add hb_move and hb_forward ala std::
+
+ src/hb-meta.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 9a19b885f9136b0b7cdfa04679274cd4b6d16188
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 18:14:30 2019 -0700
+
+    [serialize] Flesh out packing
+
+ src/hb-serialize.hh | 58 +++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 34 insertions(+), 24 deletions(-)
+
+commit 357c7c611cc20f86c646bd2d392c243140f92d34
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 18:13:57 2019 -0700
+
+    [vector] Add copy constructor and assignment operator
+
+ src/hb-vector.hh | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+commit 6f69c9d26fa53cd8a2331395bbc146bfc85fd1e3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 18:00:03 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-serialize.hh | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit a43290192beedc6335efc3841c05ec7fa54e8871
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 17:51:26 2019 -0700
+
+    [serialize] Add packed_map
+
+ src/hb-map.hh       |  7 +++++++
+ src/hb-serialize.hh | 24 +++++++++++++++++++++---
+ 2 files changed, 28 insertions(+), 3 deletions(-)
+
+commit bed150bd2e8d61950ea17d1b5a4bf4705801c1cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 17:26:35 2019 -0700
+
+    [serialize] Start fleshing out object stack
+
+ src/hb-serialize.hh | 91 ++++++++++++++++++++++++++++++++++++++---------------
+ src/hb-vector.hh    |  9 ++++--
+ 2 files changed, 72 insertions(+), 28 deletions(-)
+
+commit 63c35651893b2a1c555f728012e9ad36c0f84145
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 17:12:40 2019 -0700
+
+    [serialize] Simplify propagate_error()
+
+ src/hb-serialize.hh | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+commit dbe9ba6711c6d35374de645097babfd81bc295b2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 17:10:59 2019 -0700
+
+    [serialize] Add object_t, link_t, and snapshot_t
+
+ src/hb-serialize.hh | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+commit 38d57b9a66008c9722125d4d677d759a910cf2a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 16:38:06 2019 -0700
+
+    [map] Add another TODO item
+
+ src/hb-map.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 7fd940f899da4948d2c61ed497c1face42776187
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 16:29:19 2019 -0700
+
+    [map] Add TODO
+
+ src/hb-map.hh | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit 6dcf7c4017619c782dbc8bd2c584bb33df96fc83
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 15:08:39 2019 -0700
+
+    [serialize] Add unused 'tail'
+
+ src/hb-serialize.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit fe05e48086be9ed685b8a6ca4af966660744bc0f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 15:06:25 2019 -0700
+
+    [serialize] Add ran_out_of_room
+
+ src/hb-serialize.hh | 8 +++++++-
+ src/hb-subset.cc    | 7 ++++++-
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+commit a7c63cd8f8475c6de7fd5bb6444bf5d24082a191
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 14:59:40 2019 -0700
+
+    Split sanitize and dispatch into their own files
+
+ src/Makefile.sources |   2 +
+ src/hb-dispatch.hh   |  50 +++++++
+ src/hb-machinery.hh  | 369 +-----------------------------------------------
+ src/hb-sanitize.hh   | 388 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 442 insertions(+), 367 deletions(-)
+
+commit be66b575fc15dbbe82cf1a7fa0b58020e86cffdc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 14:53:54 2019 -0700
+
+    Move serializer to hb-serialize.hh
+
+ src/Makefile.sources |   1 +
+ src/hb-machinery.hh  | 164 +-----------------------------------------
+ src/hb-serialize.hh  | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 198 insertions(+), 163 deletions(-)
+
+commit bb22462f292995a724bf20363adf52d3a8357a97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 14:46:54 2019 -0700
+
+    Whitespace
+
+ src/hb-machinery.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit ef33b5d1f6d3ec21e15ad74ca2524a117f594e06
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 14:39:21 2019 -0700
+
+    [map] Deref pointers before equality check
+
+ src/hb-map.hh  | 6 ++++--
+ src/hb-meta.hh | 4 ++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+commit c98f51da719d1792bf23b53a9a345926056bf34d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 14:30:22 2019 -0700
+
+    [map] Templatize hb_map_t
+    
+    Template name is hb_hashmap_t<K,V>.
+
+ src/hb-map.hh | 65 ++++++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 37 insertions(+), 28 deletions(-)
+
+commit 4b7f4dbc0cf58d87f4c91f059734e91e4d988480
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Mar 30 13:48:32 2019 -0700
+
+    Add hb_deref_pointer()
+
+ src/hb-algs.hh | 18 +++++++++++++-----
+ src/hb-meta.hh |  8 ++++++++
+ 2 files changed, 21 insertions(+), 5 deletions(-)
+
+commit e5306927994e8e412dea5dd960b8b3ed4ca848eb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 23:31:07 2019 -0700
+
+    [iter] Fix bug in hb_any() and hb_none()
+
+ src/hb-iter.hh               |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh | 12 ++++++------
+ src/test-iter.cc             |  2 +-
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+commit f505b5d5c9c05741a933b4b986503e1697bbdfdb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 22:55:02 2019 -0700
+
+    [iter] Port remaining "for (auto" instances to daggers
+
+ src/hb-ot-layout-gsubgpos.hh | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+commit 668d2d562fec797d779c6d6a43eb6e1c7cfbc07a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 22:48:38 2019 -0700
+
+    [iter] One more dagger
+
+ src/hb-ot-layout-gsubgpos.hh | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+commit d51452500f909803a346f26c71cf4b3f84f619bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 22:48:12 2019 -0700
+
+    [iter] Remove more wrong &&'s
+    
+    Sigh...
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 05f2130a1c479afe7982e8ddcfb3d83af9960e5b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 22:40:13 2019 -0700
+
+    [iter] More daggers
+
+ src/hb-ot-layout-gsubgpos.hh | 110 +++++++++++++++++++++++++------------------
+ 1 file changed, 64 insertions(+), 46 deletions(-)
+
+commit 22ec4c3aa5aa41b7aa2a89290851ddd386273579
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 22:27:46 2019 -0700
+
+    [iter] More daggers
+
+ src/hb-ot-layout-gsubgpos.hh | 55 ++++++++++++++++++++++++++------------------
+ 1 file changed, 33 insertions(+), 22 deletions(-)
+
+commit 688069bbfb40d69fb141371633cd499d91324cc2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 22:17:31 2019 -0700
+
+    [iter] One more dagger
+
+ src/hb-ot-layout-gsub-table.hh | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+commit 90b60bd6909ffc6d0bff3e6901057439460407ca
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 22:12:42 2019 -0700
+
+    Remove HB_DEBUG_WOULD_APPLY
+    
+    Not that useful.
+
+ src/hb-debug.hh                | 15 +---------
+ src/hb-ot-layout-gsub-table.hh | 49 ++++++++++----------------------
+ src/hb-ot-layout-gsubgpos.hh   | 64 ++++++++++++++++++------------------------
+ 3 files changed, 43 insertions(+), 85 deletions(-)
+
+commit 4d28267e59406cc85761131b84c5b2b4c65c6b35
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 22:04:15 2019 -0700
+
+    [iter] Port more to daggers
+
+ src/hb-ot-layout-gsub-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 9d8c72042b4a023b55cb39779407fdecaf098af1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:59:28 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gpos-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 418e9d07e2120f806852312f4c74204fa085a6cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:57:26 2019 -0700
+
+    Simplify code
+
+ src/hb-ot-layout-gsub-table.hh | 20 +++-----------------
+ 1 file changed, 3 insertions(+), 17 deletions(-)
+
+commit f5ef8a7347656ad5f5bb8cec5f9a3de262a79411
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:57:17 2019 -0700
+
+    [iter] Port one more function to dagger
+
+ src/hb-ot-layout-gpos-table.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit bcab098c8f35ac4bef6618d949a7bf1d95869fa5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:49:18 2019 -0700
+
+    [iter] Port more code to daggers
+
+ src/hb-ot-layout-gsub-table.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 4c75158e1803e73d6126f715aa4b22ebe30aa7c7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:46:13 2019 -0700
+
+    [iter] Port two more functions to daggers
+
+ src/hb-ot-layout-gsub-table.hh | 29 +++++++++++++++++------------
+ 1 file changed, 17 insertions(+), 12 deletions(-)
+
+commit e70ccbe9edd4d5e033df4afa728b3593ba9f78af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:45:49 2019 -0700
+
+    Fix pair signature
+    
+    Oh well.  Again, who does fully understand what is right???
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6237b47f0c59fd3913b19b23800cdf83eaa01fb6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:36:49 2019 -0700
+
+    [iter] Add hb_unzip()
+
+ src/hb-iter.hh | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+commit f1dad91eb3ce9dcdedbb4a0d6e34517db0154a84
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:17:08 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 896b31670d07cbe276feff1db249b64faa5c552c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:16:30 2019 -0700
+
+    [iter] Port two more loops to dagger
+
+ src/hb-ot-layout-gsub-table.hh | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit 8e34cb251a9b22d6fbc637fd2f25965beb260270
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:14:20 2019 -0700
+
+    [iter] Remove unneeded &&
+    
+    Next commit needs this.  I never fully get this, sigh.
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 12a4c0441ff13e56bb87f53eab45930c2a6142ed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 21:06:10 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 4c38a9f6011a9b1dd6c4fc98620e23decc340322
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 20:23:07 2019 -0700
+
+    Remove hb_assign()
+    
+    Not needed anymore.  We just use operator= now.
+
+ src/hb-iter.hh      |  2 +-
+ src/hb-machinery.hh |  2 +-
+ src/hb-null.hh      | 13 -------------
+ src/hb-open-type.hh |  2 +-
+ 4 files changed, 3 insertions(+), 16 deletions(-)
+
+commit b986c6a321f7d997eba0a9308b651966644bf336
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 20:17:46 2019 -0700
+
+    [C++11] Remove IntType::set() in favor of operator=
+
+ src/hb-cff-interp-common.hh                |  4 +-
+ src/hb-ft.cc                               |  2 +-
+ src/hb-null.hh                             |  6 ---
+ src/hb-open-file.hh                        | 14 +++---
+ src/hb-open-type.hh                        | 43 +++++++++++------
+ src/hb-ot-cff-common.hh                    | 24 +++++-----
+ src/hb-ot-cff1-table.hh                    | 32 ++++++-------
+ src/hb-ot-cmap-table.hh                    | 77 +++++++++++++++---------------
+ src/hb-ot-glyf-table.hh                    |  2 +-
+ src/hb-ot-hdmx-table.hh                    | 12 ++---
+ src/hb-ot-hmtx-table.hh                    |  8 ++--
+ src/hb-ot-layout-common.hh                 | 44 ++++++++---------
+ src/hb-ot-layout-gdef-table.hh             |  8 ++--
+ src/hb-ot-layout-gsub-table.hh             | 18 +++----
+ src/hb-ot-maxp-table.hh                    | 16 +++----
+ src/hb-ot-os2-table.hh                     | 10 ++--
+ src/hb-ot-post-table.hh                    |  2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh | 10 ++--
+ src/hb-ot-vorg-table.hh                    | 12 ++---
+ src/hb-subset-cff-common.cc                | 12 ++---
+ src/hb-subset-cff-common.hh                |  2 +-
+ src/hb-subset-cff1.cc                      | 10 ++--
+ src/hb-subset-cff2.cc                      |  8 ++--
+ src/hb-subset-glyf.cc                      |  8 ++--
+ src/hb-uniscribe.cc                        | 22 ++++-----
+ 25 files changed, 206 insertions(+), 200 deletions(-)
+
+commit 58ad357951a732f05d9680573d00a4764171a9dd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 20:05:19 2019 -0700
+
+    [vector] Accept all types in push(...)
+    
+    Let assignment operator worry about conversion.
+
+ src/hb-vector.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 489faf826ca16e9bc89515869ebaf52653450b54
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 20:01:37 2019 -0700
+
+    [C++11] Use type aliases for template partial instantiations
+
+ src/hb-open-type.hh | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+commit 4fd02f6ee58ebf7b4ecf0526328938c5bd74a180
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 17:57:59 2019 -0700
+
+    Remove unused line
+
+ src/hb-machinery.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 9a5b15dc1eda4f34496bb942d78f0df4e975b469
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 17:57:24 2019 -0700
+
+    [C++11] Replace BEInt.set() with operator=
+
+ src/hb-machinery.hh | 15 +++++++++++----
+ src/hb-open-type.hh |  8 ++++----
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+
+commit 0aa59b1de34ddebc242cca3ebddde6859269f5f1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 17:49:55 2019 -0700
+
+    [C++11] Add operator= to IntType<>
+    
+    Now that we require C++11 we can do this.
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit eca466e6b1a3e29532af92a2d30b2555c0fafbfc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 15:59:04 2019 -0700
+
+    Err.  Fixup C++11 polyfill removal
+    
+    Fixes 1d75db19fb5df139b9648ff3f5e6184a5c554345
+
+ src/hb.hh | 27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+commit 3f36c89f2ea16e293f8af7e7f549ebcd7247ea97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 15:22:46 2019 -0700
+
+    Inline explicit_operator macro
+    
+    Now that we require C++11, no need to macro.
+
+ src/hb-iter.hh      | 2 +-
+ src/hb-machinery.hh | 2 +-
+ src/hb-open-type.hh | 2 +-
+ src/hb-vector.hh    | 6 +++---
+ src/hb.hh           | 5 -----
+ 5 files changed, 6 insertions(+), 11 deletions(-)
+
+commit 1d75db19fb5df139b9648ff3f5e6184a5c554345
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 15:20:34 2019 -0700
+
+    Remove C++<11 polyfill
+    
+    Leaving hb-atomic.hh as is since harmless and other projects might
+    copy from that file.
+
+ src/hb.hh | 81 ---------------------------------------------------------------
+ 1 file changed, 81 deletions(-)
+
+commit 8e7887ca5f8a2822345bdcbdc873c73a31c81177
+Merge: 7929b0f0 90aebc6c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 14:37:04 2019 -0700
+
+    Merge branch 'master' into iter
+
+commit 90aebc6cf1aaca281ce51cb8e23831d7167cdcd3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 14:30:02 2019 -0700
+
+    Update RELEASING
+
+ RELEASING.md | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit 7929b0f07e87a77687ea50205e6e4013c9264f85
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 14:14:55 2019 -0700
+
+    [ci] Fix build
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b292772e6ef15728dd66329e637265748df0efe1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Mar 29 13:00:56 2019 -0700
+
+    [dwrite] A new API, hb_directwrite_face_get_font_face (#1600)
+    
+    Can be useful when using HarfBuzz for font loading and shaping
+    but using DirectWrite for rendering.
+
+ docs/harfbuzz-sections.txt | 10 ++++++++--
+ src/hb-directwrite.cc      | 34 ++++++++++++++++++++++++++++++----
+ src/hb-directwrite.h       |  3 +++
+ 3 files changed, 41 insertions(+), 6 deletions(-)
+
+commit 59f36f36820f6e6fb1d3b6da26d6b5ee7588c42f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 10:55:12 2019 -0700
+
+    Replace REPLACEME's left out of 2.4.0
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1641
+
+ src/hb-common.h        | 2 +-
+ src/hb-directwrite.cc  | 2 +-
+ src/hb-subset-input.cc | 4 ++--
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+commit fe570bc043ca2c6be71b18f7401c8f06e73527e0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 10:51:38 2019 -0700
+
+    [docs] Remove unexisting section
+
+ docs/harfbuzz-docs.xml | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 443db2a24624b63c49fa3ad9a10d3b4c523af1ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Mar 29 10:46:44 2019 -0700
+
+    [iter] Remove hb_len()
+    
+    Not planning on using it.  So remove.  Can add later if needed.
+
+ src/hb-iter.hh   | 8 --------
+ src/test-iter.cc | 2 --
+ 2 files changed, 10 deletions(-)
+
+commit bdd5a9c48d644b660f8fcac16902a576cc7ff443
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 21:58:07 2019 -0700
+
+    Add hb_hash()
+    
+    I don't like the hb_remove_reference() hack, but necessary.
+
+ src/hb-algs.hh | 17 +++++++++++++++++
+ src/hb-map.hh  | 10 +---------
+ src/hb.hh      |  2 +-
+ 3 files changed, 19 insertions(+), 10 deletions(-)
+
+commit 343e6063dcd512164a999f1d12bae50877392a82
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 21:44:12 2019 -0700
+
+    Add hb_is_integer(T)
+
+ src/hb-meta.hh | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit f639b9a8eab369bee6e36b3e60b585b4f720e77e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 21:34:47 2019 -0700
+
+    [iter] Add hb_len() function-object
+
+ src/hb-iter.hh   | 8 ++++++++
+ src/test-iter.cc | 2 ++
+ 2 files changed, 10 insertions(+)
+
+commit a030ce4ff83e0948e4f865accc5670e8b5e78dde
+Merge: 11456b2d d6fc1d49
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 21:26:50 2019 -0700
+
+    Merge branch 'master' into iter
+
 commit d6fc1d49aa099104a889c96bc9087c21d8fc0960
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Thu Mar 28 21:21:26 2019 -0700
@@ -539,6 +7603,60 @@
  src/hb-common.cc | 35 ++++++++++++++++++++++++++++++++++-
  1 file changed, 34 insertions(+), 1 deletion(-)
 
+commit 11456b2d9c1c567d1ad6496a3056154b69cafa21
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Fri Feb 15 16:58:43 2019 -0800
+
+    WHitespace
+
+ src/hb-ot-layout-gsubgpos.hh | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit 77060bcda229dc237d3952fbf5da59709cd81e05
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Fri Feb 15 16:55:08 2019 -0800
+
+    [iter] Add hb_all, hb_any, hb_none
+
+ src/hb-iter.hh   | 46 +++++++++++++++++++++++++++++++++++++++++++++-
+ src/test-iter.cc |  2 ++
+ 2 files changed, 47 insertions(+), 1 deletion(-)
+
+commit 72dd5e34e0fc2902857c39cd4609d40b71fa4736
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Fri Feb 15 16:11:32 2019 -0800
+
+    [iter] Make hb_iter() into function-object
+
+ src/hb-iter.hh | 28 +++++++++++++++++++---------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+commit 98be7bd77ada32e58dad76897cefcf1d99538d2b
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Fri Feb 15 16:09:29 2019 -0800
+
+    [iter] Make hb_map into function-object
+
+ src/hb-iter.hh | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit c1e5ba81fe4888143c1cf4a3deb3597875580c6d
+Merge: b8b3b3e3 3da79dd5
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Fri Feb 15 16:06:03 2019 -0800
+
+    Merge remote-tracking branch 'origin/master' into iter
+
+commit b8b3b3e38b08ee7bb8d44481dd25febcee693554
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Fri Feb 15 16:05:36 2019 -0800
+
+    [iter] Add hb_enumerate() and use it
+
+ src/hb-iter.hh               | 39 +++++++++++++++++++++++++++++++++++++--
+ src/hb-ot-layout-gsubgpos.hh | 32 ++++++++++++--------------------
+ 2 files changed, 49 insertions(+), 22 deletions(-)
+
 commit 3da79dd5b92b89fbf062cbe591e6b1ba83083aec
 Merge: 50005501 d8a68728
 Author: Behdad Esfahbod <behdad at behdad.org>
@@ -580,6 +7698,130 @@
  src/hb-atomic.hh | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
+commit 1558a43342e2c5649cf48cb5860ac8a7aa9faf1d
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 20:46:13 2019 -0800
+
+    [test] Minor
+
+ src/test-algs.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit fa373584def11c97d8a7db00d9abc04851ca9480
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 20:15:07 2019 -0800
+
+    [algs] Test pair more
+
+ src/test-algs.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 0d7af5fb02723d8f4e8ad93848e9abe384174b36
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 19:37:57 2019 -0800
+
+    [algs] Use universal references for hb_pair()
+    
+    Such that it carries lvalues inside.
+
+ src/Makefile.am  |  6 +++++-
+ src/hb-algs.hh   |  2 +-
+ src/test-algs.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 51 insertions(+), 2 deletions(-)
+
+commit 5b99c92d4c6e294bb328113308e5c9cd23b3ed67
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 17:10:04 2019 -0800
+
+    [iter] Use more
+
+ src/hb-iter.hh               |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh | 10 ++++------
+ 2 files changed, 6 insertions(+), 8 deletions(-)
+
+commit 72c1b59588bec30322abfa4de04b53e93122b25b
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 15:43:20 2019 -0800
+
+    [iter] Use in more places
+
+ src/hb-ot-layout-gsubgpos.hh | 48 ++++++++++++++++++--------------------------
+ 1 file changed, 20 insertions(+), 28 deletions(-)
+
+commit 40cce41eaeac731334251cccaa124407e6bffccb
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 15:14:37 2019 -0800
+
+    [iter] Use in a couple more intersects() calls
+
+ src/hb-ot-layout-gsubgpos.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit bafdf1829d15e658df55eabc0548e9ca71d18b1b
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 15:13:16 2019 -0800
+
+    [iter] Use in a couple more closure() calls
+
+ src/hb-ot-layout-gsubgpos.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit fa35d3fd81c1ddb847cdd83556f817db9ef7f35b
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 14:04:05 2019 -0800
+
+    [iter] Add hb_drain
+
+ src/hb-iter.hh   | 11 +++++++++++
+ src/test-iter.cc |  7 ++++++-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+commit f4cfd6b6adbe0a87fe565a29b6cd600cf86f65dd
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 13:45:52 2019 -0800
+
+    [iter] A couple more hb_apply() + lambda uses
+
+ src/hb-ot-layout-gsub-table.hh | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+commit 7514a49f217c42ae0c895755e305f1d5b75c759d
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 13:16:33 2019 -0800
+
+    [iter] Use hb_apply() with lambda functions in a few places
+
+ src/hb-ot-layout-gsub-table.hh | 30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+commit 0670e1a6f5d9938d30d5d0674ea10752d4a58114
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 11:53:40 2019 -0800
+
+    [iter] Remove excess use of universal references
+    
+    Every time I have to study these to understand why a change is right..
+
+ src/hb-iter.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 773d75637c36426b96be43f1188c68d77ac4ba47
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 11:40:22 2019 -0800
+
+    [iter] Add hb_apply()
+
+ src/hb-iter.hh   | 30 ++++++++++++++++++++++++++++++
+ src/test-iter.cc |  3 +++
+ 2 files changed, 33 insertions(+)
+
+commit 5b725784e53a96ba4d983184a2670aba2aa0fd9c
+Merge: 00db9409 28f77361
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 11:34:55 2019 -0800
+
+    Merge branch 'master' into iter
+
 commit 28f77361322886360743fdbffd388c9482cf4257
 Author: Behdad Esfahbod <behdad at fb.com>
 Date:   Thu Feb 14 11:34:28 2019 -0800
@@ -591,6 +7833,98 @@
  .circleci/config.yml | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
 
+commit 00db94095d53bd5e954be31caa428a3fd8f5f4c2
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 11:10:13 2019 -0800
+
+    [iter] Make hb_filter() a function-object
+
+ src/hb-iter.hh | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit aa4c3212628f6861f1ef3ecb9eb5205b5780ac91
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 11:07:12 2019 -0800
+
+    [iter] Make hb_zip() a function-object
+
+ src/hb-iter.hh | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit f8fcfb263e197c27015eeea56761b2dc8138da91
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 11:03:29 2019 -0800
+
+    [iter] Accept pointers to hb_sink()
+
+ src/hb-iter.hh                 | 4 ++++
+ src/hb-ot-layout-gsub-table.hh | 6 +++---
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+commit b530573ad9b30e06d5cecfd107941c573cd5d999
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 11:00:10 2019 -0800
+
+    [iter] Make hb_sink function-object
+
+ src/hb-iter.hh | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit bb139cb8d0e4339042c5d0d0f192e13707c2bda4
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 10:51:47 2019 -0800
+
+    [iter] Back to dagger formatting for pipelines
+
+ src/hb-ot-layout-gsub-table.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 5fa52e62b1744347970c42f42bbcd8d2e82d6c60
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 10:51:02 2019 -0800
+
+    [iter] Accept iterator, not iterable, in hb_sink()()
+
+ src/hb-iter.hh   | 8 ++++----
+ src/test-iter.cc | 1 +
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+commit 0f292ea85f54b3496fe87e6466acf43b76f57dcd
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 10:49:31 2019 -0800
+
+    [iter] Accept iterator, not iterable, in hb_filter()()
+
+ src/hb-iter.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 345bfbb207b4d1174ee0ec41cf35cdc2e14936ff
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 10:48:20 2019 -0800
+
+    [iter] Accept iterator, not iterable, in hb_map()()
+
+ src/hb-iter.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 16cc313dcd7d4ddf16451cadc118aeb680101384
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 10:40:05 2019 -0800
+
+    [iter] Use hb_sink()
+
+ src/hb-ot-layout-gsub-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit b702a0cbf8abae4622a99adf3a3b6adda3d9f2c1
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Thu Feb 14 10:39:58 2019 -0800
+
+    [iter] Add hb_sink()
+
+ src/hb-iter.hh | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
 commit 1cb1d5d7fb74e9f42dc8361dcdf669ed479d595d
 Merge: 8a568a88 d5287e1b
 Author: Michiharu Ariza <ariza at adobe.com>
@@ -605,6 +7939,29 @@
 
     Merge branch 'master' into cff-retain-gids
 
+commit 9e7383d124f1f1422f542720c76b4ee9605bda8b
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Wed Feb 13 23:54:36 2019 -0800
+
+    [CI] Disable cmake-oracledeveloperstudio bot
+    
+    Weird error:
+    
+    "/root/project/src/hb-iter.hh", line 277: Error: Type name expected instead of "decltype()".
+    "/root/project/src/hb-iter.hh", line 278: Error: Invalid type while substituting into Iter::item_t.
+    "/root/project/src/hb-iter.hh", line 317: Error: Type name expected instead of "decltype()".
+    "/root/project/src/hb-iter.hh", line 318: Error: Invalid type while substituting into Iter::item_t.
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4103252323b15a821f0a912b580c2107211b918f
+Merge: f1b89344 d5287e1b
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Wed Feb 13 23:46:43 2019 -0800
+
+    Merge branch 'master' into iter
+
 commit d5287e1ba40638be5d48178ce3d64557b622b01f
 Author: Behdad Esfahbod <behdad at fb.com>
 Date:   Wed Feb 13 23:46:17 2019 -0800
@@ -614,6 +7971,40 @@
  .circleci/config.yml | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
+commit f1b8934400137fe832909730ad86d73595612e9e
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Wed Feb 13 23:30:21 2019 -0800
+
+    [CI] Remove macos-notest-ios bot
+    
+    Not sure what ancient compiler it is (gcc 4.2?), but didn't like hb_zip SFINAE
+    apparently:
+    
+    In file included from /Users/distiller/project/src/hb-aat-layout.cc:28:
+    In file included from /Users/distiller/project/src/hb-open-type.hh:32:
+    In file included from /Users/distiller/project/src/hb.hh:642:
+    /Users/distiller/project/src/hb-iter.hh:364:1: note: candidate template ignored: substitution failure [with A = OT::Coverage, B = OT::OffsetArrayOf<OT::ChainRuleSet>]: non-type template argument does not refer to any declaration
+    hb_zip (const A& a, const B &b)
+    ^
+    In file included from /Users/distiller/project/src/hb-aat-layout.cc:37:
+    In file included from /Users/distiller/project/src/hb-aat-layout-kerx-table.hh:31:
+    In file included from /Users/distiller/project/src/hb-kern.hh:32:
+    /Users/distiller/project/src/hb-ot-layout-gpos-table.hh:725:20: error: no matching function for call to 'hb_zip'
+        for (auto it = hb_zip (this+coverage, pairSet)
+                       ^~~~~~
+    
+    Not going to try to appease.
+
+ .circleci/config.yml | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+commit 7d2376de336c7fc14d69e01add02115335f92db8
+Merge: 2d940946 890d0ee7
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Wed Feb 13 22:08:54 2019 -0800
+
+    Merge branch 'master' into iter
+
 commit 890d0ee77fecd6aa4f19b663bb2897735a0d4c0b
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Thu Feb 14 00:27:01 2019 +0330
@@ -1080,6 +8471,29 @@
 
     Merge branch 'master' into cff-more-arrayof-fixes
 
+commit 2d940946d5af0e3869a2324b6e36ca8ea3698c48
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 30 16:03:16 2019 -0800
+
+    [iter] Fix mystery crash
+    
+    Fuzzer caught it:
+    
+    ==14==ERROR: AddressSanitizer: stack-use-after-return on address 0x7fca2ed7a3e0 at pc 0x0000006057aa bp 0x7ffc3290f1d0 sp 0x7ffc3290f1c8
+    READ of size 4 at 0x7fca2ed7a3e0 thread T0
+    SCARINESS: 55 (4-byte-read-stack-use-after-return)
+        #0 0x6057a9 in OT::SingleSubstFormat2::subset(hb_subset_context_t*) const /src/harfbuzz/src/./hb-ot-layout-gsub-table.hh:194:40
+        #1 0x5ff921 in hb_subset_context_t::return_t OT::SingleSubst::dispatch<hb_subset_context_t>(hb_subset_context_t*) const /src/harfbuzz/src/./hb-ot-layout-gsub-table.hh:256:13
+    
+    I can't reproduce locally, but many of the bots are failing because of this
+    as well.
+    
+    It's a pity that operator-> must return pointer.  Ugh.  Why?!
+
+ src/hb-iter.hh                 | 4 ++++
+ src/hb-ot-layout-gsub-table.hh | 4 ++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
 commit d14d2c20b05c5acf0a6f9c6dc36a7b8d8966153e
 Merge: acf5f0a3 dc04261a
 Author: Behdad Esfahbod <behdad at behdad.org>
@@ -1099,6 +8513,13 @@
  test/fuzzing/hb-subset-fuzzer.cc | 32 +++++++++++++++++++-------------
  1 file changed, 19 insertions(+), 13 deletions(-)
 
+commit 2e675d49f2f705a5b5d95574a5336d5e670a0fba
+Merge: ede117dc acf5f0a3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 30 15:10:43 2019 -0800
+
+    Merge branch 'master' into iter
+
 commit acf5f0a3aff0e128509b0979f629edf0596fcee5
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Wed Jan 30 15:10:23 2019 -0800
@@ -1108,6 +8529,22 @@
  configure.ac | 11 +++++------
  1 file changed, 5 insertions(+), 6 deletions(-)
 
+commit ede117dc40d547cd457a420c9f7c9829cdb5f307
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 30 15:10:23 2019 -0800
+
+    [configure] Fix up
+
+ configure.ac | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit cbe2118c588622070612ba7ac7eae7496a092e3c
+Merge: 8b46c2d9 6b834c1c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 30 15:07:09 2019 -0800
+
+    Merge branch 'master' into iter
+
 commit 6b834c1c76b867ef32747202a755255d2f360f1e
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Wed Jan 30 15:06:22 2019 -0800
@@ -1117,6 +8554,52 @@
  configure.ac | 6 ++++++
  1 file changed, 6 insertions(+)
 
+commit 8b46c2d933b546a88799b08f4a74fd1285518ed5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 30 15:06:22 2019 -0800
+
+    [configure] Print compiler version info in report
+
+ configure.ac | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 4aa4eedfd5633ee84d37469c9625d12856dbc575
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 30 15:02:29 2019 -0800
+
+    [ci] Switch clang-O3-O0 bot to Ubuntu image
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1566
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7c292c0853140540f13f73d43ef7f7e0746e5f28
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 30 14:54:23 2019 -0800
+
+    [iter] Warning fix
+    
+    Not sure why I don't get it, but this warning:
+    
+    warning: base class ‘struct hb_iter_fallback_mixin_t<hb_array_t<const OT::UVSMapping>, const OT::UVSMapping&>’ should be explicitly initialized in the copy constructor [-Wextra]
+
+ src/hb-iter.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a84b0145ea799c9452ecb97713689247955d30ff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 30 14:42:48 2019 -0800
+
+    [ci] Disable -Wunused-template on -Weverything bot
+    
+    ./hb-algs.hh:37:3: error: unused function template 'operator()' [-Werror,-Wunused-template]
+      operator () (const T& v) const { return v; }
+      ^
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit d983c529b66b530715e9c813c69e699b1d8029d3
 Merge: 55d1d7c8 e6ffcc59
 Author: Behdad Esfahbod <behdad at behdad.org>
@@ -1137,6 +8620,63 @@
  src/hb-version.h | 4 ++--
  3 files changed, 10 insertions(+), 3 deletions(-)
 
+commit e799004e9f6821864b955a09673544d92e8b45e6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 29 17:15:12 2019 -0800
+
+    [iter] Whitespace
+
+ src/hb-iter.hh | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+commit 849a0f1758b67eb3b4d864047b9df671e76404a5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 29 17:10:19 2019 -0800
+
+    [iter] Add hb_iter_with_fallback_t instead
+
+ src/hb-array.hh            |  5 +----
+ src/hb-iter.hh             | 29 +++++++++++++----------------
+ src/hb-ot-layout-common.hh |  5 +----
+ src/hb-set.hh              |  5 +----
+ src/test-iter.cc           |  5 +----
+ 5 files changed, 17 insertions(+), 32 deletions(-)
+
+commit 4d40ed9d1a7a4f18af6710a1b8ba90257b8456a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 29 13:55:23 2019 -0800
+
+    [iter] Add hb_iter_with_mixin_t<>
+
+ src/hb-array.hh            |  5 +++--
+ src/hb-iter.hh             | 18 ++++++++++++++++--
+ src/hb-ot-layout-common.hh |  5 +++--
+ src/hb-set.hh              |  5 +++--
+ src/test-iter.cc           |  5 +++--
+ 5 files changed, 28 insertions(+), 10 deletions(-)
+
+commit 6521d5b201cb8df5a3c2657b4da703cf52472f81
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 29 13:44:39 2019 -0800
+
+    [iter] Export operator << / >>
+
+ src/hb-iter.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 84a25d79c649776a299526c087bf369a9705f89e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 29 13:39:19 2019 -0800
+
+    [iter] Rename
+
+ src/hb-array.hh            |  2 +-
+ src/hb-iter.hh             | 12 ++++++------
+ src/hb-ot-layout-common.hh |  2 +-
+ src/hb-set.hh              |  2 +-
+ src/test-iter.cc           |  2 +-
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
 commit e6ffcc5904ab88143cad0c7a7a4c990147af278b
 Author: Garret Rieger <grieger at google.com>
 Date:   Mon Jan 28 18:12:19 2019 -0800
@@ -1350,6 +8890,46 @@
 
     Merge branch 'master' into cff-more-arrayof-fixes
 
+commit e75b22039f4129b5057f4b175c9e9d79634b1728
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 21:26:23 2019 -0500
+
+    Move hb_addressof() to hb-meta.hh
+
+ src/hb-algs.hh | 12 ------------
+ src/hb-iter.hh |  1 -
+ src/hb-meta.hh | 14 +++++++++++++-
+ src/hb.hh      |  2 +-
+ 4 files changed, 14 insertions(+), 15 deletions(-)
+
+commit 6cf25c2971aa9a7471b1cc00176ef36e9acacad4
+Merge: 71157a45 fe532923
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 21:23:28 2019 -0500
+
+    Merge branch 'master' into iter
+
+commit 71157a4520ae5cdbbeb197a979ae02b484856686
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 21:20:12 2019 -0500
+
+    [meta] Remove _ft struct names
+    
+    Using decltype() instead.
+
+ src/hb-algs.hh | 8 ++++----
+ src/hb-iter.hh | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 9103bd056fadd73eab2531f632790920ce602f18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 21:16:51 2019 -0500
+
+    [pair] Use decltype
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
 commit fe532923101586e316b300d419a337d357cd93da
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Mon Jan 28 20:47:58 2019 -0500
@@ -1384,6 +8964,53 @@
  README.md | 19 ++++++++++++++++++-
  2 files changed, 19 insertions(+), 19 deletions(-)
 
+commit a30e13469e6d3ec6ff412211722d26f70a97e261
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 16:39:01 2019 -0500
+
+    [iter] Add operator << to set / vector
+
+ src/hb-set.hh    | 3 +++
+ src/hb-vector.hh | 3 +++
+ 2 files changed, 6 insertions(+)
+
+commit d438e610420d931a203b31332cf74d7e0f9dd3f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 16:34:04 2019 -0500
+
+    [iter] Fix operator() impls
+
+ src/hb-map.hh              | 5 +++--
+ src/hb-ot-layout-common.hh | 8 +++++---
+ src/hb-set.hh              | 3 ++-
+ 3 files changed, 10 insertions(+), 6 deletions(-)
+
+commit 57795bc8dd6a9ee894c2abb8633c271876b5f596
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 16:23:12 2019 -0500
+
+    [iter] Add operator>> and operator<<
+
+ src/hb-iter.hh   | 4 ++++
+ src/test-iter.cc | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+commit 8bd96be9940ca73e45138172f9f4178190566225
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 16:17:36 2019 -0500
+
+    [iter] Use auto c = C.iter() internally
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 073fa4ac5aff4ee72bbb38676bd351b5aa1ec167
+Merge: d592bd16 9a1df82e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 14:35:41 2019 -0500
+
+    Merge branch 'master' into iter
+
 commit 9a1df82e3f13fbd4488ee9955814bbb5d0957074
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Mon Jan 28 14:15:18 2019 -0500
@@ -1422,6 +9049,153 @@
  src/hb.hh | 3 +++
  1 file changed, 3 insertions(+)
 
+commit d592bd16cd6c5ad1ee351d90d213ee2a1ea71b05
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 28 13:41:40 2019 -0500
+
+    Try fixing MSVC build
+
+ src/hb-algs.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 0363ce650b6085f62e66aff4639aa203fa17d419
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 27 01:03:56 2019 +0100
+
+    [iter] Accept C arrays in hb_iter()
+
+ src/hb-array.hh  |  4 +---
+ src/hb-iter.hh   | 11 +++++++++++
+ src/test-iter.cc |  5 ++++-
+ 3 files changed, 16 insertions(+), 4 deletions(-)
+
+commit b62e7f9223a6369768bde2500efe1bd1d27a0ea2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 27 00:51:43 2019 +0100
+
+    [test] Test unary operator+
+    
+    "Test" as in compiles..
+
+ src/test-iter.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 778c96b8d7b86ae2a0fe944f499fa4a57c12e365
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 27 00:50:54 2019 +0100
+
+    [iter] Fix hb_iter()
+
+ src/hb-algs.hh   |  4 ----
+ src/hb-iter.hh   | 10 +++++++---
+ src/test-iter.cc |  2 +-
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 2f5b1a9104e5f4a14aa77a2f4c3c6e1c2837500c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 27 00:49:37 2019 +0100
+
+    [iter] Add unary operator+ that returns a copy
+
+ src/hb-iter.hh   | 1 +
+ src/test-iter.cc | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit fbab07f9b3dac90ce2136506f72879335193fc02
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 27 00:44:45 2019 +0100
+
+    [iter] Add hb_bool() and make hb_filter default to it for predicate
+
+ src/hb-algs.hh   |  6 ++++++
+ src/hb-iter.hh   |  4 ++--
+ src/test-iter.cc | 10 +++++++++-
+ 3 files changed, 17 insertions(+), 3 deletions(-)
+
+commit 313d63e240736bfe7c312133fe8c09ccff428d52
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 26 22:58:26 2019 +0100
+
+    [meta] Back to using _ft suffix for function-object types
+    
+    Seprate namespace, cleaner, more clear.
+
+ src/hb-algs.hh | 6 +++---
+ src/hb-iter.hh | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 2aff6d9625673062b1129e2af5b7d029f7622e71
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 26 22:54:25 2019 +0100
+
+    [iter] Test that default-constructed iterators are empty
+
+ src/test-iter.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit f35e7eabf10d99c2a4ddab054cf89f3da359e7a8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 26 22:50:00 2019 +0100
+
+    pragma GCC diagnostic error   "-Winjected-class-name"
+    
+    See 6b6783e1588ebe5772a1edc19552219e9d931bda
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 509353357c220a3a60910b70b3a90ea8fa6a14a8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 26 22:47:35 2019 +0100
+
+    [iter] Use hb_declval() instead of Null() to get instance
+    
+    I had used Null to make one of the bots happy before.  Not going
+    to bend to such demands anymore..
+
+ src/hb-iter.hh | 3 +--
+ src/hb.hh      | 2 +-
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+commit 6b6783e1588ebe5772a1edc19552219e9d931bda
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 26 22:44:09 2019 +0100
+
+    [iter/meta] Fix build on newer clang
+    
+    The mystery failure had to do with SFINAE failure because the template
+    function involved was accessing ::iter_t of a type that was also named iter_t.
+    In this context, apparently:
+    
+    warning: ISO C++ specifies that qualified reference to 'iter_t' is a
+    constructor name rather than a type in this context, despite preceding 'typename' keyword
+    [-Winjected-class-name]
+    
+    We use a new macro, also called hb_iter_t(), to get iterator type of
+    a type.  This uses declval/hb_decltype, and has the added benefit
+    that it returns correct type for const vs non-const objects, if they
+    have different iterators.
+
+ src/hb-iter.hh | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+commit 5adb113bafb2cf10ea768ff7a15ad4e6a1270a29
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 26 22:15:59 2019 +0100
+
+    [meta] Mark function-objects as const
+
+ src/hb-algs.hh | 6 +++---
+ src/hb-iter.hh | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit ac90f17c552e5264ad0a9d17c50fac9008d6ebe7
+Merge: 090fe56d 60022ecc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 26 14:05:39 2019 +0100
+
+    Merge branch 'master' into iter
+
 commit 60022ecced202760daa7f75516bba6a4689a49de
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Sat Jan 26 14:04:51 2019 +0100
@@ -1451,6 +9225,13 @@
  src/hb-set-digest.hh | 14 +++++++-------
  2 files changed, 12 insertions(+), 12 deletions(-)
 
+commit 090fe56dc6ef5f7afa297f2cb200418a520a2026
+Merge: 21c0713a 06358ae9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 25 15:34:03 2019 +0100
+
+    Merge branch 'master' into iter
+
 commit 06358ae9746ae72c0917e8a5f294d14fd695f380
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri Jan 25 15:11:47 2019 +0100
@@ -2030,6 +9811,1306 @@
  docs/usermanual-install-harfbuzz.xml | 12 ++++++++++++
  1 file changed, 12 insertions(+)
 
+commit 21c0713a1cf4b42b5dfa8fb9bdf1c1935a481b00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 21:24:51 2019 -0800
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 934d3fa2a7d5d47da7030f43ea7ca7234625fc7e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 21:00:13 2019 -0800
+
+    Use more iter pipelines
+
+ src/hb-ot-layout-gpos-table.hh |  9 +++++----
+ src/hb-ot-layout-gsubgpos.hh   | 32 ++++++++++++++++++--------------
+ 2 files changed, 23 insertions(+), 18 deletions(-)
+
+commit 420d8ac350590d776832dc7b353d997857cd7b45
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 20:58:25 2019 -0800
+
+    [algs] Add hb_iter()
+    
+    Makes it nicer in pipelines.
+
+ src/hb-algs.hh                 | 4 ++++
+ src/hb-ot-layout-gsub-table.hh | 6 +++---
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+commit 54ec48ea20d7d7d9e62bca12265e2f26383f9bc1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 20:54:21 2019 -0800
+
+    Use iter pipelines more
+
+ src/hb-ot-layout-gsub-table.hh | 81 +++++++++++++++++++++++-------------------
+ 1 file changed, 44 insertions(+), 37 deletions(-)
+
+commit 83cecd80d93a1e09231b8deaa6ecf8cd44875dfd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 19:49:13 2019 -0800
+
+    [iter] Default projection to identity
+
+ src/hb-algs.hh | 6 +++---
+ src/hb-iter.hh | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit a699c6b17cf2d272ac445838e82db6b0017cdbd7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 19:42:41 2019 -0800
+
+    [algs] Add hb_identity
+
+ src/hb-algs.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 463cfb426ff94b78b8e44f1c5662931b948beca7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 16:19:40 2019 -0800
+
+    Fix unused-variable warnings
+    
+    inline variables are not C++11, so mark them unused...
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f4cbb1ee0c7e1c2911c3676936e1bb571f6b255f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 13:28:00 2019 -0800
+
+    WIP
+
+ src/hb-ot-layout-gsub-table.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 471e96e55d3366a6ad723fe88c9aa895921c048f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 12:42:01 2019 -0800
+
+    [iter] Use forwarding references
+
+ src/hb-iter.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 528ea66f24c326d7361663a145bd9b8081c7c5c2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 12:36:17 2019 -0800
+
+    [algs] Fix hb_first() / hb_second()
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 343f5a4bfcf528ed8f5239fae9ddfca64b998fde
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 12:35:45 2019 -0800
+
+    [iter] Misc fixes to get piping almost work
+
+ src/hb-iter.hh | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+commit 7cedf7f64c2be0d16771dba73fd370325f7b66a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 12:22:14 2019 -0800
+
+    Change hb_first() and hb_second() to function objects
+
+ src/hb-algs.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit f35568d603df6409e4f867acf2f58794560f6649
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 11:32:33 2019 -0800
+
+    [iter] Add hb_filter()
+    
+    Untested.
+
+ src/hb-iter.hh | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+commit 1733e4702c4f4f8058e69500008d050cf9df0318
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 11:15:49 2019 -0800
+
+    [iter] Add hb_map()
+    
+    Untested.
+
+ src/hb-iter.hh | 43 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 42 insertions(+), 1 deletion(-)
+
+commit f7fcc476418099e2b89c52068ac81280a95bf76f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 11:00:32 2019 -0800
+
+    [iter] Make hb_zip() take const references
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ede1a71b31f49a6dc247ac0491b78508346e9932
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 10:45:53 2019 -0800
+
+    Minor rename
+
+ src/hb-ot-layout-gsub-table.hh | 12 ++++++------
+ src/hb-ot-layout-gsubgpos.hh   |  6 +++---
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 93551669c5a41ee11a156ef60a9f80dc328430b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 10:18:49 2019 -0800
+
+    Remove unused Coverage::iter_t::get_coverage()
+
+ src/hb-ot-layout-common.hh | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+commit af2067e87b06995a9cc9154baab2a5bc4f3f6955
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 10:17:33 2019 -0800
+
+    Use hb_zip() moooore
+
+ src/hb-ot-layout-gsub-table.hh | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+commit 0d1fdf939de13bb1994bc8f70da7f9f511b7e5be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 10:06:48 2019 -0800
+
+    Use hb_zip() some mooore
+
+ src/hb-ot-layout-gpos-table.hh | 13 +++------
+ src/hb-ot-layout-gsub-table.hh | 64 +++++++++++-------------------------------
+ 2 files changed, 21 insertions(+), 56 deletions(-)
+
+commit af6c1902356c937bc47ad8c37ab6f037b5810b67
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 10:01:28 2019 -0800
+
+    Use hb_zip() some moore
+
+ src/hb-ot-layout-gsubgpos.hh | 52 ++++++++++++--------------------------------
+ 1 file changed, 14 insertions(+), 38 deletions(-)
+
+commit 83ad0b6d0f3e7656f78611e89d7ebb939cd8e713
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 09:57:36 2019 -0800
+
+    Use hb_zip() some more
+
+ src/hb-ot-layout-gsub-table.hh | 36 ++++++++++--------------------------
+ 1 file changed, 10 insertions(+), 26 deletions(-)
+
+commit f0dd0656b8d2038ae6aa8d0a39d17130ddc8f16f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 09:52:10 2019 -0800
+
+    Use hb_zip() some
+
+ src/hb-ot-layout-gsub-table.hh | 20 +++++---------------
+ 1 file changed, 5 insertions(+), 15 deletions(-)
+
+commit 200cdb721bfb125cd462437ccbcc40554560c4d0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 09:49:12 2019 -0800
+
+    [iter] Rename hb_zip_t to hb_zip_iter_t
+
+ src/hb-iter.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 3290c181c17db33991cd1b79eca49f70d2601ce0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 09:08:15 2019 -0800
+
+    [algs] Whitespace
+
+ src/hb-algs.hh | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit 014c50292b471de0167b65fdc0eb446245438b84
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 09:07:01 2019 -0800
+
+    [iter] Move code
+
+ src/hb-iter.hh | 47 ++++++++++++++++++++++++++++-------------------
+ 1 file changed, 28 insertions(+), 19 deletions(-)
+
+commit 6e3ad650d1b864742084c6254d020734f09cb396
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 09:05:01 2019 -0800
+
+    Rename hb-dsalgs to hb-algs
+
+ src/Makefile.sources             | 2 +-
+ src/{hb-dsalgs.hh => hb-algs.hh} | 6 +++---
+ src/hb-array.hh                  | 2 +-
+ src/hb-debug.hh                  | 2 +-
+ src/hb-iter.hh                   | 2 +-
+ src/hb.hh                        | 8 ++++----
+ 6 files changed, 11 insertions(+), 11 deletions(-)
+
+commit f27607580e4d13e8ddf721df971a7d5062c54fb2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 09:03:21 2019 -0800
+
+    [algs] Add hb_first() and hb_second()
+
+ src/hb-dsalgs.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit a7de144df342f30b3d6f9e61c3fe3d1348ab222d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 08:39:25 2019 -0800
+
+    Implement uniform map interface
+    
+    Coverage, ClassDef, hb_set_t, and hb_map_t implement.
+
+ src/hb-map.hh              | 13 +++++++------
+ src/hb-ot-layout-common.hh | 14 ++++++++++++--
+ src/hb-set.hh              | 17 ++++++++++++-----
+ 3 files changed, 31 insertions(+), 13 deletions(-)
+
+commit 7987095e64e52b509661828aeadabe0b27bba0d0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 01:02:38 2019 -0800
+
+    [meta] Remove hb_enable_if_t
+    
+    It was only used for C++<11 which does not allow default parameters
+    in function templates.  Looks like we cannot support <11 anyway, so,
+    start cleaning up.
+
+ src/hb-iter.hh             | 18 +++++++++---------
+ src/hb-meta.hh             |  1 -
+ src/hb-open-type.hh        | 14 ++++++--------
+ src/hb-ot-layout-common.hh | 21 +++++++++------------
+ src/test-iter.cc           | 12 ++++++------
+ 5 files changed, 30 insertions(+), 36 deletions(-)
+
+commit 15a69284369ce739e79bf288a55c4c3010313144
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 00:36:47 2019 -0800
+
+    [iter] Implement operator-> unconditionally
+    
+    The right condition to check for would have been "is_struct", which
+    we don't have.
+
+ src/hb-iter.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 8f52a827e7d93abf3ef6159fd00f7c85c6d46793
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 00:36:26 2019 -0800
+
+    Allow rvalues in hb_addressof()
+
+ src/hb-dsalgs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a4ea0d368015b91df8d4c164a8838c45943562dc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 00:32:11 2019 -0800
+
+    [iter] Change from const_iter_t/iter_t to iter_t/writer_t
+
+ src/hb-open-type.hh | 26 ++++++++++++--------------
+ src/hb-vector.hh    | 13 ++++++-------
+ 2 files changed, 18 insertions(+), 21 deletions(-)
+
+commit 7798e4fcc34edca5c7d5d2fe7abd09a0540f0fea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 9 00:25:53 2019 -0800
+
+    [iter] Change Coverage iterator to only return glyph-id
+
+ src/hb-ot-layout-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 84e5d002290eb2f58392743bc841fa7def7fc96d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 23:57:16 2019 -0800
+
+    [iter] Add hb_zip()
+
+ src/hb-iter.hh   | 34 ++++++++++++++++++++++++++++++++++
+ src/test-iter.cc |  2 ++
+ 2 files changed, 36 insertions(+)
+
+commit 636786ecaf18c52d4c337d009434b22e868ab796
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 23:48:35 2019 -0800
+
+    [iter] Rename __item_type__ to __item_t__
+
+ src/hb-array.hh            | 2 +-
+ src/hb-iter.hh             | 4 ++--
+ src/hb-ot-layout-common.hh | 4 ++--
+ src/hb-set.hh              | 2 +-
+ src/test-iter.cc           | 2 +-
+ 5 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 6caf76f4a8b5e232a87b84dc5e357dddef63d00b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 23:28:05 2019 -0800
+
+    Tighten Coverage iteration
+
+ src/hb-ot-layout-common.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit ff3a7ce1e75b020c2d536200beb5610ed054e097
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 23:20:23 2019 -0800
+
+    [subset] Minor
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 42bf80e578a1b7f4023b3edeea7de103a3c7d7be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 19:13:17 2019 -0800
+
+    [iter] More semicolon
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f78f837ef17591144d6b22ae3cc71c49458253ff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 16:38:08 2019 -0800
+
+    [iter] Use aliasing using for types
+    
+    Fix ambiguity of hb_sorted_array_t::item_t with gcc.  No idea if that's a gcc bug
+    or what spec requires, but using aliasing using seems to fix it.  It probably breaks
+    our non-C++11 bots, in which case I have to condition the change.  Testing.
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3fc03e42ce73021c4573729a637d19346f7e5f44
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 16:33:31 2019 -0800
+
+    [iter] Use static_assert with hb_is_random_access_iterator()
+    
+    Both, checks constexpr'ness, and fixes build with cra**y implementations
+    of assert() macro:
+    
+    test-iter.cc:108:11: error: too many arguments provided to function-like macro invocation
+      assert (hb_is_random_access_iterator (array_iter_t<int>));
+              ^
+    ./hb-iter.hh:186:42: note: expanded from macro 'hb_is_random_access_iterator'
+      hb_is_random_access_iterator_of (Iter, typename Iter::item_t)
+                                             ^
+    /usr/include/x86_64-linux-gnu/sys/cdefs.h:89:9: note: macro '__STRING' defined here
+    \#define __STRING(x)     #x
+            ^
+    test-iter.cc:108:3: error: use of undeclared identifier '__STRING'
+      assert (hb_is_random_access_iterator (array_iter_t<int>));
+      ^
+    /usr/include/assert.h:91:21: note: expanded from macro 'assert'
+       : __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))
+                        ^
+
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6af9c5f18eaf51f2d7e564d23d9b09219af9d700
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 16:27:37 2019 -0800
+
+    [iter] Remove stray semicolons
+
+ src/hb-iter.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 74ca7b580c284d6fe3bf7067a19a2095102e72d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 13:48:42 2019 -0800
+
+    [OT] Implement operator[] for Coverage and ClassDef
+
+ src/hb-ot-layout-common.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 6c548b6657d419e013969f9a456418e46bef0b30
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 13:43:49 2019 -0800
+
+    [iter] Add TODO
+
+ src/hb-iter.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 362d4e7cc324bf99b087aa34a4fae6898e50674f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 13:41:30 2019 -0800
+
+    [iter] Implement for OT::ArrayOf / OT::SortedArrayOf
+
+ src/hb-open-type.hh | 36 ++++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+commit 2f837a365c0986c2f925624d9c00ede8cd9e7669
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 13:05:01 2019 -0800
+
+    [SortedArrayOf] Fix sub_array() return type
+
+ src/hb-open-type.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 54c30e949e7d0a80c19cb8a12c300d62425683a9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 13:00:06 2019 -0800
+
+    [iter] Constrain hb_fill() and hb_copy()
+
+ src/hb-iter.hh | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+commit dc0a98cbe7be25a38220eda19ee06b19bf2d130d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 12:57:01 2019 -0800
+
+    [iter] Add TODO
+
+ src/hb-iter.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 2658e40ffb66dba6e2e5525d6ee4792fe1ea1dd1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 12:53:02 2019 -0800
+
+    [iter] Add hb_is_random_access_iterator()
+
+ src/hb-iter.hh   | 10 +++++++---
+ src/test-iter.cc |  2 ++
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+commit 445364d80a06007de5ac4c0fca9bb0b846f25c9c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 12:42:15 2019 -0800
+
+    [iter] Rename hb_is_[sorted_]iterator() -> hb_is_[sorted_]iterator_of()
+
+ src/hb-iter.hh             | 15 +++++++++------
+ src/hb-open-type.hh        |  4 ++--
+ src/hb-ot-layout-common.hh |  6 +++---
+ src/test-iter.cc           |  2 +-
+ 4 files changed, 15 insertions(+), 12 deletions(-)
+
+commit a6c013b1bf1f828f1eea7db801f2efb9a1486773
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 14:27:51 2019 -0500
+
+    [meta] Add hb_declval() macro
+
+ src/hb-iter.hh | 2 +-
+ src/hb-meta.hh | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit adc5910a63f209e35133c59f4466443844c9a18a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 14:26:41 2019 -0500
+
+    [iter] Syntax
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ca6adcd1ad35932aeac4d46a191809b010636b3d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 8 14:23:12 2019 -0500
+
+    [iter] Test hb_is_iterable / hb_is_iterator
+
+ src/test-iter.cc | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit 8237809f065f41653a12c95885e3b76409c42f36
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 22:00:45 2019 -0500
+
+    [serialize] Make SortedArrayOf:;serialize() take sorted-iterator
+
+ src/hb-open-type.hh     | 17 +++++++++++++++++
+ src/hb-ot-cmap-table.hh | 18 +++++++++---------
+ 2 files changed, 26 insertions(+), 9 deletions(-)
+
+commit 47333c8a304c6f57f848b5f60eea8ec85ffe2b33
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 21:38:49 2019 -0500
+
+    [iter] Fix operator->
+
+ src/hb-iter.hh   | 3 ++-
+ src/test-iter.cc | 3 +++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 177a8af380738e5be598952adbf275503bb3f5bc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 20:20:44 2019 -0500
+
+    [array] SFINAE fun
+
+ src/hb-array.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 8414f167879c1af8ce5c80a15ba1aec2f7e436a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 19:41:52 2019 -0500
+
+    [meta] Rename
+
+ src/hb-meta.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 8e0a58e1b3f338098d2384f2e6e0b4ad08d6c042
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 19:03:53 2019 -0500
+
+    [array] Remove construction that was removing constness
+
+ src/hb-array.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 85969e357a34691cc42c88490fc7e341175783dd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 18:59:26 2019 -0500
+
+    [iter] Fix test
+
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit da4996183693b4acecf245c58b58d6040d92a1bf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 18:36:14 2019 -0500
+
+    [iter] Remove comment
+
+ src/hb-iter.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 815cde9fa3465828030ca1ed4f32ca1df72c1f37
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 18:33:04 2019 -0500
+
+    [iter] Use is_sorted_iterator
+
+ src/hb-aat-map.hh                          |  2 +-
+ src/hb-array.hh                            |  4 +++
+ src/hb-meta.hh                             | 23 +++++++++-------
+ src/hb-ot-layout-common.hh                 |  8 +++---
+ src/hb-ot-layout-gsub-table.hh             | 42 +++++++++++++++---------------
+ src/hb-ot-map.hh                           |  2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh |  4 +--
+ src/hb-set.hh                              |  2 +-
+ src/hb-vector.hh                           | 32 ++++++++++++++---------
+ 9 files changed, 66 insertions(+), 53 deletions(-)
+
+commit ed4336680d3fc080f99c7dd67db48c55bcd7a020
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 7 17:24:23 2019 -0500
+
+    [iter] Handhold hb_is_iterator() type deduction
+    
+    by partial-instantiating on Iter.
+
+ src/hb-iter.hh | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+commit cb5011d364904452a625cfc0485f5a713f472d07
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 4 11:22:32 2019 -0500
+
+    Revert "[iter] Add hb_iter_of_t<>"
+    
+    This reverts commit d6cbe96e2fc7bc8f1c10e631b52b1ef31ff9a6f5.
+    
+    Isn't useful, as duplicate inheritance of same type results in ambiguity
+    errors...
+
+ src/hb-iter.hh | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+commit c132cda9d98286f002d2f5b27d1d00bf80b42a9c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 2 17:00:01 2019 -0500
+
+    [iter] Fix warnings
+
+ src/hb-iter.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit c9d8a07e30d05b870c3d2374853adba019601b02
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 2 16:43:52 2019 -0500
+
+    [iter] Add hb_iter_of_t<>
+
+ src/hb-iter.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit b5d6fe1a452c72dd47d20c03a563321771330acc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 2 16:20:40 2019 -0500
+
+    [iter] Remove hb_sorted_iter_t
+    
+    Not enforcing it using type hierarchy.
+
+ src/hb-array.hh            |  6 ++++--
+ src/hb-iter.hh             | 26 ++++----------------------
+ src/hb-ot-layout-common.hh |  3 ++-
+ src/hb-set.hh              |  3 ++-
+ 4 files changed, 12 insertions(+), 26 deletions(-)
+
+commit 255085bd599cb108779d467690b372263f304dcb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 2 16:14:00 2019 -0500
+
+    [iter] Const correctness
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 415f3f4320c80d47e03fe9594a917fb2964b1144
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 31 13:37:13 2018 -0500
+
+    Add operator= to IntType, commented out
+    
+    https://github.com/harfbuzz/harfbuzz/pull/1510
+
+ src/hb-open-type.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 183be8f452862aaf0cdedb28d54ec114d67745b2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 20:58:25 2018 -0500
+
+    [iter] Minor
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6cd96ba1aca99b6eb31f8402d02c565dd4e96e03
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 20:51:31 2018 -0500
+
+    [iter] Make is_random_access_iterator a constant
+    
+    We cannot rely on constexpr functions...
+
+ src/hb-array.hh  |  2 +-
+ src/hb-iter.hh   | 11 ++++-------
+ src/test-iter.cc |  2 +-
+ 3 files changed, 6 insertions(+), 9 deletions(-)
+
+commit a685bfe8fc93ac1886a708687ea6fa7aa0b7c8c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 20:24:21 2018 -0500
+
+    Separate GlyphID from HBUINT16
+    
+    For stricter enforcement.
+
+ src/hb-dsalgs.hh                           | 8 ++++----
+ src/hb-open-type.hh                        | 2 +-
+ src/hb-ot-layout-common.hh                 | 2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh | 8 ++++++--
+ 4 files changed, 12 insertions(+), 8 deletions(-)
+
+commit 8ac64d00907756333d5917db4b627619420f9260
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 20:06:12 2018 -0500
+
+    [iter] Fix sorted_iter iter class
+
+ src/hb-array.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 93615b9598f6b5e514384327b30acfd6bd8cfcfb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 19:12:06 2018 -0500
+
+    [iter/meta] Add hb_is_sorted_iterator()
+
+ src/hb-iter.hh | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+commit 92f25db1e86c7b79962a2eb735cd3596c302f71f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 19:10:26 2018 -0500
+
+    [iter] Remove stale comment
+
+ src/hb-iter.hh | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+commit 40c24fd4a623c5f570e657f22fb4e88cba48b02b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 19:06:47 2018 -0500
+
+    [iter] Port Coverage towards iter_t instead of array_t specifics
+
+ src/hb-ot-layout-common.hh | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit d552b6818c21efe9eae8b9cd72d5199dadd3724f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 18:54:07 2018 -0500
+
+    [meta] Move typename around
+    
+    We'll see if bots like.
+
+ src/hb-atomic.hh | 2 +-
+ src/hb-blob.hh   | 2 +-
+ src/hb-iter.hh   | 2 +-
+ src/hb-meta.hh   | 6 +++---
+ src/hb-null.hh   | 6 +++---
+ 5 files changed, 9 insertions(+), 9 deletions(-)
+
+commit f64ea8fc65b0dacc2ac3b1de97c92488b6e1b6fa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 18:49:34 2018 -0500
+
+    [meta] Move code around
+
+ src/hb-atomic.hh |  1 +
+ src/hb-meta.hh   | 10 ++++++++++
+ src/hb.hh        | 14 +-------------
+ 3 files changed, 12 insertions(+), 13 deletions(-)
+
+commit aa2ab4f0617c50de2501722205d3d0eaaf808ff4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 18:47:47 2018 -0500
+
+    [iter] WHitespace
+
+ src/hb-iter.hh | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+commit 851fbb23ea552bc639269670949a9937236d96d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 18:45:50 2018 -0500
+
+    [iter] Port Coverage::serialize to hb_is_iterator
+
+ src/hb-open-type.hh        |  2 +-
+ src/hb-ot-layout-common.hh | 18 ++++++++++++------
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+commit 06a44e2e537303ab8ed1fb761bf3885eb433a718
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 18:42:14 2018 -0500
+
+    [iter/meta] Match hb_is_iterator<> using SFINAE
+    
+    By specifying Item type, which is desirable.
+
+ src/hb-iter.hh      | 28 +++++++++++-----------------
+ src/hb-open-type.hh |  2 +-
+ 2 files changed, 12 insertions(+), 18 deletions(-)
+
+commit bcb913efb484e971d8a76ac1a897a1724bdad58b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 17:54:24 2018 -0500
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fa1ae3d465fd627ea99c5eb597b85cffe04c1e34
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 12:01:13 2018 -0500
+
+    Use C++11 when available
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dc0f98298eca6520efd6e05d34f9aa7847979203
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 11:22:16 2018 -0500
+
+    [ci] Remove unused config for gcc 4.2
+    
+    [skip ci]
+
+ .circleci/config.yml | 25 -------------------------
+ 1 file changed, 25 deletions(-)
+
+commit eaa9023634282bed5955a068f9f92b8ef1733c39
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 11:16:14 2018 -0500
+
+    [ci] Disable other gcc 4.2 bot
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 859a880b083c67e767162c394e08c46367078b0b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 02:11:03 2018 -0500
+
+    [iter] Add back operator +
+    
+    Too ugly to remove..
+
+ src/hb-iter.hh   | 6 +++---
+ src/test-iter.cc | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 076faf7c1803238f135034579935e6b8f10c774c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 30 01:40:08 2018 -0500
+
+    [iter] Disable operator +
+    
+    To see if it makes bots happy... This is frustrating.
+
+ src/hb-iter.hh   | 5 +++--
+ src/test-iter.cc | 5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+commit a46874f1ab4b2470784c9ef688c7a8e00592165f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 21:23:26 2018 -0500
+
+    [iter] Revert back uses of C++11 auto type deduction
+
+ src/hb-ot-layout-gpos-table.hh |  2 +-
+ src/hb-ot-layout-gsub-table.hh | 26 +++++++++++++-------------
+ src/hb-ot-layout-gsubgpos.hh   |  8 ++++----
+ 3 files changed, 18 insertions(+), 18 deletions(-)
+
+commit 0828db8444d4b6922469770ca1b432356512db18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 21:22:26 2018 -0500
+
+    [iter] Rename
+
+ src/hb-ot-layout-common.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 037f735efdc77ae9c8a24527da5d9805163180a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 21:09:15 2018 -0500
+
+    [iter] Remove friend operator +, hoping to fix some bots
+
+ src/hb-iter.hh   | 1 -
+ src/test-iter.cc | 1 -
+ 2 files changed, 2 deletions(-)
+
+commit cb27918d0a104c5f3884013a7dc7c99f3e3e3378
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 20:16:44 2018 -0500
+
+    Use Null() instead of declval(), hoping to fix some bots
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3d22900f6251b4386d8a7dfd7e2118dd75f12763
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 20:01:57 2018 -0500
+
+    [meta] Don't use template default arguments for functions
+    
+    That's a C++11 extension apparently...
+
+ src/hb-meta.hh      | 2 +-
+ src/hb-open-type.hh | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit b89d20dd9f7e0b4fad3f6c8803c73d2ace34c340
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 16:41:04 2018 -0500
+
+    [meta] Fix unused-function-template warning
+
+ src/hb-meta.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit df138da2e67ce72bec13e656e3146b21b4600c14
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 16:29:48 2018 -0500
+
+    [iter/meta] Implement is_iterator
+    
+    Removes use of auto type deduction again, which was not supported on many bots.
+
+ src/hb-iter.hh      | 42 +++++++++++++++++++++++++++++++++++++++---
+ src/hb-meta.hh      |  4 ++--
+ src/hb-open-type.hh | 13 +++++++------
+ 3 files changed, 48 insertions(+), 11 deletions(-)
+
+commit 8570da1d741bbe6becbfd27d7bce3b2a6b78dae7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 14:40:30 2018 -0500
+
+    [meta] Minor
+
+ src/hb-iter.hh | 4 ++--
+ src/hb-null.hh | 8 ++++----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 442f4a58919b8e997daf5465b948975ecbe7e3df
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 14:34:00 2018 -0500
+
+    [meta] Move more code here
+
+ src/hb-dsalgs.hh    | 20 --------------------
+ src/hb-meta.hh      | 31 +++++++++++++++++++++++++++++++
+ src/hb-open-type.hh |  6 +-----
+ 3 files changed, 32 insertions(+), 25 deletions(-)
+
+commit 8c6cbbdfa326d6edee4a4b5f33971ad1ecfbcd2c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 28 14:29:09 2018 -0500
+
+    [iter/meta] Add hb_is_iterable
+
+ src/hb-iter.hh      | 26 +++++++++++++++++++++++---
+ src/hb-meta.hh      | 15 ++++++++++-----
+ src/hb-null.hh      | 17 ++++++++---------
+ src/hb-open-type.hh |  6 ++++--
+ src/hb.hh           |  2 +-
+ 5 files changed, 46 insertions(+), 20 deletions(-)
+
+commit 576d5e242028b492c2a8bbe56edeaa484b8a886a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 18:39:39 2018 -0500
+
+    Don't use delegating constructors
+    
+    Not all C++11 features are created equal when it comes to support...
+
+ src/hb-dsalgs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e32bf3976686c01fe9804086a8ca48aa0069b392
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 17:38:26 2018 -0500
+
+    [meta] Add enable_if
+
+ src/hb-meta.hh | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit e76a3cae0fd8cb1e716f4e55f4abbb57af49b10f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 17:23:12 2018 -0500
+
+    Add hb-meta.hh for meta-programming
+
+ src/Makefile.sources |  1 +
+ src/hb-dsalgs.hh     |  4 ----
+ src/hb-iter.hh       |  1 +
+ src/hb-meta.hh       | 40 ++++++++++++++++++++++++++++++++++++++++
+ src/hb.hh            |  3 ++-
+ 5 files changed, 44 insertions(+), 5 deletions(-)
+
+commit 5ec11ce13a6bf4479205f3cf2a9cc96342df7f60
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 17:17:28 2018 -0500
+
+    [iter] Clarify readonly vs lvalue iterators
+    
+    lvalue iterators must declare __item_type__ as a reference.
+
+ src/hb-array.hh  |  6 +++---
+ src/hb-iter.hh   | 11 ++++++-----
+ src/hb-set.hh    |  6 +++---
+ src/test-iter.cc |  6 ++++--
+ 4 files changed, 16 insertions(+), 13 deletions(-)
+
+commit 2cbf5bf3a959402a7f69b328469232b7050bae01
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 16:55:18 2018 -0500
+
+    [iter] Test OT::Coverage iter
+
+ src/hb-dsalgs.hh           | 6 +++++-
+ src/hb-ot-layout-common.hh | 6 +++---
+ src/test-iter.cc           | 9 ++++++++-
+ 3 files changed, 16 insertions(+), 5 deletions(-)
+
+commit fd75d29f0f317c4fb36b093c8fabf2a7dcd28042
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 16:29:22 2018 -0500
+
+    [iter] Streamline vector iterators
+
+ src/hb-vector.hh | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+commit 570473a345a73ab05ea8e8acf88cfba9b90a81a4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 13:29:51 2018 -0500
+
+    [iter] Make hb_sorted_array_t work as iter
+    
+    Ugly, but does the job.
+
+ src/hb-array.hh  |  6 ++++--
+ src/hb-iter.hh   | 18 ++++++++++++++++++
+ src/test-iter.cc |  2 ++
+ 3 files changed, 24 insertions(+), 2 deletions(-)
+
+commit d6024794fb072647d8233b184c25da5def26c435
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 09:56:41 2018 -0500
+
+    Change hb_void_t implementation
+
+ src/hb-dsalgs.hh               |  3 +--
+ src/hb-ot-layout-gsub-table.hh |  2 +-
+ src/hb-ot-layout-gsubgpos.hh   | 12 ++++++------
+ 3 files changed, 8 insertions(+), 9 deletions(-)
+
+commit cde31988c26043a47e4599bf7e0d88ea67fc333f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 27 09:39:34 2018 -0500
+
+    [iter] Mark Coverage iterator sorted
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 49161d411f30d06bc920f4153f5925944895cdbc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 22:50:33 2018 -0500
+
+    [subset] Take iterator in ArrayOf serialize
+    
+    Still not satisfied with how I can enforce iterators only, but
+    seems to work for now.
+
+ src/hb-open-type.hh | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit e16884248f80c52cd29e39a9b27b15422d76b0f1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 22:27:23 2018 -0500
+
+    [iter] Port Coverage iterator to hb_iter_t
+
+ src/hb-ot-layout-common.hh     | 12 +++++++++---
+ src/hb-ot-layout-gpos-table.hh |  2 +-
+ src/hb-ot-layout-gsub-table.hh | 26 +++++++++++++-------------
+ src/hb-ot-layout-gsubgpos.hh   |  8 ++++----
+ 4 files changed, 27 insertions(+), 21 deletions(-)
+
+commit c68bca0f953f5b7b7e15780f65a8e3da24917800
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 22:21:58 2018 -0500
+
+    Add hb_pair_t<> and hb_pair()
+
+ src/hb-dsalgs.hh | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit 8303a9b011eb2ab710371b9bd7d75693c7639bc1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 22:08:54 2018 -0500
+
+    [Coverage] Ensure increasing coverage in iteration
+
+ src/hb-ot-layout-common.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 50cd26d3941156daefb1d9ba7f514049eed04b16
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 22:05:25 2018 -0500
+
+    [Coverage] Mark iterator methods const
+
+ src/hb-ot-layout-common.hh | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+commit 9df1a6eba77e8b7319fc7724e41ceaeda70c2590
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 20:28:41 2018 -0500
+
+    [iter] Use operator bool in a few places
+
+ src/hb-ot-layout-common.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 7788ac14a408e038fae9da4299fad69158c7b465
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 20:06:10 2018 -0500
+
+    [iter] Remove redundant methods
+
+ src/hb-iter.hh | 44 +++++++++++++++++---------------------------
+ 1 file changed, 17 insertions(+), 27 deletions(-)
+
+commit 3dea9affdaa063c01d67d6697df1f16c62f55c9a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 19:56:37 2018 -0500
+
+    [iter] Test default-constructability
+
+ src/test-iter.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 743ff09368f223c56beeda9b72b0520766130322
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 19:54:52 2018 -0500
+
+    [iter] Implement friend opeator + (int, iter)
+
+ src/hb-iter.hh   | 1 +
+ src/test-iter.cc | 1 +
+ 2 files changed, 2 insertions(+)
+
+commit 6dc4a1c9b1f6aa38bca094d251154f9e51049d4d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 19:49:13 2018 -0500
+
+    [iter] Remove const_iter
+
+ src/hb-iter.hh   |  2 --
+ src/hb-set.hh    | 14 ++++++--------
+ src/hb-vector.hh |  6 +++---
+ 3 files changed, 9 insertions(+), 13 deletions(-)
+
+commit d12b80c05a2673c4e4bf2337e2cd4f3100e9f88b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 19:15:21 2018 -0500
+
+    [ci] Disable macos-llvm-gcc-4.2 again
+    
+    Not C++11.
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f2b56af3ef721ce3961bea7d2ee8b6dba6f3fbf2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 19:14:39 2018 -0500
+
+    [iter] Remove hack for older compilers
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2ea79e0340c01d58ebeeaab9d31ffdd64250a24b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 19:01:46 2018 -0500
+
+    [iter] Minor
+
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fb053b633351afe2012ece0874a8ac15d504a15c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 19:01:30 2018 -0500
+
+    [iter] Rename random_access() to constexpr is_random_access()
+
+ src/hb-iter.hh   | 4 ++--
+ src/test-iter.cc | 2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+commit 2790aad28ce58acf0077e02921332120325edb4c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 18:58:42 2018 -0500
+
+    [iter] Add operator ->
+
+ src/hb-iter.hh | 2 ++
+ src/hb.hh      | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit d3976b7e63559b87ef34abc62acf5033f3369197
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 18:54:27 2018 -0500
+
+    [iter] Make them work, mostly
+
+ src/hb-iter.hh   | 11 ++++++++---
+ src/hb-set.hh    | 18 ++++++++++--------
+ src/test-iter.cc | 25 +++++++++++++++++++++++++
+ 3 files changed, 43 insertions(+), 11 deletions(-)
+
+commit 959bb58bdda8e78690789441e07cf22a99113c53
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 26 18:54:15 2018 -0500
+
+    [vector] Add iterator
+
+ src/hb-vector.hh | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+commit 6fc6a141e6d68955310d15c91f6e3d061f7221fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 20 20:09:10 2019 -0500
+
+    Remove wrongly added files
+
+ test/api/test-ot-extents-cff                        | Bin 8574336 -> 0 bytes
+ .../test-ot-extents-cff.dSYM/Contents/Info.plist    |  20 --------------------
+ .../Contents/Resources/DWARF/test-ot-extents-cff    | Bin 7650053 -> 0 bytes
+ 3 files changed, 20 deletions(-)
+
+commit dd7c628ed122f858be9ad08c184c87ff31f2ec2d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 20 19:51:08 2019 -0500
+
+    Use enum for class constant
+
+ src/hb-cff-interp-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cf7edf52c3cb38989af20b196a69bf099a1681d6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 20 19:49:59 2019 -0500
+
+    [CFF] Use enum for tableTag
+
+ src/hb-ot-cff1-table.hh | 2 +-
+ src/hb-ot-cff2-table.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit bd1318b8ccf08d5f9241851dbb689c7dac717f0a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 20 19:47:52 2019 -0500
+
+    Use static constexpr for large class constants
+
+ src/hb-map.hh | 2 +-
+ src/hb-set.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
 commit 043b610fa698ed247347dfaa042f032f3fd3f572
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Sat Jan 19 09:20:46 2019 -0500
@@ -21462,6 +30543,15 @@
  src/hb-cache.hh | 5 ++++-
  1 file changed, 4 insertions(+), 1 deletion(-)
 
+commit 341b70a3b47ef3ceeb81e715937d6b2305258060
+Merge: bbf2a095 9e9a36ee
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Thu Sep 27 11:15:22 2018 -0500
+
+    Merge pull request #1 from harfbuzz/master
+    
+    Resync with upstream
+
 commit 9e9a36ee651502b69717895385387951a2d0802a
 Author: Volker Krause <vkrause at kde.org>
 Date:   Thu Sep 27 16:33:49 2018 +0200
@@ -28073,6 +37163,15 @@
  ...testcase-minimized-hb-subset-fuzzer-5750092395970560 | Bin 0 -> 72435 bytes
  1 file changed, 0 insertions(+), 0 deletions(-)
 
+commit bbf2a09549a88bd52ac3db89a0ae93f3b71b3e37
+Merge: 8db058d2 35ce8f31
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon Jun 25 13:02:11 2018 -0500
+
+    Merge branch 'master' of http://github.com/behdad/harfbuzz
+    
+    Catching up.
+
 commit 35ce8f31d37cf7c2a1f8265d36ba4c2c9a3efb2c
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Mon Jun 25 22:23:43 2018 +0430
@@ -40295,6 +49394,15 @@
  src/hb-ot-shape-complex-indic.cc | 16 ++++++++--------
  1 file changed, 8 insertions(+), 8 deletions(-)
 
+commit 8db058d20c1b7efce33157c676d4aee97591deb1
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Tue Dec 5 17:43:09 2017 +0000
+
+    Indic: always hyphenate pre-base-reordering, for clarity.
+
+ src/hb-ot-shape-complex-indic.cc | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
 commit be59f3cbf4e3269ea05d5a707cdae04a32e097ce
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Tue Dec 5 09:01:28 2017 -0800

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am	2019-05-24 23:03:55 UTC (rev 51218)
@@ -71,7 +71,7 @@
 	chmod -R a-s $(distdir)
 
 
-tar_file = $(PACKAGE_TARNAME)-$(VERSION).tar.bz2
+tar_file = $(PACKAGE_TARNAME)-$(VERSION).tar.xz
 sha256_file = $(tar_file).sha256
 gpg_file = $(sha256_file).asc
 $(sha256_file): $(tar_file)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,3 +1,17 @@
+Overview of changes leading to 2.5.0
+Friday, May 24, 2019
+====================================
+- This release does not include much functional changes, but includes major internal
+  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
+  UCDN.
+- Subsetter improvements.
+- Improved documentation, thanks to Nathan Willis.
+- Misc shaping fixes.
+
+
 Overview of changes leading to 2.4.0
 Monday, March 25, 2019
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/README
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/README	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/README	2019-05-24 23:03:55 UTC (rev 51218)
@@ -13,6 +13,10 @@
 
   http://harfbuzz.org/
 
-For license information, see the file COPYING.
+For license information, see [COPYING](COPYING).
 
+For build information, see [BUILD.md](BUILD.md).
+
+For test execution, see [TESTING.md](TESTING.md).
+
 Documentation: https://harfbuzz.github.io

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md	2019-05-24 23:03:55 UTC (rev 51218)
@@ -33,13 +33,14 @@
    That's what happened to 2.0.0 going out with 1.8.0 hb-version.h...  So, that's
    a clue.
 
-7. "make release-files".  Enter your GPG password.  This creates a sha256 hash
-   and signs it.
-
-8. Now that you have release files, commit NEWS, configure.ac, and src/hb-version.h,
+7. Now that you have release files, commit NEWS, configure.ac, and src/hb-version.h,
    as well as any REPLACEME changes you made.  The commit message is simply the
    release number.  Eg. "1.4.7"
 
+8. "make dist" again to get a tarball with your new commit in the ChangeLog.  Then
+   "make release-files".  Enter your GPG password.  This creates a sha256 hash
+   and signs it.  Check the size of the three resulting files.
+
 9. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7".  Enter your
    GPG password again.
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/THANKS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/THANKS	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/THANKS	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,6 +1,6 @@
 Bradley Grainger
-Khaled Hosny
 Kenichi Ishibashi
+Ivan Kuckir <https://photopea.com/>
 Ryan Lortie
 Jeff Muizelaar
 suzuki toshiya

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2019-05-24 23:03:55 UTC (rev 51218)
@@ -15,6 +15,9 @@
 /* Have Core Text backend */
 #undef HAVE_CORETEXT
 
+/* define if the compiler supports basic C++11 syntax */
+#undef HAVE_CXX11
+
 /* Define to 1 if you have the declaration of `round', and to 0 if you don't.
    */
 #undef HAVE_DECL_ROUND
@@ -136,9 +139,6 @@
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 
-/* Have UCDN Unicode functions */
-#undef HAVE_UCDN
-
 /* Have Uniscribe library */
 #undef HAVE_UNISCRIBE
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [2.4.0],
+        [2.5.0],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
@@ -9,7 +9,7 @@
 AC_CONFIG_SRCDIR([src/harfbuzz.pc.in])
 AC_CONFIG_HEADERS([config.h])
 
-AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability])
+AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-xz no-dist-gzip -Wall no-define color-tests -Wno-portability])
 AM_SILENT_RULES([yes])
 AX_CODE_COVERAGE
 
@@ -23,7 +23,7 @@
 AC_PROG_CC_C99
 AM_PROG_CC_C_O
 AC_PROG_CXX
-dnl AX_CXX_COMPILE_STDCXX(11, noext, optional)
+AX_CXX_COMPILE_STDCXX(11,, optional)
 AC_SYS_LARGEFILE
 PKG_PROG_PKG_CONFIG([0.20])
 AM_MISSING_PROG([RAGEL], [ragel])
@@ -300,21 +300,6 @@
 
 dnl ===========================================================================
 
-AC_ARG_WITH(ucdn,
-	[AS_HELP_STRING([--with-ucdn=@<:@yes/no@:>@],
-			[Use builtin UCDN library @<:@default=yes@:>@])],,
-	[with_ucdn=yes])
-have_ucdn=false
-if test "x$with_ucdn" = "xyes"; then
-	have_ucdn=true
-fi
-if $have_ucdn; then
-	AC_DEFINE(HAVE_UCDN, 1, [Have UCDN Unicode functions])
-fi
-AM_CONDITIONAL(HAVE_UCDN, $have_ucdn)
-
-dnl ==========================================================================
-
 AC_ARG_WITH(graphite2,
 	[AS_HELP_STRING([--with-graphite2=@<:@yes/no/auto@:>@],
 			[Use the graphite2 library @<:@default=no@:>@])],,
@@ -497,7 +482,6 @@
 Makefile
 src/Makefile
 src/harfbuzz-config.cmake
-src/hb-ucdn/Makefile
 util/Makefile
 test/Makefile
 test/api/Makefile
@@ -525,7 +509,7 @@
 Build configuration:
 
 Unicode callbacks (you want at least one):
-	Builtin (UCDN):		${have_ucdn}
+	Builtin			true
 	Glib:			${have_glib}
 	ICU:			${have_icu}
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2019-05-24 23:03:55 UTC (rev 51218)
@@ -87,18 +87,7 @@
 HBHEADERS += $(HB_CORETEXT_headers)
 endif
 
-if HAVE_UCDN
-SUBDIRS += hb-ucdn
-HBCFLAGS += -I$(srcdir)/hb-ucdn
-HBLIBS   += hb-ucdn/libhb-ucdn.la
-HBSOURCES += $(HB_UCDN_sources)
-hb-ucdn/libhb-ucdn.la: ucdn
-ucdn:
-	@$(MAKE) $(AM_MAKEFLAGS) -C hb-ucdn
-endif
-DIST_SUBDIRS += hb-ucdn
 
-
 BUILT_SOURCES += \
 	hb-version.h
 
@@ -258,6 +247,7 @@
 	gen-indic-table.py \
 	gen-os2-unicode-ranges.py \
 	gen-tag-table.py \
+	gen-ucd-table.py \
 	gen-use-table.py \
 	gen-vowel-constraints.py \
 	$(NULL)
@@ -310,9 +300,9 @@
 	main \
 	test \
 	test-buffer-serialize \
-	test-name-table \
-	test-size-params \
-	test-would-substitute \
+	test-ot-name \
+	test-gpos-size-params \
+	test-gsub-would-substitute \
 	$(NULL)
 bin_PROGRAMS =
 
@@ -328,17 +318,17 @@
 test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
 test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
 
-test_name_table_SOURCES = test-name-table.cc
-test_name_table_CPPFLAGS = $(HBCFLAGS)
-test_name_table_LDADD = libharfbuzz.la $(HBLIBS)
+test_ot_name_SOURCES = test-ot-name.cc
+test_ot_name_CPPFLAGS = $(HBCFLAGS)
+test_ot_name_LDADD = libharfbuzz.la $(HBLIBS)
 
-test_size_params_SOURCES = test-size-params.cc
-test_size_params_CPPFLAGS = $(HBCFLAGS)
-test_size_params_LDADD = libharfbuzz.la $(HBLIBS)
+test_gpos_size_params_SOURCES = test-gpos-size-params.cc
+test_gpos_size_params_CPPFLAGS = $(HBCFLAGS)
+test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS)
 
-test_would_substitute_SOURCES = test-would-substitute.cc
-test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
-test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
+test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc
+test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
+test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
 
 if HAVE_FREETYPE
 if HAVE_CAIRO_FT
@@ -384,16 +374,24 @@
 dump_use_data_CPPFLAGS = $(HBCFLAGS)
 dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
 
-COMPILED_TESTS = test-iter test-ot-tag test-unicode-ranges
+COMPILED_TESTS = test-algs test-iter test-meta test-ot-tag test-unicode-ranges
 COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
 COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
 check_PROGRAMS += $(COMPILED_TESTS)
 TESTS += $(COMPILED_TESTS)
 
+test_algs_SOURCES = test-algs.cc hb-static.cc
+test_algs_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_algs_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_iter_SOURCES = test-iter.cc hb-static.cc
 test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_iter_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_meta_SOURCES = test-meta.cc hb-static.cc
+test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_meta_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_ot_tag_SOURCES = hb-ot-tag.cc
 test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2019-05-24 23:03:55 UTC (rev 51218)
@@ -16,6 +16,7 @@
 	hb-aat-ltag-table.hh \
 	hb-aat-map.cc \
 	hb-aat-map.hh \
+	hb-algs.hh \
 	hb-array.hh \
 	hb-atomic.hh \
 	hb-blob.cc \
@@ -30,8 +31,9 @@
 	hb-cff1-interp-cs.hh \
 	hb-cff2-interp-cs.hh \
 	hb-common.cc \
+	hb-config.hh \
 	hb-debug.hh \
-	hb-dsalgs.hh \
+	hb-dispatch.hh \
 	hb-face.cc \
 	hb-face.hh \
 	hb-font.cc \
@@ -41,6 +43,7 @@
 	hb-machinery.hh \
 	hb-map.cc \
 	hb-map.hh \
+	hb-meta.hh \
 	hb-mutex.hh \
 	hb-null.hh \
 	hb-object.hh \
@@ -82,7 +85,7 @@
 	hb-ot-math-table.hh \
 	hb-ot-math.cc \
 	hb-ot-maxp-table.hh \
-	hb-ot-name-language.cc \
+	hb-ot-name-language-static.hh \
 	hb-ot-name-language.hh \
 	hb-ot-name-table.hh \
 	hb-ot-name.cc \
@@ -127,6 +130,9 @@
 	hb-ot-var-mvar-table.hh \
 	hb-ot-var.cc \
 	hb-ot-vorg-table.hh \
+	hb-pool.hh \
+	hb-sanitize.hh \
+	hb-serialize.hh \
 	hb-set-digest.hh \
 	hb-set.cc \
 	hb-set.hh \
@@ -139,6 +145,8 @@
 	hb-shaper.hh \
 	hb-static.cc \
 	hb-string-array.hh \
+	hb-ucd-table.hh \
+	hb-ucd.cc \
 	hb-unicode-emoji-table.hh \
 	hb-unicode.cc \
 	hb-unicode.hh \
@@ -218,9 +226,6 @@
 HB_UNISCRIBE_sources = hb-uniscribe.cc
 HB_UNISCRIBE_headers = hb-uniscribe.h
 
-# Additional supplemental sources
-HB_UCDN_sources  = hb-ucdn.cc
-
 # Sources for libharfbuzz-gobject and libharfbuzz-icu
 HB_ICU_sources = hb-icu.cc
 HB_ICU_headers = hb-icu.h
@@ -236,9 +241,6 @@
 	hb-subset-cff1.hh \
 	hb-subset-cff2.cc \
 	hb-subset-cff2.hh \
-	hb-subset-glyf.cc \
-	hb-subset-glyf.hh \
-	hb-subset-glyf.hh \
 	hb-subset-input.cc \
 	hb-subset-input.hh \
 	hb-subset-plan.cc \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -7,7 +7,7 @@
 test -z "$libs" && libs=.libs
 stat=0
 
-IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_flush\|llvm_.*'
+IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_.*\|llvm_.*'
 
 if which nm 2>/dev/null >/dev/null; then
 	:

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,8 +1,10 @@
+#!/usr/bin/python
+
 # -*- coding: utf-8 -*-
 
 # 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
-# (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1).
+# (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur).
 
 from __future__ import print_function, division, absolute_import
 

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	2019-05-24 23:03:55 UTC (rev 51218)
@@ -895,20 +895,18 @@
 def get_matching_language_name (intersection, candidates):
 	return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c))))
 
-maximum_tags = 0
+def same_tag (bcp_47_tag, ot_tags):
+	return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower ()
+
 for language, tags in sorted (ot.from_bcp_47.items ()):
 	if language == '' or '-' in language:
 		continue
-	print ('  {\"%s\",\t{' % language, end='')
-	maximum_tags = max (maximum_tags, len (tags))
-	tag_count = len (tags)
+	commented_out = same_tag (language, tags)
 	for i, tag in enumerate (tags, start=1):
-		if i > 1:
-			print ('\t\t ', end='')
-		print (hb_tag (tag), end='')
-		if i == tag_count:
-			print ('}}', end='')
-		print (',\t/* ', end='')
+		print ('%s{\"%s\",\t%s},' % ('/*' if commented_out else '  ', language, hb_tag (tag)), end='')
+		if commented_out:
+			print ('*/', end='')
+		print ('\t/* ', end='')
 		bcp_47_name = bcp_47.names.get (language, '')
 		bcp_47_name_candidates = bcp_47_name.split ('\n')
 		intersection = language_name_intersection (bcp_47_name, ot.names[tag])
@@ -923,8 +921,6 @@
 
 print ('};')
 print ()
-print ('static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == %iu, "");' % maximum_tags)
-print ()
 
 print ('/**')
 print (' * hb_ot_tags_from_complex_language:')
@@ -1051,7 +1047,8 @@
 print (' *')
 print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to')
 print (' * many language tags) and the best tag is not the alphabetically first, or if')
-print (' * the best tag consists of multiple subtags.')
+print (' * the best tag consists of multiple subtags, or if the best tag does not appear')
+print (' * in #ot_languages.')
 print (' *')
 print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,')
 print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.')
@@ -1102,7 +1099,8 @@
 						'%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag))
 			elif ot_tag not in disambiguation:
 				disambiguation[ot_tag] = macrolanguages[0]
-			if disambiguation[ot_tag] == sorted (primary_tags)[0] and '-' not in disambiguation[ot_tag]:
+			different_primary_tags = sorted (t for t in primary_tags if not same_tag (t, ot.from_bcp_47.get (t)))
+			if different_primary_tags and disambiguation[ot_tag] == different_primary_tags[0] and '-' not in disambiguation[ot_tag]:
 				del disambiguation[ot_tag]
 	for ot_tag in disambiguation.keys ():
 		expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag)

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+
+from __future__ import print_function, division, absolute_import
+
+import io, os.path, sys, re
+
+if len (sys.argv) != 2:
+	print("usage: ./gen-ucd-table ucd.nonunihan.grouped.xml", file=sys.stderr)
+	sys.exit(1)
+
+
+# https://github.com/harfbuzz/packtab
+# https://github.com/harfbuzz/youseedy
+import youseedy, packTab
+
+ucdxml = youseedy.load_ucdxml(sys.argv[1])
+ucd = youseedy.ucdxml_get_repertoire(ucdxml)
+
+
+gc = [u['gc'] for u in ucd]
+ccc = [int(u['ccc']) for u in ucd]
+bmg = [int(v, 16) - int(u) if v else 0 for u,v in enumerate(u['bmg'] for u in ucd)]
+#gc_ccc_non0 = set((cat,klass) for cat,klass in zip(gc,ccc) if klass)
+#gc_bmg_non0 = set((cat,mirr) for cat,mirr in zip(gc, bmg) if mirr)
+
+sc = [u['sc'] for u in ucd]
+
+dm = {i:tuple(int(v, 16) for v in u['dm'].split()) for i,u in enumerate(ucd)
+      if u['dm'] != '#' and u['dt'] == 'can' and not (0xAC00 <= i < 0xAC00+11172)}
+ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'}
+
+assert not any(v for v in dm.values() if len(v) not in (1,2))
+dm1 = sorted(set(v for v in dm.values() if len(v) == 1))
+dm1_array = ['0x%04Xu' % v for v in dm1]
+dm1_order = {v:i+1 for i,v in enumerate(dm1)}
+dm2 = sorted((v, i) for i,v in dm.items() if len(v) == 2)
+dm2 = [("HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" %
+        (v+(i if i not in ce and not ccc[i] else 0,)), v)
+       for v,i in dm2]
+dm2_array = [s for s,v in dm2]
+l = 1 + len(dm1_array)
+dm2_order = {v[1]:i+l for i,v in enumerate(dm2)}
+dm_order = {None: 0}
+dm_order.update(dm1_order)
+dm_order.update(dm2_order)
+
+gc_order = packTab.AutoMapping()
+for _ in ('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu',
+          'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf',
+          'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',):
+    gc_order[_]
+
+sc_order = packTab.AutoMapping()
+sc_array = []
+sc_re = re.compile(" (HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
+for line in open('hb-common.h'):
+    m = sc_re.search (line)
+    if not m: continue
+    name = m.group(1)
+    tag = ''.join(m.group(i) for i in range(2, 6))
+    i = sc_order[tag]
+    assert i == len(sc_array)
+    sc_array.append(name)
+
+# TODO Currently if gc_order or sc_order do not capture all values, we get in
+# trouble because they silently add new values.  We should be able to "freeze"
+# them, or just do the mapping ourselves.
+
+DEFAULT = 1
+COMPACT = 3
+
+
+print("/* == Start of generated table == */")
+print("/*")
+print(" * The following table is generated by running:")
+print(" *")
+print(" *   ./gen-ucd-table.py ucd.nonunihan.grouped.xml")
+print(" *")
+print(" * on file with this description:", ucdxml.description)
+print(" */")
+print()
+print("#ifndef HB_UCD_TABLE_HH")
+print("#define HB_UCD_TABLE_HH")
+print()
+
+print()
+print('#include "hb.hh"')
+print()
+
+code = packTab.Code('_hb_ucd')
+sc_array, _, _ = code.addArray('hb_script_t', 'sc_map', sc_array)
+dm1_array, _, _ = code.addArray('hb_codepoint_t', 'dm1_map', dm1_array)
+dm2_array, _, _ = code.addArray('uint64_t', 'dm2_map', dm2_array)
+code.print_c(linkage='static inline')
+
+for compression in (DEFAULT, COMPACT):
+    print()
+    if compression == DEFAULT:
+        print('#ifndef HB_OPTIMIZE_SIZE')
+    else:
+        print('#else')
+    print()
+
+    code = packTab.Code('_hb_ucd')
+
+    packTab.pack_table(gc, 'Cn', mapping=gc_order, compression=compression).genCode(code, 'gc')
+    packTab.pack_table(ccc, 0, compression=compression).genCode(code, 'ccc')
+    packTab.pack_table(bmg, 0, compression=compression).genCode(code, 'bmg')
+    packTab.pack_table(sc, 'Zzzz', mapping=sc_order, compression=compression).genCode(code, 'sc')
+    packTab.pack_table(dm, None, mapping=dm_order, compression=compression).genCode(code, 'dm')
+
+    code.print_c(linkage='static inline')
+
+
+    if compression != DEFAULT:
+        print()
+        print('#endif')
+    print()
+
+print()
+print("#endif /* HB_UCD_TABLE_HH */")
+print()
+print("/* == End of generated table == */")

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2019-05-24 23:03:55 UTC (rev 51218)
@@ -47,8 +47,22 @@
 
 # TODO Characters that are not in Unicode Indic files, but used in USE
 data[0][0x034F] = defaults[0]
+data[0][0x1B61] = defaults[0]
+data[0][0x1B63] = defaults[0]
+data[0][0x1B64] = defaults[0]
+data[0][0x1B65] = defaults[0]
+data[0][0x1B66] = defaults[0]
+data[0][0x1B67] = defaults[0]
+data[0][0x1B69] = defaults[0]
+data[0][0x1B6A] = defaults[0]
 data[0][0x2060] = defaults[0]
-# TODO https://github.com/roozbehp/unicode-data/issues/9
+# TODO https://github.com/harfbuzz/harfbuzz/pull/1685
+data[0][0x1B5B] = 'Consonant_Placeholder'
+data[0][0x1B5C] = 'Consonant_Placeholder'
+data[0][0x1B5F] = 'Consonant_Placeholder'
+data[0][0x1B62] = 'Consonant_Placeholder'
+data[0][0x1B68] = 'Consonant_Placeholder'
+# TODO https://github.com/harfbuzz/harfbuzz/issues/1035
 data[0][0x11C44] = 'Consonant_Placeholder'
 data[0][0x11C45] = 'Consonant_Placeholder'
 # TODO https://github.com/harfbuzz/harfbuzz/pull/1399
@@ -171,7 +185,7 @@
 def is_BASE_IND(U, UISC, UGC):
 	#SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po)
 	return (UISC in [Consonant_Dead, Modifying_Letter] or
-		(UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or
+		(UGC == Po and not U in [0x104B, 0x104E, 0x1B5B, 0x1B5C, 0x1B5F, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or
 		False # SPEC-DRAFT-OUTDATED! U == 0x002D
 		)
 def is_BASE_NUM(U, UISC, UGC):
@@ -183,15 +197,15 @@
 def is_CGJ(U, UISC, UGC):
 	return U == 0x034F
 def is_CONS_FINAL(U, UISC, UGC):
-	# Consonant_Initial_Postfixed is new in Unicode 11; not in the spec.
 	return ((UISC == Consonant_Final and UGC != Lo) or
-		UISC == Consonant_Initial_Postfixed or
 		UISC == Consonant_Succeeding_Repha)
 def is_CONS_FINAL_MOD(U, UISC, UGC):
 	#SPEC-DRAFT return  UISC in [Consonant_Final_Modifier, Syllable_Modifier]
 	return  UISC == Syllable_Modifier
 def is_CONS_MED(U, UISC, UGC):
-	return UISC == Consonant_Medial and UGC != Lo
+	# Consonant_Initial_Postfixed is new in Unicode 11; not in the spec.
+	return (UISC == Consonant_Medial and UGC != Lo or
+		UISC == Consonant_Initial_Postfixed)
 def is_CONS_MOD(U, UISC, UGC):
 	return UISC in [Nukta, Gemination_Mark, Consonant_Killer]
 def is_CONS_SUB(U, UISC, UGC):
@@ -216,6 +230,7 @@
 def is_OTHER(U, UISC, UGC):
 	#SPEC-OUTDATED return UGC == Zs # or any other SCRIPT_COMMON characters
 	return (UISC == Other
+		and not is_SYM(U, UISC, UGC)
 		and not is_SYM_MOD(U, UISC, UGC)
 		and not is_CGJ(U, UISC, UGC)
 		and not is_Word_Joiner(U, UISC, UGC)
@@ -228,17 +243,17 @@
 def is_SYM(U, UISC, UGC):
 	if U == 0x25CC: return False #SPEC-DRAFT
 	#SPEC-DRAFT return UGC in [So, Sc] or UISC == Symbol_Letter
-	return UGC in [So, Sc]
+	return UGC in [So, Sc] and U not in [0x1B62, 0x1B68]
 def is_SYM_MOD(U, UISC, UGC):
 	return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73]
 def is_VARIATION_SELECTOR(U, UISC, UGC):
 	return 0xFE00 <= U <= 0xFE0F
 def is_VOWEL(U, UISC, UGC):
-	# https://github.com/roozbehp/unicode-data/issues/6
+	# https://github.com/harfbuzz/harfbuzz/issues/376
 	return (UISC == Pure_Killer or
 		(UGC != Lo and UISC in [Vowel, Vowel_Dependent] and U not in [0xAA29]))
 def is_VOWEL_MOD(U, UISC, UGC):
-	# https://github.com/roozbehp/unicode-data/issues/6
+	# https://github.com/harfbuzz/harfbuzz/issues/376
 	return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or
 		(UGC != Lo and (UISC == Bindu or U in [0xAA29])))
 
@@ -305,7 +320,11 @@
 	'H': None,
 	'HVM': None,
 	'B': None,
-	'FM': None,
+	'FM': {
+		'Abv': [Top],
+		'Blw': [Bottom],
+		'Pst': [Not_Applicable],
+	},
 	'SUB': None,
 }
 
@@ -344,15 +363,9 @@
 		# the nasalization marks, maybe only for U+1CE9..U+1CF1.
 		if U == 0x1CED: UISC = Tone_Mark
 
-		# TODO: https://github.com/harfbuzz/harfbuzz/issues/525
-		if U == 0x1A7F: UISC = Consonant_Final
-
 		# TODO: https://github.com/harfbuzz/harfbuzz/issues/1105
 		if U == 0x11134: UISC = Gemination_Mark
 
-		# TODO: https://github.com/harfbuzz/harfbuzz/pull/1399
-		if U == 0x111C9: UISC = Consonant_Final
-
 		values = [k for k,v in items if v(U,UISC,UGC)]
 		assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values)
 		USE = values[0]

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py	2019-05-24 23:03:55 UTC (rev 51218)
@@ -180,6 +180,9 @@
 print ('\t\t\t\t       hb_buffer_t              *buffer,')
 print ('\t\t\t\t       hb_font_t                *font HB_UNUSED)')
 print ('{')
+print ('#if defined(HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS)')
+print ('  return;')
+print ('#endif')
 print ('  if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)')
 print ('    return;')
 print ()

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -83,7 +83,7 @@
   protected:
   HBUINT16	version; 	/* Version number (set to zero) */
   HBUINT16	flags;		/* Flags (currently unused; set to zero) */
-  LOffsetTo<Lookup<NNOffsetTo<GlyphAnchors> > >
+  LOffsetTo<Lookup<NNOffsetTo<GlyphAnchors>>>
 		lookupTable;	/* Offset to the table's lookup table */
   LNNOffsetTo<HBUINT8>
 		anchorData;	/* Offset to the glyph data table */

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -125,7 +125,7 @@
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 2 */
-  VarSizedBinSearchArrayOf<LookupSegmentSingle<T> >
+  VarSizedBinSearchArrayOf<LookupSegmentSingle<T>>
 		segments;	/* The actual segments. These must already be sorted,
 				 * according to the first word in each one (the last
 				 * glyph in each segment). */
@@ -153,18 +153,18 @@
 		  first <= last &&
 		  valuesZ.sanitize (c, base, last - first + 1));
   }
-  template <typename T2>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T2 user_data) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
 		  first <= last &&
-		  valuesZ.sanitize (c, base, last - first + 1, user_data));
+		  valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...));
   }
 
   GlyphID	last;		/* Last GlyphID in this segment */
   GlyphID	first;		/* First GlyphID in this segment */
-  NNOffsetTo<UnsizedArrayOf<T> >
+  NNOffsetTo<UnsizedArrayOf<T>>
 		valuesZ;	/* A 16-bit offset from the start of
 				 * the table to the data. */
   public:
@@ -196,7 +196,7 @@
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 4 */
-  VarSizedBinSearchArrayOf<LookupSegmentArray<T> >
+  VarSizedBinSearchArrayOf<LookupSegmentArray<T>>
 		segments;	/* The actual segments. These must already be sorted,
 				 * according to the first word in each one (the last
 				 * glyph in each segment). */
@@ -253,7 +253,7 @@
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 6 */
-  VarSizedBinSearchArrayOf<LookupSingle<T> >
+  VarSizedBinSearchArrayOf<LookupSingle<T>>
 		entries;	/* The actual entries, sorted by glyph index. */
   public:
   DEFINE_SIZE_ARRAY (8, entries);
@@ -419,7 +419,7 @@
 /* Ugly hand-coded null objects for template Lookup<> :(. */
 extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2];
 template <typename T>
-struct Null<AAT::Lookup<T> > {
+struct Null<AAT::Lookup<T>> {
   static AAT::Lookup<T> const & get_null ()
   { return *reinterpret_cast<const AAT::Lookup<T> *> (_hb_Null_AAT_Lookup); }
 };
@@ -510,7 +510,7 @@
   const Entry<Extra> &get_entry (int state, unsigned int klass) const
   {
     if (unlikely (klass >= nClasses))
-      klass = StateTable<Types, Entry<Extra> >::CLASS_OUT_OF_BOUNDS;
+      klass = StateTable<Types, Entry<Extra>>::CLASS_OUT_OF_BOUNDS;
 
     const HBUSHORT *states = (this+stateArrayTable).arrayZ;
     const Entry<Extra> *entries = (this+entryTable).arrayZ;
@@ -576,7 +576,7 @@
 	  if (unlikely (stop > states))
 	    return_trace (false);
 	  for (const HBUSHORT *p = states; stop < p; p--)
-	    num_entries = MAX<unsigned int> (num_entries, *(p - 1) + 1);
+	    num_entries = hb_max (num_entries, *(p - 1) + 1);
 	  state_neg = min_state;
 	}
       }
@@ -597,7 +597,7 @@
 	  if (unlikely (stop < states))
 	    return_trace (false);
 	  for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
-	    num_entries = MAX<unsigned int> (num_entries, *p + 1);
+	    num_entries = hb_max (num_entries, *p + 1);
 	  state_pos = max_state + 1;
 	}
       }
@@ -611,8 +611,8 @@
 	for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
 	{
 	  int newState = new_state (p->newState);
-	  min_state = MIN (min_state, newState);
-	  max_state = MAX (max_state, newState);
+	  min_state = hb_min (min_state, newState);
+	  max_state = hb_max (max_state, newState);
 	}
 	entry = num_entries;
       }
@@ -631,7 +631,7 @@
 		classTable;	/* Offset to the class table. */
   NNOffsetTo<UnsizedArrayOf<HBUSHORT>, HBUINT>
 		stateArrayTable;/* Offset to the state array. */
-  NNOffsetTo<UnsizedArrayOf<Entry<Extra> >, HBUINT>
+  NNOffsetTo<UnsizedArrayOf<Entry<Extra>>, HBUINT>
 		entryTable;	/* Offset to the entry array. */
 
   public:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -165,7 +165,7 @@
     unsigned int feature_count = featureNameCount;
     if (count && *count)
     {
-      unsigned int len = MIN (feature_count - start_offset, *count);
+      unsigned int len = hb_min (feature_count - start_offset, *count);
       for (unsigned int i = 0; i < len; i++)
 	features[i] = namesZ[i + start_offset].get_feature_type ();
       *count = len;

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -309,7 +309,7 @@
   public:
   DEFINE_SIZE_STATIC (24);
 };
-  
+
 typedef OT::LArrayOf<WidthDeltaPair> WidthDeltaCluster;
 
 struct JustificationCategory
@@ -371,7 +371,7 @@
 				 * of postcompensation subtable (set to zero if none).
 				 *
 				 * The postcompensation subtable, if present in the font. */
-  Lookup<OffsetTo<WidthDeltaCluster> >
+  Lookup<OffsetTo<WidthDeltaCluster>>
   		lookupTable;	/* Lookup table associating glyphs with width delta
 				 * clusters. See the description of Width Delta Clusters
 				 * table for details on how to interpret the lookup values. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -251,7 +251,7 @@
 
       if (Format1EntryT::performAction (entry) && depth)
       {
-	unsigned int tuple_count = MAX (1u, table->header.tuple_count ());
+	unsigned int tuple_count = hb_max (1u, table->header.tuple_count ());
 
 	unsigned int kern_idx = Format1EntryT::kernActionIndex (entry);
 	kern_idx = Types::byteOffsetToIndex (kern_idx, &table->machine, kernAction.arrayZ);
@@ -712,18 +712,18 @@
   {
     struct Long
     {
-      LNNOffsetTo<Lookup<HBUINT32> >		rowIndexTable;
-      LNNOffsetTo<Lookup<HBUINT32> >		columnIndexTable;
-      LNNOffsetTo<UnsizedArrayOf<FWORD32> >	array;
+      LNNOffsetTo<Lookup<HBUINT32>>		rowIndexTable;
+      LNNOffsetTo<Lookup<HBUINT32>>		columnIndexTable;
+      LNNOffsetTo<UnsizedArrayOf<FWORD32>>	array;
     } l;
     struct Short
     {
-      LNNOffsetTo<Lookup<HBUINT16> >		rowIndexTable;
-      LNNOffsetTo<Lookup<HBUINT16> >		columnIndexTable;
-      LNNOffsetTo<UnsizedArrayOf<FWORD> >	array;
+      LNNOffsetTo<Lookup<HBUINT16>>		rowIndexTable;
+      LNNOffsetTo<Lookup<HBUINT16>>		columnIndexTable;
+      LNNOffsetTo<UnsizedArrayOf<FWORD>>	array;
     } s;
   } u;
-  LNNOffsetTo<UnsizedArrayOf<FWORD> >	vector;
+  LNNOffsetTo<UnsizedArrayOf<FWORD>>	vector;
   public:
   DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 24);
 };
@@ -771,17 +771,17 @@
   unsigned int get_size () const { return u.header.length; }
   unsigned int get_type () const { return u.header.coverage & u.header.SubtableType; }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case 0:	return_trace (c->dispatch (u.format0));
-    case 1:	return_trace (c->dispatch (u.format1));
-    case 2:	return_trace (c->dispatch (u.format2));
-    case 4:	return_trace (c->dispatch (u.format4));
-    case 6:	return_trace (c->dispatch (u.format6));
+    case 0:	return_trace (c->dispatch (u.format0, hb_forward<Ts> (ds)...));
+    case 1:	return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2:	return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 4:	return_trace (c->dispatch (u.format4, hb_forward<Ts> (ds)...));
+    case 6:	return_trace (c->dispatch (u.format6, hb_forward<Ts> (ds)...));
     default:	return_trace (c->default_return_value ());
     }
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -81,7 +81,7 @@
   protected:
   FixedVersion<>version;	/* Version number of the ligature caret table */
   HBUINT16	format;		/* Format of the ligature caret table. */
-  Lookup<OffsetTo<LigCaretClassEntry> >
+  Lookup<OffsetTo<LigCaretClassEntry>>
 		lookup;		/* data Lookup table associating glyphs */
 
   public:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -88,7 +88,7 @@
 	start = buffer->idx;
 
       if (flags & MarkLast)
-	end = MIN (buffer->idx + 1, buffer->len);
+	end = hb_min (buffer->idx + 1, buffer->len);
 
       if ((flags & Verb) && start < end)
       {
@@ -117,14 +117,14 @@
 	};
 
 	unsigned int m = map[flags & Verb];
-	unsigned int l = MIN<unsigned int> (2, m >> 4);
-	unsigned int r = MIN<unsigned int> (2, m & 0x0F);
+	unsigned int l = hb_min (2u, m >> 4);
+	unsigned int r = hb_min (2u, m & 0x0F);
 	bool reverse_l = 3 == (m >> 4);
 	bool reverse_r = 3 == (m & 0x0F);
 
 	if (end - start >= l + r)
 	{
-	  buffer->merge_clusters (start, MIN (buffer->idx + 1, buffer->len));
+	  buffer->merge_clusters (start, hb_min (buffer->idx + 1, buffer->len));
 	  buffer->merge_clusters (start, end);
 
 	  hb_glyph_info_t *info = buffer->info;
@@ -261,13 +261,13 @@
       }
       if (replacement)
       {
-	buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len));
+	buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len));
 	buffer->info[mark].codepoint = *replacement;
 	ret = true;
       }
 
       replacement = nullptr;
-      unsigned int idx = MIN (buffer->idx, buffer->len - 1);
+      unsigned int idx = hb_min (buffer->idx, buffer->len - 1);
       if (Types::extended)
       {
 	if (entry.data.currentIndex != 0xFFFF)
@@ -337,9 +337,9 @@
       const EntryData &data = entries[i].data;
 
       if (data.markIndex != 0xFFFF)
-	num_lookups = MAX<unsigned int> (num_lookups, 1 + data.markIndex);
+	num_lookups = hb_max (num_lookups, 1 + data.markIndex);
       if (data.currentIndex != 0xFFFF)
-	num_lookups = MAX<unsigned int> (num_lookups, 1 + data.currentIndex);
+	num_lookups = hb_max (num_lookups, 1 + data.currentIndex);
     }
 
     return_trace (substitutionTables.sanitize (c, this, num_lookups));
@@ -744,7 +744,7 @@
 
 	buffer->move_to (end + count);
 
-	buffer->unsafe_to_break_from_outbuffer (mark, MIN (buffer->idx + 1, buffer->len));
+	buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len));
       }
 
       if (flags & SetMark)
@@ -883,17 +883,17 @@
     Insertion		= 5
   };
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case Rearrangement:		return_trace (c->dispatch (u.rearrangement));
-    case Contextual:		return_trace (c->dispatch (u.contextual));
-    case Ligature:		return_trace (c->dispatch (u.ligature));
-    case Noncontextual:		return_trace (c->dispatch (u.noncontextual));
-    case Insertion:		return_trace (c->dispatch (u.insertion));
+    case Rearrangement:		return_trace (c->dispatch (u.rearrangement, hb_forward<Ts> (ds)...));
+    case Contextual:		return_trace (c->dispatch (u.contextual, hb_forward<Ts> (ds)...));
+    case Ligature:		return_trace (c->dispatch (u.ligature, hb_forward<Ts> (ds)...));
+    case Noncontextual:		return_trace (c->dispatch (u.noncontextual, hb_forward<Ts> (ds)...));
+    case Insertion:		return_trace (c->dispatch (u.insertion, hb_forward<Ts> (ds)...));
     default:			return_trace (c->default_return_value ());
     }
   }
@@ -969,7 +969,7 @@
   void apply (hb_aat_apply_context_t *c,
 		     hb_mask_t flags) const
   {
-    const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types> > (featureZ.as_array (featureCount));
+    const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
     unsigned int count = subtableCount;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -1031,7 +1031,7 @@
       if (unlikely (!c->buffer->successful)) return;
 
     skip:
-      subtable = &StructAfter<ChainSubtable<Types> > (*subtable);
+      subtable = &StructAfter<ChainSubtable<Types>> (*subtable);
       c->set_lookup_index (c->lookup_index + 1);
     }
   }
@@ -1049,13 +1049,13 @@
     if (!c->check_array (featureZ.arrayZ, featureCount))
       return_trace (false);
 
-    const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types> > (featureZ.as_array (featureCount));
+    const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
     unsigned int count = subtableCount;
     for (unsigned int i = 0; i < count; i++)
     {
       if (!subtable->sanitize (c))
 	return_trace (false);
-      subtable = &StructAfter<ChainSubtable<Types> > (*subtable);
+      subtable = &StructAfter<ChainSubtable<Types>> (*subtable);
     }
 
     return_trace (true);
@@ -1095,7 +1095,7 @@
     for (unsigned int i = 0; i < count; i++)
     {
       map->chain_flags.push (chain->compile_flags (mapper));
-      chain = &StructAfter<Chain<Types> > (*chain);
+      chain = &StructAfter<Chain<Types>> (*chain);
     }
   }
 
@@ -1109,7 +1109,7 @@
     {
       chain->apply (c, c->plan->aat_map.chain_flags[i]);
       if (unlikely (!c->buffer->successful)) return;
-      chain = &StructAfter<Chain<Types> > (*chain);
+      chain = &StructAfter<Chain<Types>> (*chain);
     }
   }
 
@@ -1125,7 +1125,7 @@
     {
       if (!chain->sanitize (c, version))
 	return_trace (false);
-      chain = &StructAfter<Chain<Types> > (*chain);
+      chain = &StructAfter<Chain<Types>> (*chain);
     }
 
     return_trace (true);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -66,7 +66,7 @@
   NameID	trackNameID;	/* The 'name' table index for this track.
 				 * (a short word or phrase like "loose"
 				 * or "very tight") */
-  NNOffsetTo<UnsizedArrayOf<FWORD> >
+  NNOffsetTo<UnsizedArrayOf<FWORD>>
 		valuesZ;	/* Offset from start of tracking table to
 				 * per-size tracking values for this track. */
 
@@ -133,8 +133,8 @@
       if (size_table[size_index].to_float () >= csspx)
         break;
 
-    return round (interpolate_at (size_index ? size_index - 1 : 0, csspx,
-				  *trackTableEntry, base));
+    return roundf (interpolate_at (size_index ? size_index - 1 : 0, csspx,
+				   *trackTableEntry, base));
   }
 
   bool sanitize (hb_sanitize_context_t *c, const void *base) const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -135,6 +135,10 @@
 const hb_aat_feature_mapping_t *
 hb_aat_layout_find_feature_mapping (hb_tag_t tag)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return nullptr;
+#endif
+
   return (const hb_aat_feature_mapping_t *) bsearch (&tag,
 						     feature_mappings,
 						     ARRAY_LENGTH (feature_mappings),
@@ -147,6 +151,8 @@
  * hb_aat_apply_context_t
  */
 
+/* Note: This context is used for kerning, even without AAT. */
+
 AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
 						     hb_font_t *font_,
 						     hb_buffer_t *buffer_,
@@ -183,6 +189,10 @@
 hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
 			   hb_aat_map_t *map)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return;
+#endif
+
   const AAT::morx& morx = *mapper->face->table.morx;
   if (morx.has_data ())
   {
@@ -209,6 +219,10 @@
 hb_bool_t
 hb_aat_layout_has_substitution (hb_face_t *face)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return false;
+#endif
+
   return face->table.morx->has_data () ||
 	 face->table.mort->has_data ();
 }
@@ -218,6 +232,10 @@
 			  hb_font_t *font,
 			  hb_buffer_t *buffer)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return;
+#endif
+
   hb_blob_t *morx_blob = font->face->table.morx.get_blob ();
   const AAT::morx& morx = *morx_blob->as<AAT::morx> ();
   if (morx.has_data ())
@@ -240,6 +258,10 @@
 void
 hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return;
+#endif
+
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   hb_glyph_position_t *pos = buffer->pos;
@@ -257,6 +279,10 @@
 void
 hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return;
+#endif
+
   hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
 }
 
@@ -270,6 +296,10 @@
 hb_bool_t
 hb_aat_layout_has_positioning (hb_face_t *face)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return false;
+#endif
+
   return face->table.kerx->has_data ();
 }
 
@@ -278,6 +308,10 @@
 			hb_font_t *font,
 			hb_buffer_t *buffer)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return;
+#endif
+
   hb_blob_t *kerx_blob = font->face->table.kerx.get_blob ();
   const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> ();
 
@@ -297,6 +331,10 @@
 hb_bool_t
 hb_aat_layout_has_tracking (hb_face_t *face)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return false;
+#endif
+
   return face->table.trak->has_data ();
 }
 
@@ -305,6 +343,10 @@
 		     hb_font_t *font,
 		     hb_buffer_t *buffer)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return;
+#endif
+
   const AAT::trak& trak = *font->face->table.trak;
 
   AAT::hb_aat_apply_context_t c (plan, font, buffer);
@@ -311,14 +353,6 @@
   trak.apply (&c);
 }
 
-
-hb_language_t
-_hb_aat_language_get (hb_face_t *face,
-		      unsigned int i)
-{
-  return face->table.ltag->get_language (i);
-}
-
 /**
  * hb_aat_layout_get_feature_types:
  * @face: a face object
@@ -336,6 +370,12 @@
 				 unsigned int                 *feature_count, /* IN/OUT.  May be NULL. */
 				 hb_aat_layout_feature_type_t *features       /* OUT.     May be NULL. */)
 {
+#ifdef HB_NO_SHAPE_AAT
+  if (feature_count)
+    *feature_count = 0;
+  return 0;
+#endif
+
   return face->table.feat->get_feature_types (start_offset, feature_count, features);
 }
 
@@ -352,6 +392,10 @@
 hb_aat_layout_feature_type_get_name_id (hb_face_t                    *face,
 					hb_aat_layout_feature_type_t  feature_type)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return HB_OT_NAME_ID_INVALID;
+#endif
+
   return face->table.feat->get_feature_name_id (feature_type);
 }
 
@@ -380,5 +424,11 @@
 					       hb_aat_layout_feature_selector_info_t *selectors,      /* OUT.     May be NULL. */
 					       unsigned int                          *default_index   /* OUT.     May be NULL. */)
 {
+#ifdef HB_NO_SHAPE_AAT
+  if (selector_count)
+    *selector_count = 0;
+  return 0;
+#endif
+
   return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index);
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -30,8 +30,8 @@
 #include "hb.hh"
 
 #include "hb-ot-shape.hh"
+#include "hb-aat-ltag-table.hh"
 
-
 struct hb_aat_feature_mapping_t
 {
   hb_tag_t otFeatureTag;
@@ -39,7 +39,7 @@
   hb_aat_layout_feature_selector_t selectorToEnable;
   hb_aat_layout_feature_selector_t selectorToDisable;
 
-  static int cmp (const void *key_, const void *entry_)
+  HB_INTERNAL static int cmp (const void *key_, const void *entry_)
   {
     hb_tag_t key = * (unsigned int *) key_;
     const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_;
@@ -77,9 +77,13 @@
 		     hb_font_t *font,
 		     hb_buffer_t *buffer);
 
-HB_INTERNAL hb_language_t
+
+inline hb_language_t
 _hb_aat_language_get (hb_face_t *face,
-		      unsigned int i);
+                      unsigned int i)
+{
+  return face->table.ltag->get_language (i);
+}
 
 
 #endif /* HB_AAT_LAYOUT_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -50,7 +50,7 @@
   }
 
   protected:
-  NNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  NNOffsetTo<UnsizedArrayOf<HBUINT8>>
 		tag;		/* Offset from the start of the table to
 				 * the beginning of the string */
   HBUINT16	length;		/* String length (in bytes) */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -34,6 +34,10 @@
 void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
 					unsigned int value)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return;
+#endif
+
   if (tag == HB_TAG ('a','a','l','t'))
   {
     feature_info_t *info = features.push();
@@ -53,6 +57,10 @@
 void
 hb_aat_map_builder_t::compile (hb_aat_map_t  &m)
 {
+#ifdef HB_NO_SHAPE_AAT
+  return;
+#endif
+
   /* Sort features and merge duplicates */
   if (features.length)
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -66,7 +66,7 @@
     hb_aat_layout_feature_selector_t  setting;
     unsigned  seq; /* For stable sorting only. */
 
-    static int cmp (const void *pa, const void *pb)
+    HB_INTERNAL static int cmp (const void *pa, const void *pb)
     {
       const feature_info_t *a = (const feature_info_t *) pa;
       const feature_info_t *b = (const feature_info_t *) pb;
@@ -84,7 +84,7 @@
   hb_face_t *face;
 
   public:
-  hb_vector_t<feature_info_t> features;
+  hb_sorted_vector_t<feature_info_t> features;
 };
 
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,940 @@
+/*
+ * Copyright © 2017  Google, Inc.
+ * Copyright © 2019  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_ALGS_HH
+#define HB_ALGS_HH
+
+#include "hb.hh"
+#include "hb-meta.hh"
+#include "hb-null.hh"
+
+
+/* Encodes three unsigned integers in one 64-bit number.  If the inputs have more than 21 bits,
+ * values will be truncated / overlap, and might not decode exactly. */
+#define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z))
+#define HB_CODEPOINT_DECODE3_1(v) ((hb_codepoint_t) ((v) >> 42))
+#define HB_CODEPOINT_DECODE3_2(v) ((hb_codepoint_t) ((v) >> 21) & 0x1FFFFFu)
+#define HB_CODEPOINT_DECODE3_3(v) ((hb_codepoint_t) (v) & 0x1FFFFFu)
+
+
+struct
+{
+  /* Note.  This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */
+  template <typename T> auto
+  operator () (T&& v) const HB_AUTO_RETURN ( hb_forward<T> (v) )
+}
+HB_FUNCOBJ (hb_identity);
+struct
+{
+  /* Like identity(), but only retains lvalue-references.  Rvalues are returned as rvalues. */
+  template <typename T> T&
+  operator () (T& v) const { return v; }
+
+  template <typename T> hb_remove_reference<T>
+  operator () (T&& v) const { return v; }
+}
+HB_FUNCOBJ (hb_lidentity);
+struct
+{
+  /* Like identity(), but always returns rvalue. */
+  template <typename T> hb_remove_reference<T>
+  operator () (T&& v) const { return v; }
+}
+HB_FUNCOBJ (hb_ridentity);
+
+struct
+{
+  template <typename T> bool
+  operator () (T&& v) const { return bool (hb_forward<T> (v)); }
+}
+HB_FUNCOBJ (hb_bool);
+
+struct
+{
+  private:
+  template <typename T> auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+
+  template <typename T,
+	    hb_enable_if (hb_is_integral (T))> auto
+  impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    /* Knuth's multiplicative method: */
+    (uint32_t) v * 2654435761u
+  )
+
+  public:
+
+  template <typename T> auto
+  operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize))
+}
+HB_FUNCOBJ (hb_hash);
+
+
+struct
+{
+  private:
+
+  /* Pointer-to-member-function. */
+  template <typename Appl, typename T, typename ...Ts> auto
+  impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN
+  ((hb_deref (hb_forward<T> (v)).*hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...))
+
+  /* Pointer-to-member. */
+  template <typename Appl, typename T> auto
+  impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN
+  ((hb_deref (hb_forward<T> (v))).*hb_forward<Appl> (a))
+
+  /* Operator(). */
+  template <typename Appl, typename ...Ts> auto
+  impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN
+  (hb_deref (hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...))
+
+  public:
+
+  template <typename Appl, typename ...Ts> auto
+  operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN
+  (
+    impl (hb_forward<Appl> (a),
+	  hb_prioritize,
+	  hb_forward<Ts> (ds)...)
+  )
+}
+HB_FUNCOBJ (hb_invoke);
+
+template <unsigned Pos, typename Appl, typename V>
+struct hb_partial_t
+{
+  hb_partial_t (Appl a, V v) : a (a), v (v) {}
+
+  static_assert (Pos > 0, "");
+
+  template <typename ...Ts,
+	    unsigned P = Pos,
+	    hb_enable_if (P == 1)> auto
+  operator () (Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
+						   hb_declval (V),
+						   hb_declval (Ts)...))
+  {
+    return hb_invoke (hb_forward<Appl> (a),
+		      hb_forward<V> (v),
+		      hb_forward<Ts> (ds)...);
+  }
+  template <typename T0, typename ...Ts,
+	    unsigned P = Pos,
+	    hb_enable_if (P == 2)> auto
+  operator () (T0&& d0, Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
+							    hb_declval (T0),
+							    hb_declval (V),
+							    hb_declval (Ts)...))
+  {
+    return hb_invoke (hb_forward<Appl> (a),
+		      hb_forward<T0> (d0),
+		      hb_forward<V> (v),
+		      hb_forward<Ts> (ds)...);
+  }
+
+  private:
+  hb_reference_wrapper<Appl> a;
+  V v;
+};
+template <unsigned Pos=1, typename Appl, typename V>
+auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN
+(( hb_partial_t<Pos, Appl, V> (a, v) ))
+
+#define HB_PARTIALIZE(Pos) \
+  template <typename _T> \
+  auto operator () (_T&& _v) const HB_AUTO_RETURN (hb_partial<Pos> (this, hb_forward<_T> (_v))) \
+  static_assert (true, "")
+
+
+struct
+{
+  private:
+
+  template <typename Pred, typename Val> auto
+  impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
+  (hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v)))
+
+  template <typename Pred, typename Val> auto
+  impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    hb_invoke (hb_forward<Pred> (p),
+	       hb_forward<Val> (v))
+  )
+
+  public:
+
+  template <typename Pred, typename Val> auto
+  operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
+    impl (hb_forward<Pred> (p),
+	  hb_forward<Val> (v),
+	  hb_prioritize)
+  )
+}
+HB_FUNCOBJ (hb_has);
+
+struct
+{
+  private:
+
+  template <typename Pred, typename Val> auto
+  impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
+  (
+    hb_has (hb_forward<Pred> (p),
+	    hb_forward<Val> (v))
+  )
+
+  template <typename Pred, typename Val> auto
+  impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    hb_forward<Pred> (p) == hb_forward<Val> (v)
+  )
+
+  public:
+
+  template <typename Pred, typename Val> auto
+  operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
+    impl (hb_forward<Pred> (p),
+	  hb_forward<Val> (v),
+	  hb_prioritize)
+  )
+}
+HB_FUNCOBJ (hb_match);
+
+struct
+{
+  private:
+
+  template <typename Proj, typename Val> auto
+  impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
+  (hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v)))
+
+  template <typename Proj, typename Val> auto
+  impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
+  (
+    hb_invoke (hb_forward<Proj> (f),
+	       hb_forward<Val> (v))
+  )
+
+  template <typename Proj, typename Val> auto
+  impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    hb_forward<Proj> (f)[hb_forward<Val> (v)]
+  )
+
+  public:
+
+  template <typename Proj, typename Val> auto
+  operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN
+  (
+    impl (hb_forward<Proj> (f),
+	  hb_forward<Val> (v),
+	  hb_prioritize)
+  )
+}
+HB_FUNCOBJ (hb_get);
+
+
+template <typename T1, typename T2>
+struct hb_pair_t
+{
+  typedef T1 first_t;
+  typedef T2 second_t;
+  typedef hb_pair_t<T1, T2> pair_t;
+
+  hb_pair_t (T1 a, T2 b) : first (a), second (b) {}
+
+  template <typename Q1, typename Q2,
+	    hb_enable_if (hb_is_convertible (T1, Q1) &&
+			  hb_is_convertible (T2, T2))>
+  operator hb_pair_t<Q1, Q2> () { return hb_pair_t<Q1, Q2> (first, second); }
+
+  hb_pair_t<T1, T2> reverse () const
+  { return hb_pair_t<T1, T2> (second, first); }
+
+  bool operator == (const pair_t& o) const { return first == o.first && second == o.second; }
+  bool operator != (const pair_t& o) const { return !(*this == o); }
+  bool operator < (const pair_t& o) const { return first < o.first || (first == o.first && second < o.second); }
+  bool operator >= (const pair_t& o) const { return !(*this < o); }
+  bool operator > (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); }
+  bool operator <= (const pair_t& o) const { return !(*this > o); }
+
+  T1 first;
+  T2 second;
+};
+#define hb_pair_t(T1,T2) hb_pair_t<T1, T2>
+template <typename T1, typename T2> static inline hb_pair_t<T1, T2>
+hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
+
+struct
+{
+  template <typename Pair> typename Pair::first_t
+  operator () (const Pair& pair) const { return pair.first; }
+}
+HB_FUNCOBJ (hb_first);
+
+struct
+{
+  template <typename Pair> typename Pair::second_t
+  operator () (const Pair& pair) const { return pair.second; }
+}
+HB_FUNCOBJ (hb_second);
+
+/* Note.  In min/max impl, we can use hb_type_identity<T> for second argument.
+ * However, that would silently convert between different-signedness integers.
+ * Instead we accept two different types, such that compiler can err if
+ * comparing integers of different signedness. */
+struct
+{
+  template <typename T, typename T2> auto
+  operator () (T&& a, T2&& b) const HB_AUTO_RETURN
+  (hb_forward<T> (a) <= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
+}
+HB_FUNCOBJ (hb_min);
+struct
+{
+  template <typename T, typename T2> auto
+  operator () (T&& a, T2&& b) const HB_AUTO_RETURN
+  (hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
+}
+HB_FUNCOBJ (hb_max);
+
+
+/*
+ * Bithacks.
+ */
+
+/* Return the number of 1 bits in v. */
+template <typename T>
+static inline HB_CONST_FUNC unsigned int
+hb_popcount (T v)
+{
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+  if (sizeof (T) <= sizeof (unsigned int))
+    return __builtin_popcount (v);
+
+  if (sizeof (T) <= sizeof (unsigned long))
+    return __builtin_popcountl (v);
+
+  if (sizeof (T) <= sizeof (unsigned long long))
+    return __builtin_popcountll (v);
+#endif
+
+  if (sizeof (T) <= 4)
+  {
+    /* "HACKMEM 169" */
+    uint32_t y;
+    y = (v >> 1) &033333333333;
+    y = v - y - ((y >>1) & 033333333333);
+    return (((y + (y >> 3)) & 030707070707) % 077);
+  }
+
+  if (sizeof (T) == 8)
+  {
+    unsigned int shift = 32;
+    return hb_popcount<uint32_t> ((uint32_t) v) + hb_popcount ((uint32_t) (v >> shift));
+  }
+
+  if (sizeof (T) == 16)
+  {
+    unsigned int shift = 64;
+    return hb_popcount<uint64_t> ((uint64_t) v) + hb_popcount ((uint64_t) (v >> shift));
+  }
+
+  assert (0);
+  return 0; /* Shut up stupid compiler. */
+}
+
+/* Returns the number of bits needed to store number */
+template <typename T>
+static inline HB_CONST_FUNC unsigned int
+hb_bit_storage (T v)
+{
+  if (unlikely (!v)) return 0;
+
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+  if (sizeof (T) <= sizeof (unsigned int))
+    return sizeof (unsigned int) * 8 - __builtin_clz (v);
+
+  if (sizeof (T) <= sizeof (unsigned long))
+    return sizeof (unsigned long) * 8 - __builtin_clzl (v);
+
+  if (sizeof (T) <= sizeof (unsigned long long))
+    return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
+#endif
+
+#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
+  if (sizeof (T) <= sizeof (unsigned int))
+  {
+    unsigned long where;
+    _BitScanReverse (&where, v);
+    return 1 + where;
+  }
+# if defined(_WIN64)
+  if (sizeof (T) <= 8)
+  {
+    unsigned long where;
+    _BitScanReverse64 (&where, v);
+    return 1 + where;
+  }
+# endif
+#endif
+
+  if (sizeof (T) <= 4)
+  {
+    /* "bithacks" */
+    const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
+    const unsigned int S[] = {1, 2, 4, 8, 16};
+    unsigned int r = 0;
+    for (int i = 4; i >= 0; i--)
+      if (v & b[i])
+      {
+	v >>= S[i];
+	r |= S[i];
+      }
+    return r + 1;
+  }
+  if (sizeof (T) <= 8)
+  {
+    /* "bithacks" */
+    const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
+    const unsigned int S[] = {1, 2, 4, 8, 16, 32};
+    unsigned int r = 0;
+    for (int i = 5; i >= 0; i--)
+      if (v & b[i])
+      {
+	v >>= S[i];
+	r |= S[i];
+      }
+    return r + 1;
+  }
+  if (sizeof (T) == 16)
+  {
+    unsigned int shift = 64;
+    return (v >> shift) ? hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
+			  hb_bit_storage<uint64_t> ((uint64_t) v);
+  }
+
+  assert (0);
+  return 0; /* Shut up stupid compiler. */
+}
+
+/* Returns the number of zero bits in the least significant side of v */
+template <typename T>
+static inline HB_CONST_FUNC unsigned int
+hb_ctz (T v)
+{
+  if (unlikely (!v)) return 0;
+
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+  if (sizeof (T) <= sizeof (unsigned int))
+    return __builtin_ctz (v);
+
+  if (sizeof (T) <= sizeof (unsigned long))
+    return __builtin_ctzl (v);
+
+  if (sizeof (T) <= sizeof (unsigned long long))
+    return __builtin_ctzll (v);
+#endif
+
+#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
+  if (sizeof (T) <= sizeof (unsigned int))
+  {
+    unsigned long where;
+    _BitScanForward (&where, v);
+    return where;
+  }
+# if defined(_WIN64)
+  if (sizeof (T) <= 8)
+  {
+    unsigned long where;
+    _BitScanForward64 (&where, v);
+    return where;
+  }
+# endif
+#endif
+
+  if (sizeof (T) <= 4)
+  {
+    /* "bithacks" */
+    unsigned int c = 32;
+    v &= - (int32_t) v;
+    if (v) c--;
+    if (v & 0x0000FFFF) c -= 16;
+    if (v & 0x00FF00FF) c -= 8;
+    if (v & 0x0F0F0F0F) c -= 4;
+    if (v & 0x33333333) c -= 2;
+    if (v & 0x55555555) c -= 1;
+    return c;
+  }
+  if (sizeof (T) <= 8)
+  {
+    /* "bithacks" */
+    unsigned int c = 64;
+    v &= - (int64_t) (v);
+    if (v) c--;
+    if (v & 0x00000000FFFFFFFFULL) c -= 32;
+    if (v & 0x0000FFFF0000FFFFULL) c -= 16;
+    if (v & 0x00FF00FF00FF00FFULL) c -= 8;
+    if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4;
+    if (v & 0x3333333333333333ULL) c -= 2;
+    if (v & 0x5555555555555555ULL) c -= 1;
+    return c;
+  }
+  if (sizeof (T) == 16)
+  {
+    unsigned int shift = 64;
+    return (uint64_t) v ? hb_bit_storage<uint64_t> ((uint64_t) v) :
+			  hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift;
+  }
+
+  assert (0);
+  return 0; /* Shut up stupid compiler. */
+}
+
+
+/*
+ * Tiny stuff.
+ */
+
+/* ASCII tag/character handling */
+static inline bool ISALPHA (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
+static inline bool ISALNUM (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
+static inline bool ISSPACE (unsigned char c)
+{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
+static inline unsigned char TOUPPER (unsigned char c)
+{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
+static inline unsigned char TOLOWER (unsigned char c)
+{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
+
+static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
+{ return (a + (b - 1)) / b; }
+
+
+#undef  ARRAY_LENGTH
+template <typename Type, unsigned int n>
+static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
+/* A const version, but does not detect erratically being called on pointers. */
+#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
+
+
+static inline int
+hb_memcmp (const void *a, const void *b, unsigned int len)
+{
+  /* It's illegal to pass NULL to memcmp(), even if len is zero.
+   * So, wrap it.
+   * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
+  if (!len) return 0;
+  return memcmp (a, b, len);
+}
+
+static inline bool
+hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
+{
+  return (size > 0) && (count >= ((unsigned int) -1) / size);
+}
+
+static inline unsigned int
+hb_ceil_to_4 (unsigned int v)
+{
+  return ((v - 1) | 3) + 1;
+}
+
+template <typename T> static inline bool
+hb_in_range (T u, T lo, T hi)
+{
+  static_assert (!hb_is_signed<T>::value, "");
+
+  /* The casts below are important as if T is smaller than int,
+   * the subtract results will become a signed int! */
+  return (T)(u - lo) <= (T)(hi - lo);
+}
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
+{
+  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
+}
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
+{
+  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
+}
+
+
+/*
+ * Sort and search.
+ */
+
+static inline void *
+hb_bsearch (const void *key, const void *base,
+	    size_t nmemb, size_t size,
+	    int (*compar)(const void *_key, const void *_item))
+{
+  int min = 0, max = (int) nmemb - 1;
+  while (min <= max)
+  {
+    int mid = (min + max) / 2;
+    const void *p = (const void *) (((const char *) base) + (mid * size));
+    int c = compar (key, p);
+    if (c < 0)
+      max = mid - 1;
+    else if (c > 0)
+      min = mid + 1;
+    else
+      return (void *) p;
+  }
+  return nullptr;
+}
+
+static inline void *
+hb_bsearch_r (const void *key, const void *base,
+	      size_t nmemb, size_t size,
+	      int (*compar)(const void *_key, const void *_item, void *_arg),
+	      void *arg)
+{
+  int min = 0, max = (int) nmemb - 1;
+  while (min <= max)
+  {
+    int mid = ((unsigned int) min + (unsigned int) max) / 2;
+    const void *p = (const void *) (((const char *) base) + (mid * size));
+    int c = compar (key, p, arg);
+    if (c < 0)
+      max = mid - 1;
+    else if (c > 0)
+      min = mid + 1;
+    else
+      return (void *) p;
+  }
+  return nullptr;
+}
+
+
+/* From https://github.com/noporpoise/sort_r
+ * With following modifications:
+ *
+ * 10 November 2018:
+ * https://github.com/noporpoise/sort_r/issues/7
+ */
+
+/* Isaac Turner 29 April 2014 Public Domain */
+
+/*
+
+hb_sort_r function to be exported.
+
+Parameters:
+  base is the array to be sorted
+  nel is the number of elements in the array
+  width is the size in bytes of each element of the array
+  compar is the comparison function
+  arg is a pointer to be passed to the comparison function
+
+void hb_sort_r(void *base, size_t nel, size_t width,
+               int (*compar)(const void *_a, const void *_b, void *_arg),
+               void *arg);
+*/
+
+
+/* swap a, b iff a>b */
+/* __restrict is same as restrict but better support on old machines */
+static int sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w,
+			  int (*compar)(const void *_a, const void *_b,
+					void *_arg),
+			  void *arg)
+{
+  char tmp, *end = a+w;
+  if(compar(a, b, arg) > 0) {
+    for(; a < end; a++, b++) { tmp = *a; *a = *b; *b = tmp; }
+    return 1;
+  }
+  return 0;
+}
+
+/* Note: quicksort is not stable, equivalent values may be swapped */
+static inline void sort_r_simple(void *base, size_t nel, size_t w,
+				 int (*compar)(const void *_a, const void *_b,
+					       void *_arg),
+				 void *arg)
+{
+  char *b = (char *)base, *end = b + nel*w;
+  if(nel < 7) {
+    /* Insertion sort for arbitrarily small inputs */
+    char *pi, *pj;
+    for(pi = b+w; pi < end; pi += w) {
+      for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {}
+    }
+  }
+  else
+  {
+    /* nel > 6; Quicksort */
+
+    /* Use median of first, middle and last items as pivot */
+    char *x, *y, *xend, ch;
+    char *pl, *pm, *pr;
+    char *last = b+w*(nel-1), *tmp;
+    char *l[3];
+    l[0] = b;
+    l[1] = b+w*(nel/2);
+    l[2] = last;
+
+    if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
+    if(compar(l[1],l[2],arg) > 0) {
+      tmp=l[1]; l[1]=l[2]; l[2]=tmp; /* swap(l[1],l[2]) */
+      if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
+    }
+
+    /* swap l[id], l[2] to put pivot as last element */
+    for(x = l[1], y = last, xend = x+w; x<xend; x++, y++) {
+      ch = *x; *x = *y; *y = ch;
+    }
+
+    pl = b;
+    pr = last;
+
+    while(pl < pr) {
+      pm = pl+((pr-pl+1)>>1);
+      for(; pl < pm; pl += w) {
+        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
+          pr -= w; /* pivot now at pl */
+          break;
+        }
+      }
+      pm = pl+((pr-pl)>>1);
+      for(; pm < pr; pr -= w) {
+        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
+          pl += w; /* pivot now at pr */
+          break;
+        }
+      }
+    }
+
+    sort_r_simple(b, (pl-b)/w, w, compar, arg);
+    sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg);
+  }
+}
+
+static inline void
+hb_sort_r (void *base, size_t nel, size_t width,
+	   int (*compar)(const void *_a, const void *_b, void *_arg),
+	   void *arg)
+{
+    sort_r_simple(base, nel, width, compar, arg);
+}
+
+
+template <typename T, typename T2, typename T3> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2)
+{
+  for (unsigned int i = 1; i < len; i++)
+  {
+    unsigned int j = i;
+    while (j && compar (&array[j - 1], &array[i]) > 0)
+      j--;
+    if (i == j)
+      continue;
+    /* Move item i to occupy place for item j, shift what's in between. */
+    {
+      T t = array[i];
+      memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
+      array[j] = t;
+    }
+    if (array2)
+    {
+      T3 t = array2[i];
+      memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T3));
+      array2[j] = t;
+    }
+  }
+}
+
+template <typename T> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
+{
+  hb_stable_sort (array, len, compar, (int *) nullptr);
+}
+
+static inline hb_bool_t
+hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
+{
+  /* Pain because we don't know whether s is nul-terminated. */
+  char buf[64];
+  len = hb_min (ARRAY_LENGTH (buf) - 1, len);
+  strncpy (buf, s, len);
+  buf[len] = '\0';
+
+  char *end;
+  errno = 0;
+  unsigned long v = strtoul (buf, &end, base);
+  if (errno) return false;
+  if (*end) return false;
+  *out = v;
+  return true;
+}
+
+
+/* Operators. */
+
+struct hb_bitwise_and
+{ HB_PARTIALIZE(2);
+  static constexpr bool passthru_left = false;
+  static constexpr bool passthru_right = false;
+  template <typename T> auto
+   operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
+}
+HB_FUNCOBJ (hb_bitwise_and);
+struct hb_bitwise_or
+{ HB_PARTIALIZE(2);
+  static constexpr bool passthru_left = true;
+  static constexpr bool passthru_right = true;
+  template <typename T> auto
+   operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
+}
+HB_FUNCOBJ (hb_bitwise_or);
+struct hb_bitwise_xor
+{ HB_PARTIALIZE(2);
+  static constexpr bool passthru_left = true;
+  static constexpr bool passthru_right = true;
+  template <typename T> auto
+   operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
+}
+HB_FUNCOBJ (hb_bitwise_xor);
+struct hb_bitwise_sub
+{ HB_PARTIALIZE(2);
+  static constexpr bool passthru_left = true;
+  static constexpr bool passthru_right = false;
+  template <typename T> auto
+   operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
+}
+HB_FUNCOBJ (hb_bitwise_sub);
+
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a + b)
+}
+HB_FUNCOBJ (hb_add);
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a - b)
+}
+HB_FUNCOBJ (hb_sub);
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b)
+}
+HB_FUNCOBJ (hb_mul);
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a / b)
+}
+HB_FUNCOBJ (hb_div);
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a % b)
+}
+HB_FUNCOBJ (hb_mod);
+struct
+{
+  template <typename T> auto
+  operator () (const T &a) const HB_AUTO_RETURN (+a)
+}
+HB_FUNCOBJ (hb_pos);
+struct
+{
+  template <typename T> auto
+  operator () (const T &a) const HB_AUTO_RETURN (-a)
+}
+HB_FUNCOBJ (hb_neg);
+
+
+/* Compiler-assisted vectorization. */
+
+/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
+ * using vectorized operations if HB_VECTOR_SIZE is set to **bit** numbers (eg 128).
+ * Define that to 0 to disable. */
+template <typename elt_t, unsigned int byte_size>
+struct hb_vector_size_t
+{
+  elt_t& operator [] (unsigned int i) { return u.v[i]; }
+  const elt_t& operator [] (unsigned int i) const { return u.v[i]; }
+
+  void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); }
+
+  template <typename Op>
+  hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
+  {
+    hb_vector_size_t r;
+#if HB_VECTOR_SIZE
+    if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
+      for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
+	r.u.vec[i] = op (u.vec[i], o.u.vec[i]);
+    else
+#endif
+      for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
+	r.u.v[i] = op (u.v[i], o.u.v[i]);
+    return r;
+  }
+  hb_vector_size_t operator | (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_or, o); }
+  hb_vector_size_t operator & (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_and, o); }
+  hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_xor, o); }
+  hb_vector_size_t operator ~ () const
+  {
+    hb_vector_size_t r;
+#if HB_VECTOR_SIZE && 0
+    if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
+      for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
+	r.u.vec[i] = ~u.vec[i];
+    else
+#endif
+    for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
+      r.u.v[i] = ~u.v[i];
+    return r;
+  }
+
+  private:
+  static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
+  union {
+    elt_t v[byte_size / sizeof (elt_t)];
+#if HB_VECTOR_SIZE
+    hb_vector_size_impl_t vec[byte_size / sizeof (hb_vector_size_impl_t)];
+#endif
+  } u;
+};
+
+
+#endif /* HB_ALGS_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -28,7 +28,7 @@
 #define HB_ARRAY_HH
 
 #include "hb.hh"
-#include "hb-dsalgs.hh"
+#include "hb-algs.hh"
 #include "hb-iter.hh"
 #include "hb-null.hh"
 
@@ -37,22 +37,31 @@
 struct hb_sorted_array_t;
 
 template <typename Type>
-struct hb_array_t :
-	hb_iter_t<hb_array_t<Type>, Type>,
-	hb_iter_mixin_t<hb_array_t<Type>, Type>
+struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
 {
   /*
    * Constructors.
    */
-  hb_array_t () : arrayZ (nullptr), length (0) {}
-  hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
-  template <unsigned int length_> hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {}
+  hb_array_t () : arrayZ (nullptr), length (0), backwards_length (0) {}
+  hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_), backwards_length (0) {}
+  template <unsigned int length_>
+  hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {}
 
+  template <typename U,
+	    hb_enable_if (hb_is_cr_convertible(U, Type))>
+  hb_array_t (const hb_array_t<U> &o) :
+    hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (),
+    arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
+  template <typename U,
+	    hb_enable_if (hb_is_cr_convertible(U, Type))>
+  hb_array_t& operator = (const hb_array_t<U> &o)
+  { arrayZ = o.arrayZ; length = o.length; backwards_length = o.backwards_length; return *this; }
 
   /*
    * Iterator implementation.
    */
-  typedef Type __item_type__;
+  typedef Type& __item_t__;
+  static constexpr bool is_random_access_iterator = true;
   Type& __item_at__ (unsigned i) const
   {
     if (unlikely (i >= length)) return CrapOrNull (Type);
@@ -63,16 +72,25 @@
     if (unlikely (n > length))
       n = length;
     length -= n;
+    backwards_length += n;
     arrayZ += n;
   }
   void __rewind__ (unsigned n)
   {
-    if (unlikely (n > length))
-      n = length;
-    length -= n;
+    if (unlikely (n > backwards_length))
+      n = backwards_length;
+    length += n;
+    backwards_length -= n;
+    arrayZ -= n;
   }
   unsigned __len__ () const { return length; }
-  bool __random_access__ () const { return true; }
+  /* Ouch. The operator== compares the contents of the array.  For range-based for loops,
+   * it's best if we can just compare arrayZ, though comparing contents is still fast,
+   * but also would require that Type has operator==.  As such, we optimize this operator
+   * for range-based for loop and just compare arrayZ.  No need to compare length, as we
+   * assume we're only compared to .end(). */
+  bool operator != (const hb_array_t& o) const
+  { return arrayZ != o.arrayZ; }
 
   /* Extra operators.
    */
@@ -80,6 +98,9 @@
   operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); }
   template <typename T> operator T * () const { return arrayZ; }
 
+  HB_INTERNAL bool operator == (const hb_array_t &o) const;
+  HB_INTERNAL uint32_t hash () const;
+
   /*
    * Compare, Sort, and Search.
    */
@@ -91,7 +112,7 @@
       return (int) a.length - (int) length;
     return hb_memcmp (a.arrayZ, arrayZ, get_size ());
   }
-  static int cmp (const void *pa, const void *pb)
+  HB_INTERNAL static int cmp (const void *pa, const void *pb)
   {
     hb_array_t<Type> *a = (hb_array_t<Type> *) pa;
     hb_array_t<Type> *b = (hb_array_t<Type> *) pb;
@@ -131,7 +152,7 @@
   }
   void qsort (unsigned int start, unsigned int end)
   {
-    end = MIN (end, length);
+    end = hb_min (end, length);
     assert (start <= end);
     if (likely (start < end))
       ::qsort (arrayZ + start, end - start, this->item_size, Type::cmp);
@@ -154,7 +175,7 @@
     else
       count -= start_offset;
     if (seg_count)
-      count = *seg_count = MIN (count, *seg_count);
+      count = *seg_count = hb_min (count, *seg_count);
     return hb_array_t<Type> (arrayZ + start_offset, count);
   }
   hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int seg_count) const
@@ -164,6 +185,17 @@
   void free ()
   { ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
 
+  template <typename hb_serialize_context_t>
+  hb_array_t copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto* out = c->start_embed (arrayZ);
+    if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ());
+    for (unsigned i = 0; i < length; i++)
+      out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
+    return_trace (hb_array_t (out, length));
+  }
+
   template <typename hb_sanitize_context_t>
   bool sanitize (hb_sanitize_context_t *c) const
   { return c->check_array (arrayZ, length); }
@@ -175,6 +207,7 @@
   public:
   Type *arrayZ;
   unsigned int length;
+  unsigned int backwards_length;
 };
 template <typename T> inline hb_array_t<T>
 hb_array (T *array, unsigned int length)
@@ -183,7 +216,6 @@
 hb_array (T (&array_)[length_])
 { return hb_array_t<T> (array_); }
 
-
 enum hb_bfind_not_found_t
 {
   HB_BFIND_NOT_FOUND_DONT_STORE,
@@ -193,15 +225,33 @@
 
 template <typename Type>
 struct hb_sorted_array_t :
-	hb_sorted_iter_t<hb_sorted_array_t<Type>, Type>,
-	hb_array_t<Type>,
-	hb_iter_mixin_t<hb_sorted_array_t<Type>, Type>
+	hb_iter_t<hb_sorted_array_t<Type>, Type&>,
+	hb_array_t<Type>
 {
+  typedef hb_iter_t<hb_sorted_array_t<Type>, Type&> iter_base_t;
+  HB_ITER_USING (iter_base_t);
+  static constexpr bool is_random_access_iterator = true;
+  static constexpr bool is_sorted_iterator = true;
+
   hb_sorted_array_t () : hb_array_t<Type> () {}
-  hb_sorted_array_t (const hb_array_t<Type> &o) : hb_array_t<Type> (o) {}
   hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
-  template <unsigned int length_> hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
+  template <unsigned int length_>
+  hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
 
+  template <typename U,
+	    hb_enable_if (hb_is_cr_convertible(U, Type))>
+  hb_sorted_array_t (const hb_array_t<U> &o) :
+    hb_iter_t<hb_sorted_array_t<Type>, Type&> (),
+    hb_array_t<Type> (o) {}
+  template <typename U,
+	    hb_enable_if (hb_is_cr_convertible(U, Type))>
+  hb_sorted_array_t& operator = (const hb_array_t<U> &o)
+  { hb_array_t<Type> (*this) = o; return *this; }
+
+  /* Iterator implementation. */
+  bool operator != (const hb_sorted_array_t& o) const
+  { return this->arrayZ != o.arrayZ || this->length != o.length; }
+
   hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
   { return hb_sorted_array_t<Type> (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
   hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int seg_count) const
@@ -269,9 +319,30 @@
 hb_sorted_array (T (&array_)[length_])
 { return hb_sorted_array_t<T> (array_); }
 
+template <typename T>
+bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
+{
+  return length == o.length &&
+  + hb_zip (*this, o)
+  | hb_map ([] (hb_pair_t<T&, T&> &&_) { return _.first == _.second; })
+  | hb_all
+  ;
+}
+template <typename T>
+uint32_t hb_array_t<T>::hash () const
+{
+  return
+  + hb_iter (*this)
+  | hb_map (hb_hash)
+  | hb_reduce ([] (uint32_t a, uint32_t b) { return a * 31 + b; }, 0)
+  ;
+}
 
 typedef hb_array_t<const char> hb_bytes_t;
 typedef hb_array_t<const unsigned char> hb_ubytes_t;
 
+/* TODO Specialize opeator==/hash() for hb_bytes_t and hb_ubytes_t. */
+//template <>
+//uint32_t hb_array_t<const char>::hash () const { return 0; }
 
 #endif /* HB_ARRAY_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -33,6 +33,7 @@
 #define HB_ATOMIC_HH
 
 #include "hb.hh"
+#include "hb-meta.hh"
 
 
 /*
@@ -106,7 +107,7 @@
 
 static inline void _hb_memory_barrier ()
 {
-#if !defined(MemoryBarrier)
+#ifndef MemoryBarrier
   /* MinGW has a convoluted history of supporting MemoryBarrier. */
   LONG dummy = 0;
   InterlockedExchange (&dummy, 1);
@@ -282,7 +283,7 @@
 template <typename P>
 struct hb_atomic_ptr_t
 {
-  typedef typename hb_remove_pointer (P) T;
+  typedef hb_remove_pointer<P> T;
 
   void init (T* v_ = nullptr) { set_relaxed (v_); }
   void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -30,7 +30,7 @@
  * http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
  * https://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html
  */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) && !defined(_MSC_VER) && !defined(__NetBSD__)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-macros"
 #define _POSIX_C_SOURCE 200809L
@@ -155,7 +155,7 @@
   hb_blob_make_immutable (parent);
 
   blob = hb_blob_create (parent->data + offset,
-			 MIN (length, parent->length - offset),
+			 hb_min (length, parent->length - offset),
 			 HB_MEMORY_MODE_READONLY,
 			 hb_blob_reference (parent),
 			 _hb_blob_destroy);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.h	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.h	2019-05-24 23:03:55 UTC (rev 51218)
@@ -71,6 +71,9 @@
 		void              *user_data,
 		hb_destroy_func_t  destroy);
 
+HB_EXTERN hb_blob_t *
+hb_blob_create_from_file (const char *file_name);
+
 /* Always creates with MEMORY_MODE_READONLY.
  * Even if the parent blob is writable, we don't
  * want the user of the sub-blob to be able to
@@ -123,9 +126,6 @@
 HB_EXTERN char *
 hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
 
-HB_EXTERN hb_blob_t *
-hb_blob_create_from_file (const char *file_name);
-
 HB_END_DECLS
 
 #endif /* HB_BLOB_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -81,7 +81,7 @@
 template <typename P>
 struct hb_blob_ptr_t
 {
-  typedef typename hb_remove_pointer (P) T;
+  typedef hb_remove_pointer<P> T;
 
   hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {}
   hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -28,8 +28,10 @@
 
 
 static const char *serialize_formats[] = {
+#ifndef HB_NO_BUFFER_SERIALIZE
   "text",
   "json",
+#endif
   nullptr
 };
 
@@ -85,10 +87,12 @@
 const char *
 hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
 {
-  switch (format)
+  switch ((unsigned) format)
   {
+#ifndef HB_NO_BUFFER_SERIALIZE
     case HB_BUFFER_SERIALIZE_FORMAT_TEXT:	return serialize_formats[0];
     case HB_BUFFER_SERIALIZE_FORMAT_JSON:	return serialize_formats[1];
+#endif
     default:
     case HB_BUFFER_SERIALIZE_FORMAT_INVALID:	return nullptr;
   }
@@ -138,18 +142,18 @@
       *p++ = '"';
     }
     else
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
     }
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
     {
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
 			     x+pos[i].x_offset, y+pos[i].y_offset));
       if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
-	p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
+	p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
 			       pos[i].x_advance, pos[i].y_advance));
     }
 
@@ -156,7 +160,7 @@
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
     {
       if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
-	p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
+	p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
     }
 
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
@@ -163,9 +167,9 @@
     {
       hb_glyph_extents_t extents;
       hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
 		extents.x_bearing, extents.y_bearing));
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
 		extents.width, extents.height));
     }
 
@@ -224,23 +228,23 @@
       p += strlen (p);
     }
     else
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
     }
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
     {
       if (x+pos[i].x_offset || y+pos[i].y_offset)
-	p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
+	p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
 
       if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
       {
 	*p++ = '+';
-	p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
+	p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
 	if (pos[i].y_advance)
-	  p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
+	  p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
       }
     }
 
@@ -247,7 +251,7 @@
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
     {
       if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
-	p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
+	p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
     }
 
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
@@ -254,7 +258,7 @@
     {
       hb_glyph_extents_t extents;
       hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
     }
 
     unsigned int l = p - b;
@@ -344,6 +348,10 @@
   if (buf_size)
     *buf = '\0';
 
+#ifdef HB_NO_BUFFER_SERIALIZE
+  return 0;
+#endif
+
   assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
 	  buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
 
@@ -380,7 +388,7 @@
 parse_uint (const char *pp, const char *end, uint32_t *pv)
 {
   char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
+  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
   strncpy (buf, pp, len);
   buf[len] = '\0';
 
@@ -401,7 +409,7 @@
 parse_int (const char *pp, const char *end, int32_t *pv)
 {
   char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
+  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
   strncpy (buf, pp, len);
   buf[len] = '\0';
 
@@ -449,6 +457,10 @@
     end_ptr = &end;
   *end_ptr = buf;
 
+#ifdef HB_NO_BUFFER_SERIALIZE
+  return false;
+#endif
+
   assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
 	  buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -524,7 +524,7 @@
   unsigned int cluster = info[start].cluster;
 
   for (unsigned int i = start + 1; i < end; i++)
-    cluster = MIN<unsigned int> (cluster, info[i].cluster);
+    cluster = hb_min (cluster, info[i].cluster);
 
   /* Extend end */
   while (end < len && info[end - 1].cluster == info[end].cluster)
@@ -555,7 +555,7 @@
   unsigned int cluster = out_info[start].cluster;
 
   for (unsigned int i = start + 1; i < end; i++)
-    cluster = MIN<unsigned int> (cluster, out_info[i].cluster);
+    cluster = hb_min (cluster, out_info[i].cluster);
 
   /* Extend start */
   while (start && out_info[start - 1].cluster == out_info[start].cluster)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -379,7 +379,7 @@
 				     unsigned int cluster) const
   {
     for (unsigned int i = start; i < end; i++)
-      cluster = MIN<unsigned int> (cluster, infos[i].cluster);
+      cluster = hb_min (cluster, infos[i].cluster);
     return cluster;
   }
   void

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -272,11 +272,11 @@
 
     HBUINT8 *p = c->allocate_size<HBUINT8> (1);
     if (unlikely (p == nullptr)) return_trace (false);
-    p->set (intOp);
+    *p = intOp;
 
     INTTYPE *ip = c->allocate_size<INTTYPE> (INTTYPE::static_size);
     if (unlikely (ip == nullptr)) return_trace (false);
-    ip->set ((unsigned int)value);
+    *ip = (unsigned int) value;
 
     return_trace (true);
   }
@@ -691,7 +691,7 @@
 
       case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1:
       case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3:
-	env.argStack.push_int ((int16_t)(-(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108));
+	env.argStack.push_int ((-(int16_t)(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108));
 	env.str_ref.inc ();
 	break;
 

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -147,8 +147,9 @@
     return callStack.in_error () || SUPER::in_error ();
   }
 
-  bool popSubrNum (const biased_subrs_t<SUBRS>& biasedSubrs, unsigned int &subr_num)
+  bool pop_subr_num (const biased_subrs_t<SUBRS>& biasedSubrs, unsigned int &subr_num)
   {
+    subr_num = 0;
     int n = SUPER::argStack.pop_int ();
     n += biasedSubrs.get_bias ();
     if (unlikely ((n < 0) || ((unsigned int)n >= biasedSubrs.get_count ())))
@@ -158,11 +159,11 @@
     return true;
   }
 
-  void callSubr (const biased_subrs_t<SUBRS>& biasedSubrs, cs_type_t type)
+  void call_subr (const biased_subrs_t<SUBRS>& biasedSubrs, cs_type_t type)
   {
-    unsigned int subr_num;
+    unsigned int subr_num = 0;
 
-    if (unlikely (!popSubrNum (biasedSubrs, subr_num)
+    if (unlikely (!pop_subr_num (biasedSubrs, subr_num)
 		 || callStack.get_count () >= kMaxCallLimit))
     {
       SUPER::set_error ();
@@ -175,7 +176,7 @@
     SUPER::str_ref = context.str_ref;
   }
 
-  void returnFromSubr ()
+  void return_from_subr ()
   {
     if (unlikely (SUPER::str_ref.in_error ()))
       SUPER::set_error ();
@@ -246,7 +247,7 @@
   static void flex1 (ENV &env, PARAM& param) {}
 };
 
-template <typename ARG, typename OPSET, typename ENV, typename PARAM, typename PATH=path_procs_null_t<ENV, PARAM> >
+template <typename ARG, typename OPSET, typename ENV, typename PARAM, typename PATH=path_procs_null_t<ENV, PARAM>>
 struct cs_opset_t : opset_t<ARG>
 {
   static void process_op (op_code_t op, ENV &env, PARAM& param)
@@ -254,7 +255,7 @@
     switch (op) {
 
       case OpCode_return:
-	env.returnFromSubr ();
+	env.return_from_subr ();
 	break;
       case OpCode_endchar:
 	OPSET::check_width (op, env, param);
@@ -267,11 +268,11 @@
 	break;
 
       case OpCode_callsubr:
-	env.callSubr (env.localSubrs, CSType_LocalSubr);
+	env.call_subr (env.localSubrs, CSType_LocalSubr);
 	break;
 
       case OpCode_callgsubr:
-	env.callSubr (env.globalSubrs, CSType_GlobalSubr);
+	env.call_subr (env.globalSubrs, CSType_GlobalSubr);
 	break;
 
       case OpCode_hstem:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff1-interp-cs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff1-interp-cs.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff1-interp-cs.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -81,7 +81,7 @@
   typedef cs_interp_env_t<number_t, CFF1Subrs> SUPER;
 };
 
-template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff1_cs_interp_env_t, PARAM> >
+template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff1_cs_interp_env_t, PARAM>>
 struct cff1_cs_opset_t : cs_opset_t<number_t, OPSET, cff1_cs_interp_env_t, PARAM, PATH>
 {
   /* PostScript-originated legacy opcodes (OpCode_add etc) are unsupported */

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -193,7 +193,7 @@
 
   typedef cs_interp_env_t<blend_arg_t, CFF2Subrs> SUPER;
 };
-template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff2_cs_interp_env_t, PARAM> >
+template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff2_cs_interp_env_t, PARAM>>
 struct cff2_cs_opset_t : cs_opset_t<blend_arg_t, OPSET, cff2_cs_interp_env_t, PARAM, PATH>
 {
   static void process_op (op_code_t op, cff2_cs_interp_env_t &env, PARAM& param)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -67,7 +67,7 @@
         p = c + strlen (c);
 
 #define OPTION(name, symbol) \
-	if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) u.opts.symbol = true;
+	if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) do { u.opts.symbol = true; } while (0)
 
       OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
       OPTION ("aat", aat);
@@ -356,7 +356,7 @@
   {
     /* NUL-terminate it. */
     char strbuf[64];
-    len = MIN (len, (int) sizeof (strbuf) - 1);
+    len = hb_min (len, (int) sizeof (strbuf) - 1);
     memcpy (strbuf, str, len);
     strbuf[len] = '\0';
     item = lang_find_or_insert (strbuf);
@@ -488,7 +488,7 @@
 
 /**
  * hb_script_to_iso15924_tag:
- * @script: an #hb_script_ to convert.
+ * @script: an #hb_script_t to convert.
  *
  * See hb_script_from_iso15924_tag().
  *
@@ -720,7 +720,7 @@
 parse_uint (const char **pp, const char *end, unsigned int *pv)
 {
   char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
   strncpy (buf, *pp, len);
   buf[len] = '\0';
 
@@ -744,7 +744,7 @@
 parse_uint32 (const char **pp, const char *end, uint32_t *pv)
 {
   char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
   strncpy (buf, *pp, len);
   buf[len] = '\0';
 
@@ -783,7 +783,7 @@
 static void free_static_C_locale ();
 #endif
 
-static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (HB_LOCALE_T),
+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 ()
@@ -825,7 +825,7 @@
 parse_float (const char **pp, const char *end, float *pv)
 {
   char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
   strncpy (buf, *pp, len);
   buf[len] = '\0';
 
@@ -1071,11 +1071,11 @@
   {
     s[len++] = '[';
     if (feature->start)
-      len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
+      len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
     if (feature->end != feature->start + 1) {
       s[len++] = ':';
       if (feature->end != (unsigned int) -1)
-	len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
+	len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
     }
     s[len++] = ']';
   }
@@ -1082,10 +1082,10 @@
   if (feature->value > 1)
   {
     s[len++] = '=';
-    len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
+    len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
   }
   assert (len < ARRAY_LENGTH (s));
-  len = MIN (len, size - 1);
+  len = hb_min (len, size - 1);
   memcpy (buf, s, len);
   buf[len] = '\0';
 }
@@ -1152,14 +1152,71 @@
   while (len && s[len - 1] == ' ')
     len--;
   s[len++] = '=';
-  len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
+  len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
 
   assert (len < ARRAY_LENGTH (s));
-  len = MIN (len, size - 1);
+  len = hb_min (len, size - 1);
   memcpy (buf, s, len);
   buf[len] = '\0';
 }
 
+/**
+ * hb_color_get_alpha:
+ * color: a #hb_color_t we are interested in its channels.
+ *
+ * Return value: Alpha channel value of the given color
+ *
+ * Since: 2.1.0
+ */
+uint8_t
+(hb_color_get_alpha) (hb_color_t color)
+{
+  return hb_color_get_alpha (color);
+}
+
+/**
+ * hb_color_get_red:
+ * color: a #hb_color_t we are interested in its channels.
+ *
+ * Return value: Red channel value of the given color
+ *
+ * Since: 2.1.0
+ */
+uint8_t
+(hb_color_get_red) (hb_color_t color)
+{
+  return hb_color_get_red (color);
+}
+
+/**
+ * hb_color_get_green:
+ * color: a #hb_color_t we are interested in its channels.
+ *
+ * Return value: Green channel value of the given color
+ *
+ * Since: 2.1.0
+ */
+uint8_t
+(hb_color_get_green) (hb_color_t color)
+{
+  return hb_color_get_green (color);
+}
+
+/**
+ * hb_color_get_blue:
+ * color: a #hb_color_t we are interested in its channels.
+ *
+ * Return value: Blue channel value of the given color
+ *
+ * Since: 2.1.0
+ */
+uint8_t
+(hb_color_get_blue) (hb_color_t color)
+{
+  return hb_color_get_blue (color);
+}
+
+
 /* If there is no visibility control, then hb-static.cc will NOT
  * define anything.  Instead, we get it to define one set in here
  * only, so only libharfbuzz.so defines them, not other libs. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2019-05-24 23:03:55 UTC (rev 51218)
@@ -358,7 +358,7 @@
   /*11.0*/HB_SCRIPT_SOGDIAN			= HB_TAG ('S','o','g','d'),
 
   /*
-   * Since REPLACEME
+   * Since 2.4.0
    */
   /*12.0*/HB_SCRIPT_ELYMAIC			= HB_TAG ('E','l','y','m'),
   /*12.0*/HB_SCRIPT_NANDINAGARI			= HB_TAG ('N','a','n','d'),
@@ -467,40 +467,22 @@
 
 #define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a)))
 
-/**
- * hb_color_get_alpha:
- *
- *
- *
- * Since: 2.1.0
- */
+HB_EXTERN uint8_t
+hb_color_get_alpha (hb_color_t color);
 #define hb_color_get_alpha(color)	((color) & 0xFF)
-/**
- * hb_color_get_red:
- *
- *
- *
- * Since: 2.1.0
- */
+
+HB_EXTERN uint8_t
+hb_color_get_red (hb_color_t color);
 #define hb_color_get_red(color)		(((color) >> 8) & 0xFF)
-/**
- * hb_color_get_green:
- *
- *
- *
- * Since: 2.1.0
- */
+
+HB_EXTERN uint8_t
+hb_color_get_green (hb_color_t color);
 #define hb_color_get_green(color)	(((color) >> 16) & 0xFF)
-/**
- * hb_color_get_blue:
- *
- *
- *
- * Since: 2.1.0
- */
+
+HB_EXTERN uint8_t
+hb_color_get_blue (hb_color_t color);
 #define hb_color_get_blue(color)	(((color) >> 24) & 0xFF)
 
-
 HB_END_DECLS
 
 #endif /* HB_COMMON_H */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2019  Facebook, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_CONFIG_HH
+#define HB_CONFIG_HH
+
+#if 0 /* Make test happy. */
+#include "hb.hh"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HB_TINY
+#define HB_LEAN
+#define HB_MINI
+#define HB_NO_MT
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+#ifndef __OPTIMIZE_SIZE__
+#define __OPTIMIZE_SIZE__
+#endif
+#endif
+
+#ifdef HB_LEAN
+#define HB_DISABLE_DEPRECATED
+#define HB_NDEBUG
+#define HB_NO_ATEXIT
+#define HB_NO_BUFFER_SERIALIZE
+#define HB_NO_BITMAP
+#define HB_NO_CFF
+#define HB_NO_COLOR
+#define HB_NO_GETENV
+#define HB_NO_LAYOUT_UNUSED
+#define HB_NO_MATH
+#define HB_NO_NAME
+#define HB_NO_SUBSET_LAYOUT
+#endif
+
+#ifdef HB_MINI
+#define HB_NO_AAT
+#define HB_NO_LEGACY
+#endif
+
+/* Closure. */
+
+#ifdef HB_DISABLE_DEPRECATED
+#define HB_IF_NOT_DEPRECATED(x)
+#else
+#define HB_IF_NOT_DEPRECATED(x) x
+#endif
+
+#ifdef HB_NO_AAT
+#define HB_NO_OT_NAME_LANGUAGE_AAT
+#define HB_NO_SHAPE_AAT
+#endif
+
+#ifdef HB_NO_BITMAP
+#define HB_NO_OT_FONT_BITMAP
+#endif
+
+#ifdef HB_NO_CFF
+#define HB_NO_OT_FONT_CFF
+#define HB_NO_SUBSET_CFF
+#endif
+
+#ifdef HB_NO_GETENV
+#define HB_NO_UNISCRIBE_BUG_COMPATIBLE
+#endif
+
+#ifdef HB_NO_LEGACY
+#define HB_NO_OT_LAYOUT_BLACKLIST
+#define HB_NO_OT_SHAPE_FALLBACK
+#endif
+
+#ifdef HB_NO_NAME
+#define HB_NO_OT_NAME_LANGUAGE
+#endif
+
+#ifdef HB_NO_OT_SHAPE_FALLBACK
+#define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
+#define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
+#define HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
+#define HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
+#endif
+
+#ifdef NDEBUG
+#ifndef HB_NDEBUG
+#define HB_NDEBUG
+#endif
+#endif
+
+#ifdef __OPTIMIZE_SIZE__
+#ifndef HB_OPTIMIZE_SIZE
+#define HB_OPTIMIZE_SIZE
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_OVERRIDE_H
+#include "config-override.h"
+#endif
+
+
+#endif /* HB_CONFIG_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -55,13 +55,13 @@
    * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
    */
   ptem *= 96.f / 72.f;
-  return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem;
+  return (CGFloat) (ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem);
 }
 static float
 coretext_font_size_to_ptem (CGFloat size)
 {
-  size *= 72.f / 96.f;
-  return size <= 0.f ? 0 : size;
+  size *= 72. / 96.;
+  return size <= 0 ? 0 : size;
 }
 
 static void
@@ -410,7 +410,7 @@
   feature_record_t rec;
   unsigned int order;
 
-  static int cmp (const void *pa, const void *pb) {
+  HB_INTERNAL static int cmp (const void *pa, const void *pb) {
     const active_feature_t *a = (const active_feature_t *) pa;
     const active_feature_t *b = (const active_feature_t *) pb;
     return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
@@ -428,7 +428,7 @@
   bool start;
   active_feature_t feature;
 
-  static int cmp (const void *pa, const void *pb) {
+  HB_INTERNAL static int cmp (const void *pa, const void *pb) {
     const feature_event_t *a = (const feature_event_t *) pa;
     const feature_event_t *b = (const feature_event_t *) pb;
     return a->index < b->index ? -1 : a->index > b->index ? 1 :
@@ -598,7 +598,7 @@
       } else {
         active_feature_t *feature = active_features.find (&event->feature);
 	if (feature)
-	  active_features.remove (feature - active_features.arrayZ ());
+	  active_features.remove (feature - active_features.arrayZ);
       }
     }
   }
@@ -608,7 +608,7 @@
 
 #define ALLOCATE_ARRAY(Type, name, len, on_no_room) \
   Type *name = (Type *) scratch; \
-  { \
+  do { \
     unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
     if (unlikely (_consumed > scratch_size)) \
     { \
@@ -617,7 +617,7 @@
     } \
     scratch += _consumed; \
     scratch_size -= _consumed; \
-  }
+  } while (0)
 
   ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/);
   unsigned int chars_len = 0;
@@ -771,7 +771,7 @@
 	      feature.start < chars_len && feature.start < feature.end)
 	  {
 	    CFRange feature_range = CFRangeMake (feature.start,
-	                                         MIN (feature.end, chars_len) - feature.start);
+	                                         hb_min (feature.end, chars_len) - feature.start);
 	    if (feature.value)
 	      CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName);
 	    else
@@ -1069,7 +1069,7 @@
     if (false)
     {
       /* Make sure all runs had the expected direction. */
-      bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+      HB_UNUSED bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
       assert (bool (status_and & kCTRunStatusRightToLeft) == backward);
       assert (bool (status_or  & kCTRunStatusRightToLeft) == backward);
     }
@@ -1116,7 +1116,7 @@
 	unsigned int cluster = info[count - 1].cluster;
 	for (unsigned int i = count - 1; i > 0; i--)
 	{
-	  cluster = MIN (cluster, info[i - 1].cluster);
+	  cluster = hb_min (cluster, info[i - 1].cluster);
 	  info[i - 1].cluster = cluster;
 	}
       }
@@ -1125,7 +1125,7 @@
 	unsigned int cluster = info[0].cluster;
 	for (unsigned int i = 1; i < count; i++)
 	{
-	  cluster = MIN (cluster, info[i].cluster);
+	  cluster = hb_min (cluster, info[i].cluster);
 	  info[i].cluster = cluster;
 	}
       }
@@ -1148,59 +1148,3 @@
 
   return ret;
 }
-
-
-/*
- * AAT shaper
- */
-
-/*
- * shaper face data
- */
-
-struct hb_coretext_aat_face_data_t {};
-
-hb_coretext_aat_face_data_t *
-_hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
-{
-  return hb_aat_layout_has_substitution (face) || hb_aat_layout_has_positioning (face) ?
-	 (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
-}
-
-void
-_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_face_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
- * shaper font data
- */
-
-struct hb_coretext_aat_font_data_t {};
-
-hb_coretext_aat_font_data_t *
-_hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
-{
-  return font->data.coretext ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
-}
-
-void
-_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_font_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
- * shaper
- */
-
-hb_bool_t
-_hb_coretext_aat_shape (hb_shape_plan_t    *shape_plan,
-			hb_font_t          *font,
-			hb_buffer_t        *buffer,
-			const hb_feature_t *features,
-			unsigned int        num_features)
-{
-  return _hb_coretext_shape (shape_plan, font, buffer, features, num_features);
-}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -29,7 +29,7 @@
 
 #include "hb.hh"
 #include "hb-atomic.hh"
-#include "hb-dsalgs.hh"
+#include "hb-algs.hh"
 
 
 #ifndef HB_DEBUG
@@ -63,6 +63,9 @@
 static inline hb_options_t
 hb_options ()
 {
+#ifdef HB_NO_GETENV
+  return hb_options_t ();
+#endif
   /* Make a local copy, so we can access bitfield threadsafely. */
   hb_options_union_t u;
   u.i = _hb_options.get_relaxed ();
@@ -158,7 +161,7 @@
       VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
     fprintf (stderr, "%2u %s" VRBAR "%s",
 	     level,
-	     bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
+	     bars + sizeof (bars) - 1 - hb_min ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
 	     level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
   } else
     fprintf (stderr, "   " VRBAR LBAR);
@@ -246,8 +249,8 @@
 };
 
 template <>
-struct hb_printer_t<hb_void_t> {
-  const char *print (hb_void_t) { return ""; }
+struct hb_printer_t<hb_empty_t> {
+  const char *print (hb_empty_t) { return ""; }
 };
 
 
@@ -263,7 +266,7 @@
   }
 }
 template <>
-/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
+/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED)
 {}
 
 template <int max_level, typename ret_t>
@@ -327,9 +330,10 @@
 				   const char *message,
 				   ...) HB_PRINTF_FUNC(6, 7) {}
 
-  ret_t ret (ret_t v,
-	     const char *func HB_UNUSED = nullptr,
-	     unsigned int line HB_UNUSED = 0) { return v; }
+  template <typename T>
+  T ret (T&& v,
+	 const char *func HB_UNUSED = nullptr,
+	 unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); }
 };
 
 /* For disabled tracing; optimize out everything.
@@ -336,9 +340,10 @@
  * https://github.com/harfbuzz/harfbuzz/pull/605 */
 template <typename ret_t>
 struct hb_no_trace_t {
-  ret_t ret (ret_t v,
-	     const char *func HB_UNUSED = "",
-	     unsigned int line HB_UNUSED = 0) { return v; }
+  template <typename T>
+  T ret (T&& v,
+	 const char *func HB_UNUSED = nullptr,
+	 unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); }
 };
 
 #define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__)
@@ -437,25 +442,12 @@
 #define TRACE_SUBSET(this) hb_no_trace_t<bool> trace
 #endif
 
-#ifndef HB_DEBUG_WOULD_APPLY
-#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
-#endif
-#if HB_DEBUG_WOULD_APPLY
-#define TRACE_WOULD_APPLY(this) \
-	hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
-	(&c->debug_depth, c->get_name (), this, HB_FUNC, \
-	 "%d glyphs", c->len);
-#else
-#define TRACE_WOULD_APPLY(this) hb_no_trace_t<bool> trace
-#endif
-
 #ifndef HB_DEBUG_DISPATCH
 #define HB_DEBUG_DISPATCH ( \
 	HB_DEBUG_APPLY + \
 	HB_DEBUG_SANITIZE + \
 	HB_DEBUG_SERIALIZE + \
-  HB_DEBUG_SUBSET + \
-	HB_DEBUG_WOULD_APPLY + \
+	HB_DEBUG_SUBSET + \
 	0)
 #endif
 #if HB_DEBUG_DISPATCH

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h	2019-05-24 23:03:55 UTC (rev 51218)
@@ -63,7 +63,7 @@
 					       hb_codepoint_t *glyph,
 					       void *user_data);
 
-HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func or hb_font_funcs_set_variation_glyph_func) void
+HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func and hb_font_funcs_set_variation_glyph_func) void
 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
 			      hb_font_get_glyph_func_t func,
 			      void *user_data, hb_destroy_func_t destroy);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -530,12 +530,12 @@
   hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
 #define ALLOCATE_ARRAY(Type, name, len) \
   Type *name = (Type *) scratch; \
-  { \
+  do { \
     unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
     assert (_consumed <= scratch_size); \
     scratch += _consumed; \
     scratch_size -= _consumed; \
-  }
+  } while (0)
 
 #define utf16_index() var1.u32
 
@@ -778,7 +778,7 @@
   {
     uint32_t *p =
       &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]];
-    *p = MIN (*p, buffer->info[i].cluster);
+    *p = hb_min (*p, buffer->info[i].cluster);
   }
   for (unsigned int i = 1; i < glyphCount; i++)
     if (vis_clusters[i] == (uint32_t) -1)
@@ -846,10 +846,23 @@
 				     features, num_features, 0);
 }
 
-/*
- * Public [experimental] API
- */
-
+/**
+ * hb_directwrite_shape_experimental_width:
+ * Experimental API to test DirectWrite's justification algorithm.
+ *
+ * It inserts Kashida at wrong order so don't use the API ever.
+ *
+ * It doesn't work with cygwin/msys due to header bugs so one
+ * should use MSVC toolchain in order to use it for now.
+ *
+ * @font:
+ * @buffer:
+ * @features:
+ * @num_features:
+ * @width:
+ *
+ * Since: 1.4.2
+ **/
 hb_bool_t
 hb_directwrite_shape_experimental_width (hb_font_t          *font,
 					 hb_buffer_t        *buffer,
@@ -917,8 +930,11 @@
 
 /**
  * hb_directwrite_face_create:
- * @font_face:
- * Since: REPLACEME
+ * @font_face: a DirectWrite IDWriteFontFace object.
+ *
+ * Return value: #hb_face_t object corresponding to the given input
+ *
+ * Since: 2.4.0
  **/
 hb_face_t *
 hb_directwrite_face_create (IDWriteFontFace *font_face)
@@ -928,3 +944,17 @@
   return hb_face_create_for_tables (reference_table, font_face,
 				    _hb_directwrite_font_release);
 }
+
+/**
+* hb_directwrite_face_get_font_face:
+* @face: a #hb_face_t object
+*
+* Return value: DirectWrite IDWriteFontFace object corresponding to the given input
+*
+* Since: REPLACEME
+**/
+IDWriteFontFace *
+hb_directwrite_face_get_font_face (hb_face_t *face)
+{
+  return face->data.directwrite->fontFace;
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.h	2019-05-24 23:03:55 UTC (rev 51218)
@@ -37,6 +37,9 @@
 HB_EXTERN hb_face_t *
 hb_directwrite_face_create (IDWriteFontFace *font_face);
 
+HB_EXTERN IDWriteFontFace *
+hb_directwrite_face_get_font_face (hb_face_t *face);
+
 HB_END_DECLS
 
 #endif /* HB_DIRECTWRITE_H */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dispatch.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dispatch.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dispatch.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2012,2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_DISPATCH_HH
+#define HB_DISPATCH_HH
+
+#include "hb.hh"
+
+/*
+ * Dispatch
+ */
+
+template <typename Context, typename Return, unsigned int MaxDebugDepth>
+struct hb_dispatch_context_t
+{
+  private:
+  /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
+  const Context* thiz () const { return static_cast<const Context *> (this); }
+        Context* thiz ()       { return static_cast<      Context *> (this); }
+  public:
+  static constexpr unsigned max_debug_depth = MaxDebugDepth;
+  typedef Return return_t;
+  template <typename T, typename F>
+  bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; }
+  template <typename T, typename ...Ts>
+  return_t dispatch (const T &obj, Ts&&... ds)
+  { return obj.dispatch (thiz (), hb_forward<Ts> (ds)...); }
+  static return_t no_dispatch_return_value () { return Context::default_return_value (); }
+  static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; }
+};
+
+
+#endif /* HB_DISPATCH_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,627 +0,0 @@
-/*
- * Copyright © 2017  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_DSALGS_HH
-#define HB_DSALGS_HH
-
-#include "hb.hh"
-#include "hb-null.hh"
-
-
-/* Void! For when we need a expression-type of void. */
-typedef const struct _hb_void_t *hb_void_t;
-#define HB_VOID ((const _hb_void_t *) nullptr)
-
-
-/*
- * Bithacks.
- */
-
-/* Return the number of 1 bits in v. */
-template <typename T>
-static inline HB_CONST_FUNC unsigned int
-hb_popcount (T v)
-{
-#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
-  if (sizeof (T) <= sizeof (unsigned int))
-    return __builtin_popcount (v);
-
-  if (sizeof (T) <= sizeof (unsigned long))
-    return __builtin_popcountl (v);
-
-  if (sizeof (T) <= sizeof (unsigned long long))
-    return __builtin_popcountll (v);
-#endif
-
-  if (sizeof (T) <= 4)
-  {
-    /* "HACKMEM 169" */
-    uint32_t y;
-    y = (v >> 1) &033333333333;
-    y = v - y - ((y >>1) & 033333333333);
-    return (((y + (y >> 3)) & 030707070707) % 077);
-  }
-
-  if (sizeof (T) == 8)
-  {
-    unsigned int shift = 32;
-    return hb_popcount<uint32_t> ((uint32_t) v) + hb_popcount ((uint32_t) (v >> shift));
-  }
-
-  if (sizeof (T) == 16)
-  {
-    unsigned int shift = 64;
-    return hb_popcount<uint64_t> ((uint64_t) v) + hb_popcount ((uint64_t) (v >> shift));
-  }
-
-  assert (0);
-  return 0; /* Shut up stupid compiler. */
-}
-
-/* Returns the number of bits needed to store number */
-template <typename T>
-static inline HB_CONST_FUNC unsigned int
-hb_bit_storage (T v)
-{
-  if (unlikely (!v)) return 0;
-
-#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
-  if (sizeof (T) <= sizeof (unsigned int))
-    return sizeof (unsigned int) * 8 - __builtin_clz (v);
-
-  if (sizeof (T) <= sizeof (unsigned long))
-    return sizeof (unsigned long) * 8 - __builtin_clzl (v);
-
-  if (sizeof (T) <= sizeof (unsigned long long))
-    return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
-#endif
-
-#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
-  if (sizeof (T) <= sizeof (unsigned int))
-  {
-    unsigned long where;
-    _BitScanReverse (&where, v);
-    return 1 + where;
-  }
-# if defined(_WIN64)
-  if (sizeof (T) <= 8)
-  {
-    unsigned long where;
-    _BitScanReverse64 (&where, v);
-    return 1 + where;
-  }
-# endif
-#endif
-
-  if (sizeof (T) <= 4)
-  {
-    /* "bithacks" */
-    const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
-    const unsigned int S[] = {1, 2, 4, 8, 16};
-    unsigned int r = 0;
-    for (int i = 4; i >= 0; i--)
-      if (v & b[i])
-      {
-	v >>= S[i];
-	r |= S[i];
-      }
-    return r + 1;
-  }
-  if (sizeof (T) <= 8)
-  {
-    /* "bithacks" */
-    const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
-    const unsigned int S[] = {1, 2, 4, 8, 16, 32};
-    unsigned int r = 0;
-    for (int i = 5; i >= 0; i--)
-      if (v & b[i])
-      {
-	v >>= S[i];
-	r |= S[i];
-      }
-    return r + 1;
-  }
-  if (sizeof (T) == 16)
-  {
-    unsigned int shift = 64;
-    return (v >> shift) ? hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
-			  hb_bit_storage<uint64_t> ((uint64_t) v);
-  }
-
-  assert (0);
-  return 0; /* Shut up stupid compiler. */
-}
-
-/* Returns the number of zero bits in the least significant side of v */
-template <typename T>
-static inline HB_CONST_FUNC unsigned int
-hb_ctz (T v)
-{
-  if (unlikely (!v)) return 0;
-
-#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
-  if (sizeof (T) <= sizeof (unsigned int))
-    return __builtin_ctz (v);
-
-  if (sizeof (T) <= sizeof (unsigned long))
-    return __builtin_ctzl (v);
-
-  if (sizeof (T) <= sizeof (unsigned long long))
-    return __builtin_ctzll (v);
-#endif
-
-#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
-  if (sizeof (T) <= sizeof (unsigned int))
-  {
-    unsigned long where;
-    _BitScanForward (&where, v);
-    return where;
-  }
-# if defined(_WIN64)
-  if (sizeof (T) <= 8)
-  {
-    unsigned long where;
-    _BitScanForward64 (&where, v);
-    return where;
-  }
-# endif
-#endif
-
-  if (sizeof (T) <= 4)
-  {
-    /* "bithacks" */
-    unsigned int c = 32;
-    v &= - (int32_t) v;
-    if (v) c--;
-    if (v & 0x0000FFFF) c -= 16;
-    if (v & 0x00FF00FF) c -= 8;
-    if (v & 0x0F0F0F0F) c -= 4;
-    if (v & 0x33333333) c -= 2;
-    if (v & 0x55555555) c -= 1;
-    return c;
-  }
-  if (sizeof (T) <= 8)
-  {
-    /* "bithacks" */
-    unsigned int c = 64;
-    v &= - (int64_t) (v);
-    if (v) c--;
-    if (v & 0x00000000FFFFFFFFULL) c -= 32;
-    if (v & 0x0000FFFF0000FFFFULL) c -= 16;
-    if (v & 0x00FF00FF00FF00FFULL) c -= 8;
-    if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4;
-    if (v & 0x3333333333333333ULL) c -= 2;
-    if (v & 0x5555555555555555ULL) c -= 1;
-    return c;
-  }
-  if (sizeof (T) == 16)
-  {
-    unsigned int shift = 64;
-    return (uint64_t) v ? hb_bit_storage<uint64_t> ((uint64_t) v) :
-			  hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift;
-  }
-
-  assert (0);
-  return 0; /* Shut up stupid compiler. */
-}
-
-
-/*
- * Tiny stuff.
- */
-
-template <typename T>
-static inline T* hb_addressof (T& arg)
-{
-#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
-}
-
-/* ASCII tag/character handling */
-static inline bool ISALPHA (unsigned char c)
-{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
-static inline bool ISALNUM (unsigned char c)
-{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
-static inline bool ISSPACE (unsigned char c)
-{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
-static inline unsigned char TOUPPER (unsigned char c)
-{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
-static inline unsigned char TOLOWER (unsigned char c)
-{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
-
-#undef MIN
-template <typename Type>
-static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
-
-#undef MAX
-template <typename Type>
-static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
-
-static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
-{ return (a + (b - 1)) / b; }
-
-
-#undef  ARRAY_LENGTH
-template <typename Type, unsigned int n>
-static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
-/* A const version, but does not detect erratically being called on pointers. */
-#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
-
-
-static inline int
-hb_memcmp (const void *a, const void *b, unsigned int len)
-{
-  /* It's illegal to pass NULL to memcmp(), even if len is zero.
-   * So, wrap it.
-   * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
-  if (!len) return 0;
-  return memcmp (a, b, len);
-}
-
-static inline bool
-hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
-{
-  return (size > 0) && (count >= ((unsigned int) -1) / size);
-}
-
-static inline unsigned int
-hb_ceil_to_4 (unsigned int v)
-{
-  return ((v - 1) | 3) + 1;
-}
-
-template <typename T> struct hb_is_signed;
-/* https://github.com/harfbuzz/harfbuzz/issues/1535 */
-template <> struct hb_is_signed<int8_t> { enum { value = true }; };
-template <> struct hb_is_signed<int16_t> { enum { value = true }; };
-template <> struct hb_is_signed<int32_t> { enum { value = true }; };
-template <> struct hb_is_signed<int64_t> { enum { value = true }; };
-template <> struct hb_is_signed<uint8_t> { enum { value = false }; };
-template <> struct hb_is_signed<uint16_t> { enum { value = false }; };
-template <> struct hb_is_signed<uint32_t> { enum { value = false }; };
-template <> struct hb_is_signed<uint64_t> { enum { value = false }; };
-
-template <typename T> static inline bool
-hb_in_range (T u, T lo, T hi)
-{
-  static_assert (!hb_is_signed<T>::value, "");
-
-  /* The casts below are important as if T is smaller than int,
-   * the subtract results will become a signed int! */
-  return (T)(u - lo) <= (T)(hi - lo);
-}
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
-{
-  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
-}
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
-{
-  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
-}
-
-
-/*
- * Sort and search.
- */
-
-static inline void *
-hb_bsearch (const void *key, const void *base,
-	    size_t nmemb, size_t size,
-	    int (*compar)(const void *_key, const void *_item))
-{
-  int min = 0, max = (int) nmemb - 1;
-  while (min <= max)
-  {
-    int mid = (min + max) / 2;
-    const void *p = (const void *) (((const char *) base) + (mid * size));
-    int c = compar (key, p);
-    if (c < 0)
-      max = mid - 1;
-    else if (c > 0)
-      min = mid + 1;
-    else
-      return (void *) p;
-  }
-  return nullptr;
-}
-
-static inline void *
-hb_bsearch_r (const void *key, const void *base,
-	      size_t nmemb, size_t size,
-	      int (*compar)(const void *_key, const void *_item, void *_arg),
-	      void *arg)
-{
-  int min = 0, max = (int) nmemb - 1;
-  while (min <= max)
-  {
-    int mid = ((unsigned int) min + (unsigned int) max) / 2;
-    const void *p = (const void *) (((const char *) base) + (mid * size));
-    int c = compar (key, p, arg);
-    if (c < 0)
-      max = mid - 1;
-    else if (c > 0)
-      min = mid + 1;
-    else
-      return (void *) p;
-  }
-  return nullptr;
-}
-
-
-/* From https://github.com/noporpoise/sort_r
- * With following modifications:
- *
- * 10 November 2018:
- * https://github.com/noporpoise/sort_r/issues/7
- */
-
-/* Isaac Turner 29 April 2014 Public Domain */
-
-/*
-
-hb_sort_r function to be exported.
-
-Parameters:
-  base is the array to be sorted
-  nel is the number of elements in the array
-  width is the size in bytes of each element of the array
-  compar is the comparison function
-  arg is a pointer to be passed to the comparison function
-
-void hb_sort_r(void *base, size_t nel, size_t width,
-               int (*compar)(const void *_a, const void *_b, void *_arg),
-               void *arg);
-*/
-
-
-/* swap a, b iff a>b */
-/* __restrict is same as restrict but better support on old machines */
-static int sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w,
-			  int (*compar)(const void *_a, const void *_b,
-					void *_arg),
-			  void *arg)
-{
-  char tmp, *end = a+w;
-  if(compar(a, b, arg) > 0) {
-    for(; a < end; a++, b++) { tmp = *a; *a = *b; *b = tmp; }
-    return 1;
-  }
-  return 0;
-}
-
-/* Note: quicksort is not stable, equivalent values may be swapped */
-static inline void sort_r_simple(void *base, size_t nel, size_t w,
-				 int (*compar)(const void *_a, const void *_b,
-					       void *_arg),
-				 void *arg)
-{
-  char *b = (char *)base, *end = b + nel*w;
-  if(nel < 7) {
-    /* Insertion sort for arbitrarily small inputs */
-    char *pi, *pj;
-    for(pi = b+w; pi < end; pi += w) {
-      for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {}
-    }
-  }
-  else
-  {
-    /* nel > 6; Quicksort */
-
-    /* Use median of first, middle and last items as pivot */
-    char *x, *y, *xend, ch;
-    char *pl, *pm, *pr;
-    char *last = b+w*(nel-1), *tmp;
-    char *l[3];
-    l[0] = b;
-    l[1] = b+w*(nel/2);
-    l[2] = last;
-
-    if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
-    if(compar(l[1],l[2],arg) > 0) {
-      tmp=l[1]; l[1]=l[2]; l[2]=tmp; /* swap(l[1],l[2]) */
-      if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
-    }
-
-    /* swap l[id], l[2] to put pivot as last element */
-    for(x = l[1], y = last, xend = x+w; x<xend; x++, y++) {
-      ch = *x; *x = *y; *y = ch;
-    }
-
-    pl = b;
-    pr = last;
-
-    while(pl < pr) {
-      pm = pl+((pr-pl+1)>>1);
-      for(; pl < pm; pl += w) {
-        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
-          pr -= w; /* pivot now at pl */
-          break;
-        }
-      }
-      pm = pl+((pr-pl)>>1);
-      for(; pm < pr; pr -= w) {
-        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
-          pl += w; /* pivot now at pr */
-          break;
-        }
-      }
-    }
-
-    sort_r_simple(b, (pl-b)/w, w, compar, arg);
-    sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg);
-  }
-}
-
-static inline void hb_sort_r(void *base, size_t nel, size_t width,
-			     int (*compar)(const void *_a, const void *_b, void *_arg),
-			     void *arg)
-{
-    sort_r_simple(base, nel, width, compar, arg);
-}
-
-
-template <typename T, typename T2> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
-{
-  for (unsigned int i = 1; i < len; i++)
-  {
-    unsigned int j = i;
-    while (j && compar (&array[j - 1], &array[i]) > 0)
-      j--;
-    if (i == j)
-      continue;
-    /* Move item i to occupy place for item j, shift what's in between. */
-    {
-      T t = array[i];
-      memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
-      array[j] = t;
-    }
-    if (array2)
-    {
-      T2 t = array2[i];
-      memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2));
-      array2[j] = t;
-    }
-  }
-}
-
-template <typename T> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
-{
-  hb_stable_sort (array, len, compar, (int *) nullptr);
-}
-
-static inline hb_bool_t
-hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
-{
-  /* Pain because we don't know whether s is nul-terminated. */
-  char buf[64];
-  len = MIN (ARRAY_LENGTH (buf) - 1, len);
-  strncpy (buf, s, len);
-  buf[len] = '\0';
-
-  char *end;
-  errno = 0;
-  unsigned long v = strtoul (buf, &end, base);
-  if (errno) return false;
-  if (*end) return false;
-  *out = v;
-  return true;
-}
-
-
-struct HbOpOr
-{
-  static constexpr bool passthru_left = true;
-  static constexpr bool passthru_right = true;
-  template <typename T> static void process (T &o, const T &a, const T &b) { o = a | b; }
-};
-struct HbOpAnd
-{
-  static constexpr bool passthru_left = false;
-  static constexpr bool passthru_right = false;
-  template <typename T> static void process (T &o, const T &a, const T &b) { o = a & b; }
-};
-struct HbOpMinus
-{
-  static constexpr bool passthru_left = true;
-  static constexpr bool passthru_right = false;
-  template <typename T> static void process (T &o, const T &a, const T &b) { o = a & ~b; }
-};
-struct HbOpXor
-{
-  static constexpr bool passthru_left = true;
-  static constexpr bool passthru_right = true;
-  template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; }
-};
-
-
-/* Compiler-assisted vectorization. */
-
-/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
- * using vectorized operations if HB_VECTOR_SIZE is set to **bit** numbers (eg 128).
- * Define that to 0 to disable. */
-template <typename elt_t, unsigned int byte_size>
-struct hb_vector_size_t
-{
-  elt_t& operator [] (unsigned int i) { return u.v[i]; }
-  const elt_t& operator [] (unsigned int i) const { return u.v[i]; }
-
-  void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); }
-
-  template <class Op>
-  hb_vector_size_t process (const hb_vector_size_t &o) const
-  {
-    hb_vector_size_t r;
-#if HB_VECTOR_SIZE
-    if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
-      for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
-	Op::process (r.u.vec[i], u.vec[i], o.u.vec[i]);
-    else
-#endif
-      for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
-	Op::process (r.u.v[i], u.v[i], o.u.v[i]);
-    return r;
-  }
-  hb_vector_size_t operator | (const hb_vector_size_t &o) const
-  { return process<HbOpOr> (o); }
-  hb_vector_size_t operator & (const hb_vector_size_t &o) const
-  { return process<HbOpAnd> (o); }
-  hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
-  { return process<HbOpXor> (o); }
-  hb_vector_size_t operator ~ () const
-  {
-    hb_vector_size_t r;
-#if HB_VECTOR_SIZE && 0
-    if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
-      for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
-	r.u.vec[i] = ~u.vec[i];
-    else
-#endif
-    for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
-      r.u.v[i] = ~u.v[i];
-    return r;
-  }
-
-  private:
-  static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
-  union {
-    elt_t v[byte_size / sizeof (elt_t)];
-#if HB_VECTOR_SIZE
-    hb_vector_size_impl_t vec[byte_size / sizeof (hb_vector_size_impl_t)];
-#endif
-  } u;
-};
-
-
-#endif /* HB_DSALGS_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -336,6 +336,7 @@
   return ret;
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 static hb_position_t
 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
@@ -373,6 +374,7 @@
 {
   return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
 }
+#endif
 
 static hb_bool_t
 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
@@ -925,6 +927,7 @@
   return font->get_glyph_v_origin (glyph, x, y);
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_font_get_glyph_h_kerning:
  * @font: a font.
@@ -964,6 +967,7 @@
 {
   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
 }
+#endif
 
 /**
  * hb_font_get_glyph_extents:
@@ -1173,6 +1177,7 @@
   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_font_get_glyph_kerning_for_direction:
  * @font: a font.
@@ -1195,6 +1200,7 @@
 {
   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
 }
+#endif
 
 /**
  * hb_font_get_glyph_extents_for_origin:
@@ -1347,8 +1353,10 @@
 {
   hb_font_t *font = _hb_font_create (face);
 
+#ifndef HB_NO_OT_FONT
   /* Install our in-house, very lightweight, funcs. */
   hb_ot_font_set_funcs (font);
+#endif
 
   return font;
 }
@@ -1914,6 +1922,7 @@
 }
 
 
+#ifndef HB_DISABLE_DEPRECATED
 /*
  * Deprecated get_glyph_func():
  */
@@ -2036,3 +2045,4 @@
 					  trampoline,
 					  trampoline_destroy);
 }
+#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -51,8 +51,8 @@
   HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \
   HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
   HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
+  HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning)) \
+  HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \
   HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
   HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
   HB_FONT_FUNC_IMPLEMENT (glyph_name) \
@@ -304,17 +304,25 @@
   hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph,
 				     hb_codepoint_t right_glyph)
   {
+#ifdef HB_DISABLE_DEPRECATED
+    return 0;
+#else
     return klass->get.f.glyph_h_kerning (this, user_data,
 					 left_glyph, right_glyph,
 					 klass->user_data.glyph_h_kerning);
+#endif
   }
 
   hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph,
 				     hb_codepoint_t bottom_glyph)
   {
+#ifdef HB_DISABLE_DEPRECATED
+    return 0;
+#else
     return klass->get.f.glyph_v_kerning (this, user_data,
 					 top_glyph, bottom_glyph,
 					 klass->user_data.glyph_v_kerning);
+#endif
   }
 
   hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
@@ -607,7 +615,7 @@
     return (hb_position_t) (scaled / upem);
   }
   hb_position_t em_scalef (float v, int scale)
-  { return (hb_position_t) round (v * scale / face->get_upem ()); }
+  { return (hb_position_t) roundf (v * scale / face->get_upem ()); }
   float em_fscale (int16_t v, int scale)
   { return (float) v * scale / face->get_upem (); }
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -96,7 +96,7 @@
 
   ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
 
-  ft_font->cached_x_scale.set (0);
+  ft_font->cached_x_scale.set_relaxed (0);
   ft_font->advance_cache.init ();
 
   return ft_font;
@@ -439,7 +439,7 @@
   else {
     /* Make a nul-terminated version. */
     char buf[128];
-    len = MIN (len, (int) sizeof (buf) - 1);
+    len = hb_min (len, (int) sizeof (buf) - 1);
     strncpy (buf, name, len);
     buf[len] = '\0';
     *glyph = FT_Get_Name_Index (ft_face, buf);
@@ -748,7 +748,7 @@
 static void free_static_ft_library ();
 #endif
 
-static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (FT_Library),
+static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<FT_Library>,
 							     hb_ft_library_lazy_loader_t>
 {
   static FT_Library create ()

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -202,6 +202,7 @@
 {
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_graphite2_font_get_gr_font:
  *
@@ -213,6 +214,7 @@
 {
   return nullptr;
 }
+#endif
 
 
 /*
@@ -308,12 +310,12 @@
 
 #define ALLOCATE_ARRAY(Type, name, len) \
   Type *name = (Type *) scratch; \
-  { \
+  do { \
     unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
     assert (_consumed <= scratch_size); \
     scratch += _consumed; \
     scratch_size -= _consumed; \
-  }
+  } while (0)
 
   ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
   ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -49,6 +49,9 @@
  * Functions for using HarfBuzz with the ICU library to provide Unicode data.
  **/
 
+/* ICU doesn't do-while(0) around their statements.  Ugh!
+ * https://unicode-org.atlassian.net/browse/CLDR-13027 */
+#define HB_ICU_STMT(S) do { S } while (0)
 
 hb_script_t
 hb_icu_script_to_script (UScriptCode script)
@@ -183,9 +186,9 @@
 
   len = 0;
   err = false;
-  U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err);
+  HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err));
   if (err) return false;
-  U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err);
+  HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err));
   if (err) return false;
 
   icu_err = U_ZERO_ERROR;
@@ -193,7 +196,7 @@
   if (U_FAILURE (icu_err))
     return false;
   if (u_countChar32 (normalized, len) == 1) {
-    U16_GET_UNSAFE (normalized, 0, *ab);
+    HB_ICU_STMT (U16_GET_UNSAFE (normalized, 0, *ab));
     ret = true;
   } else {
     ret = false;
@@ -221,13 +224,13 @@
 
     len = u_countChar32 (decomposed, len);
     if (len == 1) {
-      U16_GET_UNSAFE (decomposed, 0, *a);
+      HB_ICU_STMT (U16_GET_UNSAFE (decomposed, 0, *a));
       *b = 0;
       return *a != ab;
     } else if (len == 2) {
       len =0;
-      U16_NEXT_UNSAFE (decomposed, len, *a);
-      U16_NEXT_UNSAFE (decomposed, len, *b);
+      HB_ICU_STMT (U16_NEXT_UNSAFE (decomposed, len, *a));
+      HB_ICU_STMT (U16_NEXT_UNSAFE (decomposed, len, *b));
     }
     return true;
   }
@@ -236,7 +239,7 @@
   /* We don't ifdef-out the fallback code such that compiler always
    * sees it and makes sure it's compilable. */
 
-  UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
+  UChar utf16[2], normalized[2 * 19/*HB_UNICODE_MAX_DECOMPOSITION_LEN*/ + 1];
   unsigned int len;
   hb_bool_t ret, err;
   UErrorCode icu_err;
@@ -247,7 +250,7 @@
 
   len = 0;
   err = false;
-  U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err);
+  HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err));
   if (err) return false;
 
   icu_err = U_ZERO_ERROR;
@@ -258,13 +261,13 @@
   len = u_countChar32 (normalized, len);
 
   if (len == 1) {
-    U16_GET_UNSAFE (normalized, 0, *a);
+    HB_ICU_STMT (U16_GET_UNSAFE (normalized, 0, *a));
     *b = 0;
     ret = *a != ab;
   } else if (len == 2) {
     len =0;
-    U16_NEXT_UNSAFE (normalized, len, *a);
-    U16_NEXT_UNSAFE (normalized, len, *b);
+    HB_ICU_STMT (U16_NEXT_UNSAFE (normalized, len, *a));
+    HB_ICU_STMT (U16_NEXT_UNSAFE (normalized, len, *b));
 
     /* Here's the ugly part: if ab decomposes to a single character and
      * that character decomposes again, we have to detect that and undo
@@ -275,7 +278,7 @@
     if (U_FAILURE (icu_err))
       return false;
     hb_codepoint_t c;
-    U16_GET_UNSAFE (recomposed, 0, c);
+    HB_ICU_STMT (U16_GET_UNSAFE (recomposed, 0, c));
     if (c != *a && c != ab) {
       *a = c;
       *b = 0;
@@ -284,7 +287,7 @@
   } else {
     /* If decomposed to more than two characters, take the last one,
      * and recompose the rest to get the first component. */
-    U16_PREV_UNSAFE (normalized, len, *b); /* Changes len in-place. */
+    HB_ICU_STMT (U16_PREV_UNSAFE (normalized, len, *b)); /* Changes len in-place. */
     UChar recomposed[18 * 2];
     icu_err = U_ZERO_ERROR;
     len = unorm2_normalize (unorm2_getNFCInstance (&icu_err), normalized, len, recomposed, ARRAY_LENGTH (recomposed), &icu_err);
@@ -293,7 +296,7 @@
     /* We expect that recomposed has exactly one character now. */
     if (unlikely (u_countChar32 (recomposed, len) != 1))
       return false;
-    U16_GET_UNSAFE (recomposed, 0, *a);
+    HB_ICU_STMT (U16_GET_UNSAFE (recomposed, 0, *a));
     ret = true;
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2018  Google, Inc.
+ * Copyright © 2019  Facebook, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -22,6 +23,7 @@
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * Google Author(s): Behdad Esfahbod
+ * Facebook Author(s): Behdad Esfahbod
  */
 
 #ifndef HB_ITER_HH
@@ -28,7 +30,8 @@
 #define HB_ITER_HH
 
 #include "hb.hh"
-#include "hb-null.hh"
+#include "hb-algs.hh"
+#include "hb-meta.hh"
 
 
 /* Unified iterator object.
@@ -39,16 +42,32 @@
  * copied by value.  If the collection / object being iterated on
  * is writable, then the iterator returns lvalues, otherwise it
  * returns rvalues.
+ *
+ * TODO Document more.
+ *
+ * If iterator implementation implements operator!=, then can be
+ * used in range-based for loop.  That comes free if the iterator
+ * is random-access.  Otherwise, the range-based for loop incurs
+ * one traversal to find end(), which can be avoided if written
+ * as a while-style for loop, or if iterator implements a faster
+ * __end__() method.
+ * TODO When opting in for C++17, address this by changing return
+ * type of .end()?
  */
 
+/*
+ * Base classes for iterators.
+ */
+
 /* Base class for all iterators. */
-template <typename Iter, typename Item = typename Iter::__item_type__>
+template <typename iter_t, typename Item = typename iter_t::__item_t__>
 struct hb_iter_t
 {
-  typedef Iter iter_t;
-  typedef iter_t const_iter_t;
   typedef Item item_t;
   static constexpr unsigned item_size = hb_static_size (Item);
+  static constexpr bool is_iterator = true;
+  static constexpr bool is_random_access_iterator = false;
+  static constexpr bool is_sorted_iterator = false;
 
   private:
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
@@ -56,53 +75,110 @@
         iter_t* thiz ()       { return static_cast<      iter_t *> (this); }
   public:
 
+  /* TODO:
+   * Port operators below to use hb_enable_if to sniff which method implements
+   * an operator and use it, and remove hb_iter_fallback_mixin_t completely. */
+
   /* Operators. */
-  operator iter_t () { return iter(); }
-  explicit_operator bool () const { return more (); }
-  item_t& operator * () const { return item (); }
-  item_t& operator [] (signed i) const { return item_at ((unsigned) i); }
-  iter_t& operator += (unsigned count) { forward (count); return *thiz(); }
-  iter_t& operator ++ () { next (); return *thiz(); }
-  iter_t& operator -= (unsigned count) { rewind (count); return *thiz(); }
-  iter_t& operator -- () { prev (); return *thiz(); }
-  iter_t operator + (unsigned count) { iter_t c (*thiz()); c += count; return c; }
+  iter_t iter () const { return *thiz(); }
+  iter_t operator + () const { return *thiz(); }
+  iter_t begin () const { return *thiz(); }
+  iter_t end () const { return thiz()->__end__ (); }
+  explicit operator bool () const { return thiz()->__more__ (); }
+  unsigned len () const { return thiz()->__len__ (); }
+  /* The following can only be enabled if item_t is reference type.  Otherwise
+   * 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()); }
+  item_t operator * () const { return thiz()->__item__ (); }
+  item_t operator * () { return thiz()->__item__ (); }
+  item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); }
+  item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); }
+  iter_t& operator += (unsigned count) &  { thiz()->__forward__ (count); return *thiz(); }
+  iter_t  operator += (unsigned count) && { thiz()->__forward__ (count); return *thiz(); }
+  iter_t& operator ++ () &  { thiz()->__next__ (); return *thiz(); }
+  iter_t  operator ++ () && { thiz()->__next__ (); return *thiz(); }
+  iter_t& operator -= (unsigned count) &  { thiz()->__rewind__ (count); return *thiz(); }
+  iter_t  operator -= (unsigned count) && { thiz()->__rewind__ (count); return *thiz(); }
+  iter_t& operator -- () &  { thiz()->__prev__ (); return *thiz(); }
+  iter_t  operator -- () && { thiz()->__prev__ (); return *thiz(); }
+  iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; }
+  friend iter_t operator + (unsigned count, const iter_t &it) { return it + count; }
   iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; }
-  iter_t operator - (unsigned count) { iter_t c (*thiz()); c -= count; return c; }
+  iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; }
   iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; }
+  template <typename T>
+  iter_t& operator >> (T &v) &  { v = **thiz(); ++*thiz(); return *thiz(); }
+  template <typename T>
+  iter_t  operator >> (T &v) && { v = **thiz(); ++*thiz(); return *thiz(); }
+  template <typename T>
+  iter_t& operator << (const T v) &  { **thiz() = v; ++*thiz(); return *thiz(); }
+  template <typename T>
+  iter_t  operator << (const T v) && { **thiz() = v; ++*thiz(); return *thiz(); }
 
-  /* Methods. */
-  iter_t iter () const { return *thiz(); }
-  const_iter_t const_iter () const { return iter (); }
-  item_t& item () const { return thiz()->__item__ (); }
-  item_t& item_at (unsigned i) const { return thiz()->__item_at__ (i); }
-  bool more () const { return thiz()->__more__ (); }
-  unsigned len () const { return thiz()->__len__ (); }
-  void next () { thiz()->__next__ (); }
-  void forward (unsigned n) { thiz()->__forward__ (n); }
-  void prev () { thiz()->__prev__ (); }
-  void rewind (unsigned n) { thiz()->__rewind__ (n); }
-  bool random_access () const { return thiz()->__random_access__ (); }
-
   protected:
-  hb_iter_t () {}
-  hb_iter_t (const hb_iter_t &o HB_UNUSED) {}
-  void operator = (const hb_iter_t &o HB_UNUSED) {}
+  hb_iter_t () = default;
+  hb_iter_t (const hb_iter_t &o HB_UNUSED) = default;
+  hb_iter_t (hb_iter_t &&o HB_UNUSED) = default;
+  hb_iter_t& operator = (const hb_iter_t &o HB_UNUSED) = default;
+  hb_iter_t& operator = (hb_iter_t &&o HB_UNUSED) = default;
 };
 
-/* Base class for sorted iterators.  Does not enforce anything.
- * Just for class taxonomy and requirements. */
-template <typename Iter, typename Item = typename Iter::__item_type__>
-struct hb_sorted_iter_t : hb_iter_t<Iter, Item>
+#define HB_ITER_USING(Name) \
+  using item_t = typename Name::item_t; \
+  using Name::begin; \
+  using Name::end; \
+  using Name::item_size; \
+  using Name::is_iterator; \
+  using Name::iter; \
+  using Name::operator bool; \
+  using Name::len; \
+  using Name::operator ->; \
+  using Name::operator *; \
+  using Name::operator []; \
+  using Name::operator +=; \
+  using Name::operator ++; \
+  using Name::operator -=; \
+  using Name::operator --; \
+  using Name::operator +; \
+  using Name::operator -; \
+  using Name::operator >>; \
+  using Name::operator <<; \
+  static_assert (true, "")
+
+/* Returns iterator / item type of a type. */
+template <typename Iterable>
+using hb_iter_type = decltype (hb_deref (hb_declval (Iterable)).iter ());
+template <typename Iterable>
+using hb_item_type = decltype (*hb_deref (hb_declval (Iterable)).iter ());
+
+
+template <typename> struct hb_array_t;
+
+struct
 {
-  protected:
-  hb_sorted_iter_t () {}
-  hb_sorted_iter_t (const hb_sorted_iter_t &o) : hb_iter_t<Iter, Item> (o) {}
-  void operator = (const hb_sorted_iter_t &o HB_UNUSED) {}
-};
+  template <typename T> hb_iter_type<T>
+  operator () (T&& c) const
+  { return hb_deref (hb_forward<T> (c)).iter (); }
 
+  /* Specialization for C arrays. */
+
+  template <typename Type> inline hb_array_t<Type>
+  operator () (Type *array, unsigned int length) const
+  { return hb_array_t<Type> (array, length); }
+
+  template <typename Type, unsigned int length> hb_array_t<Type>
+  operator () (Type (&array)[length]) const
+  { return hb_array_t<Type> (array, length); }
+
+}
+HB_FUNCOBJ (hb_iter);
+
 /* Mixin to fill in what the subclass doesn't provide. */
-template <typename iter_t, typename item_t = typename iter_t::__item_type__>
-struct hb_iter_mixin_t
+template <typename iter_t, typename item_t = typename iter_t::__item_t__>
+struct hb_iter_fallback_mixin_t
 {
   private:
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
@@ -111,43 +187,646 @@
   public:
 
   /* Access: Implement __item__(), or __item_at__() if random-access. */
-  item_t& __item__ () const { return thiz()->item_at (0); }
-  item_t& __item_at__ (unsigned i) const { return *(thiz() + i); }
+  item_t __item__ () const { return (*thiz())[0]; }
+  item_t __item_at__ (unsigned i) const { return *(*thiz() + i); }
 
   /* Termination: Implement __more__(), or __len__() if random-access. */
-  bool __more__ () const { return thiz()->__len__ (); }
+  bool __more__ () const { return bool (thiz()->len ()); }
   unsigned __len__ () const
-  { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; }
+  { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; } return l; }
 
   /* Advancing: Implement __next__(), or __forward__() if random-access. */
-  void __next__ () { thiz()->forward (1); }
-  void __forward__ (unsigned n) { while (n--) thiz()->next (); }
+  void __next__ () { *thiz() += 1; }
+  void __forward__ (unsigned n) { while (*thiz() && n--) ++*thiz(); }
 
   /* Rewinding: Implement __prev__() or __rewind__() if bidirectional. */
-  void __prev__ () { thiz()->rewind (1); }
-  void __rewind__ (unsigned n) { while (n--) thiz()->prev (); }
+  void __prev__ () { *thiz() -= 1; }
+  void __rewind__ (unsigned n) { while (*thiz() && n--) --*thiz(); }
 
-  /* Random access: Return true if item_at(), len(), forward() are fast. */
-  bool __random_access__ () const { return false; }
+  /* Range-based for: Implement __end__() if can be done faster,
+   * and operator!=. */
+  iter_t __end__ () const
+  {
+    if (thiz()->is_random_access_iterator)
+      return *thiz() + thiz()->len ();
+    /* Above expression loops twice. Following loops once. */
+    auto it = *thiz();
+    while (it) ++it;
+    return it;
+  }
+
+  protected:
+  hb_iter_fallback_mixin_t () = default;
+  hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) = default;
+  hb_iter_fallback_mixin_t (hb_iter_fallback_mixin_t &&o HB_UNUSED) = default;
+  hb_iter_fallback_mixin_t& operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) = default;
+  hb_iter_fallback_mixin_t& operator = (hb_iter_fallback_mixin_t &&o HB_UNUSED) = default;
 };
 
+template <typename iter_t, typename item_t = typename iter_t::__item_t__>
+struct hb_iter_with_fallback_t :
+  hb_iter_t<iter_t, item_t>,
+  hb_iter_fallback_mixin_t<iter_t, item_t>
+{
+  protected:
+  hb_iter_with_fallback_t () = default;
+  hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) = default;
+  hb_iter_with_fallback_t (hb_iter_with_fallback_t &&o HB_UNUSED) = default;
+  hb_iter_with_fallback_t& operator = (const hb_iter_with_fallback_t &o HB_UNUSED) = default;
+  hb_iter_with_fallback_t& operator = (hb_iter_with_fallback_t &&o HB_UNUSED) = default;
+};
 
-/* Functions operating on iterators or iteratables. */
+/*
+ * Meta-programming predicates.
+ */
 
-template <typename C, typename V> inline void
-hb_fill (const C& c, const V &v)
+/* hb_is_iterator() / hb_is_iterator_of() */
+
+template<typename Iter, typename Item>
+struct hb_is_iterator_of
 {
-  for (typename C::iter_t i (c); i; i++)
-    hb_assign (*i, v);
+  template <typename Item2 = Item>
+  static hb_true_type impl (hb_priority<2>, hb_iter_t<Iter, hb_type_identity<Item2>> *);
+  static hb_false_type impl (hb_priority<0>, const void *);
+
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize, hb_declval (Iter*)))::value;
+};
+#define hb_is_iterator_of(Iter, Item) hb_is_iterator_of<Iter, Item>::value
+#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t)
+
+/* hb_is_iterable() */
+
+template <typename T>
+struct hb_is_iterable
+{
+  private:
+
+  template <typename U>
+  static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_type ());
+
+  template <typename>
+  static hb_false_type impl (hb_priority<0>);
+
+  public:
+  static constexpr bool value = decltype (impl<T> (hb_prioritize))::value;
+};
+#define hb_is_iterable(Iterable) hb_is_iterable<Iterable>::value
+
+/* hb_is_source_of() / hb_is_sink_of() */
+
+template<typename Iter, typename Item>
+struct hb_is_source_of
+{
+  private:
+  template <typename Iter2 = Iter,
+	    hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<hb_add_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 ());
+  static hb_false_type impl (hb_priority<0>);
+
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize))::value;
+};
+#define hb_is_source_of(Iter, Item) hb_is_source_of<Iter, Item>::value
+
+template<typename Iter, typename Item>
+struct hb_is_sink_of
+{
+  private:
+  template <typename Iter2 = Iter,
+	    hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<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 ());
+  static hb_false_type impl (hb_priority<0>);
+
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize))::value;
+};
+#define hb_is_sink_of(Iter, Item) hb_is_sink_of<Iter, Item>::value
+
+/* This is commonly used, so define: */
+#define hb_is_sorted_source_of(Iter, Item) \
+	(hb_is_source_of(Iter, Item) && Iter::is_sorted_iterator)
+
+
+/* Range-based 'for' for iterables. */
+
+template <typename Iterable,
+	  hb_requires (hb_is_iterable (Iterable))>
+static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ())
+
+template <typename Iterable,
+	  hb_requires (hb_is_iterable (Iterable))>
+static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ())
+
+/* begin()/end() are NOT looked up non-ADL.  So each namespace must declare them.
+ * Do it for namespace OT. */
+namespace OT {
+
+template <typename Iterable,
+	  hb_requires (hb_is_iterable (Iterable))>
+static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ())
+
+template <typename Iterable,
+	  hb_requires (hb_is_iterable (Iterable))>
+static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ())
+
 }
 
-template <typename S, typename D> inline bool
-hb_copy (hb_iter_t<D> &id, hb_iter_t<S> &is)
+
+/*
+ * Adaptors, combiners, etc.
+ */
+
+template <typename Lhs, typename Rhs,
+	  hb_requires (hb_is_iterator (Lhs))>
+static inline auto
+operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (hb_forward<Rhs> (rhs) (hb_forward<Lhs> (lhs)))
+
+/* hb_map(), hb_filter(), hb_reduce() */
+
+enum  class hb_function_sortedness_t {
+  NOT_SORTED,
+  RETAINS_SORTING,
+  SORTED,
+};
+
+template <typename Iter, typename Proj, hb_function_sortedness_t Sorted,
+	 hb_requires (hb_is_iterator (Iter))>
+struct hb_map_iter_t :
+  hb_iter_t<hb_map_iter_t<Iter, Proj, Sorted>,
+	    decltype (hb_get (hb_declval (Proj), *hb_declval (Iter)))>
 {
-  for (; id && is; ++id, ++is)
-    *id = *is;
-  return !is;
+  hb_map_iter_t (const Iter& it, Proj f_) : it (it), f (f_) {}
+
+  typedef decltype (hb_get (hb_declval (Proj), *hb_declval (Iter))) __item_t__;
+  static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
+  static constexpr bool is_sorted_iterator =
+    Sorted == hb_function_sortedness_t::SORTED ? true :
+    Sorted == hb_function_sortedness_t::RETAINS_SORTING ? Iter::is_sorted_iterator :
+    false;
+  __item_t__ __item__ () const { return hb_get (f.get (), *it); }
+  __item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); }
+  bool __more__ () const { return bool (it); }
+  unsigned __len__ () const { return it.len (); }
+  void __next__ () { ++it; }
+  void __forward__ (unsigned n) { it += n; }
+  void __prev__ () { --it; }
+  void __rewind__ (unsigned n) { it -= n; }
+  hb_map_iter_t __end__ () const { return hb_map_iter_t (it.end (), f); }
+  bool operator != (const hb_map_iter_t& o) const
+  { return it != o.it; }
+
+  private:
+  Iter it;
+  hb_reference_wrapper<Proj> f;
+};
+
+template <typename Proj, hb_function_sortedness_t Sorted>
+struct hb_map_iter_factory_t
+{
+  hb_map_iter_factory_t (Proj f) : f (f) {}
+
+  template <typename Iter,
+	    hb_requires (hb_is_iterator (Iter))>
+  hb_map_iter_t<Iter, Proj, Sorted>
+  operator () (Iter it)
+  { return hb_map_iter_t<Iter, Proj, Sorted> (it, f); }
+
+  private:
+  Proj f;
+};
+struct
+{
+  template <typename Proj>
+  hb_map_iter_factory_t<Proj, hb_function_sortedness_t::NOT_SORTED>
+  operator () (Proj&& f) const
+  { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::NOT_SORTED> (f); }
 }
+HB_FUNCOBJ (hb_map);
+struct
+{
+  template <typename Proj>
+  hb_map_iter_factory_t<Proj, hb_function_sortedness_t::RETAINS_SORTING>
+  operator () (Proj&& f) const
+  { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::RETAINS_SORTING> (f); }
+}
+HB_FUNCOBJ (hb_map_retains_sorting);
+struct
+{
+  template <typename Proj>
+  hb_map_iter_factory_t<Proj, hb_function_sortedness_t::SORTED>
+  operator () (Proj&& f) const
+  { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::SORTED> (f); }
+}
+HB_FUNCOBJ (hb_map_sorted);
 
+template <typename Iter, typename Pred, typename Proj,
+	 hb_requires (hb_is_iterator (Iter))>
+struct hb_filter_iter_t :
+  hb_iter_with_fallback_t<hb_filter_iter_t<Iter, Pred, Proj>,
+			  typename Iter::item_t>
+{
+  hb_filter_iter_t (const Iter& it_, Pred p_, Proj f_) : it (it_), p (p_), f (f_)
+  { while (it && !hb_has (p.get (), hb_get (f.get (), *it))) ++it; }
 
+  typedef typename Iter::item_t __item_t__;
+  static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
+  __item_t__ __item__ () const { return *it; }
+  bool __more__ () const { return bool (it); }
+  void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
+  void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
+  hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); }
+  bool operator != (const hb_filter_iter_t& o) const
+  { return it != o.it; }
+
+  private:
+  Iter it;
+  hb_reference_wrapper<Pred> p;
+  hb_reference_wrapper<Proj> f;
+};
+template <typename Pred, typename Proj>
+struct hb_filter_iter_factory_t
+{
+  hb_filter_iter_factory_t (Pred p, Proj f) : p (p), f (f) {}
+
+  template <typename Iter,
+	    hb_requires (hb_is_iterator (Iter))>
+  hb_filter_iter_t<Iter, Pred, Proj>
+  operator () (Iter it)
+  { return hb_filter_iter_t<Iter, Pred, Proj> (it, p, f); }
+
+  private:
+  Pred p;
+  Proj f;
+};
+struct
+{
+  template <typename Pred = decltype ((hb_identity)),
+	    typename Proj = decltype ((hb_identity))>
+  hb_filter_iter_factory_t<Pred, Proj>
+  operator () (Pred&& p = hb_identity, Proj&& f = hb_identity) const
+  { return hb_filter_iter_factory_t<Pred, Proj> (p, f); }
+}
+HB_FUNCOBJ (hb_filter);
+
+template <typename Redu, typename InitT>
+struct hb_reduce_t
+{
+  hb_reduce_t (Redu r, InitT init_value) : r (r), init_value (init_value) {}
+
+  template <typename Iter,
+	    hb_requires (hb_is_iterator (Iter)),
+	    typename AccuT = decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))>
+  AccuT
+  operator () (Iter it)
+  {
+    AccuT value = init_value;
+    for (; it; ++it)
+      value = r (value, *it);
+    return value;
+  }
+
+  private:
+  Redu r;
+  InitT init_value;
+};
+struct
+{
+  template <typename Redu, typename InitT>
+  hb_reduce_t<Redu, InitT>
+  operator () (Redu&& r, InitT init_value) const
+  { return hb_reduce_t<Redu, InitT> (r, init_value); }
+}
+HB_FUNCOBJ (hb_reduce);
+
+
+/* hb_zip() */
+
+template <typename A, typename B>
+struct hb_zip_iter_t :
+  hb_iter_t<hb_zip_iter_t<A, B>,
+	    hb_pair_t<typename A::item_t, typename B::item_t>>
+{
+  hb_zip_iter_t () {}
+  hb_zip_iter_t (const A& a, const B& b) : a (a), b (b) {}
+
+  typedef hb_pair_t<typename A::item_t, typename B::item_t> __item_t__;
+  static constexpr bool is_random_access_iterator =
+    A::is_random_access_iterator &&
+    B::is_random_access_iterator;
+  /* Note.  The following categorization is only valid if A is strictly sorted,
+   * ie. does NOT have duplicates.  Previously I tried to categorize sortedness
+   * more granularly, see commits:
+   *
+   *   513762849a683914fc266a17ddf38f133cccf072
+   *   4d3cf2adb669c345cc43832d11689271995e160a
+   *
+   * However, that was not enough, since hb_sorted_array_t, hb_sorted_vector_t,
+   * SortedArrayOf, etc all needed to be updated to add more variants.  At that
+   * point I saw it not worth the effort, and instead we now deem all sorted
+   * collections as essentially strictly-sorted for the purposes of zip.
+   *
+   * The above assumption is not as bad as it sounds.  Our "sorted" comes with
+   * no guarantees.  It's just a contract, put in place to help you remember,
+   * and think about, whether an iterator you receive is expected to be
+   * sorted or not.  As such, it's not perfect by definition, and should not
+   * be treated so.  The inaccuracy here just errs in the direction of being
+   * more permissive, so your code compiles instead of erring on the side of
+   * marking your zipped iterator unsorted in which case your code won't
+   * compile.
+   *
+   * This semantical limitation does NOT affect logic in any other place I
+   * know of as of this writing.
+   */
+  static constexpr bool is_sorted_iterator = A::is_sorted_iterator;
+
+  __item_t__ __item__ () const { return __item_t__ (*a, *b); }
+  __item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); }
+  bool __more__ () const { return bool (a) && bool (b); }
+  unsigned __len__ () const { return hb_min (a.len (), b.len ()); }
+  void __next__ () { ++a; ++b; }
+  void __forward__ (unsigned n) { a += n; b += n; }
+  void __prev__ () { --a; --b; }
+  void __rewind__ (unsigned n) { a -= n; b -= n; }
+  hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); }
+  /* Note, we should stop if ANY of the iters reaches end.  As such two compare
+   * unequal if both items are unequal, NOT if either is unequal. */
+  bool operator != (const hb_zip_iter_t& o) const
+  { return a != o.a && b != o.b; }
+
+  private:
+  A a;
+  B b;
+};
+struct
+{
+  template <typename A, typename B,
+	    hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
+  hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>>
+  operator () (A&& a, B&& b) const
+  { return hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>> (hb_iter (a), hb_iter (b)); }
+}
+HB_FUNCOBJ (hb_zip);
+
+/* hb_apply() */
+
+template <typename Appl>
+struct hb_apply_t
+{
+  hb_apply_t (Appl a) : a (a) {}
+
+  template <typename Iter,
+	    hb_requires (hb_is_iterator (Iter))>
+  void operator () (Iter it)
+  {
+    for (; it; ++it)
+      (void) hb_invoke (a, *it);
+  }
+
+  private:
+  Appl a;
+};
+struct
+{
+  template <typename Appl> hb_apply_t<Appl>
+  operator () (Appl&& a) const
+  { return hb_apply_t<Appl> (a); }
+
+  template <typename Appl> hb_apply_t<Appl&>
+  operator () (Appl *a) const
+  { return hb_apply_t<Appl&> (*a); }
+}
+HB_FUNCOBJ (hb_apply);
+
+/* hb_iota()/hb_range() */
+
+template <typename T, typename S>
+struct hb_counter_iter_t :
+  hb_iter_t<hb_counter_iter_t<T, S>, T>
+{
+  hb_counter_iter_t (T start, T end_, S step) : v (start), end_ (end_for (start, end_, step)), step (step) {}
+
+  typedef T __item_t__;
+  static constexpr bool is_random_access_iterator = true;
+  static constexpr bool is_sorted_iterator = true;
+  __item_t__ __item__ () const { return +v; }
+  __item_t__ __item_at__ (unsigned j) const { return v + j * step; }
+  bool __more__ () const { return v != end_; }
+  unsigned __len__ () const { return !step ? UINT_MAX : (end_ - v) / step; }
+  void __next__ () { v += step; }
+  void __forward__ (unsigned n) { v += n * step; }
+  void __prev__ () { v -= step; }
+  void __rewind__ (unsigned n) { v -= n * step; }
+  hb_counter_iter_t __end__ () const { return hb_counter_iter_t (end_, end_, step); }
+  bool operator != (const hb_counter_iter_t& o) const
+  { return v != o.v; }
+
+  private:
+  static inline T end_for (T start, T end_, S step)
+  {
+    if (!step)
+      return end_;
+    auto res = (end_ - start) % step;
+    if (!res)
+      return end_;
+    end_ += step - res;
+    return end_;
+  }
+
+  private:
+  T v;
+  T end_;
+  S step;
+};
+struct
+{
+  template <typename T = unsigned, typename S = unsigned> hb_counter_iter_t<T, S>
+  operator () (T start = 0u, S&& step = 1u) const
+  { return hb_counter_iter_t<T, S> (start, step >= 0 ? hb_int_max (T) : hb_int_min (T), step); }
+}
+HB_FUNCOBJ (hb_iota);
+struct
+{
+  template <typename T = unsigned> hb_counter_iter_t<T, unsigned>
+  operator () (T end = (unsigned) -1) const
+  { return hb_counter_iter_t<T, unsigned> (0, end, 1u); }
+
+  template <typename T, typename S = unsigned> hb_counter_iter_t<T, S>
+  operator () (T start, T end, S&& step = 1u) const
+  { return hb_counter_iter_t<T, S> (start, end, step); }
+}
+HB_FUNCOBJ (hb_range);
+
+/* hb_enumerate */
+
+struct
+{
+  template <typename Iterable,
+	    typename Index = unsigned,
+	    hb_requires (hb_is_iterable (Iterable))>
+  auto operator () (Iterable&& it, Index start = 0u) const HB_AUTO_RETURN
+  ( hb_zip (hb_iota (start), it) )
+}
+HB_FUNCOBJ (hb_enumerate);
+
+
+/* hb_sink() */
+
+template <typename Sink>
+struct hb_sink_t
+{
+  hb_sink_t (Sink s) : s (s) {}
+
+  template <typename Iter,
+	    hb_requires (hb_is_iterator (Iter))>
+  void operator () (Iter it)
+  {
+    for (; it; ++it)
+      s << *it;
+  }
+
+  private:
+  Sink s;
+};
+struct
+{
+  template <typename Sink> hb_sink_t<Sink>
+  operator () (Sink&& s) const
+  { return hb_sink_t<Sink> (s); }
+
+  template <typename Sink> hb_sink_t<Sink&>
+  operator () (Sink *s) const
+  { return hb_sink_t<Sink&> (*s); }
+}
+HB_FUNCOBJ (hb_sink);
+
+/* hb-drain: hb_sink to void / blackhole / /dev/null. */
+
+struct
+{
+  template <typename Iter,
+	    hb_requires (hb_is_iterator (Iter))>
+  void operator () (Iter it) const
+  {
+    for (; it; ++it)
+      (void) *it;
+  }
+}
+HB_FUNCOBJ (hb_drain);
+
+/* hb_unzip(): unzip and sink to two sinks. */
+
+template <typename Sink1, typename Sink2>
+struct hb_unzip_t
+{
+  hb_unzip_t (Sink1 s1, Sink2 s2) : s1 (s1), s2 (s2) {}
+
+  template <typename Iter,
+	    hb_requires (hb_is_iterator (Iter))>
+  void operator () (Iter it)
+  {
+    for (; it; ++it)
+    {
+      const auto &v = *it;
+      s1 << v.first;
+      s2 << v.second;
+    }
+  }
+
+  private:
+  Sink1 s1;
+  Sink2 s2;
+};
+struct
+{
+  template <typename Sink1, typename Sink2> hb_unzip_t<Sink1, Sink2>
+  operator () (Sink1&& s1, Sink2&& s2) const
+  { return hb_unzip_t<Sink1, Sink2> (s1, s2); }
+
+  template <typename Sink1, typename Sink2> hb_unzip_t<Sink1&, Sink2&>
+  operator () (Sink1 *s1, Sink2 *s2) const
+  { return hb_unzip_t<Sink1&, Sink2&> (*s1, *s2); }
+}
+HB_FUNCOBJ (hb_unzip);
+
+
+/* hb-all, hb-any, hb-none. */
+
+struct
+{
+  template <typename Iterable,
+	    typename Pred = decltype ((hb_identity)),
+	    typename Proj = decltype ((hb_identity)),
+	    hb_requires (hb_is_iterable (Iterable))>
+  bool operator () (Iterable&& c,
+		    Pred&& p = hb_identity,
+		    Proj&& f = hb_identity) const
+  {
+    for (auto it = hb_iter (c); it; ++it)
+      if (!hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+	return false;
+    return true;
+  }
+}
+HB_FUNCOBJ (hb_all);
+struct
+{
+  template <typename Iterable,
+	    typename Pred = decltype ((hb_identity)),
+	    typename Proj = decltype ((hb_identity)),
+	    hb_requires (hb_is_iterable (Iterable))>
+  bool operator () (Iterable&& c,
+		    Pred&& p = hb_identity,
+		    Proj&& f = hb_identity) const
+  {
+    for (auto it = hb_iter (c); it; ++it)
+      if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+	return true;
+    return false;
+  }
+}
+HB_FUNCOBJ (hb_any);
+struct
+{
+  template <typename Iterable,
+	    typename Pred = decltype ((hb_identity)),
+	    typename Proj = decltype ((hb_identity)),
+	    hb_requires (hb_is_iterable (Iterable))>
+  bool operator () (Iterable&& c,
+		    Pred&& p = hb_identity,
+		    Proj&& f = hb_identity) const
+  {
+    for (auto it = hb_iter (c); it; ++it)
+      if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+	return false;
+    return true;
+  }
+}
+HB_FUNCOBJ (hb_none);
+
+/*
+ * Algorithms operating on iterators.
+ */
+
+template <typename C, typename V,
+	  hb_requires (hb_is_iterable (C))>
+inline void
+hb_fill (C& c, const V &v)
+{
+  for (auto i = hb_iter (c); i; i++)
+    *i = v;
+}
+
+template <typename S, typename D>
+inline void
+hb_copy (S&& is, D&& id)
+{
+  hb_iter (is) | hb_sink (id);
+}
+
+
 #endif /* HB_ITER_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -32,8 +32,9 @@
 #include "hb.hh"
 #include "hb-blob.hh"
 
-#include "hb-array.hh"
-#include "hb-vector.hh"
+#include "hb-dispatch.hh"
+#include "hb-sanitize.hh"
+#include "hb-serialize.hh"
 
 
 /*
@@ -143,619 +144,8 @@
   DEFINE_SIZE_ARRAY(size, array)
 
 
-/*
- * Dispatch
- */
 
-template <typename Context, typename Return, unsigned int MaxDebugDepth>
-struct hb_dispatch_context_t
-{
-  static constexpr unsigned max_debug_depth = MaxDebugDepth;
-  typedef Return return_t;
-  template <typename T, typename F>
-  bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; }
-  static return_t no_dispatch_return_value () { return Context::default_return_value (); }
-  static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; }
-};
-
-
 /*
- * Sanitize
- *
- *
- * === Introduction ===
- *
- * The sanitize machinery is at the core of our zero-cost font loading.  We
- * mmap() font file into memory and create a blob out of it.  Font subtables
- * are returned as a readonly sub-blob of the main font blob.  These table
- * blobs are then sanitized before use, to ensure invalid memory access does
- * not happen.  The toplevel sanitize API use is like, eg. to load the 'head'
- * table:
- *
- *   hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (face);
- *
- * The blob then can be converted to a head table struct with:
- *
- *   const head *head_table = head_blob->as<head> ();
- *
- * What the reference_table does is, to call hb_face_reference_table() to load
- * the table blob, sanitize it and return either the sanitized blob, or empty
- * blob if sanitization failed.  The blob->as() function returns the null
- * object of its template type argument if the blob is empty.  Otherwise, it
- * just casts the blob contents to the desired type.
- *
- * Sanitizing a blob of data with a type T works as follows (with minor
- * simplification):
- *
- *   - Cast blob content to T*, call sanitize() method of it,
- *   - If sanitize succeeded, return blob.
- *   - Otherwise, if blob is not writable, try making it writable,
- *     or copy if cannot be made writable in-place,
- *   - Call sanitize() again.  Return blob if sanitize succeeded.
- *   - Return empty blob otherwise.
- *
- *
- * === The sanitize() contract ===
- *
- * The sanitize() method of each object type shall return true if it's safe to
- * call other methods of the object, and false otherwise.
- *
- * Note that what sanitize() checks for might align with what the specification
- * describes as valid table data, but does not have to be.  In particular, we
- * do NOT want to be pedantic and concern ourselves with validity checks that
- * are irrelevant to our use of the table.  On the contrary, we want to be
- * lenient with error handling and accept invalid data to the extent that it
- * does not impose extra burden on us.
- *
- * Based on the sanitize contract, one can see that what we check for depends
- * on how we use the data in other table methods.  Ie. if other table methods
- * assume that offsets do NOT point out of the table data block, then that's
- * something sanitize() must check for (GSUB/GPOS/GDEF/etc work this way).  On
- * the other hand, if other methods do such checks themselves, then sanitize()
- * does not have to bother with them (glyf/local work this way).  The choice
- * depends on the table structure and sanitize() performance.  For example, to
- * check glyf/loca offsets in sanitize() would cost O(num-glyphs).  We try hard
- * to avoid such costs during font loading.  By postponing such checks to the
- * actual glyph loading, we reduce the sanitize cost to O(1) and total runtime
- * cost to O(used-glyphs).  As such, this is preferred.
- *
- * The same argument can be made re GSUB/GPOS/GDEF, but there, the table
- * structure is so complicated that by checking all offsets at sanitize() time,
- * we make the code much simpler in other methods, as offsets and referenced
- * objects do not need to be validated at each use site.
- */
-
-/* This limits sanitizing time on really broken fonts. */
-#ifndef HB_SANITIZE_MAX_EDITS
-#define HB_SANITIZE_MAX_EDITS 32
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_FACTOR
-#define HB_SANITIZE_MAX_OPS_FACTOR 8
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_MIN
-#define HB_SANITIZE_MAX_OPS_MIN 16384
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_MAX
-#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
-#endif
-
-struct hb_sanitize_context_t :
-       hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
-{
-  hb_sanitize_context_t () :
-	debug_depth (0),
-	start (nullptr), end (nullptr),
-	max_ops (0),
-	writable (false), edit_count (0),
-	blob (nullptr),
-	num_glyphs (65536),
-	num_glyphs_set (false) {}
-
-  const char *get_name () { return "SANITIZE"; }
-  template <typename T, typename F>
-  bool may_dispatch (const T *obj HB_UNUSED, const F *format)
-  { return format->sanitize (this); }
-  template <typename T>
-  return_t dispatch (const T &obj) { return obj.sanitize (this); }
-  static return_t default_return_value () { return true; }
-  static return_t no_dispatch_return_value () { return false; }
-  bool stop_sublookup_iteration (const return_t r) const { return !r; }
-
-  void init (hb_blob_t *b)
-  {
-    this->blob = hb_blob_reference (b);
-    this->writable = false;
-  }
-
-  void set_num_glyphs (unsigned int num_glyphs_)
-  {
-    num_glyphs = num_glyphs_;
-    num_glyphs_set = true;
-  }
-  unsigned int get_num_glyphs () { return num_glyphs; }
-
-  void set_max_ops (int max_ops_) { max_ops = max_ops_; }
-
-  template <typename T>
-  void set_object (const T *obj)
-  {
-    reset_object ();
-
-    if (!obj) return;
-
-    const char *obj_start = (const char *) obj;
-    if (unlikely (obj_start < this->start || this->end <= obj_start))
-      this->start = this->end = nullptr;
-    else
-    {
-      this->start = obj_start;
-      this->end   = obj_start + MIN<uintptr_t> (this->end - obj_start, obj->get_size ());
-    }
-  }
-
-  void reset_object ()
-  {
-    this->start = this->blob->data;
-    this->end = this->start + this->blob->length;
-    assert (this->start <= this->end); /* Must not overflow. */
-  }
-
-  void start_processing ()
-  {
-    reset_object ();
-    this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
-			 (unsigned) HB_SANITIZE_MAX_OPS_MIN);
-    this->edit_count = 0;
-    this->debug_depth = 0;
-
-    DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
-		     "start [%p..%p] (%lu bytes)",
-		     this->start, this->end,
-		     (unsigned long) (this->end - this->start));
-  }
-
-  void end_processing ()
-  {
-    DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
-		     "end [%p..%p] %u edit requests",
-		     this->start, this->end, this->edit_count);
-
-    hb_blob_destroy (this->blob);
-    this->blob = nullptr;
-    this->start = this->end = nullptr;
-  }
-
-  bool check_range (const void *base,
-		    unsigned int len) const
-  {
-    const char *p = (const char *) base;
-    bool ok = !len ||
-	      (this->start <= p &&
-	       p <= this->end &&
-	       (unsigned int) (this->end - p) >= len &&
-	       this->max_ops-- > 0);
-
-    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
-		     "check_range [%p..%p]"
-		     " (%d bytes) in [%p..%p] -> %s",
-		     p, p + len, len,
-		     this->start, this->end,
-		     ok ? "OK" : "OUT-OF-RANGE");
-
-    return likely (ok);
-  }
-
-  template <typename T>
-  bool check_range (const T *base,
-		    unsigned int a,
-		    unsigned int b) const
-  {
-    return !hb_unsigned_mul_overflows (a, b) &&
-	   this->check_range (base, a * b);
-  }
-
-  template <typename T>
-  bool check_range (const T *base,
-		    unsigned int a,
-		    unsigned int b,
-		    unsigned int c) const
-  {
-    return !hb_unsigned_mul_overflows (a, b) &&
-	   this->check_range (base, a * b, c);
-  }
-
-  template <typename T>
-  bool check_array (const T *base, unsigned int len) const
-  {
-    return this->check_range (base, len, hb_static_size (T));
-  }
-
-  template <typename T>
-  bool check_array (const T *base,
-		    unsigned int a,
-		    unsigned int b) const
-  {
-    return this->check_range (base, a, b, hb_static_size (T));
-  }
-
-  template <typename Type>
-  bool check_struct (const Type *obj) const
-  { return likely (this->check_range (obj, obj->min_size)); }
-
-  bool may_edit (const void *base, unsigned int len)
-  {
-    if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
-      return false;
-
-    const char *p = (const char *) base;
-    this->edit_count++;
-
-    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
-       "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
-       this->edit_count,
-       p, p + len, len,
-       this->start, this->end,
-       this->writable ? "GRANTED" : "DENIED");
-
-    return this->writable;
-  }
-
-  template <typename Type, typename ValueType>
-  bool try_set (const Type *obj, const ValueType &v)
-  {
-    if (this->may_edit (obj, hb_static_size (Type)))
-    {
-      hb_assign (* const_cast<Type *> (obj), v);
-      return true;
-    }
-    return false;
-  }
-
-  template <typename Type>
-  hb_blob_t *sanitize_blob (hb_blob_t *blob)
-  {
-    bool sane;
-
-    init (blob);
-
-  retry:
-    DEBUG_MSG_FUNC (SANITIZE, start, "start");
-
-    start_processing ();
-
-    if (unlikely (!start))
-    {
-      end_processing ();
-      return blob;
-    }
-
-    Type *t = CastP<Type> (const_cast<char *> (start));
-
-    sane = t->sanitize (this);
-    if (sane)
-    {
-      if (edit_count)
-      {
-	DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %d edits; going for second round", edit_count);
-
-        /* sanitize again to ensure no toe-stepping */
-        edit_count = 0;
-	sane = t->sanitize (this);
-	if (edit_count) {
-	  DEBUG_MSG_FUNC (SANITIZE, start, "requested %d edits in second round; FAILLING", edit_count);
-	  sane = false;
-	}
-      }
-    }
-    else
-    {
-      if (edit_count && !writable) {
-        start = hb_blob_get_data_writable (blob, nullptr);
-	end = start + blob->length;
-
-	if (start)
-	{
-	  writable = true;
-	  /* ok, we made it writable by relocating.  try again */
-	  DEBUG_MSG_FUNC (SANITIZE, start, "retry");
-	  goto retry;
-	}
-      }
-    }
-
-    end_processing ();
-
-    DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED");
-    if (sane)
-    {
-      hb_blob_make_immutable (blob);
-      return blob;
-    }
-    else
-    {
-      hb_blob_destroy (blob);
-      return hb_blob_get_empty ();
-    }
-  }
-
-  template <typename Type>
-  hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
-  {
-    if (!num_glyphs_set)
-      set_num_glyphs (hb_face_get_glyph_count (face));
-    return sanitize_blob<Type> (hb_face_reference_table (face, tableTag));
-  }
-
-  mutable unsigned int debug_depth;
-  const char *start, *end;
-  mutable int max_ops;
-  private:
-  bool writable;
-  unsigned int edit_count;
-  hb_blob_t *blob;
-  unsigned int num_glyphs;
-  bool  num_glyphs_set;
-};
-
-struct hb_sanitize_with_object_t
-{
-  template <typename T>
-  hb_sanitize_with_object_t (hb_sanitize_context_t *c,
-				    const T& obj) : c (c)
-  { c->set_object (obj); }
-  ~hb_sanitize_with_object_t ()
-  { c->reset_object (); }
-
-  private:
-  hb_sanitize_context_t *c;
-};
-
-
-/*
- * Serialize
- */
-
-struct hb_serialize_context_t
-{
-  hb_serialize_context_t (void *start_, unsigned int size)
-  {
-    this->start = (char *) start_;
-    this->end = this->start + size;
-    reset ();
-  }
-
-  bool in_error () const { return !this->successful; }
-
-  void reset ()
-  {
-    this->successful = true;
-    this->head = this->start;
-    this->debug_depth = 0;
-  }
-
-  bool propagate_error (bool e)
-  { return this->successful = this->successful && e; }
-  template <typename T> bool propagate_error (const T &obj)
-  { return this->successful = this->successful && !obj.in_error (); }
-  template <typename T> bool propagate_error (const T *obj)
-  { return this->successful = this->successful && !obj->in_error (); }
-  template <typename T1, typename T2> bool propagate_error (T1 &o1, T2 &o2)
-  { return propagate_error (o1) && propagate_error (o2); }
-  template <typename T1, typename T2> bool propagate_error (T1 *o1, T2 *o2)
-  { return propagate_error (o1) && propagate_error (o2); }
-  template <typename T1, typename T2, typename T3>
-  bool propagate_error (T1 &o1, T2 &o2, T3 &o3)
-  { return propagate_error (o1) && propagate_error (o2, o3); }
-  template <typename T1, typename T2, typename T3>
-  bool propagate_error (T1 *o1, T2 *o2, T3 *o3)
-  { return propagate_error (o1) && propagate_error (o2, o3); }
-
-  /* To be called around main operation. */
-  template <typename Type>
-  Type *start_serialize ()
-  {
-    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
-		     "start [%p..%p] (%lu bytes)",
-		     this->start, this->end,
-		     (unsigned long) (this->end - this->start));
-
-    return start_embed<Type> ();
-  }
-  void end_serialize ()
-  {
-    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
-		     "end [%p..%p] serialized %d bytes; %s",
-		     this->start, this->end,
-		     (int) (this->head - this->start),
-		     this->successful ? "successful" : "UNSUCCESSFUL");
-  }
-
-  unsigned int length () const { return this->head - this->start; }
-
-  void align (unsigned int alignment)
-  {
-    unsigned int l = length () % alignment;
-    if (l)
-      allocate_size<void> (alignment - l);
-  }
-
-  template <typename Type>
-  Type *start_embed (const Type *_ HB_UNUSED = nullptr) const
-  {
-    Type *ret = reinterpret_cast<Type *> (this->head);
-    return ret;
-  }
-
-  template <typename Type>
-  Type *allocate_size (unsigned int size)
-  {
-    if (unlikely (!this->successful || this->end - this->head < ptrdiff_t (size))) {
-      this->successful = false;
-      return nullptr;
-    }
-    memset (this->head, 0, size);
-    char *ret = this->head;
-    this->head += size;
-    return reinterpret_cast<Type *> (ret);
-  }
-
-  template <typename Type>
-  Type *allocate_min ()
-  {
-    return this->allocate_size<Type> (Type::min_size);
-  }
-
-  template <typename Type>
-  Type *embed (const Type &obj)
-  {
-    unsigned int size = obj.get_size ();
-    Type *ret = this->allocate_size<Type> (size);
-    if (unlikely (!ret)) return nullptr;
-    memcpy (ret, &obj, size);
-    return ret;
-  }
-  template <typename Type>
-  hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; }
-
-  template <typename Type>
-  Type *extend_size (Type &obj, unsigned int size)
-  {
-    assert (this->start <= (char *) &obj);
-    assert ((char *) &obj <= this->head);
-    assert ((char *) &obj + size >= this->head);
-    if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
-    return reinterpret_cast<Type *> (&obj);
-  }
-
-  template <typename Type>
-  Type *extend_min (Type &obj) { return extend_size (obj, obj.min_size); }
-
-  template <typename Type>
-  Type *extend (Type &obj) { return extend_size (obj, obj.get_size ()); }
-
-  /* Output routines. */
-  template <typename Type>
-  Type *copy () const
-  {
-    assert (this->successful);
-    unsigned int len = this->head - this->start;
-    void *p = malloc (len);
-    if (p)
-      memcpy (p, this->start, len);
-    return reinterpret_cast<Type *> (p);
-  }
-  hb_bytes_t copy_bytes () const
-  {
-    assert (this->successful);
-    unsigned int len = this->head - this->start;
-    void *p = malloc (len);
-    if (p)
-      memcpy (p, this->start, len);
-    else
-      return hb_bytes_t ();
-    return hb_bytes_t ((char *) p, len);
-  }
-  hb_blob_t *copy_blob () const
-  {
-    assert (this->successful);
-    return hb_blob_create (this->start,
-			   this->head - this->start,
-			   HB_MEMORY_MODE_DUPLICATE,
-			   nullptr, nullptr);
-  }
-
-  public:
-  unsigned int debug_depth;
-  char *start, *end, *head;
-  bool successful;
-};
-
-
-
-/*
- * Big-endian integers.
- */
-
-template <typename Type, int Bytes> struct BEInt;
-
-template <typename Type>
-struct BEInt<Type, 1>
-{
-  public:
-  void set (Type V)      { v = V; }
-  operator Type () const { return v; }
-  private: uint8_t v;
-};
-template <typename Type>
-struct BEInt<Type, 2>
-{
-  public:
-  void set (Type V)
-  {
-    v[0] = (V >>  8) & 0xFF;
-    v[1] = (V      ) & 0xFF;
-  }
-  operator Type () const
-  {
-#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
-    defined(__BYTE_ORDER) && \
-    (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
-    /* Spoon-feed the compiler a big-endian integer with alignment 1.
-     * https://github.com/harfbuzz/harfbuzz/pull/1398 */
-    struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-    return __builtin_bswap16 (((packed_uint16_t *) this)->v);
-#else /* __BYTE_ORDER == __BIG_ENDIAN */
-    return ((packed_uint16_t *) this)->v;
-#endif
-#endif
-    return (v[0] <<  8)
-         + (v[1]      );
-  }
-  private: uint8_t v[2];
-};
-template <typename Type>
-struct BEInt<Type, 3>
-{
-  public:
-  void set (Type V)
-  {
-    v[0] = (V >> 16) & 0xFF;
-    v[1] = (V >>  8) & 0xFF;
-    v[2] = (V      ) & 0xFF;
-  }
-  operator Type () const
-  {
-    return (v[0] << 16)
-         + (v[1] <<  8)
-         + (v[2]      );
-  }
-  private: uint8_t v[3];
-};
-template <typename Type>
-struct BEInt<Type, 4>
-{
-  public:
-  typedef Type type;
-  void set (Type V)
-  {
-    v[0] = (V >> 24) & 0xFF;
-    v[1] = (V >> 16) & 0xFF;
-    v[2] = (V >>  8) & 0xFF;
-    v[3] = (V      ) & 0xFF;
-  }
-  operator Type () const
-  {
-    return (v[0] << 24)
-         + (v[1] << 16)
-         + (v[2] <<  8)
-         + (v[3]      );
-  }
-  private: uint8_t v[4];
-};
-
-
-/*
  * Lazy loaders.
  */
 
@@ -816,7 +206,7 @@
 
   const Returned * operator -> () const { return get (); }
   const Returned & operator * () const  { return *get (); }
-  explicit_operator bool () const
+  explicit operator bool () const
   { return get_stored () != Funcs::get_null (); }
   template <typename C> operator const C * () const { return get (); }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -30,31 +30,39 @@
 #include "hb.hh"
 
 
-template <typename T>
-inline uint32_t Hash (const T &v)
-{
-  /* Knuth's multiplicative method: */
-  return (uint32_t) v * 2654435761u;
-}
-
-
 /*
- * hb_map_t
+ * hb_hashmap_t
  */
 
-struct hb_map_t
+template <typename K, typename V,
+	  K kINVALID = hb_is_pointer (K) ? 0 : hb_is_signed (K) ? hb_int_min (K) : (K) -1,
+	  V vINVALID = hb_is_pointer (V) ? 0 : hb_is_signed (V) ? hb_int_min (V) : (V) -1>
+struct hb_hashmap_t
 {
-  HB_NO_COPY_ASSIGN (hb_map_t);
-  hb_map_t ()  { init (); }
-  ~hb_map_t () { fini (); }
+  HB_DELETE_COPY_ASSIGN (hb_hashmap_t);
+  hb_hashmap_t ()  { init (); }
+  ~hb_hashmap_t () { fini (); }
 
+  static_assert (hb_is_integral (K) || hb_is_pointer (K), "");
+  static_assert (hb_is_integral (V) || hb_is_pointer (V), "");
+
+  /* TODO If key type is a pointer, keep hash in item_t and use to:
+   * 1. avoid rehashing when resizing table, and
+   * 2. compare hash before comparing keys, for speed.
+   */
   struct item_t
   {
-    hb_codepoint_t key;
-    hb_codepoint_t value;
+    K key;
+    V value;
 
-    bool is_unused () const    { return key == INVALID; }
-    bool is_tombstone () const { return key != INVALID && value == INVALID; }
+    void clear () { key = kINVALID; value = vINVALID; }
+
+    bool operator == (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; }
+    hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
   };
 
   hb_object_header_t header;
@@ -82,14 +90,22 @@
   {
     free (items);
     items = nullptr;
+    population = occupancy = 0;
   }
   void fini ()
   {
-    population = occupancy = 0;
     hb_object_fini (this);
     fini_shallow ();
   }
 
+  void reset ()
+  {
+    if (unlikely (hb_object_is_immutable (this)))
+      return;
+    successful = true;
+    clear ();
+  }
+
   bool in_error () const { return !successful; }
 
   bool resize ()
@@ -104,7 +120,9 @@
       successful = false;
       return false;
     }
-    memset (new_items, 0xFF, (size_t) new_size * sizeof (item_t));
+    + hb_iter (new_items, new_size)
+    | hb_apply (&item_t::clear)
+    ;
 
     unsigned int old_size = mask + 1;
     item_t *old_items = items;
@@ -118,7 +136,7 @@
     /* Insert back old items. */
     if (old_items)
       for (unsigned int i = 0; i < old_size; i++)
-	if (old_items[i].key != INVALID && old_items[i].value != INVALID)
+	if (old_items[i].is_real ())
 	  set (old_items[i].key, old_items[i].value);
 
     free (old_items);
@@ -126,14 +144,14 @@
     return true;
   }
 
-  void set (hb_codepoint_t key, hb_codepoint_t value)
+  void set (K key, V value)
   {
     if (unlikely (!successful)) return;
-    if (unlikely (key == INVALID)) return;
+    if (unlikely (key == kINVALID)) return;
     if ((occupancy + occupancy / 2) >= mask && !resize ()) return;
     unsigned int i = bucket_for (key);
 
-    if (value == INVALID && items[i].key != key)
+    if (value == vINVALID && items[i].key != key)
       return; /* Trying to delete non-existent key. */
 
     if (!items[i].is_unused ())
@@ -151,26 +169,37 @@
       population++;
 
   }
-  hb_codepoint_t get (hb_codepoint_t key) const
+  V get (K key) const
   {
-    if (unlikely (!items)) return INVALID;
+    if (unlikely (!items)) return vINVALID;
     unsigned int i = bucket_for (key);
-    return items[i].key == key ? items[i].value : INVALID;
+    return items[i].is_real () && items[i] == key ? items[i].value : vINVALID;
   }
 
-  void del (hb_codepoint_t key) { set (key, INVALID); }
+  void del (K key) { set (key, vINVALID); }
 
-  bool has (hb_codepoint_t key) const
-  { return get (key) != INVALID; }
+  /* 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
+  {
+    V v = (*this)[k];
+    if (vp) *vp = v;
+    return v != SENTINEL;
+  }
+  /* Projection. */
+  V operator () (K k) const { return get (k); }
 
-  hb_codepoint_t operator [] (unsigned int key) const
-  { return get (key); }
-
-  static constexpr hb_codepoint_t INVALID = HB_MAP_VALUE_INVALID;
-
   void clear ()
   {
-    if (items) memset (items, 0xFF, ((size_t) mask + 1) * sizeof (item_t));
+    if (unlikely (hb_object_is_immutable (this)))
+      return;
+    if (items)
+      + hb_iter (items, mask + 1)
+      | hb_apply (&item_t::clear)
+      ;
+
     population = occupancy = 0;
   }
 
@@ -178,22 +207,50 @@
 
   unsigned int get_population () const { return population; }
 
+  /*
+   * Iterator
+   */
+  auto iter () const HB_AUTO_RETURN
+  (
+    + hb_array (items, mask ? mask + 1 : 0)
+    | hb_filter (&item_t::is_real)
+    | hb_map (&item_t::get_pair)
+  )
+  auto keys () const HB_AUTO_RETURN
+  (
+    + hb_array (items, mask ? mask + 1 : 0)
+    | hb_filter (&item_t::is_real)
+    | hb_map (&item_t::key)
+    | hb_map (hb_ridentity)
+  )
+  auto values () const HB_AUTO_RETURN
+  (
+    + hb_array (items, mask ? mask + 1 : 0)
+    | hb_filter (&item_t::is_real)
+    | hb_map (&item_t::value)
+    | hb_map (hb_ridentity)
+  )
+
+  /* Sink interface. */
+  hb_hashmap_t<K, V, kINVALID, vINVALID>& operator << (const hb_pair_t<K, V>& v)
+  { set (v.first, v.second); return *this; }
+
   protected:
 
-  unsigned int bucket_for (hb_codepoint_t key) const
+  unsigned int bucket_for (K key) const
   {
-    unsigned int i = Hash (key) % prime;
+    unsigned int i = hb_hash (key) % prime;
     unsigned int step = 0;
-    unsigned int tombstone = INVALID;
+    unsigned int tombstone = (unsigned) -1;
     while (!items[i].is_unused ())
     {
-      if (items[i].key == key)
-        return i;
-      if (tombstone == INVALID && items[i].is_tombstone ())
-        tombstone = i;
+      if (items[i] == key)
+	return i;
+      if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
+	tombstone = i;
       i = (i + ++step) & mask;
     }
-    return tombstone == INVALID ? i : tombstone;
+    return tombstone == (unsigned) -1 ? i : tombstone;
   }
 
   static unsigned int prime_for (unsigned int shift)
@@ -248,5 +305,14 @@
   }
 };
 
+/*
+ * hb_map_t
+ */
 
+struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
+			       hb_codepoint_t,
+			       HB_MAP_VALUE_INVALID,
+			       HB_MAP_VALUE_INVALID> {};
+
+
 #endif /* HB_MAP_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,400 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_META_HH
+#define HB_META_HH
+
+#include "hb.hh"
+
+
+/*
+ * C++ template meta-programming & fundamentals used with them.
+ */
+
+/* Void!  For when we need a expression-type of void. */
+struct hb_empty_t {};
+
+/* https://en.cppreference.com/w/cpp/types/void_t */
+template<typename... Ts> struct _hb_void_t { typedef void type; };
+template<typename... Ts> using hb_void_t = typename _hb_void_t<Ts...>::type;
+
+template<typename Head, typename... Ts> struct _hb_head_t { typedef Head type; };
+template<typename... Ts> using hb_head_t = typename _hb_head_t<Ts...>::type;
+
+template <typename T, T v> struct hb_integral_constant { static constexpr T value = v; };
+template <bool b> using hb_bool_constant = hb_integral_constant<bool, b>;
+using hb_true_type = hb_bool_constant<true>;
+using hb_false_type = hb_bool_constant<false>;
+
+
+/* Basic type SFINAE. */
+
+template <bool B, typename T = void> struct hb_enable_if {};
+template <typename T>                struct hb_enable_if<true, T> { typedef T type; };
+#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+/* Concepts/Requires alias: */
+#define hb_requires(Cond) hb_enable_if((Cond))
+
+template <typename T, typename T2> struct hb_is_same : hb_false_type {};
+template <typename T>              struct hb_is_same<T, T> : hb_true_type {};
+#define hb_is_same(T, T2) hb_is_same<T, T2>::value
+
+/* Function overloading SFINAE and priority. */
+
+#define HB_RETURN(Ret, E) -> hb_head_t<Ret, decltype ((E))> { return (E); }
+#define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
+#define HB_VOID_RETURN(E) -> hb_void_t<decltype ((E))> { (E); }
+
+template <unsigned Pri> struct hb_priority : hb_priority<Pri - 1> {};
+template <>             struct hb_priority<0> {};
+#define hb_prioritize hb_priority<16> ()
+
+#define HB_FUNCOBJ(x) static_const x HB_UNUSED
+
+
+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>
+  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> ())
+
+template <typename T> struct hb_match_const		: hb_type_identity_t<T>, hb_bool_constant<false>{};
+template <typename T> struct hb_match_const<const T>	: hb_type_identity_t<T>, hb_bool_constant<true>	{};
+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_bool_constant<false>{};
+template <typename T> struct hb_match_reference<T &>	: hb_type_identity_t<T>, hb_bool_constant<true>	{};
+template <typename T> struct hb_match_reference<T &&>	: hb_type_identity_t<T>, hb_bool_constant<true>	{};
+template <typename T> using hb_remove_reference = typename hb_match_reference<T>::type;
+template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<1>) -> hb_type_identity<T&>;
+template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
+template <typename T> using hb_add_lvalue_reference = decltype (_hb_try_add_lvalue_reference<T> (hb_prioritize));
+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_bool_constant<false>{};
+template <typename T> struct hb_match_pointer<T *>	: hb_type_identity_t<T>, hb_bool_constant<true>	{};
+template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
+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. */
+template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
+
+
+template<bool B, class T, class F>
+struct _hb_conditional { typedef T type; };
+template<class T, class F>
+struct _hb_conditional<false, T, F> { typedef F type; };
+template<bool B, class T, class F>
+using hb_conditional = typename _hb_conditional<B, T, F>::type;
+
+
+template <typename From, typename To>
+struct hb_is_convertible
+{
+  private:
+  static constexpr bool   from_void = hb_is_same (void, hb_decay<From>);
+  static constexpr bool     to_void = hb_is_same (void, hb_decay<To>  );
+  static constexpr bool either_void = from_void || to_void;
+  static constexpr bool   both_void = from_void && to_void;
+
+  static hb_true_type impl2 (hb_conditional<to_void, int, To>);
+
+  template <typename T>
+  static auto impl (hb_priority<1>) -> decltype (impl2 (hb_declval (T)));
+  template <typename T>
+  static hb_false_type impl (hb_priority<0>);
+  public:
+  static constexpr bool value = both_void ||
+		       (!either_void &&
+			decltype (impl<hb_conditional<from_void, int, From>> (hb_prioritize))::value);
+};
+#define hb_is_convertible(From,To) hb_is_convertible<From, To>::value
+
+template <typename Base, typename Derived>
+using hb_is_base_of = hb_is_convertible<hb_decay<Derived> *, hb_decay<Base> *>;
+#define hb_is_base_of(Base,Derived) hb_is_base_of<Base, Derived>::value
+
+template <typename From, typename To>
+using hb_is_cr_convertible = hb_bool_constant<
+  hb_is_same (hb_decay<From>, hb_decay<To>) &&
+  (!hb_is_const (From) || hb_is_const (To)) &&
+  (!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To))
+>;
+#define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
+
+/* std::move and std::forward */
+
+template <typename T>
+static hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
+
+template <typename T>
+static T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
+template <typename T>
+static T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
+
+struct
+{
+  template <typename T> auto
+  operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
+
+  template <typename T> auto
+  operator () (T *v) const HB_AUTO_RETURN (*v)
+}
+HB_FUNCOBJ (hb_deref);
+
+struct
+{
+  template <typename T> auto
+  operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
+
+  template <typename T> auto
+  operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
+}
+HB_FUNCOBJ (hb_ref);
+
+template <typename T>
+struct hb_reference_wrapper
+{
+  hb_reference_wrapper (T v) : v (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; }
+  T get () const { return v; }
+  T v;
+};
+template <typename T>
+struct hb_reference_wrapper<T&>
+{
+  hb_reference_wrapper (T& v) : v (hb_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; }
+  T& get () const { return *v; }
+  T* v;
+};
+
+
+template <typename T>
+using hb_is_integral = hb_bool_constant<
+  hb_is_same (hb_decay<T>, char) ||
+  hb_is_same (hb_decay<T>, signed char) ||
+  hb_is_same (hb_decay<T>, unsigned char) ||
+  hb_is_same (hb_decay<T>, signed int) ||
+  hb_is_same (hb_decay<T>, unsigned int) ||
+  hb_is_same (hb_decay<T>, signed short) ||
+  hb_is_same (hb_decay<T>, unsigned short) ||
+  hb_is_same (hb_decay<T>, signed long) ||
+  hb_is_same (hb_decay<T>, unsigned long) ||
+  hb_is_same (hb_decay<T>, signed long long) ||
+  hb_is_same (hb_decay<T>, unsigned long long) ||
+  false
+>;
+#define hb_is_integral(T) hb_is_integral<T>::value
+template <typename T>
+using hb_is_floating_point = hb_bool_constant<
+  hb_is_same (hb_decay<T>, float) ||
+  hb_is_same (hb_decay<T>, double) ||
+  hb_is_same (hb_decay<T>, long double) ||
+  false
+>;
+#define hb_is_floating_point(T) hb_is_floating_point<T>::value
+template <typename T>
+using hb_is_arithmetic = hb_bool_constant<
+  hb_is_integral (T) ||
+  hb_is_floating_point (T) ||
+  false
+>;
+#define hb_is_arithmetic(T) hb_is_arithmetic<T>::value
+
+
+template <typename T>
+using hb_is_signed = hb_conditional<hb_is_arithmetic (T),
+				    hb_bool_constant<(T) -1 < (T) 0>,
+				    hb_false_type>;
+#define hb_is_signed(T) hb_is_signed<T>::value
+template <typename T>
+using hb_is_unsigned = hb_conditional<hb_is_arithmetic (T),
+				      hb_bool_constant<(T) 0 < (T) -1>,
+				      hb_false_type>;
+#define hb_is_unsigned(T) hb_is_unsigned<T>::value
+
+template <typename T> struct hb_int_min;
+template <> struct hb_int_min<char>			: hb_integral_constant<char,			CHAR_MIN>	{};
+template <> struct hb_int_min<signed char>		: hb_integral_constant<signed char,		SCHAR_MIN>	{};
+template <> struct hb_int_min<unsigned char>		: hb_integral_constant<unsigned char,		0>		{};
+template <> struct hb_int_min<signed short>		: hb_integral_constant<signed short,		SHRT_MIN>	{};
+template <> struct hb_int_min<unsigned short>		: hb_integral_constant<unsigned short,		0>		{};
+template <> struct hb_int_min<signed int>		: hb_integral_constant<signed int,		INT_MIN>	{};
+template <> struct hb_int_min<unsigned int>		: hb_integral_constant<unsigned int,		0>		{};
+template <> struct hb_int_min<signed long>		: hb_integral_constant<signed long,		LONG_MIN>	{};
+template <> struct hb_int_min<unsigned long>		: hb_integral_constant<unsigned long,		0>		{};
+template <> struct hb_int_min<signed long long>		: hb_integral_constant<signed long long,	LLONG_MIN>	{};
+template <> struct hb_int_min<unsigned long long>	: hb_integral_constant<unsigned long long,	0>		{};
+#define hb_int_min(T) hb_int_min<T>::value
+template <typename T> struct hb_int_max;
+template <> struct hb_int_max<char>			: hb_integral_constant<char,			CHAR_MAX>	{};
+template <> struct hb_int_max<signed char>		: hb_integral_constant<signed char,		SCHAR_MAX>	{};
+template <> struct hb_int_max<unsigned char>		: hb_integral_constant<unsigned char,		UCHAR_MAX>	{};
+template <> struct hb_int_max<signed short>		: hb_integral_constant<signed short,		SHRT_MAX>	{};
+template <> struct hb_int_max<unsigned short>		: hb_integral_constant<unsigned short,		USHRT_MAX>	{};
+template <> struct hb_int_max<signed int>		: hb_integral_constant<signed int,		INT_MAX>	{};
+template <> struct hb_int_max<unsigned int>		: hb_integral_constant<unsigned int,		UINT_MAX>	{};
+template <> struct hb_int_max<signed long>		: hb_integral_constant<signed long,		LONG_MAX>	{};
+template <> struct hb_int_max<unsigned long>		: hb_integral_constant<unsigned long,		ULONG_MAX>	{};
+template <> struct hb_int_max<signed long long>		: hb_integral_constant<signed long long,	LLONG_MAX>	{};
+template <> struct hb_int_max<unsigned long long>	: hb_integral_constant<unsigned long long,	ULLONG_MAX>	{};
+#define hb_int_max(T) hb_int_max<T>::value
+
+
+
+template <typename T, typename>
+struct _hb_is_destructible : hb_false_type {};
+template <typename T>
+struct _hb_is_destructible<T, hb_void_t<decltype (hb_declval (T).~T ())>> : hb_true_type {};
+template <typename T>
+using hb_is_destructible = _hb_is_destructible<T, void>;
+#define hb_is_destructible(T) hb_is_destructible<T>::value
+
+template <typename T, typename, typename ...Ts>
+struct _hb_is_constructible : hb_false_type {};
+template <typename T, typename ...Ts>
+struct _hb_is_constructible<T, hb_void_t<decltype (T (hb_declval (Ts)...))>, Ts...> : hb_true_type {};
+template <typename T, typename ...Ts>
+using hb_is_constructible = _hb_is_constructible<T, void, Ts...>;
+#define hb_is_constructible(...) hb_is_constructible<__VA_ARGS__>::value
+
+template <typename T>
+using hb_is_default_constructible = hb_is_constructible<T>;
+#define hb_is_default_constructible(T) hb_is_default_constructible<T>::value
+
+template <typename T>
+using hb_is_copy_constructible = hb_is_constructible<T, hb_add_lvalue_reference<hb_add_const<T>>>;
+#define hb_is_copy_constructible(T) hb_is_copy_constructible<T>::value
+
+template <typename T>
+using hb_is_move_constructible = hb_is_constructible<T, hb_add_rvalue_reference<hb_add_const<T>>>;
+#define hb_is_move_constructible(T) hb_is_move_constructible<T>::value
+
+template <typename T, typename U, typename>
+struct _hb_is_assignable : hb_false_type {};
+template <typename T, typename U>
+struct _hb_is_assignable<T, U, hb_void_t<decltype (hb_declval (T) = hb_declval (U))>> : hb_true_type {};
+template <typename T, typename U>
+using hb_is_assignable = _hb_is_assignable<T, U, void>;
+#define hb_is_assignable(T,U) hb_is_assignable<T, U>::value
+
+template <typename T>
+using hb_is_copy_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
+					       hb_add_lvalue_reference<hb_add_const<T>>>;
+#define hb_is_copy_assignable(T) hb_is_copy_assignable<T>::value
+
+template <typename T>
+using hb_is_move_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
+					       hb_add_rvalue_reference<T>>;
+#define hb_is_move_assignable(T) hb_is_move_assignable<T>::value
+
+/* Trivial versions. */
+
+template <typename T> union hb_trivial { T value; };
+
+/* Don't know how to do the following. */
+template <typename T>
+using hb_is_trivially_destructible= hb_is_destructible<hb_trivial<T>>;
+#define hb_is_trivially_destructible(T) hb_is_trivially_destructible<T>::value
+
+/* Don't know how to do the following. */
+//template <typename T, typename ...Ts>
+//using hb_is_trivially_constructible= hb_is_constructible<hb_trivial<T>, hb_trivial<Ts>...>;
+//#define hb_is_trivially_constructible(...) hb_is_trivially_constructible<__VA_ARGS__>::value
+
+template <typename T>
+using hb_is_trivially_default_constructible= hb_is_default_constructible<hb_trivial<T>>;
+#define hb_is_trivially_default_constructible(T) hb_is_trivially_default_constructible<T>::value
+
+template <typename T>
+using hb_is_trivially_copy_constructible= hb_is_copy_constructible<hb_trivial<T>>;
+#define hb_is_trivially_copy_constructible(T) hb_is_trivially_copy_constructible<T>::value
+
+template <typename T>
+using hb_is_trivially_move_constructible= hb_is_move_constructible<hb_trivial<T>>;
+#define hb_is_trivially_move_constructible(T) hb_is_trivially_move_constructible<T>::value
+
+/* Don't know how to do the following. */
+//template <typename T, typename U>
+//using hb_is_trivially_assignable= hb_is_assignable<hb_trivial<T>, hb_trivial<U>>;
+//#define hb_is_trivially_assignable(T,U) hb_is_trivially_assignable<T, U>::value
+
+template <typename T>
+using hb_is_trivially_copy_assignable= hb_is_copy_assignable<hb_trivial<T>>;
+#define hb_is_trivially_copy_assignable(T) hb_is_trivially_copy_assignable<T>::value
+
+template <typename T>
+using hb_is_trivially_move_assignable= hb_is_move_assignable<hb_trivial<T>>;
+#define hb_is_trivially_move_assignable(T) hb_is_trivially_move_assignable<T>::value
+
+template <typename T>
+using hb_is_trivially_copyable= hb_bool_constant<
+  hb_is_trivially_destructible (T) &&
+  (!hb_is_move_assignable (T) || hb_is_trivially_move_assignable (T)) &&
+  (!hb_is_move_constructible (T) || hb_is_trivially_move_constructible (T)) &&
+  (!hb_is_copy_assignable (T) || hb_is_trivially_copy_assignable (T)) &&
+  (!hb_is_copy_constructible (T) || hb_is_trivially_copy_constructible (T)) &&
+  true
+>;
+#define hb_is_trivially_copyable(T) hb_is_trivially_copyable<T>::value
+
+template <typename T>
+using hb_is_trivial= hb_bool_constant<
+  hb_is_trivially_copyable (T) &&
+  hb_is_trivially_default_constructible (T)
+>;
+#define hb_is_trivial(T) hb_is_trivial<T>::value
+
+
+#endif /* HB_META_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -127,8 +127,6 @@
 
 struct hb_mutex_t
 {
-  /* TODO Add tracing. */
-
   hb_mutex_impl_t m;
 
   void init   () { hb_mutex_impl_init   (&m); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -28,6 +28,7 @@
 #define HB_NULL_HH
 
 #include "hb.hh"
+#include "hb-meta.hh"
 
 
 /*
@@ -36,7 +37,7 @@
 
 /* Global nul-content Null pool.  Enlarge as necessary. */
 
-#define HB_NULL_POOL_SIZE 9880
+#define HB_NULL_POOL_SIZE 384
 
 /* Use SFINAE to sniff whether T has min_size; in which case return T::null_size,
  * otherwise return sizeof(T). */
@@ -45,18 +46,13 @@
  * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol
  */
 
-template<bool> struct _hb_bool_type {};
-
-template <typename T, typename B>
-struct _hb_null_size
-{ enum { value = sizeof (T) }; };
+template <typename T, typename>
+struct _hb_null_size : hb_integral_constant<unsigned, sizeof (T)> {};
 template <typename T>
-struct _hb_null_size<T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
-{ enum { value = T::null_size }; };
+struct _hb_null_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::null_size> {};
 
 template <typename T>
-struct hb_null_size
-{ enum { value = _hb_null_size<T, _hb_bool_type<true> >::value }; };
+using hb_null_size = _hb_null_size<T, void>;
 #define hb_null_size(T) hb_null_size<T>::value
 
 /* These doesn't belong here, but since is copy/paste from above, put it here. */
@@ -64,38 +60,15 @@
 /* hb_static_size (T)
  * Returns T::static_size if T::min_size is defined, or sizeof (T) otherwise. */
 
-template <typename T, typename B>
-struct _hb_static_size
-{ enum { value = sizeof (T) }; };
+template <typename T, typename>
+struct _hb_static_size : hb_integral_constant<unsigned, sizeof (T)> {};
 template <typename T>
-struct _hb_static_size<T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
-{ enum { value = T::static_size }; };
-
+struct _hb_static_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::static_size> {};
 template <typename T>
-struct hb_static_size
-{ enum { value = _hb_static_size<T, _hb_bool_type<true> >::value }; };
+using hb_static_size = _hb_static_size<T, void>;
 #define hb_static_size(T) hb_static_size<T>::value
 
 
-/* hb_assign (obj, value)
- * Calls obj.set (value) if obj.min_size is defined and value has different type
- * from obj, or obj = v otherwise. */
-
-template <typename T, typename V, typename B>
-struct _hb_assign
-{ static inline void value (T &o, const V v) { o = v; } };
-template <typename T, typename V>
-struct _hb_assign<T, V, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
-{ static inline void value (T &o, const V v) { o.set (v); } };
-template <typename T>
-struct _hb_assign<T, T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
-{ static inline void value (T &o, const T v) { o = v; } };
-
-template <typename T, typename V>
-static inline void hb_assign (T &o, const V v)
-{ _hb_assign<T, V, _hb_bool_type<true> >::value (o, v); }
-
-
 /*
  * Null()
  */
@@ -115,7 +88,7 @@
 template <typename QType>
 struct NullHelper
 {
-  typedef typename hb_remove_const (typename hb_remove_reference (QType)) Type;
+  typedef hb_remove_const<hb_remove_reference<QType>> Type;
   static const Type & get_null () { return Null<Type>::get_null (); }
 };
 #define Null(Type) NullHelper<Type>::get_null ()
@@ -168,7 +141,7 @@
 template <typename QType>
 struct CrapHelper
 {
-  typedef typename hb_remove_const (typename hb_remove_reference (QType)) Type;
+  typedef hb_remove_const<hb_remove_reference<QType>> Type;
   static Type & get_crap () { return Crap<Type> (); }
 };
 #define Crap(Type) CrapHelper<Type>::get_crap ()
@@ -191,7 +164,7 @@
 template <typename P>
 struct hb_nonnull_ptr_t
 {
-  typedef typename hb_remove_pointer (P) T;
+  typedef hb_remove_pointer<P> T;
 
   hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {}
   T * operator = (T *v_)   { return v = v_; }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -56,7 +56,7 @@
 {
   int cmp (Tag t) const { return -t.cmp (tag); }
 
-  static int cmp (const void *pa, const void *pb)
+  HB_INTERNAL static int cmp (const void *pa, const void *pb)
   {
     const TableRecord *a = (const TableRecord *) pa;
     const TableRecord *b = (const TableRecord *) pb;
@@ -86,8 +86,8 @@
   const TableRecord& get_table (unsigned int i) const
   { return tables[i]; }
   unsigned int get_table_tags (unsigned int  start_offset,
-				      unsigned int *table_count, /* IN/OUT */
-				      hb_tag_t     *table_tags /* OUT */) const
+			       unsigned int *table_count, /* IN/OUT */
+			       hb_tag_t     *table_tags /* OUT */) const
   {
     if (table_count)
     {
@@ -94,7 +94,7 @@
       if (start_offset >= tables.len)
         *table_count = 0;
       else
-        *table_count = MIN<unsigned int> (*table_count, tables.len - start_offset);
+        *table_count = hb_min (*table_count, tables.len - start_offset);
 
       const TableRecord *sub_tables = tables.arrayZ + start_offset;
       unsigned int count = *table_count;
@@ -106,7 +106,7 @@
   bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
   {
     Tag t;
-    t.set (tag);
+    t = tag;
     return tables.bfind (t, table_index, HB_BFIND_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
   }
   const TableRecord& get_table_by_tag (hb_tag_t tag) const
@@ -127,7 +127,7 @@
     /* Alloc 12 for the OTHeader. */
     if (unlikely (!c->extend_min (*this))) return_trace (false);
     /* Write sfntVersion (bytes 0..3). */
-    sfnt_version.set (sfnt_tag);
+    sfnt_version = sfnt_tag;
     /* Take space for numTables, searchRange, entrySelector, RangeShift
      * and the TableRecords themselves.  */
     if (unlikely (!tables.serialize (c, items.length))) return_trace (false);
@@ -140,8 +140,8 @@
     {
       TableRecord &rec = tables.arrayZ[i];
       hb_blob_t *blob = items[i].blob;
-      rec.tag.set (items[i].tag);
-      rec.length.set (hb_blob_get_length (blob));
+      rec.tag = items[i].tag;
+      rec.length = hb_blob_get_length (blob);
       rec.offset.serialize (c, this);
 
       /* Allocate room for the table and copy it. */
@@ -159,7 +159,7 @@
       {
 	head *h = (head *) start;
 	checksum_adjustment = &h->checkSumAdjustment;
-	checksum_adjustment->set (0);
+	*checksum_adjustment = 0;
       }
 
       rec.checkSum.set_for_data (start, end - start);
@@ -177,10 +177,10 @@
       for (unsigned int i = 0; i < items.length; i++)
       {
 	TableRecord &rec = tables.arrayZ[i];
-	checksum.set (checksum + rec.checkSum);
+	checksum = checksum + rec.checkSum;
       }
 
-      checksum_adjustment->set (0xB1B0AFBAu - checksum);
+      *checksum_adjustment = 0xB1B0AFBAu - checksum;
     }
 
     return_trace (true);
@@ -222,7 +222,7 @@
   Tag		ttcTag;		/* TrueType Collection ID string: 'ttcf' */
   FixedVersion<>version;	/* Version of the TTC Header (1.0),
 				 * 0x00010000u */
-  LArrayOf<LOffsetTo<OffsetTable> >
+  LArrayOf<LOffsetTo<OffsetTable>>
 		table;		/* Array of offsets to the OffsetTable for each font
 				 * from the beginning of the file */
   public:
@@ -334,7 +334,7 @@
   protected:
   Tag		tag;		/* Resource type. */
   HBUINT16	resCountM1;	/* Number of resources minus 1. */
-  NNOffsetTo<UnsizedArrayOf<ResourceRecord> >
+  NNOffsetTo<UnsizedArrayOf<ResourceRecord>>
 		resourcesZ;	/* Offset from beginning of resource type list
 				 * to reference item list for this type. */
   public:
@@ -390,7 +390,7 @@
   HBUINT32	reserved1;	/* Reserved for handle to next resource map */
   HBUINT16	resreved2;	/* Reserved for file reference number */
   HBUINT16	attrs;		/* Resource fork attribute */
-  NNOffsetTo<ArrayOfM1<ResourceTypeRecord> >
+  NNOffsetTo<ArrayOfM1<ResourceTypeRecord>>
 		typeList;	/* Offset from beginning of map to
 				 * resource type list */
   Offset16	nameList;	/* Offset from beginning of map to
@@ -422,7 +422,7 @@
   }
 
   protected:
-  LNNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  LNNOffsetTo<UnsizedArrayOf<HBUINT8>>
 		data;		/* Offset from beginning of resource fork
 				 * to resource data */
   LNNOffsetTo<ResourceMap >

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -52,22 +52,19 @@
  * Int types
  */
 
-template <bool is_signed> struct hb_signedness_int;
-template <> struct hb_signedness_int<false> { typedef unsigned int value; };
-template <> struct hb_signedness_int<true>  { typedef   signed int value; };
-
 /* Integer types in big-endian order and no alignment requirement */
 template <typename Type, unsigned int Size>
 struct IntType
 {
   typedef Type type;
-  typedef typename hb_signedness_int<hb_is_signed<Type>::value>::value wide_type;
+  typedef hb_conditional<hb_is_signed (Type), signed, unsigned> wide_type;
 
-  void set (wide_type i) { v.set (i); }
+  IntType<Type, Size>& operator = (wide_type i) { v = i; return *this; }
   operator wide_type () const { return v; }
   bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
   bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
-  static int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
+  HB_INTERNAL static int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b)
+  { return b->cmp (*a); }
   template <typename Type2>
   int cmp (Type2 a) const
   {
@@ -110,9 +107,10 @@
 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
 struct F2DOT14 : HBINT16
 {
+  F2DOT14& operator = (uint16_t i ) { HBINT16::operator= (i); return *this; }
   // 16384 means 1<<14
   float to_float () const  { return ((int32_t) v) / 16384.f; }
-  void set_float (float f) { v.set (round (f * 16384.f)); }
+  void set_float (float f) { v = roundf (f * 16384.f); }
   public:
   DEFINE_SIZE_STATIC (2);
 };
@@ -120,9 +118,10 @@
 /* 32-bit signed fixed-point number (16.16). */
 struct Fixed : HBINT32
 {
+  Fixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; }
   // 65536 means 1<<16
   float to_float () const  { return ((int32_t) v) / 65536.f; }
-  void set_float (float f) { v.set (round (f * 65536.f)); }
+  void set_float (float f) { v = roundf (f * 65536.f); }
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -147,6 +146,7 @@
  * system, feature, or baseline */
 struct Tag : HBUINT32
 {
+  Tag& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
   /* What the char* converters return is NOT nul-terminated.  Print using "%.4s" */
   operator const char* () const { return reinterpret_cast<const char *> (&this->v); }
   operator char* ()             { return reinterpret_cast<char *> (&this->v); }
@@ -155,11 +155,15 @@
 };
 
 /* Glyph index number, same as uint16 (length = 16 bits) */
-typedef HBUINT16 GlyphID;
+struct GlyphID : HBUINT16
+{
+  GlyphID& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
+};
 
 /* Script/language-system/feature index */
 struct Index : HBUINT16 {
   static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFu;
+  Index& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
 };
 DECLARE_NULL_NAMESPACE_BYTES (OT, Index);
 
@@ -169,6 +173,8 @@
 template <typename Type, bool has_null=true>
 struct Offset : Type
 {
+  Offset& operator = (typename Type::type i) { Type::operator= (i); return *this; }
+
   typedef Type type;
 
   bool is_null () const { return has_null && 0 == *this; }
@@ -176,7 +182,7 @@
   void *serialize (hb_serialize_context_t *c, const void *base)
   {
     void *t = c->start_embed<void> ();
-    this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
+    c->check_assign (*this, (unsigned) ((char *) t - (char *) base));
     return t;
   }
 
@@ -191,6 +197,8 @@
 /* CheckSum */
 struct CheckSum : HBUINT32
 {
+  CheckSum& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
+
   /* This is reference implementation from the spec. */
   static uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length)
   {
@@ -205,7 +213,7 @@
 
   /* Note: data should be 4byte aligned and have 4byte padding at the end. */
   void set_for_data (const void *data, unsigned int length)
-  { set (CalcTableChecksum ((const HBUINT32 *) data, length)); }
+  { *this = CalcTableChecksum ((const HBUINT32 *) data, length); }
 
   public:
   DEFINE_SIZE_STATIC (4);
@@ -255,6 +263,11 @@
 template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
 struct OffsetTo : Offset<OffsetType, has_null>
 {
+  HB_DELETE_COPY_ASSIGN (OffsetTo);
+  OffsetTo () = default;
+
+  OffsetTo& operator = (typename OffsetType::type i) { OffsetType::operator= (i); return *this; }
+
   const Type& operator () (const void *base) const
   {
     if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_null ();
@@ -266,24 +279,62 @@
     return StructAtOffset<Type> (base, *this);
   }
 
+  template <typename Base,
+	    hb_enable_if (hb_is_convertible (const Base, const void *))>
+  friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); }
+  template <typename Base,
+	    hb_enable_if (hb_is_convertible (const Base, const void *))>
+  friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); }
+  template <typename Base,
+	    hb_enable_if (hb_is_convertible (Base, void *))>
+  friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); }
+  template <typename Base,
+	    hb_enable_if (hb_is_convertible (Base, void *))>
+  friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); }
+
   Type& serialize (hb_serialize_context_t *c, const void *base)
   {
     return * (Type *) Offset<OffsetType>::serialize (c, base);
   }
 
-  template <typename T>
-  void serialize_subset (hb_subset_context_t *c, const T &src, const void *base)
+  template <typename ...Ts>
+  bool serialize_subset (hb_subset_context_t *c, const Type &src, const void *base, Ts&&... ds)
   {
-    if (&src == &Null (T))
-    {
-      this->set (0);
-      return;
-    }
-    serialize (c->serializer, base);
-    if (!src.subset (c))
-      this->set (0);
+    *this = 0;
+    if (has_null && &src == _hb_has_null<Type, has_null>::get_null ())
+      return false;
+
+    auto *s = c->serializer;
+
+    s->push ();
+
+    bool ret = c->dispatch (src, hb_forward<Ts> (ds)...);
+
+    if (ret || !has_null)
+      s->add_link (*this, s->pop_pack (), base);
+    else
+      s->pop_discard ();
+
+    return ret;
   }
 
+  /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */
+  template <typename ...Ts>
+  bool serialize_copy (hb_serialize_context_t *c, const Type &src, const void *base, Ts&&... ds)
+  {
+    *this = 0;
+    if (has_null && &src == _hb_has_null<Type, has_null>::get_null ())
+      return false;
+
+    c->push ();
+
+    bool ret = c->copy (src, hb_forward<Ts> (ds)...);
+
+    c->add_link (*this, c->pop_pack (), base);
+
+    return ret;
+  }
+
   bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -293,41 +344,15 @@
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     return_trace (sanitize_shallow (c, base) &&
 		  (this->is_null () ||
-		   StructAtOffset<Type> (base, *this).sanitize (c) ||
+		   c->dispatch (StructAtOffset<Type> (base, *this), hb_forward<Ts> (ds)...) ||
 		   neuter (c)));
   }
-  template <typename T1>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (sanitize_shallow (c, base) &&
-		  (this->is_null () ||
-		   StructAtOffset<Type> (base, *this).sanitize (c, d1) ||
-		   neuter (c)));
-  }
-  template <typename T1, typename T2>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (sanitize_shallow (c, base) &&
-		  (this->is_null () ||
-		   StructAtOffset<Type> (base, *this).sanitize (c, d1, d2) ||
-		   neuter (c)));
-  }
-  template <typename T1, typename T2, typename T3>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2, T3 d3) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (sanitize_shallow (c, base) &&
-		  (this->is_null () ||
-		   StructAtOffset<Type> (base, *this).sanitize (c, d1, d2, d3) ||
-		   neuter (c)));
-  }
 
   /* Set the offset to Null */
   bool neuter (hb_sanitize_context_t *c) const
@@ -338,16 +363,14 @@
   DEFINE_SIZE_STATIC (sizeof (OffsetType));
 };
 /* Partial specializations. */
-template <typename Type,                               bool has_null=true> struct   LOffsetTo : OffsetTo<Type, HBUINT32,   has_null> {};
-template <typename Type, typename OffsetType=HBUINT16                    > struct  NNOffsetTo : OffsetTo<Type, OffsetType, false> {};
-template <typename Type                                                  > struct LNNOffsetTo : OffsetTo<Type, HBUINT32,   false> {};
+template <typename Type, bool has_null=true>
+using LOffsetTo = OffsetTo<Type, HBUINT32, has_null>;
+template <typename Type, typename OffsetType=HBUINT16>
+using NNOffsetTo = OffsetTo<Type, OffsetType, false>;
+template <typename Type>
+using LNNOffsetTo = LOffsetTo<Type, false>;
 
-template <typename Base, typename OffsetType, bool has_null, typename Type>
-static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
-template <typename Base, typename OffsetType, bool has_null, typename Type>
-static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
 
-
 /*
  * Array Types
  */
@@ -358,7 +381,7 @@
   typedef Type item_t;
   static constexpr unsigned item_size = hb_static_size (Type);
 
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type);
+  HB_DELETE_CREATE_COPY_ASSIGN (UnsizedArrayOf);
 
   const Type& operator [] (int i_) const
   {
@@ -397,38 +420,42 @@
   void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1)
   { as_array (len).qsort (start, end); }
 
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && arrayZ[0].sanitize (c));
-
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend (*this, items_len))) return_trace (false);
     return_trace (true);
   }
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const
+  template <typename Iterator,
+	    hb_requires (hb_is_source_of (Iterator, Type))>
+  bool serialize (hb_serialize_context_t *c, Iterator items)
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base)))
-	return_trace (false);
+    TRACE_SERIALIZE (this);
+    unsigned count = items.len ();
+    if (unlikely (!serialize (c, count))) return_trace (false);
+    /* TODO Umm. Just exhaust the iterator instead?  Being extra
+     * cautious right now.. */
+    for (unsigned i = 0; i < count; i++, ++items)
+      arrayZ[i] = *items;
     return_trace (true);
   }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const
+
+  UnsizedArrayOf* copy (hb_serialize_context_t *c, unsigned count) const
   {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!as_array (count).copy (c))) return_trace (nullptr);
+    return_trace (out);
+  }
+
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
+  {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }
@@ -447,7 +474,7 @@
 
 /* Unsized array of offset's */
 template <typename Type, typename OffsetType, bool has_null=true>
-struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null> > {};
+using UnsizedOffsetArrayOf = UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null>>;
 
 /* Unsized array of offsets relative to the beginning of the array itself. */
 template <typename Type, typename OffsetType, bool has_null=true>
@@ -468,18 +495,13 @@
     return this+*p;
   }
 
-
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
-    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>::sanitize (c, count, this)));
+    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>
+		   ::sanitize (c, count, this, hb_forward<Ts> (ds)...)));
   }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>::sanitize (c, count, this, user_data)));
-  }
 };
 
 /* An array with sorted elements.  Supports binary searching. */
@@ -514,7 +536,7 @@
   typedef Type item_t;
   static constexpr unsigned item_size = hb_static_size (Type);
 
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType);
+  HB_DELETE_CREATE_COPY_ASSIGN (ArrayOf);
 
   const Type& operator [] (int i_) const
   {
@@ -532,13 +554,19 @@
   unsigned int get_size () const
   { return len.static_size + len * Type::static_size; }
 
-  hb_array_t<Type> as_array ()
-  { return hb_array (arrayZ, len); }
-  hb_array_t<const Type> as_array () const
-  { return hb_array (arrayZ, len); }
-  operator hb_array_t<Type> (void)             { return as_array (); }
-  operator hb_array_t<const Type> (void) const { return as_array (); }
+  explicit operator bool () const { return len; }
 
+  hb_array_t<      Type> as_array ()       { return hb_array (arrayZ, len); }
+  hb_array_t<const Type> as_array () const { return hb_array (arrayZ, len); }
+
+  /* Iterator. */
+  typedef hb_array_t<const Type>   iter_t;
+  typedef hb_array_t<      Type> 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
   { 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
@@ -552,57 +580,46 @@
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    len.set (items_len); /* TODO(serialize) Overflow? */
+    c->check_assign (len, items_len);
     if (unlikely (!c->extend (*this))) return_trace (false);
     return_trace (true);
   }
-  template <typename T>
-  bool serialize (hb_serialize_context_t *c, hb_array_t<const T> items)
+  template <typename Iterator,
+	    hb_requires (hb_is_source_of (Iterator, Type))>
+  bool serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!serialize (c, items.length))) return_trace (false);
-    for (unsigned int i = 0; i < items.length; i++)
-      hb_assign (arrayZ[i], items[i]);
+    unsigned count = items.len ();
+    if (unlikely (!serialize (c, count))) return_trace (false);
+    /* TODO Umm. Just exhaust the iterator instead?  Being extra
+     * cautious right now.. */
+    for (unsigned i = 0; i < count; i++, ++items)
+      arrayZ[i] = *items;
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  ArrayOf* copy (hb_serialize_context_t *c) const
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!c->extend_min (out))) return_trace (nullptr);
+    c->check_assign (out->len, len);
+    if (unlikely (!as_array ().copy (c))) return_trace (nullptr);
+    return_trace (out);
+  }
 
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && arrayZ[0].sanitize (c));
-
-    return_trace (true);
-  }
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base)))
+      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    unsigned int count = len;
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
-	return_trace (false);
-    return_trace (true);
-  }
 
   template <typename T>
   Type &lsearch (const T &x, Type &not_found = Crap (Type))
@@ -626,16 +643,17 @@
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
-template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
-typedef ArrayOf<HBUINT8, HBUINT8> PString;
+template <typename Type>
+using LArrayOf = ArrayOf<Type, HBUINT32>;
+using PString = ArrayOf<HBUINT8, HBUINT8>;
 
 /* Array of Offset's */
 template <typename Type>
-struct OffsetArrayOf : ArrayOf<OffsetTo<Type, HBUINT16> > {};
+using OffsetArrayOf = ArrayOf<OffsetTo<Type, HBUINT16>>;
 template <typename Type>
-struct LOffsetArrayOf : ArrayOf<OffsetTo<Type, HBUINT32> > {};
+using LOffsetArrayOf = ArrayOf<OffsetTo<Type, HBUINT32>>;
 template <typename Type>
-struct LOffsetLArrayOf : ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32> {};
+using LOffsetLArrayOf = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>;
 
 /* Array of offsets relative to the beginning of the array itself. */
 template <typename Type>
@@ -665,17 +683,12 @@
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
-    return_trace (OffsetArrayOf<Type>::sanitize (c, this));
+    return_trace (OffsetArrayOf<Type>::sanitize (c, this, hb_forward<Ts> (ds)...));
   }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, T user_data) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data));
-  }
 };
 
 /* An array starting at second element. */
@@ -684,7 +697,7 @@
 {
   static constexpr unsigned item_size = Type::static_size;
 
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (HeadlessArrayOf, Type, LenType);
+  HB_DELETE_CREATE_COPY_ASSIGN (HeadlessArrayOf);
 
   const Type& operator [] (int i_) const
   {
@@ -706,7 +719,7 @@
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    lenP1.set (items.length + 1); /* TODO(serialize) Overflow? */
+    c->check_assign (lenP1, items.length + 1);
     if (unlikely (!c->extend (*this))) return_trace (false);
     for (unsigned int i = 0; i < items.length; i++)
       arrayZ[i] = items[i];
@@ -713,20 +726,16 @@
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && arrayZ[0].sanitize (c));
-
+    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
+    unsigned int count = lenP1 ? lenP1 - 1 : 0;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
+	return_trace (false);
     return_trace (true);
   }
 
@@ -749,7 +758,7 @@
 template <typename Type, typename LenType=HBUINT16>
 struct ArrayOfM1
 {
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOfM1, Type, LenType);
+  HB_DELETE_CREATE_COPY_ASSIGN (ArrayOfM1);
 
   const Type& operator [] (int i_) const
   {
@@ -766,14 +775,14 @@
   unsigned int get_size () const
   { return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
 
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
     unsigned int count = lenM1 + 1;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }
@@ -797,22 +806,41 @@
 template <typename Type, typename LenType=HBUINT16>
 struct SortedArrayOf : ArrayOf<Type, LenType>
 {
-  hb_sorted_array_t<Type> as_array ()
-  { return hb_sorted_array (this->arrayZ, this->len); }
-  hb_sorted_array_t<const Type> as_array () const
-  { return hb_sorted_array (this->arrayZ, this->len); }
-  operator hb_sorted_array_t<Type> ()             { return as_array (); }
-  operator hb_sorted_array_t<const Type> () const { return as_array (); }
+  hb_sorted_array_t<      Type> as_array ()       { return hb_sorted_array (this->arrayZ, this->len); }
+  hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->len); }
 
-  hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
+  /* Iterator. */
+  typedef hb_sorted_array_t<const Type>   iter_t;
+  typedef hb_sorted_array_t<      Type> 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_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
   { return as_array ().sub_array (start_offset, count);}
-  hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
+  hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
   { return as_array ().sub_array (start_offset, count);}
-  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
+  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
   { return as_array ().sub_array (start_offset, count);}
-  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
+  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
   { return as_array ().sub_array (start_offset, count);}
 
+  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+  {
+    TRACE_SERIALIZE (this);
+    bool ret = ArrayOf<Type, LenType>::serialize (c, items_len);
+    return_trace (ret);
+  }
+  template <typename Iterator,
+	    hb_requires (hb_is_sorted_source_of (Iterator, Type))>
+  bool serialize (hb_serialize_context_t *c, Iterator items)
+  {
+    TRACE_SERIALIZE (this);
+    bool ret = ArrayOf<Type, LenType>::serialize (c, items);
+    return_trace (ret);
+  }
+
   template <typename T>
   Type &bsearch (const T &x, Type &not_found = Crap (Type))
   { return *as_array ().bsearch (x, &not_found); }
@@ -841,15 +869,16 @@
     return_trace (c->check_struct (this));
   }
 
-  void set (unsigned int v)
+  BinSearchHeader& operator = (unsigned int v)
   {
-    len.set (v);
+    len = v;
     assert (len == v);
-    entrySelector.set (MAX (1u, hb_bit_storage (v)) - 1);
-    searchRange.set (16 * (1u << entrySelector));
-    rangeShift.set (v * 16 > searchRange
-		    ? 16 * v - searchRange
-		    : 0);
+    entrySelector = hb_max (1u, hb_bit_storage (v)) - 1;
+    searchRange = 16 * (1u << entrySelector);
+    rangeShift = v * 16 > searchRange
+		 ? 16 * v - searchRange
+		 : 0;
+    return *this;
   }
 
   protected:
@@ -863,7 +892,7 @@
 };
 
 template <typename Type, typename LenType=HBUINT16>
-struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader<LenType> > {};
+using BinSearchArrayOf = SortedArrayOf<Type, BinSearchHeader<LenType>>;
 
 
 struct VarSizedBinSearchHeader
@@ -893,7 +922,7 @@
 {
   static constexpr unsigned item_size = Type::static_size;
 
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type);
+  HB_DELETE_CREATE_COPY_ASSIGN (VarSizedBinSearchArrayOf);
 
   bool last_is_terminator () const
   {
@@ -928,43 +957,18 @@
   unsigned int get_size () const
   { return header.static_size + header.nUnits * header.unitSize; }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && StructAtOffset<Type> (&bytesZ, 0).sanitize (c));
-
-    return_trace (true);
-  }
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
     unsigned int count = get_length ();
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(*this)[i].sanitize (c, base)))
+      if (unlikely (!(*this)[i].sanitize (c, hb_forward<Ts> (ds)...)))
 	return_trace (false);
     return_trace (true);
   }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    unsigned int count = get_length ();
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(*this)[i].sanitize (c, base, user_data)))
-	return_trace (false);
-    return_trace (true);
-  }
 
   template <typename T>
   const Type *bsearch (const T &key) const

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -97,12 +97,12 @@
   unsigned int offset_array_size () const
   { return calculate_offset_array_size (offSize, count); }
 
-  static unsigned int calculate_serialized_size (unsigned int offSize, unsigned int count, unsigned int dataSize)
+  static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count, unsigned int dataSize)
   {
     if (count == 0)
       return COUNT::static_size;
     else
-      return min_size + calculate_offset_array_size (offSize, count) + dataSize;
+      return min_size + calculate_offset_array_size (offSize_, count) + dataSize;
   }
 
   bool serialize (hb_serialize_context_t *c, const CFFIndex &src)
@@ -124,15 +124,15 @@
     {
       COUNT *dest = c->allocate_min<COUNT> ();
       if (unlikely (dest == nullptr)) return_trace (false);
-      dest->set (0);
+      *dest = 0;
     }
     else
     {
       /* serialize CFFIndex header */
       if (unlikely (!c->extend_min (*this))) return_trace (false);
-      this->count.set (byteArray.length);
-      this->offSize.set (offSize_);
-      if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (byteArray.length + 1))))
+      this->count = byteArray.length;
+      this->offSize = offSize_;
+      if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (byteArray.length + 1))))
 	return_trace (false);
 
       /* serialize indices */
@@ -167,7 +167,7 @@
     byteArray.resize (buffArray.length);
     for (unsigned int i = 0; i < byteArray.length; i++)
     {
-      byteArray[i] = byte_str_t (buffArray[i].arrayZ (), buffArray[i].length);
+      byteArray[i] = byte_str_t (buffArray[i].arrayZ, buffArray[i].length);
     }
     bool result = this->serialize (c, offSize_, byteArray);
     byteArray.fini ();
@@ -181,7 +181,7 @@
     for (; size; size--)
     {
       --p;
-      p->set (offset & 0xFF);
+      *p = offset & 0xFF;
       offset >>= 8;
     }
   }
@@ -275,9 +275,9 @@
     TRACE_SERIALIZE (this);
     /* serialize CFFIndex header */
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    this->count.set (dataArrayLen);
-    this->offSize.set (offSize_);
-    if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1))))
+    this->count = dataArrayLen;
+    this->offSize = offSize_;
+    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1))))
       return_trace (false);
 
     /* serialize indices */
@@ -376,11 +376,11 @@
     if (unlikely (p == nullptr)) return_trace (false);
     if (Is_OpCode_ESC (op))
     {
-      p->set (OpCode_escape);
+      *p = OpCode_escape;
       op = Unmake_OpCode_ESC (op);
       p++;
     }
-    p->set (op);
+    *p = op;
     return_trace (true);
   }
 
@@ -477,9 +477,9 @@
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    this->count.set (fontDicts.length);
-    this->offSize.set (offSize_);
-    if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (fontDicts.length + 1))))
+    this->count = fontDicts.length;
+    this->offSize = offSize_;
+    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (fontDicts.length + 1))))
       return_trace (false);
 
     /* serialize font dict offsets */
@@ -514,9 +514,9 @@
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    this->count.set (fdCount);
-    this->offSize.set (offSize_);
-    if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (fdCount + 1))))
+    this->count = fdCount;
+    this->offSize = offSize_;
+    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (fdCount + 1))))
       return_trace (false);
 
     /* serialize font dict offsets */
@@ -589,7 +589,7 @@
 
 template <typename GID_TYPE, typename FD_TYPE>
 struct FDSelect3_4_Range {
-  bool sanitize (hb_sanitize_context_t *c, const void */*nullptr*/, unsigned int fdcount) const
+  bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const
   {
     TRACE_SANITIZE (this);
     return_trace (first < c->get_num_glyphs () && (fd < fdcount));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -27,6 +27,8 @@
 #include "hb-ot-cff1-table.hh"
 #include "hb-cff1-interp-cs.hh"
 
+#ifndef HB_NO_CFF
+
 using namespace CFF;
 
 /* SID to code */
@@ -165,8 +167,8 @@
 {
   void init ()
   {
-    min.set_int (0x7FFFFFFF, 0x7FFFFFFF);
-    max.set_int (-0x80000000, -0x80000000);
+    min.set_int (INT_MAX, INT_MAX);
+    max.set_int (INT_MIN, INT_MIN);
   }
 
   void update (const point_t &pt)
@@ -305,6 +307,11 @@
 
 bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
 {
+#ifdef HB_NO_OT_FONT_CFF
+  /* XXX Remove check when this code moves to .hh file. */
+  return true;
+#endif
+
   bounds_t  bounds;
 
   if (!_get_bounds (this, glyph, bounds))
@@ -383,3 +390,5 @@
   }
   return false;
 }
+
+#endif

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -110,7 +110,8 @@
     {
       if (glyph <= ranges[i].nLeft)
       {
-	return (hb_codepoint_t)ranges[i].first + glyph;
+	hb_codepoint_t code = (hb_codepoint_t) ranges[i].first + glyph;
+	return (likely (code < 0x100) ? code: CFF_UNDEF_CODE);
       }
       glyph -= (ranges[i].nLeft + 1);
     }
@@ -196,18 +197,18 @@
     TRACE_SERIALIZE (this);
     Encoding *dest = c->extend_min (*this);
     if (unlikely (dest == nullptr)) return_trace (false);
-    dest->format.set (format | ((supp_codes.length > 0)? 0x80: 0));
+    dest->format = format | ((supp_codes.length > 0)? 0x80: 0);
     if (format == 0)
     {
       Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count);
     if (unlikely (fmt0 == nullptr)) return_trace (false);
-      fmt0->nCodes ().set (enc_count);
+      fmt0->nCodes () = enc_count;
       unsigned int glyph = 0;
       for (unsigned int i = 0; i < code_ranges.length; i++)
       {
 	hb_codepoint_t code = code_ranges[i].code;
 	for (int left = (int)code_ranges[i].glyph; left >= 0; left--)
-	  fmt0->codes[glyph++].set (code++);
+	  fmt0->codes[glyph++] = code++;
 	if (unlikely (!((glyph <= 0x100) && (code <= 0x100))))
 	  return_trace (false);
       }
@@ -216,13 +217,13 @@
     {
       Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length);
       if (unlikely (fmt1 == nullptr)) return_trace (false);
-      fmt1->nRanges ().set (code_ranges.length);
+      fmt1->nRanges () = code_ranges.length;
       for (unsigned int i = 0; i < code_ranges.length; i++)
       {
 	if (unlikely (!((code_ranges[i].code <= 0xFF) && (code_ranges[i].glyph <= 0xFF))))
 	  return_trace (false);
-	fmt1->ranges[i].first.set (code_ranges[i].code);
-	fmt1->ranges[i].nLeft.set (code_ranges[i].glyph);
+	fmt1->ranges[i].first = code_ranges[i].code;
+	fmt1->ranges[i].nLeft = code_ranges[i].glyph;
       }
     }
     if (supp_codes.length > 0)
@@ -229,11 +230,11 @@
     {
       CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length);
       if (unlikely (suppData == nullptr)) return_trace (false);
-      suppData->nSups ().set (supp_codes.length);
+      suppData->nSups () = supp_codes.length;
       for (unsigned int i = 0; i < supp_codes.length; i++)
       {
-	suppData->supps[i].code.set (supp_codes[i].code);
-	suppData->supps[i].glyph.set (supp_codes[i].glyph); /* actually SID */
+	suppData->supps[i].code = supp_codes[i].code;
+	suppData->supps[i].glyph = supp_codes[i].glyph; /* actually SID */
       }
     }
     return_trace (true);
@@ -469,7 +470,7 @@
     TRACE_SERIALIZE (this);
     Charset *dest = c->extend_min (*this);
     if (unlikely (dest == nullptr)) return_trace (false);
-    dest->format.set (format);
+    dest->format = format;
     if (format == 0)
     {
       Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
@@ -479,7 +480,7 @@
       {
 	hb_codepoint_t sid = sid_ranges[i].code;
 	for (int left = (int)sid_ranges[i].glyph; left >= 0; left--)
-	  fmt0->sids[glyph++].set (sid++);
+	  fmt0->sids[glyph++] = sid++;
       }
     }
     else if (format == 1)
@@ -490,8 +491,8 @@
       {
       	if (unlikely (!(sid_ranges[i].glyph <= 0xFF)))
 	  return_trace (false);
-	fmt1->ranges[i].first.set (sid_ranges[i].code);
-	fmt1->ranges[i].nLeft.set (sid_ranges[i].glyph);
+	fmt1->ranges[i].first = sid_ranges[i].code;
+	fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
       }
     }
     else /* format 2 */
@@ -502,8 +503,8 @@
       {
       	if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF)))
 	  return_trace (false);
-	fmt2->ranges[i].first.set (sid_ranges[i].code);
-	fmt2->ranges[i].nLeft.set (sid_ranges[i].glyph);
+	fmt2->ranges[i].first = sid_ranges[i].code;
+	fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
       }
     }
     return_trace (true);
@@ -575,9 +576,9 @@
     TRACE_SERIALIZE (this);
     if (unlikely ((strings.count == 0) || (sidmap.get_count () == 0)))
     {
-      if (!unlikely (c->extend_min (this->count)))
+      if (unlikely (!c->extend_min (this->count)))
 	return_trace (false);
-      count.set (0);
+      count = 0;
       return_trace (true);
     }
 
@@ -598,9 +599,9 @@
   }
 
   /* in parallel to above */
-  unsigned int calculate_serialized_size (unsigned int &offSize /*OUT*/, const remap_t &sidmap) const
+  unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const remap_t &sidmap) const
   {
-    offSize = 0;
+    offSize_ = 0;
     if ((count == 0) || (sidmap.get_count () == 0))
       return count.static_size;
 
@@ -609,8 +610,8 @@
       if (sidmap[i] != CFF_UNDEF_CODE)
 	dataSize += length_at (i);
 
-    offSize = calcOffSize(dataSize);
-    return CFF1Index::calculate_serialized_size (offSize, sidmap.get_count (), dataSize);
+    offSize_ = calcOffSize(dataSize);
+    return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_count (), dataSize);
   }
 };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -27,6 +27,8 @@
 #include "hb-ot-cff2-table.hh"
 #include "hb-cff2-interp-cs.hh"
 
+#ifndef HB_NO_OT_FONT_CFF
+
 using namespace CFF;
 
 struct extents_param_t
@@ -34,10 +36,10 @@
   void init ()
   {
     path_open = false;
-    min_x.set_int (0x7FFFFFFF);
-    min_y.set_int (0x7FFFFFFF);
-    max_x.set_int (-0x80000000);
-    max_y.set_int (-0x80000000);
+    min_x.set_int (INT_MAX);
+    min_y.set_int (INT_MAX);
+    max_x.set_int (INT_MIN);
+    max_y.set_int (INT_MIN);
   }
 
   void start_path ()         { path_open = true; }
@@ -99,6 +101,11 @@
 					   hb_codepoint_t glyph,
 					   hb_glyph_extents_t *extents) const
 {
+#ifdef HB_NO_OT_FONT_CFF
+  /* XXX Remove check when this code moves to .hh file. */
+  return true;
+#endif
+
   if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
 
   unsigned int num_coords;
@@ -134,3 +141,5 @@
 
   return true;
 }
+
+#endif

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -83,21 +83,21 @@
 
   bool serialize (hb_serialize_context_t *c,
 		  const hb_subset_plan_t *plan,
-		  const hb_vector_t<segment_plan> &segments)
+		  const hb_sorted_vector_t<segment_plan> &segments)
   {
     TRACE_SERIALIZE (this);
 
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    this->format.set (4);
-    this->length.set (get_sub_table_size (segments));
+    this->format = 4;
+    this->length = get_sub_table_size (segments);
 
-    this->segCountX2.set (segments.length * 2);
-    this->entrySelector.set (MAX (1u, hb_bit_storage (segments.length)) - 1);
-    this->searchRange.set (2 * (1u << this->entrySelector));
-    this->rangeShift.set (segments.length * 2 > this->searchRange
-			  ? 2 * segments.length - this->searchRange
-			  : 0);
+    this->segCountX2 = segments.length * 2;
+    this->entrySelector = hb_max (1u, hb_bit_storage (segments.length)) - 1;
+    this->searchRange = 2 * (1u << this->entrySelector);
+    this->rangeShift = segments.length * 2 > this->searchRange
+		       ? 2 * segments.length - this->searchRange
+		       : 0;
 
     HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length);
     c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
@@ -110,8 +110,8 @@
 
     for (unsigned int i = 0; i < segments.length; i++)
     {
-      end_count[i].set (segments[i].end_code);
-      start_count[i].set (segments[i].start_code);
+      end_count[i] = segments[i].end_code;
+      start_count[i] = segments[i].start_code;
       if (segments[i].use_delta)
       {
 	hb_codepoint_t cp = segments[i].start_code;
@@ -118,9 +118,9 @@
 	hb_codepoint_t start_gid = 0;
 	if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF))
 	  return_trace (false);
-	id_delta[i].set (start_gid - segments[i].start_code);
+	id_delta[i] = start_gid - segments[i].start_code;
       } else {
-	id_delta[i].set (0);
+	id_delta[i] = 0;
 	unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1;
 	HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints);
 	if (glyph_id_array == nullptr)
@@ -138,15 +138,14 @@
 	// id_range_offset[i]
 	// =
 	// 2 * (glyph_id_array - id_range_offset - i)
-	id_range_offset[i].set (2 * (
-	    glyph_id_array - id_range_offset - i));
+	id_range_offset[i] = 2 * (glyph_id_array - id_range_offset - i);
 	for (unsigned int j = 0; j < num_codepoints; j++)
 	{
 	  hb_codepoint_t cp = segments[i].start_code + j;
-	  hb_codepoint_t new_gid;
+	  hb_codepoint_t new_gid = 0;
 	  if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
 	    return_trace (false);
-	  glyph_id_array[j].set (new_gid);
+	  glyph_id_array[j] = new_gid;
 	}
       }
     }
@@ -154,7 +153,7 @@
     return_trace (true);
   }
 
-  static size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments)
+  static size_t get_sub_table_size (const hb_sorted_vector_t<segment_plan> &segments)
   {
     size_t segment_size = 0;
     for (unsigned int i = 0; i < segments.length; i++)
@@ -177,7 +176,7 @@
   }
 
   static bool create_sub_table_plan (const hb_subset_plan_t *plan,
-				     hb_vector_t<segment_plan> *segments)
+				     hb_sorted_vector_t<segment_plan> *segments)
   {
     segment_plan *segment = nullptr;
     hb_codepoint_t last_gid = 0;
@@ -184,7 +183,7 @@
 
     hb_codepoint_t cp = HB_SET_VALUE_INVALID;
     while (plan->unicodes->next (&cp)) {
-      hb_codepoint_t new_gid;
+      hb_codepoint_t new_gid = 0;
       if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
       {
 	DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
@@ -198,11 +197,11 @@
 	  cp != segment->end_code + 1u)
       {
 	segment = segments->push ();
-	segment->start_code.set (cp);
-	segment->end_code.set (cp);
+	segment->start_code = cp;
+	segment->end_code = cp;
 	segment->use_delta = true;
       } else {
-	segment->end_code.set (cp);
+	segment->end_code = cp;
 	if (last_gid + 1u != new_gid)
 	  // gid's are not consecutive in this segment so delta
 	  // cannot be used.
@@ -216,8 +215,8 @@
     if (segment == nullptr || segment->end_code != 0xFFFF)
     {
       segment = segments->push ();
-      segment->start_code.set (0xFFFF);
-      segment->end_code.set (0xFFFF);
+      segment->start_code = 0xFFFF;
+      segment->end_code = 0xFFFF;
       segment->use_delta = true;
     }
 
@@ -286,7 +285,7 @@
       *glyph = gid;
       return true;
     }
-    static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
+    HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
     {
       return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph);
     }
@@ -349,7 +348,7 @@
       /* Some broken fonts have too long of a "length" value.
        * If that is the case, just change the value to truncate
        * the subtable at the end of the blob. */
-      uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535,
+      uint16_t new_length = (uint16_t) hb_min ((uintptr_t) 65535,
 					    (uintptr_t) (c->end -
 							 (char *) this));
       if (!c->try_set (&length, new_length))
@@ -479,7 +478,7 @@
   {
     for (unsigned int i = 0; i < this->groups.len; i++) {
       out->add_range (this->groups[i].startCharCode,
-		      MIN ((hb_codepoint_t) this->groups[i].endCharCode,
+		      hb_min ((hb_codepoint_t) this->groups[i].endCharCode,
 			   (hb_codepoint_t) HB_UNICODE_MAX));
     }
   }
@@ -491,12 +490,12 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  const hb_vector_t<CmapSubtableLongGroup> &group_data)
+		  const hb_sorted_vector_t<CmapSubtableLongGroup> &group_data)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
     if (unlikely (!groups.serialize (c, group_data.as_array ()))) return_trace (false);
-    return true;
+    return_trace (true);
   }
 
   protected:
@@ -519,30 +518,31 @@
 
 
   bool serialize (hb_serialize_context_t *c,
-		  const hb_vector_t<CmapSubtableLongGroup> &groups)
+		  const hb_sorted_vector_t<CmapSubtableLongGroup> &groups_data)
   {
-    if (unlikely (!c->extend_min (*this))) return false;
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    this->format.set (12);
-    this->reserved.set (0);
-    this->length.set (get_sub_table_size (groups));
+    this->format = 12;
+    this->reserved = 0;
+    this->length = get_sub_table_size (groups_data);
 
-    return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups);
+    return_trace (CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups_data));
   }
 
-  static size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups)
+  static size_t get_sub_table_size (const hb_sorted_vector_t<CmapSubtableLongGroup> &groups_data)
   {
-    return 16 + 12 * groups.length;
+    return 16 + 12 * groups_data.length;
   }
 
   static bool create_sub_table_plan (const hb_subset_plan_t *plan,
-				     hb_vector_t<CmapSubtableLongGroup> *groups)
+				     hb_sorted_vector_t<CmapSubtableLongGroup> *groups_out)
   {
     CmapSubtableLongGroup *group = nullptr;
 
     hb_codepoint_t cp = HB_SET_VALUE_INVALID;
     while (plan->unicodes->next (&cp)) {
-      hb_codepoint_t new_gid;
+      hb_codepoint_t new_gid = 0;
       if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
       {
 	DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
@@ -551,17 +551,17 @@
 
       if (!group || !_is_gid_consecutive (group, cp, new_gid))
       {
-	group = groups->push ();
-	group->startCharCode.set (cp);
-	group->endCharCode.set (cp);
-	group->glyphID.set (new_gid);
+	group = groups_out->push ();
+	group->startCharCode = cp;
+	group->endCharCode = cp;
+	group->glyphID = new_gid;
       }
-      else group->endCharCode.set (cp);
+      else group->endCharCode = cp;
     }
 
     DEBUG_MSG(SUBSET, nullptr, "cmap");
-    for (unsigned int i = 0; i < groups->length; i++) {
-      CmapSubtableLongGroup& group = (*groups)[i];
+    for (unsigned int i = 0; i < groups_out->length; i++) {
+      CmapSubtableLongGroup& group = (*groups_out)[i];
       DEBUG_MSG(SUBSET, nullptr, "  %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode));
     }
 
@@ -623,7 +623,7 @@
     for (unsigned int i = 0; i < count; i++)
     {
       hb_codepoint_t first = arrayZ[i].startUnicodeValue;
-      hb_codepoint_t last = MIN ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
+      hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
 				 (hb_codepoint_t) HB_UNICODE_MAX);
       out->add_range (first, last);
     }
@@ -853,8 +853,8 @@
 	  +  CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
     }
 
-    hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
-    hb_vector_t<CmapSubtableLongGroup> format12_groups;
+    hb_sorted_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
+    hb_sorted_vector_t<CmapSubtableLongGroup> format12_groups;
   };
 
   bool _create_plan (const hb_subset_plan_t *plan,
@@ -863,6 +863,7 @@
     if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
       return false;
 
+    if (!find_subtable (12)) return true;
     return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
   }
 
@@ -879,33 +880,35 @@
       return false;
     }
 
-    table->version.set (0);
+    table->version = 0;
 
-    if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ 3)))
-      return false;
+    if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ cmap_subset_plan.format12_groups ? 3 : 2))) return false;
 
     // TODO(grieger): Convert the below to a for loop
 
     // Format 4, Plat 0 Encoding Record
     EncodingRecord &format4_plat0_rec = table->encodingRecord[0];
-    format4_plat0_rec.platformID.set (0); // Unicode
-    format4_plat0_rec.encodingID.set (3);
+    format4_plat0_rec.platformID = 0; // Unicode
+    format4_plat0_rec.encodingID = 3;
 
     // Format 4, Plat 3 Encoding Record
     EncodingRecord &format4_plat3_rec = table->encodingRecord[1];
-    format4_plat3_rec.platformID.set (3); // Windows
-    format4_plat3_rec.encodingID.set (1); // Unicode BMP
+    format4_plat3_rec.platformID = 3; // Windows
+    format4_plat3_rec.encodingID = 1; // Unicode BMP
 
     // Format 12 Encoding Record
-    EncodingRecord &format12_rec = table->encodingRecord[2];
-    format12_rec.platformID.set (3); // Windows
-    format12_rec.encodingID.set (10); // Unicode UCS-4
+    if (cmap_subset_plan.format12_groups)
+    {
+      EncodingRecord &format12_rec = table->encodingRecord[2];
+      format12_rec.platformID = 3; // Windows
+      format12_rec.encodingID = 10; // Unicode UCS-4
+    }
 
     // Write out format 4 sub table
     {
       CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table);
-      format4_plat3_rec.subtable.set (format4_plat0_rec.subtable);
-      subtable.u.format.set (4);
+      format4_plat3_rec.subtable = (unsigned int) format4_plat0_rec.subtable;
+      subtable.u.format = 4;
 
       CmapSubtableFormat4 &format4 = subtable.u.format4;
       if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments)))
@@ -913,9 +916,11 @@
     }
 
     // Write out format 12 sub table.
+    if (cmap_subset_plan.format12_groups)
     {
+      EncodingRecord &format12_rec = table->encodingRecord[2];
       CmapSubtable &subtable = format12_rec.subtable.serialize (&c, table);
-      subtable.u.format.set (12);
+      subtable.u.format = 12;
 
       CmapSubtableFormat12 &format12 = subtable.u.format12;
       if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
@@ -1096,9 +1101,9 @@
 					      hb_codepoint_t *glyph);
 
     template <typename Type>
-    static bool get_glyph_from (const void *obj,
-				hb_codepoint_t codepoint,
-				hb_codepoint_t *glyph)
+    HB_INTERNAL static bool get_glyph_from (const void *obj,
+					    hb_codepoint_t codepoint,
+					    hb_codepoint_t *glyph)
     {
       const Type *typed_obj = (const Type *) obj;
       return typed_obj->get_glyph (codepoint, glyph);
@@ -1105,9 +1110,9 @@
     }
 
     template <typename Type>
-    static bool get_glyph_from_symbol (const void *obj,
-					      hb_codepoint_t codepoint,
-					      hb_codepoint_t *glyph)
+    HB_INTERNAL static bool get_glyph_from_symbol (const void *obj,
+						   hb_codepoint_t codepoint,
+						   hb_codepoint_t *glyph)
     {
       const Type *typed_obj = (const Type *) obj;
       if (likely (typed_obj->get_glyph (codepoint, glyph)))
@@ -1144,8 +1149,8 @@
 				     unsigned int encoding_id) const
   {
     EncodingRecord key;
-    key.platformID.set (platform_id);
-    key.encodingID.set (encoding_id);
+    key.platformID = platform_id;
+    key.encodingID = encoding_id;
 
     const EncodingRecord &result = encodingRecord.bsearch (key);
     if (!result.subtable)
@@ -1154,6 +1159,18 @@
     return &(this+result.subtable);
   }
 
+  bool find_subtable (unsigned format) const
+  {
+    auto it =
+    + hb_iter (encodingRecord)
+    | hb_map (&EncodingRecord::subtable)
+    | hb_map (hb_add (this))
+    | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == format; })
+    ;
+
+    return it.len ();
+  }
+
   public:
 
   bool sanitize (hb_sanitize_context_t *c) const

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -144,7 +144,7 @@
   }
 
   IndexSubtableHeader	header;
-  UnsizedArrayOf<Offset<OffsetType> >
+  UnsizedArrayOf<Offset<OffsetType>>
  			offsetArrayZ;
   public:
   DEFINE_SIZE_ARRAY(8, offsetArrayZ);
@@ -349,15 +349,15 @@
     if (unlikely (!count))
       return Null(BitmapSizeTable);
 
-    unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem);
+    unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
     if (!requested_ppem)
       requested_ppem = 1<<30; /* Choose largest strike. */
     unsigned int best_i = 0;
-    unsigned int best_ppem = MAX (sizeTables[0].ppemX, sizeTables[0].ppemY);
+    unsigned int best_ppem = hb_max (sizeTables[0].ppemX, sizeTables[0].ppemY);
 
     for (unsigned int i = 1; i < count; i++)
     {
-      unsigned int ppem = MAX (sizeTables[i].ppemX, sizeTables[i].ppemY);
+      unsigned int ppem = hb_max (sizeTables[i].ppemX, sizeTables[i].ppemY);
       if ((requested_ppem <= ppem && ppem < best_ppem) ||
 	  (requested_ppem > best_ppem && ppem > best_ppem))
       {
@@ -442,12 +442,12 @@
       }
 
       /* Convert to font units. */
-      double x_scale = upem / (double) strike.ppemX;
-      double y_scale = upem / (double) strike.ppemY;
-      extents->x_bearing = round (extents->x_bearing * x_scale);
-      extents->y_bearing = round (extents->y_bearing * y_scale);
-      extents->width = round (extents->width * x_scale);
-      extents->height = round (extents->height * y_scale);
+      float x_scale = upem / (float) strike.ppemX;
+      float y_scale = upem / (float) strike.ppemY;
+      extents->x_bearing = roundf (extents->x_bearing * x_scale);
+      extents->y_bearing = roundf (extents->y_bearing * y_scale);
+      extents->width = roundf (extents->width * x_scale);
+      extents->height = roundf (extents->height * y_scale);
 
       return true;
     }

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -125,9 +125,9 @@
   protected:
   HBUINT16	version;	/* Table version number (starts at 0). */
   HBUINT16	numBaseGlyphs;	/* Number of Base Glyph Records. */
-  LNNOffsetTo<SortedUnsizedArrayOf<BaseGlyphRecord> >
+  LNNOffsetTo<SortedUnsizedArrayOf<BaseGlyphRecord>>
 		baseGlyphsZ;	/* Offset to Base Glyph records. */
-  LNNOffsetTo<UnsizedArrayOf<LayerRecord> >
+  LNNOffsetTo<UnsizedArrayOf<LayerRecord>>
 		layersZ;	/* Offset to Layer Records. */
   HBUINT16	numLayers;	/* Number of Layer Records. */
   public:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -87,15 +87,15 @@
   }
 
   protected:
-  LNNOffsetTo<UnsizedArrayOf<HBUINT32> >
+  LNNOffsetTo<UnsizedArrayOf<HBUINT32>>
 		paletteFlagsZ;		/* Offset from the beginning of CPAL table to
 					 * the Palette Type Array. Set to 0 if no array
 					 * is provided. */
-  LNNOffsetTo<UnsizedArrayOf<NameID> >
+  LNNOffsetTo<UnsizedArrayOf<NameID>>
 		paletteLabelsZ;		/* Offset from the beginning of CPAL table to
 					 * the palette labels array. Set to 0 if no
 					 * array is provided. */
-  LNNOffsetTo<UnsizedArrayOf<NameID> >
+  LNNOffsetTo<UnsizedArrayOf<NameID>>
 		colorLabelsZ;		/* Offset from the beginning of CPAL table to
 					 * the color labels array. Set to 0
 					 * if no array is provided. */
@@ -144,7 +144,7 @@
     {
       hb_array_t<const BGRAColor> segment_colors = palette_colors.sub_array (start_offset, *color_count);
       /* Always return numColors colors per palette even if it has out-of-bounds start index. */
-      unsigned int count = MIN<unsigned int> (MAX<int> (numColors - start_offset, 0), *color_count);
+      unsigned int count = hb_min ((unsigned) hb_max ((int) (numColors - start_offset), 0), *color_count);
       *color_count = count;
       for (unsigned int i = 0; i < count; i++)
         colors[i] = segment_colors[i]; /* Bound-checked read. */
@@ -176,7 +176,7 @@
   HBUINT16	numPalettes;		/* Number of palettes in the table. */
   HBUINT16	numColorRecords;	/* Total number of color records, combined for
 					 * all palettes. */
-  LNNOffsetTo<UnsizedArrayOf<BGRAColor> >
+  LNNOffsetTo<UnsizedArrayOf<BGRAColor>>
 		colorRecordsZ;		/* Offset from the beginning of CPAL table to
 					 * the first ColorRecord. */
   UnsizedArrayOf<HBUINT16>

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -121,7 +121,7 @@
   HBUINT16	resolution;	/* The device pixel density (in PPI) for which this
 				 * strike was designed. (E.g., 96 PPI, 192 PPI.) */
   protected:
-  UnsizedArrayOf<LOffsetTo<SBIXGlyph> >
+  UnsizedArrayOf<LOffsetTo<SBIXGlyph>>
 		imageOffsetsZ;	/* Offset from the beginning of the strike data header
 				 * to bitmap data for an individual glyph ID. */
   public:
@@ -175,7 +175,7 @@
       if (unlikely (!count))
         return Null(SBIXStrike);
 
-      unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem);
+      unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
       if (!requested_ppem)
         requested_ppem = 1<<30; /* Choose largest strike. */
       /* TODO Add DPI sensitivity as well? */
@@ -242,11 +242,11 @@
       /* Convert to font units. */
       if (strike_ppem)
       {
-	double scale = font->face->get_upem () / (double) strike_ppem;
-	extents->x_bearing = round (extents->x_bearing * scale);
-	extents->y_bearing = round (extents->y_bearing * scale);
-	extents->width = round (extents->width * scale);
-	extents->height = round (extents->height * scale);
+	float scale = font->face->get_upem () / (float) strike_ppem;
+	extents->x_bearing = roundf (extents->x_bearing * scale);
+	extents->y_bearing = roundf (extents->y_bearing * scale);
+	extents->width = roundf (extents->width * scale);
+	extents->height = roundf (extents->height * scale);
       }
 
       hb_blob_destroy (blob);

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -62,7 +62,7 @@
 				 * this index entry. */
   HBUINT16	endGlyphID;	/* The last glyph ID in the range described by
 				 * this index entry. Must be >= startGlyphID. */
-  LNNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  LNNOffsetTo<UnsizedArrayOf<HBUINT8>>
 		svgDoc;		/* Offset from the beginning of the SVG Document Index
 				 * to an SVG document. Must be non-zero. */
   HBUINT32	svgDocLength;	/* Length of the SVG document.
@@ -107,7 +107,7 @@
 
   protected:
   HBUINT16	version;	/* Table version (starting at 0). */
-  LOffsetTo<SortedArrayOf<SVGDocumentIndexEntry> >
+  LOffsetTo<SortedArrayOf<SVGDocumentIndexEntry>>
 		svgDocEntries;	/* Offset (relative to the start of the SVG table) to the
 				 * SVG Documents Index. Must be non-zero. */
 				/* Array of SVG Document Index Entries. */

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -47,6 +47,8 @@
  * @include: hb-ot.h
  *
  * Functions for fetching color-font information from OpenType font faces.
+ *
+ * HarfBuzz supports `COLR`/`CPAL`, `sbix`, `CBDT`, and `SVG` color fonts.
  **/
 
 
@@ -57,42 +59,54 @@
 
 /**
  * hb_ot_color_has_palettes:
- * @face: a font face.
+ * @face: #hb_face_t to work upon
  *
- * Returns: whether CPAL table is available.
+ * Tests whether a face includes a `CPAL` color-palette table.
  *
+ * Return value: true if data found, false otherwise
+ *
  * Since: 2.1.0
  */
 hb_bool_t
 hb_ot_color_has_palettes (hb_face_t *face)
 {
+#ifdef HB_NO_COLOR
+  return false;
+#endif
   return face->table.CPAL->has_data ();
 }
 
 /**
  * hb_ot_color_palette_get_count:
- * @face: a font face.
+ * @face: #hb_face_t to work upon
  *
- * Returns: the number of color palettes in @face, or zero if @face has
- * no colors.
+ * Fetches the number of color palettes in a face.
  *
+ * Return value: the number of palettes found
+ *
  * Since: 2.1.0
  */
 unsigned int
 hb_ot_color_palette_get_count (hb_face_t *face)
 {
+#ifdef HB_NO_COLOR
+  return 0;
+#endif
   return face->table.CPAL->get_palette_count ();
 }
 
 /**
  * hb_ot_color_palette_get_name_id:
- * @face:    a font face.
- * @palette_index: the index of the color palette whose name is being requested.
+ * @face: #hb_face_t to work upon
+ * @palette_index: The index of the color palette 
  *
- * Retrieves the name id of a color palette. For example, a color font can
- * have themed palettes like "Spring", "Summer", "Fall", and "Winter".
+ * Fetches the `name` table Name ID that provides display names for
+ * a `CPAL` color palette. 
  *
- * Returns: an identifier within @face's `name` table.
+ * 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. 
  * If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID.
  *
  * Since: 2.1.0
@@ -101,16 +115,25 @@
 hb_ot_color_palette_get_name_id (hb_face_t *face,
 				 unsigned int palette_index)
 {
+#ifdef HB_NO_COLOR
+  return HB_OT_NAME_ID_INVALID;
+#endif
   return face->table.CPAL->get_palette_name_id (palette_index);
 }
 
 /**
  * hb_ot_color_palette_color_get_name_id:
- * @face:        a font face.
- * @color_index: palette entry index.
+ * @face: #hb_face_t to work upon
+ * @color_index: The index of the color
  *
- * Returns: Name ID associated with a palette entry, e.g. eye color
+ * Fetches the `name` table Name ID that provides display names for
+ * the specificed color in a face's `CPAL` color palette. 
  *
+ * Display names can be generic (e.g., "Background") or specific
+ * (e.g., "Eye color").
+ *
+ * Return value: the Name ID found for the color.
+ *
  * Since: 2.1.0
  */
 hb_ot_name_id_t
@@ -117,16 +140,21 @@
 hb_ot_color_palette_color_get_name_id (hb_face_t *face,
 				       unsigned int color_index)
 {
+#ifdef HB_NO_COLOR
+  return HB_OT_NAME_ID_INVALID;
+#endif
   return face->table.CPAL->get_color_name_id (color_index);
 }
 
 /**
  * hb_ot_color_palette_get_flags:
- * @face:          a font face
- * @palette_index: the index of the color palette whose flags are being requested
+ * @face: #hb_face_t to work upon
+ * @palette_index: The index of the color palette
  *
- * Returns: the flags for the requested color palette.
+ * Fetches the flags defined for a color palette.
  *
+ * Return value: the #hb_ot_color_palette_flags_t of the requested color palette
+ *
  * Since: 2.1.0
  */
 hb_ot_color_palette_flags_t
@@ -133,31 +161,31 @@
 hb_ot_color_palette_get_flags (hb_face_t *face,
 			       unsigned int palette_index)
 {
+#ifdef HB_NO_COLOR
+  return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
+#endif
   return face->table.CPAL->get_palette_flags (palette_index);
 }
 
 /**
  * hb_ot_color_palette_get_colors:
- * @face:         a font face.
- * @palette_index:the index of the color palette whose colors
- *                are being requested.
- * @start_offset: the index of the first color being requested.
- * @color_count:  (inout) (optional): on input, how many colors
- *                can be maximally stored into the @colors array;
- *                on output, how many colors were actually stored.
- * @colors: (array length=color_count) (out) (optional):
- *                an array of #hb_color_t records. After calling
- *                this function, @colors will be filled with
- *                the palette colors. If @colors is NULL, the function
- *                will just return the number of total colors
- *                without storing any actual colors; this can be used
- *                for allocating a buffer of suitable size before calling
- *                hb_ot_color_palette_get_colors() a second time.
+ * @face: #hb_face_t to work upon
+ * @palette_index: the index of the color palette to query
+ * @start_offset: offset of the first color to retrieve
+ * @color_count: (inout) (optional): Input = the maximum number of colors to return;
+ *               Output = the actual number of colors returned (may be zero)
+ * @colors: (out) (array length=color_count) (nullable): The array of #hb_color_t records found
  *
- * Retrieves the colors in a color palette.
+ * Fetches a list of the colors in a color palette.
  *
- * Returns: the total number of colors in the palette.
+ * After calling this function, @colors will be filled with the palette
+ * colors. If @colors is NULL, the function will just return the number
+ * of total colors without storing any actual colors; this can be used
+ * for allocating a buffer of suitable size before calling
+ * hb_ot_color_palette_get_colors() a second time.
  *
+ * Return value: the total number of colors in the palette
+ *
  * Since: 2.1.0
  */
 unsigned int
@@ -167,6 +195,11 @@
 				unsigned int  *colors_count  /* IN/OUT.  May be NULL. */,
 				hb_color_t    *colors        /* OUT.     May be NULL. */)
 {
+#ifdef HB_NO_COLOR
+  if (colors_count)
+    *colors_count = 0;
+  return 0;
+#endif
   return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors);
 }
 
@@ -177,29 +210,37 @@
 
 /**
  * hb_ot_color_has_layers:
- * @face: a font face.
+ * @face: #hb_face_t to work upon
  *
- * Returns: whether COLR table is available.
+ * Tests whether a face includes any `COLR` color layers.
  *
+ * Return value: true if data found, false otherwise
+ *
  * Since: 2.1.0
  */
 hb_bool_t
 hb_ot_color_has_layers (hb_face_t *face)
 {
+#ifdef HB_NO_COLOR
+  return false;
+#endif
   return face->table.COLR->has_data ();
 }
 
 /**
  * hb_ot_color_glyph_get_layers:
- * @face:         a font face.
- * @glyph:        a layered color glyph id.
- * @start_offset: starting offset of layers.
- * @count:  (inout) (optional): gets number of layers available to be written on buffer
- * 				and returns number of written layers.
- * @layers: (array length=count) (out) (optional): layers buffer to buffer.
+ * @face: #hb_face_t to work upon
+ * @glyph: The glyph index to query
+ * @start_offset: offset of the first layer to retrieve
+ * @layer_count: (inout) (optional): Input = the maximum number of layers to return;
+ *         Output = the actual number of layers returned (may be zero)
+ * @layers: (out) (array length=layer_count) (nullable): The array of layers found
  *
- * Returns: Total number of layers a layered color glyph have.
+ * Fetches a list of all color layers for the specified glyph index in the specified
+ * face. The list returned will begin at the offset provided.
  *
+ * Return value: Total number of layers available for the glyph index queried
+ *
  * Since: 2.1.0
  */
 unsigned int
@@ -206,10 +247,15 @@
 hb_ot_color_glyph_get_layers (hb_face_t           *face,
 			      hb_codepoint_t       glyph,
 			      unsigned int         start_offset,
-			      unsigned int        *count, /* IN/OUT.  May be NULL. */
+			      unsigned int        *layer_count, /* IN/OUT.  May be NULL. */
 			      hb_ot_color_layer_t *layers /* OUT.     May be NULL. */)
 {
-  return face->table.COLR->get_glyph_layers (glyph, start_offset, count, layers);
+#ifdef HB_NO_COLOR
+  if (layer_count)
+    *layer_count = 0;
+  return 0;
+#endif
+  return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers);
 }
 
 
@@ -219,11 +265,11 @@
 
 /**
  * hb_ot_color_has_svg:
- * @face: a font face.
+ * @face: #hb_face_t to work upon.
  *
- * Check whether @face has SVG glyph images.
+ * Tests whether a face includes any `SVG` glyph images.
  *
- * Returns true if available, false otherwise.
+ * Return value: true if data found, false otherwise.
  *
  * Since: 2.1.0
  */
@@ -230,17 +276,20 @@
 hb_bool_t
 hb_ot_color_has_svg (hb_face_t *face)
 {
+#ifdef HB_NO_COLOR
+  return false;
+#endif
   return face->table.SVG->has_data ();
 }
 
 /**
  * hb_ot_color_glyph_reference_svg:
- * @face:  a font face.
- * @glyph: a svg glyph index.
+ * @face: #hb_face_t to work upon
+ * @glyph: a svg glyph index
  *
- * Get SVG document for a glyph. The blob may be either plain text or gzip-encoded.
+ * Fetches the SVG document for a glyph. The blob may be either plain text or gzip-encoded.
  *
- * Returns: (transfer full): respective svg blob of the glyph, if available.
+ * Return value: (transfer full): An #hb_blob_t containing the SVG document of the glyph, if available
  *
  * Since: 2.1.0
  */
@@ -247,6 +296,9 @@
 hb_blob_t *
 hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
 {
+#ifdef HB_NO_COLOR
+  return hb_blob_get_empty ();
+#endif
   return face->table.SVG->reference_blob_for_glyph (glyph);
 }
 
@@ -257,11 +309,11 @@
 
 /**
  * hb_ot_color_has_png:
- * @face: a font face.
+ * @face: #hb_face_t to work upon
  *
- * Check whether @face has PNG glyph images (either CBDT or sbix tables).
+ * Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables).
  *
- * Returns true if available, false otherwise.
+ * Return value: true if data found, false otherwise
  *
  * Since: 2.1.0
  */
@@ -268,19 +320,22 @@
 hb_bool_t
 hb_ot_color_has_png (hb_face_t *face)
 {
+#ifdef HB_NO_COLOR
+  return false;
+#endif
   return face->table.CBDT->has_data () || face->table.sbix->has_data ();
 }
 
 /**
  * hb_ot_color_glyph_reference_png:
- * @font:  a font object, not face. upem should be set on
- * 	   that font object if one wants to get optimal png blob, otherwise
- * 	   return the biggest one
- * @glyph: a glyph index.
+ * @font: #hb_font_t to work upon
+ * @glyph: a glyph index
  *
- * Get PNG image for a glyph.
+ * Fetches the PNG image for a glyph. This function takes a font object, not a face object,
+ * 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.
  *
- * Returns: (transfer full): respective PNG blob of the glyph, if available.
+ * Return value: (transfer full): An #hb_blob_t containing the PNG image for the glyph, if available
  *
  * Since: 2.1.0
  */
@@ -287,6 +342,10 @@
 hb_blob_t *
 hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t  glyph)
 {
+#ifdef HB_NO_COLOR
+  return hb_blob_get_empty ();
+#endif
+
   hb_blob_t *blob = hb_blob_get_empty ();
 
   if (font->face->table.sbix->has_data ())

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.h	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.h	2019-05-24 23:03:55 UTC (rev 51218)
@@ -59,11 +59,11 @@
 
 /**
  * hb_ot_color_palette_flags_t:
- * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special
+ * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: Default indicating that there is nothing special
  *   to note about a color palette.
- * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND: flag indicating that the color
+ * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND: Flag indicating that the color
  *   palette is appropriate to use when displaying the font on a light background such as white.
- * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: flag indicating that the color
+ * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: Flag indicating that the color
  *   palette is appropriate to use when displaying the font on a dark background such as black.
  *
  * Since: 2.1.0
@@ -110,7 +110,7 @@
 hb_ot_color_glyph_get_layers (hb_face_t           *face,
 			      hb_codepoint_t       glyph,
 			      unsigned int         start_offset,
-			      unsigned int        *count, /* IN/OUT.  May be NULL. */
+			      unsigned int        *layer_count, /* IN/OUT.  May be NULL. */
 			      hb_ot_color_layer_t *layers /* OUT.     May be NULL. */);
 
 /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -180,15 +180,20 @@
 			 void *user_data HB_UNUSED)
 {
   const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
-  bool ret = ot_face->sbix->get_extents (font, glyph, extents);
-  if (!ret)
-    ret = ot_face->glyf->get_extents (glyph, extents);
-  if (!ret)
-    ret = ot_face->cff1->get_extents (glyph, extents);
-  if (!ret)
-    ret = ot_face->cff2->get_extents (font, glyph, extents);
-  if (!ret)
-    ret = ot_face->CBDT->get_extents (font, glyph, extents);
+  bool ret = false;
+
+#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
+  if (!ret) ret = ot_face->sbix->get_extents (font, glyph, extents);
+#endif
+  if (!ret) ret = ot_face->glyf->get_extents (glyph, extents);
+#ifndef HB_NO_OT_FONT_CFF
+  if (!ret) ret = ot_face->cff1->get_extents (glyph, extents);
+  if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents);
+#endif
+#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
+  if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents);
+#endif
+
   // TODO Hook up side-bearings variations.
   extents->x_bearing = font->em_scale_x (extents->x_bearing);
   extents->y_bearing = font->em_scale_y (extents->y_bearing);

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -21,7 +21,7 @@
  * 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
+ * Google Author(s): Behdad Esfahbod, Garret Rieger, Roderick Sheeter
  */
 
 #ifndef HB_OT_GLYF_TABLE_HH
@@ -29,7 +29,6 @@
 
 #include "hb-open-type.hh"
 #include "hb-ot-head-table.hh"
-#include "hb-subset-glyf.hh"
 
 namespace OT {
 
@@ -58,7 +57,7 @@
   public:
   DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
 			* check the size externally, allow Null() object of it by
-			* defining it MIN() instead. */
+			* defining it _MIN instead. */
 };
 
 
@@ -81,26 +80,169 @@
     return_trace (true);
   }
 
-  bool subset (hb_subset_plan_t *plan) const
+  template<typename Iterator,
+	   hb_requires (hb_is_source_of (Iterator, unsigned int))>
+  static bool
+  _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets)
   {
-    hb_blob_t *glyf_prime = nullptr;
-    hb_blob_t *loca_prime = nullptr;
+    unsigned int max_offset = + padded_offsets | hb_reduce (hb_max, 0);
+    unsigned num_offsets = padded_offsets.len () + 1;
+    bool use_short_loca = max_offset < 0x1FFFF;
+    unsigned entry_size = use_short_loca ? 2 : 4;
+    char *loca_prime_data = (char *) calloc (entry_size, num_offsets);
 
-    bool success = true;
-    bool use_short_loca = false;
-    if (hb_subset_glyf_and_loca (plan, &use_short_loca, &glyf_prime, &loca_prime)) {
-      success = success && plan->add_table (HB_OT_TAG_glyf, glyf_prime);
-      success = success && plan->add_table (HB_OT_TAG_loca, loca_prime);
-      success = success && _add_head_and_set_loca_version (plan, use_short_loca);
-    } else {
-      success = false;
+    if (unlikely (!loca_prime_data)) return false;
+
+    if (use_short_loca)
+      _write_loca (padded_offsets, 1, hb_array ((HBUINT16*) loca_prime_data, num_offsets));
+    else
+      _write_loca (padded_offsets, 0, hb_array ((HBUINT32*) loca_prime_data, num_offsets));
+
+    hb_blob_t * loca_blob = hb_blob_create (loca_prime_data,
+					    entry_size * num_offsets,
+					    HB_MEMORY_MODE_WRITABLE,
+					    loca_prime_data,
+					    free);
+
+    bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
+		  && _add_head_and_set_loca_version(plan, use_short_loca);
+
+    hb_blob_destroy (loca_blob);
+    return result;
+  }
+
+  template<typename IteratorIn, typename IteratorOut,
+	   hb_requires (hb_is_source_of (IteratorIn, unsigned int)),
+	   hb_requires (hb_is_sink_of (IteratorOut, unsigned))>
+  static void
+  _write_loca (IteratorIn it, unsigned right_shift, IteratorOut dest)
+  {
+    unsigned int offset = 0;
+    dest << 0;
+    + it
+    | hb_map ([=, &offset] (unsigned int padded_size) {
+      offset += padded_size;
+      DEBUG_MSG(SUBSET, nullptr, "loca entry offset %d", offset);
+      return offset >> right_shift;
+    })
+    | hb_sink (dest)
+    ;
+  }
+
+  // requires source of SubsetGlyph complains the identifier isn't declared
+  template <typename Iterator>
+  bool serialize(hb_serialize_context_t *c,
+		 Iterator it,
+		 const hb_subset_plan_t *plan)
+  {
+    TRACE_SERIALIZE (this);
+
+    + it
+    | hb_apply ([=] (const SubsetGlyph& _) { _.serialize (c, plan); })
+    ;
+
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+
+    glyf *glyf_prime = c->serializer->start_embed <glyf> ();
+    if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
+
+    // Byte region(s) per glyph to output
+    // unpadded, hints removed if so requested
+    // If we fail to process a glyph we produce an empty (0-length) glyph
+    hb_vector_t<SubsetGlyph> glyphs;
+    _populate_subset_glyphs (c->plan, &glyphs);
+
+    glyf_prime->serialize (c->serializer, hb_iter (glyphs), c->plan);
+
+    auto padded_offsets =
+    + hb_iter (glyphs)
+    | hb_map (&SubsetGlyph::padded_size)
+    ;
+
+    return_trace (c->serializer->check_success (_add_loca_and_head (c->plan, padded_offsets)));
+  }
+
+  template <typename SubsetGlyph>
+  void
+  _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);
+
+    + hb_range (plan->num_output_glyphs ())
+    | hb_map ([&] (hb_codepoint_t new_gid) {
+      SubsetGlyph subset_glyph;
+      subset_glyph.new_gid = new_gid;
+
+      // should never fail: all old gids should be mapped
+      if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) return subset_glyph;
+
+      subset_glyph.source_glyph = glyf.bytes_for_glyph ((const char *) this, subset_glyph.old_gid);
+      if (plan->drop_hints) subset_glyph.drop_hints (glyf);
+      else subset_glyph.dest_start = subset_glyph.source_glyph;
+
+      return subset_glyph;
+    })
+    | hb_sink (glyphs)
+    ;
+
+    glyf.fini();
+  }
+
+  static void
+  _fix_component_gids (const hb_subset_plan_t *plan,
+		       hb_bytes_t glyph)
+  {
+    OT::glyf::CompositeGlyphHeader::Iterator iterator;
+    if (OT::glyf::CompositeGlyphHeader::get_iterator (&glyph,
+						      glyph.length,
+						      &iterator))
+    {
+      do
+      {
+	hb_codepoint_t new_gid;
+	if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
+					&new_gid))
+	  continue;
+	((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex = new_gid;
+      } while (iterator.move_to_next ());
     }
-    hb_blob_destroy (loca_prime);
-    hb_blob_destroy (glyf_prime);
+  }
 
-    return success;
+  static void
+  _zero_instruction_length (hb_bytes_t glyph)
+  {
+    const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
+    int16_t num_contours = (int16_t) glyph_header.numberOfContours;
+    if (num_contours <= 0) return;  // only for simple glyphs
+
+    const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (&glyph, GlyphHeader::static_size + 2 * num_contours);
+    (HBUINT16 &) instruction_length = 0;
   }
 
+  static bool _remove_composite_instruction_flag (hb_bytes_t glyph)
+  {
+    const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
+    if (glyph_header.numberOfContours >= 0) return true;  // only for composites
+
+    /* remove WE_HAVE_INSTRUCTIONS from flags in dest */
+    OT::glyf::CompositeGlyphHeader::Iterator composite_it;
+    if (unlikely (!OT::glyf::CompositeGlyphHeader::get_iterator (&glyph, glyph.length, &composite_it))) return false;
+    const OT::glyf::CompositeGlyphHeader *composite_header;
+    do {
+      composite_header = composite_it.current;
+      OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&composite_header->flags);
+      *flags = (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS;
+    } while (composite_it.move_to_next ());
+    return true;
+}
+
   static bool
   _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
   {
@@ -112,7 +254,7 @@
       return false;
 
     head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
-    head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1);
+    head_prime->indexToLocFormat = use_short_loca ? 0 : 1;
     bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
 
     hb_blob_destroy (head_prime_blob);
@@ -171,6 +313,7 @@
       return size;
     }
 
+    // TODO rewrite using new iterator framework if possible
     struct Iterator
     {
       const char *glyph_start;
@@ -241,7 +384,7 @@
       loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
       glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
 
-      num_glyphs = MAX (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
+      num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
     }
 
     void fini ()
@@ -283,7 +426,7 @@
 
     /* based on FontTools _g_l_y_f.py::trim */
     bool remove_padding (unsigned int start_offset,
-				unsigned int *end_offset) const
+			 unsigned int *end_offset) const
     {
       if (*end_offset - start_offset < GlyphHeader::static_size) return true;
 
@@ -381,25 +524,25 @@
       return true;
     }
 
-    bool get_instruction_offsets (unsigned int start_offset,
-				  unsigned int end_offset,
-				  unsigned int *instruction_start /* OUT */,
-				  unsigned int *instruction_end /* OUT */) const
+    bool get_instruction_length (hb_bytes_t glyph,
+				 unsigned int * length /* OUT */) const
     {
-      if (end_offset - start_offset < GlyphHeader::static_size)
+      /* Empty glyph; no instructions. */
+      if (glyph.length < GlyphHeader::static_size)
       {
-	*instruction_start = 0;
-	*instruction_end = 0;
-	return true; /* Empty glyph; no instructions. */
+	*length = 0;
+	// only 0 byte glyphs are healthy when missing GlyphHeader
+	return glyph.length == 0;
       }
-      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
+      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
       int16_t num_contours = (int16_t) glyph_header.numberOfContours;
       if (num_contours < 0)
       {
+	unsigned int start = glyph.length;
+	unsigned int end = glyph.length;
+	unsigned int glyph_offset = &glyph - glyf_table;
 	CompositeGlyphHeader::Iterator composite_it;
-	if (unlikely (!CompositeGlyphHeader::get_iterator (
-	    (const char*) this->glyf_table + start_offset,
-	     end_offset - start_offset, &composite_it))) return false;
+	if (unlikely (!CompositeGlyphHeader::get_iterator (&glyph, glyph.length, &composite_it))) return false;
 	const CompositeGlyphHeader *last;
 	do {
 	  last = composite_it.current;
@@ -406,36 +549,30 @@
 	} while (composite_it.move_to_next ());
 
 	if ((uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
-	  *instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size ();
-	else
-	  *instruction_start = end_offset;
-	*instruction_end = end_offset;
-	if (unlikely (*instruction_start > *instruction_end))
+	  start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size () - glyph_offset;
+	if (unlikely (start > end))
 	{
-	  DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset);
+	  DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside %d byte buffer", start, glyph.length);
 	  return false;
 	}
+	*length = end - start;
       }
       else
       {
-	unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
-	if (unlikely (instruction_length_offset + 2 > end_offset))
+	unsigned int instruction_length_offset = GlyphHeader::static_size + 2 * num_contours;
+	if (unlikely (instruction_length_offset + 2 > glyph.length))
 	{
 	  DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength.");
 	  return false;
 	}
 
-	const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
-	unsigned int start = instruction_length_offset + 2;
-	unsigned int end = start + (uint16_t) instruction_length;
-	if (unlikely (end > end_offset)) // Out of bounds of the current glyph
+	const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (&glyph, instruction_length_offset);
+	if (unlikely (instruction_length_offset + instruction_length > glyph.length)) // Out of bounds of the current glyph
 	{
 	  DEBUG_MSG(SUBSET, nullptr, "The instructions array overruns the glyph's boundaries.");
 	  return false;
 	}
-
-	*instruction_start = start;
-	*instruction_end = end;
+	*length = (uint16_t) instruction_length;
       }
       return true;
     }
@@ -451,14 +588,33 @@
 
       const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
 
-      extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax);
-      extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax);
-      extents->width     = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
-      extents->height    = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
+      extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax);
+      extents->y_bearing = hb_max (glyph_header.yMin, glyph_header.yMax);
+      extents->width     = hb_max (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
+      extents->height    = hb_min (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
 
       return true;
     }
 
+  hb_bytes_t bytes_for_glyph (const char * glyf, hb_codepoint_t gid)
+  {
+    unsigned int start_offset, end_offset;
+    if (unlikely (!(get_offsets (gid, &start_offset, &end_offset) &&
+      remove_padding (start_offset, &end_offset))))
+    {
+      DEBUG_MSG(SUBSET, nullptr, "Unable to get offset or remove padding for %d", gid);
+      return hb_bytes_t ();
+    }
+    hb_bytes_t glyph = hb_bytes_t (glyf + start_offset, end_offset - start_offset);
+    if (glyph.length == 0) return glyph;
+    if (unlikely (glyph.length < GlyphHeader::static_size))
+    {
+      DEBUG_MSG(SUBSET, nullptr, "Glyph size smaller than minimum header %d", gid);
+      return hb_bytes_t ();
+    }
+    return glyph;
+  }
+
     private:
     bool short_offset;
     unsigned int num_glyphs;
@@ -466,12 +622,99 @@
     hb_blob_ptr_t<glyf> glyf_table;
   };
 
+
+  struct SubsetGlyph
+  {
+    hb_codepoint_t new_gid;
+    hb_codepoint_t old_gid;
+    hb_bytes_t source_glyph;
+    hb_bytes_t dest_start;  // region of source_glyph to copy first
+    hb_bytes_t dest_end;    // region of source_glyph to copy second
+
+
+  bool serialize (hb_serialize_context_t *c,
+		  const hb_subset_plan_t *plan) const
+  {
+    TRACE_SERIALIZE (this);
+
+    hb_bytes_t dest_glyph = dest_start.copy(c);
+    dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy(c).length);
+    unsigned int pad_length = padding ();
+    DEBUG_MSG(SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length  + pad_length, pad_length);
+
+    HBUINT8 pad;
+    pad = 0;
+    while (pad_length > 0)
+    {
+      c->embed(pad);
+      pad_length--;
+    }
+
+    if (dest_glyph.length)
+    {
+      _fix_component_gids (plan, dest_glyph);
+      if (plan->drop_hints)
+      {
+	_zero_instruction_length (dest_glyph);
+	c->check_success (_remove_composite_instruction_flag (dest_glyph));
+      }
+    }
+
+    return_trace (true);
+  }
+
+    void drop_hints (const OT::glyf::accelerator_t& glyf)
+    {
+      if (source_glyph.length == 0) return;
+
+      unsigned int instruction_length = 0;
+      if (!glyf.get_instruction_length (source_glyph, &instruction_length))
+      {
+	 DEBUG_MSG(SUBSET, nullptr, "Unable to read instruction length for new_gid %d", new_gid);
+	return ;
+      }
+
+      const GlyphHeader& header = StructAtOffset<GlyphHeader> (&source_glyph, 0);
+      int16_t num_contours = (int16_t) header.numberOfContours;
+      DEBUG_MSG(SUBSET, nullptr, "new_gid %d (%d contours) drop %d instruction bytes from %d byte source glyph", new_gid, num_contours, instruction_length, source_glyph.length);
+      if (num_contours < 0)
+      {
+	// composite, just chop instructions off the end
+	dest_start = hb_bytes_t (&source_glyph, source_glyph.length - instruction_length);
+      }
+      else
+      {
+	// simple glyph
+	dest_start = hb_bytes_t (&source_glyph, GlyphHeader::static_size + 2 * header.numberOfContours + 2);
+	dest_end = hb_bytes_t (&source_glyph + dest_start.length + instruction_length,
+			       source_glyph.length - dest_start.length - instruction_length);
+DEBUG_MSG(SUBSET, nullptr, "source_len %d start len %d instruction_len %d end len %d", source_glyph.length, dest_start.length, instruction_length, dest_end.length);
+      }
+    }
+
+    unsigned int length () const
+    {
+      return dest_start.length + dest_end.length;
+    }
+
+    // pad to 2 to ensure 2-byte loca will be ok
+    unsigned int padding () const
+    {
+      return length () % 2;
+    }
+
+    unsigned int padded_size () const
+    {
+      return length () + padding ();
+    }
+  };
+
   protected:
   UnsizedArrayOf<HBUINT8>	dataZ;		/* Glyphs data. */
   public:
   DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
 			* check the size externally, allow Null() object of it by
-			* defining it MIN() instead. */
+			* defining it _MIN instead. */
 };
 
 struct glyf_accelerator_t : glyf::accelerator_t {};

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -41,71 +41,31 @@
 
 struct DeviceRecord
 {
-  struct SubsetView
-  {
-    const DeviceRecord *source_device_record;
-    unsigned int sizeDeviceRecord;
-    hb_subset_plan_t *subset_plan;
-
-    void init (const DeviceRecord *source_device_record,
-	       unsigned int sizeDeviceRecord,
-	       hb_subset_plan_t   *subset_plan)
-    {
-      this->source_device_record = source_device_record;
-      this->sizeDeviceRecord = sizeDeviceRecord;
-      this->subset_plan = subset_plan;
-    }
-
-    unsigned int len () const
-    { return this->subset_plan->num_output_glyphs (); }
-
-    const HBUINT8* operator [] (unsigned int new_gid) const
-    {
-      if (unlikely (new_gid >= len ())) return nullptr;
-
-      hb_codepoint_t old_gid;
-      if (!this->subset_plan->old_gid_for_new_gid (new_gid, &old_gid))
-        return &Null(HBUINT8);
-
-      if (old_gid >= sizeDeviceRecord - DeviceRecord::min_size)
-        return nullptr;
-      return &(this->source_device_record->widthsZ[old_gid]);
-    }
-  };
-
-  static unsigned int get_size (unsigned int count)
+  static unsigned int get_size (unsigned count)
   { return hb_ceil_to_4 (min_size + count * HBUINT8::static_size); }
 
-  bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view)
+  template<typename Iterator,
+	   hb_requires (hb_is_iterator (Iterator))>
+  bool serialize (hb_serialize_context_t *c, unsigned pixelSize, Iterator it)
   {
     TRACE_SERIALIZE (this);
 
-    unsigned int size = get_size (subset_view.len ());
-    if (unlikely (!c->allocate_size<DeviceRecord> (size)))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.",
-		 size);
-      return_trace (false);
-    }
+    unsigned length = it.len ();
 
-    this->pixelSize.set (subset_view.source_device_record->pixelSize);
-    this->maxWidth.set (subset_view.source_device_record->maxWidth);
+    if (unlikely (!c->extend (*this, length)))  return_trace (false);
 
-    for (unsigned int i = 0; i < subset_view.len (); i++)
-    {
-      const HBUINT8 *width = subset_view[i];
-      if (!width)
-      {
-	DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i);
-	return_trace (false);
-      }
-      widthsZ[i].set (*width);
-    }
+    this->pixelSize = pixelSize;
+    this->maxWidth =
+    + it
+    | hb_reduce (hb_max, 0u);
 
+    + it
+    | hb_sink (widthsZ.as_array (length));
+
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c, unsigned int sizeDeviceRecord) const
+  bool sanitize (hb_sanitize_context_t *c, unsigned sizeDeviceRecord) const
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
@@ -135,64 +95,65 @@
     return StructAtOffset<DeviceRecord> (&this->firstDeviceRecord, i * sizeDeviceRecord);
   }
 
-  bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
+  template<typename Iterator,
+	   hb_requires (hb_is_iterator (Iterator))>
+  bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it)
   {
     TRACE_SERIALIZE (this);
 
     if (unlikely (!c->extend_min ((*this))))  return_trace (false);
 
-    this->version.set (source_hdmx->version);
-    this->numRecords.set (source_hdmx->numRecords);
-    this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->num_output_glyphs ()));
+    this->version = version;
+    this->numRecords = it.len ();
+    this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0);
 
-    for (unsigned int i = 0; i < source_hdmx->numRecords; i++)
-    {
-      DeviceRecord::SubsetView subset_view;
-      subset_view.init (&(*source_hdmx)[i], source_hdmx->sizeDeviceRecord, plan);
+    + it
+    | hb_apply ([c] (const hb_item_type<Iterator>& _) {
+		  c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second);
+		})
+    ;
 
-      if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view))
-	return_trace (false);
-    }
-
-    return_trace (true);
+    return_trace (c->successful);
   }
 
-  static size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan)
-  {
-    return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->num_output_glyphs ());
-  }
 
-  bool subset (hb_subset_plan_t *plan) const
+  bool subset (hb_subset_context_t *c) const
   {
-    size_t dest_size = get_subsetted_size (this, plan);
-    hdmx *dest = (hdmx *) malloc (dest_size);
-    if (unlikely (!dest))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for hdmx subset output.", (unsigned long) dest_size);
-      return false;
-    }
+    TRACE_SUBSET (this);
 
-    hb_serialize_context_t c (dest, dest_size);
-    hdmx *hdmx_prime = c.start_serialize<hdmx> ();
-    if (!hdmx_prime || !hdmx_prime->serialize (&c, this, plan))
-    {
-      free (dest);
-      DEBUG_MSG(SUBSET, nullptr, "Failed to serialize write new hdmx.");
-      return false;
-    }
-    c.end_serialize ();
+    hdmx *hdmx_prime = c->serializer->start_embed <hdmx> ();
+    if (unlikely (!hdmx_prime)) return_trace (false);
 
-    hb_blob_t *hdmx_prime_blob = hb_blob_create ((const char *) dest,
-						 dest_size,
-						 HB_MEMORY_MODE_READONLY,
-						 dest,
-						 free);
-    bool result = plan->add_table (HB_OT_TAG_hdmx, hdmx_prime_blob);
-    hb_blob_destroy (hdmx_prime_blob);
+    auto it =
+    + hb_range ((unsigned) numRecords)
+    | hb_map ([c, this] (unsigned _)
+	{
+	  const DeviceRecord *device_record =
+	    &StructAtOffset<DeviceRecord> (&firstDeviceRecord,
+					   _ * sizeDeviceRecord);
+	  auto row =
+	    + hb_range (c->plan->num_output_glyphs ())
+	    | hb_map (c->plan->reverse_glyph_map)
+	    | hb_map ([=] (hb_codepoint_t _)
+		      {
+			if (c->plan->is_empty_glyph (_))
+			  return Null(HBUINT8);
+			return device_record->widthsZ.as_array (get_num_glyphs ()) [_];
+		      })
+	    ;
+	  return hb_pair ((unsigned) device_record->pixelSize, +row);
+	})
+    ;
 
-    return result;
+    hdmx_prime->serialize (c->serializer, version, it);
+    return_trace (true);
   }
 
+  unsigned get_num_glyphs () const
+  {
+    return sizeDeviceRecord - DeviceRecord::min_size;
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -78,7 +78,7 @@
 
     unsigned int length;
     H *table = (H *) hb_blob_get_data (dest_blob, &length);
-    table->numberOfLongMetrics.set (num_hmetrics);
+    table->numberOfLongMetrics = num_hmetrics;
 
     bool result = plan->add_table (H::tableTag, dest_blob);
     hb_blob_destroy (dest_blob);
@@ -128,12 +128,12 @@
       bool has_advance = i < num_advances;
       if (has_advance)
       {
-        ((LongMetric *) dest_pos)->advance.set (advance);
-        ((LongMetric *) dest_pos)->sb.set (side_bearing);
+        ((LongMetric *) dest_pos)->advance = advance;
+        ((LongMetric *) dest_pos)->sb = side_bearing;
       }
       else
       {
-        ((FWORD *) dest_pos)->set (side_bearing);
+        *((FWORD *) dest_pos) = side_bearing;
       }
       dest_pos += (has_advance ? 4 : 2);
     }
@@ -240,7 +240,7 @@
 	  return default_advance;
       }
 
-      return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance;
+      return table->longMetricZ[hb_min (glyph, (uint32_t) num_advances - 1)].advance;
     }
 
     unsigned int get_advance (hb_codepoint_t  glyph,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -47,9 +47,9 @@
   int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
     hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
-    hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (kernValue).as_array (glyphCount);
-    hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (leftClass).as_array (glyphCount);
-    hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8> > (rightClass).as_array (leftClassCount * rightClassCount);
+    hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (kernValue).as_array (glyphCount);
+    hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (leftClass).as_array (glyphCount);
+    hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8>> (rightClass).as_array (leftClassCount * rightClassCount);
 
     unsigned int leftC = leftClass[left];
     unsigned int rightC = rightClass[right];
@@ -121,16 +121,20 @@
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
     case 0:	return_trace (c->dispatch (u.format0));
-    case 1:	return_trace (u.header.apple ? c->dispatch (u.format1) : c->default_return_value ());
+#ifndef HB_NO_SHAPE_AAT
+    case 1:	return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ());
+#endif
     case 2:	return_trace (c->dispatch (u.format2));
-    case 3:	return_trace (u.header.apple ? c->dispatch (u.format3) : c->default_return_value ());
+#ifndef HB_NO_SHAPE_AAT
+    case 3:	return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ());
+#endif
     default:	return_trace (c->default_return_value ());
     }
   }
@@ -278,7 +282,9 @@
   {
     switch (get_type ()) {
     case 0: return u.ot.has_state_machine ();
+#ifndef HB_NO_SHAPE_AAT
     case 1: return u.aat.has_state_machine ();
+#endif
     default:return false;
     }
   }
@@ -287,7 +293,9 @@
   {
     switch (get_type ()) {
     case 0: return u.ot.has_cross_stream ();
+#ifndef HB_NO_SHAPE_AAT
     case 1: return u.aat.has_cross_stream ();
+#endif
     default:return false;
     }
   }
@@ -296,7 +304,9 @@
   {
     switch (get_type ()) {
     case 0: return u.ot.get_h_kerning (left, right);
+#ifndef HB_NO_SHAPE_AAT
     case 1: return u.aat.get_h_kerning (left, right);
+#endif
     default:return 0;
     }
   }
@@ -304,14 +314,16 @@
   bool apply (AAT::hb_aat_apply_context_t *c) const
   { return dispatch (c); }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case 0:	return_trace (c->dispatch (u.ot));
-    case 1:	return_trace (c->dispatch (u.aat));
+    case 0:	return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...));
+#ifndef HB_NO_SHAPE_AAT
+    case 1:	return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...));
+#endif
     default:	return_trace (c->default_return_value ());
     }
   }
@@ -328,7 +340,9 @@
   HBUINT32		version32;
   HBUINT16		major;
   KernOT		ot;
+#ifndef HB_NO_SHAPE_AAT
   KernAAT		aat;
+#endif
   } u;
   public:
   DEFINE_SIZE_UNION (4, version32);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -153,7 +153,7 @@
 
 struct FeatMinMaxRecord
 {
-  static int cmp (const void *key_, const void *entry_)
+  HB_INTERNAL static int cmp (const void *key_, const void *entry_)
   {
     hb_tag_t key = * (hb_tag_t *) key_;
     const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_;
@@ -271,7 +271,7 @@
 
 struct BaseLangSysRecord
 {
-  static int cmp (const void *key_, const void *entry_)
+  HB_INTERNAL static int cmp (const void *key_, const void *entry_)
   {
     hb_tag_t key = * (hb_tag_t *) key_;
     const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_;
@@ -345,7 +345,7 @@
 struct BaseScriptList;
 struct BaseScriptRecord
 {
-  static int cmp (const void *key_, const void *entry_)
+  HB_INTERNAL static int cmp (const void *key_, const void *entry_)
   {
     hb_tag_t key = * (hb_tag_t *) key_;
     const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_;
@@ -447,7 +447,7 @@
   }
 
   protected:
-  OffsetTo<SortedArrayOf<Tag> >
+  OffsetTo<SortedArrayOf<Tag>>
 		baseTagList;	/* Offset to BaseTagList table, from beginning
 				 * of Axis table (may be NULL)
 				 * Array of 4-byte baseline identification tags — must

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -66,7 +66,6 @@
 #define NOT_COVERED		((unsigned int) -1)
 
 
-
 /*
  *
  * OpenType Layout Common Table Formats
@@ -104,7 +103,7 @@
 };
 
 template <typename Type>
-struct RecordArrayOf : SortedArrayOf<Record<Type> >
+struct RecordArrayOf : SortedArrayOf<Record<Type>>
 {
   const OffsetTo<Type>& get_offset (unsigned int i) const
   { return (*this)[i].offset; }
@@ -139,7 +138,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct RecordListOf<Type> *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
     unsigned int count = this->len;
     for (unsigned int i = 0; i < count; i++)
@@ -227,13 +226,13 @@
   {
     if (reqFeatureIndex == 0xFFFFu)
       return Index::NOT_FOUND_INDEX;
-   return reqFeatureIndex;;
+   return reqFeatureIndex;
   }
 
-  bool subset (hb_subset_context_t *c) const
+  LangSys* copy (hb_serialize_context_t *c) const
   {
-    TRACE_SUBSET (this);
-    return_trace (c->serializer->embed (*this));
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (*this));
   }
 
   bool sanitize (hb_sanitize_context_t *c,
@@ -278,12 +277,12 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct Script *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
-    out->defaultLangSys.serialize_subset (c, this+defaultLangSys, out);
+    out->defaultLangSys.serialize_copy (c->serializer, this+defaultLangSys, out);
     unsigned int count = langSys.len;
     for (unsigned int i = 0; i < count; i++)
-      out->langSys.arrayZ[i].offset.serialize_subset (c, this+langSys[i].offset, out);
+      out->langSys.arrayZ[i].offset.serialize_copy (c->serializer, this+langSys[i].offset, out);
     return_trace (true);
   }
 
@@ -560,9 +559,9 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct Feature *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
-    out->featureParams.set (0); /* TODO(subset) FeatureParams. */
+    out->featureParams = 0; /* TODO(subset) FeatureParams. */
     return_trace (true);
   }
 
@@ -584,25 +583,25 @@
      * Adobe tools, only the 'size' feature had FeatureParams defined.
      */
 
-    OffsetTo<FeatureParams> orig_offset = featureParams;
+    if (likely (featureParams.is_null ()))
+      return_trace (true);
+
+    unsigned int orig_offset = featureParams;
     if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
       return_trace (false);
 
-    if (likely (orig_offset.is_null ()))
-      return_trace (true);
-
     if (featureParams == 0 && closure &&
 	closure->tag == HB_TAG ('s','i','z','e') &&
 	closure->list_base && closure->list_base < this)
     {
-      unsigned int new_offset_int = (unsigned int) orig_offset -
+      unsigned int new_offset_int = orig_offset -
 				    (((char *) this) - ((char *) closure->list_base));
 
       OffsetTo<FeatureParams> new_offset;
-      /* Check that it did not overflow. */
-      new_offset.set (new_offset_int);
+      /* Check that it would not overflow. */
+      new_offset = new_offset_int;
       if (new_offset == new_offset_int &&
-	  c->try_set (&featureParams, new_offset) &&
+	  c->try_set (&featureParams, new_offset_int) &&
 	  !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
 	return_trace (false);
     }
@@ -649,16 +648,19 @@
   unsigned int get_subtable_count () const { return subTable.len; }
 
   template <typename TSubTable>
-  const TSubTable& get_subtable (unsigned int i) const
-  { return this+CastR<OffsetArrayOf<TSubTable> > (subTable)[i]; }
-
-  template <typename TSubTable>
   const OffsetArrayOf<TSubTable>& get_subtables () const
-  { return CastR<OffsetArrayOf<TSubTable> > (subTable); }
+  { return CastR<OffsetArrayOf<TSubTable>> (subTable); }
   template <typename TSubTable>
   OffsetArrayOf<TSubTable>& get_subtables ()
-  { return CastR<OffsetArrayOf<TSubTable> > (subTable); }
+  { return CastR<OffsetArrayOf<TSubTable>> (subTable); }
 
+  template <typename TSubTable>
+  const TSubTable& get_subtable (unsigned int i) const
+  { return this+get_subtables<TSubTable> ()[i]; }
+  template <typename TSubTable>
+  TSubTable& get_subtable (unsigned int i)
+  { return this+get_subtables<TSubTable> ()[i]; }
+
   unsigned int get_size () const
   {
     const HBUINT16 &markFilteringSet = StructAfter<const HBUINT16> (subTable);
@@ -683,14 +685,14 @@
     return flag;
   }
 
-  template <typename TSubTable, typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename TSubTable, typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int lookup_type = get_type ();
     TRACE_DISPATCH (this, lookup_type);
     unsigned int count = get_subtable_count ();
     for (unsigned int i = 0; i < count; i++) {
-      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type);
+      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, hb_forward<Ts> (ds)...);
       if (c->stop_sublookup_iteration (r))
 	return_trace (r);
     }
@@ -704,40 +706,23 @@
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    lookupType.set (lookup_type);
-    lookupFlag.set (lookup_props & 0xFFFFu);
+    lookupType = lookup_type;
+    lookupFlag = lookup_props & 0xFFFFu;
     if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
     {
       if (unlikely (!c->extend (*this))) return_trace (false);
       HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
-      markFilteringSet.set (lookup_props >> 16);
+      markFilteringSet = lookup_props >> 16;
     }
     return_trace (true);
   }
 
-  /* Older compilers need this to NOT be locally defined in a function. */
   template <typename TSubTable>
-  struct SubTableSubsetWrapper
-  {
-    SubTableSubsetWrapper (const TSubTable &subtable_,
-			   unsigned int lookup_type_) :
-			     subtable (subtable_),
-			     lookup_type (lookup_type_) {}
-
-    bool subset (hb_subset_context_t *c) const
-    { return subtable.dispatch (c, lookup_type); }
-
-    private:
-    const TSubTable &subtable;
-    unsigned int lookup_type;
-  };
-
-  template <typename TSubTable>
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct Lookup *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
 
     /* Subset the actual subtables. */
@@ -747,24 +732,12 @@
     OffsetArrayOf<TSubTable>& out_subtables = out->get_subtables<TSubTable> ();
     unsigned int count = subTable.len;
     for (unsigned int i = 0; i < count; i++)
-    {
-      SubTableSubsetWrapper<TSubTable> wrapper (this+subtables[i], get_type ());
+      out_subtables[i].serialize_subset (c, this+subtables[i], out, get_type ());
 
-      out_subtables[i].serialize_subset (c, wrapper, out);
-    }
-
     return_trace (true);
   }
 
-  /* Older compilers need this to NOT be locally defined in a function. */
   template <typename TSubTable>
-  struct SubTableSanitizeWrapper : TSubTable
-  {
-    bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) const
-    { return this->dispatch (c, lookup_type); }
-  };
-
-  template <typename TSubTable>
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -775,16 +748,21 @@
       if (!markFilteringSet.sanitize (c)) return_trace (false);
     }
 
-    if (unlikely (!CastR<OffsetArrayOf<SubTableSanitizeWrapper<TSubTable> > > (subTable)
-		   .sanitize (c, this, get_type ())))
+    if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
       return_trace (false);
 
-    if (unlikely (get_type () == TSubTable::Extension))
+    if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
     {
       /* The spec says all subtables of an Extension lookup should
        * have the same type, which shall not be the Extension type
        * itself (but we already checked for that).
-       * This is specially important if one has a reverse type! */
+       * This is specially important if one has a reverse type!
+       *
+       * We only do this if sanitizer edit_count is zero.  Otherwise,
+       * some of the subtables might have become insane after they
+       * were sanity-checked by the edits of subsequent subtables.
+       * https://bugs.chromium.org/p/chromium/issues/detail?id=960331
+       */
       unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
       unsigned int count = get_subtable_count ();
       for (unsigned int i = 1; i < count; i++)
@@ -792,7 +770,6 @@
 	  return_trace (false);
     }
     return_trace (true);
-    return_trace (true);
   }
 
   private:
@@ -826,8 +803,9 @@
     return i;
   }
 
-  bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs)
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
     return_trace (glyphArray.serialize (c, glyphs));
@@ -853,19 +831,19 @@
 
   template <typename set_t>
   bool add_coverage (set_t *glyphs) const
-  {
-    return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len);
-  }
+  { return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len); }
 
   public:
   /* Older compilers need this to be public. */
-  struct Iter {
+  struct iter_t
+  {
     void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }
     void fini () {}
-    bool more () { return i < c->glyphArray.len; }
+    bool more () const { return i < c->glyphArray.len; }
     void next () { i++; }
-    hb_codepoint_t get_glyph () { return c->glyphArray[i]; }
-    unsigned int get_coverage () { return i; }
+    hb_codepoint_t get_glyph () const { return c->glyphArray[i]; }
+    bool operator != (const iter_t& o) const
+    { return i != o.i || c != o.c; }
 
     private:
     const struct CoverageFormat1 *c;
@@ -894,38 +872,48 @@
 	   NOT_COVERED;
   }
 
-  bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs)
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    if (unlikely (!glyphs.length))
+    if (unlikely (!glyphs))
     {
-      rangeRecord.len.set (0);
+      rangeRecord.len = 0;
       return_trace (true);
     }
 
-    unsigned int num_ranges = 1;
-    for (unsigned int i = 1; i < glyphs.length; i++)
-      if (glyphs[i - 1] + 1 != glyphs[i])
-	num_ranges++;
-    rangeRecord.len.set (num_ranges);
-    if (unlikely (!c->extend (rangeRecord))) return_trace (false);
+    /* TODO(iter) Write more efficiently? */
 
-    unsigned int range = 0;
-    rangeRecord[range].start = glyphs[0];
-    rangeRecord[range].value.set (0);
-    for (unsigned int i = 1; i < glyphs.length; i++)
+    unsigned num_ranges = 0;
+    hb_codepoint_t last = (hb_codepoint_t) -2;
+    for (auto g: glyphs)
     {
-      if (glyphs[i - 1] + 1 != glyphs[i])
+      if (last + 1 != g)
+        num_ranges++;
+      last = g;
+    }
+
+    if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false);
+
+    unsigned count = 0;
+    unsigned range = (unsigned) -1;
+    last = (hb_codepoint_t) -2;
+    for (auto g: glyphs)
+    {
+      if (last + 1 != g)
       {
-	range++;
-	rangeRecord[range].start = glyphs[i];
-	rangeRecord[range].value.set (i);
+        range++;
+	rangeRecord[range].start = g;
+	rangeRecord[range].value = count;
       }
-      rangeRecord[range].end = glyphs[i];
+      rangeRecord[range].end = g;
+      last = g;
+      count++;
     }
+
     return_trace (true);
   }
 
@@ -972,7 +960,7 @@
 
   public:
   /* Older compilers need this to be public. */
-  struct Iter
+  struct iter_t
   {
     void init (const CoverageFormat2 &c_)
     {
@@ -987,7 +975,7 @@
       }
     }
     void fini () {}
-    bool more () { return i < c->rangeRecord.len; }
+    bool more () const { return i < c->rangeRecord.len; }
     void next ()
     {
       if (j >= c->rangeRecord[i].end)
@@ -995,15 +983,18 @@
 	i++;
 	if (more ())
 	{
-	  hb_codepoint_t old = j;
+	  unsigned int old = coverage;
 	  j = c->rangeRecord[i].start;
-	  if (unlikely (j <= old))
+	  coverage = c->rangeRecord[i].value;
+	  if (unlikely (coverage != old + 1))
 	  {
-	    /* Broken table. Skip. Important to avoid DoS. */
+	    /* Broken table. Skip. Important to avoid DoS.
+	     * Also, our callers depend on coverage being
+	     * consecutive and monotonically increasing,
+	     * ie. iota(). */
 	   i = c->rangeRecord.len;
 	   return;
 	  }
-	  coverage = c->rangeRecord[i].value;
 	}
 	return;
       }
@@ -1010,8 +1001,9 @@
       coverage++;
       j++;
     }
-    hb_codepoint_t get_glyph () { return j; }
-    unsigned int get_coverage () { return coverage; }
+    hb_codepoint_t get_glyph () const { return j; }
+    bool operator != (const iter_t& o) const
+    { return i != o.i || j != o.j || c != o.c; }
 
     private:
     const struct CoverageFormat2 *c;
@@ -1032,6 +1024,15 @@
 
 struct Coverage
 {
+  /* Has interface. */
+  static constexpr unsigned SENTINEL = NOT_COVERED;
+  typedef unsigned int value_t;
+  value_t operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+  /* Predicate. */
+  bool operator () (hb_codepoint_t k) const { return has (k); }
+
+  unsigned int get (hb_codepoint_t k) const { return get_coverage (k); }
   unsigned int get_coverage (hb_codepoint_t glyph_id) const
   {
     switch (u.format) {
@@ -1041,17 +1042,24 @@
     }
   }
 
-  bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs)
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    unsigned int num_ranges = 1;
-    for (unsigned int i = 1; i < glyphs.length; i++)
-      if (glyphs[i - 1] + 1 != glyphs[i])
-	num_ranges++;
-    u.format.set (glyphs.length * 2 < num_ranges * 3 ? 1 : 2);
+    unsigned count = 0;
+    unsigned num_ranges = 0;
+    hb_codepoint_t last = (hb_codepoint_t) -2;
+    for (auto g: glyphs)
+    {
+      if (last + 1 != g)
+        num_ranges++;
+      last = g;
+      count++;
+    }
+    u.format = count * 2 < num_ranges * 3 ? 1 : 2;
 
     switch (u.format)
     {
@@ -1105,9 +1113,10 @@
     }
   }
 
-  struct Iter
+  struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
   {
-    Iter (const Coverage &c_)
+    static constexpr bool is_sorted_iterator = true;
+    iter_t (const Coverage &c_ = Null(Coverage))
     {
       memset (this, 0, sizeof (*this));
       format = c_.u.format;
@@ -1118,7 +1127,7 @@
       default:				     return;
       }
     }
-    bool more ()
+    bool __more__ () const
     {
       switch (format)
       {
@@ -1127,7 +1136,7 @@
       default:return false;
       }
     }
-    void next ()
+    void __next__ ()
     {
       switch (format)
       {
@@ -1136,7 +1145,10 @@
       default:			 break;
       }
     }
-    hb_codepoint_t get_glyph ()
+    typedef hb_codepoint_t __item_t__;
+    __item_t__ __item__ () const { return get_glyph (); }
+
+    hb_codepoint_t get_glyph () const
     {
       switch (format)
       {
@@ -1145,13 +1157,14 @@
       default:return 0;
       }
     }
-    unsigned int get_coverage ()
+    bool operator != (const iter_t& o) const
     {
+      if (format != o.format) return true;
       switch (format)
       {
-      case 1: return u.format1.get_coverage ();
-      case 2: return u.format2.get_coverage ();
-      default:return -1;
+      case 1: return u.format1 != o.u.format1;
+      case 2: return u.format2 != o.u.format2;
+      default:return false;
       }
     }
 
@@ -1158,10 +1171,11 @@
     private:
     unsigned int format;
     union {
-    CoverageFormat2::Iter	format2; /* Put this one first since it's larger; helps shut up compiler. */
-    CoverageFormat1::Iter	format1;
+    CoverageFormat2::iter_t	format2; /* Put this one first since it's larger; helps shut up compiler. */
+    CoverageFormat1::iter_t	format1;
     } u;
   };
+  iter_t iter () const { return iter_t (*this); }
 
   protected:
   union {
@@ -1193,24 +1207,24 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const HBUINT16> glyphs,
+		  hb_array_t<const GlyphID> glyphs,
 		  hb_array_t<const HBUINT16> klasses)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    if (unlikely (!glyphs.length))
+    if (unlikely (!glyphs))
     {
-      startGlyph.set (0);
-      classValue.len.set (0);
+      startGlyph = 0;
+      classValue.len = 0;
       return_trace (true);
     }
 
-    hb_codepoint_t glyph_min = glyphs[0];
-    hb_codepoint_t glyph_max = glyphs[glyphs.length - 1];
+    hb_codepoint_t glyph_min = +glyphs | hb_reduce (hb_min, 0xFFFFu);
+    hb_codepoint_t glyph_max = +glyphs | hb_reduce (hb_max, 0u);
 
-    startGlyph.set (glyph_min);
-    classValue.len.set (glyph_max - glyph_min + 1);
+    startGlyph = glyph_min;
+    c->check_assign (classValue.len, glyph_max - glyph_min + 1);
     if (unlikely (!c->extend (classValue))) return_trace (false);
 
     for (unsigned int i = 0; i < glyphs.length; i++)
@@ -1224,7 +1238,7 @@
     TRACE_SUBSET (this);
     const hb_set_t &glyphset = *c->plan->glyphset ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
-    hb_vector_t<GlyphID> glyphs;
+    hb_sorted_vector_t<GlyphID> glyphs;
     hb_vector_t<HBUINT16> klasses;
 
     hb_codepoint_t start = startGlyph;
@@ -1231,15 +1245,15 @@
     hb_codepoint_t end   = start + classValue.len;
     for (hb_codepoint_t g = start; g < end; g++)
     {
+      if (!glyphset.has (g)) continue;
       unsigned int value = classValue[g - start];
       if (!value) continue;
-      if (!glyphset.has (g)) continue;
-      glyphs.push()->set (glyph_map[g]);
-      klasses.push()->set (value);
+      glyphs.push(glyph_map[g]);
+      klasses.push(value);
     }
     c->serializer->propagate_error (glyphs, klasses);
     ClassDef_serialize (c->serializer, glyphs, klasses);
-    return_trace (glyphs.length);
+    return_trace ((bool) glyphs);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1329,40 +1343,42 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const HBUINT16> glyphs,
+		  hb_array_t<const GlyphID> glyphs,
 		  hb_array_t<const HBUINT16> klasses)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    if (unlikely (!glyphs.length))
+    if (unlikely (!glyphs))
     {
-      rangeRecord.len.set (0);
+      rangeRecord.len = 0;
       return_trace (true);
     }
 
+    unsigned int count = glyphs.len ();
     unsigned int num_ranges = 1;
-    for (unsigned int i = 1; i < glyphs.length; i++)
+    for (unsigned int i = 1; i < count; i++)
       if (glyphs[i - 1] + 1 != glyphs[i] ||
 	  klasses[i - 1] != klasses[i])
 	num_ranges++;
-    rangeRecord.len.set (num_ranges);
+    rangeRecord.len = num_ranges;
     if (unlikely (!c->extend (rangeRecord))) return_trace (false);
 
     unsigned int range = 0;
     rangeRecord[range].start = glyphs[0];
-    rangeRecord[range].value.set (klasses[0]);
-    for (unsigned int i = 1; i < glyphs.length; i++)
+    rangeRecord[range].value = klasses[0];
+    for (unsigned int i = 1; i < count; i++)
     {
       if (glyphs[i - 1] + 1 != glyphs[i] ||
 	  klasses[i - 1] != klasses[i])
       {
+	rangeRecord[range].end = glyphs[i - 1];
 	range++;
 	rangeRecord[range].start = glyphs[i];
 	rangeRecord[range].value = klasses[i];
       }
-      rangeRecord[range].end = glyphs[i];
     }
+    rangeRecord[range].end = glyphs[count - 1];
     return_trace (true);
   }
 
@@ -1384,13 +1400,13 @@
       for (hb_codepoint_t g = start; g < end; g++)
       {
 	if (!glyphset.has (g)) continue;
-	glyphs.push ()->set (glyph_map[g]);
-	klasses.push ()->set (value);
+	glyphs.push (glyph_map[g]);
+	klasses.push (value);
       }
     }
     c->serializer->propagate_error (glyphs, klasses);
     ClassDef_serialize (c->serializer, glyphs, klasses);
-    return_trace (glyphs.length);
+    return_trace ((bool) glyphs);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1468,6 +1484,15 @@
 
 struct ClassDef
 {
+  /* Has interface. */
+  static constexpr unsigned SENTINEL = 0;
+  typedef unsigned int value_t;
+  value_t operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+  /* Projection. */
+  hb_codepoint_t operator () (hb_codepoint_t k) const { return get (k); }
+
+  unsigned int get (hb_codepoint_t k) const { return get_class (k); }
   unsigned int get_class (hb_codepoint_t glyph_id) const
   {
     switch (u.format) {
@@ -1485,13 +1510,14 @@
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
     unsigned int format = 2;
-    if (glyphs.length)
+    if (likely (glyphs))
     {
-      hb_codepoint_t glyph_min = glyphs[0];
-      hb_codepoint_t glyph_max = glyphs[glyphs.length - 1];
+      hb_codepoint_t glyph_min = +glyphs | hb_reduce (hb_min, 0xFFFFu);
+      hb_codepoint_t glyph_max = +glyphs | hb_reduce (hb_max, 0u);
 
+      unsigned int count = glyphs.len ();
       unsigned int num_ranges = 1;
-      for (unsigned int i = 1; i < glyphs.length; i++)
+      for (unsigned int i = 1; i < count; i++)
 	if (glyphs[i - 1] + 1 != glyphs[i] ||
 	    klasses[i - 1] != klasses[i])
 	  num_ranges++;
@@ -1499,7 +1525,7 @@
       if (1 + (glyph_max - glyph_min + 1) < num_ranges * 3)
         format = 1;
     }
-    u.format.set (format);
+    u.format = format;
 
     switch (u.format)
     {
@@ -1975,10 +2001,10 @@
     return (this+record.substitutions).find_substitute (feature_index);
   }
 
-  bool subset (hb_subset_context_t *c) const
+  FeatureVariations* copy (hb_serialize_context_t *c) const
   {
-    TRACE_SUBSET (this);
-    return_trace (c->serializer->embed (*this));
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (*this));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -220,7 +220,7 @@
   {
     if (caret_count)
     {
-      hb_array_t <const OffsetTo<CaretValue> > array = carets.sub_array (start_offset, caret_count);
+      hb_array_t <const OffsetTo<CaretValue>> array = carets.sub_array (start_offset, caret_count);
       unsigned int count = array.length;
       for (unsigned int i = 0; i < count; i++)
 	caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store);
@@ -296,7 +296,7 @@
 
   protected:
   HBUINT16	format;			/* Format identifier--format = 1 */
-  ArrayOf<LOffsetTo<Coverage> >
+  ArrayOf<LOffsetTo<Coverage>>
 		coverage;		/* Array of long offsets to mark set
 					 * coverage tables */
   public:
@@ -439,19 +439,19 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct GDEF *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
 
     out->glyphClassDef.serialize_subset (c, this+glyphClassDef, out);
-    out->attachList.set (0);//TODO(subset) serialize_subset (c, this+attachList, out);
-    out->ligCaretList.set (0);//TODO(subset) serialize_subset (c, this+ligCaretList, out);
+    out->attachList = 0;//TODO(subset) serialize_subset (c, this+attachList, out);
+    out->ligCaretList = 0;//TODO(subset) serialize_subset (c, this+ligCaretList, out);
     out->markAttachClassDef.serialize_subset (c, this+markAttachClassDef, out);
 
     if (version.to_int () >= 0x00010002u)
-      out->markGlyphSetsDef.set (0);// TODO(subset) serialize_subset (c, this+markGlyphSetsDef, out);
+      out->markGlyphSetsDef = 0;// TODO(subset) serialize_subset (c, this+markGlyphSetsDef, out);
 
     if (version.to_int () >= 0x00010003u)
-      out->varStore.set (0);// TODO(subset) serialize_subset (c, this+varStore, out);
+      out->varStore = 0;// TODO(subset) serialize_subset (c, this+varStore, out);
 
     return_trace (true);
   }

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -173,15 +173,15 @@
     return true;
   }
 
-  static OffsetTo<Device>& get_device (Value* value)
-  { return *CastP<OffsetTo<Device> > (value); }
-  static const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
+  HB_INTERNAL static OffsetTo<Device>& get_device (Value* value)
+  { return *CastP<OffsetTo<Device>> (value); }
+  HB_INTERNAL static const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
   {
     if (worked) *worked |= bool (*value);
-    return *CastP<OffsetTo<Device> > (value);
+    return *CastP<OffsetTo<Device>> (value);
   }
 
-  static const HBINT16& get_short (const Value* value, bool *worked=nullptr)
+  HB_INTERNAL static const HBINT16& get_short (const Value* value, bool *worked=nullptr)
   {
     if (worked) *worked |= bool (*value);
     return *CastP<HBINT16> (value);
@@ -393,7 +393,7 @@
 
   HBUINT16	rows;			/* Number of rows */
   protected:
-  UnsizedArrayOf<OffsetTo<Anchor> >
+  UnsizedArrayOf<OffsetTo<Anchor>>
 		matrixZ;		/* Matrix of offsets to Anchor tables--
 					 * from beginning of AnchorMatrix table */
   public:
@@ -446,8 +446,8 @@
     glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
 
     hb_glyph_position_t &o = buffer->cur_pos();
-    o.x_offset = round (base_x - mark_x);
-    o.y_offset = round (base_y - mark_y);
+    o.x_offset = roundf (base_x - mark_x);
+    o.y_offset = roundf (base_y - mark_y);
     o.attach_type() = ATTACH_TYPE_MARK;
     o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
     buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
@@ -576,14 +576,14 @@
 
 struct SinglePos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
-    case 2: return_trace (c->dispatch (u.format2));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -616,7 +616,7 @@
   friend struct PairPosFormat1;
 
   bool intersects (const hb_set_t *glyphs,
-			  const ValueFormat *valueFormats) const
+		   const ValueFormat *valueFormats) const
   {
     unsigned int len1 = valueFormats[0].get_len ();
     unsigned int len2 = valueFormats[1].get_len ();
@@ -722,16 +722,14 @@
 {
   bool intersects (const hb_set_t *glyphs) const
   {
-    unsigned int count = pairSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (glyphs->has (iter.get_glyph ()) &&
-	  (this+pairSet[iter.get_coverage ()]).intersects (glyphs, valueFormat))
-	return true;
-    }
-    return false;
+    return
+    + hb_zip (this+coverage, pairSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map ([=] (const OffsetTo<PairSet> &_)
+	      { return (this+_).intersects (glyphs, valueFormat); })
+    | hb_any
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -909,14 +907,14 @@
 
 struct PairPos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
-    case 2: return_trace (c->dispatch (u.format2));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -995,32 +993,32 @@
     /* Main-direction adjustment */
     switch (c->direction) {
       case HB_DIRECTION_LTR:
-	pos[i].x_advance  = round (exit_x) + pos[i].x_offset;
+	pos[i].x_advance  = roundf (exit_x) + pos[i].x_offset;
 
-	d = round (entry_x) + pos[j].x_offset;
+	d = roundf (entry_x) + pos[j].x_offset;
 	pos[j].x_advance -= d;
 	pos[j].x_offset  -= d;
 	break;
       case HB_DIRECTION_RTL:
-	d = round (exit_x) + pos[i].x_offset;
+	d = roundf (exit_x) + pos[i].x_offset;
 	pos[i].x_advance -= d;
 	pos[i].x_offset  -= d;
 
-	pos[j].x_advance  = round (entry_x) + pos[j].x_offset;
+	pos[j].x_advance  = roundf (entry_x) + pos[j].x_offset;
 	break;
       case HB_DIRECTION_TTB:
-	pos[i].y_advance  = round (exit_y) + pos[i].y_offset;
+	pos[i].y_advance  = roundf (exit_y) + pos[i].y_offset;
 
-	d = round (entry_y) + pos[j].y_offset;
+	d = roundf (entry_y) + pos[j].y_offset;
 	pos[j].y_advance -= d;
 	pos[j].y_offset  -= d;
 	break;
       case HB_DIRECTION_BTT:
-	d = round (exit_y) + pos[i].y_offset;
+	d = roundf (exit_y) + pos[i].y_offset;
 	pos[i].y_advance -= d;
 	pos[i].y_offset  -= d;
 
-	pos[j].y_advance  = round (entry_y);
+	pos[j].y_advance  = roundf (entry_y);
 	break;
       case HB_DIRECTION_INVALID:
       default:
@@ -1094,13 +1092,13 @@
 
 struct CursivePos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1210,13 +1208,13 @@
 
 struct MarkBasePos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1289,7 +1287,7 @@
     unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
     unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
     if (lig_id && lig_id == mark_id && mark_comp > 0)
-      comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
+      comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
     else
       comp_index = comp_count - 1;
 
@@ -1335,13 +1333,13 @@
 
 struct MarkLigPos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1457,13 +1455,13 @@
 
 struct MarkMarkPos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1509,20 +1507,20 @@
     Extension		= 9
   };
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, lookup_type);
     switch (lookup_type) {
-    case Single:		return_trace (u.single.dispatch (c));
-    case Pair:			return_trace (u.pair.dispatch (c));
-    case Cursive:		return_trace (u.cursive.dispatch (c));
-    case MarkBase:		return_trace (u.markBase.dispatch (c));
-    case MarkLig:		return_trace (u.markLig.dispatch (c));
-    case MarkMark:		return_trace (u.markMark.dispatch (c));
-    case Context:		return_trace (u.context.dispatch (c));
-    case ChainContext:		return_trace (u.chainContext.dispatch (c));
-    case Extension:		return_trace (u.extension.dispatch (c));
+    case Single:		return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...));
+    case Pair:			return_trace (u.pair.dispatch (c, hb_forward<Ts> (ds)...));
+    case Cursive:		return_trace (u.cursive.dispatch (c, hb_forward<Ts> (ds)...));
+    case MarkBase:		return_trace (u.markBase.dispatch (c, hb_forward<Ts> (ds)...));
+    case MarkLig:		return_trace (u.markLig.dispatch (c, hb_forward<Ts> (ds)...));
+    case MarkMark:		return_trace (u.markMark.dispatch (c, hb_forward<Ts> (ds)...));
+    case Context:		return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...));
+    case ChainContext:		return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...));
+    case Extension:		return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...));
     default:			return_trace (c->default_return_value ());
     }
   }
@@ -1578,14 +1576,14 @@
     dispatch (&c);
   }
 
-  static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
+  HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
 
   template <typename context_t>
   static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
-  { return Lookup::dispatch<SubTable> (c); }
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
 
   bool subset (hb_subset_context_t *c) const
   { return Lookup::subset<SubTable> (c); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -34,11 +34,13 @@
 
 namespace OT {
 
+typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
 
+template<typename Iterator>
 static inline void SingleSubst_serialize (hb_serialize_context_t *c,
-					  hb_array_t<const GlyphID> glyphs,
-					  hb_array_t<const GlyphID> substitutes);
+					  Iterator it);
 
+
 struct SingleSubstFormat1
 {
   bool intersects (const hb_set_t *glyphs) const
@@ -46,35 +48,28 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      /* TODO Switch to range-based API to work around malicious fonts.
-       * https://github.com/harfbuzz/harfbuzz/issues/363 */
-      hb_codepoint_t glyph_id = iter.get_glyph ();
-      if (c->glyphs->has (glyph_id))
-	c->out->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
-    }
+    unsigned d = deltaGlyphID;
+    + hb_iter (this+coverage)
+    | hb_filter (*c->glyphs)
+    | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+    | hb_sink (c->output)
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      /* TODO Switch to range-based API to work around malicious fonts.
-       * https://github.com/harfbuzz/harfbuzz/issues/363 */
-      hb_codepoint_t glyph_id = iter.get_glyph ();
-      c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
-    }
+    unsigned d = deltaGlyphID;
+    + hb_iter (this+coverage)
+    | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+    | hb_sink (c->output)
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -91,14 +86,17 @@
     return_trace (true);
   }
 
+  template<typename Iterator,
+	   hb_requires (hb_is_sorted_source_of (Iterator,
+						hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs,
-		  int delta)
+		  Iterator glyphs,
+		  unsigned delta)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
     if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false);
-    deltaGlyphID.set (delta); /* TODO(serialize) overflow? */
+    c->check_assign (deltaGlyphID, delta);
     return_trace (true);
   }
 
@@ -105,20 +103,22 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
-    hb_vector_t<GlyphID> from;
-    hb_vector_t<GlyphID> to;
+
     hb_codepoint_t delta = deltaGlyphID;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (!glyphset.has (iter.get_glyph ())) continue;
-      from.push ()->set (glyph_map[iter.get_glyph ()]);
-      to.push ()->set (glyph_map[(iter.get_glyph () + delta) & 0xFFFF]);
-    }
-    c->serializer->propagate_error (from, to);
-    SingleSubst_serialize (c->serializer, from, to);
-    return_trace (from.length);
+
+    auto it =
+    + hb_iter (this+coverage)
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting ([&] (hb_codepoint_t g) {
+				return hb_codepoint_pair_t (glyph_map[g],
+							    glyph_map[(g + delta) & 0xFFFF]); })
+    ;
+
+    bool ret = bool (it);
+    SingleSubst_serialize (c->serializer, it);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -132,8 +132,8 @@
   OffsetTo<Coverage>
 		coverage;		/* Offset to Coverage table--from
 					 * beginning of Substitution table */
-  HBINT16	deltaGlyphID;		/* Add to original GlyphID to get
-					 * substitute GlyphID */
+  HBUINT16	deltaGlyphID;		/* Add to original GlyphID to get
+					 * substitute GlyphID, modulo 0x10000 */
   public:
   DEFINE_SIZE_STATIC (6);
 };
@@ -145,35 +145,26 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = substitute.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-	c->out->add (substitute[iter.get_coverage ()]);
-    }
+    + hb_zip (this+coverage, substitute)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    unsigned int count = substitute.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      c->output->add (substitute[iter.get_coverage ()]);
-    }
+    + hb_zip (this+coverage, substitute)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -188,11 +179,21 @@
     return_trace (true);
   }
 
+  template<typename Iterator,
+	   hb_requires (hb_is_sorted_source_of (Iterator,
+						const hb_codepoint_pair_t))>
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs,
-		  hb_array_t<const GlyphID> substitutes)
+		  Iterator it)
   {
     TRACE_SERIALIZE (this);
+    auto substitutes =
+      + it
+      | hb_map (hb_second)
+      ;
+    auto glyphs =
+      + it
+      | hb_map_retains_sorting (hb_first)
+      ;
     if (unlikely (!c->extend_min (*this))) return_trace (false);
     if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false);
     if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false);
@@ -202,19 +203,19 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
-    hb_vector_t<GlyphID> from;
-    hb_vector_t<GlyphID> to;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (!glyphset.has (iter.get_glyph ())) continue;
-      from.push ()->set (glyph_map[iter.get_glyph ()]);
-      to.push ()->set (glyph_map[substitute[iter.get_coverage ()]]);
-    }
-    c->serializer->propagate_error (from, to);
-    SingleSubst_serialize (c->serializer, from, to);
-    return_trace (from.length);
+
+    auto it =
+    + hb_zip (this+coverage, substitute)
+    | hb_filter (glyphset, hb_first)
+    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const GlyphID &> p) -> hb_codepoint_pair_t
+			      { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
+    ;
+
+    bool ret = bool (it);
+    SingleSubst_serialize (c->serializer, it);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -237,41 +238,45 @@
 
 struct SingleSubst
 {
+
+  template<typename Iterator,
+	   hb_requires (hb_is_sorted_source_of (Iterator,
+						const hb_codepoint_pair_t))>
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs,
-		  hb_array_t<const GlyphID> substitutes)
+		  Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
-    unsigned int format = 2;
-    int delta = 0;
-    if (glyphs.length)
+    unsigned format = 2;
+    unsigned delta = 0;
+    if (glyphs.len ())
     {
       format = 1;
-      /* TODO(serialize) check for wrap-around */
-      delta = substitutes[0] - glyphs[0];
-      for (unsigned int i = 1; i < glyphs.length; i++)
-	if (delta != (int) (substitutes[i] - glyphs[i])) {
-	  format = 2;
-	  break;
-	}
+      auto get_delta = [=] (hb_codepoint_pair_t _) {
+			 return (unsigned) (_.second - _.first) & 0xFFFF;
+		       };
+      delta = get_delta (*glyphs);
+      if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
     }
-    u.format.set (format);
+    u.format = format;
     switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c, glyphs, delta));
-    case 2: return_trace (u.format2.serialize (c, glyphs, substitutes));
+    case 1: return_trace (u.format1.serialize (c,
+					       + glyphs
+					       | hb_map_retains_sorting (hb_first),
+					       delta));
+    case 2: return_trace (u.format2.serialize (c, glyphs));
     default:return_trace (false);
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
-    case 2: return_trace (c->dispatch (u.format2));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -284,11 +289,11 @@
   } u;
 };
 
+template<typename Iterator>
 static inline void
 SingleSubst_serialize (hb_serialize_context_t *c,
-		       hb_array_t<const GlyphID> glyphs,
-		       hb_array_t<const GlyphID> substitutes)
-{ c->start_embed<SingleSubst> ()->serialize (c, glyphs, substitutes); }
+		       Iterator it)
+{ c->start_embed<SingleSubst> ()->serialize (c, it); }
 
 struct Sequence
 {
@@ -296,7 +301,7 @@
   {
     unsigned int count = substitute.len;
     for (unsigned int i = 0; i < count; i++)
-      c->out->add (substitute[i]);
+      c->output->add (substitute[i]);
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -335,10 +340,10 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs)
+		  hb_array_t<const GlyphID> subst)
   {
     TRACE_SERIALIZE (this);
-    return_trace (substitute.serialize (c, glyphs));
+    return_trace (substitute.serialize (c, subst));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -361,31 +366,28 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = sequence.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-	(this+sequence[iter.get_coverage ()]).closure (c);
-    }
+    + hb_zip (this+coverage, sequence)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Sequence &_) { _.closure (c); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    unsigned int count = sequence.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+sequence[i]).collect_glyphs (c);
+    + hb_zip (this+coverage, sequence)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); })
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -398,7 +400,7 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs,
+		  hb_sorted_array_t<const GlyphID> glyphs,
 		  hb_array_t<const unsigned int> substitute_len_list,
 		  hb_array_t<const GlyphID> substitute_glyphs_list)
   {
@@ -444,7 +446,7 @@
 struct MultipleSubst
 {
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs,
+		  hb_sorted_array_t<const GlyphID> glyphs,
 		  hb_array_t<const unsigned int> substitute_len_list,
 		  hb_array_t<const GlyphID> substitute_glyphs_list)
   {
@@ -451,7 +453,7 @@
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
     unsigned int format = 1;
-    u.format.set (format);
+    u.format = format;
     switch (u.format) {
     case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, substitute_glyphs_list));
     default:return_trace (false);
@@ -458,13 +460,13 @@
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -482,7 +484,7 @@
   {
     unsigned int count = alternates.len;
     for (unsigned int i = 0; i < count; i++)
-      c->out->add (alternates[i]);
+      c->output->add (alternates[i]);
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -502,7 +504,7 @@
     unsigned int shift = hb_ctz (lookup_mask);
     unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
 
-    /* If alt_index is MAX, randomize feature if it is the rand feature. */
+    /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */
     if (alt_index == HB_OT_MAP_MAX_VALUE && c->random)
       alt_index = c->random_number () % count + 1;
 
@@ -514,10 +516,10 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs)
+		  hb_array_t<const GlyphID> alts)
   {
     TRACE_SERIALIZE (this);
-    return_trace (alternates.serialize (c, glyphs));
+    return_trace (alternates.serialize (c, alts));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -541,35 +543,27 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = alternateSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-	(this+alternateSet[iter.get_coverage ()]).closure (c);
-    }
+    + hb_zip (this+coverage, alternateSet)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    unsigned int count = alternateSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      (this+alternateSet[iter.get_coverage ()]).collect_glyphs (c);
-    }
+    + hb_zip (this+coverage, alternateSet)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -582,7 +576,7 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs,
+		  hb_sorted_array_t<const GlyphID> glyphs,
 		  hb_array_t<const unsigned int> alternate_len_list,
 		  hb_array_t<const GlyphID> alternate_glyphs_list)
   {
@@ -628,7 +622,7 @@
 struct AlternateSubst
 {
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> glyphs,
+		  hb_sorted_array_t<const GlyphID> glyphs,
 		  hb_array_t<const unsigned int> alternate_len_list,
 		  hb_array_t<const GlyphID> alternate_glyphs_list)
   {
@@ -635,7 +629,7 @@
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
     unsigned int format = 1;
-    u.format.set (format);
+    u.format = format;
     switch (u.format) {
     case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list));
     default:return_trace (false);
@@ -642,13 +636,13 @@
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -668,17 +662,14 @@
     unsigned int count = component.lenP1;
     for (unsigned int i = 1; i < count; i++)
       if (!glyphs->has (component[i]))
-        return false;
+	return false;
     return true;
   }
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = component.lenP1;
-    for (unsigned int i = 1; i < count; i++)
-      if (!c->glyphs->has (component[i]))
-        return;
-    c->out->add (ligGlyph);
+    if (!intersects (c->glyphs)) return;
+    c->output->add (ligGlyph);
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -689,15 +680,14 @@
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
     if (c->len != component.lenP1)
-      return_trace (false);
+      return false;
 
     for (unsigned int i = 1; i < c->len; i++)
       if (likely (c->glyphs[i] != component[i]))
-	return_trace (false);
+	return false;
 
-    return_trace (true);
+    return true;
   }
 
   bool apply (hb_ot_apply_context_t *c) const
@@ -771,38 +761,38 @@
 {
   bool intersects (const hb_set_t *glyphs) const
   {
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-      if ((this+ligature[i]).intersects (glyphs))
-        return true;
-    return false;
+    return
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-      (this+ligature[i]).closure (c);
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Ligature &_) { _.closure (c); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-      (this+ligature[i]).collect_glyphs (c);
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-    {
-      const Ligature &lig = this+ligature[i];
-      if (lig.would_apply (c))
-        return_trace (true);
-    }
-    return_trace (false);
+    return
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
+    | hb_any
+    ;
   }
 
   bool apply (hb_ot_apply_context_t *c) const
@@ -828,7 +818,7 @@
     if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false);
     for (unsigned int i = 0; i < ligatures.length; i++)
     {
-      unsigned int component_count = MAX<int> (component_count_list[i] - 1, 0);
+      unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0);
       if (unlikely (!ligature[i].serialize (c, this)
 				.serialize (c,
 					    ligatures[i],
@@ -857,40 +847,35 @@
 {
   bool intersects (const hb_set_t *glyphs) const
   {
-    unsigned int count = ligatureSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (glyphs->has (iter.get_glyph ()) &&
-	  (this+ligatureSet[iter.get_coverage ()]).intersects (glyphs))
-        return true;
-    }
-    return false;
+    return
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map ([this, glyphs] (const OffsetTo<LigatureSet> &_)
+	      { return (this+_).intersects (glyphs); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = ligatureSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-	(this+ligatureSet[iter.get_coverage ()]).closure (c);
-    }
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    unsigned int count = ligatureSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
-    }
+
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); })
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -897,12 +882,11 @@
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return false;
 
     const LigatureSet &lig_set = this+ligatureSet[index];
-    return_trace (lig_set.would_apply (c));
+    return lig_set.would_apply (c);
   }
 
   bool apply (hb_ot_apply_context_t *c) const
@@ -917,7 +901,7 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> first_glyphs,
+		  hb_sorted_array_t<const GlyphID> first_glyphs,
 		  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
 		  hb_array_t<const GlyphID> ligatures_list,
 		  hb_array_t<const unsigned int> component_count_list,
@@ -968,7 +952,7 @@
 struct LigatureSubst
 {
   bool serialize (hb_serialize_context_t *c,
-		  hb_array_t<const GlyphID> first_glyphs,
+		  hb_sorted_array_t<const GlyphID> first_glyphs,
 		  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
 		  hb_array_t<const GlyphID> ligatures_list,
 		  hb_array_t<const unsigned int> component_count_list,
@@ -977,7 +961,7 @@
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
     unsigned int format = 1;
-    u.format.set (format);
+    u.format = format;
     switch (u.format) {
     case 1: return_trace (u.format1.serialize (c,
 					       first_glyphs,
@@ -989,13 +973,13 @@
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1027,7 +1011,7 @@
     if (!(this+coverage).intersects (glyphs))
       return false;
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     unsigned int count;
 
@@ -1034,12 +1018,12 @@
     count = backtrack.len;
     for (unsigned int i = 0; i < count; i++)
       if (!(this+backtrack[i]).intersects (glyphs))
-        return false;
+	return false;
 
     count = lookahead.len;
     for (unsigned int i = 0; i < count; i++)
       if (!(this+lookahead[i]).intersects (glyphs))
-        return false;
+	return false;
 
     return true;
   }
@@ -1046,29 +1030,16 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    if (!intersects (c->glyphs)) return;
 
-    unsigned int count;
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
 
-    count = backtrack.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!(this+backtrack[i]).intersects (c->glyphs))
-        return;
-
-    count = lookahead.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!(this+lookahead[i]).intersects (c->glyphs))
-        return;
-
-    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
-    count = substitute.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-	c->out->add (substitute[iter.get_coverage ()]);
-    }
+    + hb_zip (this+coverage, substitute)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -1081,12 +1052,12 @@
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return;
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     count = lookahead.len;
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
 
-    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
     count = substitute.len;
     c->output->add_array (substitute.arrayZ, substitute.len);
   }
@@ -1094,10 +1065,7 @@
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -1108,8 +1076,8 @@
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
-    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
 
   unsigned int start_index = 0, end_index = 0;
     if (match_backtrack (c,
@@ -1116,7 +1084,7 @@
 			 backtrack.len, (HBUINT16 *) backtrack.arrayZ,
 			 match_coverage, this,
 			 &start_index) &&
-        match_lookahead (c,
+	match_lookahead (c,
 			 lookahead.len, (HBUINT16 *) lookahead.arrayZ,
 			 match_coverage, this,
 			 1, &end_index))
@@ -1144,10 +1112,10 @@
     TRACE_SANITIZE (this);
     if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
       return_trace (false);
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     if (!lookahead.sanitize (c, this))
       return_trace (false);
-    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
     return_trace (substitute.sanitize (c));
   }
 
@@ -1173,13 +1141,13 @@
 
 struct ReverseChainSingleSubst
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1213,19 +1181,19 @@
     ReverseChainSingle	= 8
   };
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, lookup_type);
     switch (lookup_type) {
-    case Single:		return_trace (u.single.dispatch (c));
-    case Multiple:		return_trace (u.multiple.dispatch (c));
-    case Alternate:		return_trace (u.alternate.dispatch (c));
-    case Ligature:		return_trace (u.ligature.dispatch (c));
-    case Context:		return_trace (u.context.dispatch (c));
-    case ChainContext:		return_trace (u.chainContext.dispatch (c));
-    case Extension:		return_trace (u.extension.dispatch (c));
-    case ReverseChainSingle:	return_trace (u.reverseChainContextSingle.dispatch (c));
+    case Single:		return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...));
+    case Multiple:		return_trace (u.multiple.dispatch (c, hb_forward<Ts> (ds)...));
+    case Alternate:		return_trace (u.alternate.dispatch (c, hb_forward<Ts> (ds)...));
+    case Ligature:		return_trace (u.ligature.dispatch (c, hb_forward<Ts> (ds)...));
+    case Context:		return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...));
+    case ChainContext:		return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...));
+    case Extension:		return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...));
+    case ReverseChainSingle:	return_trace (u.reverseChainContextSingle.dispatch (c, hb_forward<Ts> (ds)...));
     default:			return_trace (c->default_return_value ());
     }
   }
@@ -1253,7 +1221,7 @@
   const SubTable& get_subtable (unsigned int i) const
   { return Lookup::get_subtable<SubTable> (i); }
 
-  static bool lookup_type_is_reverse (unsigned int lookup_type)
+  HB_INTERNAL static bool lookup_type_is_reverse (unsigned int lookup_type)
   { return lookup_type == SubTable::ReverseChainSingle; }
 
   bool is_reverse () const
@@ -1306,13 +1274,12 @@
   bool would_apply (hb_would_apply_context_t *c,
 		    const hb_ot_layout_lookup_accelerator_t *accel) const
   {
-    TRACE_WOULD_APPLY (this);
-    if (unlikely (!c->len))  return_trace (false);
-    if (!accel->may_have (c->glyphs[0]))  return_trace (false);
-      return_trace (dispatch (c));
+    if (unlikely (!c->len)) return false;
+    if (!accel->may_have (c->glyphs[0])) return false;
+      return dispatch (c);
   }
 
-  static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
+  HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
 
   SubTable& serialize_subtable (hb_serialize_context_t *c,
 				       unsigned int i)
@@ -1320,17 +1287,19 @@
 
   bool serialize_single (hb_serialize_context_t *c,
 			 uint32_t lookup_props,
-		         hb_array_t<const GlyphID> glyphs,
-		         hb_array_t<const GlyphID> substitutes)
+			 hb_sorted_array_t<const GlyphID> glyphs,
+			 hb_array_t<const GlyphID> substitutes)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes));
+
+    return_trace (serialize_subtable (c, 0).u.single
+		  .serialize (c, hb_zip (glyphs, substitutes)));
   }
 
   bool serialize_multiple (hb_serialize_context_t *c,
 			   uint32_t lookup_props,
-			   hb_array_t<const GlyphID> glyphs,
+			   hb_sorted_array_t<const GlyphID> glyphs,
 			   hb_array_t<const unsigned int> substitute_len_list,
 			   hb_array_t<const GlyphID> substitute_glyphs_list)
   {
@@ -1344,7 +1313,7 @@
 
   bool serialize_alternate (hb_serialize_context_t *c,
 			    uint32_t lookup_props,
-			    hb_array_t<const GlyphID> glyphs,
+			    hb_sorted_array_t<const GlyphID> glyphs,
 			    hb_array_t<const unsigned int> alternate_len_list,
 			    hb_array_t<const GlyphID> alternate_glyphs_list)
   {
@@ -1358,7 +1327,7 @@
 
   bool serialize_ligature (hb_serialize_context_t *c,
 			   uint32_t lookup_props,
-			   hb_array_t<const GlyphID> first_glyphs,
+			   hb_sorted_array_t<const GlyphID> first_glyphs,
 			   hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
 			   hb_array_t<const GlyphID> ligatures_list,
 			   hb_array_t<const unsigned int> component_count_list,
@@ -1375,12 +1344,12 @@
   }
 
   template <typename context_t>
-  static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+  HB_INTERNAL static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
 
-  static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
+  HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
   {
     if (!c->should_visit_lookup (lookup_index))
-      return HB_VOID;
+      return hb_empty_t ();
 
     hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index);
 
@@ -1392,9 +1361,9 @@
     return ret;
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
-  { return Lookup::dispatch<SubTable> (c); }
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
 
   bool subset (hb_subset_context_t *c) const
   { return Lookup::subset<SubTable> (c); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -59,13 +59,13 @@
 };
 
 struct hb_closure_context_t :
-       hb_dispatch_context_t<hb_closure_context_t, hb_void_t, 0>
+       hb_dispatch_context_t<hb_closure_context_t, hb_empty_t, 0>
 {
   const char *get_name () { return "CLOSURE"; }
   typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
   template <typename T>
-  return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
-  static return_t default_return_value () { return HB_VOID; }
+  return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); }
+  static return_t default_return_value () { return hb_empty_t (); }
   void recurse (unsigned int lookup_index)
   {
     if (unlikely (nesting_level_left == 0 || !recurse_func))
@@ -92,7 +92,7 @@
 
   hb_face_t *face;
   hb_set_t *glyphs;
-  hb_set_t out[1];
+  hb_set_t output[1];
   recurse_func_t recurse_func;
   unsigned int nesting_level_left;
   unsigned int debug_depth;
@@ -114,8 +114,8 @@
 
   void flush ()
   {
-    hb_set_union (glyphs, out);
-    hb_set_clear (out);
+    hb_set_union (glyphs, output);
+    hb_set_clear (output);
   }
 
   private:
@@ -124,7 +124,7 @@
 
 
 struct hb_would_apply_context_t :
-       hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY>
+       hb_dispatch_context_t<hb_would_apply_context_t, bool, 0>
 {
   const char *get_name () { return "WOULD_APPLY"; }
   template <typename T>
@@ -151,13 +151,13 @@
 
 
 struct hb_collect_glyphs_context_t :
-       hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, 0>
+       hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_empty_t, 0>
 {
   const char *get_name () { return "COLLECT_GLYPHS"; }
   typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
   template <typename T>
-  return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
-  static return_t default_return_value () { return HB_VOID; }
+  return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_empty_t (); }
+  static return_t default_return_value () { return hb_empty_t (); }
   void recurse (unsigned int lookup_index)
   {
     if (unlikely (nesting_level_left == 0 || !recurse_func))
@@ -286,7 +286,7 @@
     };
 
     may_match_t may_match (const hb_glyph_info_t &info,
-				  const HBUINT16        *glyph_data) const
+			   const HBUINT16        *glyph_data) const
     {
       if (!(info.mask & mask) ||
 	  (syllable && syllable != info.syllable ()))
@@ -610,10 +610,10 @@
 
 
 struct hb_get_subtables_context_t :
-       hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
+       hb_dispatch_context_t<hb_get_subtables_context_t, hb_empty_t, HB_DEBUG_APPLY>
 {
   template <typename Type>
-  static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
+  HB_INTERNAL static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
   {
     const Type *typed_obj = (const Type *) obj;
     return typed_obj->apply (c);
@@ -652,9 +652,9 @@
   {
     hb_applicable_t *entry = array.push();
     entry->init (obj, apply_to<T>);
-    return HB_VOID;
+    return hb_empty_t ();
   }
-  static return_t default_return_value () { return HB_VOID; }
+  static return_t default_return_value () { return hb_empty_t (); }
 
   hb_get_subtables_context_t (array_t &array_) :
 			      array (array_),
@@ -706,10 +706,11 @@
 				     intersects_func_t intersects_func,
 				     const void *intersects_data)
 {
-  for (unsigned int i = 0; i < count; i++)
-    if (likely (!intersects_func (glyphs, values[i], intersects_data)))
-      return false;
-  return true;
+  return
+  + hb_iter (values, count)
+  | hb_map ([&] (const HBUINT16 &_) { return intersects_func (glyphs, _, intersects_data); })
+  | hb_any
+  ;
 }
 
 
@@ -734,8 +735,10 @@
 				  collect_glyphs_func_t collect_func,
 				  const void *collect_data)
 {
-  for (unsigned int i = 0; i < count; i++)
-    collect_func (glyphs, values[i], collect_data);
+  return
+  + hb_iter (values, count)
+  | hb_apply ([&] (const HBUINT16 &_) { collect_func (glyphs, _, collect_data); })
+  ;
 }
 
 
@@ -846,7 +849,7 @@
 	if (ligbase == LIGBASE_NOT_CHECKED)
 	{
 	  bool found = false;
-	  const hb_glyph_info_t *out = buffer->out_info;
+	  const auto *out = buffer->out_info;
 	  unsigned int j = buffer->out_len;
 	  while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id)
 	  {
@@ -970,7 +973,7 @@
 	if (this_comp == 0)
 	  this_comp = last_num_components;
 	unsigned int new_lig_comp = components_so_far - last_num_components +
-				    MIN (this_comp, last_num_components);
+				    hb_min (this_comp, last_num_components);
 	  _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
       }
       buffer->next_glyph ();
@@ -992,7 +995,7 @@
 	if (!this_comp)
 	  break;
 	unsigned int new_lig_comp = components_so_far - last_num_components +
-				    MIN (this_comp, last_num_components);
+				    hb_min (this_comp, last_num_components);
 	_hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
       } else
 	break;
@@ -1170,7 +1173,7 @@
     else
     {
       /* NOTE: delta is negative. */
-      delta = MAX (delta, (int) next - (int) count);
+      delta = hb_max (delta, (int) next - (int) count);
       next -= delta;
     }
 
@@ -1296,7 +1299,7 @@
 
   void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
   {
-    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord> >
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
 						       (inputZ.as_array ((inputCount ? inputCount - 1 : 0)));
     context_closure_lookup (c,
 			    inputCount, inputZ.arrayZ,
@@ -1307,7 +1310,7 @@
   void collect_glyphs (hb_collect_glyphs_context_t *c,
 		       ContextCollectGlyphsLookupContext &lookup_context) const
   {
-    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord> >
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
 						       (inputZ.as_array (inputCount ? inputCount - 1 : 0));
     context_collect_glyphs_lookup (c,
 				   inputCount, inputZ.arrayZ,
@@ -1318,10 +1321,12 @@
   bool would_apply (hb_would_apply_context_t *c,
 		    ContextApplyLookupContext &lookup_context) const
   {
-    TRACE_WOULD_APPLY (this);
-    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord> >
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
 						       (inputZ.as_array (inputCount ? inputCount - 1 : 0));
-    return_trace (context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
+    return context_would_apply_lookup (c,
+				       inputCount, inputZ.arrayZ,
+				       lookupCount, lookupRecord.arrayZ,
+				       lookup_context);
   }
 
   bool apply (hb_ot_apply_context_t *c,
@@ -1328,7 +1333,7 @@
 	      ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord> >
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
 						       (inputZ.as_array (inputCount ? inputCount - 1 : 0));
     return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
   }
@@ -1364,40 +1369,43 @@
   bool intersects (const hb_set_t *glyphs,
 		   ContextClosureLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      if ((this+rule[i]).intersects (glyphs, lookup_context))
-	return true;
-    return false;
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const Rule &_) { return _.intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c,
 		ContextClosureLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      (this+rule[i]).closure (c, lookup_context);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const Rule &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c,
 		       ContextCollectGlyphsLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      (this+rule[i]).collect_glyphs (c, lookup_context);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const Rule &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c,
 		    ContextApplyLookupContext &lookup_context) const
   {
-    TRACE_WOULD_APPLY (this);
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-    {
-      if ((this+rule[i]).would_apply (c, lookup_context))
-	return_trace (true);
-    }
-    return_trace (false);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const Rule &_) { return _.would_apply (c, lookup_context); })
+    | hb_any
+    ;
   }
 
   bool apply (hb_ot_apply_context_t *c,
@@ -1404,13 +1412,13 @@
 	      ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-    {
-      if ((this+rule[i]).apply (c, lookup_context))
-	return_trace (true);
-    }
-    return_trace (false);
+    return_trace (
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
+    | hb_any
+    )
+    ;
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1437,16 +1445,14 @@
       nullptr
     };
 
-    unsigned int count = ruleSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (glyphs->has (iter.get_glyph ()) &&
-	  (this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
-	return true;
-    }
-    return false;
+    return
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const RuleSet &_) { return _.intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
@@ -1456,14 +1462,12 @@
       nullptr
     };
 
-    unsigned int count = ruleSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-	(this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
-    }
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -1475,21 +1479,20 @@
       nullptr
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
     struct ContextApplyLookupContext lookup_context = {
       {match_glyph},
       nullptr
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return rule_set.would_apply (c, lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -1549,13 +1552,13 @@
       &class_def
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (class_def.intersects_class (glyphs, i) &&
-	  (this+ruleSet[i]).intersects (glyphs, lookup_context))
-	return true;
-
-    return false;
+    return
+    + hb_enumerate (ruleSet)
+    | hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<RuleSet> &> p)
+	      { return class_def.intersects_class (glyphs, p.first) &&
+		       (this+p.second).intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
@@ -1570,12 +1573,15 @@
       &class_def
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (class_def.intersects_class (c->glyphs, i)) {
-	const RuleSet &rule_set = this+ruleSet[i];
-	rule_set.closure (c, lookup_context);
-      }
+    return
+    + hb_enumerate (ruleSet)
+    | hb_filter ([&] (unsigned _)
+		 { return class_def.intersects_class (c->glyphs, _); },
+		 hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -1588,15 +1594,14 @@
       &class_def
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const ClassDef &class_def = this+classDef;
     unsigned int index = class_def.get_class (c->glyphs[0]);
     const RuleSet &rule_set = this+ruleSet[index];
@@ -1604,7 +1609,7 @@
       {match_class},
       &class_def
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return rule_set.would_apply (c, lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -1704,14 +1709,15 @@
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
     struct ContextApplyLookupContext lookup_context = {
       {match_coverage},
       this
     };
-    return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context));
+    return context_would_apply_lookup (c,
+				       glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
+				       lookupCount, lookupRecord,
+				       lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverageZ[0]; }
@@ -1755,7 +1761,7 @@
   HBUINT16	glyphCount;		/* Number of glyphs in the input glyph
 					 * sequence */
   HBUINT16	lookupCount;		/* Number of LookupRecords */
-  UnsizedArrayOf<OffsetTo<Coverage> >
+  UnsizedArrayOf<OffsetTo<Coverage>>
 		coverageZ;		/* Array of offsets to Coverage
 					 * table in glyph sequence order */
 /*UnsizedArrayOf<LookupRecord>
@@ -1767,15 +1773,15 @@
 
 struct Context
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
-    case 2: return_trace (c->dispatch (u.format2));
-    case 3: return_trace (c->dispatch (u.format3));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1927,8 +1933,8 @@
 {
   bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
   {
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
     return chain_context_intersects (glyphs,
 				     backtrack.len, backtrack.arrayZ,
 				     input.lenP1, input.arrayZ,
@@ -1939,9 +1945,9 @@
   void closure (hb_closure_context_t *c,
 		ChainContextClosureLookupContext &lookup_context) const
   {
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     chain_context_closure_lookup (c,
 				  backtrack.len, backtrack.arrayZ,
 				  input.lenP1, input.arrayZ,
@@ -1953,9 +1959,9 @@
   void collect_glyphs (hb_collect_glyphs_context_t *c,
 		       ChainContextCollectGlyphsLookupContext &lookup_context) const
   {
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     chain_context_collect_glyphs_lookup (c,
 					 backtrack.len, backtrack.arrayZ,
 					 input.lenP1, input.arrayZ,
@@ -1967,23 +1973,22 @@
   bool would_apply (hb_would_apply_context_t *c,
 		    ChainContextApplyLookupContext &lookup_context) const
   {
-    TRACE_WOULD_APPLY (this);
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
-    return_trace (chain_context_would_apply_lookup (c,
-						    backtrack.len, backtrack.arrayZ,
-						    input.lenP1, input.arrayZ,
-						    lookahead.len, lookahead.arrayZ, lookup.len,
-						    lookup.arrayZ, lookup_context));
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+    return chain_context_would_apply_lookup (c,
+					     backtrack.len, backtrack.arrayZ,
+					     input.lenP1, input.arrayZ,
+					     lookahead.len, lookahead.arrayZ, lookup.len,
+					     lookup.arrayZ, lookup_context);
   }
 
   bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     return_trace (chain_context_apply_lookup (c,
 					      backtrack.len, backtrack.arrayZ,
 					      input.lenP1, input.arrayZ,
@@ -1995,11 +2000,11 @@
   {
     TRACE_SANITIZE (this);
     if (!backtrack.sanitize (c)) return_trace (false);
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
     if (!input.sanitize (c)) return_trace (false);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
     if (!lookahead.sanitize (c)) return_trace (false);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     return_trace (lookup.sanitize (c));
   }
 
@@ -2025,46 +2030,51 @@
 {
   bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      if ((this+rule[i]).intersects (glyphs, lookup_context))
-	return true;
-    return false;
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const ChainRule &_) { return _.intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
   void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      (this+rule[i]).closure (c, lookup_context);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRule &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      (this+rule[i]).collect_glyphs (c, lookup_context);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRule &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
-    TRACE_WOULD_APPLY (this);
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      if ((this+rule[i]).would_apply (c, lookup_context))
-	return_trace (true);
-
-    return_trace (false);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const ChainRule &_) { return _.would_apply (c, lookup_context); })
+    | hb_any
+    ;
   }
 
   bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      if ((this+rule[i]).apply (c, lookup_context))
-	return_trace (true);
-
-    return_trace (false);
+    return_trace (
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
+    | hb_any
+    )
+    ;
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2090,16 +2100,14 @@
       {nullptr, nullptr, nullptr}
     };
 
-    unsigned int count = ruleSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (glyphs->has (iter.get_glyph ()) &&
-	  (this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
-	return true;
-    }
-    return false;
+    return
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const ChainRuleSet &_) { return _.intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
@@ -2109,14 +2117,12 @@
       {nullptr, nullptr, nullptr}
     };
 
-    unsigned int count = ruleSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-	(this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
-    }
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -2128,21 +2134,20 @@
       {nullptr, nullptr, nullptr}
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
     struct ChainContextApplyLookupContext lookup_context = {
       {match_glyph},
       {nullptr, nullptr, nullptr}
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return rule_set.would_apply (c, lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -2204,13 +2209,13 @@
        &lookahead_class_def}
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (input_class_def.intersects_class (glyphs, i) &&
-	  (this+ruleSet[i]).intersects (glyphs, lookup_context))
-	return true;
-
-    return false;
+    return
+    + hb_enumerate (ruleSet)
+    | hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<ChainRuleSet> &> p)
+	      { return input_class_def.intersects_class (glyphs, p.first) &&
+		       (this+p.second).intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
   void closure (hb_closure_context_t *c) const
   {
@@ -2228,12 +2233,15 @@
        &lookahead_class_def}
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (input_class_def.intersects_class (c->glyphs, i)) {
-	const ChainRuleSet &rule_set = this+ruleSet[i];
-	rule_set.closure (c, lookup_context);
-      }
+    return
+    + hb_enumerate (ruleSet)
+    | hb_filter ([&] (unsigned _)
+		 { return input_class_def.intersects_class (c->glyphs, _); },
+		 hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -2251,15 +2259,14 @@
        &lookahead_class_def}
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const ClassDef &backtrack_class_def = this+backtrackClassDef;
     const ClassDef &input_class_def = this+inputClassDef;
     const ClassDef &lookahead_class_def = this+lookaheadClassDef;
@@ -2272,7 +2279,7 @@
        &input_class_def,
        &lookahead_class_def}
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return rule_set.would_apply (c, lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -2343,12 +2350,12 @@
 {
   bool intersects (const hb_set_t *glyphs) const
   {
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     if (!(this+input[0]).intersects (glyphs))
       return false;
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
     struct ChainContextClosureLookupContext lookup_context = {
       {intersects_coverage},
       {this, this, this}
@@ -2362,13 +2369,13 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     if (!(this+input[0]).intersects (c->glyphs))
       return;
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     struct ChainContextClosureLookupContext lookup_context = {
       {intersects_coverage},
       {this, this, this}
@@ -2383,12 +2390,12 @@
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     (this+input[0]).add_coverage (c->input);
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     struct ChainContextCollectGlyphsLookupContext lookup_context = {
       {collect_coverage},
       {this, this, this}
@@ -2403,25 +2410,23 @@
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     struct ChainContextApplyLookupContext lookup_context = {
       {match_coverage},
       {this, this, this}
     };
-    return_trace (chain_context_would_apply_lookup (c,
-						    backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
-						    input.len, (const HBUINT16 *) input.arrayZ + 1,
-						    lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
-						    lookup.len, lookup.arrayZ, lookup_context));
+    return chain_context_would_apply_lookup (c,
+					     backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
+					     input.len, (const HBUINT16 *) input.arrayZ + 1,
+					     lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
+					     lookup.len, lookup.arrayZ, lookup_context);
   }
 
   const Coverage &get_coverage () const
   {
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     return this+input[0];
   }
 
@@ -2428,13 +2433,13 @@
   bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     struct ChainContextApplyLookupContext lookup_context = {
       {match_coverage},
       {this, this, this}
@@ -2457,12 +2462,12 @@
   {
     TRACE_SANITIZE (this);
     if (!backtrack.sanitize (c, this)) return_trace (false);
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     if (!input.sanitize (c, this)) return_trace (false);
     if (!input.len) return_trace (false); /* To be consistent with Context. */
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
     if (!lookahead.sanitize (c, this)) return_trace (false);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     return_trace (lookup.sanitize (c));
   }
 
@@ -2489,15 +2494,15 @@
 
 struct ChainContext
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
-    case 2: return_trace (c->dispatch (u.format2));
-    case 3: return_trace (c->dispatch (u.format3));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2519,18 +2524,14 @@
 
   template <typename X>
   const X& get_subtable () const
-  {
-    unsigned int offset = extensionOffset;
-    if (unlikely (!offset)) return Null(typename T::SubTable);
-    return StructAtOffset<typename T::SubTable> (this, offset);
-  }
+  { return this + CastR<LOffsetTo<typename T::SubTable>> (extensionOffset); }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, format);
     if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ());
-    return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type ()));
+    return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), hb_forward<Ts> (ds)...));
   }
 
   /* This is called from may_dispatch() above with hb_sanitize_context_t. */
@@ -2538,7 +2539,6 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  extensionOffset != 0 &&
 		  extensionLookupType != T::SubTable::Extension);
   }
 
@@ -2547,7 +2547,7 @@
   HBUINT16	extensionLookupType;	/* Lookup type of subtable referenced
 					 * by ExtensionOffset (i.e. the
 					 * extension subtable). */
-  HBUINT32	extensionOffset;	/* Offset to the extension subtable,
+  Offset32	extensionOffset;	/* Offset to the extension subtable,
 					 * of lookup type subtable. */
   public:
   DEFINE_SIZE_STATIC (8);
@@ -2572,13 +2572,13 @@
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, u.format);
     if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
-    case 1: return_trace (u.format1.dispatch (c));
+    case 1: return_trace (u.format1.dispatch (c, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2681,7 +2681,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct GSUBGPOS *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
 
     out->scriptList.serialize_subset (c, this+scriptList, out);
@@ -2689,13 +2689,13 @@
 
     typedef OffsetListOf<TLookup> TLookupList;
     /* TODO Use intersects() to count how many subtables survive? */
-    CastR<OffsetTo<TLookupList> > (out->lookupList)
+    CastR<OffsetTo<TLookupList>> (out->lookupList)
       .serialize_subset (c,
-			 this+CastR<const OffsetTo<TLookupList> > (lookupList),
+			 this+CastR<OffsetTo<TLookupList>> (lookupList),
 			 out);
 
     if (version.to_int () >= 0x00010001u)
-     out->featureVars.serialize_subset (c, this+featureVars, out);
+     out->featureVars.serialize_copy (c->serializer, this+featureVars, out);
 
     return_trace (true);
   }
@@ -2715,7 +2715,7 @@
 		  likely (version.major == 1) &&
 		  scriptList.sanitize (c, this) &&
 		  featureList.sanitize (c, this) &&
-		  CastR<OffsetTo<TLookupList> > (lookupList).sanitize (c, this) &&
+		  CastR<OffsetTo<TLookupList>> (lookupList).sanitize (c, this) &&
 		  (version.to_int () < 0x00010001u || featureVars.sanitize (c, this)));
   }
 

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -62,6 +62,16 @@
  * kern
  */
 
+/**
+ * hb_ot_layout_has_kerning:
+ * @face: The #hb_face_t to work on
+ *
+ * Tests whether a face includes any kerning data in the 'kern' table.
+ * Does NOT test for kerning lookups in the GPOS table.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ **/
 bool
 hb_ot_layout_has_kerning (hb_face_t *face)
 {
@@ -68,6 +78,17 @@
   return face->table.kern->has_data ();
 }
 
+
+/**
+ * hb_ot_layout_has_machine_kerning:
+ * @face: The #hb_face_t to work on
+ *
+ * Tests whether a face includes any state-machine kerning in the 'kern' table.
+ * Does NOT examine the GPOS table.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ **/
 bool
 hb_ot_layout_has_machine_kerning (hb_face_t *face)
 {
@@ -74,6 +95,21 @@
   return face->table.kern->has_state_machine ();
 }
 
+
+/**
+ * hb_ot_layout_has_cross_kerning:
+ * @face: The #hb_face_t to work on
+ *
+ * Tests whether a face has any cross-stream kerning (i.e., kerns
+ * that make adjustments perpendicular to the direction of the text
+ * flow: Y adjustments in horizontal text or X adjustments in 
+ * vertical text) in the 'kern' table.
+ *
+ * Does NOT examine the GPOS table.
+ *
+ * Return value: true is data found, false otherwise
+ *
+ **/
 bool
 hb_ot_layout_has_cross_kerning (hb_face_t *face)
 {
@@ -102,6 +138,9 @@
 OT::GDEF::is_blacklisted (hb_blob_t *blob,
 			  hb_face_t *face) const
 {
+#ifdef HB_NO_OT_LAYOUT_BLACKLIST
+  return false;
+#endif
   /* The ugly business of blacklisting individual fonts' tables happen here!
    * See this thread for why we finally had to bend in and do this:
    * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html
@@ -119,84 +158,82 @@
    *     https://bugzilla.mozilla.org/show_bug.cgi?id=1279693
    *     https://bugzilla.mozilla.org/show_bug.cgi?id=1279875
    */
-#define ENCODE(x,y,z) (((uint64_t) (x) << 48) | ((uint64_t) (y) << 24) | (uint64_t) (z))
-  switch ENCODE(blob->length,
-		face->table.GSUB->table.get_length (),
-		face->table.GPOS->table.get_length ())
+  switch HB_CODEPOINT_ENCODE3(blob->length,
+			      face->table.GSUB->table.get_length (),
+			      face->table.GPOS->table.get_length ())
   {
     /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */
-    case ENCODE (442, 2874, 42038):
+    case HB_CODEPOINT_ENCODE3 (442, 2874, 42038):
     /* sha1sum:37fc8c16a0894ab7b749e35579856c73c840867b Windows 7? timesbi.ttf */
-    case ENCODE (430, 2874, 40662):
+    case HB_CODEPOINT_ENCODE3 (430, 2874, 40662):
     /* sha1sum:19fc45110ea6cd3cdd0a5faca256a3797a069a80 Windows 7 timesi.ttf */
-    case ENCODE (442, 2874, 39116):
+    case HB_CODEPOINT_ENCODE3 (442, 2874, 39116):
     /* sha1sum:6d2d3c9ed5b7de87bc84eae0df95ee5232ecde26 Windows 7 timesbi.ttf */
-    case ENCODE (430, 2874, 39374):
+    case HB_CODEPOINT_ENCODE3 (430, 2874, 39374):
     /* sha1sum:8583225a8b49667c077b3525333f84af08c6bcd8 OS X 10.11.3 Times New Roman Italic.ttf */
-    case ENCODE (490, 3046, 41638):
+    case HB_CODEPOINT_ENCODE3 (490, 3046, 41638):
     /* sha1sum:ec0f5a8751845355b7c3271d11f9918a966cb8c9 OS X 10.11.3 Times New Roman Bold Italic.ttf */
-    case ENCODE (478, 3046, 41902):
+    case HB_CODEPOINT_ENCODE3 (478, 3046, 41902):
     /* sha1sum:96eda93f7d33e79962451c6c39a6b51ee893ce8c  tahoma.ttf from Windows 8 */
-    case ENCODE (898, 12554, 46470):
+    case HB_CODEPOINT_ENCODE3 (898, 12554, 46470):
     /* sha1sum:20928dc06014e0cd120b6fc942d0c3b1a46ac2bc  tahomabd.ttf from Windows 8 */
-    case ENCODE (910, 12566, 47732):
+    case HB_CODEPOINT_ENCODE3 (910, 12566, 47732):
     /* sha1sum:4f95b7e4878f60fa3a39ca269618dfde9721a79e  tahoma.ttf from Windows 8.1 */
-    case ENCODE (928, 23298, 59332):
+    case HB_CODEPOINT_ENCODE3 (928, 23298, 59332):
     /* sha1sum:6d400781948517c3c0441ba42acb309584b73033  tahomabd.ttf from Windows 8.1 */
-    case ENCODE (940, 23310, 60732):
+    case HB_CODEPOINT_ENCODE3 (940, 23310, 60732):
     /* tahoma.ttf v6.04 from Windows 8.1 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
-    case ENCODE (964, 23836, 60072):
+    case HB_CODEPOINT_ENCODE3 (964, 23836, 60072):
     /* tahomabd.ttf v6.04 from Windows 8.1 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
-    case ENCODE (976, 23832, 61456):
+    case HB_CODEPOINT_ENCODE3 (976, 23832, 61456):
     /* sha1sum:e55fa2dfe957a9f7ec26be516a0e30b0c925f846  tahoma.ttf from Windows 10 */
-    case ENCODE (994, 24474, 60336):
+    case HB_CODEPOINT_ENCODE3 (994, 24474, 60336):
     /* sha1sum:7199385abb4c2cc81c83a151a7599b6368e92343  tahomabd.ttf from Windows 10 */
-    case ENCODE (1006, 24470, 61740):
+    case HB_CODEPOINT_ENCODE3 (1006, 24470, 61740):
     /* tahoma.ttf v6.91 from Windows 10 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
-    case ENCODE (1006, 24576, 61346):
+    case HB_CODEPOINT_ENCODE3 (1006, 24576, 61346):
     /* tahomabd.ttf v6.91 from Windows 10 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
-    case ENCODE (1018, 24572, 62828):
+    case HB_CODEPOINT_ENCODE3 (1018, 24572, 62828):
     /* sha1sum:b9c84d820c49850d3d27ec498be93955b82772b5  tahoma.ttf from Windows 10 AU */
-    case ENCODE (1006, 24576, 61352):
+    case HB_CODEPOINT_ENCODE3 (1006, 24576, 61352):
     /* sha1sum:2bdfaab28174bdadd2f3d4200a30a7ae31db79d2  tahomabd.ttf from Windows 10 AU */
-    case ENCODE (1018, 24572, 62834):
+    case HB_CODEPOINT_ENCODE3 (1018, 24572, 62834):
     /* sha1sum:b0d36cf5a2fbe746a3dd277bffc6756a820807a7  Tahoma.ttf from Mac OS X 10.9 */
-    case ENCODE (832, 7324, 47162):
+    case HB_CODEPOINT_ENCODE3 (832, 7324, 47162):
     /* sha1sum:12fc4538e84d461771b30c18b5eb6bd434e30fba  Tahoma Bold.ttf from Mac OS X 10.9 */
-    case ENCODE (844, 7302, 45474):
+    case HB_CODEPOINT_ENCODE3 (844, 7302, 45474):
     /* sha1sum:eb8afadd28e9cf963e886b23a30b44ab4fd83acc  himalaya.ttf from Windows 7 */
-    case ENCODE (180, 13054, 7254):
+    case HB_CODEPOINT_ENCODE3 (180, 13054, 7254):
     /* sha1sum:73da7f025b238a3f737aa1fde22577a6370f77b0  himalaya.ttf from Windows 8 */
-    case ENCODE (192, 12638, 7254):
+    case HB_CODEPOINT_ENCODE3 (192, 12638, 7254):
     /* sha1sum:6e80fd1c0b059bbee49272401583160dc1e6a427  himalaya.ttf from Windows 8.1 */
-    case ENCODE (192, 12690, 7254):
+    case HB_CODEPOINT_ENCODE3 (192, 12690, 7254):
     /* 8d9267aea9cd2c852ecfb9f12a6e834bfaeafe44  cantarell-fonts-0.0.21/otf/Cantarell-Regular.otf */
     /* 983988ff7b47439ab79aeaf9a45bd4a2c5b9d371  cantarell-fonts-0.0.21/otf/Cantarell-Oblique.otf */
-    case ENCODE (188, 248, 3852):
+    case HB_CODEPOINT_ENCODE3 (188, 248, 3852):
     /* 2c0c90c6f6087ffbfea76589c93113a9cbb0e75f  cantarell-fonts-0.0.21/otf/Cantarell-Bold.otf */
     /* 55461f5b853c6da88069ffcdf7f4dd3f8d7e3e6b  cantarell-fonts-0.0.21/otf/Cantarell-Bold-Oblique.otf */
-    case ENCODE (188, 264, 3426):
+    case HB_CODEPOINT_ENCODE3 (188, 264, 3426):
     /* d125afa82a77a6475ac0e74e7c207914af84b37a padauk-2.80/Padauk.ttf RHEL 7.2 */
-    case ENCODE (1058, 47032, 11818):
+    case HB_CODEPOINT_ENCODE3 (1058, 47032, 11818):
     /* 0f7b80437227b90a577cc078c0216160ae61b031 padauk-2.80/Padauk-Bold.ttf RHEL 7.2*/
-    case ENCODE (1046, 47030, 12600):
+    case HB_CODEPOINT_ENCODE3 (1046, 47030, 12600):
     /* d3dde9aa0a6b7f8f6a89ef1002e9aaa11b882290 padauk-2.80/Padauk.ttf Ubuntu 16.04 */
-    case ENCODE (1058, 71796, 16770):
+    case HB_CODEPOINT_ENCODE3 (1058, 71796, 16770):
     /* 5f3c98ccccae8a953be2d122c1b3a77fd805093f padauk-2.80/Padauk-Bold.ttf Ubuntu 16.04 */
-    case ENCODE (1046, 71790, 17862):
+    case HB_CODEPOINT_ENCODE3 (1046, 71790, 17862):
     /* 6c93b63b64e8b2c93f5e824e78caca555dc887c7 padauk-2.80/Padauk-book.ttf */
-    case ENCODE (1046, 71788, 17112):
+    case HB_CODEPOINT_ENCODE3 (1046, 71788, 17112):
     /* d89b1664058359b8ec82e35d3531931125991fb9 padauk-2.80/Padauk-bookbold.ttf */
-    case ENCODE (1058, 71794, 17514):
+    case HB_CODEPOINT_ENCODE3 (1058, 71794, 17514):
     /* 824cfd193aaf6234b2b4dc0cf3c6ef576c0d00ef padauk-3.0/Padauk-book.ttf */
-    case ENCODE (1330, 109904, 57938):
+    case HB_CODEPOINT_ENCODE3 (1330, 109904, 57938):
     /* 91fcc10cf15e012d27571e075b3b4dfe31754a8a padauk-3.0/Padauk-bookbold.ttf */
-    case ENCODE (1330, 109904, 58972):
+    case HB_CODEPOINT_ENCODE3 (1330, 109904, 58972):
     /* sha1sum: c26e41d567ed821bed997e937bc0c41435689e85  Padauk.ttf
      *  "Padauk Regular" "Version 2.5", see https://crbug.com/681813 */
-    case ENCODE (1004, 59092, 14836):
+    case HB_CODEPOINT_ENCODE3 (1004, 59092, 14836):
       return true;
-#undef ENCODE
   }
   return false;
 }
@@ -219,6 +256,15 @@
 
 /* Public API */
 
+/**
+ * hb_ot_layout_has_glyph_classes:
+ * @face: #hb_face_t to work upon
+ *
+ * Tests whether a face has any glyph classes defined in its GDEF table.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_has_glyph_classes (hb_face_t *face)
 {
@@ -227,7 +273,14 @@
 
 /**
  * hb_ot_layout_get_glyph_class:
+ * @face: The #hb_face_t to work on
+ * @glyph: The #hb_codepoint_t code point to query
  *
+ * Fetches the GDEF class of the requested glyph in the specified face.
+ *
+ * Return value: The #hb_ot_layout_glyph_class_t glyph class of the given code 
+ * point in the GDEF table of the face.
+ *
  * Since: 0.9.7
  **/
 hb_ot_layout_glyph_class_t
@@ -239,7 +292,14 @@
 
 /**
  * hb_ot_layout_get_glyphs_in_class:
+ * @face: The #hb_face_t to work on
+ * @klass: The #hb_ot_layout_glyph_class_t GDEF class to retrieve
+ * @glyphs: (out): The #hb_set_t set of all glyphs belonging to the requested
+ *          class.
  *
+ * Retrieves the set of all glyphs from the face that belong to the requested
+ * glyph class in the face's GDEF table.
+ *
  * Since: 0.9.7
  **/
 void
@@ -250,6 +310,22 @@
   return face->table.GDEF->table->get_glyphs_in_class (klass, glyphs);
 }
 
+
+/**
+ * hb_ot_layout_get_attach_points:
+ * @face: The #hb_face_t to work on
+ * @glyph: The #hb_codepoint_t code point to query
+ * @start_offset: offset of the first attachment point to retrieve
+ * @point_count: (inout) (allow-none): Input = the maximum number of attachment points to return;
+ *               Output = the actual number of attachment points returned (may be zero)
+ * @point_array: (out) (array length=point_count): The array of attachment points found for the query
+ *
+ * Fetches a list of all attachment points for the specified glyph in the GDEF
+ * table of the face. The list returned will begin at the offset provided. 
+ *
+ * Useful if the client program wishes to cache the list.
+ *
+ **/
 unsigned int
 hb_ot_layout_get_attach_points (hb_face_t      *face,
 				hb_codepoint_t  glyph,
@@ -257,6 +333,12 @@
 				unsigned int   *point_count /* IN/OUT */,
 				unsigned int   *point_array /* OUT */)
 {
+#ifdef HB_NO_LAYOUT_UNUSED
+  if (point_count)
+    *point_count = 0;
+  return 0;
+#endif
+
   return face->table.GDEF->table->get_attach_points (glyph,
 						     start_offset,
 						     point_count,
@@ -263,6 +345,21 @@
 						     point_array);
 }
 
+
+/**
+ * hb_ot_layout_get_ligature_carets:
+ * @font: The #hb_font_t to work on
+ * @direction: The #hb_direction_t text direction to use
+ * @glyph: The #hb_codepoint_t code point to query
+ * @start_offset: offset of the first caret position to retrieve
+ * @caret_count: (inout) (allow-none): Input = the maximum number of caret positions to return;
+ *               Output = the actual number of caret positions returned (may be zero)
+ * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query
+ *
+ * Fetches a list of the caret positions defined for a ligature glyph in the GDEF
+ * table of the font. The list returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_get_ligature_carets (hb_font_t      *font,
 				  hb_direction_t  direction,
@@ -271,6 +368,12 @@
 				  unsigned int   *caret_count /* IN/OUT */,
 				  hb_position_t  *caret_array /* OUT */)
 {
+#ifdef HB_NO_LAYOUT_UNUSED
+  if (caret_count)
+    *caret_count = 0;
+  return 0;
+#endif
+
   unsigned int result_caret_count = 0;
   unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array);
   if (result)
@@ -291,6 +394,9 @@
 OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
 			  hb_face_t *face) const
 {
+#ifdef HB_NO_OT_LAYOUT_BLACKLIST
+  return false;
+#endif
   /* Mac OS X prefers morx over GSUB.  It also ships with various Indic fonts,
    * all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken
    * GSUB/GPOS tables.  Some have GSUB with zero scripts, those are ignored by
@@ -316,7 +422,10 @@
 OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED,
 			  hb_face_t *face HB_UNUSED) const
 {
+#ifdef HB_NO_OT_LAYOUT_BLACKLIST
   return false;
+#endif
+  return false;
 }
 
 static const OT::GSUBGPOS&
@@ -331,6 +440,19 @@
 }
 
 
+/**
+ * hb_ot_layout_table_get_script_tags:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @start_offset: offset of the first script tag to retrieve
+ * @script_count: (inout) (allow-none): Input = the maximum number of script tags to return;
+ *                Output = the actual number of script tags returned (may be zero)
+ * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query
+ *
+ * Fetches a list of all scripts enumerated in the specified face's GSUB table
+ * or GPOS table. The list returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_table_get_script_tags (hb_face_t    *face,
 				    hb_tag_t      table_tag,
@@ -345,11 +467,24 @@
 
 #define HB_OT_TAG_LATIN_SCRIPT		HB_TAG ('l', 'a', 't', 'n')
 
+/**
+ * hb_ot_layout_table_find_script:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_tag: #hb_tag_t of the script tag requested
+ * @script_index: (out): The index of the requested script tag
+ *
+ * Fetches the index if a given script tag in the specified face's GSUB table
+ * or GPOS table.
+ *
+ * Return value: true if the script is found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_table_find_script (hb_face_t    *face,
 				hb_tag_t      table_tag,
 				hb_tag_t      script_tag,
-				unsigned int *script_index)
+				unsigned int *script_index /* OUT */)
 {
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -375,20 +510,38 @@
   return false;
 }
 
+#ifndef HB_DISABLE_DEPRECATED
+/**
+ * hb_ot_layout_table_choose_script:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_tags: Array of #hb_tag_t script tags
+ * @script_index: (out): The index of the requested script tag
+ * @chosen_script: (out): #hb_tag_t of the script tag requested
+ *
+ * Deprecated since 2.0.0
+ **/
 hb_bool_t
 hb_ot_layout_table_choose_script (hb_face_t      *face,
 				  hb_tag_t        table_tag,
 				  const hb_tag_t *script_tags,
-				  unsigned int   *script_index,
-				  hb_tag_t       *chosen_script)
+				  unsigned int   *script_index  /* OUT */,
+				  hb_tag_t       *chosen_script /* OUT */)
 {
   const hb_tag_t *t;
   for (t = script_tags; *t; t++);
   return hb_ot_layout_table_select_script (face, table_tag, t - script_tags, script_tags, script_index, chosen_script);
 }
+#endif
 
 /**
  * hb_ot_layout_table_select_script:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_count: Number of script tags in the array
+ * @script_tags: Array of #hb_tag_t script tags
+ * @script_index: (out): The index of the requested script
+ * @chosen_script: (out): #hb_tag_t of the requested script
  *
  * Since: 2.0.0
  **/
@@ -442,6 +595,19 @@
   return false;
 }
 
+
+/**
+ * hb_ot_layout_table_get_feature_tags:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @start_offset: offset of the first feature tag to retrieve
+ * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
+ *                 Output = the actual number of feature tags returned (may be zero)
+ * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table
+ *
+ * Fetches a list of all feature tags in the given face's GSUB or GPOS table.
+ *
+ **/
 unsigned int
 hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
 				     hb_tag_t      table_tag,
@@ -454,11 +620,24 @@
   return g.get_feature_tags (start_offset, feature_count, feature_tags);
 }
 
+
+/**
+ * hb_ot_layout_table_find_feature:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @feature_tag: The #hb_tag_t og the requested feature tag
+ * @feature_index: (out): The index of the requested feature
+ *
+ * Fetches the index for a given feature tag in the specified face's GSUB table
+ * or GPOS table.
+ *
+ * Return value: true if the feature is found, false otherwise
+ **/
 bool
 hb_ot_layout_table_find_feature (hb_face_t    *face,
 				 hb_tag_t      table_tag,
 				 hb_tag_t      feature_tag,
-				 unsigned int *feature_index)
+				 unsigned int *feature_index /* OUT */)
 {
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -477,6 +656,20 @@
 }
 
 
+/**
+ * hb_ot_layout_script_get_language_tags:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @start_offset: offset of the first language tag to retrieve
+ * @language_count: (inout) (allow-none): Input = the maximum number of language tags to return;
+ *                  Output = the actual number of language tags returned (may be zero)
+ * @language_tags: (out) (array length=language_count): Array of language tags found in the table
+ *
+ * Fetches a list of language tags in the given face's GSUB or GPOS table, underneath
+ * the specified script index. The list returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_script_get_language_tags (hb_face_t    *face,
 				       hb_tag_t      table_tag,
@@ -490,6 +683,24 @@
   return s.get_lang_sys_tags (start_offset, language_count, language_tags);
 }
 
+
+#ifndef HB_DISABLE_DEPRECATED
+/**
+ * hb_ot_layout_script_find_language:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_tag: The #hb_tag_t of the requested language
+ * @language_index: The index of the requested language
+ *
+ * Fetches the index of a given language tag in the specified face's GSUB table
+ * or GPOS table, underneath the specified script tag.
+ *
+ * Return value: true if the language tag is found, false otherwise
+ *
+ * Since: ??
+ * Deprecated: ??
+ **/
 hb_bool_t
 hb_ot_layout_script_find_language (hb_face_t    *face,
 				   hb_tag_t      table_tag,
@@ -504,10 +715,23 @@
 					      &language_tag,
 					      language_index);
 }
+#endif
 
+
 /**
  * hb_ot_layout_script_select_language:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_count: The number of languages in the specified script
+ * @language_tags: The array of language tags
+ * @language_index: (out): The index of the requested language
  *
+ * Fetches the index of a given language tag in the specified face's GSUB table
+ * or GPOS table, underneath the specified script index.
+ *
+ * Return value: true if the language tag is found, false otherwise
+ *
  * Since: 2.0.0
  **/
 hb_bool_t
@@ -536,6 +760,21 @@
   return false;
 }
 
+
+/**
+ * hb_ot_layout_language_get_required_feature_index:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_index: The index of the requested language tag
+ * @feature_index: (out): The index of the requested feature
+ *
+ * Fetches the index of a requested feature in the given face's GSUB or GPOS table,
+ * underneath the specified script and language.
+ *
+ * Return value: true if the feature is found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
 						  hb_tag_t      table_tag,
@@ -551,9 +790,21 @@
 						     nullptr);
 }
 
+
 /**
  * hb_ot_layout_language_get_required_feature:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_index: The index of the requested language tag
+ * @feature_index: The index of the requested feature
+ * @feature_tag: (out): The #hb_tag_t of the requested feature
  *
+ * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table,
+ * underneath the specified script and language.
+ *
+ * Return value: true if the feature is found, false otherwise
+ *
  * Since: 0.9.30
  **/
 hb_bool_t
@@ -574,6 +825,22 @@
   return l.has_required_feature ();
 }
 
+
+/**
+ * hb_ot_layout_language_get_feature_indexes:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_index: The index of the requested language tag
+ * @start_offset: offset of the first feature tag to retrieve
+ * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
+ *                 Output: the actual number of feature tags returned (may be zero)
+ * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query
+ *
+ * Fetches a list of all features in the specified face's GSUB table
+ * or GPOS table, underneath the specified script and language. The list
+ * returned will begin at the offset provided.
+ **/
 unsigned int
 hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
 					   hb_tag_t      table_tag,
@@ -589,6 +856,23 @@
   return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
 }
 
+
+/**
+ * hb_ot_layout_language_get_feature_tags:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_index: The index of the requested language tag
+ * @start_offset: offset of the first feature tag to retrieve
+ * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
+ *                 Output = the actual number of feature tags returned (may be zero)
+ * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query
+ *
+ * Fetches a list of all features in the specified face's GSUB table
+ * or GPOS table, underneath the specified script and language. The list
+ * returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
 					hb_tag_t      table_tag,
@@ -614,6 +898,21 @@
 }
 
 
+/**
+ * hb_ot_layout_language_find_feature:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_index: The index of the requested language tag
+ * @feature_tag: #hb_tag_t of the feature tag requested
+ * @feature_index: (out): The index of the requested feature
+ *
+ * Fetches the index of a given feature tag in the specified face's GSUB table
+ * or GPOS table, underneath the specified script and language.
+ *
+ * Return value: true if the feature is found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_language_find_feature (hb_face_t    *face,
 				    hb_tag_t      table_tag,
@@ -620,7 +919,7 @@
 				    unsigned int  script_index,
 				    unsigned int  language_index,
 				    hb_tag_t      feature_tag,
-				    unsigned int *feature_index)
+				    unsigned int *feature_index /* OUT */)
 {
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -640,9 +939,21 @@
   return false;
 }
 
+
 /**
  * hb_ot_layout_feature_get_lookups:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @feature_index: The index of the requested feature
+ * @start_offset: offset of the first lookup to retrieve
+ * @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return;
+ *                Output = the actual number of lookups returned (may be zero)
+ * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query
  *
+ * Fetches a list of all lookups enumerated for the specified feature, in
+ * the specified face's GSUB table or GPOS table. The list returned will
+ * begin at the offset provided.
+ *
  * Since: 0.9.7
  **/
 unsigned int
@@ -662,9 +973,15 @@
 							   lookup_indexes);
 }
 
+
 /**
  * hb_ot_layout_table_get_lookup_count:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
  *
+ * Fetches the total number of lookups enumerated in the specified 
+ * face's GSUB table or GPOS table.
+ *
  * Since: 0.9.22
  **/
 unsigned int
@@ -805,9 +1122,22 @@
   }
 }
 
+
 /**
  * hb_ot_layout_collect_features:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @scripts: The array of scripts to collect features for
+ * @languages: The array of languages to collect features for
+ * @features: The array of features to collect
+ * @feature_indexes: (out): The array of feature indexes found for the query
  *
+ * Fetches a list of all feature indexes in the specified face's GSUB table
+ * or GPOS table, underneath the specified scripts, languages, and features.
+ * If no list of scripts is provided, all scripts will be queried. If no list
+ * of languages is provided, all languages will be queried. If no list of
+ * features is provided, all features will be queried.
+ *
  * Since: 1.8.5
  **/
 void
@@ -843,9 +1173,22 @@
   }
 }
 
+
 /**
  * hb_ot_layout_collect_lookups:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @scripts: The array of scripts to collect lookups for
+ * @languages: The array of languages to collect lookups for
+ * @features: The array of features to collect lookups for
+ * @lookup_indexes: (out): The array of lookup indexes found for the query
  *
+ * Fetches a list of all feature-lookup indexes in the specified face's GSUB
+ * table or GPOS table, underneath the specified scripts, languages, and
+ * features. If no list of scripts is provided, all scripts will be queried.
+ * If no list of languages is provided, all languages will be queried. If no
+ * list of features is provided, all features will be queried. 
+ *
  * Since: 0.9.8
  **/
 void
@@ -866,9 +1209,20 @@
     g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes);
 }
 
+
 /**
  * hb_ot_layout_lookup_collect_glyphs:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @lookup_index: The index of the feature lookup to query
+ * @glyphs_before: (out): Array of glyphs preceding the substitution range
+ * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup
+ * @glyphs_after: (out): Array of glyphs following the substition range
+ * @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
  *
+ * Fetches a list of all glyphs affected by the specified lookup in the
+ * specified face's GSUB table of GPOS table.
+ *
  * Since: 0.9.7
  **/
 void
@@ -906,6 +1260,19 @@
 
 /* Variations support */
 
+
+/**
+ * hb_ot_layout_table_find_feature_variations:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @coords: The variation coordinates to query
+ * @num_coords: The number of variation coorinates
+ * @variations_index: (out): The array of feature variations found for the query
+ *
+ * Fetches a list of feature variations in the specified face's GSUB table
+ * or GPOS table, at the specified variation coordinates.
+ *
+ **/
 hb_bool_t
 hb_ot_layout_table_find_feature_variations (hb_face_t    *face,
 					    hb_tag_t      table_tag,
@@ -918,6 +1285,23 @@
   return g.find_variations_index (coords, num_coords, variations_index);
 }
 
+
+/**
+ * hb_ot_layout_feature_with_variations_get_lookups:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @feature_index: The index of the feature to query
+ * @variations_index: The index of the feature variation to query
+ * @start_offset: offset of the first lookup to retrieve
+ * @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return;
+ *                Output = the actual number of lookups returned (may be zero)
+ * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query
+ *
+ * Fetches a list of all lookups enumerated for the specified feature, in
+ * the specified face's GSUB table or GPOS table, enabled at the specified
+ * variations index. The list returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_feature_with_variations_get_lookups (hb_face_t    *face,
 						  hb_tag_t      table_tag,
@@ -940,6 +1324,16 @@
  * OT::GSUB
  */
 
+
+/**
+ * hb_ot_layout_has_substitution:
+ * @face: #hb_face_t to work upon
+ *
+ * Tests whether the specified face includes any GSUB substitutions.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_has_substitution (hb_face_t *face)
 {
@@ -946,9 +1340,20 @@
   return face->table.GSUB->table->has_data ();
 }
 
+
 /**
  * hb_ot_layout_lookup_would_substitute:
+ * @face: #hb_face_t to work upon
+ * @lookup_index: The index of the lookup to query
+ * @glyphs: The sequence of glyphs to query for substitution
+ * @glyphs_length: The length of the glyph sequence
+ * @zero_context: #hb_bool_t indicating whether substitutions should be context-free
  *
+ * Tests whether a specified lookup in the specified face would
+ * trigger a substitution on the given glyph sequence.
+ *
+ * Return value: true if a substitution would be triggered, false otherwise
+ *
  * Since: 0.9.7
  **/
 hb_bool_t
@@ -966,6 +1371,16 @@
   return l.would_apply (&c, &face->table.GSUB->accels[lookup_index]);
 }
 
+
+/**
+ * hb_ot_layout_substitute_start:
+ * @font: #hb_font_t to use
+ * @buffer: #hb_buffer_t buffer to work upon
+ *
+ * Called before substitution lookups are performed, to ensure that glyph
+ * class and other properties are set on the glyphs in the buffer.
+ *
+ **/
 void
 hb_ot_layout_substitute_start (hb_font_t    *font,
 			       hb_buffer_t  *buffer)
@@ -1025,13 +1440,19 @@
 
 /**
  * hb_ot_layout_lookup_substitute_closure:
+ * @face: #hb_face_t to work upon
+ * @lookup_index: index of the feature lookup to query
+ * @glyphs: (out): Array of glyphs comprising the transitive closure of the lookup
  *
+ * Compute the transitive closure of glyphs needed for a
+ * specified lookup.
+ *
  * Since: 0.9.7
  **/
 void
 hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
 				        unsigned int  lookup_index,
-				        hb_set_t     *glyphs)
+				        hb_set_t     *glyphs /* OUT */)
 {
   hb_map_t done_lookups;
   OT::hb_closure_context_t c (face, glyphs, &done_lookups);
@@ -1043,6 +1464,9 @@
 
 /**
  * hb_ot_layout_lookups_substitute_closure:
+ * @face: #hb_face_t to work upon
+ * @lookups: The set of lookups to query
+ * @glyphs: (out): Array of glyphs comprising the transitive closure of the lookups
  *
  * Compute the transitive closure of glyphs needed for all of the
  * provided lookups.
@@ -1052,7 +1476,7 @@
 void
 hb_ot_layout_lookups_substitute_closure (hb_face_t      *face,
                                          const hb_set_t *lookups,
-                                         hb_set_t       *glyphs)
+                                         hb_set_t       *glyphs /* OUT */)
 {
   hb_map_t done_lookups;
   OT::hb_closure_context_t c (face, glyphs, &done_lookups);
@@ -1081,6 +1505,14 @@
  * OT::GPOS
  */
 
+
+/**
+ * hb_ot_layout_has_positioning:
+ * @face: #hb_face_t to work upon
+ *
+ * Return value: true if the face has GPOS data, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_has_positioning (hb_face_t *face)
 {
@@ -1087,6 +1519,15 @@
   return face->table.GPOS->table->has_data ();
 }
 
+/**
+ * hb_ot_layout_position_start:
+ * @font: #hb_font_t to use
+ * @buffer: #hb_buffer_t buffer to work upon
+ *
+ * Called before positioning lookups are performed, to ensure that glyph
+ * attachment types and glyph-attachment chains are set for the glyphs in the buffer.
+ *
+ **/
 void
 hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
 {
@@ -1093,6 +1534,15 @@
   OT::GPOS::position_start (font, buffer);
 }
 
+
+/**
+ * hb_ot_layout_position_finish_advances:
+ * @font: #hb_font_t to use
+ * @buffer: #hb_buffer_t buffer to work upon
+ *
+ * Called after positioning lookups are performed, to finish glyph advances.
+ *
+ **/
 void
 hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer)
 {
@@ -1099,6 +1549,14 @@
   OT::GPOS::position_finish_advances (font, buffer);
 }
 
+/**
+ * hb_ot_layout_position_finish_offsets:
+ * @font: #hb_font_t to use
+ * @buffer: #hb_buffer_t buffer to work upon
+ *
+ * Called after positioning lookups are performed, to finish glyph offsets.
+ *
+ **/
 void
 hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
 {
@@ -1105,9 +1563,27 @@
   OT::GPOS::position_finish_offsets (font, buffer);
 }
 
+
 /**
  * hb_ot_layout_get_size_params:
+ * @face: #hb_face_t to work upon
+ * @design_size: (out): The design size of the face
+ * @subfamily_id: (out): The identifier of the face within the font subfamily
+ * @subfamily_name_id: (out): The ‘name’ table name ID of the face within the font subfamily
+ * @range_start: (out): The minimum size of the recommended size range for the face
+ * @range_end: (out): The maximum size of the recommended size range for the face
  *
+ * Fetches optical-size feature data (i.e., the `size` feature from GPOS). Note that
+ * the subfamily_id and the subfamily name string (accessible via the subfamily_name_id)
+ * as used here are defined as pertaining only to fonts within a font family that differ
+ * specifically in their respective size ranges; other ways to differentiate fonts within
+ * a subfamily are not covered by the `size` feature.
+ * 
+ * For more information on this distinction, see the `size` documentation at
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-39size39
+ *
+ * Return value: true if data found, false otherwise
+ *
  * Since: 0.9.10
  **/
 hb_bool_t
@@ -1151,6 +1627,7 @@
   return false;
 }
 
+
 /**
  * hb_ot_layout_feature_get_name_ids:
  * @face: #hb_face_t to work upon
@@ -1226,24 +1703,28 @@
   return false;
 }
 
+
 /**
  * hb_ot_layout_feature_get_characters:
  * @face: #hb_face_t to work upon
  * @table_tag: table tag to query, "GSUB" or "GPOS".
  * @feature_index: index of feature to query.
- * @start_offset: In case the resulting char_count was equal to its input value, there
- *                is a chance there were more characters on the tag so this API can be
- *                called with an offset till resulting char_count gets to a number
- *                lower than input buffer (or consider using just a bigger buffer for
- *                one shot copying).
- * @char_count: (inout) (allow-none): The count of characters for which this feature
- *              provides glyph variants. (May be zero.)
- * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. The Unicode codepoints
- *              of the characters for which this feature provides glyph variants.
+ * @start_offset: offset of the first character to retrieve
+ * @char_count: (inout) (allow-none): Input = the maximum number of characters to return;
+ *              Output = the actual number of characters returned (may be zero)
+ * @characters: (out caller-allocates) (array length=char_count): A buffer pointer.
+ *              The Unicode codepoints of the characters for which this feature provides
+ *               glyph variants.
  *
- * Fetches characters listed by designer under feature parameters for "Character
- * Variant" ("cvXX") features.
+ * Fetches a list of the characters defined as having a variant under the specified
+ * "Character Variant" ("cvXX") feature tag.
  *
+ * <note>Note: If the char_count output value is equal to its input value, then there
+ *       is a chance there were more characters defined under the feature tag than were
+ *       returned. This function can be called with incrementally larger start_offset
+ *       until the char_count output value is lower than its input value, or the size
+ *       of the characters array can be increased.</note>
+ * 
  * Return value: Number of total sample characters in the cvXX feature.
  *
  * Since: 2.0.0
@@ -1269,7 +1750,7 @@
   unsigned int len = 0;
   if (char_count && characters && start_offset < cv_params.characters.len)
   {
-    len = MIN (cv_params.characters.len - start_offset, *char_count);
+    len = hb_min (cv_params.characters.len - start_offset, *char_count);
     for (unsigned int i = 0; i < len; ++i)
       characters[i] = cv_params.characters[start_offset + i];
   }
@@ -1507,6 +1988,22 @@
   HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n')
 } hb_ot_layout_baseline_t;
 
+
+/**
+ * hb_ot_layout_get_baseline:
+ * @font: The #hb_font_t to work upon
+ * @baseline: The #hb_ot_layout_baseline_t to query
+ * @direction: The #hb_direction_t text direction to use (horizontal or vertical)
+ * @script_tag:  #hb_tag_t of the script to use
+ * @language_tag: #hb_tag_t of the language to use
+ * @coord: (out): The position of the requested baseline
+ *
+ * Fetches the coordinates of the specified baseline in the face, underneath
+ * the specified script and language and in the specified text direction.
+ *
+ * Return value: true if the baseline is found for the settings queried, false otherwise
+ *
+ **/
 HB_EXTERN hb_bool_t
 hb_ot_layout_get_baseline (hb_font_t               *font,
 			   hb_ot_layout_baseline_t  baseline,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2019-05-24 23:03:55 UTC (rev 51218)
@@ -93,6 +93,17 @@
 HB_EXTERN hb_bool_t
 hb_ot_layout_has_glyph_classes (hb_face_t *face);
 
+/**
+ * hb_ot_layout_glyph_class_t:
+ * @HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED: Glyphs not matching the other classifications
+ * @HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH: Spacing, single characters, capable of accepting marks
+ * @HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE: Glyphs that represent ligation of multiple characters
+ * @HB_OT_LAYOUT_GLYPH_CLASS_MARK: Non-spacing, combining glyphs that represent marks
+ * @HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT: Spacing glyphs that represent part of a single character
+ *
+ * The GDEF classes defined for glyphs.
+ *
+ **/
 typedef enum {
   HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED	= 0,
   HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH	= 1,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -188,12 +188,12 @@
 	  feature_infos[j].default_value = feature_infos[i].default_value;
 	} else {
 	  feature_infos[j].flags &= ~F_GLOBAL;
-	  feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
+	  feature_infos[j].max_value = hb_max (feature_infos[j].max_value, feature_infos[i].max_value);
 	  /* Inherit default_value from j */
 	}
 	feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
-	feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
-	feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
+	feature_infos[j].stage[0] = hb_min (feature_infos[j].stage[0], feature_infos[i].stage[0]);
+	feature_infos[j].stage[1] = hb_min (feature_infos[j].stage[1], feature_infos[i].stage[1]);
       }
     feature_infos.shrink (j + 1);
   }
@@ -213,13 +213,13 @@
       bits_needed = 0;
     else
       /* Limit bits per feature. */
-      bits_needed = MIN(HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value));
+      bits_needed = hb_min (HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value));
 
     if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
       continue; /* Feature disabled, or not enough bits. */
 
 
-    hb_bool_t found = false;
+    bool found = false;
     unsigned int feature_index[2];
     for (unsigned int table_index = 0; table_index < 2; table_index++)
     {
@@ -226,21 +226,21 @@
       if (required_feature_tag[table_index] == info->tag)
 	required_feature_stage[table_index] = info->stage[table_index];
 
-      found |= hb_ot_layout_language_find_feature (face,
-						   table_tags[table_index],
-						   script_index[table_index],
-						   language_index[table_index],
-						   info->tag,
-						   &feature_index[table_index]);
+      found |= (bool) hb_ot_layout_language_find_feature (face,
+							  table_tags[table_index],
+							  script_index[table_index],
+							  language_index[table_index],
+							  info->tag,
+							  &feature_index[table_index]);
     }
     if (!found && (info->flags & F_GLOBAL_SEARCH))
     {
       for (unsigned int table_index = 0; table_index < 2; table_index++)
       {
-	found |= hb_ot_layout_table_find_feature (face,
-						  table_tags[table_index],
-						  info->tag,
-						  &feature_index[table_index]);
+	found |= (bool) hb_ot_layout_table_find_feature (face,
+							 table_tags[table_index],
+							 info->tag,
+							 &feature_index[table_index]);
       }
     }
     if (!found && !(info->flags & F_HAS_FALLBACK))

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -68,7 +68,7 @@
     unsigned short random : 1;
     hb_mask_t mask;
 
-    static int cmp (const void *pa, const void *pb)
+    HB_INTERNAL static int cmp (const void *pa, const void *pb)
     {
       const lookup_map_t *a = (const lookup_map_t *) pa;
       const lookup_map_t *b = (const lookup_map_t *) pb;
@@ -167,7 +167,7 @@
 
   hb_mask_t global_mask;
 
-  hb_vector_t<feature_map_t> features;
+  hb_sorted_vector_t<feature_map_t> features;
   hb_vector_t<lookup_map_t> lookups[2]; /* GSUB/GPOS */
   hb_vector_t<stage_map_t> stages[2]; /* GSUB/GPOS */
 };
@@ -247,7 +247,7 @@
     unsigned int default_value; /* for non-global features, what should the unset glyphs take */
     unsigned int stage[2]; /* GSUB/GPOS */
 
-    static int cmp (const void *pa, const void *pb)
+    HB_INTERNAL static int cmp (const void *pa, const void *pb)
     {
       const feature_info_t *a = (const feature_info_t *) pa;
       const feature_info_t *b = (const feature_info_t *) pb;

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -664,7 +664,7 @@
   /* Array of offsets to MathGlyphConstruction tables - from the beginning of
      the MathVariants table, for shapes growing in vertical/horizontal
      direction. */
-  UnsizedArrayOf<OffsetTo<MathGlyphConstruction> >
+  UnsizedArrayOf<OffsetTo<MathGlyphConstruction>>
  			glyphConstruction;
 
   public:

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -37,6 +37,11 @@
  * @include: hb-ot.h
  *
  * Functions for fetching mathematics layout data from OpenType fonts.
+ *
+ * HarfBuzz itself does not implement a math layout solution. The
+ * functions and types provided can be used by client programs to access
+ * the font data necessary for typesetting OpenType Math layout.
+ *
  **/
 
 
@@ -48,10 +53,9 @@
  * hb_ot_math_has_data:
  * @face: #hb_face_t to test
  *
- * This function allows to verify the presence of an OpenType MATH table on the
- * face.
+ * Tests whether a face has a `MATH` table.
  *
- * Return value: true if face has a MATH table, false otherwise
+ * Return value: true if the table is found, false otherwise
  *
  * Since: 1.3.3
  **/
@@ -58,22 +62,28 @@
 hb_bool_t
 hb_ot_math_has_data (hb_face_t *face)
 {
+#ifdef HB_NO_MATH
+  return false;
+#endif
+
   return face->table.MATH->has_data ();
 }
 
 /**
  * hb_ot_math_get_constant:
- * @font: #hb_font_t from which to retrieve the value
+ * @font: #hb_font_t to work upon
  * @constant: #hb_ot_math_constant_t the constant to retrieve
  *
- * This function returns the requested math constants as a #hb_position_t.
- * If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
- * HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
- * HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is
- * actually an integer between 0 and 100 representing that percentage.
+ * Fetches the specified math constant. For most constants, the value returned
+ * is an #hb_position_t.
  *
- * Return value: the requested constant or 0
+ * However, if the requested constant is #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
+ * #HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
+ * #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, then the return value is
+ * an integer between 0 and 100 representing that percentage.
  *
+ * Return value: the requested constant or zero
+ *
  * Since: 1.3.3
  **/
 hb_position_t
@@ -80,16 +90,23 @@
 hb_ot_math_get_constant (hb_font_t *font,
 			 hb_ot_math_constant_t constant)
 {
+#ifdef HB_NO_MATH
+  return 0;
+#endif
+
   return font->face->table.MATH->get_constant(constant, font);
 }
 
 /**
  * hb_ot_math_get_glyph_italics_correction:
- * @font: #hb_font_t from which to retrieve the value
- * @glyph: glyph index from which to retrieve the value
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph index from which to retrieve the value
  *
- * Return value: the italics correction of the glyph or 0
+ * Fetches an italics-correction value (if one exists) for the specified
+ * glyph index.
  *
+  * Return value: the italics correction of the glyph or zero
+ *
  * Since: 1.3.3
  **/
 hb_position_t
@@ -96,16 +113,30 @@
 hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
 					 hb_codepoint_t glyph)
 {
+#ifdef HB_NO_MATH
+  return 0;
+#endif
+
   return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font);
 }
 
 /**
  * hb_ot_math_get_glyph_top_accent_attachment:
- * @font: #hb_font_t from which to retrieve the value
- * @glyph: glyph index from which to retrieve the value
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph index from which to retrieve the value
  *
- * Return value: the top accent attachment of the glyph or 0
+ * Fetches a top-accent-attachment value (if one exists) for the specified
+ * glyph index.
  *
+ * For any glyph that does not have a top-accent-attachment value - that is,
+ * a glyph not covered by the `MathTopAccentAttachment` table (or, when
+ * @font has no `MathTopAccentAttachment` table or no `MATH` table, any
+ * glyph) - the function synthesizes a value, returning the position at
+ * one-half the glyph's advance width.
+ *
+ * Return value: the top accent attachment of the glyph or 0.5 * the advance
+ *               width of @glyph
+ *
  * Since: 1.3.3
  **/
 hb_position_t
@@ -112,14 +143,20 @@
 hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
 					    hb_codepoint_t glyph)
 {
+#ifdef HB_NO_MATH
+  return 0;
+#endif
+
   return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font);
 }
 
 /**
  * hb_ot_math_is_glyph_extended_shape:
- * @face: a #hb_face_t to test
- * @glyph: a glyph index to test
+ * @face: #hb_face_t to work upon
+ * @glyph: The glyph index to test
  *
+ * Tests whether the given glyph index is an extended shape in the face.
+ *
  * Return value: true if the glyph is an extended shape, false otherwise
  *
  * Since: 1.3.3
@@ -128,24 +165,30 @@
 hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
 				    hb_codepoint_t glyph)
 {
+#ifdef HB_NO_MATH
+  return false;
+#endif
+
   return face->table.MATH->get_glyph_info().is_extended_shape (glyph);
 }
 
 /**
  * hb_ot_math_get_glyph_kerning:
- * @font: #hb_font_t from which to retrieve the value
- * @glyph: glyph index from which to retrieve the value
- * @kern: the #hb_ot_math_kern_t from which to retrieve the value
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph index from which to retrieve the value
+ * @kern: The #hb_ot_math_kern_t from which to retrieve the value
  * @correction_height: the correction height to use to determine the kerning.
  *
- * This function tries to retrieve the MathKern table for the specified font,
- * glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the
- * MathKern table to find one value that is greater or equal to specified
- * correction_height. If one is found the corresponding value from the list of
- * kerns is returned and otherwise the last kern value is returned.
+ * Fetches the math kerning (cut-ins) value for the specified font, glyph index, and
+ * @kern. 
  *
- * Return value: requested kerning or 0
+ * If the MathKern table is found, the function examines it to find a height
+ * value that is greater or equal to @correction_height. If such a height
+ * value is found, corresponding kerning value from the table is returned. If
+ * no such height value is found, the last kerning value is returned.
  *
+ * Return value: requested kerning value or zero
+ *
  * Since: 1.3.3
  **/
 hb_position_t
@@ -154,6 +197,10 @@
 			      hb_ot_math_kern_t kern,
 			      hb_position_t correction_height)
 {
+#ifdef HB_NO_MATH
+  return 0;
+#endif
+
   return font->face->table.MATH->get_glyph_info().get_kerning (glyph,
 							       kern,
 							       correction_height,
@@ -162,21 +209,25 @@
 
 /**
  * hb_ot_math_get_glyph_variants:
- * @font: #hb_font_t from which to retrieve the values
- * @glyph: index of the glyph to stretch
- * @direction: direction of the stretching
+ * @font: #hb_font_t to work upon
+ * @glyph: The index of the glyph to stretch
+ * @direction: The direction of the stretching (horizontal or vertical)
  * @start_offset: offset of the first variant to retrieve
- * @variants_count: maximum number of variants to retrieve after start_offset
- * (IN) and actual number of variants retrieved (OUT)
- * @variants: array of size at least @variants_count to store the result
+ * @variants_count: (inout): Input = the maximum number of variants to return;
+ *                           Output = the actual number of variants returned
+ * @variants: (out) (array length=variants_count): array of variants returned
  *
- * This function tries to retrieve the MathGlyphConstruction for the specified
- * font, glyph and direction. Note that only the value of
- * #HB_DIRECTION_IS_HORIZONTAL is considered. It provides the corresponding list
- * of size variants as an array of hb_ot_math_glyph_variant_t structs.
+ * Fetches the MathGlyphConstruction for the specified font, glyph index, and
+ * direction. The corresponding list of size variants is returned as a list of
+ * #hb_ot_math_glyph_variant_t structs.
  *
- * Return value: the total number of size variants available or 0
+ * <note>The @direction parameter is only used to select between horizontal
+ * or vertical directions for the construction. Even though all #hb_direction_t
+ * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
+ * considered.</note> 
  *
+ * Return value: the total number of size variants available or zero
+ *
  * Since: 1.3.3
  **/
 unsigned int
@@ -187,6 +238,12 @@
 			       unsigned int *variants_count, /* IN/OUT */
 			       hb_ot_math_glyph_variant_t *variants /* OUT */)
 {
+#ifdef HB_NO_MATH
+  if (variants_count)
+    *variants_count = 0;
+  return 0;
+#endif
+
   return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font,
 								    start_offset,
 								    variants_count,
@@ -195,16 +252,20 @@
 
 /**
  * hb_ot_math_get_min_connector_overlap:
- * @font: #hb_font_t from which to retrieve the value
- * @direction: direction of the stretching
+ * @font: #hb_font_t to work upon
+ * @direction: direction of the stretching (horizontal or vertical)
  *
- * This function tries to retrieve the MathVariants table for the specified
- * font and returns the minimum overlap of connecting glyphs to draw a glyph
- * assembly in the specified direction. Note that only the value of
- * #HB_DIRECTION_IS_HORIZONTAL is considered.
+ * Fetches the MathVariants table for the specified font and returns the
+ * minimum overlap of connecting glyphs that are required to draw a glyph
+ * assembly in the specified direction.
  *
- * Return value: requested min connector overlap or 0
+ * <note>The @direction parameter is only used to select between horizontal
+ * or vertical directions for the construction. Even though all #hb_direction_t
+ * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
+ * considered.</note> 
  *
+ * Return value: requested minimum connector overlap or zero
+ *
  * Since: 1.3.3
  **/
 hb_position_t
@@ -211,25 +272,34 @@
 hb_ot_math_get_min_connector_overlap (hb_font_t *font,
 				      hb_direction_t direction)
 {
+#ifdef HB_NO_MATH
+  return 0;
+#endif
+
   return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font);
 }
 
 /**
  * hb_ot_math_get_glyph_assembly:
- * @font: #hb_font_t from which to retrieve the values
- * @glyph: index of the glyph to stretch
- * @direction: direction of the stretching
+ * @font: #hb_font_t to work upon
+ * @glyph: The index of the glyph to stretch
+ * @direction: direction of the stretching (horizontal or vertical)
  * @start_offset: offset of the first glyph part to retrieve
- * @parts_count: maximum number of glyph parts to retrieve after start_offset
- * (IN) and actual number of parts retrieved (OUT)
- * @parts: array of size at least @parts_count to store the result
- * @italics_correction: italic correction of the glyph assembly
+ * @parts_count: (inout): Input = maximum number of glyph parts to return;
+ *               Output = actual number of parts returned
+ * @parts: (out) (array length=parts_count): the glyph parts returned
+ * @italics_correction: (out): italics correction of the glyph assembly
  *
- * This function tries to retrieve the GlyphAssembly for the specified font,
- * glyph and direction. Note that only the value of #HB_DIRECTION_IS_HORIZONTAL
- * is considered. It provides the information necessary to draw the glyph
- * assembly as an array of #hb_ot_math_glyph_part_t.
+ * Fetches the GlyphAssembly for the specified font, glyph index, and direction.
+ * Returned are a list of #hb_ot_math_glyph_part_t glyph parts that can be
+ * used to draw the glyph and an italics-correction value (if one is defined
+ * in the font).
  *
+ * <note>The @direction parameter is only used to select between horizontal
+ * or vertical directions for the construction. Even though all #hb_direction_t
+ * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
+ * considered.</note> 
+ *
  * Return value: the total number of parts in the glyph assembly
  *
  * Since: 1.3.3
@@ -243,6 +313,12 @@
 			       hb_ot_math_glyph_part_t *parts, /* OUT */
 			       hb_position_t *italics_correction /* OUT */)
 {
+#ifdef HB_NO_MATH
+  if (parts_count)
+    *parts_count = 0;
+  return 0;
+#endif
+
   return font->face->table.MATH->get_variants().get_glyph_parts (glyph,
 								 direction,
 								 font,

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.h	2019-05-24 23:03:55 UTC (rev 51218)
@@ -50,6 +50,9 @@
 /**
  * hb_ot_math_constant_t:
  *
+ * The 'MATH' table constants specified at
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/math
+ *
  * Since: 1.3.3
  */
 typedef enum {
@@ -114,6 +117,9 @@
 /**
  * hb_ot_math_kern_t:
  *
+ * The math kerning-table types defined for the four corners
+ * of a glyph.
+ *
  * Since: 1.3.3
  */
 typedef enum {
@@ -125,7 +131,11 @@
 
 /**
  * hb_ot_math_glyph_variant_t:
+ * @glyph: The glyph index of the variant
+ * @advance: The advance width of the variant
  *
+ * Data type to hold math-variant information for a glyph.
+ *
  * Since: 1.3.3
  */
 typedef struct hb_ot_math_glyph_variant_t {
@@ -136,6 +146,8 @@
 /**
  * hb_ot_math_glyph_part_flags_t:
  *
+ * Flags for math glyph parts.
+ *
  * Since: 1.3.3
  */
 typedef enum { /*< flags >*/
@@ -144,6 +156,15 @@
 
 /**
  * hb_ot_math_glyph_part_t:
+ * @glyph: The glyph index of the variant part
+ * @start_connector_length: The length of the connector on the starting side of the variant part
+ * @end_connection_length: The length of the conector on the ending side of the variant part
+ * @full_advance: The total advance of the part
+ * @flags: #hb_ot_math_glyph_part_flags_t flags for the part
+ * 
+ * Data type to hold information for a "part" component of a math-variant glyph.
+ * Large variants for stretchable math glyphs (such as parentheses) can be constructed
+ * on the fly from parts.
  *
  * Since: 1.3.3
  */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -77,7 +77,7 @@
 
   void set_num_glyphs (unsigned int count)
   {
-    numGlyphs.set (count);
+    numGlyphs = count;
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -119,13 +119,13 @@
     if (maxp_prime->version.major == 1)
     {
       maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*maxp_prime);
-      v1.maxZones.set (1);
-      v1.maxTwilightPoints.set (0);
-      v1.maxStorage.set (0);
-      v1.maxFunctionDefs.set (0);
-      v1.maxInstructionDefs.set (0);
-      v1.maxStackElements.set (0);
-      v1.maxSizeOfInstructions.set (0);
+      v1.maxZones = 1;
+      v1.maxTwilightPoints = 0;
+      v1.maxStorage = 0;
+      v1.maxFunctionDefs = 0;
+      v1.maxInstructionDefs = 0;
+      v1.maxStackElements = 0;
+      v1.maxSizeOfInstructions = 0;
     }
   }
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,465 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_NAME_LANGUAGE_STATIC_HH
+#define HB_OT_NAME_LANGUAGE_STATIC_HH
+
+#include "hb-ot-name-language.hh"
+
+/* Following two tables were generated by joining FreeType, FontConfig,
+ * and OpenType specification language lists, then filled in missing
+ * entries using:
+ * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings
+ */
+
+struct hb_ot_language_map_t
+{
+  static int cmp (const void *key, const void *item)
+  {
+    unsigned int a = * (unsigned int *) key;
+    unsigned int b = ((const hb_ot_language_map_t *) item)->code;
+    return a < b ? -1 : a > b ? +1 : 0;
+  }
+
+  uint16_t	code;
+  char		lang[6];
+};
+
+static const hb_ot_language_map_t
+hb_ms_language_map[] =
+{
+  {0x0001,	"ar"},	/* ??? */
+  {0x0004,	"zh"},	/* ??? */
+  {0x0009,	"en"},	/* ??? */
+  {0x0401,	"ar"},	/* Arabic (Saudi Arabia) */
+  {0x0402,	"bg"},	/* Bulgarian (Bulgaria) */
+  {0x0403,	"ca"},	/* Catalan (Catalan) */
+  {0x0404,	"zh-tw"},	/* Chinese (Taiwan) */
+  {0x0405,	"cs"},	/* Czech (Czech Republic) */
+  {0x0406,	"da"},	/* Danish (Denmark) */
+  {0x0407,	"de"},	/* German (Germany) */
+  {0x0408,	"el"},	/* Greek (Greece) */
+  {0x0409,	"en"},	/* English (United States) */
+  {0x040A,	"es"},	/* Spanish (Traditional Sort) (Spain) */
+  {0x040B,	"fi"},	/* Finnish (Finland) */
+  {0x040C,	"fr"},	/* French (France) */
+  {0x040D,	"he"},	/* Hebrew (Israel) */
+  {0x040E,	"hu"},	/* Hungarian (Hungary) */
+  {0x040F,	"is"},	/* Icelandic (Iceland) */
+  {0x0410,	"it"},	/* Italian (Italy) */
+  {0x0411,	"ja"},	/* Japanese (Japan) */
+  {0x0412,	"ko"},	/* Korean (Korea) */
+  {0x0413,	"nl"},	/* Dutch (Netherlands) */
+  {0x0414,	"no"},	/* Norwegian (Bokmal) (Norway) */
+  {0x0415,	"pl"},	/* Polish (Poland) */
+  {0x0416,	"pt"},	/* Portuguese (Brazil) */
+  {0x0417,	"rm"},	/* Romansh (Switzerland) */
+  {0x0418,	"ro"},	/* Romanian (Romania) */
+  {0x0419,	"ru"},	/* Russian (Russia) */
+  {0x041A,	"hr"},	/* Croatian (Croatia) */
+  {0x041B,	"sk"},	/* Slovak (Slovakia) */
+  {0x041C,	"sq"},	/* Albanian (Albania) */
+  {0x041D,	"sv"},	/* Swedish (Sweden) */
+  {0x041E,	"th"},	/* Thai (Thailand) */
+  {0x041F,	"tr"},	/* Turkish (Turkey) */
+  {0x0420,	"ur"},	/* Urdu (Islamic Republic of Pakistan) */
+  {0x0421,	"id"},	/* Indonesian (Indonesia) */
+  {0x0422,	"uk"},	/* Ukrainian (Ukraine) */
+  {0x0423,	"be"},	/* Belarusian (Belarus) */
+  {0x0424,	"sl"},	/* Slovenian (Slovenia) */
+  {0x0425,	"et"},	/* Estonian (Estonia) */
+  {0x0426,	"lv"},	/* Latvian (Latvia) */
+  {0x0427,	"lt"},	/* Lithuanian (Lithuania) */
+  {0x0428,	"tg"},	/* Tajik (Cyrillic) (Tajikistan) */
+  {0x0429,	"fa"},	/* Persian (Iran) */
+  {0x042A,	"vi"},	/* Vietnamese (Vietnam) */
+  {0x042B,	"hy"},	/* Armenian (Armenia) */
+  {0x042C,	"az"},	/* Azeri (Latin) (Azerbaijan) */
+  {0x042D,	"eu"},	/* Basque (Basque) */
+  {0x042E,	"hsb"},	/* Upper Sorbian (Germany) */
+  {0x042F,	"mk"},	/* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */
+  {0x0430,	"st"},	/* ??? */
+  {0x0431,	"ts"},	/* ??? */
+  {0x0432,	"tn"},	/* Setswana (South Africa) */
+  {0x0433,	"ven"},	/* ??? */
+  {0x0434,	"xh"},	/* isiXhosa (South Africa) */
+  {0x0435,	"zu"},	/* isiZulu (South Africa) */
+  {0x0436,	"af"},	/* Afrikaans (South Africa) */
+  {0x0437,	"ka"},	/* Georgian (Georgia) */
+  {0x0438,	"fo"},	/* Faroese (Faroe Islands) */
+  {0x0439,	"hi"},	/* Hindi (India) */
+  {0x043A,	"mt"},	/* Maltese (Malta) */
+  {0x043B,	"se"},	/* Sami (Northern) (Norway) */
+  {0x043C,	"ga"},	/* ??? */
+  {0x043D,	"yi"},	/* ??? */
+  {0x043E,	"ms"},	/* Malay (Malaysia) */
+  {0x043F,	"kk"},	/* Kazakh (Kazakhstan) */
+  {0x0440,	"ky"},	/* Kyrgyz (Kyrgyzstan) */
+  {0x0441,	"sw"},	/* Kiswahili (Kenya) */
+  {0x0442,	"tk"},	/* Turkmen (Turkmenistan) */
+  {0x0443,	"uz"},	/* Uzbek (Latin) (Uzbekistan) */
+  {0x0444,	"tt"},	/* Tatar (Russia) */
+  {0x0445,	"bn"},	/* Bengali (India) */
+  {0x0446,	"pa"},	/* Punjabi (India) */
+  {0x0447,	"gu"},	/* Gujarati (India) */
+  {0x0448,	"or"},	/* Odia (formerly Oriya) (India) */
+  {0x0449,	"ta"},	/* Tamil (India) */
+  {0x044A,	"te"},	/* Telugu (India) */
+  {0x044B,	"kn"},	/* Kannada (India) */
+  {0x044C,	"ml"},	/* Malayalam (India) */
+  {0x044D,	"as"},	/* Assamese (India) */
+  {0x044E,	"mr"},	/* Marathi (India) */
+  {0x044F,	"sa"},	/* Sanskrit (India) */
+  {0x0450,	"mn"},	/* Mongolian (Cyrillic) (Mongolia) */
+  {0x0451,	"bo"},	/* Tibetan (PRC) */
+  {0x0452,	"cy"},	/* Welsh (United Kingdom) */
+  {0x0453,	"km"},	/* Khmer (Cambodia) */
+  {0x0454,	"lo"},	/* Lao (Lao P.D.R.) */
+  {0x0455,	"my"},	/* ??? */
+  {0x0456,	"gl"},	/* Galician (Galician) */
+  {0x0457,	"kok"},	/* Konkani (India) */
+  {0x0458,	"mni"},	/* ??? */
+  {0x0459,	"sd"},	/* ??? */
+  {0x045A,	"syr"},	/* Syriac (Syria) */
+  {0x045B,	"si"},	/* Sinhala (Sri Lanka) */
+  {0x045C,	"chr"},	/* ??? */
+  {0x045D,	"iu"},	/* Inuktitut (Canada) */
+  {0x045E,	"am"},	/* Amharic (Ethiopia) */
+  {0x0460,	"ks"},	/* ??? */
+  {0x0461,	"ne"},	/* Nepali (Nepal) */
+  {0x0462,	"fy"},	/* Frisian (Netherlands) */
+  {0x0463,	"ps"},	/* Pashto (Afghanistan) */
+  {0x0464,	"phi"},	/* Filipino (Philippines) */
+  {0x0465,	"div"},	/* Divehi (Maldives) */
+  {0x0468,	"ha"},	/* Hausa (Latin) (Nigeria) */
+  {0x046A,	"yo"},	/* Yoruba (Nigeria) */
+  {0x046B,	"quz"},	/* Quechua (Bolivia) */
+  {0x046C,	"nso"},	/* Sesotho sa Leboa (South Africa) */
+  {0x046D,	"ba"},	/* Bashkir (Russia) */
+  {0x046E,	"lb"},	/* Luxembourgish (Luxembourg) */
+  {0x046F,	"kl"},	/* Greenlandic (Greenland) */
+  {0x0470,	"ibo"},	/* Igbo (Nigeria) */
+  {0x0471,	"kau"},	/* ??? */
+  {0x0472,	"om"},	/* ??? */
+  {0x0473,	"ti"},	/* ??? */
+  {0x0474,	"gn"},	/* ??? */
+  {0x0475,	"haw"},	/* ??? */
+  {0x0476,	"la"},	/* ??? */
+  {0x0477,	"so"},	/* ??? */
+  {0x0478,	"ii"},	/* Yi (PRC) */
+  {0x0479,	"pap"},	/* ??? */
+  {0x047A,	"arn"},	/* Mapudungun (Chile) */
+  {0x047C,	"moh"},	/* Mohawk (Mohawk) */
+  {0x047E,	"br"},	/* Breton (France) */
+  {0x0480,	"ug"},	/* Uighur (PRC) */
+  {0x0481,	"mi"},	/* Maori (New Zealand) */
+  {0x0482,	"oc"},	/* Occitan (France) */
+  {0x0483,	"co"},	/* Corsican (France) */
+  {0x0484,	"gsw"},	/* Alsatian (France) */
+  {0x0485,	"sah"},	/* Yakut (Russia) */
+  {0x0486,	"qut"},	/* K'iche (Guatemala) */
+  {0x0487,	"rw"},	/* Kinyarwanda (Rwanda) */
+  {0x0488,	"wo"},	/* Wolof (Senegal) */
+  {0x048C,	"fa"},	/* Dari (Afghanistan) */
+  {0x0801,	"ar"},	/* Arabic (Iraq) */
+  {0x0804,	"zh-cn"},	/* Chinese (People’s Republic of China) */
+  {0x0807,	"de"},	/* German (Switzerland) */
+  {0x0809,	"en"},	/* English (United Kingdom) */
+  {0x080A,	"es"},	/* Spanish (Mexico) */
+  {0x080C,	"fr"},	/* French (Belgium) */
+  {0x0810,	"it"},	/* Italian (Switzerland) */
+  {0x0812,	"ko"},	/* ??? */
+  {0x0813,	"nl"},	/* Dutch (Belgium) */
+  {0x0814,	"nn"},	/* Norwegian (Nynorsk) (Norway) */
+  {0x0816,	"pt"},	/* Portuguese (Portugal) */
+  {0x0818,	"mo"},	/* ??? */
+  {0x0819,	"ru"},	/* ??? */
+  {0x081A,	"sr"},	/* Serbian (Latin) (Serbia) */
+  {0x081D,	"sv"},	/* Sweden (Finland) */
+  {0x0820,	"ur"},	/* ??? */
+  {0x0827,	"lt"},	/* ??? */
+  {0x082C,	"az"},	/* Azeri (Cyrillic) (Azerbaijan) */
+  {0x082E,	"dsb"},	/* Lower Sorbian (Germany) */
+//{0x083B,	""},	/* Sami (Northern) (Sweden) */
+  {0x083C,	"gd"},	/* Irish (Ireland) */
+  {0x083E,	"ms"},	/* Malay (Brunei Darussalam) */
+  {0x0843,	"uz"},	/* Uzbek (Cyrillic) (Uzbekistan) */
+  {0x0845,	"bn"},	/* Bengali (Bangladesh) */
+  {0x0846,	"ar"},	/* ??? */
+  {0x0850,	"mn"},	/* Mongolian (Traditional) (People’s Republic of China) */
+  {0x0851,	"dz"},	/* ??? */
+  {0x085D,	"iu"},	/* Inuktitut (Latin) (Canada) */
+  {0x085F,	"tzm"},	/* Tamazight (Latin) (Algeria) */
+  {0x0861,	"ne"},	/* ??? */
+//{0x086B,	""},	/* Quechua (Ecuador) */
+  {0x0873,	"ti"},	/* ??? */
+  {0x0C01,	"ar"},	/* Arabic (Egypt) */
+  {0x0C04,	"zh-hk"},	/* Chinese (Hong Kong S.A.R.) */
+  {0x0C07,	"de"},	/* German (Austria) */
+  {0x0C09,	"en"},	/* English (Australia) */
+  {0x0C0A,	"es"},	/* Spanish (Modern Sort) (Spain) */
+  {0x0C0C,	"fr"},	/* French (Canada) */
+  {0x0C1A,	"sr"},	/* Serbian (Cyrillic) (Serbia) */
+  {0x0C3B,	"se"},	/* Sami (Northern) (Finland) */
+//{0x0C6B,	""},	/* Quechua (Peru) */
+  {0x1001,	"ar"},	/* Arabic (Libya) */
+  {0x1004,	"zh-sg"},	/* Chinese (Singapore) */
+  {0x1007,	"de"},	/* German (Luxembourg) */
+  {0x1009,	"en"},	/* English (Canada) */
+  {0x100A,	"es"},	/* Spanish (Guatemala) */
+  {0x100C,	"fr"},	/* French (Switzerland) */
+  {0x101A,	"hr"},	/* Croatian (Latin) (Bosnia and Herzegovina) */
+  {0x103B,	"smj"},	/* Sami (Lule) (Norway) */
+  {0x1401,	"ar"},	/* Arabic (Algeria) */
+//{0x1404,	""},	/* Chinese (Macao S.A.R.) */
+  {0x1407,	"de"},	/* German (Liechtenstein) */
+  {0x1409,	"en"},	/* English (New Zealand) */
+  {0x140A,	"es"},	/* Spanish (Costa Rica) */
+  {0x140C,	"fr"},	/* French (Luxembourg) */
+  {0x141A,	"bs"},	/* Bosnian (Latin) (Bosnia and Herzegovina) */
+//{0x143B,	""},	/* Sami (Lule) (Sweden) */
+  {0x1801,	"ar"},	/* Arabic (Morocco) */
+  {0x1809,	"en"},	/* English (Ireland) */
+  {0x180A,	"es"},	/* Spanish (Panama) */
+  {0x180C,	"fr"},	/* French (Principality of Monaco) */
+//{0x181A,	""},	/* Serbian (Latin) (Bosnia and Herzegovina) */
+  {0x183B,	"sma"},	/* Sami (Southern) (Norway) */
+  {0x1C01,	"ar"},	/* Arabic (Tunisia) */
+  {0x1C09,	"en"},	/* English (South Africa) */
+  {0x1C0A,	"es"},	/* Spanish (Dominican Republic) */
+  {0x1C0C,	"fr"},	/* ??? */
+//{0x1C1A,	""},	/* Serbian (Cyrillic) (Bosnia and Herzegovina) */
+//{0x1C3B,	""},	/* Sami (Southern) (Sweden) */
+  {0x2001,	"ar"},	/* Arabic (Oman) */
+  {0x2009,	"en"},	/* English (Jamaica) */
+  {0x200A,	"es"},	/* Spanish (Venezuela) */
+  {0x200C,	"fr"},	/* ??? */
+  {0x201A,	"bs"},	/* Bosnian (Cyrillic) (Bosnia and Herzegovina) */
+  {0x203B,	"sms"},	/* Sami (Skolt) (Finland) */
+  {0x2401,	"ar"},	/* Arabic (Yemen) */
+  {0x2409,	"en"},	/* English (Caribbean) */
+  {0x240A,	"es"},	/* Spanish (Colombia) */
+  {0x240C,	"fr"},	/* ??? */
+  {0x243B,	"smn"},	/* Sami (Inari) (Finland) */
+  {0x2801,	"ar"},	/* Arabic (Syria) */
+  {0x2809,	"en"},	/* English (Belize) */
+  {0x280A,	"es"},	/* Spanish (Peru) */
+  {0x280C,	"fr"},	/* ??? */
+  {0x2C01,	"ar"},	/* Arabic (Jordan) */
+  {0x2C09,	"en"},	/* English (Trinidad and Tobago) */
+  {0x2C0A,	"es"},	/* Spanish (Argentina) */
+  {0x2C0C,	"fr"},	/* ??? */
+  {0x3001,	"ar"},	/* Arabic (Lebanon) */
+  {0x3009,	"en"},	/* English (Zimbabwe) */
+  {0x300A,	"es"},	/* Spanish (Ecuador) */
+  {0x300C,	"fr"},	/* ??? */
+  {0x3401,	"ar"},	/* Arabic (Kuwait) */
+  {0x3409,	"en"},	/* English (Republic of the Philippines) */
+  {0x340A,	"es"},	/* Spanish (Chile) */
+  {0x340C,	"fr"},	/* ??? */
+  {0x3801,	"ar"},	/* Arabic (U.A.E.) */
+  {0x380A,	"es"},	/* Spanish (Uruguay) */
+  {0x380C,	"fr"},	/* ??? */
+  {0x3C01,	"ar"},	/* Arabic (Bahrain) */
+  {0x3C09,	"en"},	/* ??? */
+  {0x3C0A,	"es"},	/* Spanish (Paraguay) */
+  {0x3C0C,	"fr"},	/* ??? */
+  {0x4001,	"ar"},	/* Arabic (Qatar) */
+  {0x4009,	"en"},	/* English (India) */
+  {0x400A,	"es"},	/* Spanish (Bolivia) */
+  {0x4409,	"en"},	/* English (Malaysia) */
+  {0x440A,	"es"},	/* Spanish (El Salvador) */
+  {0x4809,	"en"},	/* English (Singapore) */
+  {0x480A,	"es"},	/* Spanish (Honduras) */
+  {0x4C0A,	"es"},	/* Spanish (Nicaragua) */
+  {0x500A,	"es"},	/* Spanish (Puerto Rico) */
+  {0x540A,	"es"},	/* Spanish (United States) */
+  {0xE40A,	"es"},	/* ??? */
+  {0xE40C,	"fr"},	/* ??? */
+};
+
+static const hb_ot_language_map_t
+hb_mac_language_map[] =
+{
+  {  0,	"en"},	/* English */
+  {  1,	"fr"},	/* French */
+  {  2,	"de"},	/* German */
+  {  3,	"it"},	/* Italian */
+  {  4,	"nl"},	/* Dutch */
+  {  5,	"sv"},	/* Swedish */
+  {  6,	"es"},	/* Spanish */
+  {  7,	"da"},	/* Danish */
+  {  8,	"pt"},	/* Portuguese */
+  {  9,	"no"},	/* Norwegian */
+  { 10,	"he"},	/* Hebrew */
+  { 11,	"ja"},	/* Japanese */
+  { 12,	"ar"},	/* Arabic */
+  { 13,	"fi"},	/* Finnish */
+  { 14,	"el"},	/* Greek */
+  { 15,	"is"},	/* Icelandic */
+  { 16,	"mt"},	/* Maltese */
+  { 17,	"tr"},	/* Turkish */
+  { 18,	"hr"},	/* Croatian */
+  { 19,	"zh-tw"},	/* Chinese (Traditional) */
+  { 20,	"ur"},	/* Urdu */
+  { 21,	"hi"},	/* Hindi */
+  { 22,	"th"},	/* Thai */
+  { 23,	"ko"},	/* Korean */
+  { 24,	"lt"},	/* Lithuanian */
+  { 25,	"pl"},	/* Polish */
+  { 26,	"hu"},	/* Hungarian */
+  { 27,	"et"},	/* Estonian */
+  { 28,	"lv"},	/* Latvian */
+//{ 29,	""},	/* Sami */
+  { 30,	"fo"},	/* Faroese */
+  { 31,	"fa"},	/* Farsi/Persian */
+  { 32,	"ru"},	/* Russian */
+  { 33,	"zh-cn"},	/* Chinese (Simplified) */
+  { 34,	"nl"},	/* Flemish */
+  { 35,	"ga"},	/* Irish Gaelic */
+  { 36,	"sq"},	/* Albanian */
+  { 37,	"ro"},	/* Romanian */
+  { 38,	"cs"},	/* Czech */
+  { 39,	"sk"},	/* Slovak */
+  { 40,	"sl"},	/* Slovenian */
+  { 41,	"yi"},	/* Yiddish */
+  { 42,	"sr"},	/* Serbian */
+  { 43,	"mk"},	/* Macedonian */
+  { 44,	"bg"},	/* Bulgarian */
+  { 45,	"uk"},	/* Ukrainian */
+  { 46,	"be"},	/* Byelorussian */
+  { 47,	"uz"},	/* Uzbek */
+  { 48,	"kk"},	/* Kazakh */
+  { 49,	"az"},	/* Azerbaijani (Cyrillic script) */
+  { 50,	"az"},	/* Azerbaijani (Arabic script) */
+  { 51,	"hy"},	/* Armenian */
+  { 52,	"ka"},	/* Georgian */
+  { 53,	"mo"},	/* Moldavian */
+  { 54,	"ky"},	/* Kirghiz */
+  { 55,	"tg"},	/* Tajiki */
+  { 56,	"tk"},	/* Turkmen */
+  { 57,	"mn"},	/* Mongolian (Mongolian script) */
+  { 58,	"mn"},	/* Mongolian (Cyrillic script) */
+  { 59,	"ps"},	/* Pashto */
+  { 60,	"ku"},	/* Kurdish */
+  { 61,	"ks"},	/* Kashmiri */
+  { 62,	"sd"},	/* Sindhi */
+  { 63,	"bo"},	/* Tibetan */
+  { 64,	"ne"},	/* Nepali */
+  { 65,	"sa"},	/* Sanskrit */
+  { 66,	"mr"},	/* Marathi */
+  { 67,	"bn"},	/* Bengali */
+  { 68,	"as"},	/* Assamese */
+  { 69,	"gu"},	/* Gujarati */
+  { 70,	"pa"},	/* Punjabi */
+  { 71,	"or"},	/* Oriya */
+  { 72,	"ml"},	/* Malayalam */
+  { 73,	"kn"},	/* Kannada */
+  { 74,	"ta"},	/* Tamil */
+  { 75,	"te"},	/* Telugu */
+  { 76,	"si"},	/* Sinhalese */
+  { 77,	"my"},	/* Burmese */
+  { 78,	"km"},	/* Khmer */
+  { 79,	"lo"},	/* Lao */
+  { 80,	"vi"},	/* Vietnamese */
+  { 81,	"id"},	/* Indonesian */
+  { 82,	"tl"},	/* Tagalog */
+  { 83,	"ms"},	/* Malay (Roman script) */
+  { 84,	"ms"},	/* Malay (Arabic script) */
+  { 85,	"am"},	/* Amharic */
+  { 86,	"ti"},	/* Tigrinya */
+  { 87,	"om"},	/* Galla */
+  { 88,	"so"},	/* Somali */
+  { 89,	"sw"},	/* Swahili */
+  { 90,	"rw"},	/* Kinyarwanda/Ruanda */
+  { 91,	"rn"},	/* Rundi */
+  { 92,	"ny"},	/* Nyanja/Chewa */
+  { 93,	"mg"},	/* Malagasy */
+  { 94,	"eo"},	/* Esperanto */
+  {128,	"cy"},	/* Welsh */
+  {129,	"eu"},	/* Basque */
+  {130,	"ca"},	/* Catalan */
+  {131,	"la"},	/* Latin */
+  {132,	"qu"},	/* Quechua */
+  {133,	"gn"},	/* Guarani */
+  {134,	"ay"},	/* Aymara */
+  {135,	"tt"},	/* Tatar */
+  {136,	"ug"},	/* Uighur */
+  {137,	"dz"},	/* Dzongkha */
+  {138,	"jw"},	/* Javanese (Roman script) */
+  {139,	"su"},	/* Sundanese (Roman script) */
+  {140,	"gl"},	/* Galician */
+  {141,	"af"},	/* Afrikaans */
+  {142,	"br"},	/* Breton */
+  {143,	"iu"},	/* Inuktitut */
+  {144,	"gd"},	/* Scottish Gaelic */
+  {145,	"gv"},	/* Manx Gaelic */
+  {146,	"ga"},	/* Irish Gaelic (with dot above) */
+  {147,	"to"},	/* Tongan */
+  {148,	"el"},	/* Greek (polytonic) */
+  {149,	"ik"},	/* Greenlandic */
+  {150,	"az"},	/* Azerbaijani (Roman script) */
+};
+
+
+static hb_language_t
+_hb_ot_name_language_for (unsigned int code,
+			  const hb_ot_language_map_t *array,
+			  unsigned int len)
+{
+#ifdef HB_NO_OT_NAME_LANGUAGE
+  return HB_LANGUAGE_INVALID;
+#endif
+  const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *)
+				      hb_bsearch (&code,
+						  array,
+						  len,
+						  sizeof (array[0]),
+						  hb_ot_language_map_t::cmp);
+
+  if (entry)
+    return hb_language_from_string (entry->lang, -1);
+
+  return HB_LANGUAGE_INVALID;
+}
+
+hb_language_t
+_hb_ot_name_language_for_ms_code (unsigned int code)
+{
+  return _hb_ot_name_language_for (code,
+				   hb_ms_language_map,
+				   ARRAY_LENGTH (hb_ms_language_map));
+}
+
+hb_language_t
+_hb_ot_name_language_for_mac_code (unsigned int code)
+{
+  return _hb_ot_name_language_for (code,
+				   hb_mac_language_map,
+				   ARRAY_LENGTH (hb_mac_language_map));
+}
+
+#endif /* HB_OT_NAME_LANGUAGE_STATIC_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,457 +0,0 @@
-/*
- * Copyright © 2018  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb-ot-name-language.hh"
-
-/* Following two tables were generated by joining FreeType, FontConfig,
- * and OpenType specification language lists, then filled in missing
- * entries using:
- * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings
- */
-
-struct hb_ot_language_map_t
-{
-  static int cmp (const void *key, const void *item)
-  {
-    unsigned int a = * (unsigned int *) key;
-    unsigned int b = ((const hb_ot_language_map_t *) item)->code;
-    return a < b ? -1 : a > b ? +1 : 0;
-  }
-
-  uint16_t	code;
-  char		lang[6];
-};
-
-static const hb_ot_language_map_t
-hb_ms_language_map[] =
-{
-  {0x0001,	"ar"},	/* ??? */
-  {0x0004,	"zh"},	/* ??? */
-  {0x0009,	"en"},	/* ??? */
-  {0x0401,	"ar"},	/* Arabic (Saudi Arabia) */
-  {0x0402,	"bg"},	/* Bulgarian (Bulgaria) */
-  {0x0403,	"ca"},	/* Catalan (Catalan) */
-  {0x0404,	"zh-tw"},	/* Chinese (Taiwan) */
-  {0x0405,	"cs"},	/* Czech (Czech Republic) */
-  {0x0406,	"da"},	/* Danish (Denmark) */
-  {0x0407,	"de"},	/* German (Germany) */
-  {0x0408,	"el"},	/* Greek (Greece) */
-  {0x0409,	"en"},	/* English (United States) */
-  {0x040A,	"es"},	/* Spanish (Traditional Sort) (Spain) */
-  {0x040B,	"fi"},	/* Finnish (Finland) */
-  {0x040C,	"fr"},	/* French (France) */
-  {0x040D,	"he"},	/* Hebrew (Israel) */
-  {0x040E,	"hu"},	/* Hungarian (Hungary) */
-  {0x040F,	"is"},	/* Icelandic (Iceland) */
-  {0x0410,	"it"},	/* Italian (Italy) */
-  {0x0411,	"ja"},	/* Japanese (Japan) */
-  {0x0412,	"ko"},	/* Korean (Korea) */
-  {0x0413,	"nl"},	/* Dutch (Netherlands) */
-  {0x0414,	"no"},	/* Norwegian (Bokmal) (Norway) */
-  {0x0415,	"pl"},	/* Polish (Poland) */
-  {0x0416,	"pt"},	/* Portuguese (Brazil) */
-  {0x0417,	"rm"},	/* Romansh (Switzerland) */
-  {0x0418,	"ro"},	/* Romanian (Romania) */
-  {0x0419,	"ru"},	/* Russian (Russia) */
-  {0x041A,	"hr"},	/* Croatian (Croatia) */
-  {0x041B,	"sk"},	/* Slovak (Slovakia) */
-  {0x041C,	"sq"},	/* Albanian (Albania) */
-  {0x041D,	"sv"},	/* Swedish (Sweden) */
-  {0x041E,	"th"},	/* Thai (Thailand) */
-  {0x041F,	"tr"},	/* Turkish (Turkey) */
-  {0x0420,	"ur"},	/* Urdu (Islamic Republic of Pakistan) */
-  {0x0421,	"id"},	/* Indonesian (Indonesia) */
-  {0x0422,	"uk"},	/* Ukrainian (Ukraine) */
-  {0x0423,	"be"},	/* Belarusian (Belarus) */
-  {0x0424,	"sl"},	/* Slovenian (Slovenia) */
-  {0x0425,	"et"},	/* Estonian (Estonia) */
-  {0x0426,	"lv"},	/* Latvian (Latvia) */
-  {0x0427,	"lt"},	/* Lithuanian (Lithuania) */
-  {0x0428,	"tg"},	/* Tajik (Cyrillic) (Tajikistan) */
-  {0x0429,	"fa"},	/* Persian (Iran) */
-  {0x042A,	"vi"},	/* Vietnamese (Vietnam) */
-  {0x042B,	"hy"},	/* Armenian (Armenia) */
-  {0x042C,	"az"},	/* Azeri (Latin) (Azerbaijan) */
-  {0x042D,	"eu"},	/* Basque (Basque) */
-  {0x042E,	"hsb"},	/* Upper Sorbian (Germany) */
-  {0x042F,	"mk"},	/* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */
-  {0x0430,	"st"},	/* ??? */
-  {0x0431,	"ts"},	/* ??? */
-  {0x0432,	"tn"},	/* Setswana (South Africa) */
-  {0x0433,	"ven"},	/* ??? */
-  {0x0434,	"xh"},	/* isiXhosa (South Africa) */
-  {0x0435,	"zu"},	/* isiZulu (South Africa) */
-  {0x0436,	"af"},	/* Afrikaans (South Africa) */
-  {0x0437,	"ka"},	/* Georgian (Georgia) */
-  {0x0438,	"fo"},	/* Faroese (Faroe Islands) */
-  {0x0439,	"hi"},	/* Hindi (India) */
-  {0x043A,	"mt"},	/* Maltese (Malta) */
-  {0x043B,	"se"},	/* Sami (Northern) (Norway) */
-  {0x043C,	"ga"},	/* ??? */
-  {0x043D,	"yi"},	/* ??? */
-  {0x043E,	"ms"},	/* Malay (Malaysia) */
-  {0x043F,	"kk"},	/* Kazakh (Kazakhstan) */
-  {0x0440,	"ky"},	/* Kyrgyz (Kyrgyzstan) */
-  {0x0441,	"sw"},	/* Kiswahili (Kenya) */
-  {0x0442,	"tk"},	/* Turkmen (Turkmenistan) */
-  {0x0443,	"uz"},	/* Uzbek (Latin) (Uzbekistan) */
-  {0x0444,	"tt"},	/* Tatar (Russia) */
-  {0x0445,	"bn"},	/* Bengali (India) */
-  {0x0446,	"pa"},	/* Punjabi (India) */
-  {0x0447,	"gu"},	/* Gujarati (India) */
-  {0x0448,	"or"},	/* Odia (formerly Oriya) (India) */
-  {0x0449,	"ta"},	/* Tamil (India) */
-  {0x044A,	"te"},	/* Telugu (India) */
-  {0x044B,	"kn"},	/* Kannada (India) */
-  {0x044C,	"ml"},	/* Malayalam (India) */
-  {0x044D,	"as"},	/* Assamese (India) */
-  {0x044E,	"mr"},	/* Marathi (India) */
-  {0x044F,	"sa"},	/* Sanskrit (India) */
-  {0x0450,	"mn"},	/* Mongolian (Cyrillic) (Mongolia) */
-  {0x0451,	"bo"},	/* Tibetan (PRC) */
-  {0x0452,	"cy"},	/* Welsh (United Kingdom) */
-  {0x0453,	"km"},	/* Khmer (Cambodia) */
-  {0x0454,	"lo"},	/* Lao (Lao P.D.R.) */
-  {0x0455,	"my"},	/* ??? */
-  {0x0456,	"gl"},	/* Galician (Galician) */
-  {0x0457,	"kok"},	/* Konkani (India) */
-  {0x0458,	"mni"},	/* ??? */
-  {0x0459,	"sd"},	/* ??? */
-  {0x045A,	"syr"},	/* Syriac (Syria) */
-  {0x045B,	"si"},	/* Sinhala (Sri Lanka) */
-  {0x045C,	"chr"},	/* ??? */
-  {0x045D,	"iu"},	/* Inuktitut (Canada) */
-  {0x045E,	"am"},	/* Amharic (Ethiopia) */
-  {0x0460,	"ks"},	/* ??? */
-  {0x0461,	"ne"},	/* Nepali (Nepal) */
-  {0x0462,	"fy"},	/* Frisian (Netherlands) */
-  {0x0463,	"ps"},	/* Pashto (Afghanistan) */
-  {0x0464,	"phi"},	/* Filipino (Philippines) */
-  {0x0465,	"div"},	/* Divehi (Maldives) */
-  {0x0468,	"ha"},	/* Hausa (Latin) (Nigeria) */
-  {0x046A,	"yo"},	/* Yoruba (Nigeria) */
-  {0x046B,	"quz"},	/* Quechua (Bolivia) */
-  {0x046C,	"nso"},	/* Sesotho sa Leboa (South Africa) */
-  {0x046D,	"ba"},	/* Bashkir (Russia) */
-  {0x046E,	"lb"},	/* Luxembourgish (Luxembourg) */
-  {0x046F,	"kl"},	/* Greenlandic (Greenland) */
-  {0x0470,	"ibo"},	/* Igbo (Nigeria) */
-  {0x0471,	"kau"},	/* ??? */
-  {0x0472,	"om"},	/* ??? */
-  {0x0473,	"ti"},	/* ??? */
-  {0x0474,	"gn"},	/* ??? */
-  {0x0475,	"haw"},	/* ??? */
-  {0x0476,	"la"},	/* ??? */
-  {0x0477,	"so"},	/* ??? */
-  {0x0478,	"ii"},	/* Yi (PRC) */
-  {0x0479,	"pap"},	/* ??? */
-  {0x047A,	"arn"},	/* Mapudungun (Chile) */
-  {0x047C,	"moh"},	/* Mohawk (Mohawk) */
-  {0x047E,	"br"},	/* Breton (France) */
-  {0x0480,	"ug"},	/* Uighur (PRC) */
-  {0x0481,	"mi"},	/* Maori (New Zealand) */
-  {0x0482,	"oc"},	/* Occitan (France) */
-  {0x0483,	"co"},	/* Corsican (France) */
-  {0x0484,	"gsw"},	/* Alsatian (France) */
-  {0x0485,	"sah"},	/* Yakut (Russia) */
-  {0x0486,	"qut"},	/* K'iche (Guatemala) */
-  {0x0487,	"rw"},	/* Kinyarwanda (Rwanda) */
-  {0x0488,	"wo"},	/* Wolof (Senegal) */
-  {0x048C,	"fa"},	/* Dari (Afghanistan) */
-  {0x0801,	"ar"},	/* Arabic (Iraq) */
-  {0x0804,	"zh-cn"},	/* Chinese (People’s Republic of China) */
-  {0x0807,	"de"},	/* German (Switzerland) */
-  {0x0809,	"en"},	/* English (United Kingdom) */
-  {0x080A,	"es"},	/* Spanish (Mexico) */
-  {0x080C,	"fr"},	/* French (Belgium) */
-  {0x0810,	"it"},	/* Italian (Switzerland) */
-  {0x0812,	"ko"},	/* ??? */
-  {0x0813,	"nl"},	/* Dutch (Belgium) */
-  {0x0814,	"nn"},	/* Norwegian (Nynorsk) (Norway) */
-  {0x0816,	"pt"},	/* Portuguese (Portugal) */
-  {0x0818,	"mo"},	/* ??? */
-  {0x0819,	"ru"},	/* ??? */
-  {0x081A,	"sr"},	/* Serbian (Latin) (Serbia) */
-  {0x081D,	"sv"},	/* Sweden (Finland) */
-  {0x0820,	"ur"},	/* ??? */
-  {0x0827,	"lt"},	/* ??? */
-  {0x082C,	"az"},	/* Azeri (Cyrillic) (Azerbaijan) */
-  {0x082E,	"dsb"},	/* Lower Sorbian (Germany) */
-//{0x083B,	""},	/* Sami (Northern) (Sweden) */
-  {0x083C,	"gd"},	/* Irish (Ireland) */
-  {0x083E,	"ms"},	/* Malay (Brunei Darussalam) */
-  {0x0843,	"uz"},	/* Uzbek (Cyrillic) (Uzbekistan) */
-  {0x0845,	"bn"},	/* Bengali (Bangladesh) */
-  {0x0846,	"ar"},	/* ??? */
-  {0x0850,	"mn"},	/* Mongolian (Traditional) (People’s Republic of China) */
-  {0x0851,	"dz"},	/* ??? */
-  {0x085D,	"iu"},	/* Inuktitut (Latin) (Canada) */
-  {0x085F,	"tzm"},	/* Tamazight (Latin) (Algeria) */
-  {0x0861,	"ne"},	/* ??? */
-//{0x086B,	""},	/* Quechua (Ecuador) */
-  {0x0873,	"ti"},	/* ??? */
-  {0x0C01,	"ar"},	/* Arabic (Egypt) */
-  {0x0C04,	"zh-hk"},	/* Chinese (Hong Kong S.A.R.) */
-  {0x0C07,	"de"},	/* German (Austria) */
-  {0x0C09,	"en"},	/* English (Australia) */
-  {0x0C0A,	"es"},	/* Spanish (Modern Sort) (Spain) */
-  {0x0C0C,	"fr"},	/* French (Canada) */
-  {0x0C1A,	"sr"},	/* Serbian (Cyrillic) (Serbia) */
-  {0x0C3B,	"se"},	/* Sami (Northern) (Finland) */
-//{0x0C6B,	""},	/* Quechua (Peru) */
-  {0x1001,	"ar"},	/* Arabic (Libya) */
-  {0x1004,	"zh-sg"},	/* Chinese (Singapore) */
-  {0x1007,	"de"},	/* German (Luxembourg) */
-  {0x1009,	"en"},	/* English (Canada) */
-  {0x100A,	"es"},	/* Spanish (Guatemala) */
-  {0x100C,	"fr"},	/* French (Switzerland) */
-  {0x101A,	"hr"},	/* Croatian (Latin) (Bosnia and Herzegovina) */
-  {0x103B,	"smj"},	/* Sami (Lule) (Norway) */
-  {0x1401,	"ar"},	/* Arabic (Algeria) */
-//{0x1404,	""},	/* Chinese (Macao S.A.R.) */
-  {0x1407,	"de"},	/* German (Liechtenstein) */
-  {0x1409,	"en"},	/* English (New Zealand) */
-  {0x140A,	"es"},	/* Spanish (Costa Rica) */
-  {0x140C,	"fr"},	/* French (Luxembourg) */
-  {0x141A,	"bs"},	/* Bosnian (Latin) (Bosnia and Herzegovina) */
-//{0x143B,	""},	/* Sami (Lule) (Sweden) */
-  {0x1801,	"ar"},	/* Arabic (Morocco) */
-  {0x1809,	"en"},	/* English (Ireland) */
-  {0x180A,	"es"},	/* Spanish (Panama) */
-  {0x180C,	"fr"},	/* French (Principality of Monaco) */
-//{0x181A,	""},	/* Serbian (Latin) (Bosnia and Herzegovina) */
-  {0x183B,	"sma"},	/* Sami (Southern) (Norway) */
-  {0x1C01,	"ar"},	/* Arabic (Tunisia) */
-  {0x1C09,	"en"},	/* English (South Africa) */
-  {0x1C0A,	"es"},	/* Spanish (Dominican Republic) */
-  {0x1C0C,	"fr"},	/* ??? */
-//{0x1C1A,	""},	/* Serbian (Cyrillic) (Bosnia and Herzegovina) */
-//{0x1C3B,	""},	/* Sami (Southern) (Sweden) */
-  {0x2001,	"ar"},	/* Arabic (Oman) */
-  {0x2009,	"en"},	/* English (Jamaica) */
-  {0x200A,	"es"},	/* Spanish (Venezuela) */
-  {0x200C,	"fr"},	/* ??? */
-  {0x201A,	"bs"},	/* Bosnian (Cyrillic) (Bosnia and Herzegovina) */
-  {0x203B,	"sms"},	/* Sami (Skolt) (Finland) */
-  {0x2401,	"ar"},	/* Arabic (Yemen) */
-  {0x2409,	"en"},	/* English (Caribbean) */
-  {0x240A,	"es"},	/* Spanish (Colombia) */
-  {0x240C,	"fr"},	/* ??? */
-  {0x243B,	"smn"},	/* Sami (Inari) (Finland) */
-  {0x2801,	"ar"},	/* Arabic (Syria) */
-  {0x2809,	"en"},	/* English (Belize) */
-  {0x280A,	"es"},	/* Spanish (Peru) */
-  {0x280C,	"fr"},	/* ??? */
-  {0x2C01,	"ar"},	/* Arabic (Jordan) */
-  {0x2C09,	"en"},	/* English (Trinidad and Tobago) */
-  {0x2C0A,	"es"},	/* Spanish (Argentina) */
-  {0x2C0C,	"fr"},	/* ??? */
-  {0x3001,	"ar"},	/* Arabic (Lebanon) */
-  {0x3009,	"en"},	/* English (Zimbabwe) */
-  {0x300A,	"es"},	/* Spanish (Ecuador) */
-  {0x300C,	"fr"},	/* ??? */
-  {0x3401,	"ar"},	/* Arabic (Kuwait) */
-  {0x3409,	"en"},	/* English (Republic of the Philippines) */
-  {0x340A,	"es"},	/* Spanish (Chile) */
-  {0x340C,	"fr"},	/* ??? */
-  {0x3801,	"ar"},	/* Arabic (U.A.E.) */
-  {0x380A,	"es"},	/* Spanish (Uruguay) */
-  {0x380C,	"fr"},	/* ??? */
-  {0x3C01,	"ar"},	/* Arabic (Bahrain) */
-  {0x3C09,	"en"},	/* ??? */
-  {0x3C0A,	"es"},	/* Spanish (Paraguay) */
-  {0x3C0C,	"fr"},	/* ??? */
-  {0x4001,	"ar"},	/* Arabic (Qatar) */
-  {0x4009,	"en"},	/* English (India) */
-  {0x400A,	"es"},	/* Spanish (Bolivia) */
-  {0x4409,	"en"},	/* English (Malaysia) */
-  {0x440A,	"es"},	/* Spanish (El Salvador) */
-  {0x4809,	"en"},	/* English (Singapore) */
-  {0x480A,	"es"},	/* Spanish (Honduras) */
-  {0x4C0A,	"es"},	/* Spanish (Nicaragua) */
-  {0x500A,	"es"},	/* Spanish (Puerto Rico) */
-  {0x540A,	"es"},	/* Spanish (United States) */
-  {0xE40A,	"es"},	/* ??? */
-  {0xE40C,	"fr"},	/* ??? */
-};
-
-static const hb_ot_language_map_t
-hb_mac_language_map[] =
-{
-  {  0,	"en"},	/* English */
-  {  1,	"fr"},	/* French */
-  {  2,	"de"},	/* German */
-  {  3,	"it"},	/* Italian */
-  {  4,	"nl"},	/* Dutch */
-  {  5,	"sv"},	/* Swedish */
-  {  6,	"es"},	/* Spanish */
-  {  7,	"da"},	/* Danish */
-  {  8,	"pt"},	/* Portuguese */
-  {  9,	"no"},	/* Norwegian */
-  { 10,	"he"},	/* Hebrew */
-  { 11,	"ja"},	/* Japanese */
-  { 12,	"ar"},	/* Arabic */
-  { 13,	"fi"},	/* Finnish */
-  { 14,	"el"},	/* Greek */
-  { 15,	"is"},	/* Icelandic */
-  { 16,	"mt"},	/* Maltese */
-  { 17,	"tr"},	/* Turkish */
-  { 18,	"hr"},	/* Croatian */
-  { 19,	"zh-tw"},	/* Chinese (Traditional) */
-  { 20,	"ur"},	/* Urdu */
-  { 21,	"hi"},	/* Hindi */
-  { 22,	"th"},	/* Thai */
-  { 23,	"ko"},	/* Korean */
-  { 24,	"lt"},	/* Lithuanian */
-  { 25,	"pl"},	/* Polish */
-  { 26,	"hu"},	/* Hungarian */
-  { 27,	"et"},	/* Estonian */
-  { 28,	"lv"},	/* Latvian */
-//{ 29,	""},	/* Sami */
-  { 30,	"fo"},	/* Faroese */
-  { 31,	"fa"},	/* Farsi/Persian */
-  { 32,	"ru"},	/* Russian */
-  { 33,	"zh-cn"},	/* Chinese (Simplified) */
-  { 34,	"nl"},	/* Flemish */
-  { 35,	"ga"},	/* Irish Gaelic */
-  { 36,	"sq"},	/* Albanian */
-  { 37,	"ro"},	/* Romanian */
-  { 38,	"cs"},	/* Czech */
-  { 39,	"sk"},	/* Slovak */
-  { 40,	"sl"},	/* Slovenian */
-  { 41,	"yi"},	/* Yiddish */
-  { 42,	"sr"},	/* Serbian */
-  { 43,	"mk"},	/* Macedonian */
-  { 44,	"bg"},	/* Bulgarian */
-  { 45,	"uk"},	/* Ukrainian */
-  { 46,	"be"},	/* Byelorussian */
-  { 47,	"uz"},	/* Uzbek */
-  { 48,	"kk"},	/* Kazakh */
-  { 49,	"az"},	/* Azerbaijani (Cyrillic script) */
-  { 50,	"az"},	/* Azerbaijani (Arabic script) */
-  { 51,	"hy"},	/* Armenian */
-  { 52,	"ka"},	/* Georgian */
-  { 53,	"mo"},	/* Moldavian */
-  { 54,	"ky"},	/* Kirghiz */
-  { 55,	"tg"},	/* Tajiki */
-  { 56,	"tk"},	/* Turkmen */
-  { 57,	"mn"},	/* Mongolian (Mongolian script) */
-  { 58,	"mn"},	/* Mongolian (Cyrillic script) */
-  { 59,	"ps"},	/* Pashto */
-  { 60,	"ku"},	/* Kurdish */
-  { 61,	"ks"},	/* Kashmiri */
-  { 62,	"sd"},	/* Sindhi */
-  { 63,	"bo"},	/* Tibetan */
-  { 64,	"ne"},	/* Nepali */
-  { 65,	"sa"},	/* Sanskrit */
-  { 66,	"mr"},	/* Marathi */
-  { 67,	"bn"},	/* Bengali */
-  { 68,	"as"},	/* Assamese */
-  { 69,	"gu"},	/* Gujarati */
-  { 70,	"pa"},	/* Punjabi */
-  { 71,	"or"},	/* Oriya */
-  { 72,	"ml"},	/* Malayalam */
-  { 73,	"kn"},	/* Kannada */
-  { 74,	"ta"},	/* Tamil */
-  { 75,	"te"},	/* Telugu */
-  { 76,	"si"},	/* Sinhalese */
-  { 77,	"my"},	/* Burmese */
-  { 78,	"km"},	/* Khmer */
-  { 79,	"lo"},	/* Lao */
-  { 80,	"vi"},	/* Vietnamese */
-  { 81,	"id"},	/* Indonesian */
-  { 82,	"tl"},	/* Tagalog */
-  { 83,	"ms"},	/* Malay (Roman script) */
-  { 84,	"ms"},	/* Malay (Arabic script) */
-  { 85,	"am"},	/* Amharic */
-  { 86,	"ti"},	/* Tigrinya */
-  { 87,	"om"},	/* Galla */
-  { 88,	"so"},	/* Somali */
-  { 89,	"sw"},	/* Swahili */
-  { 90,	"rw"},	/* Kinyarwanda/Ruanda */
-  { 91,	"rn"},	/* Rundi */
-  { 92,	"ny"},	/* Nyanja/Chewa */
-  { 93,	"mg"},	/* Malagasy */
-  { 94,	"eo"},	/* Esperanto */
-  {128,	"cy"},	/* Welsh */
-  {129,	"eu"},	/* Basque */
-  {130,	"ca"},	/* Catalan */
-  {131,	"la"},	/* Latin */
-  {132,	"qu"},	/* Quechua */
-  {133,	"gn"},	/* Guarani */
-  {134,	"ay"},	/* Aymara */
-  {135,	"tt"},	/* Tatar */
-  {136,	"ug"},	/* Uighur */
-  {137,	"dz"},	/* Dzongkha */
-  {138,	"jw"},	/* Javanese (Roman script) */
-  {139,	"su"},	/* Sundanese (Roman script) */
-  {140,	"gl"},	/* Galician */
-  {141,	"af"},	/* Afrikaans */
-  {142,	"br"},	/* Breton */
-  {143,	"iu"},	/* Inuktitut */
-  {144,	"gd"},	/* Scottish Gaelic */
-  {145,	"gv"},	/* Manx Gaelic */
-  {146,	"ga"},	/* Irish Gaelic (with dot above) */
-  {147,	"to"},	/* Tongan */
-  {148,	"el"},	/* Greek (polytonic) */
-  {149,	"ik"},	/* Greenlandic */
-  {150,	"az"},	/* Azerbaijani (Roman script) */
-};
-
-
-static hb_language_t
-_hb_ot_name_language_for (unsigned int code,
-			  const hb_ot_language_map_t *array,
-			  unsigned int len)
-{
-  const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *)
-				      hb_bsearch (&code,
-						  array,
-						  len,
-						  sizeof (array[0]),
-						  hb_ot_language_map_t::cmp);
-
-  if (entry)
-    return hb_language_from_string (entry->lang, -1);
-
-  return HB_LANGUAGE_INVALID;
-}
-
-hb_language_t
-_hb_ot_name_language_for_ms_code (unsigned int code)
-{
-  return _hb_ot_name_language_for (code,
-				   hb_ms_language_map,
-				   ARRAY_LENGTH (hb_ms_language_map));
-}
-
-hb_language_t
-_hb_ot_name_language_for_mac_code (unsigned int code)
-{
-  return _hb_ot_name_language_for (code,
-				   hb_mac_language_map,
-				   ARRAY_LENGTH (hb_mac_language_map));
-}

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -51,6 +51,7 @@
 {
   hb_language_t language (hb_face_t *face) const
   {
+#ifndef HB_NO_OT_NAME_LANGUAGE
     unsigned int p = platformID;
     unsigned int l = languageID;
 
@@ -60,9 +61,12 @@
     if (p == 1)
       return _hb_ot_name_language_for_mac_code (l);
 
+#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
     if (p == 0)
       return _hb_aat_language_get (face, l);
+#endif
 
+#endif
     return HB_LANGUAGE_INVALID;
   }
 
@@ -93,11 +97,21 @@
     return UNSUPPORTED;
   }
 
+  NameRecord* copy (hb_serialize_context_t *c,
+		    const void *src_base,
+		    const void *dst_base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+    out->offset.serialize_copy (c, src_base + offset, dst_base, length);
+    return_trace (out);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
-    /* We can check from base all the way up to the end of string... */
-    return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
+    return_trace (c->check_struct (this) && offset.sanitize (c, base, length));
   }
 
   HBUINT16	platformID;	/* Platform ID. */
@@ -105,7 +119,8 @@
   HBUINT16	languageID;	/* Language ID. */
   HBUINT16	nameID;		/* Name ID. */
   HBUINT16	length;		/* String length (in bytes). */
-  HBUINT16	offset;		/* String offset from start of storage area (in bytes). */
+  NNOffsetTo<UnsizedArrayOf<HBUINT8>>
+		offset;		/* String offset from start of storage area (in bytes). */
   public:
   DEFINE_SIZE_STATIC (12);
 };
@@ -156,15 +171,58 @@
   unsigned int get_size () const
   { return min_size + count * nameRecordZ.item_size; }
 
+  template <typename Iterator,
+	    hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
+  bool serialize (hb_serialize_context_t *c,
+		  Iterator it,
+		  const void *src_string_pool)
+  {
+    TRACE_SERIALIZE (this);
+
+    if (unlikely (!c->extend_min ((*this))))  return_trace (false);
+
+    this->format = 0;
+    this->count = it.len ();
+
+    auto snap = c->snapshot ();
+    this->nameRecordZ.serialize (c, this->count);
+    if (unlikely (!c->check_assign (this->stringOffset, c->length ()))) return_trace (false);
+    c->revert (snap);
+
+    const void *dst_string_pool = &(this + this->stringOffset);
+
+    + it
+    | hb_apply ([=] (const NameRecord& _) { c->copy (_, src_string_pool, dst_string_pool); })
+    ;
+
+    if (unlikely (c->ran_out_of_room)) return_trace (false);
+
+    assert (this->stringOffset == c->length ());
+
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+
+    name *name_prime = c->serializer->start_embed<name> ();
+    if (unlikely (!name_prime)) return_trace (false);
+
+    auto it =
+    + nameRecordZ.as_array (count)
+    | hb_filter (c->plan->name_ids, &NameRecord::nameID)
+    ;
+
+    name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset));
+    return_trace (name_prime->count);
+  }
+
   bool sanitize_records (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     const void *string_pool = (this+stringOffset).arrayZ;
-    unsigned int _count = count;
-    /* Move to run-time?! */
-    for (unsigned int i = 0; i < _count; i++)
-      if (!nameRecordZ[i].sanitize (c, string_pool)) return_trace (false);
-    return_trace (true);
+    return_trace (nameRecordZ.sanitize (c, count, string_pool));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -173,7 +231,8 @@
     return_trace (c->check_struct (this) &&
 		  likely (format == 0 || format == 1) &&
 		  c->check_array (nameRecordZ.arrayZ, count) &&
-		  c->check_range (this, stringOffset));
+		  c->check_range (this, stringOffset) &&
+		  sanitize_records (c));
   }
 
   struct accelerator_t
@@ -263,7 +322,7 @@
   /* We only implement format 0 for now. */
   HBUINT16	format;			/* Format selector (=0/1). */
   HBUINT16	count;			/* Number of name records. */
-  NNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  NNOffsetTo<UnsizedArrayOf<HBUINT8>>
 		stringOffset;		/* Offset to start of string storage (from start of table). */
   UnsizedArrayOf<NameRecord>
 		nameRecordZ;		/* The name records where count is the number of records. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -58,6 +58,11 @@
 hb_ot_name_list_names (hb_face_t    *face,
 		       unsigned int *num_entries /* OUT */)
 {
+#ifdef HB_NO_NAME
+  if (num_entries)
+    *num_entries = 0;
+  return 0;
+#endif
   const OT::name_accelerator_t &name = *face->table.name;
   if (num_entries) *num_entries = name.names.length;
   return (const hb_ot_name_entry_t *) name.names;
@@ -93,7 +98,7 @@
 
       dst = dst_next;
       src = src_next;
-    };
+    }
 
     *text_size = dst - text;
     *dst = 0; /* NUL-terminate. */
@@ -105,7 +110,7 @@
   {
     src = in_utf_t::next (src, src_end, &unicode, replacement);
     dst_len += out_utf_t::encode_len (unicode);
-  };
+  }
   return dst_len;
 }
 
@@ -167,6 +172,11 @@
 		     unsigned int    *text_size /* IN/OUT */,
 		     char            *text      /* OUT */)
 {
+#ifdef HB_NO_NAME
+  if (text_size)
+    *text_size = 0;
+  return 0;
+#endif
   return hb_ot_name_get_utf<hb_utf8_t> (face, name_id, language, text_size,
 					(hb_utf8_t::codepoint_t *) text);
 }
@@ -194,6 +204,11 @@
 		      unsigned int    *text_size /* IN/OUT */,
 		      uint16_t        *text      /* OUT */)
 {
+#ifdef HB_NO_NAME
+  if (text_size)
+    *text_size = 0;
+  return 0;
+#endif
   return hb_ot_name_get_utf<hb_utf16_t> (face, name_id, language, text_size, text);
 }
 
@@ -220,5 +235,10 @@
 		      unsigned int    *text_size /* IN/OUT */,
 		      uint32_t        *text      /* OUT */)
 {
+#ifdef HB_NO_NAME
+  if (text_size)
+    *text_size = 0;
+  return 0;
+#endif
   return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -160,8 +160,8 @@
 
     uint16_t min_cp, max_cp;
     find_min_and_max_codepoint (plan->unicodes, &min_cp, &max_cp);
-    os2_prime->usFirstCharIndex.set (min_cp);
-    os2_prime->usLastCharIndex.set (max_cp);
+    os2_prime->usFirstCharIndex = min_cp;
+    os2_prime->usLastCharIndex = max_cp;
 
     _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange);
     bool result = plan->add_table (HB_OT_TAG_OS2, os2_prime_blob);
@@ -174,7 +174,7 @@
 			       HBUINT32 ulUnicodeRange[4]) const
   {
     for (unsigned int i = 0; i < 4; i++)
-      ulUnicodeRange[i].set (0);
+      ulUnicodeRange[i] = 0;
 
     hb_codepoint_t cp = HB_SET_VALUE_INVALID;
     while (codepoints->next (&cp)) {
@@ -184,7 +184,7 @@
 	unsigned int block = bit / 32;
 	unsigned int bit_in_block = bit % 32;
 	unsigned int mask = 1 << bit_in_block;
-	ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
+	ulUnicodeRange[block] = ulUnicodeRange[block] | mask;
       }
       if (cp >= 0x10000 && cp <= 0x110000)
       {
@@ -191,7 +191,7 @@
 	/* the spec says that bit 57 ("Non Plane 0") implies that there's
 	   at least one codepoint beyond the BMP; so I also include all
 	   the non-BMP codepoints here */
-	ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
+	ulUnicodeRange[1] = ulUnicodeRange[1] | (1 << 25);
       }
     }
   }

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -88,7 +88,7 @@
       return false;
     }
 
-    post_prime->version.major.set (3); // Version 3 does not have any glyph names.
+    post_prime->version.major = 3; // Version 3 does not have any glyph names.
     bool result = plan->add_table (HB_OT_TAG_post, post_prime_blob);
     hb_blob_destroy (post_prime_blob);
 
@@ -131,7 +131,7 @@
       hb_bytes_t s = find_glyph_name (glyph);
       if (!s.length) return false;
       if (!buf_len) return true;
-      unsigned int len = MIN (buf_len - 1, s.length);
+      unsigned int len = hb_min (buf_len - 1, s.length);
       strncpy (buf, s.arrayZ, len);
       buf[len] = '\0';
       return true;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -66,8 +66,8 @@
 	u_glyph > 0xFFFFu || s_glyph > 0xFFFFu)
       continue;
 
-    glyphs[num_glyphs].set (u_glyph);
-    substitutes[num_glyphs].set (s_glyph);
+    glyphs[num_glyphs] = u_glyph;
+    substitutes[num_glyphs] = s_glyph;
 
     num_glyphs++;
   }
@@ -77,7 +77,9 @@
 
   /* Bubble-sort or something equally good!
    * May not be good-enough for presidential candidate interviews, but good-enough for us... */
-  hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]);
+  hb_stable_sort (&glyphs[0], num_glyphs,
+		  (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::GlyphID::cmp,
+		  &substitutes[0]);
 
 
   /* Each glyph takes four bytes max, and there's some overhead. */
@@ -86,10 +88,9 @@
   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
   bool ret = lookup->serialize_single (&c,
 				       OT::LookupFlag::IgnoreMarks,
-				       hb_array (glyphs, num_glyphs),
+				       hb_sorted_array (glyphs, num_glyphs),
 				       hb_array (substitutes, num_glyphs));
   c.end_serialize ();
-  /* TODO sanitize the results? */
 
   return ret ? c.copy<OT::SubstLookup> () : nullptr;
 }
@@ -118,12 +119,14 @@
     hb_codepoint_t first_glyph;
     if (!hb_font_get_glyph (font, first_u, 0, &first_glyph))
       continue;
-    first_glyphs[num_first_glyphs].set (first_glyph);
+    first_glyphs[num_first_glyphs] = first_glyph;
     ligature_per_first_glyph_count_list[num_first_glyphs] = 0;
     first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
     num_first_glyphs++;
   }
-  hb_stable_sort (&first_glyphs[0], num_first_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &first_glyphs_indirection[0]);
+  hb_stable_sort (&first_glyphs[0], num_first_glyphs,
+		  (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::GlyphID::cmp,
+		  &first_glyphs_indirection[0]);
 
   /* Now that the first-glyphs are sorted, walk again, populate ligatures. */
   for (unsigned int i = 0; i < num_first_glyphs; i++)
@@ -142,9 +145,9 @@
 
       ligature_per_first_glyph_count_list[i]++;
 
-      ligature_list[num_ligatures].set (ligature_glyph);
+      ligature_list[num_ligatures] = ligature_glyph;
       component_count_list[num_ligatures] = 2;
-      component_list[num_ligatures].set (second_glyph);
+      component_list[num_ligatures] = second_glyph;
       num_ligatures++;
     }
   }
@@ -159,7 +162,7 @@
   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
   bool ret = lookup->serialize_ligature (&c,
 					 OT::LookupFlag::IgnoreMarks,
-					 hb_array (first_glyphs, num_first_glyphs),
+					 hb_sorted_array (first_glyphs, num_first_glyphs),
 					 hb_array (ligature_per_first_glyph_count_list, num_first_glyphs),
 					 hb_array (ligature_list, num_ligatures),
 					 hb_array (component_count_list, num_ligatures),

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -383,6 +383,10 @@
 		       hb_font_t *font,
 		       hb_buffer_t *buffer)
 {
+#ifdef HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
+  return;
+#endif
+
   const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
 
   if (!arabic_plan->do_fallback)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -70,6 +70,10 @@
 
   bool found = (bool) c->unicode->compose (a, b, ab);
 
+#ifdef HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
+  return found;
+#endif
+
   if (!found && !c->plan->has_gpos_mark)
   {
       /* Special-case Hebrew presentation forms that are excluded from

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -34,788 +34,284 @@
 
 #line 36 "hb-ot-shape-complex-indic-machine.hh"
 static const unsigned char _indic_syllable_machine_trans_keys[] = {
-	8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 
-	5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 
-	4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 
-	16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 
-	4u, 8u, 4u, 13u, 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 
-	7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 
-	6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 
-	4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 
-	4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 
-	5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 
-	7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 
-	6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 
-	4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 8u, 8u, 4u, 8u, 5u, 7u, 
-	7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 
-	5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 
-	4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 
-	4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 13u, 
-	5u, 8u, 8u, 8u, 1u, 19u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
-	3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
-	3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 
-	5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, 
-	4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 
-	3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
-	3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 
-	1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 
-	3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 
-	1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 
-	1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 
-	10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 
-	3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 
-	4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 
-	1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
-	3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 8u, 3u, 17u, 3u, 17u, 
-	4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 
-	4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 
-	4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 
-	3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 
-	3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 
-	1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
-	3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 
-	1u, 16u, 1u, 16u, 4u, 13u, 3u, 17u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 
-	1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 
-	1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 
-	5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 
-	5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 
-	4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 
-	1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 
-	3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 
-	1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, 
-	10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 
-	10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 0
+	8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 
+	4u, 13u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 
+	4u, 8u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 
+	6u, 6u, 16u, 16u, 4u, 8u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 7u, 5u, 8u, 
+	4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 8u, 5u, 8u, 8u, 8u, 1u, 19u, 
+	3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 5u, 10u, 5u, 10u, 10u, 10u, 5u, 10u, 
+	1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 4u, 10u, 5u, 10u, 
+	3u, 10u, 5u, 10u, 3u, 17u, 3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 
+	3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 
+	1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 
+	5u, 10u, 3u, 17u, 3u, 17u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 
+	3u, 17u, 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 1u, 16u, 3u, 10u, 
+	4u, 10u, 5u, 10u, 3u, 17u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 
+	3u, 17u, 4u, 13u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
+	1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 1u, 16u, 3u, 10u, 4u, 10u, 
+	5u, 10u, 3u, 17u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 1u, 17u, 
+	3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 
+	5u, 10u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 0
 };
 
 static const char _indic_syllable_machine_key_spans[] = {
-	1, 5, 3, 1, 4, 3, 1, 4, 
-	3, 1, 4, 3, 1, 5, 1, 1, 
-	5, 1, 1, 5, 1, 1, 5, 1, 
-	1, 10, 5, 10, 5, 10, 5, 10, 
-	5, 10, 1, 5, 3, 1, 4, 3, 
-	1, 4, 3, 1, 4, 3, 1, 5, 
-	1, 1, 5, 1, 1, 5, 1, 1, 
-	5, 1, 1, 10, 5, 10, 5, 10, 
-	5, 10, 5, 10, 1, 5, 3, 1, 
-	4, 3, 1, 4, 3, 1, 4, 3, 
-	1, 5, 1, 1, 5, 1, 1, 5, 
-	1, 1, 5, 1, 1, 10, 5, 10, 
-	5, 10, 5, 10, 5, 1, 5, 3, 
-	1, 4, 3, 1, 4, 3, 1, 4, 
-	3, 1, 5, 1, 1, 5, 1, 1, 
-	5, 1, 1, 5, 1, 1, 10, 5, 
-	10, 5, 10, 5, 10, 5, 10, 10, 
-	4, 1, 19, 15, 15, 14, 16, 15, 
-	15, 14, 16, 15, 15, 14, 16, 15, 
-	15, 14, 16, 15, 15, 14, 6, 6, 
-	6, 1, 1, 1, 6, 8, 6, 8, 
-	7, 6, 8, 7, 6, 8, 7, 6, 
-	8, 7, 7, 15, 15, 16, 16, 16, 
-	15, 15, 16, 16, 16, 15, 15, 16, 
-	16, 16, 15, 15, 16, 16, 16, 15, 
-	15, 15, 15, 14, 16, 15, 15, 14, 
-	16, 15, 15, 14, 16, 15, 15, 14, 
-	16, 15, 15, 14, 6, 6, 6, 1, 
-	1, 1, 6, 8, 6, 8, 7, 6, 
-	8, 7, 6, 8, 7, 6, 8, 7, 
-	7, 15, 15, 16, 16, 16, 15, 15, 
-	16, 16, 16, 15, 15, 16, 16, 16, 
-	15, 15, 16, 16, 16, 5, 15, 15, 
-	14, 16, 15, 15, 14, 16, 15, 15, 
-	14, 16, 15, 15, 14, 16, 15, 15, 
-	14, 6, 6, 6, 1, 1, 1, 6, 
-	8, 6, 8, 7, 6, 8, 7, 6, 
-	8, 7, 6, 8, 7, 7, 15, 15, 
-	16, 16, 16, 15, 15, 16, 16, 16, 
-	15, 15, 16, 16, 16, 15, 15, 16, 
-	16, 16, 10, 15, 5, 15, 15, 14, 
-	16, 15, 15, 14, 16, 15, 15, 14, 
-	16, 15, 15, 14, 16, 15, 15, 14, 
-	6, 6, 6, 1, 1, 1, 6, 8, 
-	6, 8, 7, 6, 8, 7, 6, 8, 
-	7, 6, 8, 7, 7, 15, 15, 16, 
-	16, 16, 15, 15, 16, 16, 16, 15, 
-	15, 16, 16, 16, 15, 15, 16, 16, 
-	16, 15, 17, 15, 17, 10, 6, 1, 
-	1, 1, 6, 16, 8, 6, 6, 1, 
-	1, 1, 6, 16
+	1, 5, 3, 4, 5, 1, 1, 5, 
+	10, 5, 1, 3, 4, 5, 1, 1, 
+	5, 10, 10, 10, 1, 3, 4, 5, 
+	1, 1, 5, 5, 10, 1, 3, 4, 
+	5, 1, 1, 5, 5, 4, 1, 19, 
+	15, 15, 14, 16, 6, 6, 1, 6, 
+	16, 16, 16, 8, 7, 6, 7, 6, 
+	8, 6, 15, 15, 15, 15, 14, 16, 
+	15, 15, 14, 16, 6, 1, 6, 16, 
+	16, 8, 7, 6, 7, 6, 6, 8, 
+	6, 15, 15, 5, 15, 15, 14, 16, 
+	15, 16, 6, 1, 6, 16, 16, 8, 
+	7, 6, 15, 7, 6, 6, 8, 6, 
+	15, 10, 5, 15, 15, 14, 16, 15, 
+	16, 6, 1, 6, 16, 16, 8, 7, 
+	6, 15, 7, 6, 6, 8, 6, 17, 
+	15, 17, 10, 6, 1, 6, 16, 8, 
+	6, 6, 1, 6, 16
 };
 
 static const short _indic_syllable_machine_index_offsets[] = {
-	0, 2, 8, 12, 14, 19, 23, 25, 
-	30, 34, 36, 41, 45, 47, 53, 55, 
-	57, 63, 65, 67, 73, 75, 77, 83, 
-	85, 87, 98, 104, 115, 121, 132, 138, 
-	149, 155, 166, 168, 174, 178, 180, 185, 
-	189, 191, 196, 200, 202, 207, 211, 213, 
-	219, 221, 223, 229, 231, 233, 239, 241, 
-	243, 249, 251, 253, 264, 270, 281, 287, 
-	298, 304, 315, 321, 332, 334, 340, 344, 
-	346, 351, 355, 357, 362, 366, 368, 373, 
-	377, 379, 385, 387, 389, 395, 397, 399, 
-	405, 407, 409, 415, 417, 419, 430, 436, 
-	447, 453, 464, 470, 481, 487, 489, 495, 
-	499, 501, 506, 510, 512, 517, 521, 523, 
-	528, 532, 534, 540, 542, 544, 550, 552, 
-	554, 560, 562, 564, 570, 572, 574, 585, 
-	591, 602, 608, 619, 625, 636, 642, 653, 
-	664, 669, 671, 691, 707, 723, 738, 755, 
-	771, 787, 802, 819, 835, 851, 866, 883, 
-	899, 915, 930, 947, 963, 979, 994, 1001, 
-	1008, 1015, 1017, 1019, 1021, 1028, 1037, 1044, 
-	1053, 1061, 1068, 1077, 1085, 1092, 1101, 1109, 
-	1116, 1125, 1133, 1141, 1157, 1173, 1190, 1207, 
-	1224, 1240, 1256, 1273, 1290, 1307, 1323, 1339, 
-	1356, 1373, 1390, 1406, 1422, 1439, 1456, 1473, 
-	1489, 1505, 1521, 1537, 1552, 1569, 1585, 1601, 
-	1616, 1633, 1649, 1665, 1680, 1697, 1713, 1729, 
-	1744, 1761, 1777, 1793, 1808, 1815, 1822, 1829, 
-	1831, 1833, 1835, 1842, 1851, 1858, 1867, 1875, 
-	1882, 1891, 1899, 1906, 1915, 1923, 1930, 1939, 
-	1947, 1955, 1971, 1987, 2004, 2021, 2038, 2054, 
-	2070, 2087, 2104, 2121, 2137, 2153, 2170, 2187, 
-	2204, 2220, 2236, 2253, 2270, 2287, 2293, 2309, 
-	2325, 2340, 2357, 2373, 2389, 2404, 2421, 2437, 
-	2453, 2468, 2485, 2501, 2517, 2532, 2549, 2565, 
-	2581, 2596, 2603, 2610, 2617, 2619, 2621, 2623, 
-	2630, 2639, 2646, 2655, 2663, 2670, 2679, 2687, 
-	2694, 2703, 2711, 2718, 2727, 2735, 2743, 2759, 
-	2775, 2792, 2809, 2826, 2842, 2858, 2875, 2892, 
-	2909, 2925, 2941, 2958, 2975, 2992, 3008, 3024, 
-	3041, 3058, 3075, 3086, 3102, 3108, 3124, 3140, 
-	3155, 3172, 3188, 3204, 3219, 3236, 3252, 3268, 
-	3283, 3300, 3316, 3332, 3347, 3364, 3380, 3396, 
-	3411, 3418, 3425, 3432, 3434, 3436, 3438, 3445, 
-	3454, 3461, 3470, 3478, 3485, 3494, 3502, 3509, 
-	3518, 3526, 3533, 3542, 3550, 3558, 3574, 3590, 
-	3607, 3624, 3641, 3657, 3673, 3690, 3707, 3724, 
-	3740, 3756, 3773, 3790, 3807, 3823, 3839, 3856, 
-	3873, 3890, 3906, 3924, 3940, 3958, 3969, 3976, 
-	3978, 3980, 3982, 3989, 4006, 4015, 4022, 4029, 
-	4031, 4033, 4035, 4042
+	0, 2, 8, 12, 17, 23, 25, 27, 
+	33, 44, 50, 52, 56, 61, 67, 69, 
+	71, 77, 88, 99, 110, 112, 116, 121, 
+	127, 129, 131, 137, 143, 154, 156, 160, 
+	165, 171, 173, 175, 181, 187, 192, 194, 
+	214, 230, 246, 261, 278, 285, 292, 294, 
+	301, 318, 335, 352, 361, 369, 376, 384, 
+	391, 400, 407, 423, 439, 455, 471, 486, 
+	503, 519, 535, 550, 567, 574, 576, 583, 
+	600, 617, 626, 634, 641, 649, 656, 663, 
+	672, 679, 695, 711, 717, 733, 749, 764, 
+	781, 797, 814, 821, 823, 830, 847, 864, 
+	873, 881, 888, 904, 912, 919, 926, 935, 
+	942, 958, 969, 975, 991, 1007, 1022, 1039, 
+	1055, 1072, 1079, 1081, 1088, 1105, 1122, 1131, 
+	1139, 1146, 1162, 1170, 1177, 1184, 1193, 1200, 
+	1218, 1234, 1252, 1263, 1270, 1272, 1279, 1296, 
+	1305, 1312, 1319, 1321, 1328
 };
 
-static const short _indic_syllable_machine_indicies[] = {
+static const unsigned char _indic_syllable_machine_indicies[] = {
 	1, 0, 2, 3, 3, 4, 1, 0, 
-	5, 5, 4, 0, 4, 0, 6, 6, 
-	7, 1, 0, 8, 8, 7, 0, 7, 
-	0, 9, 9, 10, 1, 0, 11, 11, 
-	10, 0, 10, 0, 12, 12, 13, 1, 
-	0, 14, 14, 13, 0, 13, 0, 15, 
-	0, 0, 0, 1, 0, 16, 0, 17, 
-	0, 18, 12, 12, 13, 1, 0, 19, 
-	0, 20, 0, 21, 9, 9, 10, 1, 
-	0, 22, 0, 23, 0, 24, 6, 6, 
-	7, 1, 0, 25, 0, 26, 0, 2, 
-	3, 3, 4, 1, 0, 0, 0, 0, 
-	27, 0, 28, 3, 3, 4, 1, 0, 
-	28, 3, 3, 4, 1, 0, 0, 0, 
-	0, 29, 0, 30, 3, 3, 4, 1, 
-	0, 30, 3, 3, 4, 1, 0, 0, 
-	0, 0, 31, 0, 32, 3, 3, 4, 
-	1, 0, 32, 3, 3, 4, 1, 0, 
-	0, 0, 0, 33, 0, 34, 3, 3, 
-	4, 1, 0, 34, 3, 3, 4, 1, 
-	0, 0, 0, 0, 35, 0, 37, 36, 
-	38, 39, 39, 40, 37, 36, 41, 41, 
-	40, 36, 40, 36, 42, 42, 43, 37, 
-	36, 44, 44, 43, 36, 43, 36, 45, 
-	45, 46, 37, 36, 47, 47, 46, 36, 
-	46, 36, 48, 48, 49, 37, 36, 50, 
-	50, 49, 36, 49, 36, 51, 36, 36, 
-	36, 37, 36, 52, 36, 53, 36, 54, 
-	48, 48, 49, 37, 36, 55, 36, 56, 
-	36, 57, 45, 45, 46, 37, 36, 58, 
-	36, 59, 36, 60, 42, 42, 43, 37, 
-	36, 61, 36, 62, 36, 38, 39, 39, 
-	40, 37, 36, 36, 36, 36, 63, 36, 
-	64, 39, 39, 40, 37, 36, 64, 39, 
-	39, 40, 37, 36, 36, 36, 36, 65, 
-	36, 66, 39, 39, 40, 37, 36, 66, 
-	39, 39, 40, 37, 36, 36, 36, 36, 
-	67, 36, 68, 39, 39, 40, 37, 36, 
-	68, 39, 39, 40, 37, 36, 36, 36, 
-	36, 69, 36, 70, 39, 39, 40, 37, 
-	36, 70, 39, 39, 40, 37, 36, 36, 
-	36, 36, 71, 36, 73, 72, 74, 75, 
-	75, 76, 73, 72, 78, 78, 76, 77, 
-	76, 77, 79, 79, 80, 73, 72, 81, 
-	81, 80, 72, 80, 72, 82, 82, 83, 
-	73, 72, 84, 84, 83, 72, 83, 72, 
-	85, 85, 86, 73, 72, 87, 87, 86, 
-	72, 86, 72, 88, 72, 72, 72, 73, 
-	72, 89, 72, 90, 72, 91, 85, 85, 
-	86, 73, 72, 92, 72, 93, 72, 94, 
-	82, 82, 83, 73, 72, 95, 72, 96, 
-	72, 97, 79, 79, 80, 73, 72, 98, 
-	72, 99, 72, 74, 75, 75, 76, 73, 
-	72, 72, 72, 72, 100, 72, 101, 75, 
-	75, 76, 73, 72, 101, 75, 75, 76, 
-	73, 72, 72, 72, 72, 102, 72, 103, 
-	75, 75, 76, 73, 72, 103, 75, 75, 
-	76, 73, 72, 72, 72, 72, 104, 72, 
-	105, 75, 75, 76, 73, 72, 105, 75, 
-	75, 76, 73, 72, 72, 72, 72, 106, 
-	72, 107, 75, 75, 76, 73, 72, 109, 
-	108, 110, 111, 111, 112, 109, 108, 113, 
-	113, 112, 108, 112, 108, 114, 114, 115, 
-	109, 108, 116, 116, 115, 108, 115, 108, 
-	117, 117, 118, 109, 108, 119, 119, 118, 
-	108, 118, 108, 120, 120, 121, 109, 108, 
-	122, 122, 121, 108, 121, 108, 123, 108, 
-	108, 108, 109, 108, 124, 108, 125, 108, 
-	126, 120, 120, 121, 109, 108, 127, 108, 
-	128, 108, 129, 117, 117, 118, 109, 108, 
-	130, 108, 131, 108, 132, 114, 114, 115, 
-	109, 108, 133, 108, 134, 108, 110, 111, 
-	111, 112, 109, 108, 108, 108, 108, 135, 
-	108, 136, 111, 111, 112, 109, 108, 136, 
-	111, 111, 112, 109, 108, 108, 108, 108, 
-	137, 108, 138, 111, 111, 112, 109, 108, 
-	138, 111, 111, 112, 109, 108, 108, 108, 
-	108, 139, 108, 140, 111, 111, 112, 109, 
-	108, 140, 111, 111, 112, 109, 108, 108, 
-	108, 108, 141, 108, 142, 111, 111, 112, 
-	109, 108, 142, 111, 111, 112, 109, 108, 
-	108, 108, 108, 143, 108, 107, 75, 75, 
-	76, 73, 72, 72, 72, 72, 144, 72, 
-	78, 78, 76, 1, 0, 146, 145, 148, 
-	149, 150, 151, 152, 153, 76, 73, 147, 
-	154, 155, 155, 144, 147, 156, 157, 158, 
-	159, 160, 147, 162, 163, 164, 165, 4, 
-	1, 161, 166, 161, 161, 35, 161, 161, 
-	161, 167, 161, 168, 163, 169, 169, 4, 
-	1, 161, 166, 161, 161, 161, 161, 161, 
-	161, 167, 161, 163, 169, 169, 4, 1, 
-	161, 166, 161, 161, 161, 161, 161, 161, 
-	167, 161, 170, 161, 161, 161, 17, 171, 
-	161, 1, 161, 166, 161, 161, 161, 161, 
-	161, 170, 161, 172, 173, 174, 175, 4, 
-	1, 161, 166, 161, 161, 33, 161, 161, 
-	161, 167, 161, 176, 173, 177, 177, 4, 
-	1, 161, 166, 161, 161, 161, 161, 161, 
-	161, 167, 161, 173, 177, 177, 4, 1, 
-	161, 166, 161, 161, 161, 161, 161, 161, 
-	167, 161, 178, 161, 161, 161, 17, 179, 
-	161, 1, 161, 166, 161, 161, 161, 161, 
-	161, 178, 161, 180, 181, 182, 183, 4, 
-	1, 161, 166, 161, 161, 31, 161, 161, 
-	161, 167, 161, 184, 181, 185, 185, 4, 
-	1, 161, 166, 161, 161, 161, 161, 161, 
-	161, 167, 161, 181, 185, 185, 4, 1, 
-	161, 166, 161, 161, 161, 161, 161, 161, 
-	167, 161, 186, 161, 161, 161, 17, 187, 
-	161, 1, 161, 166, 161, 161, 161, 161, 
-	161, 186, 161, 188, 189, 190, 191, 4, 
-	1, 161, 166, 161, 161, 29, 161, 161, 
-	161, 167, 161, 192, 189, 193, 193, 4, 
-	1, 161, 166, 161, 161, 161, 161, 161, 
-	161, 167, 161, 189, 193, 193, 4, 1, 
-	161, 166, 161, 161, 161, 161, 161, 161, 
-	167, 161, 194, 161, 161, 161, 17, 195, 
-	161, 1, 161, 166, 161, 161, 161, 161, 
-	161, 194, 161, 196, 197, 198, 199, 4, 
-	1, 161, 166, 161, 161, 27, 161, 161, 
-	161, 167, 161, 200, 197, 201, 201, 4, 
-	1, 161, 166, 161, 161, 161, 161, 161, 
-	161, 167, 161, 197, 201, 201, 4, 1, 
-	161, 166, 161, 161, 161, 161, 161, 161, 
-	167, 161, 17, 202, 161, 1, 161, 166, 
-	161, 203, 203, 161, 1, 161, 166, 161, 
-	204, 161, 161, 205, 161, 166, 161, 166, 
-	161, 206, 161, 207, 161, 204, 161, 161, 
-	161, 161, 166, 161, 17, 161, 203, 203, 
-	161, 1, 161, 166, 161, 203, 202, 161, 
-	1, 161, 166, 161, 208, 26, 209, 210, 
-	7, 1, 161, 166, 161, 26, 209, 210, 
-	7, 1, 161, 166, 161, 209, 209, 7, 
-	1, 161, 166, 161, 211, 23, 212, 213, 
-	10, 1, 161, 166, 161, 23, 212, 213, 
-	10, 1, 161, 166, 161, 212, 212, 10, 
-	1, 161, 166, 161, 214, 20, 215, 216, 
-	13, 1, 161, 166, 161, 20, 215, 216, 
-	13, 1, 161, 166, 161, 215, 215, 13, 
-	1, 161, 166, 161, 217, 17, 203, 218, 
-	161, 1, 161, 166, 161, 17, 203, 218, 
-	161, 1, 161, 166, 161, 197, 201, 201, 
-	4, 1, 161, 166, 161, 196, 197, 201, 
-	201, 4, 1, 161, 166, 161, 161, 161, 
-	161, 161, 161, 167, 161, 196, 197, 198, 
-	201, 4, 1, 161, 166, 161, 161, 27, 
-	161, 161, 161, 167, 161, 194, 161, 219, 
-	161, 203, 203, 161, 1, 161, 166, 161, 
-	161, 161, 161, 161, 194, 161, 194, 161, 
-	161, 161, 203, 203, 161, 1, 161, 166, 
-	161, 161, 161, 161, 161, 194, 161, 194, 
-	161, 161, 161, 203, 195, 161, 1, 161, 
-	166, 161, 161, 161, 161, 161, 194, 161, 
-	188, 189, 193, 193, 4, 1, 161, 166, 
-	161, 161, 161, 161, 161, 161, 167, 161, 
-	188, 189, 190, 193, 4, 1, 161, 166, 
-	161, 161, 29, 161, 161, 161, 167, 161, 
-	186, 161, 220, 161, 203, 203, 161, 1, 
-	161, 166, 161, 161, 161, 161, 161, 186, 
-	161, 186, 161, 161, 161, 203, 203, 161, 
-	1, 161, 166, 161, 161, 161, 161, 161, 
-	186, 161, 186, 161, 161, 161, 203, 187, 
-	161, 1, 161, 166, 161, 161, 161, 161, 
-	161, 186, 161, 180, 181, 185, 185, 4, 
-	1, 161, 166, 161, 161, 161, 161, 161, 
-	161, 167, 161, 180, 181, 182, 185, 4, 
-	1, 161, 166, 161, 161, 31, 161, 161, 
-	161, 167, 161, 178, 161, 221, 161, 203, 
-	203, 161, 1, 161, 166, 161, 161, 161, 
-	161, 161, 178, 161, 178, 161, 161, 161, 
-	203, 203, 161, 1, 161, 166, 161, 161, 
-	161, 161, 161, 178, 161, 178, 161, 161, 
-	161, 203, 179, 161, 1, 161, 166, 161, 
-	161, 161, 161, 161, 178, 161, 172, 173, 
-	177, 177, 4, 1, 161, 166, 161, 161, 
-	161, 161, 161, 161, 167, 161, 172, 173, 
-	174, 177, 4, 1, 161, 166, 161, 161, 
-	33, 161, 161, 161, 167, 161, 170, 161, 
-	222, 161, 203, 203, 161, 1, 161, 166, 
-	161, 161, 161, 161, 161, 170, 161, 170, 
-	161, 161, 161, 203, 203, 161, 1, 161, 
-	166, 161, 161, 161, 161, 161, 170, 161, 
-	170, 161, 161, 161, 203, 171, 161, 1, 
-	161, 166, 161, 161, 161, 161, 161, 170, 
-	161, 162, 163, 169, 169, 4, 1, 161, 
-	166, 161, 161, 161, 161, 161, 161, 167, 
-	161, 162, 163, 164, 169, 4, 1, 161, 
-	166, 161, 161, 35, 161, 161, 161, 167, 
-	161, 224, 225, 226, 227, 40, 37, 223, 
-	228, 223, 223, 71, 223, 223, 223, 229, 
-	223, 230, 225, 231, 227, 40, 37, 223, 
-	228, 223, 223, 223, 223, 223, 223, 229, 
-	223, 225, 231, 227, 40, 37, 223, 228, 
-	223, 223, 223, 223, 223, 223, 229, 223, 
-	232, 223, 223, 223, 53, 233, 223, 37, 
-	223, 228, 223, 223, 223, 223, 223, 232, 
-	223, 234, 235, 236, 237, 40, 37, 223, 
-	228, 223, 223, 69, 223, 223, 223, 229, 
-	223, 238, 235, 239, 239, 40, 37, 223, 
-	228, 223, 223, 223, 223, 223, 223, 229, 
-	223, 235, 239, 239, 40, 37, 223, 228, 
-	223, 223, 223, 223, 223, 223, 229, 223, 
-	240, 223, 223, 223, 53, 241, 223, 37, 
-	223, 228, 223, 223, 223, 223, 223, 240, 
-	223, 242, 243, 244, 245, 40, 37, 223, 
-	228, 223, 223, 67, 223, 223, 223, 229, 
-	223, 246, 243, 247, 247, 40, 37, 223, 
-	228, 223, 223, 223, 223, 223, 223, 229, 
-	223, 243, 247, 247, 40, 37, 223, 228, 
-	223, 223, 223, 223, 223, 223, 229, 223, 
-	248, 223, 223, 223, 53, 249, 223, 37, 
-	223, 228, 223, 223, 223, 223, 223, 248, 
-	223, 250, 251, 252, 253, 40, 37, 223, 
-	228, 223, 223, 65, 223, 223, 223, 229, 
-	223, 254, 251, 255, 255, 40, 37, 223, 
-	228, 223, 223, 223, 223, 223, 223, 229, 
-	223, 251, 255, 255, 40, 37, 223, 228, 
-	223, 223, 223, 223, 223, 223, 229, 223, 
-	256, 223, 223, 223, 53, 257, 223, 37, 
-	223, 228, 223, 223, 223, 223, 223, 256, 
-	223, 258, 259, 260, 261, 40, 37, 223, 
-	228, 223, 223, 63, 223, 223, 223, 229, 
-	223, 262, 259, 263, 263, 40, 37, 223, 
-	228, 223, 223, 223, 223, 223, 223, 229, 
-	223, 259, 263, 263, 40, 37, 223, 228, 
-	223, 223, 223, 223, 223, 223, 229, 223, 
-	53, 264, 223, 37, 223, 228, 223, 265, 
-	265, 223, 37, 223, 228, 223, 266, 223, 
-	223, 267, 223, 228, 223, 228, 223, 268, 
-	223, 269, 223, 266, 223, 223, 223, 223, 
-	228, 223, 53, 223, 265, 265, 223, 37, 
-	223, 228, 223, 265, 264, 223, 37, 223, 
-	228, 223, 270, 62, 271, 272, 43, 37, 
-	223, 228, 223, 62, 271, 272, 43, 37, 
-	223, 228, 223, 271, 271, 43, 37, 223, 
-	228, 223, 273, 59, 274, 275, 46, 37, 
-	223, 228, 223, 59, 274, 275, 46, 37, 
-	223, 228, 223, 274, 274, 46, 37, 223, 
-	228, 223, 276, 56, 277, 278, 49, 37, 
-	223, 228, 223, 56, 277, 278, 49, 37, 
-	223, 228, 223, 277, 277, 49, 37, 223, 
-	228, 223, 279, 53, 265, 280, 223, 37, 
-	223, 228, 223, 53, 265, 280, 223, 37, 
-	223, 228, 223, 259, 263, 263, 40, 37, 
-	223, 228, 223, 258, 259, 263, 263, 40, 
-	37, 223, 228, 223, 223, 223, 223, 223, 
-	223, 229, 223, 258, 259, 260, 263, 40, 
-	37, 223, 228, 223, 223, 63, 223, 223, 
-	223, 229, 223, 256, 223, 281, 223, 265, 
-	265, 223, 37, 223, 228, 223, 223, 223, 
-	223, 223, 256, 223, 256, 223, 223, 223, 
-	265, 265, 223, 37, 223, 228, 223, 223, 
-	223, 223, 223, 256, 223, 256, 223, 223, 
-	223, 265, 257, 223, 37, 223, 228, 223, 
-	223, 223, 223, 223, 256, 223, 250, 251, 
-	255, 255, 40, 37, 223, 228, 223, 223, 
-	223, 223, 223, 223, 229, 223, 250, 251, 
-	252, 255, 40, 37, 223, 228, 223, 223, 
-	65, 223, 223, 223, 229, 223, 248, 223, 
-	282, 223, 265, 265, 223, 37, 223, 228, 
-	223, 223, 223, 223, 223, 248, 223, 248, 
-	223, 223, 223, 265, 265, 223, 37, 223, 
-	228, 223, 223, 223, 223, 223, 248, 223, 
-	248, 223, 223, 223, 265, 249, 223, 37, 
-	223, 228, 223, 223, 223, 223, 223, 248, 
-	223, 242, 243, 247, 247, 40, 37, 223, 
-	228, 223, 223, 223, 223, 223, 223, 229, 
-	223, 242, 243, 244, 247, 40, 37, 223, 
-	228, 223, 223, 67, 223, 223, 223, 229, 
-	223, 240, 223, 283, 223, 265, 265, 223, 
-	37, 223, 228, 223, 223, 223, 223, 223, 
-	240, 223, 240, 223, 223, 223, 265, 265, 
-	223, 37, 223, 228, 223, 223, 223, 223, 
-	223, 240, 223, 240, 223, 223, 223, 265, 
-	241, 223, 37, 223, 228, 223, 223, 223, 
-	223, 223, 240, 223, 234, 235, 239, 239, 
-	40, 37, 223, 228, 223, 223, 223, 223, 
-	223, 223, 229, 223, 234, 235, 236, 239, 
-	40, 37, 223, 228, 223, 223, 69, 223, 
-	223, 223, 229, 223, 232, 223, 284, 223, 
-	265, 265, 223, 37, 223, 228, 223, 223, 
-	223, 223, 223, 232, 223, 232, 223, 223, 
-	223, 265, 265, 223, 37, 223, 228, 223, 
-	223, 223, 223, 223, 232, 223, 232, 223, 
-	223, 223, 265, 233, 223, 37, 223, 228, 
-	223, 223, 223, 223, 223, 232, 223, 70, 
-	39, 39, 40, 37, 223, 224, 225, 231, 
-	227, 40, 37, 223, 228, 223, 223, 223, 
-	223, 223, 223, 229, 223, 286, 151, 287, 
-	287, 76, 73, 285, 154, 285, 285, 285, 
-	285, 285, 285, 158, 285, 151, 287, 287, 
-	76, 73, 285, 154, 285, 285, 285, 285, 
-	285, 285, 158, 285, 288, 285, 285, 285, 
-	90, 289, 285, 73, 285, 154, 285, 285, 
-	285, 285, 285, 288, 285, 290, 291, 292, 
-	293, 76, 73, 285, 154, 285, 285, 106, 
-	285, 285, 285, 158, 285, 294, 291, 295, 
-	295, 76, 73, 285, 154, 285, 285, 285, 
-	285, 285, 285, 158, 285, 291, 295, 295, 
-	76, 73, 285, 154, 285, 285, 285, 285, 
-	285, 285, 158, 285, 296, 285, 285, 285, 
-	90, 297, 285, 73, 285, 154, 285, 285, 
-	285, 285, 285, 296, 285, 298, 299, 300, 
-	301, 76, 73, 285, 154, 285, 285, 104, 
-	285, 285, 285, 158, 285, 302, 299, 303, 
-	303, 76, 73, 285, 154, 285, 285, 285, 
-	285, 285, 285, 158, 285, 299, 303, 303, 
-	76, 73, 285, 154, 285, 285, 285, 285, 
-	285, 285, 158, 285, 304, 285, 285, 285, 
-	90, 305, 285, 73, 285, 154, 285, 285, 
-	285, 285, 285, 304, 285, 306, 307, 308, 
-	309, 76, 73, 285, 154, 285, 285, 102, 
-	285, 285, 285, 158, 285, 310, 307, 311, 
-	311, 76, 73, 285, 154, 285, 285, 285, 
-	285, 285, 285, 158, 285, 307, 311, 311, 
-	76, 73, 285, 154, 285, 285, 285, 285, 
-	285, 285, 158, 285, 312, 285, 285, 285, 
-	90, 313, 285, 73, 285, 154, 285, 285, 
-	285, 285, 285, 312, 285, 314, 315, 316, 
-	317, 76, 73, 285, 154, 285, 285, 100, 
-	285, 285, 285, 158, 285, 318, 315, 319, 
-	319, 76, 73, 285, 154, 285, 285, 285, 
-	285, 285, 285, 158, 285, 315, 319, 319, 
-	76, 73, 285, 154, 285, 285, 285, 285, 
-	285, 285, 158, 285, 90, 320, 285, 73, 
-	285, 154, 285, 321, 321, 285, 73, 285, 
-	154, 285, 322, 285, 285, 323, 285, 154, 
-	285, 154, 285, 324, 285, 325, 285, 322, 
-	285, 285, 285, 285, 154, 285, 90, 285, 
-	321, 321, 285, 73, 285, 154, 285, 321, 
-	320, 285, 73, 285, 154, 285, 326, 99, 
-	327, 328, 80, 73, 285, 154, 285, 99, 
-	327, 328, 80, 73, 285, 154, 285, 327, 
-	327, 80, 73, 285, 154, 285, 329, 96, 
-	330, 331, 83, 73, 285, 154, 285, 96, 
-	330, 331, 83, 73, 285, 154, 285, 330, 
-	330, 83, 73, 285, 154, 285, 332, 93, 
-	333, 334, 86, 73, 285, 154, 285, 93, 
-	333, 334, 86, 73, 285, 154, 285, 333, 
-	333, 86, 73, 285, 154, 285, 335, 90, 
-	321, 336, 285, 73, 285, 154, 285, 90, 
-	321, 336, 285, 73, 285, 154, 285, 315, 
-	319, 319, 76, 73, 285, 154, 285, 314, 
-	315, 319, 319, 76, 73, 285, 154, 285, 
-	285, 285, 285, 285, 285, 158, 285, 314, 
-	315, 316, 319, 76, 73, 285, 154, 285, 
-	285, 100, 285, 285, 285, 158, 285, 312, 
-	285, 337, 285, 321, 321, 285, 73, 285, 
-	154, 285, 285, 285, 285, 285, 312, 285, 
-	312, 285, 285, 285, 321, 321, 285, 73, 
-	285, 154, 285, 285, 285, 285, 285, 312, 
-	285, 312, 285, 285, 285, 321, 313, 285, 
-	73, 285, 154, 285, 285, 285, 285, 285, 
-	312, 285, 306, 307, 311, 311, 76, 73, 
-	285, 154, 285, 285, 285, 285, 285, 285, 
-	158, 285, 306, 307, 308, 311, 76, 73, 
-	285, 154, 285, 285, 102, 285, 285, 285, 
-	158, 285, 304, 285, 338, 285, 321, 321, 
-	285, 73, 285, 154, 285, 285, 285, 285, 
-	285, 304, 285, 304, 285, 285, 285, 321, 
-	321, 285, 73, 285, 154, 285, 285, 285, 
-	285, 285, 304, 285, 304, 285, 285, 285, 
-	321, 305, 285, 73, 285, 154, 285, 285, 
-	285, 285, 285, 304, 285, 298, 299, 303, 
-	303, 76, 73, 285, 154, 285, 285, 285, 
-	285, 285, 285, 158, 285, 298, 299, 300, 
-	303, 76, 73, 285, 154, 285, 285, 104, 
-	285, 285, 285, 158, 285, 296, 285, 339, 
-	285, 321, 321, 285, 73, 285, 154, 285, 
-	285, 285, 285, 285, 296, 285, 296, 285, 
-	285, 285, 321, 321, 285, 73, 285, 154, 
-	285, 285, 285, 285, 285, 296, 285, 296, 
-	285, 285, 285, 321, 297, 285, 73, 285, 
-	154, 285, 285, 285, 285, 285, 296, 285, 
-	290, 291, 295, 295, 76, 73, 285, 154, 
-	285, 285, 285, 285, 285, 285, 158, 285, 
-	290, 291, 292, 295, 76, 73, 285, 154, 
-	285, 285, 106, 285, 285, 285, 158, 285, 
-	288, 285, 340, 285, 321, 321, 285, 73, 
-	285, 154, 285, 285, 285, 285, 285, 288, 
-	285, 288, 285, 285, 285, 321, 321, 285, 
-	73, 285, 154, 285, 285, 285, 285, 285, 
-	288, 285, 288, 285, 285, 285, 321, 289, 
-	285, 73, 285, 154, 285, 285, 285, 285, 
-	285, 288, 285, 107, 75, 75, 76, 73, 
-	341, 341, 341, 341, 144, 341, 150, 151, 
-	287, 287, 76, 73, 285, 154, 285, 285, 
-	285, 285, 285, 285, 158, 285, 107, 75, 
-	75, 76, 73, 341, 343, 344, 345, 346, 
-	112, 109, 342, 347, 342, 342, 143, 342, 
-	342, 342, 348, 342, 349, 344, 346, 346, 
-	112, 109, 342, 347, 342, 342, 342, 342, 
-	342, 342, 348, 342, 344, 346, 346, 112, 
-	109, 342, 347, 342, 342, 342, 342, 342, 
-	342, 348, 342, 350, 342, 342, 342, 125, 
-	351, 342, 109, 342, 347, 342, 342, 342, 
-	342, 342, 350, 342, 352, 353, 354, 355, 
-	112, 109, 342, 347, 342, 342, 141, 342, 
-	342, 342, 348, 342, 356, 353, 357, 357, 
-	112, 109, 342, 347, 342, 342, 342, 342, 
-	342, 342, 348, 342, 353, 357, 357, 112, 
-	109, 342, 347, 342, 342, 342, 342, 342, 
-	342, 348, 342, 358, 342, 342, 342, 125, 
-	359, 342, 109, 342, 347, 342, 342, 342, 
-	342, 342, 358, 342, 360, 361, 362, 363, 
-	112, 109, 342, 347, 342, 342, 139, 342, 
-	342, 342, 348, 342, 364, 361, 365, 365, 
-	112, 109, 342, 347, 342, 342, 342, 342, 
-	342, 342, 348, 342, 361, 365, 365, 112, 
-	109, 342, 347, 342, 342, 342, 342, 342, 
-	342, 348, 342, 366, 342, 342, 342, 125, 
-	367, 342, 109, 342, 347, 342, 342, 342, 
-	342, 342, 366, 342, 368, 369, 370, 371, 
-	112, 109, 342, 347, 342, 342, 137, 342, 
-	342, 342, 348, 342, 372, 369, 373, 373, 
-	112, 109, 342, 347, 342, 342, 342, 342, 
-	342, 342, 348, 342, 369, 373, 373, 112, 
-	109, 342, 347, 342, 342, 342, 342, 342, 
-	342, 348, 342, 374, 342, 342, 342, 125, 
-	375, 342, 109, 342, 347, 342, 342, 342, 
-	342, 342, 374, 342, 376, 377, 378, 379, 
-	112, 109, 342, 347, 342, 342, 135, 342, 
-	342, 342, 348, 342, 380, 377, 381, 381, 
-	112, 109, 342, 347, 342, 342, 342, 342, 
-	342, 342, 348, 342, 377, 381, 381, 112, 
-	109, 342, 347, 342, 342, 342, 342, 342, 
-	342, 348, 342, 125, 382, 342, 109, 342, 
-	347, 342, 383, 383, 342, 109, 342, 347, 
-	342, 384, 342, 342, 385, 342, 347, 342, 
-	347, 342, 386, 342, 387, 342, 384, 342, 
-	342, 342, 342, 347, 342, 125, 342, 383, 
-	383, 342, 109, 342, 347, 342, 383, 382, 
-	342, 109, 342, 347, 342, 388, 134, 389, 
-	390, 115, 109, 342, 347, 342, 134, 389, 
-	390, 115, 109, 342, 347, 342, 389, 389, 
-	115, 109, 342, 347, 342, 391, 131, 392, 
-	393, 118, 109, 342, 347, 342, 131, 392, 
-	393, 118, 109, 342, 347, 342, 392, 392, 
-	118, 109, 342, 347, 342, 394, 128, 395, 
-	396, 121, 109, 342, 347, 342, 128, 395, 
-	396, 121, 109, 342, 347, 342, 395, 395, 
-	121, 109, 342, 347, 342, 397, 125, 383, 
-	398, 342, 109, 342, 347, 342, 125, 383, 
-	398, 342, 109, 342, 347, 342, 377, 381, 
-	381, 112, 109, 342, 347, 342, 376, 377, 
-	381, 381, 112, 109, 342, 347, 342, 342, 
-	342, 342, 342, 342, 348, 342, 376, 377, 
-	378, 381, 112, 109, 342, 347, 342, 342, 
-	135, 342, 342, 342, 348, 342, 374, 342, 
-	399, 342, 383, 383, 342, 109, 342, 347, 
-	342, 342, 342, 342, 342, 374, 342, 374, 
-	342, 342, 342, 383, 383, 342, 109, 342, 
-	347, 342, 342, 342, 342, 342, 374, 342, 
-	374, 342, 342, 342, 383, 375, 342, 109, 
-	342, 347, 342, 342, 342, 342, 342, 374, 
-	342, 368, 369, 373, 373, 112, 109, 342, 
-	347, 342, 342, 342, 342, 342, 342, 348, 
-	342, 368, 369, 370, 373, 112, 109, 342, 
-	347, 342, 342, 137, 342, 342, 342, 348, 
-	342, 366, 342, 400, 342, 383, 383, 342, 
-	109, 342, 347, 342, 342, 342, 342, 342, 
-	366, 342, 366, 342, 342, 342, 383, 383, 
-	342, 109, 342, 347, 342, 342, 342, 342, 
-	342, 366, 342, 366, 342, 342, 342, 383, 
-	367, 342, 109, 342, 347, 342, 342, 342, 
-	342, 342, 366, 342, 360, 361, 365, 365, 
-	112, 109, 342, 347, 342, 342, 342, 342, 
-	342, 342, 348, 342, 360, 361, 362, 365, 
-	112, 109, 342, 347, 342, 342, 139, 342, 
-	342, 342, 348, 342, 358, 342, 401, 342, 
-	383, 383, 342, 109, 342, 347, 342, 342, 
-	342, 342, 342, 358, 342, 358, 342, 342, 
-	342, 383, 383, 342, 109, 342, 347, 342, 
-	342, 342, 342, 342, 358, 342, 358, 342, 
-	342, 342, 383, 359, 342, 109, 342, 347, 
-	342, 342, 342, 342, 342, 358, 342, 352, 
-	353, 357, 357, 112, 109, 342, 347, 342, 
-	342, 342, 342, 342, 342, 348, 342, 352, 
-	353, 354, 357, 112, 109, 342, 347, 342, 
-	342, 141, 342, 342, 342, 348, 342, 350, 
-	342, 402, 342, 383, 383, 342, 109, 342, 
-	347, 342, 342, 342, 342, 342, 350, 342, 
-	350, 342, 342, 342, 383, 383, 342, 109, 
-	342, 347, 342, 342, 342, 342, 342, 350, 
-	342, 350, 342, 342, 342, 383, 351, 342, 
-	109, 342, 347, 342, 342, 342, 342, 342, 
-	350, 342, 343, 344, 346, 346, 112, 109, 
-	342, 347, 342, 342, 342, 342, 342, 342, 
-	348, 342, 148, 149, 150, 151, 403, 287, 
-	76, 73, 285, 154, 155, 155, 144, 285, 
-	285, 148, 158, 285, 162, 404, 164, 165, 
-	4, 1, 161, 166, 161, 161, 35, 161, 
-	161, 161, 167, 161, 170, 149, 150, 151, 
-	405, 406, 76, 407, 161, 408, 161, 155, 
-	144, 161, 161, 170, 158, 161, 107, 409, 
-	409, 76, 407, 161, 166, 161, 161, 144, 
-	161, 410, 161, 161, 411, 161, 408, 161, 
-	408, 161, 412, 161, 207, 161, 410, 161, 
-	161, 161, 161, 408, 161, 170, 161, 222, 
-	107, 409, 409, 76, 407, 161, 166, 161, 
-	161, 161, 161, 161, 170, 161, 414, 413, 
-	415, 415, 413, 146, 413, 416, 413, 415, 
-	415, 413, 146, 413, 416, 413, 417, 413, 
-	413, 418, 413, 416, 413, 416, 413, 419, 
-	413, 420, 413, 417, 413, 413, 413, 413, 
-	416, 413, 148, 341, 341, 341, 341, 341, 
-	341, 341, 341, 341, 155, 341, 341, 341, 
-	341, 148, 341, 0
+	3, 3, 4, 0, 3, 3, 4, 1, 
+	0, 5, 3, 3, 4, 1, 0, 6, 
+	0, 7, 0, 8, 3, 3, 4, 1, 
+	0, 2, 3, 3, 4, 1, 0, 0, 
+	0, 0, 9, 0, 11, 12, 12, 13, 
+	14, 10, 14, 10, 12, 12, 13, 10, 
+	12, 12, 13, 14, 10, 15, 12, 12, 
+	13, 14, 10, 16, 10, 17, 10, 18, 
+	12, 12, 13, 14, 10, 11, 12, 12, 
+	13, 14, 10, 10, 10, 10, 19, 10, 
+	11, 12, 12, 13, 14, 10, 10, 10, 
+	10, 20, 10, 22, 23, 23, 24, 25, 
+	21, 21, 21, 21, 26, 21, 25, 21, 
+	23, 23, 24, 27, 23, 23, 24, 25, 
+	21, 28, 23, 23, 24, 25, 21, 29, 
+	21, 30, 21, 22, 23, 23, 24, 25, 
+	21, 31, 23, 23, 24, 25, 21, 33, 
+	34, 34, 35, 36, 32, 32, 32, 32, 
+	37, 32, 36, 32, 34, 34, 35, 32, 
+	34, 34, 35, 36, 32, 38, 34, 34, 
+	35, 36, 32, 39, 32, 40, 32, 33, 
+	34, 34, 35, 36, 32, 41, 34, 34, 
+	35, 36, 32, 23, 23, 24, 1, 0, 
+	43, 42, 45, 46, 47, 48, 49, 50, 
+	24, 25, 44, 51, 52, 52, 26, 44, 
+	53, 54, 55, 56, 57, 44, 59, 60, 
+	61, 62, 4, 1, 58, 63, 58, 58, 
+	9, 58, 58, 58, 64, 58, 65, 60, 
+	66, 66, 4, 1, 58, 63, 58, 58, 
+	58, 58, 58, 58, 64, 58, 60, 66, 
+	66, 4, 1, 58, 63, 58, 58, 58, 
+	58, 58, 58, 64, 58, 45, 58, 58, 
+	58, 67, 68, 58, 1, 58, 63, 58, 
+	58, 58, 58, 58, 45, 58, 69, 69, 
+	58, 1, 58, 63, 58, 63, 58, 58, 
+	70, 58, 63, 58, 63, 58, 63, 58, 
+	58, 58, 58, 63, 58, 45, 58, 71, 
+	58, 69, 69, 58, 1, 58, 63, 58, 
+	58, 58, 58, 58, 45, 58, 45, 58, 
+	58, 58, 69, 69, 58, 1, 58, 63, 
+	58, 58, 58, 58, 58, 45, 58, 45, 
+	58, 58, 58, 69, 68, 58, 1, 58, 
+	63, 58, 58, 58, 58, 58, 45, 58, 
+	72, 7, 73, 74, 4, 1, 58, 63, 
+	58, 7, 73, 74, 4, 1, 58, 63, 
+	58, 73, 73, 4, 1, 58, 63, 58, 
+	75, 76, 76, 4, 1, 58, 63, 58, 
+	67, 77, 58, 1, 58, 63, 58, 67, 
+	58, 69, 69, 58, 1, 58, 63, 58, 
+	69, 77, 58, 1, 58, 63, 58, 59, 
+	60, 66, 66, 4, 1, 58, 63, 58, 
+	58, 58, 58, 58, 58, 64, 58, 59, 
+	60, 61, 66, 4, 1, 58, 63, 58, 
+	58, 9, 58, 58, 58, 64, 58, 79, 
+	80, 81, 82, 13, 14, 78, 83, 78, 
+	78, 20, 78, 78, 78, 84, 78, 85, 
+	80, 86, 82, 13, 14, 78, 83, 78, 
+	78, 78, 78, 78, 78, 84, 78, 80, 
+	86, 82, 13, 14, 78, 83, 78, 78, 
+	78, 78, 78, 78, 84, 78, 87, 78, 
+	78, 78, 88, 89, 78, 14, 78, 83, 
+	78, 78, 78, 78, 78, 87, 78, 90, 
+	80, 91, 92, 13, 14, 78, 83, 78, 
+	78, 19, 78, 78, 78, 84, 78, 93, 
+	80, 86, 86, 13, 14, 78, 83, 78, 
+	78, 78, 78, 78, 78, 84, 78, 80, 
+	86, 86, 13, 14, 78, 83, 78, 78, 
+	78, 78, 78, 78, 84, 78, 87, 78, 
+	78, 78, 94, 89, 78, 14, 78, 83, 
+	78, 78, 78, 78, 78, 87, 78, 83, 
+	78, 78, 95, 78, 83, 78, 83, 78, 
+	83, 78, 78, 78, 78, 83, 78, 87, 
+	78, 96, 78, 94, 94, 78, 14, 78, 
+	83, 78, 78, 78, 78, 78, 87, 78, 
+	87, 78, 78, 78, 94, 94, 78, 14, 
+	78, 83, 78, 78, 78, 78, 78, 87, 
+	78, 97, 17, 98, 99, 13, 14, 78, 
+	83, 78, 17, 98, 99, 13, 14, 78, 
+	83, 78, 98, 98, 13, 14, 78, 83, 
+	78, 100, 101, 101, 13, 14, 78, 83, 
+	78, 88, 102, 78, 14, 78, 83, 78, 
+	94, 94, 78, 14, 78, 83, 78, 88, 
+	78, 94, 94, 78, 14, 78, 83, 78, 
+	94, 102, 78, 14, 78, 83, 78, 90, 
+	80, 86, 86, 13, 14, 78, 83, 78, 
+	78, 78, 78, 78, 78, 84, 78, 90, 
+	80, 91, 86, 13, 14, 78, 83, 78, 
+	78, 19, 78, 78, 78, 84, 78, 11, 
+	12, 12, 13, 14, 78, 79, 80, 86, 
+	82, 13, 14, 78, 83, 78, 78, 78, 
+	78, 78, 78, 84, 78, 104, 48, 105, 
+	105, 24, 25, 103, 51, 103, 103, 103, 
+	103, 103, 103, 55, 103, 48, 105, 105, 
+	24, 25, 103, 51, 103, 103, 103, 103, 
+	103, 103, 55, 103, 106, 103, 103, 103, 
+	107, 108, 103, 25, 103, 51, 103, 103, 
+	103, 103, 103, 106, 103, 47, 48, 109, 
+	110, 24, 25, 103, 51, 103, 103, 26, 
+	103, 103, 103, 55, 103, 106, 103, 103, 
+	103, 111, 108, 103, 25, 103, 51, 103, 
+	103, 103, 103, 103, 106, 103, 51, 103, 
+	103, 112, 103, 51, 103, 51, 103, 51, 
+	103, 103, 103, 103, 51, 103, 106, 103, 
+	113, 103, 111, 111, 103, 25, 103, 51, 
+	103, 103, 103, 103, 103, 106, 103, 106, 
+	103, 103, 103, 111, 111, 103, 25, 103, 
+	51, 103, 103, 103, 103, 103, 106, 103, 
+	114, 30, 115, 116, 24, 25, 103, 51, 
+	103, 30, 115, 116, 24, 25, 103, 51, 
+	103, 115, 115, 24, 25, 103, 51, 103, 
+	47, 48, 105, 105, 24, 25, 103, 51, 
+	103, 103, 103, 103, 103, 103, 55, 103, 
+	117, 118, 118, 24, 25, 103, 51, 103, 
+	107, 119, 103, 25, 103, 51, 103, 111, 
+	111, 103, 25, 103, 51, 103, 107, 103, 
+	111, 111, 103, 25, 103, 51, 103, 111, 
+	119, 103, 25, 103, 51, 103, 47, 48, 
+	109, 105, 24, 25, 103, 51, 103, 103, 
+	26, 103, 103, 103, 55, 103, 22, 23, 
+	23, 24, 25, 120, 120, 120, 120, 26, 
+	120, 22, 23, 23, 24, 25, 120, 122, 
+	123, 124, 125, 35, 36, 121, 126, 121, 
+	121, 37, 121, 121, 121, 127, 121, 128, 
+	123, 125, 125, 35, 36, 121, 126, 121, 
+	121, 121, 121, 121, 121, 127, 121, 123, 
+	125, 125, 35, 36, 121, 126, 121, 121, 
+	121, 121, 121, 121, 127, 121, 129, 121, 
+	121, 121, 130, 131, 121, 36, 121, 126, 
+	121, 121, 121, 121, 121, 129, 121, 122, 
+	123, 124, 52, 35, 36, 121, 126, 121, 
+	121, 37, 121, 121, 121, 127, 121, 129, 
+	121, 121, 121, 132, 131, 121, 36, 121, 
+	126, 121, 121, 121, 121, 121, 129, 121, 
+	126, 121, 121, 133, 121, 126, 121, 126, 
+	121, 126, 121, 121, 121, 121, 126, 121, 
+	129, 121, 134, 121, 132, 132, 121, 36, 
+	121, 126, 121, 121, 121, 121, 121, 129, 
+	121, 129, 121, 121, 121, 132, 132, 121, 
+	36, 121, 126, 121, 121, 121, 121, 121, 
+	129, 121, 135, 40, 136, 137, 35, 36, 
+	121, 126, 121, 40, 136, 137, 35, 36, 
+	121, 126, 121, 136, 136, 35, 36, 121, 
+	126, 121, 122, 123, 125, 125, 35, 36, 
+	121, 126, 121, 121, 121, 121, 121, 121, 
+	127, 121, 138, 139, 139, 35, 36, 121, 
+	126, 121, 130, 140, 121, 36, 121, 126, 
+	121, 132, 132, 121, 36, 121, 126, 121, 
+	130, 121, 132, 132, 121, 36, 121, 126, 
+	121, 132, 140, 121, 36, 121, 126, 121, 
+	45, 46, 47, 48, 109, 105, 24, 25, 
+	103, 51, 52, 52, 26, 103, 103, 45, 
+	55, 103, 59, 141, 61, 62, 4, 1, 
+	58, 63, 58, 58, 9, 58, 58, 58, 
+	64, 58, 45, 46, 47, 48, 142, 143, 
+	24, 144, 58, 145, 58, 52, 26, 58, 
+	58, 45, 55, 58, 22, 146, 146, 24, 
+	144, 58, 63, 58, 58, 26, 58, 145, 
+	58, 58, 147, 58, 145, 58, 145, 58, 
+	145, 58, 58, 58, 58, 145, 58, 45, 
+	58, 71, 22, 146, 146, 24, 144, 58, 
+	63, 58, 58, 58, 58, 58, 45, 58, 
+	149, 148, 150, 150, 148, 43, 148, 151, 
+	148, 150, 150, 148, 43, 148, 151, 148, 
+	151, 148, 148, 152, 148, 151, 148, 151, 
+	148, 151, 148, 148, 148, 148, 151, 148, 
+	45, 120, 120, 120, 120, 120, 120, 120, 
+	120, 120, 52, 120, 120, 120, 120, 45, 
+	120, 0
 };
 
-static const short _indic_syllable_machine_trans_targs[] = {
-	138, 160, 166, 2, 167, 3, 5, 170, 
-	6, 8, 173, 9, 11, 176, 12, 14, 
-	15, 159, 17, 18, 175, 20, 21, 172, 
-	23, 24, 169, 179, 183, 184, 188, 189, 
-	193, 194, 198, 199, 138, 222, 228, 36, 
-	229, 37, 39, 232, 40, 42, 235, 43, 
-	45, 238, 46, 48, 49, 221, 51, 52, 
-	237, 54, 55, 234, 57, 58, 231, 241, 
-	245, 246, 250, 251, 255, 256, 260, 262, 
-	138, 283, 289, 70, 290, 138, 71, 73, 
-	293, 74, 76, 296, 77, 79, 299, 80, 
-	82, 83, 282, 85, 86, 298, 88, 89, 
-	295, 91, 92, 292, 302, 306, 307, 311, 
-	312, 316, 317, 321, 138, 346, 352, 103, 
-	353, 104, 106, 356, 107, 109, 359, 110, 
-	112, 362, 113, 115, 116, 345, 118, 119, 
-	361, 121, 122, 358, 124, 125, 355, 365, 
-	369, 370, 374, 375, 379, 380, 384, 385, 
-	323, 138, 398, 138, 139, 201, 263, 265, 
-	322, 324, 285, 325, 386, 387, 301, 396, 
-	403, 138, 140, 142, 33, 200, 162, 178, 
-	141, 32, 143, 196, 144, 146, 31, 195, 
-	145, 30, 147, 191, 148, 150, 29, 190, 
-	149, 28, 151, 186, 152, 154, 27, 185, 
-	153, 26, 155, 181, 156, 158, 25, 180, 
-	157, 1, 165, 0, 161, 164, 163, 138, 
-	168, 4, 22, 171, 7, 19, 174, 10, 
-	16, 177, 13, 182, 187, 192, 197, 138, 
-	202, 204, 67, 261, 224, 240, 203, 66, 
-	205, 258, 206, 208, 65, 257, 207, 64, 
-	209, 253, 210, 212, 63, 252, 211, 62, 
-	213, 248, 214, 216, 61, 247, 215, 60, 
-	217, 243, 218, 220, 59, 242, 219, 35, 
-	227, 34, 223, 226, 225, 138, 230, 38, 
-	56, 233, 41, 53, 236, 44, 50, 239, 
-	47, 244, 249, 254, 259, 138, 264, 100, 
-	266, 319, 267, 269, 99, 318, 268, 98, 
-	270, 314, 271, 273, 97, 313, 272, 96, 
-	274, 309, 275, 277, 95, 308, 276, 94, 
-	278, 304, 279, 281, 93, 303, 280, 69, 
-	288, 68, 284, 287, 286, 138, 291, 72, 
-	90, 294, 75, 87, 297, 78, 84, 300, 
-	81, 305, 310, 315, 320, 138, 138, 326, 
-	328, 134, 133, 348, 364, 327, 329, 382, 
-	330, 332, 132, 381, 331, 131, 333, 377, 
-	334, 336, 130, 376, 335, 129, 337, 372, 
-	338, 340, 128, 371, 339, 127, 341, 367, 
-	342, 344, 126, 366, 343, 102, 351, 101, 
-	347, 350, 349, 138, 354, 105, 123, 357, 
-	108, 120, 360, 111, 117, 363, 114, 368, 
-	373, 378, 383, 135, 388, 389, 395, 390, 
-	392, 136, 391, 394, 393, 138, 397, 137, 
-	400, 399, 402, 401, 138
+static const unsigned char _indic_syllable_machine_trans_targs[] = {
+	39, 45, 50, 2, 51, 5, 6, 53, 
+	57, 58, 39, 67, 11, 73, 68, 14, 
+	15, 75, 80, 81, 84, 39, 89, 21, 
+	95, 90, 98, 39, 24, 25, 97, 103, 
+	39, 112, 30, 118, 113, 121, 33, 34, 
+	120, 126, 39, 137, 39, 40, 60, 85, 
+	87, 105, 106, 91, 107, 127, 128, 99, 
+	135, 140, 39, 41, 43, 8, 59, 46, 
+	54, 42, 1, 44, 48, 0, 47, 49, 
+	52, 3, 4, 55, 7, 56, 39, 61, 
+	63, 18, 83, 69, 76, 62, 9, 64, 
+	78, 71, 65, 17, 82, 66, 10, 70, 
+	72, 74, 12, 13, 77, 16, 79, 39, 
+	86, 26, 88, 101, 93, 19, 104, 20, 
+	92, 94, 96, 22, 23, 100, 27, 102, 
+	39, 39, 108, 110, 28, 35, 114, 122, 
+	109, 111, 124, 116, 29, 115, 117, 119, 
+	31, 32, 123, 36, 125, 129, 130, 134, 
+	131, 132, 37, 133, 39, 136, 38, 138, 
+	139
 };
 
 static const char _indic_syllable_machine_trans_actions[] = {
 	1, 0, 2, 0, 2, 0, 0, 2, 
-	0, 0, 2, 0, 0, 2, 0, 0, 
-	0, 2, 0, 0, 2, 0, 0, 2, 
-	0, 0, 2, 2, 2, 2, 2, 2, 
-	2, 2, 2, 2, 3, 0, 2, 0, 
-	2, 0, 0, 2, 0, 0, 2, 0, 
-	0, 2, 0, 0, 0, 2, 0, 0, 
-	2, 0, 0, 2, 0, 0, 2, 2, 
-	2, 2, 2, 2, 2, 2, 2, 2, 
-	4, 0, 2, 0, 2, 5, 0, 0, 
-	2, 0, 0, 2, 0, 0, 2, 0, 
-	0, 0, 2, 0, 0, 2, 0, 0, 
-	2, 0, 0, 2, 6, 2, 6, 2, 
-	6, 2, 6, 2, 7, 0, 2, 0, 
-	2, 0, 0, 2, 0, 0, 2, 0, 
-	0, 2, 0, 0, 0, 2, 0, 0, 
-	2, 0, 0, 2, 0, 0, 2, 2, 
-	2, 2, 2, 2, 2, 2, 2, 2, 
-	6, 8, 0, 11, 2, 2, 6, 0, 
-	12, 12, 0, 2, 6, 2, 6, 2, 
-	0, 13, 2, 0, 0, 2, 0, 2, 
-	2, 0, 2, 2, 2, 0, 0, 2, 
-	2, 0, 2, 2, 2, 0, 0, 2, 
-	2, 0, 2, 2, 2, 0, 0, 2, 
-	2, 0, 2, 2, 2, 0, 0, 2, 
-	2, 0, 2, 0, 0, 0, 0, 14, 
-	2, 0, 0, 2, 0, 0, 2, 0, 
-	0, 2, 0, 2, 2, 2, 2, 15, 
-	2, 0, 0, 2, 0, 2, 2, 0, 
-	2, 2, 2, 0, 0, 2, 2, 0, 
-	2, 2, 2, 0, 0, 2, 2, 0, 
-	2, 2, 2, 0, 0, 2, 2, 0, 
-	2, 2, 2, 0, 0, 2, 2, 0, 
-	2, 0, 0, 0, 0, 16, 2, 0, 
-	0, 2, 0, 0, 2, 0, 0, 2, 
-	0, 2, 2, 2, 2, 17, 6, 0, 
-	6, 2, 6, 0, 0, 6, 6, 0, 
-	6, 2, 6, 0, 0, 6, 6, 0, 
-	6, 2, 6, 0, 0, 6, 6, 0, 
-	6, 2, 6, 0, 0, 6, 6, 0, 
-	2, 0, 0, 0, 0, 18, 2, 0, 
-	0, 2, 0, 0, 2, 0, 0, 2, 
-	0, 2, 2, 2, 2, 19, 20, 2, 
-	0, 0, 0, 0, 2, 2, 2, 2, 
-	2, 0, 0, 2, 2, 0, 2, 2, 
-	2, 0, 0, 2, 2, 0, 2, 2, 
-	2, 0, 0, 2, 2, 0, 2, 2, 
-	2, 0, 0, 2, 2, 0, 2, 0, 
-	0, 0, 0, 21, 2, 0, 0, 2, 
-	0, 0, 2, 0, 0, 2, 0, 2, 
-	2, 2, 2, 0, 0, 22, 22, 0, 
-	0, 0, 0, 0, 0, 23, 2, 0, 
-	0, 0, 0, 0, 24
+	2, 2, 3, 2, 0, 2, 0, 0, 
+	0, 2, 2, 2, 2, 4, 2, 0, 
+	5, 0, 5, 6, 0, 0, 5, 2, 
+	7, 2, 0, 2, 0, 2, 0, 0, 
+	2, 2, 8, 0, 11, 2, 2, 5, 
+	0, 12, 12, 0, 2, 5, 2, 5, 
+	2, 0, 13, 2, 0, 0, 2, 0, 
+	2, 2, 0, 2, 2, 0, 0, 2, 
+	2, 0, 0, 0, 0, 2, 14, 2, 
+	0, 0, 2, 0, 2, 2, 0, 2, 
+	2, 2, 2, 0, 2, 2, 0, 0, 
+	2, 2, 0, 0, 0, 0, 2, 15, 
+	5, 0, 5, 2, 2, 0, 5, 0, 
+	0, 2, 5, 0, 0, 0, 0, 2, 
+	16, 17, 2, 0, 0, 0, 0, 2, 
+	2, 2, 2, 2, 0, 0, 2, 2, 
+	0, 0, 0, 0, 2, 0, 18, 18, 
+	0, 0, 0, 0, 19, 2, 0, 0, 
+	0
 };
 
 static const char _indic_syllable_machine_to_state_actions[] = {
@@ -823,6 +319,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 9, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
@@ -835,41 +332,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 9, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0
+	0, 0, 0, 0, 0
 };
 
 static const char _indic_syllable_machine_from_state_actions[] = {
@@ -877,6 +340,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 10, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
@@ -889,102 +353,35 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 10, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0
+	0, 0, 0, 0, 0
 };
 
 static const short _indic_syllable_machine_eof_trans[] = {
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 37, 37, 37, 73, 73, 78, 78, 
-	73, 73, 73, 73, 73, 73, 73, 73, 
-	73, 73, 73, 73, 73, 73, 73, 73, 
-	73, 73, 73, 73, 73, 73, 73, 73, 
-	73, 73, 73, 73, 73, 109, 109, 109, 
-	109, 109, 109, 109, 109, 109, 109, 109, 
-	109, 109, 109, 109, 109, 109, 109, 109, 
-	109, 109, 109, 109, 109, 109, 109, 109, 
-	109, 109, 109, 109, 109, 109, 109, 73, 
-	1, 146, 0, 162, 162, 162, 162, 162, 
-	162, 162, 162, 162, 162, 162, 162, 162, 
-	162, 162, 162, 162, 162, 162, 162, 162, 
-	162, 162, 162, 162, 162, 162, 162, 162, 
-	162, 162, 162, 162, 162, 162, 162, 162, 
-	162, 162, 162, 162, 162, 162, 162, 162, 
-	162, 162, 162, 162, 162, 162, 162, 162, 
-	162, 162, 162, 162, 162, 162, 162, 162, 
-	162, 224, 224, 224, 224, 224, 224, 224, 
-	224, 224, 224, 224, 224, 224, 224, 224, 
-	224, 224, 224, 224, 224, 224, 224, 224, 
-	224, 224, 224, 224, 224, 224, 224, 224, 
-	224, 224, 224, 224, 224, 224, 224, 224, 
-	224, 224, 224, 224, 224, 224, 224, 224, 
-	224, 224, 224, 224, 224, 224, 224, 224, 
-	224, 224, 224, 224, 224, 224, 224, 286, 
-	286, 286, 286, 286, 286, 286, 286, 286, 
-	286, 286, 286, 286, 286, 286, 286, 286, 
-	286, 286, 286, 286, 286, 286, 286, 286, 
-	286, 286, 286, 286, 286, 286, 286, 286, 
-	286, 286, 286, 286, 286, 286, 286, 286, 
-	286, 286, 286, 286, 286, 286, 286, 286, 
-	286, 286, 286, 286, 286, 286, 286, 286, 
-	286, 286, 342, 286, 342, 343, 343, 343, 
-	343, 343, 343, 343, 343, 343, 343, 343, 
-	343, 343, 343, 343, 343, 343, 343, 343, 
-	343, 343, 343, 343, 343, 343, 343, 343, 
-	343, 343, 343, 343, 343, 343, 343, 343, 
-	343, 343, 343, 343, 343, 343, 343, 343, 
-	343, 343, 343, 343, 343, 343, 343, 343, 
-	343, 343, 343, 343, 343, 343, 343, 343, 
-	343, 343, 286, 162, 162, 162, 162, 162, 
-	162, 162, 162, 162, 414, 414, 414, 414, 
-	414, 414, 414, 342
+	1, 11, 11, 11, 11, 11, 11, 11, 
+	11, 11, 11, 22, 22, 28, 22, 22, 
+	22, 22, 22, 22, 33, 33, 33, 33, 
+	33, 33, 33, 33, 33, 1, 43, 0, 
+	59, 59, 59, 59, 59, 59, 59, 59, 
+	59, 59, 59, 59, 59, 59, 59, 59, 
+	59, 59, 59, 59, 79, 79, 79, 79, 
+	79, 79, 79, 79, 79, 79, 79, 79, 
+	79, 79, 79, 79, 79, 79, 79, 79, 
+	79, 79, 79, 79, 79, 104, 104, 104, 
+	104, 104, 104, 104, 104, 104, 104, 104, 
+	104, 104, 104, 104, 104, 104, 104, 104, 
+	104, 121, 121, 122, 122, 122, 122, 122, 
+	122, 122, 122, 122, 122, 122, 122, 122, 
+	122, 122, 122, 122, 122, 122, 122, 104, 
+	59, 59, 59, 59, 59, 59, 59, 149, 
+	149, 149, 149, 149, 121
 };
 
-static const int indic_syllable_machine_start = 138;
-static const int indic_syllable_machine_first_final = 138;
+static const int indic_syllable_machine_start = 39;
+static const int indic_syllable_machine_first_final = 39;
 static const int indic_syllable_machine_error = -1;
 
-static const int indic_syllable_machine_en_main = 138;
+static const int indic_syllable_machine_en_main = 39;
 
 
 #line 36 "hb-ot-shape-complex-indic-machine.rl"
@@ -1010,7 +407,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 1014 "hb-ot-shape-complex-indic-machine.hh"
+#line 411 "hb-ot-shape-complex-indic-machine.hh"
 	{
 	cs = indic_syllable_machine_start;
 	ts = 0;
@@ -1026,12 +423,12 @@
 
   unsigned int syllable_serial = 1;
   
-#line 1030 "hb-ot-shape-complex-indic-machine.hh"
+#line 427 "hb-ot-shape-complex-indic-machine.hh"
 	{
 	int _slen;
 	int _trans;
 	const unsigned char *_keys;
-	const short *_inds;
+	const unsigned char *_inds;
 	if ( p == pe )
 		goto _test_eof;
 _resume:
@@ -1040,7 +437,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 1044 "hb-ot-shape-complex-indic-machine.hh"
+#line 441 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 	_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -1062,26 +459,6 @@
 #line 1 "NONE"
 	{te = p+1;}
 	break;
-	case 14:
-#line 84 "hb-ot-shape-complex-indic-machine.rl"
-	{te = p+1;{ found_syllable (consonant_syllable); }}
-	break;
-	case 16:
-#line 85 "hb-ot-shape-complex-indic-machine.rl"
-	{te = p+1;{ found_syllable (vowel_syllable); }}
-	break;
-	case 21:
-#line 86 "hb-ot-shape-complex-indic-machine.rl"
-	{te = p+1;{ found_syllable (standalone_cluster); }}
-	break;
-	case 24:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
-	{te = p+1;{ found_syllable (symbol_cluster); }}
-	break;
-	case 18:
-#line 88 "hb-ot-shape-complex-indic-machine.rl"
-	{te = p+1;{ found_syllable (broken_cluster); }}
-	break;
 	case 11:
 #line 89 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p+1;{ found_syllable (non_indic_cluster); }}
@@ -1090,23 +467,23 @@
 #line 84 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (consonant_syllable); }}
 	break;
-	case 15:
+	case 14:
 #line 85 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (vowel_syllable); }}
 	break;
-	case 20:
+	case 17:
 #line 86 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (standalone_cluster); }}
 	break;
-	case 23:
+	case 19:
 #line 87 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (symbol_cluster); }}
 	break;
-	case 17:
+	case 15:
 #line 88 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
-	case 19:
+	case 16:
 #line 89 "hb-ot-shape-complex-indic-machine.rl"
 	{te = p;p--;{ found_syllable (non_indic_cluster); }}
 	break;
@@ -1130,7 +507,7 @@
 #line 88 "hb-ot-shape-complex-indic-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
 	break;
-	case 5:
+	case 6:
 #line 1 "NONE"
 	{	switch( act ) {
 	case 1:
@@ -1145,13 +522,13 @@
 	}
 	}
 	break;
-	case 22:
+	case 18:
 #line 1 "NONE"
 	{te = p+1;}
 #line 84 "hb-ot-shape-complex-indic-machine.rl"
 	{act = 1;}
 	break;
-	case 6:
+	case 5:
 #line 1 "NONE"
 	{te = p+1;}
 #line 88 "hb-ot-shape-complex-indic-machine.rl"
@@ -1163,7 +540,7 @@
 #line 89 "hb-ot-shape-complex-indic-machine.rl"
 	{act = 6;}
 	break;
-#line 1167 "hb-ot-shape-complex-indic-machine.hh"
+#line 544 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 _again:
@@ -1172,7 +549,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 1176 "hb-ot-shape-complex-indic-machine.hh"
+#line 553 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 	if ( ++p != pe )

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl	2019-05-24 23:03:55 UTC (rev 51218)
@@ -64,14 +64,14 @@
 cn = c.ZWJ?.n?;
 forced_rakar = ZWJ H ZWJ Ra;
 symbol = Symbol.N?;
-matra_group = z{0,3}.M.N?.(H | forced_rakar)?;
-syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}?;
+matra_group = z*.M.N?.(H | forced_rakar)?;
+syllable_tail = (z?.SM.SM?.ZWNJ?)? A*;
 halant_group = (z?.H.(ZWJ.N?)?);
 final_halant_group = halant_group | H.ZWNJ;
 medial_group = CM?;
-halant_or_matra_group = (final_halant_group | matra_group{0,4});
+halant_or_matra_group = (final_halant_group | matra_group*);
 
-complex_syllable_tail = (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
+complex_syllable_tail = (halant_group.cn)* medial_group halant_or_matra_group syllable_tail;
 
 consonant_syllable =	(Repha|CS)? cn complex_syllable_tail;
 vowel_syllable =	reph? V.n? (ZWJ | complex_syllable_tail);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -274,7 +274,11 @@
   const indic_config_t *config;
 
   bool is_old_spec;
+#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE
   bool uniscribe_bug_compatible;
+#else
+  static constexpr bool uniscribe_bug_compatible = false;
+#endif
   mutable hb_atomic_int_t virama_glyph;
 
   would_substitute_feature_t rphf;
@@ -300,7 +304,9 @@
     }
 
   indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
+#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE
   indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible;
+#endif
   indic_plan->virama_glyph.set_relaxed (-1);
 
   /* Use zero-context would_substitute() matching for new-spec of the main
@@ -645,7 +651,7 @@
   /* Reorder characters */
 
   for (unsigned int i = start; i < base; i++)
-    info[i].indic_position() = MIN (POS_PRE_C, (indic_position_t) info[i].indic_position());
+    info[i].indic_position() = hb_min (POS_PRE_C, (indic_position_t) info[i].indic_position());
 
   if (base < end)
     info[base].indic_position() = POS_BASE_C;
@@ -801,7 +807,7 @@
 	  unsigned int j = start + info[i].syllable();
 	  while (j != i)
 	  {
-	    max = MAX (max, j);
+	    max = hb_max (max, j);
 	    unsigned int next = start + info[j].syllable();
 	    info[j].syllable() = 255; /* So we don't process j later again. */
 	    j = next;
@@ -918,11 +924,10 @@
 				       hb_buffer_t *buffer,
 				       unsigned int start, unsigned int end)
 {
-  const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
-
   /* We treat placeholder/dotted-circle as if they are consonants, so we
    * should just chain.  Only if not in compatibility mode that is... */
 
+  const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
   if (indic_plan->uniscribe_bug_compatible)
   {
     /* For dotted-circle, this is what Uniscribe does:
@@ -1008,7 +1013,6 @@
       ginfo.cluster = buffer->cur().cluster;
       ginfo.mask = buffer->cur().mask;
       ginfo.syllable() = buffer->cur().syllable();
-      /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
       while (buffer->idx < buffer->len && buffer->successful &&
@@ -1232,7 +1236,7 @@
 
 	  /* Note: this merge_clusters() is intentionally *after* the reordering.
 	   * Indic matra reordering is special and tricky... */
-	  buffer->merge_clusters (new_pos, MIN (end, base + 1));
+	  buffer->merge_clusters (new_pos, hb_min (end, base + 1));
 
 	  new_pos--;
 	}
@@ -1239,7 +1243,7 @@
     } else {
       for (unsigned int i = start; i < base; i++)
 	if (info[i].indic_position () == POS_PRE_M) {
-	  buffer->merge_clusters (i, MIN (end, base + 1));
+	  buffer->merge_clusters (i, hb_min (end, base + 1));
 	  break;
 	}
     }
@@ -1372,7 +1376,8 @@
        * TEST: U+0930,U+094D,U+0915,U+094B,U+094D
        */
       if (!indic_plan->uniscribe_bug_compatible &&
-	  unlikely (is_halant (info[new_reph_pos]))) {
+	  unlikely (is_halant (info[new_reph_pos])))
+      {
 	for (unsigned int i = base + 1; i < new_reph_pos; i++)
 	  if (info[i].indic_category() == OT_M) {
 	    /* Ok, got it. */
@@ -1379,6 +1384,7 @@
 	    new_reph_pos--;
 	  }
       }
+
       goto reph_move;
     }
 
@@ -1591,11 +1597,10 @@
      *   https://docs.microsoft.com/en-us/typography/script-development/sinhala#shaping
      */
 
+
     const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
-
     hb_codepoint_t glyph;
-
-    if (hb_options ().uniscribe_bug_compatible ||
+    if (indic_plan->uniscribe_bug_compatible ||
 	(c->font->get_nominal_glyph (ab, &glyph) &&
 	 indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
     {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -278,7 +278,7 @@
     case POS_POST_C:	return MATRA_POS_RIGHT (u);
     case POS_ABOVE_C:	return MATRA_POS_TOP (u);
     case POS_BELOW_C:	return MATRA_POS_BOTTOM (u);
-  };
+  }
   return side;
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -368,7 +368,8 @@
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return;
 
-  /* Note: This loop is extra overhead, but should not be measurable. */
+  /* Note: This loop is extra overhead, but should not be measurable.
+   * TODO Use a buffer scratch flag to remove the loop. */
   bool has_broken_syllables = false;
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
@@ -407,7 +408,6 @@
       ginfo.cluster = buffer->cur().cluster;
       ginfo.mask = buffer->cur().mask;
       ginfo.syllable() = buffer->cur().syllable();
-      /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
       while (buffer->idx < buffer->len && buffer->successful &&

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -105,7 +105,7 @@
       case POS_ABOVE_C:	cat = OT_VAbv; break;
       case POS_POST_C:	cat = OT_VPst; break;
       default: assert (0);
-    };
+    }
 
   info.khmer_category() = cat;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -38,9 +38,9 @@
 	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, 
 	3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 
 	5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 
-	3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
-	3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 32u, 8u, 8u, 
-	0
+	3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
+	3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u, 
+	1u, 32u, 8u, 8u, 0
 };
 
 static const char _myanmar_syllable_machine_key_spans[] = {
@@ -48,8 +48,9 @@
 	27, 27, 27, 27, 16, 27, 27, 27, 
 	27, 27, 28, 27, 27, 27, 27, 25, 
 	4, 25, 23, 21, 21, 27, 27, 27, 
-	27, 28, 27, 32, 27, 27, 27, 27, 
-	27, 28, 27, 27, 27, 27, 32, 1
+	27, 16, 28, 27, 27, 27, 27, 27, 
+	28, 27, 27, 27, 27, 28, 27, 32, 
+	32, 1
 };
 
 static const short _myanmar_syllable_machine_index_offsets[] = {
@@ -57,8 +58,9 @@
 	187, 215, 243, 271, 299, 316, 344, 372, 
 	400, 428, 456, 485, 513, 541, 569, 597, 
 	623, 628, 654, 678, 700, 722, 750, 778, 
-	806, 834, 863, 891, 924, 952, 980, 1008, 
-	1036, 1064, 1093, 1121, 1149, 1177, 1205, 1238
+	806, 834, 851, 880, 908, 936, 964, 992, 
+	1020, 1049, 1077, 1105, 1133, 1161, 1190, 1218, 
+	1251, 1284
 };
 
 static const char _myanmar_syllable_machine_indicies[] = {
@@ -136,108 +138,115 @@
 	21, 22, 23, 24, 24, 21, 25, 21, 
 	26, 21, 21, 21, 21, 21, 21, 21, 
 	27, 21, 21, 28, 29, 30, 31, 32, 
-	33, 34, 35, 36, 21, 3, 3, 44, 
+	33, 34, 35, 36, 21, 45, 45, 44, 
 	5, 44, 44, 44, 44, 44, 44, 44, 
-	44, 44, 45, 44, 44, 44, 44, 44, 
-	44, 14, 44, 44, 44, 18, 44, 3, 
-	3, 44, 5, 44, 3, 3, 44, 5, 
+	44, 44, 46, 44, 44, 44, 44, 44, 
+	44, 14, 44, 44, 44, 18, 44, 45, 
+	45, 44, 5, 44, 45, 45, 44, 5, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
-	14, 44, 44, 44, 18, 44, 46, 44, 
-	3, 3, 44, 5, 44, 14, 44, 44, 
-	44, 44, 44, 44, 44, 47, 44, 44, 
-	44, 44, 44, 44, 14, 44, 3, 3, 
+	14, 44, 44, 44, 18, 44, 47, 44, 
+	45, 45, 44, 5, 44, 14, 44, 44, 
+	44, 44, 44, 44, 44, 48, 44, 44, 
+	44, 44, 44, 44, 14, 44, 45, 45, 
 	44, 5, 44, 44, 44, 44, 44, 44, 
-	44, 44, 44, 47, 44, 44, 44, 44, 
-	44, 44, 14, 44, 3, 3, 44, 5, 
+	44, 44, 44, 48, 44, 44, 44, 44, 
+	44, 44, 14, 44, 45, 45, 44, 5, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
-	14, 44, 2, 44, 3, 3, 44, 5, 
+	14, 44, 2, 44, 45, 45, 44, 5, 
 	44, 6, 44, 44, 44, 44, 44, 44, 
-	44, 48, 44, 44, 48, 44, 44, 44, 
-	14, 49, 44, 44, 18, 44, 2, 44, 
-	3, 3, 44, 5, 44, 6, 44, 44, 
+	44, 49, 44, 44, 49, 44, 44, 44, 
+	14, 50, 44, 44, 18, 44, 2, 44, 
+	45, 45, 44, 5, 44, 6, 44, 44, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
 	44, 44, 44, 44, 14, 44, 44, 44, 
-	18, 44, 2, 44, 3, 3, 44, 5, 
+	18, 44, 2, 44, 45, 45, 44, 5, 
 	44, 6, 44, 44, 44, 44, 44, 44, 
-	44, 48, 44, 44, 44, 44, 44, 44, 
-	14, 49, 44, 44, 18, 44, 2, 44, 
-	3, 3, 44, 5, 44, 6, 44, 44, 
+	44, 49, 44, 44, 44, 44, 44, 44, 
+	14, 50, 44, 44, 18, 44, 2, 44, 
+	45, 45, 44, 5, 44, 6, 44, 44, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
-	44, 44, 44, 44, 14, 49, 44, 44, 
-	18, 44, 22, 23, 24, 24, 21, 25, 
-	21, 26, 21, 21, 21, 21, 21, 21, 
-	21, 50, 21, 21, 28, 29, 30, 31, 
-	32, 33, 34, 35, 36, 37, 21, 22, 
-	51, 24, 24, 21, 25, 21, 26, 21, 
-	21, 21, 21, 21, 21, 21, 27, 21, 
-	21, 28, 29, 30, 31, 32, 33, 34, 
-	35, 36, 21, 1, 1, 2, 3, 3, 
-	3, 44, 5, 44, 6, 1, 44, 44, 
-	44, 44, 1, 44, 8, 44, 44, 10, 
-	11, 12, 13, 14, 15, 16, 17, 18, 
-	19, 44, 1, 44, 2, 44, 3, 3, 
+	44, 44, 44, 44, 14, 50, 44, 44, 
+	18, 44, 51, 51, 44, 44, 44, 44, 
+	44, 44, 44, 44, 44, 44, 44, 44, 
+	44, 51, 44, 2, 3, 45, 45, 44, 
+	5, 44, 6, 44, 44, 44, 44, 44, 
+	44, 44, 8, 44, 44, 10, 11, 12, 
+	13, 14, 15, 16, 17, 18, 19, 44, 
+	2, 44, 45, 45, 44, 5, 44, 6, 
+	44, 44, 44, 44, 44, 44, 44, 8, 
+	44, 44, 10, 11, 12, 13, 14, 15, 
+	16, 17, 18, 44, 2, 44, 45, 45, 
 	44, 5, 44, 6, 44, 44, 44, 44, 
-	44, 44, 44, 8, 44, 44, 10, 11, 
-	12, 13, 14, 15, 16, 17, 18, 44, 
-	2, 44, 3, 3, 44, 5, 44, 6, 
-	44, 44, 44, 44, 44, 44, 44, 52, 
+	44, 44, 44, 52, 44, 44, 44, 44, 
+	44, 44, 14, 15, 16, 17, 18, 44, 
+	2, 44, 45, 45, 44, 5, 44, 6, 
+	44, 44, 44, 44, 44, 44, 44, 44, 
 	44, 44, 44, 44, 44, 44, 14, 15, 
-	16, 17, 18, 44, 2, 44, 3, 3, 
+	16, 17, 18, 44, 2, 44, 45, 45, 
 	44, 5, 44, 6, 44, 44, 44, 44, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
-	44, 44, 14, 15, 16, 17, 18, 44, 
-	2, 44, 3, 3, 44, 5, 44, 6, 
+	44, 44, 14, 15, 16, 44, 18, 44, 
+	2, 44, 45, 45, 44, 5, 44, 6, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
-	44, 44, 44, 44, 44, 44, 14, 15, 
-	16, 44, 18, 44, 2, 44, 3, 3, 
+	44, 44, 44, 44, 44, 44, 14, 44, 
+	16, 44, 18, 44, 2, 44, 45, 45, 
 	44, 5, 44, 6, 44, 44, 44, 44, 
 	44, 44, 44, 44, 44, 44, 44, 44, 
-	44, 44, 14, 44, 16, 44, 18, 44, 
-	2, 44, 3, 3, 44, 5, 44, 6, 
-	44, 44, 44, 44, 44, 44, 44, 44, 
-	44, 44, 44, 44, 44, 44, 14, 15, 
-	16, 17, 18, 52, 44, 2, 44, 3, 
-	3, 44, 5, 44, 6, 44, 44, 44, 
-	44, 44, 44, 44, 52, 44, 44, 10, 
-	44, 12, 44, 14, 15, 16, 17, 18, 
-	44, 2, 44, 3, 3, 44, 5, 44, 
+	44, 44, 14, 15, 16, 17, 18, 52, 
+	44, 2, 44, 45, 45, 44, 5, 44, 
 	6, 44, 44, 44, 44, 44, 44, 44, 
-	52, 44, 44, 10, 44, 44, 44, 14, 
-	15, 16, 17, 18, 44, 2, 44, 3, 
-	3, 44, 5, 44, 6, 44, 44, 44, 
+	52, 44, 44, 10, 44, 12, 44, 14, 
+	15, 16, 17, 18, 44, 2, 44, 45, 
+	45, 44, 5, 44, 6, 44, 44, 44, 
 	44, 44, 44, 44, 52, 44, 44, 10, 
-	11, 12, 44, 14, 15, 16, 17, 18, 
-	44, 2, 3, 3, 3, 44, 5, 44, 
+	44, 44, 44, 14, 15, 16, 17, 18, 
+	44, 2, 44, 45, 45, 44, 5, 44, 
 	6, 44, 44, 44, 44, 44, 44, 44, 
-	8, 44, 44, 10, 11, 12, 13, 14, 
-	15, 16, 17, 18, 44, 1, 1, 53, 
-	53, 53, 53, 53, 53, 53, 53, 1, 
-	53, 53, 53, 53, 1, 53, 53, 53, 
-	53, 53, 53, 53, 53, 53, 53, 53, 
-	53, 53, 53, 53, 1, 53, 54, 53, 
-	0
+	52, 44, 44, 10, 11, 12, 44, 14, 
+	15, 16, 17, 18, 44, 2, 3, 45, 
+	45, 44, 5, 44, 6, 44, 44, 44, 
+	44, 44, 44, 44, 8, 44, 44, 10, 
+	11, 12, 13, 14, 15, 16, 17, 18, 
+	44, 22, 23, 24, 24, 21, 25, 21, 
+	26, 21, 21, 21, 21, 21, 21, 21, 
+	53, 21, 21, 28, 29, 30, 31, 32, 
+	33, 34, 35, 36, 37, 21, 22, 54, 
+	24, 24, 21, 25, 21, 26, 21, 21, 
+	21, 21, 21, 21, 21, 27, 21, 21, 
+	28, 29, 30, 31, 32, 33, 34, 35, 
+	36, 21, 1, 1, 2, 3, 45, 45, 
+	44, 5, 44, 6, 1, 44, 44, 44, 
+	44, 1, 44, 8, 44, 44, 10, 11, 
+	12, 13, 14, 15, 16, 17, 18, 19, 
+	44, 1, 44, 1, 1, 55, 55, 55, 
+	55, 55, 55, 55, 55, 1, 55, 55, 
+	55, 55, 1, 55, 55, 55, 55, 55, 
+	55, 55, 55, 55, 55, 55, 55, 55, 
+	55, 55, 1, 55, 56, 55, 0
 };
 
 static const char _myanmar_syllable_machine_trans_targs[] = {
-	0, 1, 23, 0, 0, 24, 30, 33, 
-	36, 46, 37, 42, 43, 44, 26, 39, 
-	40, 41, 29, 45, 47, 0, 2, 12, 
+	0, 1, 23, 33, 0, 24, 30, 45, 
+	35, 48, 36, 41, 42, 43, 26, 38, 
+	39, 40, 29, 44, 49, 0, 2, 12, 
 	0, 3, 9, 13, 14, 19, 20, 21, 
 	5, 16, 17, 18, 8, 22, 4, 6, 
-	7, 10, 11, 15, 0, 25, 27, 28, 
-	31, 32, 34, 35, 38, 0, 0
+	7, 10, 11, 15, 0, 0, 25, 27, 
+	28, 31, 32, 34, 37, 46, 47, 0, 
+	0
 };
 
 static const char _myanmar_syllable_machine_trans_actions[] = {
-	3, 0, 0, 4, 5, 0, 0, 0, 
+	3, 0, 0, 0, 4, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 6, 0, 0, 
-	7, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 5, 0, 0, 
+	6, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 8, 0, 0, 0, 
-	0, 0, 0, 0, 0, 9, 10
+	0, 0, 0, 0, 7, 8, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 9, 
+	10
 };
 
 static const char _myanmar_syllable_machine_to_state_actions[] = {
@@ -246,7 +255,8 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0
 };
 
 static const char _myanmar_syllable_machine_from_state_actions[] = {
@@ -255,7 +265,8 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0
 };
 
 static const short _myanmar_syllable_machine_eof_trans[] = {
@@ -263,8 +274,9 @@
 	22, 22, 22, 22, 22, 22, 22, 22, 
 	22, 22, 22, 22, 22, 22, 22, 45, 
 	45, 45, 45, 45, 45, 45, 45, 45, 
-	45, 22, 22, 45, 45, 45, 45, 45, 
-	45, 45, 45, 45, 45, 45, 54, 54
+	45, 45, 45, 45, 45, 45, 45, 45, 
+	45, 45, 45, 45, 45, 22, 22, 45, 
+	56, 56
 };
 
 static const int myanmar_syllable_machine_start = 0;
@@ -297,7 +309,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 301 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 313 "hb-ot-shape-complex-myanmar-machine.hh"
 	{
 	cs = myanmar_syllable_machine_start;
 	ts = 0;
@@ -313,7 +325,7 @@
 
   unsigned int syllable_serial = 1;
   
-#line 317 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 329 "hb-ot-shape-complex-myanmar-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -327,7 +339,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 331 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 343 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 	_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -345,11 +357,11 @@
 		goto _again;
 
 	switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
-	case 7:
+	case 6:
 #line 86 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (consonant_syllable); }}
 	break;
-	case 5:
+	case 4:
 #line 87 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (non_myanmar_cluster); }}
 	break;
@@ -357,7 +369,7 @@
 #line 88 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (punctuation_cluster); }}
 	break;
-	case 4:
+	case 8:
 #line 89 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (broken_cluster); }}
 	break;
@@ -365,11 +377,11 @@
 #line 90 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (non_myanmar_cluster); }}
 	break;
-	case 6:
+	case 5:
 #line 86 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (consonant_syllable); }}
 	break;
-	case 8:
+	case 7:
 #line 89 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
@@ -377,7 +389,7 @@
 #line 90 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
 	break;
-#line 381 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 393 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 _again:
@@ -386,7 +398,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 390 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 402 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 	if ( ++p != pe )

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl	2019-05-24 23:03:55 UTC (rev 51218)
@@ -75,9 +75,9 @@
 pwo_tone_group = PT A* DB? As?;
 
 complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;
-syllable_tail = (H | complex_syllable_tail);
+syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail);
 
-consonant_syllable =	(k|CS)? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
+consonant_syllable =	(k|CS)? (c|IV|D|GB).VS? syllable_tail;
 punctuation_cluster = 	P V;
 broken_cluster =	k? VS? syllable_tail;
 other =			any;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -301,7 +301,8 @@
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return;
 
-  /* Note: This loop is extra overhead, but should not be measurable. */
+  /* Note: This loop is extra overhead, but should not be measurable.
+   * TODO Use a buffer scratch flag to remove the loop. */
   bool has_broken_syllables = false;
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -146,7 +146,7 @@
       break;
 
     case 0xAA74u: case 0xAA75u: case 0xAA76u:
-      /* https://github.com/roozbehp/unicode-data/issues/3 */
+      /* https://github.com/harfbuzz/harfbuzz/issues/218 */
       cat = OT_C;
       break;
   }

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -218,6 +218,10 @@
 		     hb_buffer_t              *buffer,
 		     hb_font_t                *font)
 {
+#ifdef HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
+  return;
+#endif
+
   thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT];
   thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT];
   unsigned int base = 0;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -36,279 +36,273 @@
 
 #line 38 "hb-ot-shape-complex-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-	12u, 44u, 1u, 15u, 1u, 1u, 12u, 44u, 0u, 44u, 21u, 21u, 8u, 44u, 8u, 44u,
-	1u, 15u, 1u, 1u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u,
-	8u, 39u, 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u,
-	8u, 44u, 8u, 44u, 8u, 44u, 1u, 39u, 8u, 44u, 13u, 21u, 4u, 4u, 13u, 13u,
-	8u, 44u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u,
-	8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u,
-	8u, 44u, 8u, 44u, 1u, 39u, 1u, 15u, 12u, 44u, 1u, 44u, 8u, 44u, 21u, 42u,
-	41u, 42u, 42u, 42u, 1u, 5u, 0
+	12u, 44u, 1u, 15u, 1u, 1u, 12u, 44u, 0u, 47u, 21u, 21u, 11u, 47u, 11u, 47u, 
+	1u, 15u, 1u, 1u, 11u, 47u, 22u, 47u, 23u, 47u, 24u, 47u, 25u, 47u, 26u, 47u, 
+	45u, 46u, 46u, 46u, 24u, 47u, 24u, 47u, 24u, 47u, 23u, 47u, 23u, 47u, 23u, 47u, 
+	22u, 47u, 22u, 47u, 22u, 47u, 22u, 47u, 11u, 47u, 1u, 47u, 11u, 47u, 13u, 21u, 
+	4u, 4u, 13u, 13u, 11u, 47u, 11u, 47u, 41u, 42u, 42u, 42u, 11u, 47u, 11u, 47u, 
+	22u, 47u, 23u, 47u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 47u, 
+	24u, 47u, 24u, 47u, 23u, 47u, 23u, 47u, 23u, 47u, 22u, 47u, 22u, 47u, 22u, 47u, 
+	22u, 47u, 11u, 47u, 1u, 47u, 1u, 15u, 4u, 4u, 13u, 21u, 13u, 13u, 12u, 44u, 
+	1u, 47u, 11u, 47u, 41u, 42u, 42u, 42u, 21u, 42u, 1u, 5u, 0
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-	33, 15, 1, 33, 45, 1, 37, 37,
-	15, 1, 37, 37, 32, 19, 19, 19,
-	32, 32, 32, 37, 37, 37, 37, 37,
-	37, 37, 37, 39, 37, 9, 1, 1,
-	37, 37, 37, 32, 19, 19, 19, 32,
-	32, 32, 37, 37, 37, 37, 37, 37,
-	37, 37, 39, 15, 33, 44, 37, 22,
-	2, 1, 5
+	33, 15, 1, 33, 48, 1, 37, 37, 
+	15, 1, 37, 26, 25, 24, 23, 22, 
+	2, 1, 24, 24, 24, 25, 25, 25, 
+	26, 26, 26, 26, 37, 47, 37, 9, 
+	1, 1, 37, 37, 2, 1, 37, 37, 
+	26, 25, 24, 23, 22, 2, 1, 24, 
+	24, 24, 25, 25, 25, 26, 26, 26, 
+	26, 37, 47, 15, 1, 9, 1, 33, 
+	47, 37, 2, 1, 22, 5
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-	0, 34, 50, 52, 86, 132, 134, 172,
-	210, 226, 228, 266, 304, 337, 357, 377,
-	397, 430, 463, 496, 534, 572, 610, 648,
-	686, 724, 762, 800, 840, 878, 888, 890,
-	892, 930, 968, 1006, 1039, 1059, 1079, 1099,
-	1132, 1165, 1198, 1236, 1274, 1312, 1350, 1388,
-	1426, 1464, 1502, 1542, 1558, 1592, 1637, 1675,
-	1698, 1701, 1703
+	0, 34, 50, 52, 86, 135, 137, 175, 
+	213, 229, 231, 269, 296, 322, 347, 371, 
+	394, 397, 399, 424, 449, 474, 500, 526, 
+	552, 579, 606, 633, 660, 698, 746, 784, 
+	794, 796, 798, 836, 874, 877, 879, 917, 
+	955, 982, 1008, 1033, 1057, 1080, 1083, 1085, 
+	1110, 1135, 1160, 1186, 1212, 1238, 1265, 1292, 
+	1319, 1346, 1384, 1432, 1448, 1450, 1460, 1462, 
+	1496, 1544, 1582, 1585, 1587, 1610
 };
 
 static const char _use_syllable_machine_indicies[] = {
-	1, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
+	1, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
 	1, 0, 3, 2, 2, 2, 2, 2, 
 	2, 2, 2, 2, 2, 2, 2, 2, 
-	4, 2, 3, 2, 6, 5, 5, 5,
-	5, 5, 5, 5, 5, 5, 5, 5,
-	5, 5, 5, 5, 5, 5, 5, 5,
-	5, 5, 5, 5, 5, 5, 5, 5,
-	5, 5, 5, 5, 6, 5, 7, 8,
-	9, 7, 10, 8, 9, 9, 11, 9, 
-	9, 3, 12, 9, 9, 13, 7, 7, 
-	14, 15, 9, 9, 16, 17, 18, 19, 
-	20, 21, 22, 16, 23, 24, 25, 26, 
-	27, 28, 9, 29, 30, 31, 9, 9, 
-	9, 32, 33, 9, 35, 34, 37, 36,
-	36, 38, 1, 36, 36, 39, 36, 36,
-	36, 36, 36, 40, 41, 42, 43, 44,
-	45, 46, 47, 41, 48, 40, 49, 50,
-	51, 52, 36, 53, 54, 55, 36, 36,
-	36, 36, 56, 36, 37, 36, 36, 38,
-	1, 36, 36, 39, 36, 36, 36, 36,
-	36, 57, 41, 42, 43, 44, 45, 46,
-	47, 41, 48, 49, 49, 50, 51, 52,
-	36, 53, 54, 55, 36, 36, 36, 36,
-	56, 36, 38, 58, 58, 58, 58, 58,
-	58, 58, 58, 58, 58, 58, 58, 58,
-	59, 58, 38, 58, 37, 36, 36, 38,
-	1, 36, 36, 39, 36, 36, 36, 36,
-	36, 36, 41, 42, 43, 44, 45, 46,
-	47, 41, 48, 49, 49, 50, 51, 52,
-	36, 53, 54, 55, 36, 36, 36, 36,
-	56, 36, 37, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	41, 42, 43, 44, 45, 36, 36, 36,
-	36, 36, 36, 50, 51, 52, 36, 53,
-	54, 55, 36, 36, 36, 36, 42, 36,
-	37, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 42,
-	43, 44, 45, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 53, 54, 55,
-	36, 37, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 43, 44, 45, 36, 37, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 44, 45,
-	36, 37, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 45, 36, 37, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 43, 44, 45,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 53, 54, 55, 36, 37, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 43, 44,
-	45, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 54, 55, 36, 37,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 43,
-	44, 45, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 55, 36,
-	37, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 42,
-	43, 44, 45, 36, 36, 36, 36, 36,
-	36, 50, 51, 52, 36, 53, 54, 55,
-	36, 36, 36, 36, 42, 36, 37, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 42, 43, 44,
-	45, 36, 36, 36, 36, 36, 36, 36,
-	51, 52, 36, 53, 54, 55, 36, 36,
-	36, 36, 42, 36, 37, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 42, 43, 44, 45, 36,
-	36, 36, 36, 36, 36, 36, 36, 52,
-	36, 53, 54, 55, 36, 36, 36, 36,
-	42, 36, 37, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	41, 42, 43, 44, 45, 36, 47, 41,
-	36, 36, 36, 50, 51, 52, 36, 53,
-	54, 55, 36, 36, 36, 36, 42, 36,
-	37, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 41, 42,
-	43, 44, 45, 36, 60, 41, 36, 36,
-	36, 50, 51, 52, 36, 53, 54, 55,
-	36, 36, 36, 36, 42, 36, 37, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 36, 36, 41, 42, 43, 44,
-	45, 36, 36, 41, 36, 36, 36, 50,
-	51, 52, 36, 53, 54, 55, 36, 36,
-	36, 36, 42, 36, 37, 36, 36, 36,
-	36, 36, 36, 36, 36, 36, 36, 36,
-	36, 36, 41, 42, 43, 44, 45, 46,
-	47, 41, 36, 36, 36, 50, 51, 52,
-	36, 53, 54, 55, 36, 36, 36, 36,
-	42, 36, 37, 36, 36, 38, 1, 36,
-	36, 39, 36, 36, 36, 36, 36, 36,
-	41, 42, 43, 44, 45, 46, 47, 41,
-	48, 36, 49, 50, 51, 52, 36, 53,
-	54, 55, 36, 36, 36, 36, 56, 36,
-	38, 58, 58, 58, 58, 58, 58, 37,
-	58, 58, 58, 58, 58, 58, 59, 58,
-	58, 58, 58, 58, 58, 58, 42, 43,
-	44, 45, 58, 58, 58, 58, 58, 58,
-	58, 58, 58, 58, 53, 54, 55, 58,
-	37, 36, 36, 38, 1, 36, 36, 39,
-	36, 36, 36, 36, 36, 36, 41, 42,
-	43, 44, 45, 46, 47, 41, 48, 40,
-	49, 50, 51, 52, 36, 53, 54, 55,
-	36, 36, 36, 36, 56, 36, 62, 61,
-	61, 61, 61, 61, 61, 61, 63, 61,
-	10, 64, 62, 61, 11, 65, 65, 3,
-	6, 65, 65, 66, 65, 65, 65, 65,
-	65, 67, 16, 17, 18, 19, 20, 21,
-	22, 16, 23, 25, 25, 26, 27, 28,
-	65, 29, 30, 31, 65, 65, 65, 65,
-	33, 65, 11, 65, 65, 3, 6, 65,
-	65, 66, 65, 65, 65, 65, 65, 65,
-	16, 17, 18, 19, 20, 21, 22, 16, 
-	23, 25, 25, 26, 27, 28, 65, 29,
-	30, 31, 65, 65, 65, 65, 33, 65,
-	11, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 16, 17,
-	18, 19, 20, 65, 65, 65, 65, 65,
-	65, 26, 27, 28, 65, 29, 30, 31,
-	65, 65, 65, 65, 17, 65, 11, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 17, 18, 19,
-	20, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 29, 30, 31, 65, 11,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 18,
-	19, 20, 65, 11, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 19, 20, 65, 11,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 20, 65, 11, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 18, 19, 20, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	29, 30, 31, 65, 11, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 18, 19, 20, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 30, 31, 65, 11, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 18, 19, 20,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 31, 65, 11, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 17, 18, 19,
-	20, 65, 65, 65, 65, 65, 65, 26,
-	27, 28, 65, 29, 30, 31, 65, 65,
-	65, 65, 17, 65, 11, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 17, 18, 19, 20, 65,
-	65, 65, 65, 65, 65, 65, 27, 28,
-	65, 29, 30, 31, 65, 65, 65, 65,
-	17, 65, 11, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 17, 18, 19, 20, 65, 65, 65,
-	65, 65, 65, 65, 65, 28, 65, 29,
-	30, 31, 65, 65, 65, 65, 17, 65,
-	11, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 16, 17,
-	18, 19, 20, 65, 22, 16, 65, 65,
-	65, 26, 27, 28, 65, 29, 30, 31,
-	65, 65, 65, 65, 17, 65, 11, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 16, 17, 18, 19,
-	20, 65, 68, 16, 65, 65, 65, 26,
-	27, 28, 65, 29, 30, 31, 65, 65,
-	65, 65, 17, 65, 11, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 16, 17, 18, 19, 20, 65,
-	65, 16, 65, 65, 65, 26, 27, 28,
-	65, 29, 30, 31, 65, 65, 65, 65,
-	17, 65, 11, 65, 65, 65, 65, 65,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	16, 17, 18, 19, 20, 21, 22, 16,
-	65, 65, 65, 26, 27, 28, 65, 29,
-	30, 31, 65, 65, 65, 65, 17, 65,
-	11, 65, 65, 3, 6, 65, 65, 66,
-	65, 65, 65, 65, 65, 65, 16, 17,
-	18, 19, 20, 21, 22, 16, 23, 65,
-	25, 26, 27, 28, 65, 29, 30, 31,
-	65, 65, 65, 65, 33, 65, 3, 65,
-	65, 65, 65, 65, 65, 11, 65, 65,
-	65, 65, 65, 65, 4, 65, 65, 65,
-	65, 65, 65, 65, 17, 18, 19, 20,
-	65, 65, 65, 65, 65, 65, 65, 65,
-	65, 65, 29, 30, 31, 65, 3, 69,
-	69, 69, 69, 69, 69, 69, 69, 69,
-	69, 69, 69, 69, 4, 69, 6, 69,
-	69, 69, 69, 69, 69, 69, 69, 69,
-	69, 69, 69, 69, 69, 69, 69, 69,
-	69, 69, 69, 69, 69, 69, 69, 69,
-	69, 69, 69, 69, 69, 69, 6, 69,
-	8, 65, 65, 65, 8, 65, 65, 11,
-	65, 65, 3, 6, 65, 65, 66, 65,
-	65, 65, 65, 65, 65, 16, 17, 18,
-	19, 20, 21, 22, 16, 23, 24, 25, 
-	26, 27, 28, 65, 29, 30, 31, 65,
-	65, 65, 65, 33, 65, 11, 65, 65,
-	3, 6, 65, 65, 66, 65, 65, 65,
-	65, 65, 65, 16, 17, 18, 19, 20,
-	21, 22, 16, 23, 24, 25, 26, 27,
-	28, 65, 29, 30, 31, 65, 65, 65,
-	65, 33, 65, 71, 70, 70, 70, 70,
-	70, 70, 70, 70, 70, 70, 70, 70,
-	70, 70, 70, 70, 70, 70, 70, 71,
-	72, 70, 71, 72, 70, 72, 70, 8,
-	69, 69, 69, 8, 69, 0
+	4, 2, 3, 2, 6, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 5, 5, 5, 6, 5, 7, 8, 
+	9, 7, 10, 11, 9, 9, 9, 9, 
+	9, 3, 12, 13, 9, 14, 7, 7, 
+	15, 16, 9, 9, 17, 18, 19, 20, 
+	21, 22, 23, 17, 24, 25, 26, 27, 
+	28, 29, 9, 30, 31, 32, 9, 33, 
+	34, 35, 36, 37, 38, 39, 9, 41, 
+	40, 43, 1, 42, 42, 44, 42, 42, 
+	42, 42, 42, 45, 46, 47, 48, 49, 
+	50, 51, 52, 46, 53, 45, 54, 55, 
+	56, 57, 42, 58, 59, 60, 42, 42, 
+	42, 42, 61, 62, 63, 64, 42, 43, 
+	1, 42, 42, 44, 42, 42, 42, 42, 
+	42, 65, 46, 47, 48, 49, 50, 51, 
+	52, 46, 53, 54, 54, 55, 56, 57, 
+	42, 58, 59, 60, 42, 42, 42, 42, 
+	61, 62, 63, 64, 42, 43, 66, 66, 
+	66, 66, 66, 66, 66, 66, 66, 66, 
+	66, 66, 66, 67, 66, 43, 66, 43, 
+	1, 42, 42, 44, 42, 42, 42, 42, 
+	42, 42, 46, 47, 48, 49, 50, 51, 
+	52, 46, 53, 54, 54, 55, 56, 57, 
+	42, 58, 59, 60, 42, 42, 42, 42, 
+	61, 62, 63, 64, 42, 46, 47, 48, 
+	49, 50, 42, 42, 42, 42, 42, 42, 
+	55, 56, 57, 42, 58, 59, 60, 42, 
+	42, 42, 42, 47, 62, 63, 64, 42, 
+	47, 48, 49, 50, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 58, 59, 
+	60, 42, 42, 42, 42, 42, 62, 63, 
+	64, 42, 48, 49, 50, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 62, 
+	63, 64, 42, 49, 50, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 62, 
+	63, 64, 42, 50, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 62, 63, 
+	64, 42, 62, 63, 42, 63, 42, 48, 
+	49, 50, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 58, 59, 60, 42, 
+	42, 42, 42, 42, 62, 63, 64, 42, 
+	48, 49, 50, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 59, 60, 
+	42, 42, 42, 42, 42, 62, 63, 64, 
+	42, 48, 49, 50, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	60, 42, 42, 42, 42, 42, 62, 63, 
+	64, 42, 47, 48, 49, 50, 42, 42, 
+	42, 42, 42, 42, 55, 56, 57, 42, 
+	58, 59, 60, 42, 42, 42, 42, 47, 
+	62, 63, 64, 42, 47, 48, 49, 50, 
+	42, 42, 42, 42, 42, 42, 42, 56, 
+	57, 42, 58, 59, 60, 42, 42, 42, 
+	42, 47, 62, 63, 64, 42, 47, 48, 
+	49, 50, 42, 42, 42, 42, 42, 42, 
+	42, 42, 57, 42, 58, 59, 60, 42, 
+	42, 42, 42, 47, 62, 63, 64, 42, 
+	46, 47, 48, 49, 50, 42, 52, 46, 
+	42, 42, 42, 55, 56, 57, 42, 58, 
+	59, 60, 42, 42, 42, 42, 47, 62, 
+	63, 64, 42, 46, 47, 48, 49, 50, 
+	42, 68, 46, 42, 42, 42, 55, 56, 
+	57, 42, 58, 59, 60, 42, 42, 42, 
+	42, 47, 62, 63, 64, 42, 46, 47, 
+	48, 49, 50, 42, 42, 46, 42, 42, 
+	42, 55, 56, 57, 42, 58, 59, 60, 
+	42, 42, 42, 42, 47, 62, 63, 64, 
+	42, 46, 47, 48, 49, 50, 51, 52, 
+	46, 42, 42, 42, 55, 56, 57, 42, 
+	58, 59, 60, 42, 42, 42, 42, 47, 
+	62, 63, 64, 42, 43, 1, 42, 42, 
+	44, 42, 42, 42, 42, 42, 42, 46, 
+	47, 48, 49, 50, 51, 52, 46, 53, 
+	42, 54, 55, 56, 57, 42, 58, 59, 
+	60, 42, 42, 42, 42, 61, 62, 63, 
+	64, 42, 43, 66, 66, 66, 66, 66, 
+	66, 66, 66, 66, 66, 66, 66, 66, 
+	67, 66, 66, 66, 66, 66, 66, 66, 
+	47, 48, 49, 50, 66, 66, 66, 66, 
+	66, 66, 66, 66, 66, 66, 58, 59, 
+	60, 66, 66, 66, 66, 66, 62, 63, 
+	64, 66, 43, 1, 42, 42, 44, 42, 
+	42, 42, 42, 42, 42, 46, 47, 48, 
+	49, 50, 51, 52, 46, 53, 45, 54, 
+	55, 56, 57, 42, 58, 59, 60, 42, 
+	42, 42, 42, 61, 62, 63, 64, 42, 
+	70, 69, 69, 69, 69, 69, 69, 69, 
+	71, 69, 10, 72, 70, 69, 43, 1, 
+	42, 42, 44, 42, 42, 42, 42, 42, 
+	73, 46, 47, 48, 49, 50, 51, 52, 
+	46, 53, 45, 54, 55, 56, 57, 42, 
+	58, 59, 60, 42, 74, 75, 42, 61, 
+	62, 63, 64, 42, 43, 1, 42, 42, 
+	44, 42, 42, 42, 42, 42, 42, 46, 
+	47, 48, 49, 50, 51, 52, 46, 53, 
+	45, 54, 55, 56, 57, 42, 58, 59, 
+	60, 42, 74, 75, 42, 61, 62, 63, 
+	64, 42, 74, 75, 76, 75, 76, 3, 
+	6, 77, 77, 78, 77, 77, 77, 77, 
+	77, 79, 17, 18, 19, 20, 21, 22, 
+	23, 17, 24, 26, 26, 27, 28, 29, 
+	77, 30, 31, 32, 77, 77, 77, 77, 
+	36, 37, 38, 39, 77, 3, 6, 77, 
+	77, 78, 77, 77, 77, 77, 77, 77, 
+	17, 18, 19, 20, 21, 22, 23, 17, 
+	24, 26, 26, 27, 28, 29, 77, 30, 
+	31, 32, 77, 77, 77, 77, 36, 37, 
+	38, 39, 77, 17, 18, 19, 20, 21, 
+	77, 77, 77, 77, 77, 77, 27, 28, 
+	29, 77, 30, 31, 32, 77, 77, 77, 
+	77, 18, 37, 38, 39, 77, 18, 19, 
+	20, 21, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 30, 31, 32, 77, 
+	77, 77, 77, 77, 37, 38, 39, 77, 
+	19, 20, 21, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 77, 37, 38, 39, 
+	77, 20, 21, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 77, 37, 38, 39, 
+	77, 21, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 37, 38, 39, 77, 
+	37, 38, 77, 38, 77, 19, 20, 21, 
+	77, 77, 77, 77, 77, 77, 77, 77, 
+	77, 77, 30, 31, 32, 77, 77, 77, 
+	77, 77, 37, 38, 39, 77, 19, 20, 
+	21, 77, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 31, 32, 77, 77, 
+	77, 77, 77, 37, 38, 39, 77, 19, 
+	20, 21, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 77, 77, 32, 77, 
+	77, 77, 77, 77, 37, 38, 39, 77, 
+	18, 19, 20, 21, 77, 77, 77, 77, 
+	77, 77, 27, 28, 29, 77, 30, 31, 
+	32, 77, 77, 77, 77, 18, 37, 38, 
+	39, 77, 18, 19, 20, 21, 77, 77, 
+	77, 77, 77, 77, 77, 28, 29, 77, 
+	30, 31, 32, 77, 77, 77, 77, 18, 
+	37, 38, 39, 77, 18, 19, 20, 21, 
+	77, 77, 77, 77, 77, 77, 77, 77, 
+	29, 77, 30, 31, 32, 77, 77, 77, 
+	77, 18, 37, 38, 39, 77, 17, 18, 
+	19, 20, 21, 77, 23, 17, 77, 77, 
+	77, 27, 28, 29, 77, 30, 31, 32, 
+	77, 77, 77, 77, 18, 37, 38, 39, 
+	77, 17, 18, 19, 20, 21, 77, 80, 
+	17, 77, 77, 77, 27, 28, 29, 77, 
+	30, 31, 32, 77, 77, 77, 77, 18, 
+	37, 38, 39, 77, 17, 18, 19, 20, 
+	21, 77, 77, 17, 77, 77, 77, 27, 
+	28, 29, 77, 30, 31, 32, 77, 77, 
+	77, 77, 18, 37, 38, 39, 77, 17, 
+	18, 19, 20, 21, 22, 23, 17, 77, 
+	77, 77, 27, 28, 29, 77, 30, 31, 
+	32, 77, 77, 77, 77, 18, 37, 38, 
+	39, 77, 3, 6, 77, 77, 78, 77, 
+	77, 77, 77, 77, 77, 17, 18, 19, 
+	20, 21, 22, 23, 17, 24, 77, 26, 
+	27, 28, 29, 77, 30, 31, 32, 77, 
+	77, 77, 77, 36, 37, 38, 39, 77, 
+	3, 77, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 77, 77, 4, 77, 
+	77, 77, 77, 77, 77, 77, 18, 19, 
+	20, 21, 77, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 30, 31, 32, 77, 
+	77, 77, 77, 77, 37, 38, 39, 77, 
+	3, 81, 81, 81, 81, 81, 81, 81, 
+	81, 81, 81, 81, 81, 81, 4, 81, 
+	82, 77, 13, 77, 77, 77, 77, 77, 
+	77, 77, 83, 77, 13, 77, 6, 81, 
+	81, 81, 81, 81, 81, 81, 81, 81, 
+	81, 81, 81, 81, 81, 81, 81, 81, 
+	81, 81, 81, 81, 81, 81, 81, 81, 
+	81, 81, 81, 81, 81, 81, 6, 81, 
+	8, 77, 77, 77, 8, 77, 77, 77, 
+	77, 77, 3, 6, 13, 77, 78, 77, 
+	77, 77, 77, 77, 77, 17, 18, 19, 
+	20, 21, 22, 23, 17, 24, 25, 26, 
+	27, 28, 29, 77, 30, 31, 32, 77, 
+	33, 34, 77, 36, 37, 38, 39, 77, 
+	3, 6, 77, 77, 78, 77, 77, 77, 
+	77, 77, 77, 17, 18, 19, 20, 21, 
+	22, 23, 17, 24, 25, 26, 27, 28, 
+	29, 77, 30, 31, 32, 77, 77, 77, 
+	77, 36, 37, 38, 39, 77, 33, 34, 
+	77, 34, 77, 74, 76, 76, 76, 76, 
+	76, 76, 76, 76, 76, 76, 76, 76, 
+	76, 76, 76, 76, 76, 76, 76, 74, 
+	75, 76, 8, 81, 81, 81, 8, 81, 
+	0
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
-	4, 8, 4, 32, 2, 4, 1, 5,
-	6, 4, 29, 4, 51, 52, 53, 55,
-	34, 35, 36, 37, 38, 45, 46, 48,
-	54, 49, 42, 43, 44, 39, 40, 41,
-	58, 50, 4, 4, 4, 4, 7, 0,
-	28, 11, 12, 13, 14, 15, 22, 23,
-	25, 26, 19, 20, 21, 16, 17, 18,
-	27, 10, 4, 9, 24, 4, 30, 31,
-	4, 4, 3, 33, 47, 4, 4, 56,
-	57
+	4, 8, 4, 38, 2, 4, 1, 5, 
+	6, 4, 31, 34, 59, 60, 63, 64, 
+	68, 40, 41, 42, 43, 44, 53, 54, 
+	56, 65, 57, 50, 51, 52, 47, 48, 
+	49, 66, 67, 69, 58, 45, 46, 4, 
+	4, 4, 4, 7, 0, 30, 11, 12, 
+	13, 14, 15, 24, 25, 27, 28, 21, 
+	22, 23, 18, 19, 20, 29, 16, 17, 
+	4, 10, 4, 9, 26, 4, 32, 33, 
+	4, 35, 36, 37, 4, 4, 3, 39, 
+	55, 4, 61, 62
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
 	1, 0, 2, 3, 0, 4, 0, 0, 
-	7, 8, 0, 9, 10, 10, 3, 0, 
+	7, 8, 0, 7, 9, 0, 9, 3, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	3, 3, 0, 0, 0, 0, 0, 0, 
-	0, 3, 11, 12, 13, 14, 7, 0,
-	7, 0, 0, 0, 0, 0, 0, 0,
-	0, 7, 0, 0, 0, 0, 0, 0,
-	0, 7, 15, 0, 0, 16, 0, 0,
-	17, 18, 0, 3, 0, 19, 20, 0,
-	0
+	0, 3, 3, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 3, 0, 0, 10, 
+	11, 12, 13, 7, 0, 7, 0, 0, 
+	0, 0, 0, 0, 0, 0, 7, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	14, 7, 15, 0, 0, 16, 0, 0, 
+	17, 7, 0, 0, 18, 19, 0, 3, 
+	0, 20, 0, 0
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
@@ -319,7 +313,8 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0
 };
 
 static const char _use_syllable_machine_from_state_actions[] = {
@@ -330,18 +325,20 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0
 };
 
 static const short _use_syllable_machine_eof_trans[] = {
-	1, 3, 3, 6, 0, 35, 37, 37,
-	59, 59, 37, 37, 37, 37, 37, 37,
-	37, 37, 37, 37, 37, 37, 37, 37,
-	37, 37, 37, 59, 37, 62, 65, 62,
-	66, 66, 66, 66, 66, 66, 66, 66,
-	66, 66, 66, 66, 66, 66, 66, 66,
-	66, 66, 66, 70, 70, 66, 66, 71,
-	71, 71, 70
+	1, 3, 3, 6, 0, 41, 43, 43, 
+	67, 67, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 43, 67, 43, 70, 
+	73, 70, 43, 43, 77, 77, 78, 78, 
+	78, 78, 78, 78, 78, 78, 78, 78, 
+	78, 78, 78, 78, 78, 78, 78, 78, 
+	78, 78, 78, 82, 78, 78, 78, 82, 
+	78, 78, 78, 78, 77, 82
 };
 
 static const int use_syllable_machine_start = 4;
@@ -355,7 +352,7 @@
 
 
 
-#line 143 "hb-ot-shape-complex-use-machine.rl"
+#line 150 "hb-ot-shape-complex-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
@@ -374,7 +371,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 378 "hb-ot-shape-complex-use-machine.hh"
+#line 375 "hb-ot-shape-complex-use-machine.hh"
 	{
 	cs = use_syllable_machine_start;
 	ts = 0;
@@ -382,7 +379,7 @@
 	act = 0;
 	}
 
-#line 163 "hb-ot-shape-complex-use-machine.rl"
+#line 170 "hb-ot-shape-complex-use-machine.rl"
 
 
   p = 0;
@@ -390,7 +387,7 @@
 
   unsigned int syllable_serial = 1;
   
-#line 394 "hb-ot-shape-complex-use-machine.hh"
+#line 391 "hb-ot-shape-complex-use-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -404,7 +401,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 408 "hb-ot-shape-complex-use-machine.hh"
+#line 405 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -427,59 +424,59 @@
 	{te = p+1;}
 	break;
 	case 12:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 139 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (independent_cluster); }}
 	break;
 	case 14:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 141 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (standard_cluster); }}
 	break;
-	case 9:
-#line 138 "hb-ot-shape-complex-use-machine.rl"
+	case 10:
+#line 145 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (broken_cluster); }}
 	break;
 	case 8:
-#line 139 "hb-ot-shape-complex-use-machine.rl"
+#line 146 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (non_cluster); }}
 	break;
 	case 11:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 139 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (independent_cluster); }}
 	break;
 	case 15:
-#line 133 "hb-ot-shape-complex-use-machine.rl"
+#line 140 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (virama_terminated_cluster); }}
 	break;
 	case 13:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 141 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (standard_cluster); }}
 	break;
 	case 17:
-#line 135 "hb-ot-shape-complex-use-machine.rl"
+#line 142 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
 	break;
 	case 16:
-#line 136 "hb-ot-shape-complex-use-machine.rl"
+#line 143 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (numeral_cluster); }}
 	break;
-	case 20:
-#line 137 "hb-ot-shape-complex-use-machine.rl"
+	case 18:
+#line 144 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (symbol_cluster); }}
 	break;
-	case 18:
-#line 138 "hb-ot-shape-complex-use-machine.rl"
+	case 19:
+#line 145 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
-	case 19:
-#line 139 "hb-ot-shape-complex-use-machine.rl"
+	case 20:
+#line 146 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (non_cluster); }}
 	break;
 	case 1:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 141 "hb-ot-shape-complex-use-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (standard_cluster); }}
 	break;
 	case 4:
-#line 138 "hb-ot-shape-complex-use-machine.rl"
+#line 145 "hb-ot-shape-complex-use-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
 	break;
 	case 2:
@@ -497,16 +494,16 @@
 	case 3:
 #line 1 "NONE"
 	{te = p+1;}
-#line 138 "hb-ot-shape-complex-use-machine.rl"
+#line 145 "hb-ot-shape-complex-use-machine.rl"
 	{act = 7;}
 	break;
-	case 10:
+	case 9:
 #line 1 "NONE"
 	{te = p+1;}
-#line 139 "hb-ot-shape-complex-use-machine.rl"
+#line 146 "hb-ot-shape-complex-use-machine.rl"
 	{act = 8;}
 	break;
-#line 510 "hb-ot-shape-complex-use-machine.hh"
+#line 507 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 _again:
@@ -515,7 +512,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 519 "hb-ot-shape-complex-use-machine.hh"
+#line 516 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -531,7 +528,7 @@
 
 	}
 
-#line 171 "hb-ot-shape-complex-use-machine.rl"
+#line 178 "hb-ot-shape-complex-use-machine.rl"
 
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl	2019-05-24 23:03:55 UTC (rev 51218)
@@ -49,7 +49,7 @@
 GB	= 5; # BASE_OTHER
 CGJ	= 6; # CGJ
 #F	= 7; # CONS_FINAL
-FM	= 8; # CONS_FINAL_MOD
+#FM	= 8; # CONS_FINAL_MOD
 #M	= 9; # CONS_MED
 #CM	= 10; # CONS_MOD
 SUB	= 11; # CONS_SUB
@@ -66,6 +66,8 @@
 VS	= 21; # VARIATION_SELECTOR
 #V	= 36; # VOWEL
 #VM	= 40; # VOWEL_MOD
+CS	= 43; # CONS_WITH_STACKER
+HVM	= 44; # HALANT_OR_VOWEL_MODIFIER
 
 FAbv	= 24; # CONS_FINAL_ABOVE
 FBlw	= 25; # CONS_FINAL_BELOW
@@ -86,10 +88,10 @@
 VMPre	= 23; # VOWEL_MOD_PRE
 SMAbv	= 41; # SYM_MOD_ABOVE
 SMBlw	= 42; # SYM_MOD_BELOW
-CS	= 43; # CONS_WITH_STACKER
+FMAbv	= 45; # CONS_FINAL_MOD	UIPC = Top
+FMBlw	= 46; # CONS_FINAL_MOD	UIPC = Bottom
+FMPst	= 47; # CONS_FINAL_MOD	UIPC = Not_Applicable
 
-HVM	= 44; # HALANT_OR_VOWEL_MODIFIER
-
 h = H | HVM; # https://github.com/harfbuzz/harfbuzz/issues/1102
 
 # Override: Adhoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729
@@ -98,7 +100,8 @@
 medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?;
 dependent_vowels = VPre* VAbv* VBlw* VPst*;
 vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*;
-final_consonants = FAbv* FBlw* FPst* FM?;
+final_consonants = FAbv* FBlw* FPst*;
+final_modifiers = FMAbv* FMBlw* | FMPst?;
 
 complex_syllable_tail =
 	consonant_modifiers
@@ -106,7 +109,11 @@
 	dependent_vowels
 	vowel_modifiers
 	final_consonants
+	final_modifiers
 ;
+number_joiner_terminated_cluster_tail = (HN N VS?)* HN;
+numeral_cluster_tail = (HN N VS?)+;
+symbol_cluster_tail = SMAbv+ SMBlw* | SMBlw+;
 
 virama_terminated_cluster =
 	(R|CS)? (B | GB) VS?
@@ -119,12 +126,12 @@
 ;
 broken_cluster =
 	R?
-	complex_syllable_tail
+	(complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail)
 ;
 
-number_joiner_terminated_cluster = N VS? (HN N VS?)* HN;
-numeral_cluster = N VS? (HN N VS?)*;
-symbol_cluster = S VS? SMAbv* SMBlw*;
+number_joiner_terminated_cluster = N VS? number_joiner_terminated_cluster_tail;
+numeral_cluster = N VS? numeral_cluster_tail?;
+symbol_cluster = (S | GB) VS? symbol_cluster_tail?;
 independent_cluster = (IND | O | Rsv | WJ) VS?;
 other = any;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -22,7 +22,6 @@
 #define B	USE_B	/* BASE */
 #define CGJ	USE_CGJ	/* CGJ */
 #define CS	USE_CS	/* CONS_WITH_STACKER */
-#define FM	USE_FM	/* CONS_FINAL_MOD */
 #define GB	USE_GB	/* BASE_OTHER */
 #define H	USE_H	/* HALANT */
 #define HN	USE_HN	/* HALANT_NUM */
@@ -43,6 +42,9 @@
 #define FBlw	USE_FBlw
 #define FPst	USE_FPst
 #define FAbv	USE_FAbv
+#define FMBlw	USE_FMBlw
+#define FMPst	USE_FMPst
+#define FMAbv	USE_FMAbv
 #define MPre	USE_MPre
 #define MBlw	USE_MBlw
 #define MPst	USE_MPst
@@ -75,7 +77,7 @@
   /* Latin-1 Supplement */
 
   /* 00A0 */    GB,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 00B0 */     O,     O,    FM,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 00B0 */     O,     O, FMPst, FMPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 00C0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 00D0 */     O,     O,     O,     O,     O,     O,     O,    GB,
 
@@ -108,7 +110,7 @@
   /* 09C0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPst,  VPst,     H,   IND,     O,
   /* 09D0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     B,     B,     O,     B,
   /* 09E0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O,    FM,     O,
+  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O, FMAbv,     O,
 
   /* Gurmukhi */
 
@@ -204,7 +206,7 @@
   /* Tibetan */
                                                                       VBlw,  VBlw,     O,     O,     O,     O,     O,     O,
   /* 0F20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0F30 */     B,     B,     B,     B,     O,    FM,     O,    FM,     O, CMAbv,     O,     O,     O,     O,  VPst,  VPre,
+  /* 0F30 */     B,     B,     B,     B,     O, FMBlw,     O, FMBlw,     O, CMAbv,     O,     O,     O,     O,  VPst,  VPre,
   /* 0F40 */     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,
   /* 0F50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0F60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,
@@ -213,7 +215,7 @@
   /* 0F90 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 0FA0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 0FB0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,     O,     O,
-  /* 0FC0 */     O,     O,     O,     O,     O,     O,    FM,     O,
+  /* 0FC0 */     O,     O,     O,     O,     O,     O, FMBlw,     O,
 
 #define use_offset_0x1000u 1536
 
@@ -260,8 +262,8 @@
   /* 1790 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 17A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 17B0 */     B,     B,     B,     B,     O,     O,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VPst,  VPst,
-  /* 17C0 */  VPst,  VPre,  VPre,  VPre,  VPst,  VPst, VMAbv, VMPst,  VPst, VMAbv, VMAbv,    FM,  FAbv, CMAbv,    FM,    FM,
-  /* 17D0 */    FM,  VAbv,     H,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     B,    FM,     O,     O,
+  /* 17C0 */  VPst,  VPre,  VPre,  VPre,  VPst,  VPst, VMAbv, VMPst,  VPst, VMAbv, VMAbv, FMAbv,  FAbv, CMAbv, FMAbv, FMAbv,
+  /* 17D0 */ FMAbv,  VAbv,     H, FMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     B, FMAbv,     O,     O,
   /* 17E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
 #define use_offset_0x1900u 1936
@@ -272,7 +274,7 @@
   /* 1900 */    GB,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1910 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,
   /* 1920 */  VAbv,  VAbv,  VBlw,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,   SUB,   SUB,   SUB,     O,     O,     O,     O,
-  /* 1930 */  FPst,  FPst, VMBlw,  FPst,  FPst,  FPst,  FPst,  FPst,  FPst,  FBlw,  VAbv,    FM,     O,     O,     O,     O,
+  /* 1930 */  FPst,  FPst, VMBlw,  FPst,  FPst,  FPst,  FPst,  FPst,  FPst,  FBlw,  VAbv, FMBlw,     O,     O,     O,     O,
   /* 1940 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
 
   /* Tai Le */
@@ -302,9 +304,9 @@
   /* 1A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1A50 */     B,     B,     B,     B,     B,  MPre,  MBlw,   SUB,  FAbv,  FAbv,  FAbv,   SUB,   SUB,   SUB,   SUB,     O,
+  /* 1A50 */     B,     B,     B,     B,     B,  MPre,  MBlw,   SUB,  FAbv,  FAbv,  MAbv,   SUB,   SUB,   SUB,   SUB,     O,
   /* 1A60 */     H,  VPst,  VAbv,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VAbv,  VBlw,  VPst,  VPre,  VPre,
-  /* 1A70 */  VPre,  VPre,  VPre,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,  VAbv,    FM,    FM,     O,     O,  FBlw,
+  /* 1A70 */  VPre,  VPre,  VPre,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,  VAbv, FMAbv, FMAbv,     O,     O, FMBlw,
   /* 1A80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
   /* 1A90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
@@ -318,8 +320,8 @@
   /* 1B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1B30 */     B,     B,     B,     B, CMAbv,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPre,  VPre,
   /* 1B40 */  VPst,  VPst,  VAbv,  VAbv,     H,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
-  /* 1B50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
-  /* 1B60 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
+  /* 1B50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,    GB,    GB,     O,     O,    GB,
+  /* 1B60 */     O,     S,    GB,     S,     S,     S,     S,     S,    GB,     S,     S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
   /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Sundanese */
@@ -341,7 +343,7 @@
   /* 1C00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1C10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1C20 */     B,     B,     B,     B,   SUB,   SUB,  VPst,  VPre,  VPre,  VPst,  VPst,  VPst,  VBlw,  FAbv,  FAbv,  FAbv,
-  /* 1C30 */  FAbv,  FAbv,  FAbv,  FAbv, VMPre, VMPre,    FM, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 1C30 */  FAbv,  FAbv,  FAbv,  FAbv, VMPre, VMPre, FMAbv, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 1C40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,     B,     B,
 
 #define use_offset_0x1cd0u 2688
@@ -357,7 +359,7 @@
 
 
   /* Combining Diacritical Marks Supplement */
-                                                                         O,     O,     O,    FM,     O,     O,     O,     O,
+                                                                         O,     O,     O, FMAbv,     O,     O,     O,     O,
 
 #define use_offset_0x2008u 2744
 
@@ -372,8 +374,8 @@
 
   /* Superscripts and Subscripts */
 
-  /* 2070 */     O,     O,     O,     O,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 2080 */     O,     O,    FM,    FM,    FM,     O,     O,     O,
+  /* 2070 */     O,     O,     O,     O, FMPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 2080 */     O,     O, FMPst, FMPst, FMPst,     O,     O,     O,
 
 #define use_offset_0x20f0u 2800
 
@@ -547,7 +549,7 @@
   /* 11190 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111B0 */     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,
-  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,    GB,  FBlw, CMBlw,  VAbv,  VBlw,     O,     O,     O,
+  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,    GB, FMBlw, CMBlw,  VAbv,  VBlw,     O,     O,     O,
   /* 111D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
   /* Sinhala Archaic Numbers */
@@ -600,7 +602,7 @@
   /* 11420 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11430 */     B,     B,     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,
   /* 11440 */  VPst,  VPst,     H, VMAbv, VMAbv, VMPst, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 11450 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,    FM,     B,
+  /* 11450 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O, FMAbv,     B,
   /* 11460 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11470 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
@@ -683,7 +685,7 @@
   /* 11A00 */     B,  VAbv,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,     B,     B,     B,     B,     B,
   /* 11A10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11A30 */     B,     B,     B,    FM,  VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst,     R,  MBlw,  MBlw,  MBlw,  MBlw,    GB,
+  /* 11A30 */     B,     B,     B, FMBlw,  VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst,     R,  MBlw,  MBlw,  MBlw,  MBlw,    GB,
   /* 11A40 */     O,     O,     O,     O,     O,    GB,     O,     H,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Soyombo */
@@ -809,7 +811,6 @@
 #undef B
 #undef CGJ
 #undef CS
-#undef FM
 #undef GB
 #undef H
 #undef HN
@@ -830,6 +831,9 @@
 #undef FBlw
 #undef FPst
 #undef FAbv
+#undef FMBlw
+#undef FMPst
+#undef FMAbv
 #undef MPre
 #undef MBlw
 #undef MPst

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -294,7 +294,7 @@
 
   foreach_syllable (buffer, start, end)
   {
-    unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start);
+    unsigned int limit = info[start].use_category() == USE_R ? 1 : hb_min (3u, end - start);
     for (unsigned int i = start; i < start + limit; i++)
       info[i].mask |= mask;
   }
@@ -526,7 +526,8 @@
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return;
 
-  /* Note: This loop is extra overhead, but should not be measurable. */
+  /* Note: This loop is extra overhead, but should not be measurable.
+   * TODO Use a buffer scratch flag to remove the loop. */
   bool has_broken_syllables = false;
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
@@ -560,7 +561,6 @@
       ginfo.cluster = buffer->cur().cluster;
       ginfo.mask = buffer->cur().mask;
       ginfo.syllable() = buffer->cur().syllable();
-      /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
       while (buffer->idx < buffer->len && buffer->successful &&

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -68,7 +68,11 @@
   USE_VS	= 21,	/* VARIATION_SELECTOR */
 //  USE_V	= 36,	/* VOWEL */
 //  USE_VM	= 40,	/* VOWEL_MOD */
+  USE_CS	= 43,	/* CONS_WITH_STACKER */
 
+  /* https://github.com/harfbuzz/harfbuzz/issues/1102 */
+  USE_HVM	= 44,	/* HALANT_OR_VOWEL_MODIFIER */
+
   USE_FAbv	= 24,	/* CONS_FINAL_ABOVE */
   USE_FBlw	= 25,	/* CONS_FINAL_BELOW */
   USE_FPst	= 26,	/* CONS_FINAL_POST */
@@ -88,10 +92,9 @@
   USE_VMPre	= 23,	/* VOWEL_MOD_PRE */
   USE_SMAbv	= 41,	/* SYM_MOD_ABOVE */
   USE_SMBlw	= 42,	/* SYM_MOD_BELOW */
-  USE_CS	= 43,	/* CONS_WITH_STACKER */
-
-  /* https://github.com/harfbuzz/harfbuzz/issues/1102 */
-  USE_HVM	= 44,	/* HALANT_OR_VOWEL_MODIFIER */
+  USE_FMAbv	= 45,	/* CONS_FINAL_MOD	UIPC = Top */
+  USE_FMBlw	= 46,	/* CONS_FINAL_MOD	UIPC = Bottom */
+  USE_FMPst	= 47,	/* CONS_FINAL_MOD	UIPC = Not_Applicable */
 };
 
 HB_INTERNAL USE_TABLE_ELEMENT_TYPE

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -34,6 +34,9 @@
 				       hb_buffer_t              *buffer,
 				       hb_font_t                *font HB_UNUSED)
 {
+#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
+  return;
+#endif
   if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)
     return;
 

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -166,6 +166,10 @@
 						        hb_font_t *font HB_UNUSED,
 						        hb_buffer_t  *buffer)
 {
+#ifdef HB_NO_OT_SHAPE_FALLBACK
+  return;
+#endif
+
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
@@ -434,6 +438,10 @@
 				     hb_buffer_t  *buffer,
 				     bool adjust_offsets_when_zeroing)
 {
+#ifdef HB_NO_OT_SHAPE_FALLBACK
+  return;
+#endif
+
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
   unsigned int start = 0;
@@ -448,6 +456,7 @@
 }
 
 
+#ifndef HB_DISABLE_DEPRECATED
 struct hb_ot_shape_fallback_kern_driver_t
 {
   hb_ot_shape_fallback_kern_driver_t (hb_font_t   *font_,
@@ -466,6 +475,7 @@
   hb_font_t *font;
   hb_direction_t direction;
 };
+#endif
 
 /* Performs font-assisted kerning. */
 void
@@ -473,6 +483,11 @@
 			    hb_font_t *font,
 			    hb_buffer_t *buffer)
 {
+#ifdef HB_NO_OT_SHAPE_FALLBACK
+  return;
+#endif
+
+#ifndef HB_DISABLE_DEPRECATED
   if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
       !font->has_glyph_h_kerning_func () :
       !font->has_glyph_v_kerning_func ())
@@ -489,6 +504,7 @@
 
   if (reverse)
     buffer->reverse ();
+#endif
 }
 
 

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -55,7 +55,8 @@
 			      const hb_feature_t             *user_features,
 			      unsigned int                    num_user_features);
 
-static bool
+#ifndef HB_NO_SHAPE_AAT
+static inline bool
 _hb_apply_morx (hb_face_t *face)
 {
   if (hb_options ().aat &&
@@ -69,6 +70,7 @@
 					       0, nullptr, nullptr)) &&
 	 hb_aat_layout_has_substitution (face);
 }
+#endif
 
 hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t                     *face,
 					      const hb_segment_properties_t *props) :
@@ -75,8 +77,10 @@
 						face (face),
 						props (*props),
 						map (face, props),
-						aat_map (face, props),
-						apply_morx (_hb_apply_morx (face))
+						aat_map (face, props)
+#ifndef HB_NO_SHAPE_AAT
+						, apply_morx (_hb_apply_morx (face))
+#endif
 {
   shaper = hb_ot_shape_complex_categorize (this);
 
@@ -124,24 +128,36 @@
    * Decide who does substitutions. GSUB, morx, or fallback.
    */
 
+#ifndef HB_NO_SHAPE_AAT
   plan.apply_morx = apply_morx;
+#endif
 
   /*
    * Decide who does positioning. GPOS, kerx, kern, or fallback.
    */
 
-  if (hb_options ().aat && hb_aat_layout_has_positioning (face))
+  if (0)
+    ;
+#ifndef HB_NO_SHAPE_AAT
+  else if (hb_options ().aat && hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
+#endif
   else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face))
     plan.apply_gpos = true;
+#ifndef HB_NO_SHAPE_AAT
   else if (hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
+#endif
 
   if (!plan.apply_kerx && !has_gpos_kern)
   {
     /* Apparently Apple applies kerx if GPOS kern was not applied. */
-    if (hb_aat_layout_has_positioning (face))
+    if (0)
+      ;
+#ifndef HB_NO_SHAPE_AAT
+    else if (hb_aat_layout_has_positioning (face))
       plan.apply_kerx = true;
+#endif
     else if (hb_ot_layout_has_kerning (face))
       plan.apply_kern = true;
   }
@@ -158,8 +174,10 @@
   plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing &&
 				   script_fallback_mark_positioning;
 
+#ifndef HB_NO_SHAPE_AAT
   /* Currently we always apply trak. */
   plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
+#endif
 }
 
 bool
@@ -962,12 +980,12 @@
   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 = MAX (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 = MAX (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);
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -80,10 +80,16 @@
   bool adjust_mark_positioning_when_zeroing : 1;
 
   bool apply_gpos : 1;
+  bool apply_kern : 1;
+#ifndef HB_NO_SHAPE_AAT
   bool apply_kerx : 1;
-  bool apply_kern : 1;
   bool apply_morx : 1;
   bool apply_trak : 1;
+#else
+  static constexpr bool apply_kerx = false;
+  static constexpr bool apply_morx = false;
+  static constexpr bool apply_trak = false;
+#endif
 
   void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
   {
@@ -113,7 +119,11 @@
   hb_segment_properties_t props;
   hb_ot_map_builder_t map;
   hb_aat_map_builder_t aat_map;
+#ifndef HB_NO_SHAPE_AAT
   bool apply_morx : 1;
+#else
+  static constexpr bool apply_morx = false;
+#endif
   bool script_zero_marks : 1;
   bool script_fallback_mark_positioning : 1;
   const struct hb_ot_complex_shaper_t *shaper;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -65,6 +65,8 @@
     return_trace (likely (c->check_struct (this)));
   }
 
+  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
+
   protected:
   HBUINT16	format;		/* Format identifier — set to 1. */
   HBUINT16	axisIndex;	/* Zero-base index into the axis record array
@@ -88,6 +90,8 @@
     return_trace (likely (c->check_struct (this)));
   }
 
+  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
+
   protected:
   HBUINT16	format;		/* Format identifier — set to 2. */
   HBUINT16	axisIndex;	/* Zero-base index into the axis record array
@@ -115,6 +119,8 @@
     return_trace (likely (c->check_struct (this)));
   }
 
+  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
+
   protected:
   HBUINT16	format;		/* Format identifier — set to 3. */
   HBUINT16	axisIndex;	/* Zero-base index into the axis record array
@@ -157,6 +163,8 @@
     return_trace (likely (c->check_struct (this)));
   }
 
+  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
+
   protected:
   HBUINT16	format;		/* Format identifier — set to 4. */
   HBUINT16	axisCount;	/* The total number of axes contributing to
@@ -178,7 +186,7 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (c->check_struct (this)))
+    if (unlikely (!c->check_struct (this)))
       return_trace (false);
 
     switch (u.format)
@@ -191,6 +199,18 @@
     }
   }
 
+  hb_ot_name_id_t get_value_name_id () const
+  {
+    switch (u.format)
+    {
+      case 1: return u.format1.get_value_name_id ();
+      case 2: return u.format2.get_value_name_id ();
+      case 3: return u.format3.get_value_name_id ();
+      case 4: return u.format4.get_value_name_id ();
+      default: return HB_OT_NAME_ID_INVALID;
+    }
+  }
+
   protected:
   union
   {
@@ -212,6 +232,8 @@
     return_trace (likely (c->check_struct (this)));
   }
 
+  hb_ot_name_id_t get_name_id () const { return nameID; }
+
   protected:
   Tag		tag;		/* A tag identifying the axis of design variation. */
   NameID	nameID;		/* The name ID for entries in the 'name' table that
@@ -231,17 +253,59 @@
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-			  majorVersion == 1 &&
-			  minorVersion > 0 &&
+			  version.major == 1 &&
+                          version.minor > 0 &&
 			  designAxesOffset.sanitize (c, this, designAxisCount) &&
 			  offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
   }
 
+  bool has_data () const { return version.to_int (); }
+
+  unsigned get_design_axis_count () const { return designAxisCount; }
+
+  hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const
+  {
+    if (unlikely (axis_record_index >= designAxisCount)) return HB_OT_NAME_ID_INVALID;
+    const StatAxisRecord &axis_record = get_design_axes ()[axis_record_index];
+    return axis_record.get_name_id ();
+  }
+
+  unsigned get_axis_value_count () const { return axisValueCount; }
+
+  hb_ot_name_id_t get_axis_value_name_id (unsigned axis_value_index) const
+  {
+    if (unlikely (axis_value_index >= axisValueCount)) return HB_OT_NAME_ID_INVALID;
+    const AxisValue &axis_value = (this + get_axis_value_offsets ()[axis_value_index]);
+    return axis_value.get_value_name_id ();
+  }
+
+  void collect_name_ids (hb_set_t *nameids_to_retain) const
+  {
+    if (!has_data ()) return;
+
+    + get_design_axes ()
+    | hb_map (&StatAxisRecord::get_name_id)
+    | hb_sink (nameids_to_retain)
+    ;
+
+    + get_axis_value_offsets ()
+    | hb_map (hb_add (&(this + offsetToAxisValueOffsets)))
+    | hb_map (&AxisValue::get_value_name_id)
+    | hb_sink (nameids_to_retain)
+    ;
+  }
+
   protected:
-  HBUINT16	majorVersion;	/* Major version number of the style attributes
-				 * table — set to 1. */
-  HBUINT16	minorVersion;	/* Minor version number of the style attributes
-				 * table — set to 2. */
+  hb_array_t<const StatAxisRecord> const get_design_axes () const
+  { return (this+designAxesOffset).as_array (designAxisCount); }
+
+  hb_array_t<const OffsetTo<AxisValue>> const get_axis_value_offsets () const
+  { return (this+offsetToAxisValueOffsets).as_array (axisValueCount); }
+
+
+  protected:
+  FixedVersion<>version;        /* Version of the stat table
+                                 * initially set to 0x00010002u */
   HBUINT16	designAxisSize;	/* The size in bytes of each axis record. */
   HBUINT16	designAxisCount;/* The number of design axis records. In a
 				 * font with an 'fvar' table, this value must be
@@ -249,7 +313,7 @@
 				 * in the 'fvar' table. In all fonts, must
 				 * be greater than zero if axisValueCount
 				 * is greater than zero. */
-  LNNOffsetTo<UnsizedArrayOf<StatAxisRecord> >
+  LNNOffsetTo<UnsizedArrayOf<StatAxisRecord>>
 		designAxesOffset;
 				/* Offset in bytes from the beginning of
 				 * the STAT table to the start of the design
@@ -257,7 +321,7 @@
 				 * set to zero; if designAxisCount is greater
 				 * than zero, must be greater than zero. */
   HBUINT16	axisValueCount;	/* The number of axis value tables. */
-  LNNOffsetTo<UnsizedArrayOf<OffsetTo<AxisValue> > >
+  LNNOffsetTo<UnsizedArrayOf<OffsetTo<AxisValue>>>
 		offsetToAxisValueOffsets;
 				/* Offset in bytes from the beginning of
 				 * the STAT table to the start of the design

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -7,7 +7,7 @@
  * on files with these headers:
  *
  * <meta name="updated_at" content="2018-11-18 05:25 AM" />
- * File-Date: 2019-02-20
+ * File-Date: 2019-04-03
  */
 
 #ifndef HB_OT_TAG_TABLE_HH
@@ -14,1047 +14,1045 @@
 #define HB_OT_TAG_TABLE_HH
 
 static const LangTag ot_languages[] = {
-  {"aa",	{HB_TAG('A','F','R',' ')}},	/* Afar */
-  {"aae",	{HB_TAG('S','Q','I',' ')}},	/* Arbëreshë Albanian -> Albanian */
-  {"aao",	{HB_TAG('A','R','A',' ')}},	/* Algerian Saharan Arabic -> Arabic */
-  {"aat",	{HB_TAG('S','Q','I',' ')}},	/* Arvanitika Albanian -> Albanian */
-  {"ab",	{HB_TAG('A','B','K',' ')}},	/* Abkhazian */
-  {"abh",	{HB_TAG('A','R','A',' ')}},	/* Tajiki Arabic -> Arabic */
-  {"abq",	{HB_TAG('A','B','A',' ')}},	/* Abaza */
-  {"abv",	{HB_TAG('A','R','A',' ')}},	/* Baharna Arabic -> Arabic */
-  {"acf",	{HB_TAG('F','A','N',' ')}},	/* Saint Lucian Creole French -> French Antillean */
-  {"ach",	{HB_TAG('A','C','H',' ')}},	/* Acoli -> Acholi */
-  {"acm",	{HB_TAG('A','R','A',' ')}},	/* Mesopotamian Arabic -> Arabic */
-  {"acq",	{HB_TAG('A','R','A',' ')}},	/* Ta'izzi-Adeni Arabic -> Arabic */
-  {"acr",	{HB_TAG('A','C','R',' ')}},	/* Achi */
-  {"acw",	{HB_TAG('A','R','A',' ')}},	/* Hijazi Arabic -> Arabic */
-  {"acx",	{HB_TAG('A','R','A',' ')}},	/* Omani Arabic -> Arabic */
-  {"acy",	{HB_TAG('A','R','A',' ')}},	/* Cypriot Arabic -> Arabic */
-  {"ada",	{HB_TAG('D','N','G',' ')}},	/* Adangme -> Dangme */
-  {"adf",	{HB_TAG('A','R','A',' ')}},	/* Dhofari Arabic -> Arabic */
-  {"adp",	{HB_TAG('D','Z','N',' ')}},	/* Adap (retired code) -> Dzongkha */
-  {"ady",	{HB_TAG('A','D','Y',' ')}},	/* Adyghe */
-  {"aeb",	{HB_TAG('A','R','A',' ')}},	/* Tunisian Arabic -> Arabic */
-  {"aec",	{HB_TAG('A','R','A',' ')}},	/* Saidi Arabic -> Arabic */
-  {"af",	{HB_TAG('A','F','K',' ')}},	/* Afrikaans */
-  {"afb",	{HB_TAG('A','R','A',' ')}},	/* Gulf Arabic -> Arabic */
-  {"ahg",	{HB_TAG('A','G','W',' ')}},	/* Qimant -> Agaw */
-  {"aht",	{HB_TAG('A','T','H',' ')}},	/* Ahtena -> Athapaskan */
-  {"aii",	{HB_TAG('S','W','A',' '),	/* Assyrian Neo-Aramaic -> Swadaya Aramaic */
-		 HB_TAG('S','Y','R',' ')}},	/* Assyrian Neo-Aramaic -> Syriac */
-  {"aio",	{HB_TAG('A','I','O',' ')}},	/* Aiton */
-  {"aiw",	{HB_TAG('A','R','I',' ')}},	/* Aari */
-  {"ajp",	{HB_TAG('A','R','A',' ')}},	/* South Levantine Arabic -> Arabic */
-  {"ak",	{HB_TAG('A','K','A',' '),	/* Akan [macrolanguage] */
-		 HB_TAG('T','W','I',' ')}},	/* Akan [macrolanguage] -> Twi */
-  {"aln",	{HB_TAG('S','Q','I',' ')}},	/* Gheg Albanian -> Albanian */
-  {"als",	{HB_TAG('S','Q','I',' ')}},	/* Tosk Albanian -> Albanian */
-  {"alt",	{HB_TAG('A','L','T',' ')}},	/* Southern Altai -> Altai */
-  {"am",	{HB_TAG('A','M','H',' ')}},	/* Amharic */
-  {"amf",	{HB_TAG('H','B','N',' ')}},	/* Hamer-Banna -> Hammer-Banna */
-  {"amw",	{HB_TAG('S','Y','R',' ')}},	/* Western Neo-Aramaic -> Syriac */
-  {"an",	{HB_TAG('A','R','G',' ')}},	/* Aragonese */
-  {"ang",	{HB_TAG('A','N','G',' ')}},	/* Old English (ca. 450-1100) -> Anglo-Saxon */
-  {"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 */
-  {"apk",	{HB_TAG('A','T','H',' ')}},	/* Kiowa Apache -> Athapaskan */
-  {"apl",	{HB_TAG('A','T','H',' ')}},	/* Lipan Apache -> Athapaskan */
-  {"apm",	{HB_TAG('A','T','H',' ')}},	/* Mescalero-Chiricahua Apache -> Athapaskan */
-  {"apw",	{HB_TAG('A','T','H',' ')}},	/* Western Apache -> Athapaskan */
-  {"ar",	{HB_TAG('A','R','A',' ')}},	/* Arabic [macrolanguage] */
-  {"arb",	{HB_TAG('A','R','A',' ')}},	/* Standard Arabic -> Arabic */
-  {"arn",	{HB_TAG('M','A','P',' ')}},	/* Mapudungun */
-  {"arq",	{HB_TAG('A','R','A',' ')}},	/* Algerian Arabic -> Arabic */
-  {"ars",	{HB_TAG('A','R','A',' ')}},	/* Najdi Arabic -> Arabic */
-  {"ary",	{HB_TAG('M','O','R',' ')}},	/* Moroccan Arabic -> Moroccan */
-  {"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 */
-  {"atj",	{HB_TAG('R','C','R',' ')}},	/* Atikamekw -> R-Cree */
-  {"atv",	{HB_TAG('A','L','T',' ')}},	/* Northern Altai -> Altai */
-  {"auz",	{HB_TAG('A','R','A',' ')}},	/* Uzbeki Arabic -> Arabic */
-  {"av",	{HB_TAG('A','V','R',' ')}},	/* Avaric -> Avar */
-  {"avl",	{HB_TAG('A','R','A',' ')}},	/* Eastern Egyptian Bedawi Arabic -> Arabic */
-  {"awa",	{HB_TAG('A','W','A',' ')}},	/* Awadhi */
-  {"ay",	{HB_TAG('A','Y','M',' ')}},	/* Aymara [macrolanguage] */
-  {"ayc",	{HB_TAG('A','Y','M',' ')}},	/* Southern Aymara -> Aymara */
-  {"ayh",	{HB_TAG('A','R','A',' ')}},	/* Hadrami Arabic -> Arabic */
-  {"ayl",	{HB_TAG('A','R','A',' ')}},	/* Libyan Arabic -> Arabic */
-  {"ayn",	{HB_TAG('A','R','A',' ')}},	/* Sanaani Arabic -> Arabic */
-  {"ayp",	{HB_TAG('A','R','A',' ')}},	/* North Mesopotamian Arabic -> Arabic */
-  {"ayr",	{HB_TAG('A','Y','M',' ')}},	/* Central Aymara -> Aymara */
-  {"az",	{HB_TAG('A','Z','E',' ')}},	/* Azerbaijani [macrolanguage] */
-  {"azb",	{HB_TAG('A','Z','B',' ')}},	/* South Azerbaijani -> Torki */
-  {"azj",	{HB_TAG('A','Z','E',' ')}},	/* North Azerbaijani -> Azerbaijani */
-  {"ba",	{HB_TAG('B','S','H',' ')}},	/* Bashkir */
-  {"bad",	{HB_TAG('B','A','D','0')}},	/* Banda [family] */
-  {"bai",	{HB_TAG('B','M','L',' ')}},	/* Bamileke [family] */
-  {"bal",	{HB_TAG('B','L','I',' ')}},	/* Baluchi [macrolanguage] */
-  {"ban",	{HB_TAG('B','A','N',' ')}},	/* Balinese */
-  {"bar",	{HB_TAG('B','A','R',' ')}},	/* Bavarian */
-  {"bbc",	{HB_TAG('B','B','C',' ')}},	/* Batak Toba */
-  {"bbz",	{HB_TAG('A','R','A',' ')}},	/* Babalia Creole Arabic -> Arabic */
-  {"bcc",	{HB_TAG('B','L','I',' ')}},	/* Southern Balochi -> Baluchi */
-  {"bci",	{HB_TAG('B','A','U',' ')}},	/* Baoulé -> Baulé */
-  {"bcl",	{HB_TAG('B','I','K',' ')}},	/* Central Bikol -> Bikol */
-  {"bcq",	{HB_TAG('B','C','H',' ')}},	/* Bench */
-  {"bcr",	{HB_TAG('A','T','H',' ')}},	/* Babine -> Athapaskan */
-  {"bdy",	{HB_TAG('B','D','Y',' ')}},	/* Bandjalang */
-  {"be",	{HB_TAG('B','E','L',' ')}},	/* Belarusian -> Belarussian */
-  {"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] */
-  {"bfq",	{HB_TAG('B','A','D',' ')}},	/* Badaga */
-  {"bft",	{HB_TAG('B','L','T',' ')}},	/* Balti */
-  {"bfu",	{HB_TAG('L','A','H',' ')}},	/* Gahri -> Lahuli */
-  {"bfy",	{HB_TAG('B','A','G',' ')}},	/* Bagheli -> Baghelkhandi */
-  {"bg",	{HB_TAG('B','G','R',' ')}},	/* Bulgarian */
-  {"bgc",	{HB_TAG('B','G','C',' ')}},	/* Haryanvi */
-  {"bgn",	{HB_TAG('B','L','I',' ')}},	/* Western Balochi -> Baluchi */
-  {"bgp",	{HB_TAG('B','L','I',' ')}},	/* Eastern Balochi -> Baluchi */
-  {"bgq",	{HB_TAG('B','G','Q',' ')}},	/* Bagri */
-  {"bgr",	{HB_TAG('Q','I','N',' ')}},	/* Bawm Chin -> Chin */
-  {"bhb",	{HB_TAG('B','H','I',' ')}},	/* Bhili */
-  {"bhi",	{HB_TAG('B','H','I',' ')}},	/* Bhilali -> Bhili */
-  {"bhk",	{HB_TAG('B','I','K',' ')}},	/* Albay Bicolano (retired code) -> Bikol */
-  {"bho",	{HB_TAG('B','H','O',' ')}},	/* Bhojpuri */
-  {"bhr",	{HB_TAG('M','L','G',' ')}},	/* Bara Malagasy -> Malagasy */
-  {"bi",	{HB_TAG('B','I','S',' ')}},	/* Bislama */
-  {"bik",	{HB_TAG('B','I','K',' ')}},	/* Bikol [macrolanguage] */
-  {"bin",	{HB_TAG('E','D','O',' ')}},	/* Edo */
-  {"bjj",	{HB_TAG('B','J','J',' ')}},	/* Kanauji */
-  {"bjn",	{HB_TAG('M','L','Y',' ')}},	/* Banjar -> Malay */
-  {"bjq",	{HB_TAG('M','L','G',' ')}},	/* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */
-  {"bjt",	{HB_TAG('B','L','N',' ')}},	/* Balanta-Ganja -> Balante */
-  {"bla",	{HB_TAG('B','K','F',' ')}},	/* Siksika -> Blackfoot */
-  {"ble",	{HB_TAG('B','L','N',' ')}},	/* Balanta-Kentohe -> Balante */
-  {"blk",	{HB_TAG('B','L','K',' ')}},	/* Pa’o Karen */
-  {"bln",	{HB_TAG('B','I','K',' ')}},	/* Southern Catanduanes Bikol -> Bikol */
-  {"bm",	{HB_TAG('B','M','B',' ')}},	/* Bambara (Bamanankan) */
-  {"bmm",	{HB_TAG('M','L','G',' ')}},	/* Northern Betsimisaraka Malagasy -> Malagasy */
-  {"bn",	{HB_TAG('B','E','N',' ')}},	/* Bengali */
-  {"bo",	{HB_TAG('T','I','B',' ')}},	/* Tibetan */
-  {"bpy",	{HB_TAG('B','P','Y',' ')}},	/* Bishnupriya -> Bishnupriya Manipuri */
-  {"bqi",	{HB_TAG('L','R','C',' ')}},	/* Bakhtiari -> Luri */
-  {"br",	{HB_TAG('B','R','E',' ')}},	/* Breton */
-  {"bra",	{HB_TAG('B','R','I',' ')}},	/* Braj -> Braj Bhasha */
-  {"brh",	{HB_TAG('B','R','H',' ')}},	/* Brahui */
-  {"brx",	{HB_TAG('B','R','X',' ')}},	/* Bodo (India) */
-  {"bs",	{HB_TAG('B','O','S',' ')}},	/* Bosnian */
-  {"bsk",	{HB_TAG('B','S','K',' ')}},	/* Burushaski */
-  {"btb",	{HB_TAG('B','T','I',' ')}},	/* Beti (Cameroon) (retired code) */
-  {"btj",	{HB_TAG('M','L','Y',' ')}},	/* Bacanese Malay -> Malay */
-  {"bto",	{HB_TAG('B','I','K',' ')}},	/* Rinconada Bikol -> Bikol */
-  {"bts",	{HB_TAG('B','T','S',' ')}},	/* Batak Simalungun */
-  {"bug",	{HB_TAG('B','U','G',' ')}},	/* Buginese -> Bugis */
-  {"bum",	{HB_TAG('B','T','I',' ')}},	/* Bulu (Cameroon) -> Beti */
-  {"bve",	{HB_TAG('M','L','Y',' ')}},	/* Berau Malay -> Malay */
-  {"bvu",	{HB_TAG('M','L','Y',' ')}},	/* Bukit Malay -> Malay */
-  {"bxk",	{HB_TAG('L','U','H',' ')}},	/* Bukusu -> Luyia */
-  {"bxp",	{HB_TAG('B','T','I',' ')}},	/* Bebil -> Beti */
-  {"bxr",	{HB_TAG('R','B','U',' ')}},	/* Russia Buriat -> Russian Buriat */
-  {"byn",	{HB_TAG('B','I','L',' ')}},	/* Bilin -> Bilen */
-  {"byv",	{HB_TAG('B','Y','V',' ')}},	/* Medumba */
-  {"bzc",	{HB_TAG('M','L','G',' ')}},	/* Southern Betsimisaraka Malagasy -> Malagasy */
-  {"ca",	{HB_TAG('C','A','T',' ')}},	/* Catalan */
-  {"caf",	{HB_TAG('C','R','R',' '),	/* Southern Carrier -> Carrier */
-		 HB_TAG('A','T','H',' ')}},	/* Southern Carrier -> Athapaskan */
-  {"cak",	{HB_TAG('C','A','K',' ')}},	/* Kaqchikel */
-  {"cbk",	{HB_TAG('C','B','K',' ')}},	/* Chavacano -> Zamboanga Chavacano */
-  {"cbl",	{HB_TAG('Q','I','N',' ')}},	/* Bualkhaw Chin -> Chin */
-  {"cco",	{HB_TAG('C','C','H','N')}},	/* Comaltepec Chinantec -> Chinantec */
-  {"ccq",	{HB_TAG('A','R','K',' ')}},	/* Chaungtha (retired code) -> Rakhine */
-  {"cdo",	{HB_TAG('Z','H','S',' ')}},	/* Min Dong Chinese -> Chinese Simplified */
-  {"ce",	{HB_TAG('C','H','E',' ')}},	/* Chechen */
-  {"ceb",	{HB_TAG('C','E','B',' ')}},	/* Cebuano */
-  {"cfm",	{HB_TAG('H','A','L',' ')}},	/* Halam (Falam Chin) */
-  {"cgg",	{HB_TAG('C','G','G',' ')}},	/* Chiga */
-  {"ch",	{HB_TAG('C','H','A',' ')}},	/* Chamorro */
-  {"chj",	{HB_TAG('C','C','H','N')}},	/* Ojitlán Chinantec -> Chinantec */
-  {"chk",	{HB_TAG('C','H','K','0')}},	/* Chuukese */
-  {"cho",	{HB_TAG('C','H','O',' ')}},	/* Choctaw */
-  {"chp",	{HB_TAG('C','H','P',' '),	/* Chipewyan */
-		 HB_TAG('S','A','Y',' '),	/* Chipewyan -> Sayisi */
-		 HB_TAG('A','T','H',' ')}},	/* Chipewyan -> Athapaskan */
-  {"chq",	{HB_TAG('C','C','H','N')}},	/* Quiotepec Chinantec -> Chinantec */
-  {"chr",	{HB_TAG('C','H','R',' ')}},	/* Cherokee */
-  {"chy",	{HB_TAG('C','H','Y',' ')}},	/* Cheyenne */
-  {"chz",	{HB_TAG('C','C','H','N')}},	/* Ozumacín Chinantec -> Chinantec */
-  {"ciw",	{HB_TAG('O','J','B',' ')}},	/* Chippewa -> Ojibway */
-  {"cja",	{HB_TAG('C','J','A',' ')}},	/* Western Cham */
-  {"cjm",	{HB_TAG('C','J','M',' ')}},	/* Eastern Cham */
-  {"cjy",	{HB_TAG('Z','H','S',' ')}},	/* Jinyu Chinese -> Chinese Simplified */
-  {"cka",	{HB_TAG('Q','I','N',' ')}},	/* Khumi Awa Chin (retired code) -> Chin */
-  {"ckb",	{HB_TAG('K','U','R',' ')}},	/* Central Kurdish -> Kurdish */
-  {"ckt",	{HB_TAG('C','H','K',' ')}},	/* Chukot -> Chukchi */
-  {"clc",	{HB_TAG('A','T','H',' ')}},	/* Chilcotin -> Athapaskan */
-  {"cld",	{HB_TAG('S','Y','R',' ')}},	/* Chaldean Neo-Aramaic -> Syriac */
-  {"cle",	{HB_TAG('C','C','H','N')}},	/* Lealao Chinantec -> Chinantec */
-  {"cmn",	{HB_TAG('Z','H','S',' ')}},	/* Mandarin Chinese -> Chinese Simplified */
-  {"cmr",	{HB_TAG('Q','I','N',' ')}},	/* Mro-Khimi Chin -> Chin */
-  {"cnb",	{HB_TAG('Q','I','N',' ')}},	/* Chinbon Chin -> Chin */
-  {"cnh",	{HB_TAG('Q','I','N',' ')}},	/* Hakha Chin -> Chin */
-  {"cnk",	{HB_TAG('Q','I','N',' ')}},	/* Khumi Chin -> Chin */
-  {"cnl",	{HB_TAG('C','C','H','N')}},	/* Lalana Chinantec -> Chinantec */
-  {"cnt",	{HB_TAG('C','C','H','N')}},	/* Tepetotutla Chinantec -> Chinantec */
-  {"cnw",	{HB_TAG('Q','I','N',' ')}},	/* Ngawn Chin -> Chin */
-  {"co",	{HB_TAG('C','O','S',' ')}},	/* Corsican */
-  {"coa",	{HB_TAG('M','L','Y',' ')}},	/* Cocos Islands Malay -> Malay */
-  {"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 */
-  {"cpp",	{HB_TAG('C','P','P',' ')}},	/* Portuguese-based creoles and pidgins [family] -> 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) */
-  {"cr",	{HB_TAG('C','R','E',' '),	/* Cree [macrolanguage] */
-		 HB_TAG('Y','C','R',' ')}},	/* Cree [macrolanguage] -> Y-Cree */
-  {"crh",	{HB_TAG('C','R','T',' ')}},	/* Crimean Tatar */
-  {"crj",	{HB_TAG('E','C','R',' ')}},	/* Southern East Cree -> Eastern Cree */
-  {"crk",	{HB_TAG('W','C','R',' ')}},	/* Plains Cree -> West-Cree */
-  {"crl",	{HB_TAG('E','C','R',' ')}},	/* Northern East Cree -> Eastern Cree */
-  {"crm",	{HB_TAG('M','C','R',' '),	/* Moose Cree */
-		 HB_TAG('L','C','R',' ')}},	/* Moose Cree -> L-Cree */
-  {"crp",	{HB_TAG('C','P','P',' ')}},	/* Creoles and pidgins [family] -> Creoles */
-  {"crx",	{HB_TAG('C','R','R',' '),	/* Carrier */
-		 HB_TAG('A','T','H',' ')}},	/* Carrier -> Athapaskan */
-  {"cs",	{HB_TAG('C','S','Y',' ')}},	/* Czech */
-  {"csa",	{HB_TAG('C','C','H','N')}},	/* Chiltepec Chinantec -> Chinantec */
-  {"csb",	{HB_TAG('C','S','B',' ')}},	/* Kashubian */
-  {"csh",	{HB_TAG('Q','I','N',' ')}},	/* Asho Chin -> Chin */
-  {"cso",	{HB_TAG('C','C','H','N')}},	/* Sochiapam Chinantec -> Chinantec */
-  {"csw",	{HB_TAG('N','C','R',' '),	/* Swampy Cree -> N-Cree */
-		 HB_TAG('N','H','C',' ')}},	/* Swampy Cree -> Norway House Cree */
-  {"csy",	{HB_TAG('Q','I','N',' ')}},	/* Siyin Chin -> Chin */
-  {"ctc",	{HB_TAG('A','T','H',' ')}},	/* Chetco -> Athapaskan */
-  {"ctd",	{HB_TAG('Q','I','N',' ')}},	/* Tedim Chin -> Chin */
-  {"cte",	{HB_TAG('C','C','H','N')}},	/* Tepinapa Chinantec -> Chinantec */
-  {"ctg",	{HB_TAG('C','T','G',' ')}},	/* Chittagonian */
-  {"ctl",	{HB_TAG('C','C','H','N')}},	/* Tlacoatzintepec Chinantec -> Chinantec */
-  {"cts",	{HB_TAG('B','I','K',' ')}},	/* Northern Catanduanes Bikol -> Bikol */
-  {"cu",	{HB_TAG('C','S','L',' ')}},	/* Church Slavonic */
-  {"cuc",	{HB_TAG('C','C','H','N')}},	/* Usila Chinantec -> Chinantec */
-  {"cuk",	{HB_TAG('C','U','K',' ')}},	/* San Blas Kuna */
-  {"cv",	{HB_TAG('C','H','U',' ')}},	/* Chuvash */
-  {"cvn",	{HB_TAG('C','C','H','N')}},	/* Valle Nacional Chinantec -> Chinantec */
-  {"cwd",	{HB_TAG('D','C','R',' '),	/* Woods Cree */
-		 HB_TAG('T','C','R',' ')}},	/* Woods Cree -> TH-Cree */
-  {"cy",	{HB_TAG('W','E','L',' ')}},	/* Welsh */
-  {"czh",	{HB_TAG('Z','H','S',' ')}},	/* Huizhou Chinese -> Chinese Simplified */
-  {"czo",	{HB_TAG('Z','H','S',' ')}},	/* Min Zhong Chinese -> Chinese Simplified */
-  {"czt",	{HB_TAG('Q','I','N',' ')}},	/* Zotung Chin -> Chin */
-  {"da",	{HB_TAG('D','A','N',' ')}},	/* Danish */
-  {"dao",	{HB_TAG('Q','I','N',' ')}},	/* Daai Chin -> Chin */
-  {"dap",	{HB_TAG('N','I','S',' ')}},	/* Nisi (India) (retired code) */
-  {"dar",	{HB_TAG('D','A','R',' ')}},	/* Dargwa */
-  {"dax",	{HB_TAG('D','A','X',' ')}},	/* Dayi */
-  {"de",	{HB_TAG('D','E','U',' ')}},	/* German */
-  {"den",	{HB_TAG('S','L','A',' '),	/* Slave (Athapascan) [macrolanguage] -> Slavey */
-		 HB_TAG('A','T','H',' ')}},	/* Slave (Athapascan) [macrolanguage] -> Athapaskan */
-  {"dgo",	{HB_TAG('D','G','O',' ')}},	/* Dogri */
-  {"dgr",	{HB_TAG('A','T','H',' ')}},	/* Dogrib -> Athapaskan */
-  {"dhd",	{HB_TAG('M','A','W',' ')}},	/* Dhundari -> Marwari */
-  {"dhg",	{HB_TAG('D','H','G',' ')}},	/* Dhangu */
-  {"dib",	{HB_TAG('D','N','K',' ')}},	/* South Central Dinka -> Dinka */
-  {"dik",	{HB_TAG('D','N','K',' ')}},	/* Southwestern Dinka -> Dinka */
-  {"din",	{HB_TAG('D','N','K',' ')}},	/* Dinka [macrolanguage] */
-  {"dip",	{HB_TAG('D','N','K',' ')}},	/* Northeastern Dinka -> Dinka */
-  {"diq",	{HB_TAG('D','I','Q',' ')}},	/* Dimli */
-  {"diw",	{HB_TAG('D','N','K',' ')}},	/* Northwestern Dinka -> Dinka */
-  {"dje",	{HB_TAG('D','J','R',' ')}},	/* Zarma */
-  {"djr",	{HB_TAG('D','J','R','0')}},	/* Djambarrpuyngu */
-  {"dks",	{HB_TAG('D','N','K',' ')}},	/* Southeastern Dinka -> Dinka */
-  {"dng",	{HB_TAG('D','U','N',' ')}},	/* Dungan */
-  {"dnj",	{HB_TAG('D','N','J',' ')}},	/* Dan */
-  {"doi",	{HB_TAG('D','G','R',' ')}},	/* Dogri [macrolanguage] */
-  {"drh",	{HB_TAG('M','N','G',' ')}},	/* Darkhat (retired code) -> Mongolian */
-  {"drw",	{HB_TAG('D','R','I',' ')}},	/* Darwazi (retired code) -> Dari */
-  {"dsb",	{HB_TAG('L','S','B',' ')}},	/* Lower Sorbian */
-  {"dty",	{HB_TAG('N','E','P',' ')}},	/* Dotyali -> Nepali */
-  {"duj",	{HB_TAG('D','U','J',' ')}},	/* Dhuwal (retired code) */
-  {"dup",	{HB_TAG('M','L','Y',' ')}},	/* Duano -> Malay */
-  {"dv",	{HB_TAG('D','I','V',' '),	/* Divehi (Dhivehi, Maldivian) */
-		 HB_TAG('D','H','V',' ')}},	/* Divehi (Dhivehi, Maldivian) (deprecated) */
-  {"dwu",	{HB_TAG('D','U','J',' ')}},	/* Dhuwal */
-  {"dwy",	{HB_TAG('D','U','J',' ')}},	/* Dhuwaya -> Dhuwal */
-  {"dyu",	{HB_TAG('J','U','L',' ')}},	/* Dyula -> Jula */
-  {"dz",	{HB_TAG('D','Z','N',' ')}},	/* Dzongkha */
-  {"ee",	{HB_TAG('E','W','E',' ')}},	/* Ewe */
-  {"efi",	{HB_TAG('E','F','I',' ')}},	/* Efik */
-  {"ekk",	{HB_TAG('E','T','I',' ')}},	/* Standard Estonian -> Estonian */
-  {"el",	{HB_TAG('E','L','L',' ')}},	/* Modern Greek (1453-) -> Greek */
-  {"emk",	{HB_TAG('E','M','K',' '),	/* Eastern Maninkakan */
-		 HB_TAG('M','N','K',' ')}},	/* Eastern Maninkakan -> Maninka */
-  {"en",	{HB_TAG('E','N','G',' ')}},	/* English */
-  {"enb",	{HB_TAG('K','A','L',' ')}},	/* Markweeta -> Kalenjin */
-  {"enf",	{HB_TAG('F','N','E',' ')}},	/* Forest Enets -> Forest Nenets */
-  {"enh",	{HB_TAG('T','N','E',' ')}},	/* Tundra Enets -> Tundra Nenets */
-  {"eo",	{HB_TAG('N','T','O',' ')}},	/* Esperanto */
-  {"es",	{HB_TAG('E','S','P',' ')}},	/* Spanish */
-  {"esg",	{HB_TAG('G','O','N',' ')}},	/* Aheri Gondi -> Gondi */
-  {"esi",	{HB_TAG('I','P','K',' ')}},	/* North Alaskan Inupiatun -> Inupiat */
-  {"esk",	{HB_TAG('I','P','K',' ')}},	/* Northwest Alaska Inupiatun -> Inupiat */
-  {"esu",	{HB_TAG('E','S','U',' ')}},	/* Central Yupik */
-  {"et",	{HB_TAG('E','T','I',' ')}},	/* Estonian [macrolanguage] */
-  {"eto",	{HB_TAG('B','T','I',' ')}},	/* Eton (Cameroon) -> Beti */
-  {"eu",	{HB_TAG('E','U','Q',' ')}},	/* Basque */
-  {"eve",	{HB_TAG('E','V','N',' ')}},	/* Even */
-  {"evn",	{HB_TAG('E','V','K',' ')}},	/* Evenki */
-  {"ewo",	{HB_TAG('B','T','I',' ')}},	/* Ewondo -> Beti */
-  {"eyo",	{HB_TAG('K','A','L',' ')}},	/* Keiyo -> Kalenjin */
-  {"fa",	{HB_TAG('F','A','R',' ')}},	/* Persian [macrolanguage] */
-  {"fan",	{HB_TAG('F','A','N','0')}},	/* Fang (Equatorial Guinea) */
-  {"fat",	{HB_TAG('F','A','T',' ')}},	/* Fanti */
-  {"fbl",	{HB_TAG('B','I','K',' ')}},	/* West Albay Bikol -> Bikol */
-  {"ff",	{HB_TAG('F','U','L',' ')}},	/* Fulah [macrolanguage] */
-  {"ffm",	{HB_TAG('F','U','L',' ')}},	/* Maasina Fulfulde -> Fulah */
-  {"fi",	{HB_TAG('F','I','N',' ')}},	/* Finnish */
-  {"fil",	{HB_TAG('P','I','L',' ')}},	/* Filipino */
-  {"fj",	{HB_TAG('F','J','I',' ')}},	/* Fijian */
-  {"flm",	{HB_TAG('H','A','L',' '),	/* Halam (Falam Chin) (retired code) */
-		 HB_TAG('Q','I','N',' ')}},	/* Falam Chin (retired code) -> Chin */
-  {"fmp",	{HB_TAG('F','M','P',' ')}},	/* Fe’fe’ */
-  {"fo",	{HB_TAG('F','O','S',' ')}},	/* Faroese */
-  {"fon",	{HB_TAG('F','O','N',' ')}},	/* Fon */
-  {"fr",	{HB_TAG('F','R','A',' ')}},	/* French */
-  {"frc",	{HB_TAG('F','R','C',' ')}},	/* Cajun French */
-  {"frp",	{HB_TAG('F','R','P',' ')}},	/* Arpitan */
-  {"fub",	{HB_TAG('F','U','L',' ')}},	/* Adamawa Fulfulde -> Fulah */
-  {"fuc",	{HB_TAG('F','U','L',' ')}},	/* Pulaar -> Fulah */
-  {"fue",	{HB_TAG('F','U','L',' ')}},	/* Borgu Fulfulde -> Fulah */
-  {"fuf",	{HB_TAG('F','T','A',' ')}},	/* Pular -> Futa */
-  {"fuh",	{HB_TAG('F','U','L',' ')}},	/* Western Niger Fulfulde -> Fulah */
-  {"fui",	{HB_TAG('F','U','L',' ')}},	/* Bagirmi Fulfulde -> Fulah */
-  {"fuq",	{HB_TAG('F','U','L',' ')}},	/* Central-Eastern Niger Fulfulde -> Fulah */
-  {"fur",	{HB_TAG('F','R','L',' ')}},	/* Friulian */
-  {"fuv",	{HB_TAG('F','U','V',' ')}},	/* Nigerian Fulfulde */
-  {"fy",	{HB_TAG('F','R','I',' ')}},	/* Western Frisian -> Frisian */
-  {"ga",	{HB_TAG('I','R','I',' ')}},	/* Irish */
-  {"gaa",	{HB_TAG('G','A','D',' ')}},	/* Ga */
-  {"gag",	{HB_TAG('G','A','G',' ')}},	/* Gagauz */
-  {"gan",	{HB_TAG('Z','H','S',' ')}},	/* Gan Chinese -> Chinese Simplified */
-  {"gax",	{HB_TAG('O','R','O',' ')}},	/* Borana-Arsi-Guji Oromo -> Oromo */
-  {"gaz",	{HB_TAG('O','R','O',' ')}},	/* West Central Oromo -> Oromo */
-  {"gbm",	{HB_TAG('G','A','W',' ')}},	/* Garhwali */
-  {"gce",	{HB_TAG('A','T','H',' ')}},	/* Galice -> Athapaskan */
-  {"gd",	{HB_TAG('G','A','E',' ')}},	/* Scottish Gaelic (Gaelic) */
-  {"gda",	{HB_TAG('R','A','J',' ')}},	/* Gade Lohar -> Rajasthani */
-  {"gez",	{HB_TAG('G','E','Z',' ')}},	/* Geez */
-  {"ggo",	{HB_TAG('G','O','N',' ')}},	/* Southern Gondi (retired code) -> Gondi */
-  {"gih",	{HB_TAG('G','I','H',' ')}},	/* Githabul */
-  {"gil",	{HB_TAG('G','I','L','0')}},	/* Kiribati (Gilbertese) */
-  {"gju",	{HB_TAG('R','A','J',' ')}},	/* Gujari -> Rajasthani */
-  {"gkp",	{HB_TAG('G','K','P',' ')}},	/* Guinea Kpelle -> Kpelle (Guinea) */
-  {"gl",	{HB_TAG('G','A','L',' ')}},	/* Galician */
-  {"gld",	{HB_TAG('N','A','N',' ')}},	/* Nanai */
-  {"glk",	{HB_TAG('G','L','K',' ')}},	/* Gilaki */
-  {"gn",	{HB_TAG('G','U','A',' ')}},	/* Guarani [macrolanguage] */
-  {"gnn",	{HB_TAG('G','N','N',' ')}},	/* Gumatj */
-  {"gno",	{HB_TAG('G','O','N',' ')}},	/* Northern Gondi -> Gondi */
-  {"gnw",	{HB_TAG('G','U','A',' ')}},	/* Western Bolivian Guaraní -> Guarani */
-  {"gog",	{HB_TAG('G','O','G',' ')}},	/* Gogo */
-  {"gom",	{HB_TAG('K','O','K',' ')}},	/* Goan Konkani -> Konkani */
-  {"gon",	{HB_TAG('G','O','N',' ')}},	/* Gondi [macrolanguage] */
-  {"grt",	{HB_TAG('G','R','O',' ')}},	/* Garo */
-  {"gru",	{HB_TAG('S','O','G',' ')}},	/* Kistane -> Sodo Gurage */
-  {"gsw",	{HB_TAG('A','L','S',' ')}},	/* Alsatian */
-  {"gu",	{HB_TAG('G','U','J',' ')}},	/* Gujarati */
-  {"guc",	{HB_TAG('G','U','C',' ')}},	/* Wayuu */
-  {"guf",	{HB_TAG('G','U','F',' ')}},	/* Gupapuyngu */
-  {"gug",	{HB_TAG('G','U','A',' ')}},	/* Paraguayan Guaraní -> Guarani */
-  {"gui",	{HB_TAG('G','U','A',' ')}},	/* Eastern Bolivian Guaraní -> Guarani */
-  {"guk",	{HB_TAG('G','M','Z',' '),	/* Gumuz */
-		 HB_TAG('G','U','K',' ')}},	/* Gumuz (SIL fonts) */
-  {"gun",	{HB_TAG('G','U','A',' ')}},	/* Mbyá Guaraní -> Guarani */
-  {"guz",	{HB_TAG('G','U','Z',' ')}},	/* Gusii */
-  {"gv",	{HB_TAG('M','N','X',' ')}},	/* Manx */
-  {"gwi",	{HB_TAG('A','T','H',' ')}},	/* Gwichʼin -> Athapaskan */
-  {"ha",	{HB_TAG('H','A','U',' ')}},	/* Hausa */
-  {"haa",	{HB_TAG('A','T','H',' ')}},	/* Han -> Athapaskan */
-  {"hae",	{HB_TAG('O','R','O',' ')}},	/* Eastern Oromo -> Oromo */
-  {"hak",	{HB_TAG('Z','H','S',' ')}},	/* Hakka Chinese -> Chinese Simplified */
-  {"har",	{HB_TAG('H','R','I',' ')}},	/* Harari */
-  {"haw",	{HB_TAG('H','A','W',' ')}},	/* Hawaiian */
-  {"hay",	{HB_TAG('H','A','Y',' ')}},	/* Haya */
-  {"haz",	{HB_TAG('H','A','Z',' ')}},	/* Hazaragi */
-  {"he",	{HB_TAG('I','W','R',' ')}},	/* Hebrew */
-  {"hea",	{HB_TAG('H','M','N',' ')}},	/* Northern Qiandong Miao -> Hmong */
-  {"hi",	{HB_TAG('H','I','N',' ')}},	/* Hindi */
-  {"hil",	{HB_TAG('H','I','L',' ')}},	/* Hiligaynon */
-  {"hji",	{HB_TAG('M','L','Y',' ')}},	/* Haji -> Malay */
-  {"hlt",	{HB_TAG('Q','I','N',' ')}},	/* Matu Chin -> Chin */
-  {"hma",	{HB_TAG('H','M','N',' ')}},	/* Southern Mashan Hmong -> Hmong */
-  {"hmc",	{HB_TAG('H','M','N',' ')}},	/* Central Huishui Hmong -> Hmong */
-  {"hmd",	{HB_TAG('H','M','N',' ')}},	/* Large Flowery Miao -> Hmong */
-  {"hme",	{HB_TAG('H','M','N',' ')}},	/* Eastern Huishui Hmong -> Hmong */
-  {"hmg",	{HB_TAG('H','M','N',' ')}},	/* Southwestern Guiyang Hmong -> Hmong */
-  {"hmh",	{HB_TAG('H','M','N',' ')}},	/* Southwestern Huishui Hmong -> Hmong */
-  {"hmi",	{HB_TAG('H','M','N',' ')}},	/* Northern Huishui Hmong -> Hmong */
-  {"hmj",	{HB_TAG('H','M','N',' ')}},	/* Ge -> Hmong */
-  {"hml",	{HB_TAG('H','M','N',' ')}},	/* Luopohe Hmong -> Hmong */
-  {"hmm",	{HB_TAG('H','M','N',' ')}},	/* Central Mashan Hmong -> Hmong */
-  {"hmn",	{HB_TAG('H','M','N',' ')}},	/* Hmong [macrolanguage] */
-  {"hmp",	{HB_TAG('H','M','N',' ')}},	/* Northern Mashan Hmong -> Hmong */
-  {"hmq",	{HB_TAG('H','M','N',' ')}},	/* Eastern Qiandong Miao -> Hmong */
-  {"hms",	{HB_TAG('H','M','N',' ')}},	/* Southern Qiandong Miao -> Hmong */
-  {"hmw",	{HB_TAG('H','M','N',' ')}},	/* Western Mashan Hmong -> Hmong */
-  {"hmy",	{HB_TAG('H','M','N',' ')}},	/* Southern Guiyang Hmong -> Hmong */
-  {"hmz",	{HB_TAG('H','M','N',' ')}},	/* Hmong Shua -> Hmong */
-  {"hnd",	{HB_TAG('H','N','D',' ')}},	/* Southern Hindko -> Hindko */
-  {"hne",	{HB_TAG('C','H','H',' ')}},	/* Chhattisgarhi -> Chattisgarhi */
-  {"hnj",	{HB_TAG('H','M','N',' ')}},	/* Hmong Njua -> Hmong */
-  {"hno",	{HB_TAG('H','N','D',' ')}},	/* Northern Hindko -> Hindko */
-  {"ho",	{HB_TAG('H','M','O',' ')}},	/* Hiri Motu */
-  {"hoc",	{HB_TAG('H','O',' ',' ')}},	/* Ho */
-  {"hoi",	{HB_TAG('A','T','H',' ')}},	/* Holikachuk -> Athapaskan */
-  {"hoj",	{HB_TAG('H','A','R',' ')}},	/* Hadothi -> Harauti */
-  {"hr",	{HB_TAG('H','R','V',' ')}},	/* Croatian */
-  {"hrm",	{HB_TAG('H','M','N',' ')}},	/* Horned Miao -> Hmong */
-  {"hsb",	{HB_TAG('U','S','B',' ')}},	/* Upper Sorbian */
-  {"hsn",	{HB_TAG('Z','H','S',' ')}},	/* Xiang Chinese -> Chinese Simplified */
-  {"ht",	{HB_TAG('H','A','I',' ')}},	/* Haitian (Haitian Creole) */
-  {"hu",	{HB_TAG('H','U','N',' ')}},	/* Hungarian */
-  {"huj",	{HB_TAG('H','M','N',' ')}},	/* Northern Guiyang Hmong -> Hmong */
-  {"hup",	{HB_TAG('A','T','H',' ')}},	/* Hupa -> Athapaskan */
-  {"hy",	{HB_TAG('H','Y','E','0'),	/* Armenian -> Armenian East */
-		 HB_TAG('H','Y','E',' ')}},	/* Armenian */
-  {"hyw",	{HB_TAG('H','Y','E',' ')}},	/* Western Armenian -> Armenian */
-  {"hz",	{HB_TAG('H','E','R',' ')}},	/* Herero */
-  {"ia",	{HB_TAG('I','N','A',' ')}},	/* Interlingua (International Auxiliary Language Association) */
-  {"iba",	{HB_TAG('I','B','A',' ')}},	/* Iban */
-  {"ibb",	{HB_TAG('I','B','B',' ')}},	/* Ibibio */
-  {"id",	{HB_TAG('I','N','D',' ')}},	/* Indonesian */
-  {"ida",	{HB_TAG('L','U','H',' ')}},	/* Idakho-Isukha-Tiriki -> Luyia */
-  {"ie",	{HB_TAG('I','L','E',' ')}},	/* Interlingue */
-  {"ig",	{HB_TAG('I','B','O',' ')}},	/* Igbo */
-  {"igb",	{HB_TAG('E','B','I',' ')}},	/* Ebira */
-  {"ii",	{HB_TAG('Y','I','M',' ')}},	/* Sichuan Yi -> Yi Modern */
-  {"ijc",	{HB_TAG('I','J','O',' ')}},	/* Izon -> Ijo */
-  {"ijo",	{HB_TAG('I','J','O',' ')}},	/* Ijo [family] */
-  {"ik",	{HB_TAG('I','P','K',' ')}},	/* Inupiaq [macrolanguage] -> Inupiat */
-  {"ike",	{HB_TAG('I','N','U',' ')}},	/* Eastern Canadian Inuktitut -> 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) */
-  {"ing",	{HB_TAG('A','T','H',' ')}},	/* Degexit'an -> Athapaskan */
-  {"inh",	{HB_TAG('I','N','G',' ')}},	/* Ingush */
-  {"io",	{HB_TAG('I','D','O',' ')}},	/* Ido */
-  {"is",	{HB_TAG('I','S','L',' ')}},	/* Icelandic */
-  {"it",	{HB_TAG('I','T','A',' ')}},	/* Italian */
-  {"iu",	{HB_TAG('I','N','U',' ')}},	/* Inuktitut [macrolanguage] */
-  {"iw",	{HB_TAG('I','W','R',' ')}},	/* Hebrew (retired code) */
-  {"ja",	{HB_TAG('J','A','N',' ')}},	/* Japanese */
-  {"jak",	{HB_TAG('M','L','Y',' ')}},	/* Jakun -> Malay */
-  {"jam",	{HB_TAG('J','A','M',' ')}},	/* Jamaican Creole English -> Jamaican Creole */
-  {"jax",	{HB_TAG('M','L','Y',' ')}},	/* Jambi Malay -> Malay */
-  {"jbo",	{HB_TAG('J','B','O',' ')}},	/* Lojban */
-  {"jct",	{HB_TAG('J','C','T',' ')}},	/* Krymchak */
-  {"ji",	{HB_TAG('J','I','I',' ')}},	/* Yiddish (retired code) */
-  {"jv",	{HB_TAG('J','A','V',' ')}},	/* Javanese */
-  {"jw",	{HB_TAG('J','A','V',' ')}},	/* Javanese (retired code) */
-  {"ka",	{HB_TAG('K','A','T',' ')}},	/* Georgian */
-  {"kaa",	{HB_TAG('K','R','K',' ')}},	/* Kara-Kalpak -> Karakalpak */
-  {"kab",	{HB_TAG('K','A','B','0')}},	/* Kabyle */
-  {"kam",	{HB_TAG('K','M','B',' ')}},	/* Kamba (Kenya) */
-  {"kar",	{HB_TAG('K','R','N',' ')}},	/* Karen [family] */
-  {"kbd",	{HB_TAG('K','A','B',' ')}},	/* Kabardian */
-  {"kby",	{HB_TAG('K','N','R',' ')}},	/* Manga Kanuri -> Kanuri */
-  {"kca",	{HB_TAG('K','H','K',' '),	/* Khanty -> Khanty-Kazim */
-		 HB_TAG('K','H','S',' '),	/* Khanty -> Khanty-Shurishkar */
-		 HB_TAG('K','H','V',' ')}},	/* Khanty -> Khanty-Vakhi */
-  {"kde",	{HB_TAG('K','D','E',' ')}},	/* Makonde */
-  {"kdr",	{HB_TAG('K','R','M',' ')}},	/* Karaim */
-  {"kdt",	{HB_TAG('K','U','Y',' ')}},	/* Kuy */
-  {"kea",	{HB_TAG('K','E','A',' ')}},	/* Kabuverdianu (Crioulo) */
-  {"kek",	{HB_TAG('K','E','K',' ')}},	/* Kekchi */
-  {"kex",	{HB_TAG('K','K','N',' ')}},	/* Kukna -> Kokni */
-  {"kfa",	{HB_TAG('K','O','D',' ')}},	/* Kodava -> Kodagu */
-  {"kfr",	{HB_TAG('K','A','C',' ')}},	/* Kachhi -> Kachchi */
-  {"kfx",	{HB_TAG('K','U','L',' ')}},	/* Kullu Pahari -> Kulvi */
-  {"kfy",	{HB_TAG('K','M','N',' ')}},	/* Kumaoni */
-  {"kg",	{HB_TAG('K','O','N','0')}},	/* Kongo [macrolanguage] */
-  {"kha",	{HB_TAG('K','S','I',' ')}},	/* Khasi */
-  {"khb",	{HB_TAG('X','B','D',' ')}},	/* Lü */
-  {"khk",	{HB_TAG('M','N','G',' ')}},	/* Halh Mongolian -> Mongolian */
-  {"kht",	{HB_TAG('K','H','N',' '),	/* Khamti -> Khamti Shan (Microsoft fonts) */
-		 HB_TAG('K','H','T',' ')}},	/* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */
-  {"khw",	{HB_TAG('K','H','W',' ')}},	/* Khowar */
-  {"ki",	{HB_TAG('K','I','K',' ')}},	/* Kikuyu (Gikuyu) */
-  {"kiu",	{HB_TAG('K','I','U',' ')}},	/* Kirmanjki */
-  {"kj",	{HB_TAG('K','U','A',' ')}},	/* Kuanyama */
-  {"kjd",	{HB_TAG('K','J','D',' ')}},	/* Southern Kiwai */
-  {"kjh",	{HB_TAG('K','H','A',' ')}},	/* Khakas -> Khakass */
-  {"kjp",	{HB_TAG('K','J','P',' ')}},	/* Pwo Eastern Karen -> Eastern Pwo Karen */
-  {"kjz",	{HB_TAG('K','J','Z',' ')}},	/* Bumthangkha */
-  {"kk",	{HB_TAG('K','A','Z',' ')}},	/* Kazakh */
-  {"kkz",	{HB_TAG('A','T','H',' ')}},	/* Kaska -> Athapaskan */
-  {"kl",	{HB_TAG('G','R','N',' ')}},	/* Greenlandic */
-  {"kln",	{HB_TAG('K','A','L',' ')}},	/* Kalenjin [macrolanguage] */
-  {"km",	{HB_TAG('K','H','M',' ')}},	/* Khmer */
-  {"kmb",	{HB_TAG('M','B','N',' ')}},	/* Kimbundu -> Mbundu */
-  {"kmr",	{HB_TAG('K','U','R',' ')}},	/* Northern Kurdish -> Kurdish */
-  {"kmw",	{HB_TAG('K','M','O',' ')}},	/* Komo (Democratic Republic of Congo) */
-  {"kmz",	{HB_TAG('K','M','Z',' ')}},	/* Khorasani Turkish -> Khorasani Turkic */
-  {"kn",	{HB_TAG('K','A','N',' ')}},	/* Kannada */
-  {"knc",	{HB_TAG('K','N','R',' ')}},	/* Central Kanuri -> Kanuri */
-  {"kng",	{HB_TAG('K','O','N','0')}},	/* Koongo -> Kongo */
-  {"knn",	{HB_TAG('K','O','K',' ')}},	/* Konkani */
-  {"ko",	{HB_TAG('K','O','R',' ')}},	/* Korean */
-  {"koi",	{HB_TAG('K','O','P',' ')}},	/* Komi-Permyak */
-  {"kok",	{HB_TAG('K','O','K',' ')}},	/* Konkani [macrolanguage] */
-  {"kos",	{HB_TAG('K','O','S',' ')}},	/* Kosraean */
-  {"koy",	{HB_TAG('A','T','H',' ')}},	/* Koyukon -> Athapaskan */
-  {"kpe",	{HB_TAG('K','P','L',' ')}},	/* Kpelle [macrolanguage] */
-  {"kpv",	{HB_TAG('K','O','Z',' ')}},	/* Komi-Zyrian */
-  {"kpy",	{HB_TAG('K','Y','K',' ')}},	/* Koryak */
-  {"kqs",	{HB_TAG('K','I','S',' ')}},	/* Northern Kissi -> Kisii */
-  {"kqy",	{HB_TAG('K','R','T',' ')}},	/* Koorete */
-  {"kr",	{HB_TAG('K','N','R',' ')}},	/* Kanuri [macrolanguage] */
-  {"krc",	{HB_TAG('K','A','R',' '),	/* Karachay-Balkar -> Karachay */
-		 HB_TAG('B','A','L',' ')}},	/* Karachay-Balkar -> Balkar */
-  {"kri",	{HB_TAG('K','R','I',' ')}},	/* Krio */
-  {"krl",	{HB_TAG('K','R','L',' ')}},	/* Karelian */
-  {"krt",	{HB_TAG('K','N','R',' ')}},	/* Tumari Kanuri -> Kanuri */
-  {"kru",	{HB_TAG('K','U','U',' ')}},	/* Kurukh */
-  {"ks",	{HB_TAG('K','S','H',' ')}},	/* Kashmiri */
-  {"ksh",	{HB_TAG('K','S','H','0')}},	/* Kölsch -> Ripuarian */
-  {"kss",	{HB_TAG('K','I','S',' ')}},	/* Southern Kisi -> Kisii */
-  {"ksw",	{HB_TAG('K','S','W',' ')}},	/* S’gaw Karen */
-  {"ktb",	{HB_TAG('K','E','B',' ')}},	/* Kambaata -> Kebena */
-  {"ktu",	{HB_TAG('K','O','N',' ')}},	/* Kituba (Democratic Republic of Congo) -> Kikongo */
-  {"ktw",	{HB_TAG('A','T','H',' ')}},	/* Kato -> Athapaskan */
-  {"ku",	{HB_TAG('K','U','R',' ')}},	/* Kurdish [macrolanguage] */
-  {"kum",	{HB_TAG('K','U','M',' ')}},	/* Kumyk */
-  {"kuu",	{HB_TAG('A','T','H',' ')}},	/* Upper Kuskokwim -> Athapaskan */
-  {"kv",	{HB_TAG('K','O','M',' ')}},	/* Komi [macrolanguage] */
-  {"kvb",	{HB_TAG('M','L','Y',' ')}},	/* Kubu -> Malay */
-  {"kvr",	{HB_TAG('M','L','Y',' ')}},	/* Kerinci -> Malay */
-  {"kw",	{HB_TAG('C','O','R',' ')}},	/* Cornish */
-  {"kwy",	{HB_TAG('K','O','N','0')}},	/* San Salvador Kongo -> Kongo */
-  {"kxc",	{HB_TAG('K','M','S',' ')}},	/* Konso -> Komso */
-  {"kxd",	{HB_TAG('M','L','Y',' ')}},	/* Brunei -> Malay */
-  {"kxu",	{HB_TAG('K','U','I',' ')}},	/* Kui (India) */
-  {"ky",	{HB_TAG('K','I','R',' ')}},	/* Kirghiz (Kyrgyz) */
-  {"kyu",	{HB_TAG('K','Y','U',' ')}},	/* Western Kayah */
-  {"la",	{HB_TAG('L','A','T',' ')}},	/* Latin */
-  {"lad",	{HB_TAG('J','U','D',' ')}},	/* Ladino */
-  {"lb",	{HB_TAG('L','T','Z',' ')}},	/* Luxembourgish */
-  {"lbe",	{HB_TAG('L','A','K',' ')}},	/* Lak */
-  {"lbj",	{HB_TAG('L','D','K',' ')}},	/* Ladakhi */
-  {"lbl",	{HB_TAG('B','I','K',' ')}},	/* Libon Bikol -> Bikol */
-  {"lce",	{HB_TAG('M','L','Y',' ')}},	/* Loncong -> Malay */
-  {"lcf",	{HB_TAG('M','L','Y',' ')}},	/* Lubu -> Malay */
-  {"ldi",	{HB_TAG('K','O','N','0')}},	/* Laari -> Kongo */
-  {"lez",	{HB_TAG('L','E','Z',' ')}},	/* Lezghian -> Lezgi */
-  {"lg",	{HB_TAG('L','U','G',' ')}},	/* Ganda */
-  {"li",	{HB_TAG('L','I','M',' ')}},	/* Limburgish */
-  {"lif",	{HB_TAG('L','M','B',' ')}},	/* Limbu */
-  {"lij",	{HB_TAG('L','I','J',' ')}},	/* Ligurian */
-  {"lis",	{HB_TAG('L','I','S',' ')}},	/* Lisu */
-  {"liw",	{HB_TAG('M','L','Y',' ')}},	/* Col -> Malay */
-  {"ljp",	{HB_TAG('L','J','P',' ')}},	/* Lampung Api -> Lampung */
-  {"lkb",	{HB_TAG('L','U','H',' ')}},	/* Kabras -> Luyia */
-  {"lki",	{HB_TAG('L','K','I',' ')}},	/* Laki */
-  {"lko",	{HB_TAG('L','U','H',' ')}},	/* Khayo -> Luyia */
-  {"lks",	{HB_TAG('L','U','H',' ')}},	/* Kisa -> Luyia */
-  {"lld",	{HB_TAG('L','A','D',' ')}},	/* Ladin */
-  {"lmn",	{HB_TAG('L','A','M',' ')}},	/* Lambadi -> Lambani */
-  {"lmo",	{HB_TAG('L','M','O',' ')}},	/* Lombard */
-  {"ln",	{HB_TAG('L','I','N',' ')}},	/* Lingala */
-  {"lo",	{HB_TAG('L','A','O',' ')}},	/* Lao */
-  {"lom",	{HB_TAG('L','O','M',' ')}},	/* Loma (Liberia) */
-  {"lrc",	{HB_TAG('L','R','C',' ')}},	/* Northern Luri -> Luri */
-  {"lri",	{HB_TAG('L','U','H',' ')}},	/* Marachi -> Luyia */
-  {"lrm",	{HB_TAG('L','U','H',' ')}},	/* Marama -> Luyia */
-  {"lsm",	{HB_TAG('L','U','H',' ')}},	/* Saamia -> Luyia */
-  {"lt",	{HB_TAG('L','T','H',' ')}},	/* Lithuanian */
-  {"ltg",	{HB_TAG('L','V','I',' ')}},	/* Latgalian -> Latvian */
-  {"lto",	{HB_TAG('L','U','H',' ')}},	/* Tsotso -> Luyia */
-  {"lts",	{HB_TAG('L','U','H',' ')}},	/* Tachoni -> Luyia */
-  {"lu",	{HB_TAG('L','U','B',' ')}},	/* Luba-Katanga */
-  {"lua",	{HB_TAG('L','U','A',' ')}},	/* Luba-Lulua */
-  {"luo",	{HB_TAG('L','U','O',' ')}},	/* Luo (Kenya and Tanzania) */
-  {"lus",	{HB_TAG('M','I','Z',' ')}},	/* Lushai -> Mizo */
-  {"luy",	{HB_TAG('L','U','H',' ')}},	/* Luyia [macrolanguage] */
-  {"luz",	{HB_TAG('L','R','C',' ')}},	/* Southern Luri -> Luri */
-  {"lv",	{HB_TAG('L','V','I',' ')}},	/* Latvian [macrolanguage] */
-  {"lvs",	{HB_TAG('L','V','I',' ')}},	/* Standard Latvian -> Latvian */
-  {"lwg",	{HB_TAG('L','U','H',' ')}},	/* Wanga -> Luyia */
-  {"lzh",	{HB_TAG('Z','H','T',' ')}},	/* Literary Chinese -> Chinese Traditional */
-  {"lzz",	{HB_TAG('L','A','Z',' ')}},	/* Laz */
-  {"mad",	{HB_TAG('M','A','D',' ')}},	/* Madurese -> Madura */
-  {"mag",	{HB_TAG('M','A','G',' ')}},	/* Magahi */
-  {"mai",	{HB_TAG('M','T','H',' ')}},	/* Maithili */
-  {"mak",	{HB_TAG('M','K','R',' ')}},	/* Makasar */
-  {"mam",	{HB_TAG('M','A','M',' ')}},	/* Mam */
-  {"man",	{HB_TAG('M','N','K',' ')}},	/* Mandingo [macrolanguage] -> Maninka */
-  {"max",	{HB_TAG('M','L','Y',' ')}},	/* North Moluccan Malay -> Malay */
-  {"mbo",	{HB_TAG('M','B','O',' ')}},	/* Mbo (Cameroon) */
-  {"mct",	{HB_TAG('B','T','I',' ')}},	/* Mengisa -> Beti */
-  {"mdf",	{HB_TAG('M','O','K',' ')}},	/* Moksha */
-  {"mdr",	{HB_TAG('M','D','R',' ')}},	/* Mandar */
-  {"mdy",	{HB_TAG('M','L','E',' ')}},	/* Male (Ethiopia) */
-  {"men",	{HB_TAG('M','D','E',' ')}},	/* Mende (Sierra Leone) */
-  {"meo",	{HB_TAG('M','L','Y',' ')}},	/* Kedah Malay -> Malay */
-  {"mer",	{HB_TAG('M','E','R',' ')}},	/* Meru */
-  {"mfa",	{HB_TAG('M','F','A',' ')}},	/* Pattani Malay */
-  {"mfb",	{HB_TAG('M','L','Y',' ')}},	/* Bangka -> Malay */
-  {"mfe",	{HB_TAG('M','F','E',' ')}},	/* Morisyen */
-  {"mg",	{HB_TAG('M','L','G',' ')}},	/* Malagasy [macrolanguage] */
-  {"mh",	{HB_TAG('M','A','H',' ')}},	/* Marshallese */
-  {"mhr",	{HB_TAG('L','M','A',' ')}},	/* Eastern Mari -> Low Mari */
-  {"mhv",	{HB_TAG('A','R','K',' ')}},	/* Arakanese (retired code) -> Rakhine */
-  {"mi",	{HB_TAG('M','R','I',' ')}},	/* Maori */
-  {"min",	{HB_TAG('M','I','N',' ')}},	/* Minangkabau */
-  {"mk",	{HB_TAG('M','K','D',' ')}},	/* Macedonian */
-  {"mku",	{HB_TAG('M','N','K',' ')}},	/* Konyanka Maninka -> Maninka */
-  {"mkw",	{HB_TAG('M','K','W',' ')}},	/* Kituba (Congo) */
-  {"ml",	{HB_TAG('M','A','L',' '),	/* Malayalam -> Malayalam Traditional */
-		 HB_TAG('M','L','R',' ')}},	/* Malayalam -> Malayalam Reformed */
-  {"mlq",	{HB_TAG('M','L','N',' '),	/* Western Maninkakan -> Malinke */
-		 HB_TAG('M','N','K',' ')}},	/* Western Maninkakan -> Maninka */
-  {"mmr",	{HB_TAG('H','M','N',' ')}},	/* Western Xiangxi Miao -> Hmong */
-  {"mn",	{HB_TAG('M','N','G',' ')}},	/* Mongolian [macrolanguage] */
-  {"mnc",	{HB_TAG('M','C','H',' ')}},	/* Manchu */
-  {"mni",	{HB_TAG('M','N','I',' ')}},	/* Manipuri */
-  {"mnk",	{HB_TAG('M','N','D',' '),	/* Mandinka */
-		 HB_TAG('M','N','K',' ')}},	/* Mandinka -> Maninka */
-  {"mnp",	{HB_TAG('Z','H','S',' ')}},	/* Min Bei Chinese -> Chinese Simplified */
-  {"mns",	{HB_TAG('M','A','N',' ')}},	/* Mansi */
-  {"mnw",	{HB_TAG('M','O','N',' ')}},	/* Mon */
-  {"mo",	{HB_TAG('M','O','L',' ')}},	/* Moldavian (retired code) */
-  {"moh",	{HB_TAG('M','O','H',' ')}},	/* Mohawk */
-  {"mos",	{HB_TAG('M','O','S',' ')}},	/* Mossi */
-  {"mpe",	{HB_TAG('M','A','J',' ')}},	/* Majang */
-  {"mqg",	{HB_TAG('M','L','Y',' ')}},	/* Kota Bangun Kutai Malay -> Malay */
-  {"mr",	{HB_TAG('M','A','R',' ')}},	/* Marathi */
-  {"mrh",	{HB_TAG('Q','I','N',' ')}},	/* Mara Chin -> Chin */
-  {"mrj",	{HB_TAG('H','M','A',' ')}},	/* Western Mari -> High Mari */
-  {"ms",	{HB_TAG('M','L','Y',' ')}},	/* Malay [macrolanguage] */
-  {"msc",	{HB_TAG('M','N','K',' ')}},	/* Sankaran Maninka -> Maninka */
-  {"msh",	{HB_TAG('M','L','G',' ')}},	/* Masikoro Malagasy -> Malagasy */
-  {"msi",	{HB_TAG('M','L','Y',' ')}},	/* Sabah Malay -> Malay */
-  {"mt",	{HB_TAG('M','T','S',' ')}},	/* Maltese */
-  {"mtr",	{HB_TAG('M','A','W',' ')}},	/* Mewari -> Marwari */
-  {"mui",	{HB_TAG('M','L','Y',' ')}},	/* Musi -> Malay */
-  {"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 */
-  {"mvb",	{HB_TAG('A','T','H',' ')}},	/* Mattole -> Athapaskan */
-  {"mve",	{HB_TAG('M','A','W',' ')}},	/* Marwari (Pakistan) */
-  {"mvf",	{HB_TAG('M','N','G',' ')}},	/* Peripheral Mongolian -> Mongolian */
-  {"mwk",	{HB_TAG('M','N','K',' ')}},	/* Kita Maninkakan -> Maninka */
-  {"mwl",	{HB_TAG('M','W','L',' ')}},	/* Mirandese */
-  {"mwr",	{HB_TAG('M','A','W',' ')}},	/* Marwari [macrolanguage] */
-  {"mww",	{HB_TAG('M','W','W',' ')}},	/* Hmong Daw */
-  {"my",	{HB_TAG('B','R','M',' ')}},	/* Burmese */
-  {"mym",	{HB_TAG('M','E','N',' ')}},	/* Me’en */
-  {"myn",	{HB_TAG('M','Y','N',' ')}},	/* Mayan [family] */
-  {"myq",	{HB_TAG('M','N','K',' ')}},	/* Forest Maninka (retired code) -> Maninka */
-  {"myv",	{HB_TAG('E','R','Z',' ')}},	/* Erzya */
-  {"mzn",	{HB_TAG('M','Z','N',' ')}},	/* Mazanderani */
-  {"na",	{HB_TAG('N','A','U',' ')}},	/* Nauru -> Nauruan */
-  {"nag",	{HB_TAG('N','A','G',' ')}},	/* Naga Pidgin -> Naga-Assamese */
-  {"nah",	{HB_TAG('N','A','H',' ')}},	/* Nahuatl [family] */
-  {"nan",	{HB_TAG('Z','H','S',' ')}},	/* Min Nan Chinese -> Chinese Simplified */
-  {"nap",	{HB_TAG('N','A','P',' ')}},	/* Neapolitan */
-  {"nb",	{HB_TAG('N','O','R',' ')}},	/* Norwegian Bokmål -> Norwegian */
-  {"nd",	{HB_TAG('N','D','B',' ')}},	/* North Ndebele -> Ndebele */
-  {"ndc",	{HB_TAG('N','D','C',' ')}},	/* Ndau */
-  {"nds",	{HB_TAG('N','D','S',' ')}},	/* Low Saxon */
-  {"ne",	{HB_TAG('N','E','P',' ')}},	/* Nepali [macrolanguage] */
-  {"new",	{HB_TAG('N','E','W',' ')}},	/* Newari */
-  {"ng",	{HB_TAG('N','D','G',' ')}},	/* Ndonga */
-  {"nga",	{HB_TAG('N','G','A',' ')}},	/* Ngbaka */
-  {"ngl",	{HB_TAG('L','M','W',' ')}},	/* Lomwe */
-  {"ngo",	{HB_TAG('S','X','T',' ')}},	/* Ngoni -> Sutu */
-  {"nhd",	{HB_TAG('G','U','A',' ')}},	/* Chiripá -> Guarani */
-  {"niq",	{HB_TAG('K','A','L',' ')}},	/* Nandi -> Kalenjin */
-  {"niu",	{HB_TAG('N','I','U',' ')}},	/* Niuean */
-  {"niv",	{HB_TAG('G','I','L',' ')}},	/* Gilyak */
-  {"njz",	{HB_TAG('N','I','S',' ')}},	/* Nyishi -> Nisi */
-  {"nl",	{HB_TAG('N','L','D',' ')}},	/* Dutch */
-  {"nle",	{HB_TAG('L','U','H',' ')}},	/* East Nyala -> Luyia */
-  {"nn",	{HB_TAG('N','Y','N',' ')}},	/* Norwegian Nynorsk (Nynorsk, Norwegian) */
-  {"no",	{HB_TAG('N','O','R',' ')}},	/* Norwegian [macrolanguage] */
-  {"nod",	{HB_TAG('N','T','A',' ')}},	/* Northern Thai -> Northern Tai */
-  {"noe",	{HB_TAG('N','O','E',' ')}},	/* Nimadi */
-  {"nog",	{HB_TAG('N','O','G',' ')}},	/* Nogai */
-  {"nov",	{HB_TAG('N','O','V',' ')}},	/* Novial */
-  {"npi",	{HB_TAG('N','E','P',' ')}},	/* Nepali */
-  {"nqo",	{HB_TAG('N','K','O',' ')}},	/* N’Ko */
-  {"nr",	{HB_TAG('N','D','B',' ')}},	/* South Ndebele -> Ndebele */
-  {"nsk",	{HB_TAG('N','A','S',' ')}},	/* Naskapi */
-  {"nso",	{HB_TAG('N','S','O',' ')}},	/* Pedi -> Sotho, Northern */
-  {"nv",	{HB_TAG('N','A','V',' '),	/* Navajo */
-		 HB_TAG('A','T','H',' ')}},	/* Navajo -> Athapaskan */
-  {"ny",	{HB_TAG('C','H','I',' ')}},	/* Chichewa (Chewa, Nyanja) */
-  {"nyd",	{HB_TAG('L','U','H',' ')}},	/* Nyore -> Luyia */
-  {"nym",	{HB_TAG('N','Y','M',' ')}},	/* Nyamwezi */
-  {"nyn",	{HB_TAG('N','K','L',' ')}},	/* Nyankole */
-  {"nza",	{HB_TAG('N','Z','A',' ')}},	/* Tigon Mbembe -> Mbembe Tigon */
-  {"oc",	{HB_TAG('O','C','I',' ')}},	/* Occitan (post 1500) */
-  {"oj",	{HB_TAG('O','J','B',' ')}},	/* Ojibwa [macrolanguage] -> Ojibway */
-  {"ojb",	{HB_TAG('O','J','B',' ')}},	/* Northwestern Ojibwa -> Ojibway */
-  {"ojc",	{HB_TAG('O','J','B',' ')}},	/* Central Ojibwa -> Ojibway */
-  {"ojg",	{HB_TAG('O','J','B',' ')}},	/* Eastern Ojibwa -> Ojibway */
-  {"ojs",	{HB_TAG('O','C','R',' ')}},	/* Severn Ojibwa -> Oji-Cree */
-  {"ojw",	{HB_TAG('O','J','B',' ')}},	/* Western Ojibwa -> Ojibway */
-  {"oki",	{HB_TAG('K','A','L',' ')}},	/* Okiek -> Kalenjin */
-  {"okm",	{HB_TAG('K','O','H',' ')}},	/* Middle Korean (10th-16th cent.) -> Korean Old Hangul */
-  {"om",	{HB_TAG('O','R','O',' ')}},	/* Oromo [macrolanguage] */
-  {"or",	{HB_TAG('O','R','I',' ')}},	/* Odia (formerly Oriya) [macrolanguage] */
-  {"orc",	{HB_TAG('O','R','O',' ')}},	/* Orma -> Oromo */
-  {"orn",	{HB_TAG('M','L','Y',' ')}},	/* Orang Kanaq -> Malay */
-  {"ors",	{HB_TAG('M','L','Y',' ')}},	/* Orang Seletar -> Malay */
-  {"ory",	{HB_TAG('O','R','I',' ')}},	/* Odia (formerly Oriya) */
-  {"os",	{HB_TAG('O','S','S',' ')}},	/* Ossetian */
-  {"otw",	{HB_TAG('O','J','B',' ')}},	/* Ottawa -> Ojibway */
-  {"pa",	{HB_TAG('P','A','N',' ')}},	/* Punjabi */
-  {"pag",	{HB_TAG('P','A','G',' ')}},	/* Pangasinan */
-  {"pam",	{HB_TAG('P','A','M',' ')}},	/* Pampanga -> Pampangan */
-  {"pap",	{HB_TAG('P','A','P','0')}},	/* Papiamento -> Papiamentu */
-  {"pau",	{HB_TAG('P','A','U',' ')}},	/* Palauan */
-  {"pbt",	{HB_TAG('P','A','S',' ')}},	/* Southern Pashto -> Pashto */
-  {"pbu",	{HB_TAG('P','A','S',' ')}},	/* Northern Pashto -> Pashto */
-  {"pcc",	{HB_TAG('P','C','C',' ')}},	/* Bouyei */
-  {"pcd",	{HB_TAG('P','C','D',' ')}},	/* Picard */
-  {"pce",	{HB_TAG('P','L','G',' ')}},	/* Ruching Palaung -> Palaung */
-  {"pck",	{HB_TAG('Q','I','N',' ')}},	/* Paite Chin -> Chin */
-  {"pdc",	{HB_TAG('P','D','C',' ')}},	/* Pennsylvania German */
-  {"pel",	{HB_TAG('M','L','Y',' ')}},	/* Pekal -> Malay */
-  {"pes",	{HB_TAG('F','A','R',' ')}},	/* Iranian Persian -> Persian */
-  {"pga",	{HB_TAG('A','R','A',' ')}},	/* Sudanese Creole Arabic -> Arabic */
-  {"phk",	{HB_TAG('P','H','K',' ')}},	/* Phake */
-  {"pi",	{HB_TAG('P','A','L',' ')}},	/* Pali */
-  {"pih",	{HB_TAG('P','I','H',' ')}},	/* Pitcairn-Norfolk -> Norfolk */
-  {"pko",	{HB_TAG('K','A','L',' ')}},	/* Pökoot -> Kalenjin */
-  {"pl",	{HB_TAG('P','L','K',' ')}},	/* Polish */
-  {"pll",	{HB_TAG('P','L','G',' ')}},	/* Shwe Palaung -> Palaung */
-  {"plp",	{HB_TAG('P','A','P',' ')}},	/* Palpa */
-  {"plt",	{HB_TAG('M','L','G',' ')}},	/* Plateau Malagasy -> Malagasy */
-  {"pms",	{HB_TAG('P','M','S',' ')}},	/* Piemontese */
-  {"pnb",	{HB_TAG('P','N','B',' ')}},	/* Western Panjabi */
-  {"poh",	{HB_TAG('P','O','H',' ')}},	/* Poqomchi' -> Pocomchi */
-  {"pon",	{HB_TAG('P','O','N',' ')}},	/* Pohnpeian */
-  {"ppa",	{HB_TAG('B','A','G',' ')}},	/* Pao (retired code) -> Baghelkhandi */
-  {"pro",	{HB_TAG('P','R','O',' ')}},	/* Old Provençal (to 1500) -> Provençal / Old Provençal */
-  {"prs",	{HB_TAG('D','R','I',' ')}},	/* Dari */
-  {"ps",	{HB_TAG('P','A','S',' ')}},	/* Pashto [macrolanguage] */
-  {"pse",	{HB_TAG('M','L','Y',' ')}},	/* Central Malay -> Malay */
-  {"pst",	{HB_TAG('P','A','S',' ')}},	/* Central Pashto -> Pashto */
-  {"pt",	{HB_TAG('P','T','G',' ')}},	/* Portuguese */
-  {"pwo",	{HB_TAG('P','W','O',' ')}},	/* Pwo Western Karen -> Western Pwo Karen */
-  {"qu",	{HB_TAG('Q','U','Z',' ')}},	/* Quechua [macrolanguage] */
-  {"qub",	{HB_TAG('Q','W','H',' ')}},	/* Huallaga Huánuco Quechua -> Quechua (Peru) */
-  {"quc",	{HB_TAG('Q','U','C',' ')}},	/* K’iche’ */
-  {"qud",	{HB_TAG('Q','V','I',' ')}},	/* Calderón Highland Quichua -> Quechua (Ecuador) */
-  {"quf",	{HB_TAG('Q','U','Z',' ')}},	/* Lambayeque Quechua -> Quechua */
-  {"qug",	{HB_TAG('Q','V','I',' ')}},	/* Chimborazo Highland Quichua -> Quechua (Ecuador) */
-  {"quh",	{HB_TAG('Q','U','H',' ')}},	/* South Bolivian Quechua -> Quechua (Bolivia) */
-  {"quk",	{HB_TAG('Q','U','Z',' ')}},	/* Chachapoyas Quechua -> Quechua */
-  {"qul",	{HB_TAG('Q','U','Z',' ')}},	/* North Bolivian Quechua -> Quechua */
-  {"qup",	{HB_TAG('Q','V','I',' ')}},	/* Southern Pastaza Quechua -> Quechua (Ecuador) */
-  {"qur",	{HB_TAG('Q','W','H',' ')}},	/* Yanahuanca Pasco Quechua -> Quechua (Peru) */
-  {"qus",	{HB_TAG('Q','U','H',' ')}},	/* Santiago del Estero Quichua -> Quechua (Bolivia) */
-  {"quw",	{HB_TAG('Q','V','I',' ')}},	/* Tena Lowland Quichua -> Quechua (Ecuador) */
-  {"qux",	{HB_TAG('Q','W','H',' ')}},	/* Yauyos Quechua -> Quechua (Peru) */
-  {"quy",	{HB_TAG('Q','U','Z',' ')}},	/* Ayacucho Quechua -> Quechua */
-  {"quz",	{HB_TAG('Q','U','Z',' ')}},	/* Cusco Quechua -> Quechua */
-  {"qva",	{HB_TAG('Q','W','H',' ')}},	/* Ambo-Pasco Quechua -> Quechua (Peru) */
-  {"qvc",	{HB_TAG('Q','U','Z',' ')}},	/* Cajamarca Quechua -> Quechua */
-  {"qve",	{HB_TAG('Q','U','Z',' ')}},	/* Eastern Apurímac Quechua -> Quechua */
-  {"qvh",	{HB_TAG('Q','W','H',' ')}},	/* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */
-  {"qvi",	{HB_TAG('Q','V','I',' ')}},	/* Imbabura Highland Quichua -> Quechua (Ecuador) */
-  {"qvj",	{HB_TAG('Q','V','I',' ')}},	/* Loja Highland Quichua -> Quechua (Ecuador) */
-  {"qvl",	{HB_TAG('Q','W','H',' ')}},	/* Cajatambo North Lima Quechua -> Quechua (Peru) */
-  {"qvm",	{HB_TAG('Q','W','H',' ')}},	/* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */
-  {"qvn",	{HB_TAG('Q','W','H',' ')}},	/* North Junín Quechua -> Quechua (Peru) */
-  {"qvo",	{HB_TAG('Q','V','I',' ')}},	/* Napo Lowland Quechua -> Quechua (Ecuador) */
-  {"qvp",	{HB_TAG('Q','W','H',' ')}},	/* Pacaraos Quechua -> Quechua (Peru) */
-  {"qvs",	{HB_TAG('Q','U','Z',' ')}},	/* San Martín Quechua -> Quechua */
-  {"qvw",	{HB_TAG('Q','W','H',' ')}},	/* Huaylla Wanca Quechua -> Quechua (Peru) */
-  {"qvz",	{HB_TAG('Q','V','I',' ')}},	/* Northern Pastaza Quichua -> Quechua (Ecuador) */
-  {"qwa",	{HB_TAG('Q','W','H',' ')}},	/* Corongo Ancash Quechua -> Quechua (Peru) */
-  {"qwc",	{HB_TAG('Q','U','Z',' ')}},	/* Classical Quechua -> Quechua */
-  {"qwh",	{HB_TAG('Q','W','H',' ')}},	/* Huaylas Ancash Quechua -> Quechua (Peru) */
-  {"qws",	{HB_TAG('Q','W','H',' ')}},	/* Sihuas Ancash Quechua -> Quechua (Peru) */
-  {"qxa",	{HB_TAG('Q','W','H',' ')}},	/* Chiquián Ancash Quechua -> Quechua (Peru) */
-  {"qxc",	{HB_TAG('Q','W','H',' ')}},	/* Chincha Quechua -> Quechua (Peru) */
-  {"qxh",	{HB_TAG('Q','W','H',' ')}},	/* Panao Huánuco Quechua -> Quechua (Peru) */
-  {"qxl",	{HB_TAG('Q','V','I',' ')}},	/* Salasaca Highland Quichua -> Quechua (Ecuador) */
-  {"qxn",	{HB_TAG('Q','W','H',' ')}},	/* Northern Conchucos Ancash Quechua -> Quechua (Peru) */
-  {"qxo",	{HB_TAG('Q','W','H',' ')}},	/* Southern Conchucos Ancash Quechua -> Quechua (Peru) */
-  {"qxp",	{HB_TAG('Q','U','Z',' ')}},	/* Puno Quechua -> Quechua */
-  {"qxr",	{HB_TAG('Q','V','I',' ')}},	/* Cañar Highland Quichua -> Quechua (Ecuador) */
-  {"qxt",	{HB_TAG('Q','W','H',' ')}},	/* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */
-  {"qxu",	{HB_TAG('Q','U','Z',' ')}},	/* Arequipa-La Unión Quechua -> Quechua */
-  {"qxw",	{HB_TAG('Q','W','H',' ')}},	/* Jauja Wanca Quechua -> Quechua (Peru) */
-  {"rag",	{HB_TAG('L','U','H',' ')}},	/* Logooli -> Luyia */
-  {"raj",	{HB_TAG('R','A','J',' ')}},	/* Rajasthani [macrolanguage] */
-  {"rar",	{HB_TAG('R','A','R',' ')}},	/* Rarotongan */
-  {"rbb",	{HB_TAG('P','L','G',' ')}},	/* Rumai Palaung -> Palaung */
-  {"rbl",	{HB_TAG('B','I','K',' ')}},	/* Miraya Bikol -> Bikol */
-  {"rej",	{HB_TAG('R','E','J',' ')}},	/* Rejang */
-  {"ria",	{HB_TAG('R','I','A',' ')}},	/* Riang (India) */
-  {"rif",	{HB_TAG('R','I','F',' ')}},	/* Tarifit */
-  {"rit",	{HB_TAG('R','I','T',' ')}},	/* Ritarungo */
-  {"rki",	{HB_TAG('A','R','K',' ')}},	/* Rakhine */
-  {"rkw",	{HB_TAG('R','K','W',' ')}},	/* Arakwal */
-  {"rm",	{HB_TAG('R','M','S',' ')}},	/* Romansh */
-  {"rmc",	{HB_TAG('R','O','Y',' ')}},	/* Carpathian Romani -> Romany */
-  {"rmf",	{HB_TAG('R','O','Y',' ')}},	/* Kalo Finnish Romani -> Romany */
-  {"rml",	{HB_TAG('R','O','Y',' ')}},	/* Baltic Romani -> Romany */
-  {"rmn",	{HB_TAG('R','O','Y',' ')}},	/* Balkan Romani -> Romany */
-  {"rmo",	{HB_TAG('R','O','Y',' ')}},	/* Sinte Romani -> Romany */
-  {"rmw",	{HB_TAG('R','O','Y',' ')}},	/* Welsh Romani -> Romany */
-  {"rmy",	{HB_TAG('R','M','Y',' ')}},	/* Vlax Romani */
-  {"rmz",	{HB_TAG('A','R','K',' ')}},	/* Marma -> Rakhine */
-  {"rn",	{HB_TAG('R','U','N',' ')}},	/* Rundi */
-  {"rnl",	{HB_TAG('H','A','L',' ')}},	/* Ranglong -> Halam (Falam Chin) */
-  {"ro",	{HB_TAG('R','O','M',' ')}},	/* Romanian */
-  {"rom",	{HB_TAG('R','O','Y',' ')}},	/* Romany [macrolanguage] */
-  {"rtm",	{HB_TAG('R','T','M',' ')}},	/* Rotuman */
-  {"ru",	{HB_TAG('R','U','S',' ')}},	/* Russian */
-  {"rue",	{HB_TAG('R','S','Y',' ')}},	/* Rusyn */
-  {"rup",	{HB_TAG('R','U','P',' ')}},	/* Aromanian */
-  {"rw",	{HB_TAG('R','U','A',' ')}},	/* Kinyarwanda */
-  {"rwr",	{HB_TAG('M','A','W',' ')}},	/* Marwari (India) */
-  {"sa",	{HB_TAG('S','A','N',' ')}},	/* Sanskrit */
-  {"sah",	{HB_TAG('Y','A','K',' ')}},	/* Yakut -> Sakha */
-  {"sam",	{HB_TAG('P','A','A',' ')}},	/* Samaritan Aramaic -> Palestinian Aramaic */
-  {"sas",	{HB_TAG('S','A','S',' ')}},	/* Sasak */
-  {"sat",	{HB_TAG('S','A','T',' ')}},	/* Santali */
-  {"sc",	{HB_TAG('S','R','D',' ')}},	/* Sardinian [macrolanguage] */
-  {"sck",	{HB_TAG('S','A','D',' ')}},	/* Sadri */
-  {"scn",	{HB_TAG('S','C','N',' ')}},	/* Sicilian */
-  {"sco",	{HB_TAG('S','C','O',' ')}},	/* Scots */
-  {"scs",	{HB_TAG('S','C','S',' '),	/* North Slavey */
-		 HB_TAG('S','L','A',' '),	/* North Slavey -> Slavey */
-		 HB_TAG('A','T','H',' ')}},	/* North Slavey -> Athapaskan */
-  {"sd",	{HB_TAG('S','N','D',' ')}},	/* Sindhi */
-  {"sdc",	{HB_TAG('S','R','D',' ')}},	/* Sassarese Sardinian -> Sardinian */
-  {"sdh",	{HB_TAG('K','U','R',' ')}},	/* Southern Kurdish -> Kurdish */
-  {"sdn",	{HB_TAG('S','R','D',' ')}},	/* Gallurese Sardinian -> Sardinian */
-  {"se",	{HB_TAG('N','S','M',' ')}},	/* Northern Sami */
-  {"seh",	{HB_TAG('S','N','A',' ')}},	/* Sena */
-  {"sek",	{HB_TAG('A','T','H',' ')}},	/* Sekani -> Athapaskan */
-  {"sel",	{HB_TAG('S','E','L',' ')}},	/* Selkup */
-  {"sez",	{HB_TAG('Q','I','N',' ')}},	/* Senthang Chin -> Chin */
-  {"sfm",	{HB_TAG('H','M','N',' ')}},	/* Small Flowery Miao -> Hmong */
-  {"sg",	{HB_TAG('S','G','O',' ')}},	/* Sango */
-  {"sga",	{HB_TAG('S','G','A',' ')}},	/* Old Irish (to 900) */
-  {"sgc",	{HB_TAG('K','A','L',' ')}},	/* Kipsigis -> Kalenjin */
-  {"sgs",	{HB_TAG('S','G','S',' ')}},	/* Samogitian */
-  {"sgw",	{HB_TAG('C','H','G',' '),	/* Sebat Bet Gurage -> Chaha Gurage */
-		 HB_TAG('S','G','W',' ')}},	/* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */
-  {"shi",	{HB_TAG('S','H','I',' ')}},	/* Tachelhit */
-  {"shn",	{HB_TAG('S','H','N',' ')}},	/* Shan */
-  {"shu",	{HB_TAG('A','R','A',' ')}},	/* Chadian Arabic -> Arabic */
-  {"si",	{HB_TAG('S','N','H',' ')}},	/* Sinhala (Sinhalese) */
-  {"sid",	{HB_TAG('S','I','D',' ')}},	/* Sidamo */
-  {"sjd",	{HB_TAG('K','S','M',' ')}},	/* Kildin Sami */
-  {"sjo",	{HB_TAG('S','I','B',' ')}},	/* Xibe -> Sibe */
-  {"sk",	{HB_TAG('S','K','Y',' ')}},	/* Slovak */
-  {"skg",	{HB_TAG('M','L','G',' ')}},	/* Sakalava Malagasy -> Malagasy */
-  {"skr",	{HB_TAG('S','R','K',' ')}},	/* Saraiki */
-  {"sl",	{HB_TAG('S','L','V',' ')}},	/* Slovenian */
-  {"sm",	{HB_TAG('S','M','O',' ')}},	/* Samoan */
-  {"sma",	{HB_TAG('S','S','M',' ')}},	/* Southern Sami */
-  {"smj",	{HB_TAG('L','S','M',' ')}},	/* Lule Sami */
-  {"smn",	{HB_TAG('I','S','M',' ')}},	/* Inari Sami */
-  {"sms",	{HB_TAG('S','K','S',' ')}},	/* Skolt Sami */
-  {"sn",	{HB_TAG('S','N','A','0')}},	/* Shona */
-  {"snk",	{HB_TAG('S','N','K',' ')}},	/* Soninke */
-  {"so",	{HB_TAG('S','M','L',' ')}},	/* Somali */
-  {"sop",	{HB_TAG('S','O','P',' ')}},	/* Songe */
-  {"spv",	{HB_TAG('O','R','I',' ')}},	/* Sambalpuri -> Odia (formerly Oriya) */
-  {"spy",	{HB_TAG('K','A','L',' ')}},	/* Sabaot -> Kalenjin */
-  {"sq",	{HB_TAG('S','Q','I',' ')}},	/* Albanian [macrolanguage] */
-  {"sr",	{HB_TAG('S','R','B',' ')}},	/* Serbian */
-  {"src",	{HB_TAG('S','R','D',' ')}},	/* Logudorese Sardinian -> Sardinian */
-  {"sro",	{HB_TAG('S','R','D',' ')}},	/* Campidanese Sardinian -> Sardinian */
-  {"srr",	{HB_TAG('S','R','R',' ')}},	/* Serer */
-  {"srs",	{HB_TAG('A','T','H',' ')}},	/* Sarsi -> Athapaskan */
-  {"ss",	{HB_TAG('S','W','Z',' ')}},	/* Swati */
-  {"ssh",	{HB_TAG('A','R','A',' ')}},	/* Shihhi Arabic -> Arabic */
-  {"st",	{HB_TAG('S','O','T',' ')}},	/* Southern Sotho -> Sotho, Southern */
-  {"stq",	{HB_TAG('S','T','Q',' ')}},	/* Saterfriesisch -> Saterland Frisian */
-  {"stv",	{HB_TAG('S','I','G',' ')}},	/* Silt'e -> Silte Gurage */
-  {"su",	{HB_TAG('S','U','N',' ')}},	/* Sundanese */
-  {"suk",	{HB_TAG('S','U','K',' ')}},	/* Sukuma */
-  {"suq",	{HB_TAG('S','U','R',' ')}},	/* Suri */
-  {"sv",	{HB_TAG('S','V','E',' ')}},	/* Swedish */
-  {"sva",	{HB_TAG('S','V','A',' ')}},	/* Svan */
-  {"sw",	{HB_TAG('S','W','K',' ')}},	/* Swahili [macrolanguage] */
-  {"swb",	{HB_TAG('C','M','R',' ')}},	/* Maore Comorian -> Comorian */
-  {"swc",	{HB_TAG('S','W','K',' ')}},	/* Congo Swahili -> Swahili */
-  {"swh",	{HB_TAG('S','W','K',' ')}},	/* Swahili */
-  {"swv",	{HB_TAG('M','A','W',' ')}},	/* Shekhawati -> Marwari */
-  {"sxu",	{HB_TAG('S','X','U',' ')}},	/* Upper Saxon */
-  {"syc",	{HB_TAG('S','Y','R',' ')}},	/* Classical Syriac -> Syriac */
-  {"syl",	{HB_TAG('S','Y','L',' ')}},	/* Sylheti */
-  {"syr",	{HB_TAG('S','Y','R',' ')}},	/* Syriac [macrolanguage] */
-  {"szl",	{HB_TAG('S','Z','L',' ')}},	/* Silesian */
-  {"ta",	{HB_TAG('T','A','M',' ')}},	/* Tamil */
-  {"taa",	{HB_TAG('A','T','H',' ')}},	/* Lower Tanana -> Athapaskan */
-  {"tab",	{HB_TAG('T','A','B',' ')}},	/* Tabassaran -> Tabasaran */
-  {"taq",	{HB_TAG('T','M','H',' ')}},	/* Tamasheq -> Tamashek */
-  {"tau",	{HB_TAG('A','T','H',' ')}},	/* Upper Tanana -> Athapaskan */
-  {"tcb",	{HB_TAG('A','T','H',' ')}},	/* Tanacross -> Athapaskan */
-  {"tce",	{HB_TAG('A','T','H',' ')}},	/* Southern Tutchone -> Athapaskan */
-  {"tcp",	{HB_TAG('Q','I','N',' ')}},	/* Tawr Chin -> Chin */
-  {"tcy",	{HB_TAG('T','U','L',' ')}},	/* Tulu -> Tumbuka */
-  {"tcz",	{HB_TAG('Q','I','N',' ')}},	/* Thado Chin -> Chin */
-  {"tdd",	{HB_TAG('T','D','D',' ')}},	/* Tai Nüa -> Dehong Dai */
-  {"tdx",	{HB_TAG('M','L','G',' ')}},	/* Tandroy-Mahafaly Malagasy -> Malagasy */
-  {"te",	{HB_TAG('T','E','L',' ')}},	/* Telugu */
-  {"tec",	{HB_TAG('K','A','L',' ')}},	/* Terik -> Kalenjin */
-  {"tem",	{HB_TAG('T','M','N',' ')}},	/* Timne -> Temne */
-  {"tet",	{HB_TAG('T','E','T',' ')}},	/* Tetum */
-  {"tfn",	{HB_TAG('A','T','H',' ')}},	/* Tanaina -> Athapaskan */
-  {"tg",	{HB_TAG('T','A','J',' ')}},	/* Tajik -> Tajiki */
-  {"tgj",	{HB_TAG('N','I','S',' ')}},	/* Tagin -> Nisi */
-  {"tgx",	{HB_TAG('A','T','H',' ')}},	/* Tagish -> Athapaskan */
-  {"th",	{HB_TAG('T','H','A',' ')}},	/* Thai */
-  {"tht",	{HB_TAG('A','T','H',' ')}},	/* Tahltan -> Athapaskan */
-  {"thv",	{HB_TAG('T','M','H',' ')}},	/* Tahaggart Tamahaq -> Tamashek */
-  {"thz",	{HB_TAG('T','M','H',' ')}},	/* Tayart Tamajeq -> Tamashek */
-  {"ti",	{HB_TAG('T','G','Y',' ')}},	/* Tigrinya */
-  {"tig",	{HB_TAG('T','G','R',' ')}},	/* Tigre */
-  {"tiv",	{HB_TAG('T','I','V',' ')}},	/* Tiv */
-  {"tk",	{HB_TAG('T','K','M',' ')}},	/* Turkmen */
-  {"tkg",	{HB_TAG('M','L','G',' ')}},	/* Tesaka Malagasy -> Malagasy */
-  {"tl",	{HB_TAG('T','G','L',' ')}},	/* Tagalog */
-  {"tmh",	{HB_TAG('T','M','H',' ')}},	/* Tamashek [macrolanguage] */
-  {"tmw",	{HB_TAG('M','L','Y',' ')}},	/* Temuan -> Malay */
-  {"tn",	{HB_TAG('T','N','A',' ')}},	/* Tswana */
-  {"tnf",	{HB_TAG('D','R','I',' ')}},	/* Tangshewi (retired code) -> Dari */
-  {"to",	{HB_TAG('T','G','N',' ')}},	/* Tonga (Tonga Islands) -> Tongan */
-  {"tod",	{HB_TAG('T','O','D','0')}},	/* Toma */
-  {"toi",	{HB_TAG('T','N','G',' ')}},	/* Tonga (Zambia) */
-  {"tol",	{HB_TAG('A','T','H',' ')}},	/* Tolowa -> Athapaskan */
-  {"tpi",	{HB_TAG('T','P','I',' ')}},	/* Tok Pisin */
-  {"tr",	{HB_TAG('T','R','K',' ')}},	/* Turkish */
-  {"tru",	{HB_TAG('T','U','A',' '),	/* Turoyo -> Turoyo Aramaic */
-		 HB_TAG('S','Y','R',' ')}},	/* Turoyo -> Syriac */
-  {"ts",	{HB_TAG('T','S','G',' ')}},	/* Tsonga */
-  {"tsj",	{HB_TAG('T','S','J',' ')}},	/* Tshangla */
-  {"tt",	{HB_TAG('T','A','T',' ')}},	/* Tatar */
-  {"ttm",	{HB_TAG('A','T','H',' ')}},	/* Northern Tutchone -> Athapaskan */
-  {"ttq",	{HB_TAG('T','M','H',' ')}},	/* Tawallammat Tamajaq -> Tamashek */
-  {"tum",	{HB_TAG('T','U','M',' ')}},	/* Tumbuka -> Tulu */
-  {"tuu",	{HB_TAG('A','T','H',' ')}},	/* Tututni -> Athapaskan */
-  {"tuy",	{HB_TAG('K','A','L',' ')}},	/* Tugen -> Kalenjin */
-  {"tvl",	{HB_TAG('T','V','L',' ')}},	/* Tuvalu */
-  {"tw",	{HB_TAG('T','W','I',' '),	/* Twi */
-		 HB_TAG('A','K','A',' ')}},	/* Twi -> Akan */
-  {"txc",	{HB_TAG('A','T','H',' ')}},	/* Tsetsaut -> Athapaskan */
-  {"txy",	{HB_TAG('M','L','G',' ')}},	/* Tanosy Malagasy -> Malagasy */
-  {"ty",	{HB_TAG('T','H','T',' ')}},	/* Tahitian */
-  {"tyv",	{HB_TAG('T','U','V',' ')}},	/* Tuvinian -> Tuvin */
-  {"tyz",	{HB_TAG('T','Y','Z',' ')}},	/* Tày */
-  {"tzm",	{HB_TAG('T','Z','M',' ')}},	/* Central Atlas Tamazight -> Tamazight */
-  {"tzo",	{HB_TAG('T','Z','O',' ')}},	/* Tzotzil */
-  {"ubl",	{HB_TAG('B','I','K',' ')}},	/* Buhi'non Bikol -> Bikol */
-  {"udm",	{HB_TAG('U','D','M',' ')}},	/* Udmurt */
-  {"ug",	{HB_TAG('U','Y','G',' ')}},	/* Uyghur */
-  {"uk",	{HB_TAG('U','K','R',' ')}},	/* Ukrainian */
-  {"umb",	{HB_TAG('U','M','B',' ')}},	/* Umbundu */
-  {"unr",	{HB_TAG('M','U','N',' ')}},	/* Mundari */
-  {"ur",	{HB_TAG('U','R','D',' ')}},	/* Urdu */
-  {"urk",	{HB_TAG('M','L','Y',' ')}},	/* Urak Lawoi' -> Malay */
-  {"uz",	{HB_TAG('U','Z','B',' ')}},	/* Uzbek [macrolanguage] */
-  {"uzn",	{HB_TAG('U','Z','B',' ')}},	/* Northern Uzbek -> Uzbek */
-  {"uzs",	{HB_TAG('U','Z','B',' ')}},	/* Southern Uzbek -> Uzbek */
-  {"ve",	{HB_TAG('V','E','N',' ')}},	/* Venda */
-  {"vec",	{HB_TAG('V','E','C',' ')}},	/* Venetian */
-  {"vi",	{HB_TAG('V','I','T',' ')}},	/* Vietnamese */
-  {"vkk",	{HB_TAG('M','L','Y',' ')}},	/* Kaur -> Malay */
-  {"vkt",	{HB_TAG('M','L','Y',' ')}},	/* Tenggarong Kutai Malay -> Malay */
-  {"vls",	{HB_TAG('F','L','E',' ')}},	/* Vlaams -> Dutch (Flemish) */
-  {"vmw",	{HB_TAG('M','A','K',' ')}},	/* Makhuwa */
-  {"vo",	{HB_TAG('V','O','L',' ')}},	/* Volapük */
-  {"vro",	{HB_TAG('V','R','O',' ')}},	/* Võro */
-  {"wa",	{HB_TAG('W','L','N',' ')}},	/* Walloon */
-  {"war",	{HB_TAG('W','A','R',' ')}},	/* Waray (Philippines) -> Waray-Waray */
-  {"wbm",	{HB_TAG('W','A',' ',' ')}},	/* Wa */
-  {"wbr",	{HB_TAG('W','A','G',' ')}},	/* Wagdi */
-  {"wlc",	{HB_TAG('C','M','R',' ')}},	/* Mwali Comorian -> Comorian */
-  {"wle",	{HB_TAG('S','I','G',' ')}},	/* Wolane -> Silte Gurage */
-  {"wlk",	{HB_TAG('A','T','H',' ')}},	/* Wailaki -> Athapaskan */
-  {"wni",	{HB_TAG('C','M','R',' ')}},	/* Ndzwani Comorian -> Comorian */
-  {"wo",	{HB_TAG('W','L','F',' ')}},	/* Wolof */
-  {"wry",	{HB_TAG('M','A','W',' ')}},	/* Merwari -> Marwari */
-  {"wsg",	{HB_TAG('G','O','N',' ')}},	/* Adilabad Gondi -> Gondi */
-  {"wtm",	{HB_TAG('W','T','M',' ')}},	/* Mewati */
-  {"wuu",	{HB_TAG('Z','H','S',' ')}},	/* Wu Chinese -> Chinese Simplified */
-  {"xal",	{HB_TAG('K','L','M',' '),	/* Kalmyk */
-		 HB_TAG('T','O','D',' ')}},	/* Kalmyk -> Todo */
-  {"xan",	{HB_TAG('S','E','K',' ')}},	/* Xamtanga -> Sekota */
-  {"xh",	{HB_TAG('X','H','S',' ')}},	/* Xhosa */
-  {"xjb",	{HB_TAG('X','J','B',' ')}},	/* Minjungbal -> Minjangbal */
-  {"xkf",	{HB_TAG('X','K','F',' ')}},	/* Khengkha */
-  {"xmm",	{HB_TAG('M','L','Y',' ')}},	/* Manado Malay -> Malay */
-  {"xmv",	{HB_TAG('M','L','G',' ')}},	/* Antankarana Malagasy -> Malagasy */
-  {"xmw",	{HB_TAG('M','L','G',' ')}},	/* Tsimihety Malagasy -> Malagasy */
-  {"xnr",	{HB_TAG('D','G','R',' ')}},	/* Kangri -> Dogri */
-  {"xog",	{HB_TAG('X','O','G',' ')}},	/* Soga */
-  {"xpe",	{HB_TAG('X','P','E',' ')}},	/* Liberia Kpelle -> Kpelle (Liberia) */
-  {"xsl",	{HB_TAG('S','S','L',' '),	/* South Slavey */
-		 HB_TAG('S','L','A',' '),	/* South Slavey -> Slavey */
-		 HB_TAG('A','T','H',' ')}},	/* South Slavey -> Athapaskan */
-  {"xst",	{HB_TAG('S','I','G',' ')}},	/* Silt'e (retired code) -> Silte Gurage */
-  {"xwo",	{HB_TAG('T','O','D',' ')}},	/* Written Oirat -> Todo */
-  {"yao",	{HB_TAG('Y','A','O',' ')}},	/* Yao */
-  {"yap",	{HB_TAG('Y','A','P',' ')}},	/* Yapese */
-  {"ybd",	{HB_TAG('A','R','K',' ')}},	/* Yangbye (retired code) -> Rakhine */
-  {"ydd",	{HB_TAG('J','I','I',' ')}},	/* Eastern Yiddish -> Yiddish */
-  {"yi",	{HB_TAG('J','I','I',' ')}},	/* Yiddish [macrolanguage] */
-  {"yih",	{HB_TAG('J','I','I',' ')}},	/* Western Yiddish -> Yiddish */
-  {"yo",	{HB_TAG('Y','B','A',' ')}},	/* Yoruba */
-  {"yos",	{HB_TAG('Q','I','N',' ')}},	/* Yos (retired code) -> Chin */
-  {"yrk",	{HB_TAG('T','N','E',' '),	/* Nenets -> Tundra Nenets */
-		 HB_TAG('F','N','E',' ')}},	/* Nenets -> Forest Nenets */
-  {"yue",	{HB_TAG('Z','H','H',' ')}},	/* Yue Chinese -> Chinese, Hong Kong SAR */
-  {"za",	{HB_TAG('Z','H','A',' ')}},	/* Zhuang [macrolanguage] */
-  {"zch",	{HB_TAG('Z','H','A',' ')}},	/* Central Hongshuihe Zhuang -> Zhuang */
-  {"zdj",	{HB_TAG('C','M','R',' ')}},	/* Ngazidja Comorian -> Comorian */
-  {"zea",	{HB_TAG('Z','E','A',' ')}},	/* Zeeuws -> Zealandic */
-  {"zeh",	{HB_TAG('Z','H','A',' ')}},	/* Eastern Hongshuihe Zhuang -> Zhuang */
-  {"zgb",	{HB_TAG('Z','H','A',' ')}},	/* Guibei Zhuang -> Zhuang */
-  {"zgh",	{HB_TAG('Z','G','H',' ')}},	/* Standard Moroccan Tamazight */
-  {"zgm",	{HB_TAG('Z','H','A',' ')}},	/* Minz Zhuang -> Zhuang */
-  {"zgn",	{HB_TAG('Z','H','A',' ')}},	/* Guibian Zhuang -> Zhuang */
-  {"zh",	{HB_TAG('Z','H','S',' ')}},	/* Chinese [macrolanguage] -> Chinese Simplified */
-  {"zhd",	{HB_TAG('Z','H','A',' ')}},	/* Dai Zhuang -> Zhuang */
-  {"zhn",	{HB_TAG('Z','H','A',' ')}},	/* Nong Zhuang -> Zhuang */
-  {"zlj",	{HB_TAG('Z','H','A',' ')}},	/* Liujiang Zhuang -> Zhuang */
-  {"zlm",	{HB_TAG('M','L','Y',' ')}},	/* Malay */
-  {"zln",	{HB_TAG('Z','H','A',' ')}},	/* Lianshan Zhuang -> Zhuang */
-  {"zlq",	{HB_TAG('Z','H','A',' ')}},	/* Liuqian Zhuang -> Zhuang */
-  {"zmi",	{HB_TAG('M','L','Y',' ')}},	/* Negeri Sembilan Malay -> Malay */
-  {"zne",	{HB_TAG('Z','N','D',' ')}},	/* Zande */
-  {"zom",	{HB_TAG('Q','I','N',' ')}},	/* Zou -> Chin */
-  {"zqe",	{HB_TAG('Z','H','A',' ')}},	/* Qiubei Zhuang -> Zhuang */
-  {"zsm",	{HB_TAG('M','L','Y',' ')}},	/* Standard Malay -> Malay */
-  {"zu",	{HB_TAG('Z','U','L',' ')}},	/* Zulu */
-  {"zum",	{HB_TAG('L','R','C',' ')}},	/* Kumzari -> Luri */
-  {"zyb",	{HB_TAG('Z','H','A',' ')}},	/* Yongbei Zhuang -> Zhuang */
-  {"zyg",	{HB_TAG('Z','H','A',' ')}},	/* Yang Zhuang -> Zhuang */
-  {"zyj",	{HB_TAG('Z','H','A',' ')}},	/* Youjiang Zhuang -> Zhuang */
-  {"zyn",	{HB_TAG('Z','H','A',' ')}},	/* Yongnan Zhuang -> Zhuang */
-  {"zza",	{HB_TAG('Z','Z','A',' ')}},	/* Zazaki [macrolanguage] */
-  {"zzj",	{HB_TAG('Z','H','A',' ')}},	/* Zuojiang Zhuang -> Zhuang */
+  {"aa",	HB_TAG('A','F','R',' ')},	/* Afar */
+  {"aae",	HB_TAG('S','Q','I',' ')},	/* Arbëreshë Albanian -> Albanian */
+  {"aao",	HB_TAG('A','R','A',' ')},	/* Algerian Saharan Arabic -> Arabic */
+  {"aat",	HB_TAG('S','Q','I',' ')},	/* Arvanitika Albanian -> Albanian */
+  {"ab",	HB_TAG('A','B','K',' ')},	/* Abkhazian */
+  {"abh",	HB_TAG('A','R','A',' ')},	/* Tajiki Arabic -> Arabic */
+  {"abq",	HB_TAG('A','B','A',' ')},	/* Abaza */
+  {"abv",	HB_TAG('A','R','A',' ')},	/* Baharna Arabic -> Arabic */
+  {"acf",	HB_TAG('F','A','N',' ')},	/* Saint Lucian Creole French -> French Antillean */
+/*{"ach",	HB_TAG('A','C','H',' ')},*/	/* Acoli -> Acholi */
+  {"acm",	HB_TAG('A','R','A',' ')},	/* Mesopotamian Arabic -> Arabic */
+  {"acq",	HB_TAG('A','R','A',' ')},	/* Ta'izzi-Adeni Arabic -> Arabic */
+/*{"acr",	HB_TAG('A','C','R',' ')},*/	/* Achi */
+  {"acw",	HB_TAG('A','R','A',' ')},	/* Hijazi Arabic -> Arabic */
+  {"acx",	HB_TAG('A','R','A',' ')},	/* Omani Arabic -> Arabic */
+  {"acy",	HB_TAG('A','R','A',' ')},	/* Cypriot Arabic -> Arabic */
+  {"ada",	HB_TAG('D','N','G',' ')},	/* Adangme -> Dangme */
+  {"adf",	HB_TAG('A','R','A',' ')},	/* Dhofari Arabic -> Arabic */
+  {"adp",	HB_TAG('D','Z','N',' ')},	/* Adap (retired code) -> Dzongkha */
+/*{"ady",	HB_TAG('A','D','Y',' ')},*/	/* Adyghe */
+  {"aeb",	HB_TAG('A','R','A',' ')},	/* Tunisian Arabic -> Arabic */
+  {"aec",	HB_TAG('A','R','A',' ')},	/* Saidi Arabic -> Arabic */
+  {"af",	HB_TAG('A','F','K',' ')},	/* Afrikaans */
+  {"afb",	HB_TAG('A','R','A',' ')},	/* Gulf Arabic -> Arabic */
+  {"ahg",	HB_TAG('A','G','W',' ')},	/* Qimant -> Agaw */
+  {"aht",	HB_TAG('A','T','H',' ')},	/* Ahtena -> Athapaskan */
+  {"aii",	HB_TAG('S','W','A',' ')},	/* Assyrian Neo-Aramaic -> Swadaya Aramaic */
+  {"aii",	HB_TAG('S','Y','R',' ')},	/* Assyrian Neo-Aramaic -> Syriac */
+/*{"aio",	HB_TAG('A','I','O',' ')},*/	/* Aiton */
+  {"aiw",	HB_TAG('A','R','I',' ')},	/* Aari */
+  {"ajp",	HB_TAG('A','R','A',' ')},	/* South Levantine Arabic -> Arabic */
+  {"ak",	HB_TAG('A','K','A',' ')},	/* Akan [macrolanguage] */
+  {"ak",	HB_TAG('T','W','I',' ')},	/* Akan [macrolanguage] -> Twi */
+  {"aln",	HB_TAG('S','Q','I',' ')},	/* Gheg Albanian -> Albanian */
+  {"als",	HB_TAG('S','Q','I',' ')},	/* Tosk Albanian -> Albanian */
+/*{"alt",	HB_TAG('A','L','T',' ')},*/	/* Southern Altai -> Altai */
+  {"am",	HB_TAG('A','M','H',' ')},	/* Amharic */
+  {"amf",	HB_TAG('H','B','N',' ')},	/* Hamer-Banna -> Hammer-Banna */
+  {"amw",	HB_TAG('S','Y','R',' ')},	/* Western Neo-Aramaic -> Syriac */
+  {"an",	HB_TAG('A','R','G',' ')},	/* Aragonese */
+/*{"ang",	HB_TAG('A','N','G',' ')},*/	/* Old English (ca. 450-1100) -> Anglo-Saxon */
+  {"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 */
+  {"apk",	HB_TAG('A','T','H',' ')},	/* Kiowa Apache -> Athapaskan */
+  {"apl",	HB_TAG('A','T','H',' ')},	/* Lipan Apache -> Athapaskan */
+  {"apm",	HB_TAG('A','T','H',' ')},	/* Mescalero-Chiricahua Apache -> Athapaskan */
+  {"apw",	HB_TAG('A','T','H',' ')},	/* Western Apache -> Athapaskan */
+  {"ar",	HB_TAG('A','R','A',' ')},	/* Arabic [macrolanguage] */
+  {"arb",	HB_TAG('A','R','A',' ')},	/* Standard Arabic -> Arabic */
+  {"arn",	HB_TAG('M','A','P',' ')},	/* Mapudungun */
+  {"arq",	HB_TAG('A','R','A',' ')},	/* Algerian Arabic -> Arabic */
+  {"ars",	HB_TAG('A','R','A',' ')},	/* Najdi Arabic -> Arabic */
+  {"ary",	HB_TAG('M','O','R',' ')},	/* Moroccan Arabic -> Moroccan */
+  {"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 */
+  {"atj",	HB_TAG('R','C','R',' ')},	/* Atikamekw -> R-Cree */
+  {"atv",	HB_TAG('A','L','T',' ')},	/* Northern Altai -> Altai */
+  {"auz",	HB_TAG('A','R','A',' ')},	/* Uzbeki Arabic -> Arabic */
+  {"av",	HB_TAG('A','V','R',' ')},	/* Avaric -> Avar */
+  {"avl",	HB_TAG('A','R','A',' ')},	/* Eastern Egyptian Bedawi Arabic -> Arabic */
+/*{"awa",	HB_TAG('A','W','A',' ')},*/	/* Awadhi */
+  {"ay",	HB_TAG('A','Y','M',' ')},	/* Aymara [macrolanguage] */
+  {"ayc",	HB_TAG('A','Y','M',' ')},	/* Southern Aymara -> Aymara */
+  {"ayh",	HB_TAG('A','R','A',' ')},	/* Hadrami Arabic -> Arabic */
+  {"ayl",	HB_TAG('A','R','A',' ')},	/* Libyan Arabic -> Arabic */
+  {"ayn",	HB_TAG('A','R','A',' ')},	/* Sanaani Arabic -> Arabic */
+  {"ayp",	HB_TAG('A','R','A',' ')},	/* North Mesopotamian Arabic -> Arabic */
+  {"ayr",	HB_TAG('A','Y','M',' ')},	/* Central Aymara -> Aymara */
+  {"az",	HB_TAG('A','Z','E',' ')},	/* Azerbaijani [macrolanguage] */
+/*{"azb",	HB_TAG('A','Z','B',' ')},*/	/* South Azerbaijani -> Torki */
+  {"azj",	HB_TAG('A','Z','E',' ')},	/* North Azerbaijani -> Azerbaijani */
+  {"ba",	HB_TAG('B','S','H',' ')},	/* Bashkir */
+  {"bad",	HB_TAG('B','A','D','0')},	/* Banda [family] */
+  {"bai",	HB_TAG('B','M','L',' ')},	/* Bamileke [family] */
+  {"bal",	HB_TAG('B','L','I',' ')},	/* Baluchi [macrolanguage] */
+/*{"ban",	HB_TAG('B','A','N',' ')},*/	/* Balinese */
+/*{"bar",	HB_TAG('B','A','R',' ')},*/	/* Bavarian */
+/*{"bbc",	HB_TAG('B','B','C',' ')},*/	/* Batak Toba */
+  {"bbz",	HB_TAG('A','R','A',' ')},	/* Babalia Creole Arabic -> Arabic */
+  {"bcc",	HB_TAG('B','L','I',' ')},	/* Southern Balochi -> Baluchi */
+  {"bci",	HB_TAG('B','A','U',' ')},	/* Baoulé -> Baulé */
+  {"bcl",	HB_TAG('B','I','K',' ')},	/* Central Bikol -> Bikol */
+  {"bcq",	HB_TAG('B','C','H',' ')},	/* Bench */
+  {"bcr",	HB_TAG('A','T','H',' ')},	/* Babine -> Athapaskan */
+/*{"bdy",	HB_TAG('B','D','Y',' ')},*/	/* Bandjalang */
+  {"be",	HB_TAG('B','E','L',' ')},	/* Belarusian -> Belarussian */
+  {"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] */
+  {"bfq",	HB_TAG('B','A','D',' ')},	/* Badaga */
+  {"bft",	HB_TAG('B','L','T',' ')},	/* Balti */
+  {"bfu",	HB_TAG('L','A','H',' ')},	/* Gahri -> Lahuli */
+  {"bfy",	HB_TAG('B','A','G',' ')},	/* Bagheli -> Baghelkhandi */
+  {"bg",	HB_TAG('B','G','R',' ')},	/* Bulgarian */
+/*{"bgc",	HB_TAG('B','G','C',' ')},*/	/* Haryanvi */
+  {"bgn",	HB_TAG('B','L','I',' ')},	/* Western Balochi -> Baluchi */
+  {"bgp",	HB_TAG('B','L','I',' ')},	/* Eastern Balochi -> Baluchi */
+/*{"bgq",	HB_TAG('B','G','Q',' ')},*/	/* Bagri */
+  {"bgr",	HB_TAG('Q','I','N',' ')},	/* Bawm Chin -> Chin */
+  {"bhb",	HB_TAG('B','H','I',' ')},	/* Bhili */
+/*{"bhi",	HB_TAG('B','H','I',' ')},*/	/* Bhilali -> Bhili */
+  {"bhk",	HB_TAG('B','I','K',' ')},	/* Albay Bicolano (retired code) -> Bikol */
+/*{"bho",	HB_TAG('B','H','O',' ')},*/	/* Bhojpuri */
+  {"bhr",	HB_TAG('M','L','G',' ')},	/* Bara Malagasy -> Malagasy */
+  {"bi",	HB_TAG('B','I','S',' ')},	/* Bislama */
+/*{"bik",	HB_TAG('B','I','K',' ')},*/	/* Bikol [macrolanguage] */
+  {"bin",	HB_TAG('E','D','O',' ')},	/* Edo */
+/*{"bjj",	HB_TAG('B','J','J',' ')},*/	/* Kanauji */
+  {"bjn",	HB_TAG('M','L','Y',' ')},	/* Banjar -> Malay */
+  {"bjq",	HB_TAG('M','L','G',' ')},	/* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */
+  {"bjt",	HB_TAG('B','L','N',' ')},	/* Balanta-Ganja -> Balante */
+  {"bla",	HB_TAG('B','K','F',' ')},	/* Siksika -> Blackfoot */
+  {"ble",	HB_TAG('B','L','N',' ')},	/* Balanta-Kentohe -> Balante */
+/*{"blk",	HB_TAG('B','L','K',' ')},*/	/* Pa’o Karen */
+  {"bln",	HB_TAG('B','I','K',' ')},	/* Southern Catanduanes Bikol -> Bikol */
+  {"bm",	HB_TAG('B','M','B',' ')},	/* Bambara (Bamanankan) */
+  {"bmm",	HB_TAG('M','L','G',' ')},	/* Northern Betsimisaraka Malagasy -> Malagasy */
+  {"bn",	HB_TAG('B','E','N',' ')},	/* Bengali */
+  {"bo",	HB_TAG('T','I','B',' ')},	/* Tibetan */
+/*{"bpy",	HB_TAG('B','P','Y',' ')},*/	/* Bishnupriya -> Bishnupriya Manipuri */
+  {"bqi",	HB_TAG('L','R','C',' ')},	/* Bakhtiari -> Luri */
+  {"br",	HB_TAG('B','R','E',' ')},	/* Breton */
+  {"bra",	HB_TAG('B','R','I',' ')},	/* Braj -> Braj Bhasha */
+/*{"brh",	HB_TAG('B','R','H',' ')},*/	/* Brahui */
+/*{"brx",	HB_TAG('B','R','X',' ')},*/	/* Bodo (India) */
+  {"bs",	HB_TAG('B','O','S',' ')},	/* Bosnian */
+/*{"bsk",	HB_TAG('B','S','K',' ')},*/	/* Burushaski */
+  {"btb",	HB_TAG('B','T','I',' ')},	/* Beti (Cameroon) (retired code) */
+  {"btj",	HB_TAG('M','L','Y',' ')},	/* Bacanese Malay -> Malay */
+  {"bto",	HB_TAG('B','I','K',' ')},	/* Rinconada Bikol -> Bikol */
+/*{"bts",	HB_TAG('B','T','S',' ')},*/	/* Batak Simalungun */
+/*{"bug",	HB_TAG('B','U','G',' ')},*/	/* Buginese -> Bugis */
+  {"bum",	HB_TAG('B','T','I',' ')},	/* Bulu (Cameroon) -> Beti */
+  {"bve",	HB_TAG('M','L','Y',' ')},	/* Berau Malay -> Malay */
+  {"bvu",	HB_TAG('M','L','Y',' ')},	/* Bukit Malay -> Malay */
+  {"bxk",	HB_TAG('L','U','H',' ')},	/* Bukusu -> Luyia */
+  {"bxp",	HB_TAG('B','T','I',' ')},	/* Bebil -> Beti */
+  {"bxr",	HB_TAG('R','B','U',' ')},	/* Russia Buriat -> Russian Buriat */
+  {"byn",	HB_TAG('B','I','L',' ')},	/* Bilin -> Bilen */
+/*{"byv",	HB_TAG('B','Y','V',' ')},*/	/* Medumba */
+  {"bzc",	HB_TAG('M','L','G',' ')},	/* Southern Betsimisaraka Malagasy -> Malagasy */
+  {"ca",	HB_TAG('C','A','T',' ')},	/* Catalan */
+  {"caf",	HB_TAG('C','R','R',' ')},	/* Southern Carrier -> Carrier */
+  {"caf",	HB_TAG('A','T','H',' ')},	/* Southern Carrier -> Athapaskan */
+/*{"cak",	HB_TAG('C','A','K',' ')},*/	/* Kaqchikel */
+/*{"cbk",	HB_TAG('C','B','K',' ')},*/	/* Chavacano -> Zamboanga Chavacano */
+  {"cbl",	HB_TAG('Q','I','N',' ')},	/* Bualkhaw Chin -> Chin */
+  {"cco",	HB_TAG('C','C','H','N')},	/* Comaltepec Chinantec -> Chinantec */
+  {"ccq",	HB_TAG('A','R','K',' ')},	/* Chaungtha (retired code) -> Rakhine */
+  {"cdo",	HB_TAG('Z','H','S',' ')},	/* Min Dong Chinese -> Chinese Simplified */
+  {"ce",	HB_TAG('C','H','E',' ')},	/* Chechen */
+/*{"ceb",	HB_TAG('C','E','B',' ')},*/	/* Cebuano */
+  {"cfm",	HB_TAG('H','A','L',' ')},	/* Halam (Falam Chin) */
+/*{"cgg",	HB_TAG('C','G','G',' ')},*/	/* Chiga */
+  {"ch",	HB_TAG('C','H','A',' ')},	/* Chamorro */
+  {"chj",	HB_TAG('C','C','H','N')},	/* Ojitlán Chinantec -> Chinantec */
+  {"chk",	HB_TAG('C','H','K','0')},	/* Chuukese */
+/*{"cho",	HB_TAG('C','H','O',' ')},*/	/* Choctaw */
+  {"chp",	HB_TAG('C','H','P',' ')},	/* Chipewyan */
+  {"chp",	HB_TAG('S','A','Y',' ')},	/* Chipewyan -> Sayisi */
+  {"chp",	HB_TAG('A','T','H',' ')},	/* Chipewyan -> Athapaskan */
+  {"chq",	HB_TAG('C','C','H','N')},	/* Quiotepec Chinantec -> Chinantec */
+/*{"chr",	HB_TAG('C','H','R',' ')},*/	/* Cherokee */
+/*{"chy",	HB_TAG('C','H','Y',' ')},*/	/* Cheyenne */
+  {"chz",	HB_TAG('C','C','H','N')},	/* Ozumacín Chinantec -> Chinantec */
+  {"ciw",	HB_TAG('O','J','B',' ')},	/* Chippewa -> Ojibway */
+/*{"cja",	HB_TAG('C','J','A',' ')},*/	/* Western Cham */
+/*{"cjm",	HB_TAG('C','J','M',' ')},*/	/* Eastern Cham */
+  {"cjy",	HB_TAG('Z','H','S',' ')},	/* Jinyu Chinese -> Chinese Simplified */
+  {"cka",	HB_TAG('Q','I','N',' ')},	/* Khumi Awa Chin (retired code) -> Chin */
+  {"ckb",	HB_TAG('K','U','R',' ')},	/* Central Kurdish -> Kurdish */
+  {"ckt",	HB_TAG('C','H','K',' ')},	/* Chukot -> Chukchi */
+  {"clc",	HB_TAG('A','T','H',' ')},	/* Chilcotin -> Athapaskan */
+  {"cld",	HB_TAG('S','Y','R',' ')},	/* Chaldean Neo-Aramaic -> Syriac */
+  {"cle",	HB_TAG('C','C','H','N')},	/* Lealao Chinantec -> Chinantec */
+  {"cmn",	HB_TAG('Z','H','S',' ')},	/* Mandarin Chinese -> Chinese Simplified */
+  {"cmr",	HB_TAG('Q','I','N',' ')},	/* Mro-Khimi Chin -> Chin */
+  {"cnb",	HB_TAG('Q','I','N',' ')},	/* Chinbon Chin -> Chin */
+  {"cnh",	HB_TAG('Q','I','N',' ')},	/* Hakha Chin -> Chin */
+  {"cnk",	HB_TAG('Q','I','N',' ')},	/* Khumi Chin -> Chin */
+  {"cnl",	HB_TAG('C','C','H','N')},	/* Lalana Chinantec -> Chinantec */
+  {"cnt",	HB_TAG('C','C','H','N')},	/* Tepetotutla Chinantec -> Chinantec */
+  {"cnw",	HB_TAG('Q','I','N',' ')},	/* Ngawn Chin -> Chin */
+  {"co",	HB_TAG('C','O','S',' ')},	/* Corsican */
+  {"coa",	HB_TAG('M','L','Y',' ')},	/* Cocos Islands Malay -> Malay */
+/*{"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 */
+/*{"cpp",	HB_TAG('C','P','P',' ')},*/	/* Portuguese-based creoles and pidgins [family] -> 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) */
+  {"cr",	HB_TAG('C','R','E',' ')},	/* Cree [macrolanguage] */
+  {"cr",	HB_TAG('Y','C','R',' ')},	/* Cree [macrolanguage] -> Y-Cree */
+  {"crh",	HB_TAG('C','R','T',' ')},	/* Crimean Tatar */
+  {"crj",	HB_TAG('E','C','R',' ')},	/* Southern East Cree -> Eastern Cree */
+  {"crk",	HB_TAG('W','C','R',' ')},	/* Plains Cree -> West-Cree */
+  {"crl",	HB_TAG('E','C','R',' ')},	/* Northern East Cree -> Eastern Cree */
+  {"crm",	HB_TAG('M','C','R',' ')},	/* Moose Cree */
+  {"crm",	HB_TAG('L','C','R',' ')},	/* Moose Cree -> L-Cree */
+  {"crp",	HB_TAG('C','P','P',' ')},	/* Creoles and pidgins [family] -> Creoles */
+  {"crx",	HB_TAG('C','R','R',' ')},	/* Carrier */
+  {"crx",	HB_TAG('A','T','H',' ')},	/* Carrier -> Athapaskan */
+  {"cs",	HB_TAG('C','S','Y',' ')},	/* Czech */
+  {"csa",	HB_TAG('C','C','H','N')},	/* Chiltepec Chinantec -> Chinantec */
+/*{"csb",	HB_TAG('C','S','B',' ')},*/	/* Kashubian */
+  {"csh",	HB_TAG('Q','I','N',' ')},	/* Asho Chin -> Chin */
+  {"cso",	HB_TAG('C','C','H','N')},	/* Sochiapam Chinantec -> Chinantec */
+  {"csw",	HB_TAG('N','C','R',' ')},	/* Swampy Cree -> N-Cree */
+  {"csw",	HB_TAG('N','H','C',' ')},	/* Swampy Cree -> Norway House Cree */
+  {"csy",	HB_TAG('Q','I','N',' ')},	/* Siyin Chin -> Chin */
+  {"ctc",	HB_TAG('A','T','H',' ')},	/* Chetco -> Athapaskan */
+  {"ctd",	HB_TAG('Q','I','N',' ')},	/* Tedim Chin -> Chin */
+  {"cte",	HB_TAG('C','C','H','N')},	/* Tepinapa Chinantec -> Chinantec */
+/*{"ctg",	HB_TAG('C','T','G',' ')},*/	/* Chittagonian */
+  {"ctl",	HB_TAG('C','C','H','N')},	/* Tlacoatzintepec Chinantec -> Chinantec */
+  {"cts",	HB_TAG('B','I','K',' ')},	/* Northern Catanduanes Bikol -> Bikol */
+  {"cu",	HB_TAG('C','S','L',' ')},	/* Church Slavonic */
+  {"cuc",	HB_TAG('C','C','H','N')},	/* Usila Chinantec -> Chinantec */
+/*{"cuk",	HB_TAG('C','U','K',' ')},*/	/* San Blas Kuna */
+  {"cv",	HB_TAG('C','H','U',' ')},	/* Chuvash */
+  {"cvn",	HB_TAG('C','C','H','N')},	/* Valle Nacional Chinantec -> Chinantec */
+  {"cwd",	HB_TAG('D','C','R',' ')},	/* Woods Cree */
+  {"cwd",	HB_TAG('T','C','R',' ')},	/* Woods Cree -> TH-Cree */
+  {"cy",	HB_TAG('W','E','L',' ')},	/* Welsh */
+  {"czh",	HB_TAG('Z','H','S',' ')},	/* Huizhou Chinese -> Chinese Simplified */
+  {"czo",	HB_TAG('Z','H','S',' ')},	/* Min Zhong Chinese -> Chinese Simplified */
+  {"czt",	HB_TAG('Q','I','N',' ')},	/* Zotung Chin -> Chin */
+  {"da",	HB_TAG('D','A','N',' ')},	/* Danish */
+  {"dao",	HB_TAG('Q','I','N',' ')},	/* Daai Chin -> Chin */
+  {"dap",	HB_TAG('N','I','S',' ')},	/* Nisi (India) (retired code) */
+/*{"dar",	HB_TAG('D','A','R',' ')},*/	/* Dargwa */
+/*{"dax",	HB_TAG('D','A','X',' ')},*/	/* Dayi */
+  {"de",	HB_TAG('D','E','U',' ')},	/* German */
+  {"den",	HB_TAG('S','L','A',' ')},	/* Slave (Athapascan) [macrolanguage] -> Slavey */
+  {"den",	HB_TAG('A','T','H',' ')},	/* Slave (Athapascan) [macrolanguage] -> Athapaskan */
+/*{"dgo",	HB_TAG('D','G','O',' ')},*/	/* Dogri */
+  {"dgr",	HB_TAG('A','T','H',' ')},	/* Dogrib -> Athapaskan */
+  {"dhd",	HB_TAG('M','A','W',' ')},	/* Dhundari -> Marwari */
+/*{"dhg",	HB_TAG('D','H','G',' ')},*/	/* Dhangu */
+  {"dib",	HB_TAG('D','N','K',' ')},	/* South Central Dinka -> Dinka */
+  {"dik",	HB_TAG('D','N','K',' ')},	/* Southwestern Dinka -> Dinka */
+  {"din",	HB_TAG('D','N','K',' ')},	/* Dinka [macrolanguage] */
+  {"dip",	HB_TAG('D','N','K',' ')},	/* Northeastern Dinka -> Dinka */
+/*{"diq",	HB_TAG('D','I','Q',' ')},*/	/* Dimli */
+  {"diw",	HB_TAG('D','N','K',' ')},	/* Northwestern Dinka -> Dinka */
+  {"dje",	HB_TAG('D','J','R',' ')},	/* Zarma */
+  {"djr",	HB_TAG('D','J','R','0')},	/* Djambarrpuyngu */
+  {"dks",	HB_TAG('D','N','K',' ')},	/* Southeastern Dinka -> Dinka */
+  {"dng",	HB_TAG('D','U','N',' ')},	/* Dungan */
+/*{"dnj",	HB_TAG('D','N','J',' ')},*/	/* Dan */
+  {"doi",	HB_TAG('D','G','R',' ')},	/* Dogri [macrolanguage] */
+  {"drh",	HB_TAG('M','N','G',' ')},	/* Darkhat (retired code) -> Mongolian */
+  {"drw",	HB_TAG('D','R','I',' ')},	/* Darwazi (retired code) -> Dari */
+  {"dsb",	HB_TAG('L','S','B',' ')},	/* Lower Sorbian */
+  {"dty",	HB_TAG('N','E','P',' ')},	/* Dotyali -> Nepali */
+/*{"duj",	HB_TAG('D','U','J',' ')},*/	/* Dhuwal (retired code) */
+  {"dup",	HB_TAG('M','L','Y',' ')},	/* Duano -> Malay */
+  {"dv",	HB_TAG('D','I','V',' ')},	/* Divehi (Dhivehi, Maldivian) */
+  {"dv",	HB_TAG('D','H','V',' ')},	/* Divehi (Dhivehi, Maldivian) (deprecated) */
+  {"dwu",	HB_TAG('D','U','J',' ')},	/* Dhuwal */
+  {"dwy",	HB_TAG('D','U','J',' ')},	/* Dhuwaya -> Dhuwal */
+  {"dyu",	HB_TAG('J','U','L',' ')},	/* Dyula -> Jula */
+  {"dz",	HB_TAG('D','Z','N',' ')},	/* Dzongkha */
+  {"ee",	HB_TAG('E','W','E',' ')},	/* Ewe */
+/*{"efi",	HB_TAG('E','F','I',' ')},*/	/* Efik */
+  {"ekk",	HB_TAG('E','T','I',' ')},	/* Standard Estonian -> Estonian */
+  {"el",	HB_TAG('E','L','L',' ')},	/* Modern Greek (1453-) -> Greek */
+  {"emk",	HB_TAG('E','M','K',' ')},	/* Eastern Maninkakan */
+  {"emk",	HB_TAG('M','N','K',' ')},	/* Eastern Maninkakan -> Maninka */
+  {"en",	HB_TAG('E','N','G',' ')},	/* English */
+  {"enb",	HB_TAG('K','A','L',' ')},	/* Markweeta -> Kalenjin */
+  {"enf",	HB_TAG('F','N','E',' ')},	/* Forest Enets -> Forest Nenets */
+  {"enh",	HB_TAG('T','N','E',' ')},	/* Tundra Enets -> Tundra Nenets */
+  {"eo",	HB_TAG('N','T','O',' ')},	/* Esperanto */
+  {"es",	HB_TAG('E','S','P',' ')},	/* Spanish */
+  {"esg",	HB_TAG('G','O','N',' ')},	/* Aheri Gondi -> Gondi */
+  {"esi",	HB_TAG('I','P','K',' ')},	/* North Alaskan Inupiatun -> Inupiat */
+  {"esk",	HB_TAG('I','P','K',' ')},	/* Northwest Alaska Inupiatun -> Inupiat */
+/*{"esu",	HB_TAG('E','S','U',' ')},*/	/* Central Yupik */
+  {"et",	HB_TAG('E','T','I',' ')},	/* Estonian [macrolanguage] */
+  {"eto",	HB_TAG('B','T','I',' ')},	/* Eton (Cameroon) -> Beti */
+  {"eu",	HB_TAG('E','U','Q',' ')},	/* Basque */
+  {"eve",	HB_TAG('E','V','N',' ')},	/* Even */
+  {"evn",	HB_TAG('E','V','K',' ')},	/* Evenki */
+  {"ewo",	HB_TAG('B','T','I',' ')},	/* Ewondo -> Beti */
+  {"eyo",	HB_TAG('K','A','L',' ')},	/* Keiyo -> Kalenjin */
+  {"fa",	HB_TAG('F','A','R',' ')},	/* Persian [macrolanguage] */
+  {"fan",	HB_TAG('F','A','N','0')},	/* Fang (Equatorial Guinea) */
+/*{"fat",	HB_TAG('F','A','T',' ')},*/	/* Fanti */
+  {"fbl",	HB_TAG('B','I','K',' ')},	/* West Albay Bikol -> Bikol */
+  {"ff",	HB_TAG('F','U','L',' ')},	/* Fulah [macrolanguage] */
+  {"ffm",	HB_TAG('F','U','L',' ')},	/* Maasina Fulfulde -> Fulah */
+  {"fi",	HB_TAG('F','I','N',' ')},	/* Finnish */
+  {"fil",	HB_TAG('P','I','L',' ')},	/* Filipino */
+  {"fj",	HB_TAG('F','J','I',' ')},	/* Fijian */
+  {"flm",	HB_TAG('H','A','L',' ')},	/* Halam (Falam Chin) (retired code) */
+  {"flm",	HB_TAG('Q','I','N',' ')},	/* Falam Chin (retired code) -> Chin */
+/*{"fmp",	HB_TAG('F','M','P',' ')},*/	/* Fe’fe’ */
+  {"fo",	HB_TAG('F','O','S',' ')},	/* Faroese */
+/*{"fon",	HB_TAG('F','O','N',' ')},*/	/* Fon */
+  {"fr",	HB_TAG('F','R','A',' ')},	/* French */
+/*{"frc",	HB_TAG('F','R','C',' ')},*/	/* Cajun French */
+/*{"frp",	HB_TAG('F','R','P',' ')},*/	/* Arpitan */
+  {"fub",	HB_TAG('F','U','L',' ')},	/* Adamawa Fulfulde -> Fulah */
+  {"fuc",	HB_TAG('F','U','L',' ')},	/* Pulaar -> Fulah */
+  {"fue",	HB_TAG('F','U','L',' ')},	/* Borgu Fulfulde -> Fulah */
+  {"fuf",	HB_TAG('F','T','A',' ')},	/* Pular -> Futa */
+  {"fuh",	HB_TAG('F','U','L',' ')},	/* Western Niger Fulfulde -> Fulah */
+  {"fui",	HB_TAG('F','U','L',' ')},	/* Bagirmi Fulfulde -> Fulah */
+  {"fuq",	HB_TAG('F','U','L',' ')},	/* Central-Eastern Niger Fulfulde -> Fulah */
+  {"fur",	HB_TAG('F','R','L',' ')},	/* Friulian */
+/*{"fuv",	HB_TAG('F','U','V',' ')},*/	/* Nigerian Fulfulde */
+  {"fy",	HB_TAG('F','R','I',' ')},	/* Western Frisian -> Frisian */
+  {"ga",	HB_TAG('I','R','I',' ')},	/* Irish */
+  {"gaa",	HB_TAG('G','A','D',' ')},	/* Ga */
+/*{"gag",	HB_TAG('G','A','G',' ')},*/	/* Gagauz */
+  {"gan",	HB_TAG('Z','H','S',' ')},	/* Gan Chinese -> Chinese Simplified */
+  {"gax",	HB_TAG('O','R','O',' ')},	/* Borana-Arsi-Guji Oromo -> Oromo */
+  {"gaz",	HB_TAG('O','R','O',' ')},	/* West Central Oromo -> Oromo */
+  {"gbm",	HB_TAG('G','A','W',' ')},	/* Garhwali */
+  {"gce",	HB_TAG('A','T','H',' ')},	/* Galice -> Athapaskan */
+  {"gd",	HB_TAG('G','A','E',' ')},	/* Scottish Gaelic (Gaelic) */
+  {"gda",	HB_TAG('R','A','J',' ')},	/* Gade Lohar -> Rajasthani */
+/*{"gez",	HB_TAG('G','E','Z',' ')},*/	/* Geez */
+  {"ggo",	HB_TAG('G','O','N',' ')},	/* Southern Gondi (retired code) -> Gondi */
+/*{"gih",	HB_TAG('G','I','H',' ')},*/	/* Githabul */
+  {"gil",	HB_TAG('G','I','L','0')},	/* Kiribati (Gilbertese) */
+  {"gju",	HB_TAG('R','A','J',' ')},	/* Gujari -> Rajasthani */
+/*{"gkp",	HB_TAG('G','K','P',' ')},*/	/* Guinea Kpelle -> Kpelle (Guinea) */
+  {"gl",	HB_TAG('G','A','L',' ')},	/* Galician */
+  {"gld",	HB_TAG('N','A','N',' ')},	/* Nanai */
+/*{"glk",	HB_TAG('G','L','K',' ')},*/	/* Gilaki */
+  {"gn",	HB_TAG('G','U','A',' ')},	/* Guarani [macrolanguage] */
+/*{"gnn",	HB_TAG('G','N','N',' ')},*/	/* Gumatj */
+  {"gno",	HB_TAG('G','O','N',' ')},	/* Northern Gondi -> Gondi */
+  {"gnw",	HB_TAG('G','U','A',' ')},	/* Western Bolivian Guaraní -> Guarani */
+/*{"gog",	HB_TAG('G','O','G',' ')},*/	/* Gogo */
+  {"gom",	HB_TAG('K','O','K',' ')},	/* Goan Konkani -> Konkani */
+/*{"gon",	HB_TAG('G','O','N',' ')},*/	/* Gondi [macrolanguage] */
+  {"grt",	HB_TAG('G','R','O',' ')},	/* Garo */
+  {"gru",	HB_TAG('S','O','G',' ')},	/* Kistane -> Sodo Gurage */
+  {"gsw",	HB_TAG('A','L','S',' ')},	/* Alsatian */
+  {"gu",	HB_TAG('G','U','J',' ')},	/* Gujarati */
+/*{"guc",	HB_TAG('G','U','C',' ')},*/	/* Wayuu */
+/*{"guf",	HB_TAG('G','U','F',' ')},*/	/* Gupapuyngu */
+  {"gug",	HB_TAG('G','U','A',' ')},	/* Paraguayan Guaraní -> Guarani */
+  {"gui",	HB_TAG('G','U','A',' ')},	/* Eastern Bolivian Guaraní -> Guarani */
+  {"guk",	HB_TAG('G','M','Z',' ')},	/* Gumuz */
+  {"guk",	HB_TAG('G','U','K',' ')},	/* Gumuz (SIL fonts) */
+  {"gun",	HB_TAG('G','U','A',' ')},	/* Mbyá Guaraní -> Guarani */
+/*{"guz",	HB_TAG('G','U','Z',' ')},*/	/* Gusii */
+  {"gv",	HB_TAG('M','N','X',' ')},	/* Manx */
+  {"gwi",	HB_TAG('A','T','H',' ')},	/* Gwichʼin -> Athapaskan */
+  {"ha",	HB_TAG('H','A','U',' ')},	/* Hausa */
+  {"haa",	HB_TAG('A','T','H',' ')},	/* Han -> Athapaskan */
+  {"hae",	HB_TAG('O','R','O',' ')},	/* Eastern Oromo -> Oromo */
+  {"hak",	HB_TAG('Z','H','S',' ')},	/* Hakka Chinese -> Chinese Simplified */
+  {"har",	HB_TAG('H','R','I',' ')},	/* Harari */
+/*{"haw",	HB_TAG('H','A','W',' ')},*/	/* Hawaiian */
+/*{"hay",	HB_TAG('H','A','Y',' ')},*/	/* Haya */
+/*{"haz",	HB_TAG('H','A','Z',' ')},*/	/* Hazaragi */
+  {"he",	HB_TAG('I','W','R',' ')},	/* Hebrew */
+  {"hea",	HB_TAG('H','M','N',' ')},	/* Northern Qiandong Miao -> Hmong */
+  {"hi",	HB_TAG('H','I','N',' ')},	/* Hindi */
+/*{"hil",	HB_TAG('H','I','L',' ')},*/	/* Hiligaynon */
+  {"hji",	HB_TAG('M','L','Y',' ')},	/* Haji -> Malay */
+  {"hlt",	HB_TAG('Q','I','N',' ')},	/* Matu Chin -> Chin */
+  {"hma",	HB_TAG('H','M','N',' ')},	/* Southern Mashan Hmong -> Hmong */
+  {"hmc",	HB_TAG('H','M','N',' ')},	/* Central Huishui Hmong -> Hmong */
+  {"hmd",	HB_TAG('H','M','N',' ')},	/* Large Flowery Miao -> Hmong */
+  {"hme",	HB_TAG('H','M','N',' ')},	/* Eastern Huishui Hmong -> Hmong */
+  {"hmg",	HB_TAG('H','M','N',' ')},	/* Southwestern Guiyang Hmong -> Hmong */
+  {"hmh",	HB_TAG('H','M','N',' ')},	/* Southwestern Huishui Hmong -> Hmong */
+  {"hmi",	HB_TAG('H','M','N',' ')},	/* Northern Huishui Hmong -> Hmong */
+  {"hmj",	HB_TAG('H','M','N',' ')},	/* Ge -> Hmong */
+  {"hml",	HB_TAG('H','M','N',' ')},	/* Luopohe Hmong -> Hmong */
+  {"hmm",	HB_TAG('H','M','N',' ')},	/* Central Mashan Hmong -> Hmong */
+/*{"hmn",	HB_TAG('H','M','N',' ')},*/	/* Hmong [macrolanguage] */
+  {"hmp",	HB_TAG('H','M','N',' ')},	/* Northern Mashan Hmong -> Hmong */
+  {"hmq",	HB_TAG('H','M','N',' ')},	/* Eastern Qiandong Miao -> Hmong */
+  {"hms",	HB_TAG('H','M','N',' ')},	/* Southern Qiandong Miao -> Hmong */
+  {"hmw",	HB_TAG('H','M','N',' ')},	/* Western Mashan Hmong -> Hmong */
+  {"hmy",	HB_TAG('H','M','N',' ')},	/* Southern Guiyang Hmong -> Hmong */
+  {"hmz",	HB_TAG('H','M','N',' ')},	/* Hmong Shua -> Hmong */
+/*{"hnd",	HB_TAG('H','N','D',' ')},*/	/* Southern Hindko -> Hindko */
+  {"hne",	HB_TAG('C','H','H',' ')},	/* Chhattisgarhi -> Chattisgarhi */
+  {"hnj",	HB_TAG('H','M','N',' ')},	/* Hmong Njua -> Hmong */
+  {"hno",	HB_TAG('H','N','D',' ')},	/* Northern Hindko -> Hindko */
+  {"ho",	HB_TAG('H','M','O',' ')},	/* Hiri Motu */
+  {"hoc",	HB_TAG('H','O',' ',' ')},	/* Ho */
+  {"hoi",	HB_TAG('A','T','H',' ')},	/* Holikachuk -> Athapaskan */
+  {"hoj",	HB_TAG('H','A','R',' ')},	/* Hadothi -> Harauti */
+  {"hr",	HB_TAG('H','R','V',' ')},	/* Croatian */
+  {"hrm",	HB_TAG('H','M','N',' ')},	/* Horned Miao -> Hmong */
+  {"hsb",	HB_TAG('U','S','B',' ')},	/* Upper Sorbian */
+  {"hsn",	HB_TAG('Z','H','S',' ')},	/* Xiang Chinese -> Chinese Simplified */
+  {"ht",	HB_TAG('H','A','I',' ')},	/* Haitian (Haitian Creole) */
+  {"hu",	HB_TAG('H','U','N',' ')},	/* Hungarian */
+  {"huj",	HB_TAG('H','M','N',' ')},	/* Northern Guiyang Hmong -> Hmong */
+  {"hup",	HB_TAG('A','T','H',' ')},	/* Hupa -> Athapaskan */
+  {"hy",	HB_TAG('H','Y','E','0')},	/* Armenian -> Armenian East */
+  {"hy",	HB_TAG('H','Y','E',' ')},	/* Armenian */
+  {"hyw",	HB_TAG('H','Y','E',' ')},	/* Western Armenian -> Armenian */
+  {"hz",	HB_TAG('H','E','R',' ')},	/* Herero */
+  {"ia",	HB_TAG('I','N','A',' ')},	/* Interlingua (International Auxiliary Language Association) */
+/*{"iba",	HB_TAG('I','B','A',' ')},*/	/* Iban */
+/*{"ibb",	HB_TAG('I','B','B',' ')},*/	/* Ibibio */
+  {"id",	HB_TAG('I','N','D',' ')},	/* Indonesian */
+  {"ida",	HB_TAG('L','U','H',' ')},	/* Idakho-Isukha-Tiriki -> Luyia */
+  {"ie",	HB_TAG('I','L','E',' ')},	/* Interlingue */
+  {"ig",	HB_TAG('I','B','O',' ')},	/* Igbo */
+  {"igb",	HB_TAG('E','B','I',' ')},	/* Ebira */
+  {"ii",	HB_TAG('Y','I','M',' ')},	/* Sichuan Yi -> Yi Modern */
+  {"ijc",	HB_TAG('I','J','O',' ')},	/* Izon -> Ijo */
+/*{"ijo",	HB_TAG('I','J','O',' ')},*/	/* Ijo [family] */
+  {"ik",	HB_TAG('I','P','K',' ')},	/* Inupiaq [macrolanguage] -> Inupiat */
+  {"ike",	HB_TAG('I','N','U',' ')},	/* Eastern Canadian Inuktitut -> 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) */
+  {"ing",	HB_TAG('A','T','H',' ')},	/* Degexit'an -> Athapaskan */
+  {"inh",	HB_TAG('I','N','G',' ')},	/* Ingush */
+  {"io",	HB_TAG('I','D','O',' ')},	/* Ido */
+  {"is",	HB_TAG('I','S','L',' ')},	/* Icelandic */
+  {"it",	HB_TAG('I','T','A',' ')},	/* Italian */
+  {"iu",	HB_TAG('I','N','U',' ')},	/* Inuktitut [macrolanguage] */
+  {"iw",	HB_TAG('I','W','R',' ')},	/* Hebrew (retired code) */
+  {"ja",	HB_TAG('J','A','N',' ')},	/* Japanese */
+  {"jak",	HB_TAG('M','L','Y',' ')},	/* Jakun -> Malay */
+/*{"jam",	HB_TAG('J','A','M',' ')},*/	/* Jamaican Creole English -> Jamaican Creole */
+  {"jax",	HB_TAG('M','L','Y',' ')},	/* Jambi Malay -> Malay */
+/*{"jbo",	HB_TAG('J','B','O',' ')},*/	/* Lojban */
+/*{"jct",	HB_TAG('J','C','T',' ')},*/	/* Krymchak */
+  {"ji",	HB_TAG('J','I','I',' ')},	/* Yiddish (retired code) */
+  {"jv",	HB_TAG('J','A','V',' ')},	/* Javanese */
+  {"jw",	HB_TAG('J','A','V',' ')},	/* Javanese (retired code) */
+  {"ka",	HB_TAG('K','A','T',' ')},	/* Georgian */
+  {"kaa",	HB_TAG('K','R','K',' ')},	/* Kara-Kalpak -> Karakalpak */
+  {"kab",	HB_TAG('K','A','B','0')},	/* Kabyle */
+  {"kam",	HB_TAG('K','M','B',' ')},	/* Kamba (Kenya) */
+  {"kar",	HB_TAG('K','R','N',' ')},	/* Karen [family] */
+  {"kbd",	HB_TAG('K','A','B',' ')},	/* Kabardian */
+  {"kby",	HB_TAG('K','N','R',' ')},	/* Manga Kanuri -> Kanuri */
+  {"kca",	HB_TAG('K','H','K',' ')},	/* Khanty -> Khanty-Kazim */
+  {"kca",	HB_TAG('K','H','S',' ')},	/* Khanty -> Khanty-Shurishkar */
+  {"kca",	HB_TAG('K','H','V',' ')},	/* Khanty -> Khanty-Vakhi */
+/*{"kde",	HB_TAG('K','D','E',' ')},*/	/* Makonde */
+  {"kdr",	HB_TAG('K','R','M',' ')},	/* Karaim */
+  {"kdt",	HB_TAG('K','U','Y',' ')},	/* Kuy */
+/*{"kea",	HB_TAG('K','E','A',' ')},*/	/* Kabuverdianu (Crioulo) */
+/*{"kek",	HB_TAG('K','E','K',' ')},*/	/* Kekchi */
+  {"kex",	HB_TAG('K','K','N',' ')},	/* Kukna -> Kokni */
+  {"kfa",	HB_TAG('K','O','D',' ')},	/* Kodava -> Kodagu */
+  {"kfr",	HB_TAG('K','A','C',' ')},	/* Kachhi -> Kachchi */
+  {"kfx",	HB_TAG('K','U','L',' ')},	/* Kullu Pahari -> Kulvi */
+  {"kfy",	HB_TAG('K','M','N',' ')},	/* Kumaoni */
+  {"kg",	HB_TAG('K','O','N','0')},	/* Kongo [macrolanguage] */
+  {"kha",	HB_TAG('K','S','I',' ')},	/* Khasi */
+  {"khb",	HB_TAG('X','B','D',' ')},	/* Lü */
+  {"khk",	HB_TAG('M','N','G',' ')},	/* Halh Mongolian -> Mongolian */
+  {"kht",	HB_TAG('K','H','N',' ')},	/* Khamti -> Khamti Shan (Microsoft fonts) */
+  {"kht",	HB_TAG('K','H','T',' ')},	/* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */
+/*{"khw",	HB_TAG('K','H','W',' ')},*/	/* Khowar */
+  {"ki",	HB_TAG('K','I','K',' ')},	/* Kikuyu (Gikuyu) */
+/*{"kiu",	HB_TAG('K','I','U',' ')},*/	/* Kirmanjki */
+  {"kj",	HB_TAG('K','U','A',' ')},	/* Kuanyama */
+/*{"kjd",	HB_TAG('K','J','D',' ')},*/	/* Southern Kiwai */
+  {"kjh",	HB_TAG('K','H','A',' ')},	/* Khakas -> Khakass */
+/*{"kjp",	HB_TAG('K','J','P',' ')},*/	/* Pwo Eastern Karen -> Eastern Pwo Karen */
+/*{"kjz",	HB_TAG('K','J','Z',' ')},*/	/* Bumthangkha */
+  {"kk",	HB_TAG('K','A','Z',' ')},	/* Kazakh */
+  {"kkz",	HB_TAG('A','T','H',' ')},	/* Kaska -> Athapaskan */
+  {"kl",	HB_TAG('G','R','N',' ')},	/* Greenlandic */
+  {"kln",	HB_TAG('K','A','L',' ')},	/* Kalenjin [macrolanguage] */
+  {"km",	HB_TAG('K','H','M',' ')},	/* Khmer */
+  {"kmb",	HB_TAG('M','B','N',' ')},	/* Kimbundu -> Mbundu */
+  {"kmr",	HB_TAG('K','U','R',' ')},	/* Northern Kurdish -> Kurdish */
+  {"kmw",	HB_TAG('K','M','O',' ')},	/* Komo (Democratic Republic of Congo) */
+/*{"kmz",	HB_TAG('K','M','Z',' ')},*/	/* Khorasani Turkish -> Khorasani Turkic */
+  {"kn",	HB_TAG('K','A','N',' ')},	/* Kannada */
+  {"knc",	HB_TAG('K','N','R',' ')},	/* Central Kanuri -> Kanuri */
+  {"kng",	HB_TAG('K','O','N','0')},	/* Koongo -> Kongo */
+  {"knn",	HB_TAG('K','O','K',' ')},	/* Konkani */
+  {"ko",	HB_TAG('K','O','R',' ')},	/* Korean */
+  {"koi",	HB_TAG('K','O','P',' ')},	/* Komi-Permyak */
+/*{"kok",	HB_TAG('K','O','K',' ')},*/	/* Konkani [macrolanguage] */
+/*{"kos",	HB_TAG('K','O','S',' ')},*/	/* Kosraean */
+  {"koy",	HB_TAG('A','T','H',' ')},	/* Koyukon -> Athapaskan */
+  {"kpe",	HB_TAG('K','P','L',' ')},	/* Kpelle [macrolanguage] */
+  {"kpv",	HB_TAG('K','O','Z',' ')},	/* Komi-Zyrian */
+  {"kpy",	HB_TAG('K','Y','K',' ')},	/* Koryak */
+  {"kqs",	HB_TAG('K','I','S',' ')},	/* Northern Kissi -> Kisii */
+  {"kqy",	HB_TAG('K','R','T',' ')},	/* Koorete */
+  {"kr",	HB_TAG('K','N','R',' ')},	/* Kanuri [macrolanguage] */
+  {"krc",	HB_TAG('K','A','R',' ')},	/* Karachay-Balkar -> Karachay */
+  {"krc",	HB_TAG('B','A','L',' ')},	/* Karachay-Balkar -> Balkar */
+/*{"kri",	HB_TAG('K','R','I',' ')},*/	/* Krio */
+/*{"krl",	HB_TAG('K','R','L',' ')},*/	/* Karelian */
+  {"krt",	HB_TAG('K','N','R',' ')},	/* Tumari Kanuri -> Kanuri */
+  {"kru",	HB_TAG('K','U','U',' ')},	/* Kurukh */
+  {"ks",	HB_TAG('K','S','H',' ')},	/* Kashmiri */
+  {"ksh",	HB_TAG('K','S','H','0')},	/* Kölsch -> Ripuarian */
+  {"kss",	HB_TAG('K','I','S',' ')},	/* Southern Kisi -> Kisii */
+/*{"ksw",	HB_TAG('K','S','W',' ')},*/	/* S’gaw Karen */
+  {"ktb",	HB_TAG('K','E','B',' ')},	/* Kambaata -> Kebena */
+  {"ktu",	HB_TAG('K','O','N',' ')},	/* Kituba (Democratic Republic of Congo) -> Kikongo */
+  {"ktw",	HB_TAG('A','T','H',' ')},	/* Kato -> Athapaskan */
+  {"ku",	HB_TAG('K','U','R',' ')},	/* Kurdish [macrolanguage] */
+/*{"kum",	HB_TAG('K','U','M',' ')},*/	/* Kumyk */
+  {"kuu",	HB_TAG('A','T','H',' ')},	/* Upper Kuskokwim -> Athapaskan */
+  {"kv",	HB_TAG('K','O','M',' ')},	/* Komi [macrolanguage] */
+  {"kvb",	HB_TAG('M','L','Y',' ')},	/* Kubu -> Malay */
+  {"kvr",	HB_TAG('M','L','Y',' ')},	/* Kerinci -> Malay */
+  {"kw",	HB_TAG('C','O','R',' ')},	/* Cornish */
+  {"kwy",	HB_TAG('K','O','N','0')},	/* San Salvador Kongo -> Kongo */
+  {"kxc",	HB_TAG('K','M','S',' ')},	/* Konso -> Komso */
+  {"kxd",	HB_TAG('M','L','Y',' ')},	/* Brunei -> Malay */
+  {"kxu",	HB_TAG('K','U','I',' ')},	/* Kui (India) */
+  {"ky",	HB_TAG('K','I','R',' ')},	/* Kirghiz (Kyrgyz) */
+/*{"kyu",	HB_TAG('K','Y','U',' ')},*/	/* Western Kayah */
+  {"la",	HB_TAG('L','A','T',' ')},	/* Latin */
+  {"lad",	HB_TAG('J','U','D',' ')},	/* Ladino */
+  {"lb",	HB_TAG('L','T','Z',' ')},	/* Luxembourgish */
+  {"lbe",	HB_TAG('L','A','K',' ')},	/* Lak */
+  {"lbj",	HB_TAG('L','D','K',' ')},	/* Ladakhi */
+  {"lbl",	HB_TAG('B','I','K',' ')},	/* Libon Bikol -> Bikol */
+  {"lce",	HB_TAG('M','L','Y',' ')},	/* Loncong -> Malay */
+  {"lcf",	HB_TAG('M','L','Y',' ')},	/* Lubu -> Malay */
+  {"ldi",	HB_TAG('K','O','N','0')},	/* Laari -> Kongo */
+/*{"lez",	HB_TAG('L','E','Z',' ')},*/	/* Lezghian -> Lezgi */
+  {"lg",	HB_TAG('L','U','G',' ')},	/* Ganda */
+  {"li",	HB_TAG('L','I','M',' ')},	/* Limburgish */
+  {"lif",	HB_TAG('L','M','B',' ')},	/* Limbu */
+/*{"lij",	HB_TAG('L','I','J',' ')},*/	/* Ligurian */
+/*{"lis",	HB_TAG('L','I','S',' ')},*/	/* Lisu */
+  {"liw",	HB_TAG('M','L','Y',' ')},	/* Col -> Malay */
+/*{"ljp",	HB_TAG('L','J','P',' ')},*/	/* Lampung Api -> Lampung */
+  {"lkb",	HB_TAG('L','U','H',' ')},	/* Kabras -> Luyia */
+/*{"lki",	HB_TAG('L','K','I',' ')},*/	/* Laki */
+  {"lko",	HB_TAG('L','U','H',' ')},	/* Khayo -> Luyia */
+  {"lks",	HB_TAG('L','U','H',' ')},	/* Kisa -> Luyia */
+  {"lld",	HB_TAG('L','A','D',' ')},	/* Ladin */
+  {"lmn",	HB_TAG('L','A','M',' ')},	/* Lambadi -> Lambani */
+/*{"lmo",	HB_TAG('L','M','O',' ')},*/	/* Lombard */
+  {"ln",	HB_TAG('L','I','N',' ')},	/* Lingala */
+  {"lo",	HB_TAG('L','A','O',' ')},	/* Lao */
+/*{"lom",	HB_TAG('L','O','M',' ')},*/	/* Loma (Liberia) */
+/*{"lrc",	HB_TAG('L','R','C',' ')},*/	/* Northern Luri -> Luri */
+  {"lri",	HB_TAG('L','U','H',' ')},	/* Marachi -> Luyia */
+  {"lrm",	HB_TAG('L','U','H',' ')},	/* Marama -> Luyia */
+  {"lsm",	HB_TAG('L','U','H',' ')},	/* Saamia -> Luyia */
+  {"lt",	HB_TAG('L','T','H',' ')},	/* Lithuanian */
+  {"ltg",	HB_TAG('L','V','I',' ')},	/* Latgalian -> Latvian */
+  {"lto",	HB_TAG('L','U','H',' ')},	/* Tsotso -> Luyia */
+  {"lts",	HB_TAG('L','U','H',' ')},	/* Tachoni -> Luyia */
+  {"lu",	HB_TAG('L','U','B',' ')},	/* Luba-Katanga */
+/*{"lua",	HB_TAG('L','U','A',' ')},*/	/* Luba-Lulua */
+/*{"luo",	HB_TAG('L','U','O',' ')},*/	/* Luo (Kenya and Tanzania) */
+  {"lus",	HB_TAG('M','I','Z',' ')},	/* Lushai -> Mizo */
+  {"luy",	HB_TAG('L','U','H',' ')},	/* Luyia [macrolanguage] */
+  {"luz",	HB_TAG('L','R','C',' ')},	/* Southern Luri -> Luri */
+  {"lv",	HB_TAG('L','V','I',' ')},	/* Latvian [macrolanguage] */
+  {"lvs",	HB_TAG('L','V','I',' ')},	/* Standard Latvian -> Latvian */
+  {"lwg",	HB_TAG('L','U','H',' ')},	/* Wanga -> Luyia */
+  {"lzh",	HB_TAG('Z','H','T',' ')},	/* Literary Chinese -> Chinese Traditional */
+  {"lzz",	HB_TAG('L','A','Z',' ')},	/* Laz */
+/*{"mad",	HB_TAG('M','A','D',' ')},*/	/* Madurese -> Madura */
+/*{"mag",	HB_TAG('M','A','G',' ')},*/	/* Magahi */
+  {"mai",	HB_TAG('M','T','H',' ')},	/* Maithili */
+  {"mak",	HB_TAG('M','K','R',' ')},	/* Makasar */
+/*{"mam",	HB_TAG('M','A','M',' ')},*/	/* Mam */
+  {"man",	HB_TAG('M','N','K',' ')},	/* Mandingo [macrolanguage] -> Maninka */
+  {"max",	HB_TAG('M','L','Y',' ')},	/* North Moluccan Malay -> Malay */
+/*{"mbo",	HB_TAG('M','B','O',' ')},*/	/* Mbo (Cameroon) */
+  {"mct",	HB_TAG('B','T','I',' ')},	/* Mengisa -> Beti */
+  {"mdf",	HB_TAG('M','O','K',' ')},	/* Moksha */
+/*{"mdr",	HB_TAG('M','D','R',' ')},*/	/* Mandar */
+  {"mdy",	HB_TAG('M','L','E',' ')},	/* Male (Ethiopia) */
+  {"men",	HB_TAG('M','D','E',' ')},	/* Mende (Sierra Leone) */
+  {"meo",	HB_TAG('M','L','Y',' ')},	/* Kedah Malay -> Malay */
+/*{"mer",	HB_TAG('M','E','R',' ')},*/	/* Meru */
+/*{"mfa",	HB_TAG('M','F','A',' ')},*/	/* Pattani Malay */
+  {"mfb",	HB_TAG('M','L','Y',' ')},	/* Bangka -> Malay */
+/*{"mfe",	HB_TAG('M','F','E',' ')},*/	/* Morisyen */
+  {"mg",	HB_TAG('M','L','G',' ')},	/* Malagasy [macrolanguage] */
+  {"mh",	HB_TAG('M','A','H',' ')},	/* Marshallese */
+  {"mhr",	HB_TAG('L','M','A',' ')},	/* Eastern Mari -> Low Mari */
+  {"mhv",	HB_TAG('A','R','K',' ')},	/* Arakanese (retired code) -> Rakhine */
+  {"mi",	HB_TAG('M','R','I',' ')},	/* Maori */
+/*{"min",	HB_TAG('M','I','N',' ')},*/	/* Minangkabau */
+  {"mk",	HB_TAG('M','K','D',' ')},	/* Macedonian */
+  {"mku",	HB_TAG('M','N','K',' ')},	/* Konyanka Maninka -> Maninka */
+/*{"mkw",	HB_TAG('M','K','W',' ')},*/	/* Kituba (Congo) */
+  {"ml",	HB_TAG('M','A','L',' ')},	/* Malayalam -> Malayalam Traditional */
+  {"ml",	HB_TAG('M','L','R',' ')},	/* Malayalam -> Malayalam Reformed */
+  {"mlq",	HB_TAG('M','L','N',' ')},	/* Western Maninkakan -> Malinke */
+  {"mlq",	HB_TAG('M','N','K',' ')},	/* Western Maninkakan -> Maninka */
+  {"mmr",	HB_TAG('H','M','N',' ')},	/* Western Xiangxi Miao -> Hmong */
+  {"mn",	HB_TAG('M','N','G',' ')},	/* Mongolian [macrolanguage] */
+  {"mnc",	HB_TAG('M','C','H',' ')},	/* Manchu */
+/*{"mni",	HB_TAG('M','N','I',' ')},*/	/* Manipuri */
+  {"mnk",	HB_TAG('M','N','D',' ')},	/* Mandinka */
+  {"mnk",	HB_TAG('M','N','K',' ')},	/* Mandinka -> Maninka */
+  {"mnp",	HB_TAG('Z','H','S',' ')},	/* Min Bei Chinese -> Chinese Simplified */
+  {"mns",	HB_TAG('M','A','N',' ')},	/* Mansi */
+  {"mnw",	HB_TAG('M','O','N',' ')},	/* Mon */
+  {"mo",	HB_TAG('M','O','L',' ')},	/* Moldavian (retired code) */
+/*{"moh",	HB_TAG('M','O','H',' ')},*/	/* Mohawk */
+/*{"mos",	HB_TAG('M','O','S',' ')},*/	/* Mossi */
+  {"mpe",	HB_TAG('M','A','J',' ')},	/* Majang */
+  {"mqg",	HB_TAG('M','L','Y',' ')},	/* Kota Bangun Kutai Malay -> Malay */
+  {"mr",	HB_TAG('M','A','R',' ')},	/* Marathi */
+  {"mrh",	HB_TAG('Q','I','N',' ')},	/* Mara Chin -> Chin */
+  {"mrj",	HB_TAG('H','M','A',' ')},	/* Western Mari -> High Mari */
+  {"ms",	HB_TAG('M','L','Y',' ')},	/* Malay [macrolanguage] */
+  {"msc",	HB_TAG('M','N','K',' ')},	/* Sankaran Maninka -> Maninka */
+  {"msh",	HB_TAG('M','L','G',' ')},	/* Masikoro Malagasy -> Malagasy */
+  {"msi",	HB_TAG('M','L','Y',' ')},	/* Sabah Malay -> Malay */
+  {"mt",	HB_TAG('M','T','S',' ')},	/* Maltese */
+  {"mtr",	HB_TAG('M','A','W',' ')},	/* Mewari -> Marwari */
+  {"mui",	HB_TAG('M','L','Y',' ')},	/* Musi -> Malay */
+  {"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 */
+  {"mvb",	HB_TAG('A','T','H',' ')},	/* Mattole -> Athapaskan */
+  {"mve",	HB_TAG('M','A','W',' ')},	/* Marwari (Pakistan) */
+  {"mvf",	HB_TAG('M','N','G',' ')},	/* Peripheral Mongolian -> Mongolian */
+  {"mwk",	HB_TAG('M','N','K',' ')},	/* Kita Maninkakan -> Maninka */
+/*{"mwl",	HB_TAG('M','W','L',' ')},*/	/* Mirandese */
+  {"mwr",	HB_TAG('M','A','W',' ')},	/* Marwari [macrolanguage] */
+/*{"mww",	HB_TAG('M','W','W',' ')},*/	/* Hmong Daw */
+  {"my",	HB_TAG('B','R','M',' ')},	/* Burmese */
+  {"mym",	HB_TAG('M','E','N',' ')},	/* Me’en */
+/*{"myn",	HB_TAG('M','Y','N',' ')},*/	/* Mayan [family] */
+  {"myq",	HB_TAG('M','N','K',' ')},	/* Forest Maninka (retired code) -> Maninka */
+  {"myv",	HB_TAG('E','R','Z',' ')},	/* Erzya */
+/*{"mzn",	HB_TAG('M','Z','N',' ')},*/	/* Mazanderani */
+  {"na",	HB_TAG('N','A','U',' ')},	/* Nauru -> Nauruan */
+/*{"nag",	HB_TAG('N','A','G',' ')},*/	/* Naga Pidgin -> Naga-Assamese */
+/*{"nah",	HB_TAG('N','A','H',' ')},*/	/* Nahuatl [family] */
+  {"nan",	HB_TAG('Z','H','S',' ')},	/* Min Nan Chinese -> Chinese Simplified */
+/*{"nap",	HB_TAG('N','A','P',' ')},*/	/* Neapolitan */
+  {"nb",	HB_TAG('N','O','R',' ')},	/* Norwegian Bokmål -> Norwegian */
+  {"nd",	HB_TAG('N','D','B',' ')},	/* North Ndebele -> Ndebele */
+/*{"ndc",	HB_TAG('N','D','C',' ')},*/	/* Ndau */
+/*{"nds",	HB_TAG('N','D','S',' ')},*/	/* Low Saxon */
+  {"ne",	HB_TAG('N','E','P',' ')},	/* Nepali [macrolanguage] */
+/*{"new",	HB_TAG('N','E','W',' ')},*/	/* Newari */
+  {"ng",	HB_TAG('N','D','G',' ')},	/* Ndonga */
+/*{"nga",	HB_TAG('N','G','A',' ')},*/	/* Ngbaka */
+  {"ngl",	HB_TAG('L','M','W',' ')},	/* Lomwe */
+  {"ngo",	HB_TAG('S','X','T',' ')},	/* Ngoni -> Sutu */
+  {"nhd",	HB_TAG('G','U','A',' ')},	/* Chiripá -> Guarani */
+  {"niq",	HB_TAG('K','A','L',' ')},	/* Nandi -> Kalenjin */
+/*{"niu",	HB_TAG('N','I','U',' ')},*/	/* Niuean */
+  {"niv",	HB_TAG('G','I','L',' ')},	/* Gilyak */
+  {"njz",	HB_TAG('N','I','S',' ')},	/* Nyishi -> Nisi */
+  {"nl",	HB_TAG('N','L','D',' ')},	/* Dutch */
+  {"nle",	HB_TAG('L','U','H',' ')},	/* East Nyala -> Luyia */
+  {"nn",	HB_TAG('N','Y','N',' ')},	/* Norwegian Nynorsk (Nynorsk, Norwegian) */
+  {"no",	HB_TAG('N','O','R',' ')},	/* Norwegian [macrolanguage] */
+  {"nod",	HB_TAG('N','T','A',' ')},	/* Northern Thai -> Northern Tai */
+/*{"noe",	HB_TAG('N','O','E',' ')},*/	/* Nimadi */
+/*{"nog",	HB_TAG('N','O','G',' ')},*/	/* Nogai */
+/*{"nov",	HB_TAG('N','O','V',' ')},*/	/* Novial */
+  {"npi",	HB_TAG('N','E','P',' ')},	/* Nepali */
+  {"nqo",	HB_TAG('N','K','O',' ')},	/* N’Ko */
+  {"nr",	HB_TAG('N','D','B',' ')},	/* South Ndebele -> Ndebele */
+  {"nsk",	HB_TAG('N','A','S',' ')},	/* Naskapi */
+/*{"nso",	HB_TAG('N','S','O',' ')},*/	/* Pedi -> Sotho, Northern */
+  {"nv",	HB_TAG('N','A','V',' ')},	/* Navajo */
+  {"nv",	HB_TAG('A','T','H',' ')},	/* Navajo -> Athapaskan */
+  {"ny",	HB_TAG('C','H','I',' ')},	/* Chichewa (Chewa, Nyanja) */
+  {"nyd",	HB_TAG('L','U','H',' ')},	/* Nyore -> Luyia */
+/*{"nym",	HB_TAG('N','Y','M',' ')},*/	/* Nyamwezi */
+  {"nyn",	HB_TAG('N','K','L',' ')},	/* Nyankole */
+/*{"nza",	HB_TAG('N','Z','A',' ')},*/	/* Tigon Mbembe -> Mbembe Tigon */
+  {"oc",	HB_TAG('O','C','I',' ')},	/* Occitan (post 1500) */
+  {"oj",	HB_TAG('O','J','B',' ')},	/* Ojibwa [macrolanguage] -> Ojibway */
+/*{"ojb",	HB_TAG('O','J','B',' ')},*/	/* Northwestern Ojibwa -> Ojibway */
+  {"ojc",	HB_TAG('O','J','B',' ')},	/* Central Ojibwa -> Ojibway */
+  {"ojg",	HB_TAG('O','J','B',' ')},	/* Eastern Ojibwa -> Ojibway */
+  {"ojs",	HB_TAG('O','C','R',' ')},	/* Severn Ojibwa -> Oji-Cree */
+  {"ojw",	HB_TAG('O','J','B',' ')},	/* Western Ojibwa -> Ojibway */
+  {"oki",	HB_TAG('K','A','L',' ')},	/* Okiek -> Kalenjin */
+  {"okm",	HB_TAG('K','O','H',' ')},	/* Middle Korean (10th-16th cent.) -> Korean Old Hangul */
+  {"om",	HB_TAG('O','R','O',' ')},	/* Oromo [macrolanguage] */
+  {"or",	HB_TAG('O','R','I',' ')},	/* Odia (formerly Oriya) [macrolanguage] */
+  {"orc",	HB_TAG('O','R','O',' ')},	/* Orma -> Oromo */
+  {"orn",	HB_TAG('M','L','Y',' ')},	/* Orang Kanaq -> Malay */
+  {"ors",	HB_TAG('M','L','Y',' ')},	/* Orang Seletar -> Malay */
+  {"ory",	HB_TAG('O','R','I',' ')},	/* Odia (formerly Oriya) */
+  {"os",	HB_TAG('O','S','S',' ')},	/* Ossetian */
+  {"otw",	HB_TAG('O','J','B',' ')},	/* Ottawa -> Ojibway */
+  {"pa",	HB_TAG('P','A','N',' ')},	/* Punjabi */
+/*{"pag",	HB_TAG('P','A','G',' ')},*/	/* Pangasinan */
+/*{"pam",	HB_TAG('P','A','M',' ')},*/	/* Pampanga -> Pampangan */
+  {"pap",	HB_TAG('P','A','P','0')},	/* Papiamento -> Papiamentu */
+/*{"pau",	HB_TAG('P','A','U',' ')},*/	/* Palauan */
+  {"pbt",	HB_TAG('P','A','S',' ')},	/* Southern Pashto -> Pashto */
+  {"pbu",	HB_TAG('P','A','S',' ')},	/* Northern Pashto -> Pashto */
+/*{"pcc",	HB_TAG('P','C','C',' ')},*/	/* Bouyei */
+/*{"pcd",	HB_TAG('P','C','D',' ')},*/	/* Picard */
+  {"pce",	HB_TAG('P','L','G',' ')},	/* Ruching Palaung -> Palaung */
+  {"pck",	HB_TAG('Q','I','N',' ')},	/* Paite Chin -> Chin */
+/*{"pdc",	HB_TAG('P','D','C',' ')},*/	/* Pennsylvania German */
+  {"pel",	HB_TAG('M','L','Y',' ')},	/* Pekal -> Malay */
+  {"pes",	HB_TAG('F','A','R',' ')},	/* Iranian Persian -> Persian */
+  {"pga",	HB_TAG('A','R','A',' ')},	/* Sudanese Creole Arabic -> Arabic */
+/*{"phk",	HB_TAG('P','H','K',' ')},*/	/* Phake */
+  {"pi",	HB_TAG('P','A','L',' ')},	/* Pali */
+/*{"pih",	HB_TAG('P','I','H',' ')},*/	/* Pitcairn-Norfolk -> Norfolk */
+  {"pko",	HB_TAG('K','A','L',' ')},	/* Pökoot -> Kalenjin */
+  {"pl",	HB_TAG('P','L','K',' ')},	/* Polish */
+  {"pll",	HB_TAG('P','L','G',' ')},	/* Shwe Palaung -> Palaung */
+  {"plp",	HB_TAG('P','A','P',' ')},	/* Palpa */
+  {"plt",	HB_TAG('M','L','G',' ')},	/* Plateau Malagasy -> Malagasy */
+/*{"pms",	HB_TAG('P','M','S',' ')},*/	/* Piemontese */
+/*{"pnb",	HB_TAG('P','N','B',' ')},*/	/* Western Panjabi */
+/*{"poh",	HB_TAG('P','O','H',' ')},*/	/* Poqomchi' -> Pocomchi */
+/*{"pon",	HB_TAG('P','O','N',' ')},*/	/* Pohnpeian */
+  {"ppa",	HB_TAG('B','A','G',' ')},	/* Pao (retired code) -> Baghelkhandi */
+/*{"pro",	HB_TAG('P','R','O',' ')},*/	/* Old Provençal (to 1500) -> Provençal / Old Provençal */
+  {"prs",	HB_TAG('D','R','I',' ')},	/* Dari */
+  {"ps",	HB_TAG('P','A','S',' ')},	/* Pashto [macrolanguage] */
+  {"pse",	HB_TAG('M','L','Y',' ')},	/* Central Malay -> Malay */
+  {"pst",	HB_TAG('P','A','S',' ')},	/* Central Pashto -> Pashto */
+  {"pt",	HB_TAG('P','T','G',' ')},	/* Portuguese */
+/*{"pwo",	HB_TAG('P','W','O',' ')},*/	/* Pwo Western Karen -> Western Pwo Karen */
+  {"qu",	HB_TAG('Q','U','Z',' ')},	/* Quechua [macrolanguage] */
+  {"qub",	HB_TAG('Q','W','H',' ')},	/* Huallaga Huánuco Quechua -> Quechua (Peru) */
+/*{"quc",	HB_TAG('Q','U','C',' ')},*/	/* K’iche’ */
+  {"qud",	HB_TAG('Q','V','I',' ')},	/* Calderón Highland Quichua -> Quechua (Ecuador) */
+  {"quf",	HB_TAG('Q','U','Z',' ')},	/* Lambayeque Quechua -> Quechua */
+  {"qug",	HB_TAG('Q','V','I',' ')},	/* Chimborazo Highland Quichua -> Quechua (Ecuador) */
+/*{"quh",	HB_TAG('Q','U','H',' ')},*/	/* South Bolivian Quechua -> Quechua (Bolivia) */
+  {"quk",	HB_TAG('Q','U','Z',' ')},	/* Chachapoyas Quechua -> Quechua */
+  {"qul",	HB_TAG('Q','U','Z',' ')},	/* North Bolivian Quechua -> Quechua */
+  {"qup",	HB_TAG('Q','V','I',' ')},	/* Southern Pastaza Quechua -> Quechua (Ecuador) */
+  {"qur",	HB_TAG('Q','W','H',' ')},	/* Yanahuanca Pasco Quechua -> Quechua (Peru) */
+  {"qus",	HB_TAG('Q','U','H',' ')},	/* Santiago del Estero Quichua -> Quechua (Bolivia) */
+  {"quw",	HB_TAG('Q','V','I',' ')},	/* Tena Lowland Quichua -> Quechua (Ecuador) */
+  {"qux",	HB_TAG('Q','W','H',' ')},	/* Yauyos Quechua -> Quechua (Peru) */
+  {"quy",	HB_TAG('Q','U','Z',' ')},	/* Ayacucho Quechua -> Quechua */
+/*{"quz",	HB_TAG('Q','U','Z',' ')},*/	/* Cusco Quechua -> Quechua */
+  {"qva",	HB_TAG('Q','W','H',' ')},	/* Ambo-Pasco Quechua -> Quechua (Peru) */
+  {"qvc",	HB_TAG('Q','U','Z',' ')},	/* Cajamarca Quechua -> Quechua */
+  {"qve",	HB_TAG('Q','U','Z',' ')},	/* Eastern Apurímac Quechua -> Quechua */
+  {"qvh",	HB_TAG('Q','W','H',' ')},	/* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */
+/*{"qvi",	HB_TAG('Q','V','I',' ')},*/	/* Imbabura Highland Quichua -> Quechua (Ecuador) */
+  {"qvj",	HB_TAG('Q','V','I',' ')},	/* Loja Highland Quichua -> Quechua (Ecuador) */
+  {"qvl",	HB_TAG('Q','W','H',' ')},	/* Cajatambo North Lima Quechua -> Quechua (Peru) */
+  {"qvm",	HB_TAG('Q','W','H',' ')},	/* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */
+  {"qvn",	HB_TAG('Q','W','H',' ')},	/* North Junín Quechua -> Quechua (Peru) */
+  {"qvo",	HB_TAG('Q','V','I',' ')},	/* Napo Lowland Quechua -> Quechua (Ecuador) */
+  {"qvp",	HB_TAG('Q','W','H',' ')},	/* Pacaraos Quechua -> Quechua (Peru) */
+  {"qvs",	HB_TAG('Q','U','Z',' ')},	/* San Martín Quechua -> Quechua */
+  {"qvw",	HB_TAG('Q','W','H',' ')},	/* Huaylla Wanca Quechua -> Quechua (Peru) */
+  {"qvz",	HB_TAG('Q','V','I',' ')},	/* Northern Pastaza Quichua -> Quechua (Ecuador) */
+  {"qwa",	HB_TAG('Q','W','H',' ')},	/* Corongo Ancash Quechua -> Quechua (Peru) */
+  {"qwc",	HB_TAG('Q','U','Z',' ')},	/* Classical Quechua -> Quechua */
+/*{"qwh",	HB_TAG('Q','W','H',' ')},*/	/* Huaylas Ancash Quechua -> Quechua (Peru) */
+  {"qws",	HB_TAG('Q','W','H',' ')},	/* Sihuas Ancash Quechua -> Quechua (Peru) */
+  {"qxa",	HB_TAG('Q','W','H',' ')},	/* Chiquián Ancash Quechua -> Quechua (Peru) */
+  {"qxc",	HB_TAG('Q','W','H',' ')},	/* Chincha Quechua -> Quechua (Peru) */
+  {"qxh",	HB_TAG('Q','W','H',' ')},	/* Panao Huánuco Quechua -> Quechua (Peru) */
+  {"qxl",	HB_TAG('Q','V','I',' ')},	/* Salasaca Highland Quichua -> Quechua (Ecuador) */
+  {"qxn",	HB_TAG('Q','W','H',' ')},	/* Northern Conchucos Ancash Quechua -> Quechua (Peru) */
+  {"qxo",	HB_TAG('Q','W','H',' ')},	/* Southern Conchucos Ancash Quechua -> Quechua (Peru) */
+  {"qxp",	HB_TAG('Q','U','Z',' ')},	/* Puno Quechua -> Quechua */
+  {"qxr",	HB_TAG('Q','V','I',' ')},	/* Cañar Highland Quichua -> Quechua (Ecuador) */
+  {"qxt",	HB_TAG('Q','W','H',' ')},	/* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */
+  {"qxu",	HB_TAG('Q','U','Z',' ')},	/* Arequipa-La Unión Quechua -> Quechua */
+  {"qxw",	HB_TAG('Q','W','H',' ')},	/* Jauja Wanca Quechua -> Quechua (Peru) */
+  {"rag",	HB_TAG('L','U','H',' ')},	/* Logooli -> Luyia */
+/*{"raj",	HB_TAG('R','A','J',' ')},*/	/* Rajasthani [macrolanguage] */
+/*{"rar",	HB_TAG('R','A','R',' ')},*/	/* Rarotongan */
+  {"rbb",	HB_TAG('P','L','G',' ')},	/* Rumai Palaung -> Palaung */
+  {"rbl",	HB_TAG('B','I','K',' ')},	/* Miraya Bikol -> Bikol */
+/*{"rej",	HB_TAG('R','E','J',' ')},*/	/* Rejang */
+/*{"ria",	HB_TAG('R','I','A',' ')},*/	/* Riang (India) */
+/*{"rif",	HB_TAG('R','I','F',' ')},*/	/* Tarifit */
+/*{"rit",	HB_TAG('R','I','T',' ')},*/	/* Ritarungo */
+  {"rki",	HB_TAG('A','R','K',' ')},	/* Rakhine */
+/*{"rkw",	HB_TAG('R','K','W',' ')},*/	/* Arakwal */
+  {"rm",	HB_TAG('R','M','S',' ')},	/* Romansh */
+  {"rmc",	HB_TAG('R','O','Y',' ')},	/* Carpathian Romani -> Romany */
+  {"rmf",	HB_TAG('R','O','Y',' ')},	/* Kalo Finnish Romani -> Romany */
+  {"rml",	HB_TAG('R','O','Y',' ')},	/* Baltic Romani -> Romany */
+  {"rmn",	HB_TAG('R','O','Y',' ')},	/* Balkan Romani -> Romany */
+  {"rmo",	HB_TAG('R','O','Y',' ')},	/* Sinte Romani -> Romany */
+  {"rmw",	HB_TAG('R','O','Y',' ')},	/* Welsh Romani -> Romany */
+/*{"rmy",	HB_TAG('R','M','Y',' ')},*/	/* Vlax Romani */
+  {"rmz",	HB_TAG('A','R','K',' ')},	/* Marma -> Rakhine */
+  {"rn",	HB_TAG('R','U','N',' ')},	/* Rundi */
+  {"rnl",	HB_TAG('H','A','L',' ')},	/* Ranglong -> Halam (Falam Chin) */
+  {"ro",	HB_TAG('R','O','M',' ')},	/* Romanian */
+  {"rom",	HB_TAG('R','O','Y',' ')},	/* Romany [macrolanguage] */
+/*{"rtm",	HB_TAG('R','T','M',' ')},*/	/* Rotuman */
+  {"ru",	HB_TAG('R','U','S',' ')},	/* Russian */
+  {"rue",	HB_TAG('R','S','Y',' ')},	/* Rusyn */
+/*{"rup",	HB_TAG('R','U','P',' ')},*/	/* Aromanian */
+  {"rw",	HB_TAG('R','U','A',' ')},	/* Kinyarwanda */
+  {"rwr",	HB_TAG('M','A','W',' ')},	/* Marwari (India) */
+  {"sa",	HB_TAG('S','A','N',' ')},	/* Sanskrit */
+  {"sah",	HB_TAG('Y','A','K',' ')},	/* Yakut -> Sakha */
+  {"sam",	HB_TAG('P','A','A',' ')},	/* Samaritan Aramaic -> Palestinian Aramaic */
+/*{"sas",	HB_TAG('S','A','S',' ')},*/	/* Sasak */
+/*{"sat",	HB_TAG('S','A','T',' ')},*/	/* Santali */
+  {"sc",	HB_TAG('S','R','D',' ')},	/* Sardinian [macrolanguage] */
+  {"sck",	HB_TAG('S','A','D',' ')},	/* Sadri */
+/*{"scn",	HB_TAG('S','C','N',' ')},*/	/* Sicilian */
+/*{"sco",	HB_TAG('S','C','O',' ')},*/	/* Scots */
+  {"scs",	HB_TAG('S','C','S',' ')},	/* North Slavey */
+  {"scs",	HB_TAG('S','L','A',' ')},	/* North Slavey -> Slavey */
+  {"scs",	HB_TAG('A','T','H',' ')},	/* North Slavey -> Athapaskan */
+  {"sd",	HB_TAG('S','N','D',' ')},	/* Sindhi */
+  {"sdc",	HB_TAG('S','R','D',' ')},	/* Sassarese Sardinian -> Sardinian */
+  {"sdh",	HB_TAG('K','U','R',' ')},	/* Southern Kurdish -> Kurdish */
+  {"sdn",	HB_TAG('S','R','D',' ')},	/* Gallurese Sardinian -> Sardinian */
+  {"se",	HB_TAG('N','S','M',' ')},	/* Northern Sami */
+  {"seh",	HB_TAG('S','N','A',' ')},	/* Sena */
+  {"sek",	HB_TAG('A','T','H',' ')},	/* Sekani -> Athapaskan */
+/*{"sel",	HB_TAG('S','E','L',' ')},*/	/* Selkup */
+  {"sez",	HB_TAG('Q','I','N',' ')},	/* Senthang Chin -> Chin */
+  {"sfm",	HB_TAG('H','M','N',' ')},	/* Small Flowery Miao -> Hmong */
+  {"sg",	HB_TAG('S','G','O',' ')},	/* Sango */
+/*{"sga",	HB_TAG('S','G','A',' ')},*/	/* Old Irish (to 900) */
+  {"sgc",	HB_TAG('K','A','L',' ')},	/* Kipsigis -> Kalenjin */
+/*{"sgs",	HB_TAG('S','G','S',' ')},*/	/* Samogitian */
+  {"sgw",	HB_TAG('C','H','G',' ')},	/* Sebat Bet Gurage -> Chaha Gurage */
+  {"sgw",	HB_TAG('S','G','W',' ')},	/* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */
+/*{"shi",	HB_TAG('S','H','I',' ')},*/	/* Tachelhit */
+/*{"shn",	HB_TAG('S','H','N',' ')},*/	/* Shan */
+  {"shu",	HB_TAG('A','R','A',' ')},	/* Chadian Arabic -> Arabic */
+  {"si",	HB_TAG('S','N','H',' ')},	/* Sinhala (Sinhalese) */
+/*{"sid",	HB_TAG('S','I','D',' ')},*/	/* Sidamo */
+  {"sjd",	HB_TAG('K','S','M',' ')},	/* Kildin Sami */
+  {"sjo",	HB_TAG('S','I','B',' ')},	/* Xibe -> Sibe */
+  {"sk",	HB_TAG('S','K','Y',' ')},	/* Slovak */
+  {"skg",	HB_TAG('M','L','G',' ')},	/* Sakalava Malagasy -> Malagasy */
+  {"skr",	HB_TAG('S','R','K',' ')},	/* Saraiki */
+  {"sl",	HB_TAG('S','L','V',' ')},	/* Slovenian */
+  {"sm",	HB_TAG('S','M','O',' ')},	/* Samoan */
+  {"sma",	HB_TAG('S','S','M',' ')},	/* Southern Sami */
+  {"smj",	HB_TAG('L','S','M',' ')},	/* Lule Sami */
+  {"smn",	HB_TAG('I','S','M',' ')},	/* Inari Sami */
+  {"sms",	HB_TAG('S','K','S',' ')},	/* Skolt Sami */
+  {"sn",	HB_TAG('S','N','A','0')},	/* Shona */
+/*{"snk",	HB_TAG('S','N','K',' ')},*/	/* Soninke */
+  {"so",	HB_TAG('S','M','L',' ')},	/* Somali */
+/*{"sop",	HB_TAG('S','O','P',' ')},*/	/* Songe */
+  {"spv",	HB_TAG('O','R','I',' ')},	/* Sambalpuri -> Odia (formerly Oriya) */
+  {"spy",	HB_TAG('K','A','L',' ')},	/* Sabaot -> Kalenjin */
+  {"sq",	HB_TAG('S','Q','I',' ')},	/* Albanian [macrolanguage] */
+  {"sr",	HB_TAG('S','R','B',' ')},	/* Serbian */
+  {"src",	HB_TAG('S','R','D',' ')},	/* Logudorese Sardinian -> Sardinian */
+  {"sro",	HB_TAG('S','R','D',' ')},	/* Campidanese Sardinian -> Sardinian */
+/*{"srr",	HB_TAG('S','R','R',' ')},*/	/* Serer */
+  {"srs",	HB_TAG('A','T','H',' ')},	/* Sarsi -> Athapaskan */
+  {"ss",	HB_TAG('S','W','Z',' ')},	/* Swati */
+  {"ssh",	HB_TAG('A','R','A',' ')},	/* Shihhi Arabic -> Arabic */
+  {"st",	HB_TAG('S','O','T',' ')},	/* Southern Sotho -> Sotho, Southern */
+/*{"stq",	HB_TAG('S','T','Q',' ')},*/	/* Saterfriesisch -> Saterland Frisian */
+  {"stv",	HB_TAG('S','I','G',' ')},	/* Silt'e -> Silte Gurage */
+  {"su",	HB_TAG('S','U','N',' ')},	/* Sundanese */
+/*{"suk",	HB_TAG('S','U','K',' ')},*/	/* Sukuma */
+  {"suq",	HB_TAG('S','U','R',' ')},	/* Suri */
+  {"sv",	HB_TAG('S','V','E',' ')},	/* Swedish */
+/*{"sva",	HB_TAG('S','V','A',' ')},*/	/* Svan */
+  {"sw",	HB_TAG('S','W','K',' ')},	/* Swahili [macrolanguage] */
+  {"swb",	HB_TAG('C','M','R',' ')},	/* Maore Comorian -> Comorian */
+  {"swc",	HB_TAG('S','W','K',' ')},	/* Congo Swahili -> Swahili */
+  {"swh",	HB_TAG('S','W','K',' ')},	/* Swahili */
+  {"swv",	HB_TAG('M','A','W',' ')},	/* Shekhawati -> Marwari */
+/*{"sxu",	HB_TAG('S','X','U',' ')},*/	/* Upper Saxon */
+  {"syc",	HB_TAG('S','Y','R',' ')},	/* Classical Syriac -> Syriac */
+/*{"syl",	HB_TAG('S','Y','L',' ')},*/	/* Sylheti */
+/*{"syr",	HB_TAG('S','Y','R',' ')},*/	/* Syriac [macrolanguage] */
+/*{"szl",	HB_TAG('S','Z','L',' ')},*/	/* Silesian */
+  {"ta",	HB_TAG('T','A','M',' ')},	/* Tamil */
+  {"taa",	HB_TAG('A','T','H',' ')},	/* Lower Tanana -> Athapaskan */
+/*{"tab",	HB_TAG('T','A','B',' ')},*/	/* Tabassaran -> Tabasaran */
+  {"taq",	HB_TAG('T','M','H',' ')},	/* Tamasheq -> Tamashek */
+  {"tau",	HB_TAG('A','T','H',' ')},	/* Upper Tanana -> Athapaskan */
+  {"tcb",	HB_TAG('A','T','H',' ')},	/* Tanacross -> Athapaskan */
+  {"tce",	HB_TAG('A','T','H',' ')},	/* Southern Tutchone -> Athapaskan */
+  {"tcp",	HB_TAG('Q','I','N',' ')},	/* Tawr Chin -> Chin */
+  {"tcy",	HB_TAG('T','U','L',' ')},	/* Tulu -> Tumbuka */
+  {"tcz",	HB_TAG('Q','I','N',' ')},	/* Thado Chin -> Chin */
+/*{"tdd",	HB_TAG('T','D','D',' ')},*/	/* Tai Nüa -> Dehong Dai */
+  {"tdx",	HB_TAG('M','L','G',' ')},	/* Tandroy-Mahafaly Malagasy -> Malagasy */
+  {"te",	HB_TAG('T','E','L',' ')},	/* Telugu */
+  {"tec",	HB_TAG('K','A','L',' ')},	/* Terik -> Kalenjin */
+  {"tem",	HB_TAG('T','M','N',' ')},	/* Timne -> Temne */
+/*{"tet",	HB_TAG('T','E','T',' ')},*/	/* Tetum */
+  {"tfn",	HB_TAG('A','T','H',' ')},	/* Tanaina -> Athapaskan */
+  {"tg",	HB_TAG('T','A','J',' ')},	/* Tajik -> Tajiki */
+  {"tgj",	HB_TAG('N','I','S',' ')},	/* Tagin -> Nisi */
+  {"tgx",	HB_TAG('A','T','H',' ')},	/* Tagish -> Athapaskan */
+  {"th",	HB_TAG('T','H','A',' ')},	/* Thai */
+  {"tht",	HB_TAG('A','T','H',' ')},	/* Tahltan -> Athapaskan */
+  {"thv",	HB_TAG('T','M','H',' ')},	/* Tahaggart Tamahaq -> Tamashek */
+  {"thz",	HB_TAG('T','M','H',' ')},	/* Tayart Tamajeq -> Tamashek */
+  {"ti",	HB_TAG('T','G','Y',' ')},	/* Tigrinya */
+  {"tig",	HB_TAG('T','G','R',' ')},	/* Tigre */
+/*{"tiv",	HB_TAG('T','I','V',' ')},*/	/* Tiv */
+  {"tk",	HB_TAG('T','K','M',' ')},	/* Turkmen */
+  {"tkg",	HB_TAG('M','L','G',' ')},	/* Tesaka Malagasy -> Malagasy */
+  {"tl",	HB_TAG('T','G','L',' ')},	/* Tagalog */
+/*{"tmh",	HB_TAG('T','M','H',' ')},*/	/* Tamashek [macrolanguage] */
+  {"tmw",	HB_TAG('M','L','Y',' ')},	/* Temuan -> Malay */
+  {"tn",	HB_TAG('T','N','A',' ')},	/* Tswana */
+  {"tnf",	HB_TAG('D','R','I',' ')},	/* Tangshewi (retired code) -> Dari */
+  {"to",	HB_TAG('T','G','N',' ')},	/* Tonga (Tonga Islands) -> Tongan */
+  {"tod",	HB_TAG('T','O','D','0')},	/* Toma */
+  {"toi",	HB_TAG('T','N','G',' ')},	/* Tonga (Zambia) */
+  {"tol",	HB_TAG('A','T','H',' ')},	/* Tolowa -> Athapaskan */
+/*{"tpi",	HB_TAG('T','P','I',' ')},*/	/* Tok Pisin */
+  {"tr",	HB_TAG('T','R','K',' ')},	/* 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 */
+/*{"tsj",	HB_TAG('T','S','J',' ')},*/	/* Tshangla */
+  {"tt",	HB_TAG('T','A','T',' ')},	/* Tatar */
+  {"ttm",	HB_TAG('A','T','H',' ')},	/* Northern Tutchone -> Athapaskan */
+  {"ttq",	HB_TAG('T','M','H',' ')},	/* Tawallammat Tamajaq -> Tamashek */
+/*{"tum",	HB_TAG('T','U','M',' ')},*/	/* Tumbuka -> Tulu */
+  {"tuu",	HB_TAG('A','T','H',' ')},	/* Tututni -> Athapaskan */
+  {"tuy",	HB_TAG('K','A','L',' ')},	/* Tugen -> Kalenjin */
+/*{"tvl",	HB_TAG('T','V','L',' ')},*/	/* Tuvalu */
+  {"tw",	HB_TAG('T','W','I',' ')},	/* Twi */
+  {"tw",	HB_TAG('A','K','A',' ')},	/* Twi -> Akan */
+  {"txc",	HB_TAG('A','T','H',' ')},	/* Tsetsaut -> Athapaskan */
+  {"txy",	HB_TAG('M','L','G',' ')},	/* Tanosy Malagasy -> Malagasy */
+  {"ty",	HB_TAG('T','H','T',' ')},	/* Tahitian */
+  {"tyv",	HB_TAG('T','U','V',' ')},	/* Tuvinian -> Tuvin */
+/*{"tyz",	HB_TAG('T','Y','Z',' ')},*/	/* Tày */
+/*{"tzm",	HB_TAG('T','Z','M',' ')},*/	/* Central Atlas Tamazight -> Tamazight */
+/*{"tzo",	HB_TAG('T','Z','O',' ')},*/	/* Tzotzil */
+  {"ubl",	HB_TAG('B','I','K',' ')},	/* Buhi'non Bikol -> Bikol */
+/*{"udm",	HB_TAG('U','D','M',' ')},*/	/* Udmurt */
+  {"ug",	HB_TAG('U','Y','G',' ')},	/* Uyghur */
+  {"uk",	HB_TAG('U','K','R',' ')},	/* Ukrainian */
+/*{"umb",	HB_TAG('U','M','B',' ')},*/	/* Umbundu */
+  {"unr",	HB_TAG('M','U','N',' ')},	/* Mundari */
+  {"ur",	HB_TAG('U','R','D',' ')},	/* Urdu */
+  {"urk",	HB_TAG('M','L','Y',' ')},	/* Urak Lawoi' -> Malay */
+  {"uz",	HB_TAG('U','Z','B',' ')},	/* Uzbek [macrolanguage] */
+  {"uzn",	HB_TAG('U','Z','B',' ')},	/* Northern Uzbek -> Uzbek */
+  {"uzs",	HB_TAG('U','Z','B',' ')},	/* Southern Uzbek -> Uzbek */
+  {"ve",	HB_TAG('V','E','N',' ')},	/* Venda */
+/*{"vec",	HB_TAG('V','E','C',' ')},*/	/* Venetian */
+  {"vi",	HB_TAG('V','I','T',' ')},	/* Vietnamese */
+  {"vkk",	HB_TAG('M','L','Y',' ')},	/* Kaur -> Malay */
+  {"vkt",	HB_TAG('M','L','Y',' ')},	/* Tenggarong Kutai Malay -> Malay */
+  {"vls",	HB_TAG('F','L','E',' ')},	/* Vlaams -> Dutch (Flemish) */
+  {"vmw",	HB_TAG('M','A','K',' ')},	/* Makhuwa */
+  {"vo",	HB_TAG('V','O','L',' ')},	/* Volapük */
+/*{"vro",	HB_TAG('V','R','O',' ')},*/	/* Võro */
+  {"wa",	HB_TAG('W','L','N',' ')},	/* Walloon */
+/*{"war",	HB_TAG('W','A','R',' ')},*/	/* Waray (Philippines) -> Waray-Waray */
+  {"wbm",	HB_TAG('W','A',' ',' ')},	/* Wa */
+  {"wbr",	HB_TAG('W','A','G',' ')},	/* Wagdi */
+  {"wlc",	HB_TAG('C','M','R',' ')},	/* Mwali Comorian -> Comorian */
+  {"wle",	HB_TAG('S','I','G',' ')},	/* Wolane -> Silte Gurage */
+  {"wlk",	HB_TAG('A','T','H',' ')},	/* Wailaki -> Athapaskan */
+  {"wni",	HB_TAG('C','M','R',' ')},	/* Ndzwani Comorian -> Comorian */
+  {"wo",	HB_TAG('W','L','F',' ')},	/* Wolof */
+  {"wry",	HB_TAG('M','A','W',' ')},	/* Merwari -> Marwari */
+  {"wsg",	HB_TAG('G','O','N',' ')},	/* Adilabad Gondi -> Gondi */
+/*{"wtm",	HB_TAG('W','T','M',' ')},*/	/* Mewati */
+  {"wuu",	HB_TAG('Z','H','S',' ')},	/* Wu Chinese -> Chinese Simplified */
+  {"xal",	HB_TAG('K','L','M',' ')},	/* Kalmyk */
+  {"xal",	HB_TAG('T','O','D',' ')},	/* Kalmyk -> Todo */
+  {"xan",	HB_TAG('S','E','K',' ')},	/* Xamtanga -> Sekota */
+  {"xh",	HB_TAG('X','H','S',' ')},	/* Xhosa */
+/*{"xjb",	HB_TAG('X','J','B',' ')},*/	/* Minjungbal -> Minjangbal */
+/*{"xkf",	HB_TAG('X','K','F',' ')},*/	/* Khengkha */
+  {"xmm",	HB_TAG('M','L','Y',' ')},	/* Manado Malay -> Malay */
+  {"xmv",	HB_TAG('M','L','G',' ')},	/* Antankarana Malagasy -> Malagasy */
+  {"xmw",	HB_TAG('M','L','G',' ')},	/* Tsimihety Malagasy -> Malagasy */
+  {"xnr",	HB_TAG('D','G','R',' ')},	/* Kangri -> Dogri */
+/*{"xog",	HB_TAG('X','O','G',' ')},*/	/* Soga */
+/*{"xpe",	HB_TAG('X','P','E',' ')},*/	/* Liberia Kpelle -> Kpelle (Liberia) */
+  {"xsl",	HB_TAG('S','S','L',' ')},	/* South Slavey */
+  {"xsl",	HB_TAG('S','L','A',' ')},	/* South Slavey -> Slavey */
+  {"xsl",	HB_TAG('A','T','H',' ')},	/* South Slavey -> Athapaskan */
+  {"xst",	HB_TAG('S','I','G',' ')},	/* Silt'e (retired code) -> Silte Gurage */
+  {"xwo",	HB_TAG('T','O','D',' ')},	/* Written Oirat -> Todo */
+/*{"yao",	HB_TAG('Y','A','O',' ')},*/	/* Yao */
+/*{"yap",	HB_TAG('Y','A','P',' ')},*/	/* Yapese */
+  {"ybd",	HB_TAG('A','R','K',' ')},	/* Yangbye (retired code) -> Rakhine */
+  {"ydd",	HB_TAG('J','I','I',' ')},	/* Eastern Yiddish -> Yiddish */
+  {"yi",	HB_TAG('J','I','I',' ')},	/* Yiddish [macrolanguage] */
+  {"yih",	HB_TAG('J','I','I',' ')},	/* Western Yiddish -> Yiddish */
+  {"yo",	HB_TAG('Y','B','A',' ')},	/* Yoruba */
+  {"yos",	HB_TAG('Q','I','N',' ')},	/* Yos (retired code) -> Chin */
+  {"yrk",	HB_TAG('T','N','E',' ')},	/* Nenets -> Tundra Nenets */
+  {"yrk",	HB_TAG('F','N','E',' ')},	/* Nenets -> Forest Nenets */
+  {"yue",	HB_TAG('Z','H','H',' ')},	/* Yue Chinese -> Chinese, Hong Kong SAR */
+  {"za",	HB_TAG('Z','H','A',' ')},	/* Zhuang [macrolanguage] */
+  {"zch",	HB_TAG('Z','H','A',' ')},	/* Central Hongshuihe Zhuang -> Zhuang */
+  {"zdj",	HB_TAG('C','M','R',' ')},	/* Ngazidja Comorian -> Comorian */
+/*{"zea",	HB_TAG('Z','E','A',' ')},*/	/* Zeeuws -> Zealandic */
+  {"zeh",	HB_TAG('Z','H','A',' ')},	/* Eastern Hongshuihe Zhuang -> Zhuang */
+  {"zgb",	HB_TAG('Z','H','A',' ')},	/* Guibei Zhuang -> Zhuang */
+/*{"zgh",	HB_TAG('Z','G','H',' ')},*/	/* Standard Moroccan Tamazight */
+  {"zgm",	HB_TAG('Z','H','A',' ')},	/* Minz Zhuang -> Zhuang */
+  {"zgn",	HB_TAG('Z','H','A',' ')},	/* Guibian Zhuang -> Zhuang */
+  {"zh",	HB_TAG('Z','H','S',' ')},	/* Chinese [macrolanguage] -> Chinese Simplified */
+  {"zhd",	HB_TAG('Z','H','A',' ')},	/* Dai Zhuang -> Zhuang */
+  {"zhn",	HB_TAG('Z','H','A',' ')},	/* Nong Zhuang -> Zhuang */
+  {"zlj",	HB_TAG('Z','H','A',' ')},	/* Liujiang Zhuang -> Zhuang */
+  {"zlm",	HB_TAG('M','L','Y',' ')},	/* Malay */
+  {"zln",	HB_TAG('Z','H','A',' ')},	/* Lianshan Zhuang -> Zhuang */
+  {"zlq",	HB_TAG('Z','H','A',' ')},	/* Liuqian Zhuang -> Zhuang */
+  {"zmi",	HB_TAG('M','L','Y',' ')},	/* Negeri Sembilan Malay -> Malay */
+  {"zne",	HB_TAG('Z','N','D',' ')},	/* Zande */
+  {"zom",	HB_TAG('Q','I','N',' ')},	/* Zou -> Chin */
+  {"zqe",	HB_TAG('Z','H','A',' ')},	/* Qiubei Zhuang -> Zhuang */
+  {"zsm",	HB_TAG('M','L','Y',' ')},	/* Standard Malay -> Malay */
+  {"zu",	HB_TAG('Z','U','L',' ')},	/* Zulu */
+  {"zum",	HB_TAG('L','R','C',' ')},	/* Kumzari -> Luri */
+  {"zyb",	HB_TAG('Z','H','A',' ')},	/* Yongbei Zhuang -> Zhuang */
+  {"zyg",	HB_TAG('Z','H','A',' ')},	/* Yang Zhuang -> Zhuang */
+  {"zyj",	HB_TAG('Z','H','A',' ')},	/* Youjiang Zhuang -> Zhuang */
+  {"zyn",	HB_TAG('Z','H','A',' ')},	/* Yongnan Zhuang -> Zhuang */
+/*{"zza",	HB_TAG('Z','Z','A',' ')},*/	/* Zazaki [macrolanguage] */
+  {"zzj",	HB_TAG('Z','H','A',' ')},	/* Zuojiang Zhuang -> Zhuang */
 };
 
-static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == 3u, "");
-
 /**
  * hb_ot_tags_from_complex_language:
  * @lang_str: a BCP 47 language tag to convert.
@@ -1934,7 +1932,8 @@
  *
  * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to
  * many language tags) and the best tag is not the alphabetically first, or if
- * the best tag consists of multiple subtags.
+ * the best tag consists of multiple subtags, or if the best tag does not appear
+ * in #ot_languages.
  *
  * Return value: The #hb_language_t corresponding to the BCP 47 language tag,
  * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.
@@ -1944,6 +1943,8 @@
 {
   switch (tag)
   {
+  case HB_TAG('A','L','T',' '):  /* Altai */
+    return hb_language_from_string ("alt", -1);  /* Southern Altai */
   case HB_TAG('A','P','P','H'):  /* Phonetic transcription—Americanist conventions */
     return hb_language_from_string ("und-fonnapa", -1);  /* Undetermined; North American Phonetic Alphabet */
   case HB_TAG('A','R','A',' '):  /* Arabic */
@@ -1962,8 +1963,6 @@
     return hb_language_from_string ("din", -1);  /* Dinka */
   case HB_TAG('D','R','I',' '):  /* Dari */
     return hb_language_from_string ("prs", -1);  /* Dari */
-  case HB_TAG('D','U','J',' '):  /* Dhuwal */
-    return hb_language_from_string ("dwu", -1);  /* Dhuwal */
   case HB_TAG('D','Z','N',' '):  /* Dzongkha */
     return hb_language_from_string ("dz", -1);  /* Dzongkha */
   case HB_TAG('E','T','I',' '):  /* Estonian */
@@ -1972,6 +1971,8 @@
     return hb_language_from_string ("gon", -1);  /* Gondi */
   case HB_TAG('H','M','N',' '):  /* Hmong */
     return hb_language_from_string ("hmn", -1);  /* Hmong */
+  case HB_TAG('H','N','D',' '):  /* Hindko */
+    return hb_language_from_string ("hnd", -1);  /* Southern Hindko */
   case HB_TAG('I','J','O',' '):  /* Ijo */
     return hb_language_from_string ("ijo", -1);  /* Ijo */
   case HB_TAG('I','N','U',' '):  /* Inuktitut */

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -113,6 +113,7 @@
   return HB_SCRIPT_UNKNOWN;
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 void
 hb_ot_tags_from_script (hb_script_t  script,
 			hb_tag_t    *script_tag_1,
@@ -124,6 +125,7 @@
   *script_tag_1 = count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_SCRIPT;
   *script_tag_2 = count > 1 ? tags[1] : HB_OT_TAG_DEFAULT_SCRIPT;
 }
+#endif
 
 /*
  * Complete list at:
@@ -198,7 +200,7 @@
 struct LangTag
 {
   char language[4];
-  hb_tag_t tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
+  hb_tag_t tag;
 
   int cmp (const char *a) const
   {
@@ -212,7 +214,7 @@
     p = strchr (b, '-');
     db = p ? (unsigned int) (p - b) : strlen (b);
 
-    return strncmp (a, b, MAX (da, db));
+    return strncmp (a, b, hb_max (da, db));
   }
   int cmp (const LangTag *that) const
   { return cmp (that->language); }
@@ -230,6 +232,7 @@
 /*{"??",	{HB_TAG('Y','I','C',' ')}},*/	/* Yi Classic */
 /*{"zh?",	{HB_TAG('Z','H','P',' ')}},*/	/* Chinese Phonetic */
 
+#ifndef HB_DISABLE_DEPRECATED
 hb_tag_t
 hb_ot_tag_from_language (hb_language_t language)
 {
@@ -238,6 +241,7 @@
   hb_ot_tags_from_script_and_language (HB_SCRIPT_UNKNOWN, language, nullptr, nullptr, &count, tags);
   return count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_LANGUAGE;
 }
+#endif
 
 static void
 hb_ot_tags_from_language (const char   *lang_str,
@@ -246,6 +250,7 @@
 			  hb_tag_t     *tags)
 {
   const char *s;
+  unsigned int tag_idx;
 
   /* Check for matches of multiple subtags. */
   if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags))
@@ -254,7 +259,6 @@
   /* Find a language matching in the first component. */
   s = strchr (lang_str, '-');
   {
-    const LangTag *lang_tag;
     if (s && limit - lang_str >= 6)
     {
       const char *extlang_end = strchr (s + 1, '-');
@@ -263,12 +267,18 @@
 	  ISALPHA (s[1]))
 	lang_str = s + 1;
     }
-    lang_tag = hb_sorted_array (ot_languages).bsearch (lang_str);
-    if (lang_tag)
+    if (hb_sorted_array (ot_languages).bfind (lang_str, &tag_idx))
     {
       unsigned int i;
-      for (i = 0; i < *count && lang_tag->tags[i] != HB_TAG_NONE; i++)
-	tags[i] = lang_tag->tags[i];
+      while (tag_idx != 0 &&
+	     0 == strcmp (ot_languages[tag_idx].language, ot_languages[tag_idx - 1].language))
+	tag_idx--;
+      for (i = 0;
+	   i < *count &&
+	   tag_idx + i < ARRAY_LENGTH (ot_languages) &&
+	   0 == strcmp (ot_languages[tag_idx + i].language, ot_languages[tag_idx].language);
+	   i++)
+	tags[i] = ot_languages[tag_idx + i].tag;
       *count = i;
       return;
     }
@@ -417,20 +427,33 @@
   }
 
   for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
-    if (ot_languages[i].tags[0] == tag)
+    if (ot_languages[i].tag == tag)
       return hb_language_from_string (ot_languages[i].language, -1);
 
-  /* Else return a custom language in the form of "x-hbotABCD" */
+  /* If it's three letters long, assume it's ISO 639-3 and lower-case and use it
+   * (if it's not a registered tag, calling hb_ot_tag_from_language on the
+   * result might not return the same tag as the original tag).
+   * Else return a custom language in the form of "x-hbotABCD". */
   {
-    unsigned char buf[11] = "x-hbot";
+    char buf[11] = "x-hbot";
+    char *str = buf;
     buf[6] = tag >> 24;
     buf[7] = (tag >> 16) & 0xFF;
     buf[8] = (tag >> 8) & 0xFF;
     buf[9] = tag & 0xFF;
     if (buf[9] == 0x20)
+    {
       buf[9] = '\0';
+      if (ISALPHA (buf[6]) && ISALPHA (buf[7]) && ISALPHA (buf[8]))
+      {
+	buf[6] = TOLOWER (buf[6]);
+	buf[7] = TOLOWER (buf[7]);
+	buf[8] = TOLOWER (buf[8]);
+	str += 6;
+      }
+    }
     buf[10] = '\0';
-    return hb_language_from_string ((char *) buf, -1);
+    return hb_language_from_string (str, -1);
   }
 }
 
@@ -506,7 +529,7 @@
   for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages); i++)
   {
     int c = ot_languages[i].cmp (&ot_languages[i - 1]);
-    if (c >= 0)
+    if (c > 0)
     {
       fprintf (stderr, "ot_languages not sorted at index %d: %s %d %s\n",
 	       i, ot_languages[i-1].language, c, ot_languages[i].language);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -123,7 +123,7 @@
 
   void map_coords (int *coords, unsigned int coords_length) const
   {
-    unsigned int count = MIN<unsigned int> (coords_length, axisCount);
+    unsigned int count = hb_min (coords_length, axisCount);
 
     const SegmentMaps *map = &firstAxisSegmentMaps;
     for (unsigned int i = 0; i < count; i++)

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -114,6 +114,7 @@
 
   unsigned int get_axis_count () const { return axisCount; }
 
+#ifndef HB_DISABLE_DEPRECATED
   void get_axis_deprecated (unsigned int axis_index,
 				   hb_ot_var_axis_t *info) const
   {
@@ -120,11 +121,12 @@
     const AxisRecord &axis = get_axes ()[axis_index];
     info->tag = axis.axisTag;
     info->name_id =  axis.axisNameID;
-    info->default_value = axis.defaultValue / 65536.;
+    info->default_value = axis.defaultValue / 65536.f;
     /* Ensure order, to simplify client math. */
-    info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
-    info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
+    info->min_value = hb_min (info->default_value, axis.minValue / 65536.f);
+    info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f);
   }
+#endif
 
   void get_axis_info (unsigned int axis_index,
 		      hb_ot_var_axis_info_t *info) const
@@ -134,13 +136,14 @@
     info->tag = axis.axisTag;
     info->name_id =  axis.axisNameID;
     info->flags = (hb_ot_var_axis_flags_t) (unsigned int) axis.flags;
-    info->default_value = axis.defaultValue / 65536.;
+    info->default_value = axis.defaultValue / 65536.f;
     /* Ensure order, to simplify client math. */
-    info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
-    info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
+    info->min_value = hb_min (info->default_value, axis.minValue / 65536.f);
+    info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f);
     info->reserved = 0;
   }
 
+#ifndef HB_DISABLE_DEPRECATED
   unsigned int get_axes_deprecated (unsigned int      start_offset,
 				    unsigned int     *axes_count /* IN/OUT */,
 				    hb_ot_var_axis_t *axes_array /* OUT */) const
@@ -149,12 +152,12 @@
     {
       /* TODO Rewrite as hb_array_t<>::sub-array() */
       unsigned int count = axisCount;
-      start_offset = MIN (start_offset, count);
+      start_offset = hb_min (start_offset, count);
 
       count -= start_offset;
       axes_array += start_offset;
 
-      count = MIN (count, *axes_count);
+      count = hb_min (count, *axes_count);
       *axes_count = count;
 
       for (unsigned int i = 0; i < count; i++)
@@ -162,6 +165,7 @@
     }
     return axisCount;
   }
+#endif
 
   unsigned int get_axis_infos (unsigned int           start_offset,
 			       unsigned int          *axes_count /* IN/OUT */,
@@ -171,12 +175,12 @@
     {
       /* TODO Rewrite as hb_array_t<>::sub-array() */
       unsigned int count = axisCount;
-      start_offset = MIN (start_offset, count);
+      start_offset = hb_min (start_offset, count);
 
       count -= start_offset;
       axes_array += start_offset;
 
-      count = MIN (count, *axes_count);
+      count = hb_min (count, *axes_count);
       *axes_count = count;
 
       for (unsigned int i = 0; i < count; i++)
@@ -185,6 +189,7 @@
     return axisCount;
   }
 
+#ifndef HB_DISABLE_DEPRECATED
   bool find_axis_deprecated (hb_tag_t tag,
 			     unsigned int *axis_index,
 			     hb_ot_var_axis_t *info) const
@@ -203,6 +208,7 @@
       *axis_index = HB_OT_VAR_NO_AXIS_INDEX;
     return false;
   }
+#endif
 
   bool find_axis_info (hb_tag_t tag,
 		       hb_ot_var_axis_info_t *info) const
@@ -223,7 +229,7 @@
     hb_ot_var_axis_info_t axis;
     get_axis_info (axis_index, &axis);
 
-    v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */
+    v = hb_max (hb_min (v, axis.max_value), axis.min_value); /* Clamp. */
 
     if (v == axis.default_value)
       return 0;
@@ -253,8 +259,8 @@
   }
 
   unsigned int get_instance_coords (unsigned int  instance_index,
-					   unsigned int *coords_length, /* IN/OUT */
-					   float        *coords         /* OUT */) const
+				    unsigned int *coords_length, /* IN/OUT */
+				    float        *coords         /* OUT */) const
   {
     const InstanceRecord *instance = get_instance (instance_index);
     if (unlikely (!instance))
@@ -274,6 +280,27 @@
     return axisCount;
   }
 
+  void collect_name_ids (hb_set_t *nameids) const
+  {
+    if (!has_data ()) return;
+
+    + get_axes ()
+    | hb_map (&AxisRecord::axisNameID)
+    | hb_sink (nameids)
+    ;
+
+    + hb_range ((unsigned) instanceCount)
+    | hb_map ([this] (const unsigned _) { return get_instance_subfamily_name_id (_); })
+    | hb_sink (nameids)
+    ;
+
+    + hb_range ((unsigned) instanceCount)
+    | hb_map ([this] (const unsigned _) { return get_instance_postscript_name_id (_); })
+    | hb_sink (nameids)
+    ;
+  }
+
+
   protected:
   hb_array_t<const AxisRecord> get_axes () const
   { return hb_array (&(this+firstAxis), axisCount); }

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -75,6 +75,7 @@
   return face->table.fvar->get_axis_count ();
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_ot_var_get_axes:
  *
@@ -104,6 +105,7 @@
 {
   return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info);
 }
+#endif
 
 /**
  * hb_ot_var_get_axis_infos:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -81,11 +81,11 @@
     if (unlikely (!c.extend_min (*subset_table)))
       return false;
 
-    subset_table->version.major.set (1);
-    subset_table->version.minor.set (0);
+    subset_table->version.major = 1;
+    subset_table->version.minor = 0;
 
-    subset_table->defaultVertOriginY.set (vorg_table->defaultVertOriginY);
-    subset_table->vertYOrigins.len.set (subset_metrics.length);
+    subset_table->defaultVertOriginY = vorg_table->defaultVertOriginY;
+    subset_table->vertYOrigins.len = subset_metrics.length;
 
     bool success = true;
     if (subset_metrics.length > 0)
@@ -130,8 +130,8 @@
         if (plan->new_gid_for_old_gid (old_glyph, &new_glyph))
         {
           VertOriginMetric *metrics = subset_metrics.push ();
-          metrics->glyph.set (new_glyph);
-          metrics->vertOriginY.set (vertYOrigins[i].vertOriginY);
+          metrics->glyph = new_glyph;
+          metrics->vertOriginY = vertYOrigins[i].vertOriginY;
         }
       }
     }

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,102 @@
+/*
+ * Copyright © 2019  Facebook, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_POOL_HH
+#define HB_POOL_HH
+
+#include "hb.hh"
+
+/* Memory pool for persistent allocation of small objects. */
+
+template <typename T, unsigned ChunkLen = 16>
+struct hb_pool_t
+{
+  hb_pool_t () : next (nullptr) {}
+  ~hb_pool_t () { fini (); }
+
+  void fini ()
+  {
+    next = nullptr;
+
+    + hb_iter (chunks)
+    | hb_apply ([] (chunk_t *_) { ::free (_); })
+    ;
+
+    chunks.fini ();
+  }
+
+  T* alloc ()
+  {
+    if (unlikely (!next))
+    {
+      if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr;
+      chunk_t *chunk = (chunk_t *) calloc (1, sizeof (chunk_t));
+      if (unlikely (!chunk)) return nullptr;
+      chunks.push (chunk);
+      next = chunk->thread ();
+    }
+
+    T* obj = next;
+    next = * ((T**) next);
+
+    memset (obj, 0, sizeof (T));
+
+    return obj;
+  }
+
+  void free (T* obj)
+  {
+    * (T**) obj = next;
+    next = obj;
+  }
+
+  private:
+
+  static_assert (ChunkLen > 1, "");
+  static_assert (sizeof (T) >= sizeof (void *), "");
+  static_assert (alignof (T) % sizeof (void *) == 0, "");
+
+  struct chunk_t
+  {
+    T* thread ()
+    {
+      for (unsigned i = 0; i < ARRAY_LENGTH (arrayZ) - 1; i++)
+        * (T**) &arrayZ[i] = &arrayZ[i + 1];
+
+      * (T**) &arrayZ[ARRAY_LENGTH (arrayZ) - 1] = nullptr;
+
+      return arrayZ;
+    }
+
+    T arrayZ[ChunkLen];
+  };
+
+  T* next;
+  hb_vector_t<chunk_t *> chunks;
+};
+
+
+#endif /* HB_POOL_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,401 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2012,2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SANITIZE_HH
+#define HB_SANITIZE_HH
+
+#include "hb.hh"
+#include "hb-blob.hh"
+#include "hb-dispatch.hh"
+
+
+/*
+ * Sanitize
+ *
+ *
+ * === Introduction ===
+ *
+ * The sanitize machinery is at the core of our zero-cost font loading.  We
+ * mmap() font file into memory and create a blob out of it.  Font subtables
+ * are returned as a readonly sub-blob of the main font blob.  These table
+ * blobs are then sanitized before use, to ensure invalid memory access does
+ * not happen.  The toplevel sanitize API use is like, eg. to load the 'head'
+ * table:
+ *
+ *   hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (face);
+ *
+ * The blob then can be converted to a head table struct with:
+ *
+ *   const head *head_table = head_blob->as<head> ();
+ *
+ * What the reference_table does is, to call hb_face_reference_table() to load
+ * the table blob, sanitize it and return either the sanitized blob, or empty
+ * blob if sanitization failed.  The blob->as() function returns the null
+ * object of its template type argument if the blob is empty.  Otherwise, it
+ * just casts the blob contents to the desired type.
+ *
+ * Sanitizing a blob of data with a type T works as follows (with minor
+ * simplification):
+ *
+ *   - Cast blob content to T*, call sanitize() method of it,
+ *   - If sanitize succeeded, return blob.
+ *   - Otherwise, if blob is not writable, try making it writable,
+ *     or copy if cannot be made writable in-place,
+ *   - Call sanitize() again.  Return blob if sanitize succeeded.
+ *   - Return empty blob otherwise.
+ *
+ *
+ * === The sanitize() contract ===
+ *
+ * The sanitize() method of each object type shall return true if it's safe to
+ * call other methods of the object, and false otherwise.
+ *
+ * Note that what sanitize() checks for might align with what the specification
+ * describes as valid table data, but does not have to be.  In particular, we
+ * do NOT want to be pedantic and concern ourselves with validity checks that
+ * are irrelevant to our use of the table.  On the contrary, we want to be
+ * lenient with error handling and accept invalid data to the extent that it
+ * does not impose extra burden on us.
+ *
+ * Based on the sanitize contract, one can see that what we check for depends
+ * on how we use the data in other table methods.  Ie. if other table methods
+ * assume that offsets do NOT point out of the table data block, then that's
+ * something sanitize() must check for (GSUB/GPOS/GDEF/etc work this way).  On
+ * the other hand, if other methods do such checks themselves, then sanitize()
+ * does not have to bother with them (glyf/local work this way).  The choice
+ * depends on the table structure and sanitize() performance.  For example, to
+ * check glyf/loca offsets in sanitize() would cost O(num-glyphs).  We try hard
+ * to avoid such costs during font loading.  By postponing such checks to the
+ * actual glyph loading, we reduce the sanitize cost to O(1) and total runtime
+ * cost to O(used-glyphs).  As such, this is preferred.
+ *
+ * The same argument can be made re GSUB/GPOS/GDEF, but there, the table
+ * structure is so complicated that by checking all offsets at sanitize() time,
+ * we make the code much simpler in other methods, as offsets and referenced
+ * objects do not need to be validated at each use site.
+ */
+
+/* This limits sanitizing time on really broken fonts. */
+#ifndef HB_SANITIZE_MAX_EDITS
+#define HB_SANITIZE_MAX_EDITS 32
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_FACTOR
+#define HB_SANITIZE_MAX_OPS_FACTOR 8
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_MIN
+#define HB_SANITIZE_MAX_OPS_MIN 16384
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_MAX
+#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
+#endif
+
+struct hb_sanitize_context_t :
+       hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
+{
+  hb_sanitize_context_t () :
+	debug_depth (0),
+	start (nullptr), end (nullptr),
+	max_ops (0),
+	writable (false), edit_count (0),
+	blob (nullptr),
+	num_glyphs (65536),
+	num_glyphs_set (false) {}
+
+  const char *get_name () { return "SANITIZE"; }
+  template <typename T, typename F>
+  bool may_dispatch (const T *obj HB_UNUSED, const F *format)
+  { return format->sanitize (this); }
+  static return_t default_return_value () { return true; }
+  static return_t no_dispatch_return_value () { return false; }
+  bool stop_sublookup_iteration (const return_t r) const { return !r; }
+
+  private:
+  template <typename T, typename ...Ts> auto
+  _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
+  ( obj.sanitize (this, hb_forward<Ts> (ds)...) )
+  template <typename T, typename ...Ts> auto
+  _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
+  ( obj.dispatch (this, hb_forward<Ts> (ds)...) )
+  public:
+  template <typename T, typename ...Ts> auto
+  dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
+  ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) )
+
+
+  void init (hb_blob_t *b)
+  {
+    this->blob = hb_blob_reference (b);
+    this->writable = false;
+  }
+
+  void set_num_glyphs (unsigned int num_glyphs_)
+  {
+    num_glyphs = num_glyphs_;
+    num_glyphs_set = true;
+  }
+  unsigned int get_num_glyphs () { return num_glyphs; }
+
+  void set_max_ops (int max_ops_) { max_ops = max_ops_; }
+
+  template <typename T>
+  void set_object (const T *obj)
+  {
+    reset_object ();
+
+    if (!obj) return;
+
+    const char *obj_start = (const char *) obj;
+    if (unlikely (obj_start < this->start || this->end <= obj_start))
+      this->start = this->end = nullptr;
+    else
+    {
+      this->start = obj_start;
+      this->end   = obj_start + hb_min (size_t (this->end - obj_start), obj->get_size ());
+    }
+  }
+
+  void reset_object ()
+  {
+    this->start = this->blob->data;
+    this->end = this->start + this->blob->length;
+    assert (this->start <= this->end); /* Must not overflow. */
+  }
+
+  void start_processing ()
+  {
+    reset_object ();
+    this->max_ops = hb_max ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
+			 (unsigned) HB_SANITIZE_MAX_OPS_MIN);
+    this->edit_count = 0;
+    this->debug_depth = 0;
+
+    DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
+		     "start [%p..%p] (%lu bytes)",
+		     this->start, this->end,
+		     (unsigned long) (this->end - this->start));
+  }
+
+  void end_processing ()
+  {
+    DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
+		     "end [%p..%p] %u edit requests",
+		     this->start, this->end, this->edit_count);
+
+    hb_blob_destroy (this->blob);
+    this->blob = nullptr;
+    this->start = this->end = nullptr;
+  }
+
+  unsigned get_edit_count () { return edit_count; }
+
+  bool check_range (const void *base,
+		    unsigned int len) const
+  {
+    const char *p = (const char *) base;
+    bool ok = !len ||
+	      (this->start <= p &&
+	       p <= this->end &&
+	       (unsigned int) (this->end - p) >= len &&
+	       this->max_ops-- > 0);
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+		     "check_range [%p..%p]"
+		     " (%d bytes) in [%p..%p] -> %s",
+		     p, p + len, len,
+		     this->start, this->end,
+		     ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
+
+  template <typename T>
+  bool check_range (const T *base,
+		    unsigned int a,
+		    unsigned int b) const
+  {
+    return !hb_unsigned_mul_overflows (a, b) &&
+	   this->check_range (base, a * b);
+  }
+
+  template <typename T>
+  bool check_range (const T *base,
+		    unsigned int a,
+		    unsigned int b,
+		    unsigned int c) const
+  {
+    return !hb_unsigned_mul_overflows (a, b) &&
+	   this->check_range (base, a * b, c);
+  }
+
+  template <typename T>
+  bool check_array (const T *base, unsigned int len) const
+  {
+    return this->check_range (base, len, hb_static_size (T));
+  }
+
+  template <typename T>
+  bool check_array (const T *base,
+		    unsigned int a,
+		    unsigned int b) const
+  {
+    return this->check_range (base, a, b, hb_static_size (T));
+  }
+
+  template <typename Type>
+  bool check_struct (const Type *obj) const
+  { return likely (this->check_range (obj, obj->min_size)); }
+
+  bool may_edit (const void *base, unsigned int len)
+  {
+    if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
+      return false;
+
+    const char *p = (const char *) base;
+    this->edit_count++;
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+       "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
+       this->edit_count,
+       p, p + len, len,
+       this->start, this->end,
+       this->writable ? "GRANTED" : "DENIED");
+
+    return this->writable;
+  }
+
+  template <typename Type, typename ValueType>
+  bool try_set (const Type *obj, const ValueType &v)
+  {
+    if (this->may_edit (obj, hb_static_size (Type)))
+    {
+      * const_cast<Type *> (obj) = v;
+      return true;
+    }
+    return false;
+  }
+
+  template <typename Type>
+  hb_blob_t *sanitize_blob (hb_blob_t *blob)
+  {
+    bool sane;
+
+    init (blob);
+
+  retry:
+    DEBUG_MSG_FUNC (SANITIZE, start, "start");
+
+    start_processing ();
+
+    if (unlikely (!start))
+    {
+      end_processing ();
+      return blob;
+    }
+
+    Type *t = reinterpret_cast<Type *> (const_cast<char *> (start));
+
+    sane = t->sanitize (this);
+    if (sane)
+    {
+      if (edit_count)
+      {
+	DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %d edits; going for second round", edit_count);
+
+        /* sanitize again to ensure no toe-stepping */
+        edit_count = 0;
+	sane = t->sanitize (this);
+	if (edit_count) {
+	  DEBUG_MSG_FUNC (SANITIZE, start, "requested %d edits in second round; FAILLING", edit_count);
+	  sane = false;
+	}
+      }
+    }
+    else
+    {
+      if (edit_count && !writable) {
+        start = hb_blob_get_data_writable (blob, nullptr);
+	end = start + blob->length;
+
+	if (start)
+	{
+	  writable = true;
+	  /* ok, we made it writable by relocating.  try again */
+	  DEBUG_MSG_FUNC (SANITIZE, start, "retry");
+	  goto retry;
+	}
+      }
+    }
+
+    end_processing ();
+
+    DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED");
+    if (sane)
+    {
+      hb_blob_make_immutable (blob);
+      return blob;
+    }
+    else
+    {
+      hb_blob_destroy (blob);
+      return hb_blob_get_empty ();
+    }
+  }
+
+  template <typename Type>
+  hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
+  {
+    if (!num_glyphs_set)
+      set_num_glyphs (hb_face_get_glyph_count (face));
+    return sanitize_blob<Type> (hb_face_reference_table (face, tableTag));
+  }
+
+  mutable unsigned int debug_depth;
+  const char *start, *end;
+  mutable int max_ops;
+  private:
+  bool writable;
+  unsigned int edit_count;
+  hb_blob_t *blob;
+  unsigned int num_glyphs;
+  bool  num_glyphs_set;
+};
+
+struct hb_sanitize_with_object_t
+{
+  template <typename T>
+  hb_sanitize_with_object_t (hb_sanitize_context_t *c, const T& obj) : c (c)
+  { c->set_object (obj); }
+  ~hb_sanitize_with_object_t ()
+  { c->reset_object (); }
+
+  private:
+  hb_sanitize_context_t *c;
+};
+
+
+#endif /* HB_SANITIZE_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,473 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2012,2018  Google, Inc.
+ * Copyright © 2019  Facebook, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SERIALIZE_HH
+#define HB_SERIALIZE_HH
+
+#include "hb.hh"
+#include "hb-blob.hh"
+#include "hb-map.hh"
+#include "hb-pool.hh"
+
+
+/*
+ * Serialize
+ */
+
+struct hb_serialize_context_t
+{
+  typedef unsigned objidx_t;
+
+  struct range_t
+  {
+    char *head, *tail;
+  };
+
+  struct object_t : range_t
+  {
+    void fini () { links.fini (); }
+
+    bool operator == (const object_t &o) const
+    {
+      return (tail - head == o.tail - o.head)
+	  && (links.length == o.links.length)
+	  && 0 == hb_memcmp (head, o.head, tail - head)
+	  && links.as_bytes () == o.links.as_bytes ();
+    }
+    uint32_t hash () const
+    {
+      return hb_bytes_t (head, tail - head).hash () ^
+	     links.as_bytes ().hash ();
+    }
+
+    struct link_t
+    {
+      bool is_wide: 1;
+      unsigned position : 31;
+      unsigned bias;
+      objidx_t objidx;
+    };
+
+    hb_vector_t<link_t> links;
+    object_t *next;
+  };
+
+  range_t snapshot () { range_t s = {head, tail} ; return s; }
+
+
+  hb_serialize_context_t (void *start_, unsigned int size) :
+    start ((char *) start_),
+    end (start + size),
+    current (nullptr)
+  { reset (); }
+  ~hb_serialize_context_t () { fini (); }
+
+  void fini ()
+  {
+    ++ hb_iter (packed)
+    | hb_apply ([] (object_t *_) { _->fini (); })
+    ;
+    packed.fini ();
+    this->packed_map.fini ();
+
+    while (current)
+    {
+      auto *_ = current;
+      current = current->next;
+      _->fini ();
+    }
+    object_pool.fini ();
+  }
+
+  bool in_error () const { return !this->successful; }
+
+  void reset ()
+  {
+    this->successful = true;
+    this->ran_out_of_room = false;
+    this->head = this->start;
+    this->tail = this->end;
+    this->debug_depth = 0;
+
+    fini ();
+    this->packed.push (nullptr);
+  }
+
+  bool check_success (bool success)
+  { return this->successful && (success || (err_other_error (), false)); }
+
+  template <typename T1, typename T2>
+  bool check_equal (T1 &&v1, T2 &&v2)
+  { return check_success (v1 == v2); }
+
+  template <typename T1, typename T2>
+  bool check_assign (T1 &v1, T2 &&v2)
+  { return check_equal (v1 = v2, v2); }
+
+  template <typename T> bool propagate_error (T &&obj)
+  { return check_success (!hb_deref (obj).in_error ()); }
+
+  template <typename T1, typename... Ts> bool propagate_error (T1 &&o1, Ts&&... os)
+  { return propagate_error (hb_forward<T1> (o1)) &&
+	   propagate_error (hb_forward<Ts> (os)...); }
+
+  /* To be called around main operation. */
+  template <typename Type>
+  Type *start_serialize ()
+  {
+    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
+		     "start [%p..%p] (%lu bytes)",
+		     this->start, this->end,
+		     (unsigned long) (this->end - this->start));
+
+    assert (!current);
+    return push<Type> ();
+  }
+  void end_serialize ()
+  {
+    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
+		     "end [%p..%p] serialized %u bytes; %s",
+		     this->start, this->end,
+		     (unsigned) (this->head - this->start),
+		     this->successful ? "successful" : "UNSUCCESSFUL");
+
+    propagate_error (packed, packed_map);
+
+    if (unlikely (!current)) return;
+    assert (!current->next);
+
+    /* Only "pack" if there exist other objects... Otherwise, don't bother.
+     * Saves a move. */
+    if (packed.length <= 1)
+      return;
+
+    pop_pack ();
+
+    resolve_links ();
+  }
+
+  template <typename Type = void>
+  Type *push ()
+  {
+    object_t *obj = object_pool.alloc ();
+    if (unlikely (!obj))
+      check_success (false);
+    else
+    {
+      obj->head = head;
+      obj->tail = tail;
+      obj->next = current;
+      current = obj;
+    }
+    return start_embed<Type> ();
+  }
+  void pop_discard ()
+  {
+    object_t *obj = current;
+    if (unlikely (!obj)) return;
+    current = current->next;
+    revert (*obj);
+    object_pool.free (obj);
+  }
+  objidx_t pop_pack ()
+  {
+    object_t *obj = current;
+    if (unlikely (!obj)) return 0;
+    current = current->next;
+    obj->tail = head;
+    obj->next = nullptr;
+    unsigned len = obj->tail - obj->head;
+    head = obj->head; /* Rewind head. */
+
+    if (!len)
+    {
+      assert (!obj->links.length);
+      return 0;
+    }
+
+    objidx_t objidx = packed_map.get (obj);
+    if (objidx)
+    {
+      obj->fini ();
+      return objidx;
+    }
+
+    tail -= len;
+    memmove (tail, obj->head, len);
+
+    obj->head = tail;
+    obj->tail = tail + len;
+
+    packed.push (obj);
+
+    if (unlikely (packed.in_error ()))
+      return 0;
+
+    objidx = packed.length - 1;
+
+    packed_map.set (obj, objidx);
+
+    return objidx;
+  }
+
+  void revert (range_t snap)
+  {
+    assert (snap.head <= head);
+    assert (tail <= snap.tail);
+    head = snap.head;
+    tail = snap.tail;
+    discard_stale_objects ();
+  }
+
+  void discard_stale_objects ()
+  {
+    while (packed.length > 1 &&
+	   packed.tail ()->head < tail)
+    {
+      packed_map.del (packed.tail ());
+      assert (!packed.tail ()->next);
+      packed.tail ()->fini ();
+      packed.pop ();
+    }
+    if (packed.length > 1)
+      assert (packed.tail ()->head == tail);
+  }
+
+  template <typename T>
+  void add_link (T &ofs, objidx_t objidx, const void *base = nullptr)
+  {
+    static_assert (sizeof (T) == 2 || sizeof (T) == 4, "");
+
+    if (!objidx)
+      return;
+
+    assert (current);
+    assert (current->head <= (const char *) &ofs);
+
+    if (!base)
+      base = current->head;
+    else
+      assert (current->head <= (const char *) base);
+
+    auto& link = *current->links.push ();
+    link.is_wide = sizeof (T) == 4;
+    link.position = (const char *) &ofs - current->head;
+    link.bias = (const char *) base - current->head;
+    link.objidx = objidx;
+  }
+
+  void resolve_links ()
+  {
+    if (unlikely (in_error ())) return;
+
+    assert (!current);
+    assert (packed.length > 1);
+
+    for (const object_t* parent : ++hb_iter (packed))
+    {
+      for (const object_t::link_t &link : parent->links)
+      {
+	const object_t* child = packed[link.objidx];
+	assert (link.bias <= (size_t) (parent->tail - parent->head));
+	unsigned offset = (child->head - parent->head) - link.bias;
+
+	if (link.is_wide)
+	{
+	  auto &off = * ((BEInt<uint32_t, 4> *) (parent->head + link.position));
+	  assert (0 == off);
+	  check_assign (off, offset);
+	}
+	else
+	{
+	  auto &off = * ((BEInt<uint16_t, 2> *) (parent->head + link.position));
+	  assert (0 == off);
+	  check_assign (off, offset);
+	}
+      }
+    }
+  }
+
+  unsigned int length () const { return this->head - current->head; }
+
+  void align (unsigned int alignment)
+  {
+    unsigned int l = length () % alignment;
+    if (l)
+      allocate_size<void> (alignment - l);
+  }
+
+  template <typename Type = void>
+  Type *start_embed (const Type *obj HB_UNUSED = nullptr) const
+  { return reinterpret_cast<Type *> (this->head); }
+  template <typename Type>
+  Type *start_embed (const Type &obj) const
+  { return start_embed (hb_addressof (obj)); }
+
+  /* Following two functions exist to allow setting breakpoint on. */
+  void err_ran_out_of_room () { this->ran_out_of_room = true; }
+  void err_other_error () { this->successful = false; }
+
+  template <typename Type>
+  Type *allocate_size (unsigned int size)
+  {
+    if (unlikely (!this->successful)) return nullptr;
+
+    if (this->tail - this->head < ptrdiff_t (size))
+    {
+      err_ran_out_of_room ();
+      this->successful = false;
+      return nullptr;
+    }
+    memset (this->head, 0, size);
+    char *ret = this->head;
+    this->head += size;
+    return reinterpret_cast<Type *> (ret);
+  }
+
+  template <typename Type>
+  Type *allocate_min ()
+  {
+    return this->allocate_size<Type> (Type::min_size);
+  }
+
+  template <typename Type>
+  Type *embed (const Type *obj)
+  {
+    unsigned int size = obj->get_size ();
+    Type *ret = this->allocate_size<Type> (size);
+    if (unlikely (!ret)) return nullptr;
+    memcpy (ret, obj, size);
+    return ret;
+  }
+  template <typename Type>
+  Type *embed (const Type &obj)
+  { return embed (hb_addressof (obj)); }
+
+  template <typename Type, typename ...Ts> auto
+  _copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
+  (Type *, src.copy (this, hb_forward<Ts> (ds)...))
+
+  template <typename Type> auto
+  _copy (const Type &src, hb_priority<0>) -> decltype (&(src = src))
+  {
+    Type *ret = this->allocate_size<Type> (sizeof (Type));
+    if (unlikely (!ret)) return nullptr;
+    *ret = src;
+    return ret;
+  }
+
+  /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data
+   * instead of memcpy(). */
+  template <typename Type, typename ...Ts>
+  Type *copy (const Type &src, Ts&&... ds)
+  { return _copy (src, hb_prioritize, hb_forward<Ts> (ds)...); }
+  template <typename Type, typename ...Ts>
+  Type *copy (const Type *src, Ts&&... ds)
+  { return copy (*src, hb_forward<Ts> (ds)...); }
+
+  template <typename Type>
+  hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
+
+  template <typename Type>
+  Type *extend_size (Type *obj, unsigned int size)
+  {
+    assert (this->start <= (char *) obj);
+    assert ((char *) obj <= this->head);
+    assert ((char *) obj + size >= this->head);
+    if (unlikely (!this->allocate_size<Type> (((char *) obj) + size - this->head))) return nullptr;
+    return reinterpret_cast<Type *> (obj);
+  }
+  template <typename Type>
+  Type *extend_size (Type &obj, unsigned int size)
+  { return extend_size (hb_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)); }
+
+  template <typename Type, typename ...Ts>
+  Type *extend (Type *obj, Ts&&... ds)
+  { return extend_size (obj, obj->get_size (hb_forward<Ts> (ds)...)); }
+  template <typename Type, typename ...Ts>
+  Type *extend (Type &obj, Ts&&... ds)
+  { return extend (hb_addressof (obj), hb_forward<Ts> (ds)...); }
+
+  /* Output routines. */
+  hb_bytes_t copy_bytes () const
+  {
+    assert (this->successful);
+    /* Copy both items from head side and tail side... */
+    unsigned int len = (this->head - this->start)
+		     + (this->end  - this->tail);
+    char *p = (char *) malloc (len);
+    if (p)
+    {
+      memcpy (p, this->start, this->head - this->start);
+      memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
+    }
+    else
+      return hb_bytes_t ();
+    return hb_bytes_t (p, len);
+  }
+  template <typename Type>
+  Type *copy () const
+  { return reinterpret_cast<Type *> ((char *) copy_bytes ().arrayZ); }
+  hb_blob_t *copy_blob () const
+  {
+    hb_bytes_t b = copy_bytes ();
+    return hb_blob_create (b.arrayZ, b.length,
+			   HB_MEMORY_MODE_WRITABLE,
+			   (char *) b.arrayZ, free);
+  }
+
+  public: /* TODO Make private. */
+  char *start, *head, *tail, *end;
+  unsigned int debug_depth;
+  bool successful;
+  bool ran_out_of_room;
+
+  private:
+
+  /* Object memory pool. */
+  hb_pool_t<object_t> object_pool;
+
+  /* Stack of currently under construction objects. */
+  object_t *current;
+
+  /* Stack of packed objects.  Object 0 is always nil object. */
+  hb_vector_t<object_t *> packed;
+
+  /* Map view of packed objects. */
+  hb_hashmap_t<const object_t *, objidx_t, nullptr, 0> packed_map;
+};
+
+
+#endif /* HB_SERIALIZE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -389,6 +389,7 @@
   set->symmetric_difference (other);
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_set_invert:
  * @set: a set.
@@ -403,6 +404,7 @@
 hb_set_invert (hb_set_t *set HB_UNUSED)
 {
 }
+#endif
 
 /**
  * hb_set_get_population:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -28,6 +28,7 @@
 #define HB_SET_HH
 
 #include "hb.hh"
+#include "hb-machinery.hh"
 
 
 /*
@@ -39,7 +40,7 @@
 
 struct hb_set_t
 {
-  HB_NO_COPY_ASSIGN (hb_set_t);
+  HB_DELETE_COPY_ASSIGN (hb_set_t);
   hb_set_t ()  { init (); }
   ~hb_set_t () { fini (); }
 
@@ -69,7 +70,7 @@
 
     void add (hb_codepoint_t g) { elt (g) |= mask (g); }
     void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
-    bool has (hb_codepoint_t g) const { return !!(elt (g) & mask (g)); }
+    bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
 
     void add_range (hb_codepoint_t a, hb_codepoint_t b)
     {
@@ -186,7 +187,7 @@
   hb_object_header_t header;
   bool successful; /* Allocations successful */
   mutable unsigned int population;
-  hb_vector_t<page_map_t> page_map;
+  hb_sorted_vector_t<page_map_t> page_map;
   hb_vector_t<page_t> pages;
 
   void init_shallow ()
@@ -227,11 +228,18 @@
     return true;
   }
 
+  void reset ()
+  {
+    if (unlikely (hb_object_is_immutable (this)))
+      return;
+    clear ();
+    successful = true;
+  }
+
   void clear ()
   {
     if (unlikely (hb_object_is_immutable (this)))
       return;
-    successful = true;
     population = 0;
     page_map.resize (0);
     pages.resize (0);
@@ -301,7 +309,7 @@
       {
 	page->add (g);
 
-	array = (const T *) ((const char *) array + stride);
+	array = &StructAtOffsetUnaligned<T> (array, stride);
 	count--;
       }
       while (count && (g = *array, start <= g && g < end));
@@ -357,15 +365,26 @@
     for (unsigned int i = a; i < b + 1; i++)
       del (i);
   }
-  bool has (hb_codepoint_t g) const
+  bool get (hb_codepoint_t g) const
   {
     const page_t *page = page_for (g);
     if (!page)
       return false;
-    return page->has (g);
+    return page->get (g);
   }
-  bool intersects (hb_codepoint_t first,
-			  hb_codepoint_t last) const
+
+  /* Has interface. */
+  static constexpr bool SENTINEL = false;
+  typedef bool value_t;
+  value_t operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+  /* Predicate. */
+  bool operator () (hb_codepoint_t k) const { return has (k); }
+
+  /* Sink interface. */
+  hb_set_t& operator << (hb_codepoint_t v) { add (v); return *this; }
+
+  bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
   {
     hb_codepoint_t c = first - 1;
     return next (&c) && c <= last;
@@ -422,8 +441,8 @@
     return true;
   }
 
-  template <class Op>
-  void process (const hb_set_t *other)
+  template <typename Op>
+  void process (const Op& op, const hb_set_t *other)
   {
     if (unlikely (!successful)) return;
 
@@ -477,7 +496,7 @@
 	b--;
 	count--;
 	page_map[count] = page_map[a];
-	Op::process (page_at (count).v, page_at (a).v, other->page_at (b).v);
+	page_at (count).v = op (page_at (a).v, other->page_at (b).v);
       }
       else if (page_map[a - 1].major > other->page_map[b - 1].major)
       {
@@ -523,19 +542,19 @@
 
   void union_ (const hb_set_t *other)
   {
-    process<HbOpOr> (other);
+    process (hb_bitwise_or, other);
   }
   void intersect (const hb_set_t *other)
   {
-    process<HbOpAnd> (other);
+    process (hb_bitwise_and, other);
   }
   void subtract (const hb_set_t *other)
   {
-    process<HbOpMinus> (other);
+    process (hb_bitwise_sub, other);
   }
   void symmetric_difference (const hb_set_t *other)
   {
-    process<HbOpXor> (other);
+    process (hb_bitwise_xor, other);
   }
   bool next (hb_codepoint_t *codepoint) const
   {
@@ -671,27 +690,29 @@
   /*
    * Iterator implementation.
    */
-  struct const_iter_t : hb_sorted_iter_t<const_iter_t, const hb_codepoint_t>
+  struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
   {
-    const_iter_t (const hb_set_t &s_) :
-      s (s_), v (INVALID), l (s.get_population () + 1) { __next__ (); }
+    static constexpr bool is_sorted_iterator = true;
+    iter_t (const hb_set_t &s_ = Null(hb_set_t)) :
+      s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); }
 
-    typedef hb_codepoint_t __item_type__;
+    typedef hb_codepoint_t __item_t__;
     hb_codepoint_t __item__ () const { return v; }
     bool __more__ () const { return v != INVALID; }
-    void __next__ () { s.next (&v); if (l) l--; }
-    void __prev__ () { s.previous (&v); }
-    unsigned __len__ () { return l; }
+    void __next__ () { s->next (&v); if (l) l--; }
+    void __prev__ () { s->previous (&v); }
+    unsigned __len__ () const { return l; }
+    iter_t end () const { return iter_t (*s); }
+    bool operator != (const iter_t& o) const
+    { return s != o.s || v != o.v; }
 
     protected:
-    const hb_set_t &s;
+    const hb_set_t *s;
     hb_codepoint_t v;
     unsigned l;
   };
-  const_iter_t const_iter () const { return const_iter_t (*this); }
-  operator const_iter_t () const { return const_iter (); }
-  typedef const_iter_t iter_t;
-  iter_t iter () const { return const_iter (); }
+  iter_t iter () const { return iter_t (*this); }
+  operator iter_t () const { return iter (); }
 
   protected:
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -45,10 +45,6 @@
 #endif
 #ifdef HAVE_CORETEXT
 HB_SHAPER_IMPLEMENT (coretext)
-
-/* Only picks up fonts that have a "mort" or "morx" table.
-   Probably going to be removed https://github.com/harfbuzz/harfbuzz/issues/1478 */
-HB_SHAPER_IMPLEMENT (coretext_aat)
 #endif
 
 #ifdef HAVE_FALLBACK

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -37,6 +37,7 @@
 #include "hb-ot-maxp-table.hh"
 
 #ifndef HB_NO_VISIBILITY
+#include "hb-ot-name-language-static.hh"
 
 hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {};
 /*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {};

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -160,13 +160,13 @@
   TRACE_SERIALIZE (this);
   FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
   if (unlikely (p == nullptr)) return_trace (false);
-  p->nRanges ().set (fdselect_ranges.length);
+  p->nRanges () = fdselect_ranges.length;
   for (unsigned int i = 0; i < fdselect_ranges.length; i++)
   {
-    p->ranges[i].first.set (fdselect_ranges[i].glyph);
-    p->ranges[i].fd.set (fdselect_ranges[i].code);
+    p->ranges[i].first = fdselect_ranges[i].glyph;
+    p->ranges[i].fd = fdselect_ranges[i].code;
   }
-  p->sentinel().set (num_glyphs);
+  p->sentinel() = num_glyphs;
   return_trace (true);
 }
 
@@ -186,7 +186,7 @@
   TRACE_SERIALIZE (this);
   FDSelect  *p = c->allocate_min<FDSelect> ();
   if (unlikely (p == nullptr)) return_trace (false);
-  p->format.set (fdselect_format);
+  p->format = fdselect_format;
   size -= FDSelect::min_size;
 
   switch (fdselect_format)
@@ -205,7 +205,7 @@
 	{
 	  fd = fdselect_ranges[range_index++].code;
 	}
-	p->fds[i].set (fd);
+	p->fds[i] = fd;
       }
       break;
     }

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -209,7 +209,7 @@
       /* serialize the opcode */
       HBUINT8 *p = c->allocate_size<HBUINT8> (1);
       if (unlikely (p == nullptr)) return_trace (false);
-      p->set (OpCode_Private);
+      *p = OpCode_Private;
 
       return_trace (true);
     }

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -32,6 +32,8 @@
 #include "hb-subset-cff-common.hh"
 #include "hb-cff1-interp-cs.hh"
 
+#ifndef HB_NO_SUBSET_CFF
+
 using namespace CFF;
 
 struct remap_sid_t : remap_t
@@ -147,7 +149,7 @@
 	    return_trace (false);
 	  HBUINT8 *p = c->allocate_size<HBUINT8> (1);
 	  if (unlikely (p == nullptr)) return_trace (false);
-	  p->set (OpCode_Private);
+	  *p = OpCode_Private;
 	}
 	break;
 
@@ -351,7 +353,7 @@
       case OpCode_return:
 	param.current_parsed_str->add_op (op, env.str_ref);
 	param.current_parsed_str->set_parsed ();
-	env.returnFromSubr ();
+	env.return_from_subr ();
 	param.set_current_str (env, false);
 	break;
 
@@ -382,7 +384,7 @@
 				 cff1_biased_subrs_t& subrs, hb_set_t *closure)
   {
     byte_str_ref_t    str_ref = env.str_ref;
-    env.callSubr (subrs, type);
+    env.call_subr (subrs, type);
     param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
     hb_set_add (closure, env.context.subr_num);
     param.set_current_str (env, true);
@@ -394,8 +396,8 @@
 
 struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs, const OT::cff1::accelerator_subset_t, cff1_cs_interp_env_t, cff1_cs_opset_subr_subset_t, OpCode_endchar>
 {
-  cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc, const hb_subset_plan_t *plan)
-    : subr_subsetter_t (acc, plan) {}
+  cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
+    : subr_subsetter_t (acc_, plan_) {}
 
   static void finalize_parsed_str (cff1_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
   {
@@ -892,10 +894,10 @@
     return false;
 
   /* header */
-  cff->version.major.set (0x01);
-  cff->version.minor.set (0x00);
-  cff->nameIndex.set (cff->min_size);
-  cff->offSize.set (4); /* unused? */
+  cff->version.major = 0x01;
+  cff->version.minor = 0x00;
+  cff->nameIndex = cff->min_size;
+  cff->offSize = 4; /* unused? */
 
   /* name INDEX */
   {
@@ -912,7 +914,7 @@
   /* top dict INDEX */
   {
     assert (plan.offsets.topDictInfo.offset == (unsigned) (c.head - c.start));
-    CFF1IndexOf<TopDict> *dest = c.start_embed< CFF1IndexOf<TopDict> > ();
+    CFF1IndexOf<TopDict> *dest = c.start_embed< CFF1IndexOf<TopDict>> ();
     if (dest == nullptr) return false;
     cff1_top_dict_op_serializer_t topSzr;
     top_dict_modifiers_t  modifier (plan.offsets, plan.topDictModSIDs);
@@ -1064,7 +1066,7 @@
   return true;
 }
 
-static bool
+static inline bool
 _hb_subset_cff1 (const OT::cff1::accelerator_subset_t  &acc,
 		const char		*data,
 		hb_subset_plan_t	*plan,
@@ -1118,3 +1120,5 @@
 
   return result;
 }
+
+#endif

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -32,6 +32,8 @@
 #include "hb-subset-cff-common.hh"
 #include "hb-cff2-interp-cs.hh"
 
+#ifndef HB_NO_SUBSET_CFF
+
 using namespace CFF;
 
 struct cff2_sub_table_offsets_t : cff_sub_table_offsets_t
@@ -183,7 +185,7 @@
 
       case OpCode_return:
 	param.current_parsed_str->set_parsed ();
-	env.returnFromSubr ();
+	env.return_from_subr ();
 	param.set_current_str (env, false);
 	break;
 
@@ -213,7 +215,7 @@
 				 cff2_biased_subrs_t& subrs, hb_set_t *closure)
   {
     byte_str_ref_t    str_ref = env.str_ref;
-    env.callSubr (subrs, type);
+    env.call_subr (subrs, type);
     param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
     hb_set_add (closure, env.context.subr_num);
     param.set_current_str (env, true);
@@ -225,8 +227,8 @@
 
 struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs, const OT::cff2::accelerator_subset_t, cff2_cs_interp_env_t, cff2_cs_opset_subr_subset_t>
 {
-  cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc, const hb_subset_plan_t *plan)
-    : subr_subsetter_t (acc, plan) {}
+  cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
+    : subr_subsetter_t (acc_, plan_) {}
 
   static void finalize_parsed_str (cff2_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
   {
@@ -451,14 +453,14 @@
     return false;
 
   /* header */
-  cff2->version.major.set (0x02);
-  cff2->version.minor.set (0x00);
-  cff2->topDict.set (OT::cff2::static_size);
+  cff2->version.major = 0x02;
+  cff2->version.minor = 0x00;
+  cff2->topDict = OT::cff2::static_size;
 
   /* top dict */
   {
     assert (cff2->topDict == (unsigned) (c.head - c.start));
-    cff2->topDictSize.set (plan.offsets.topDictInfo.size);
+    cff2->topDictSize = plan.offsets.topDictInfo.size;
     TopDict &dict = cff2 + cff2->topDict;
     cff2_top_dict_op_serializer_t topSzr;
     if (unlikely (!dict.serialize (&c, acc.topDict, topSzr, plan.offsets)))
@@ -571,7 +573,7 @@
   return true;
 }
 
-static bool
+static inline bool
 _hb_subset_cff2 (const OT::cff2::accelerator_subset_t  &acc,
 		const char		      *data,
 		hb_subset_plan_t		*plan,
@@ -626,3 +628,5 @@
 
   return result;
 }
+
+#endif

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,346 +0,0 @@
-/*
- * Copyright © 2018  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Garret Rieger, Roderick Sheeter
- */
-
-#include "hb-open-type.hh"
-#include "hb-ot-glyf-table.hh"
-#include "hb-set.h"
-#include "hb-subset-glyf.hh"
-
-struct loca_data_t
-{
-  bool          is_short;
-  void         *data;
-  unsigned int  size;
-
-  inline bool
-  _write_loca_entry (unsigned int  id,
-                     unsigned int  offset)
-  {
-    unsigned int entry_size = is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32);
-    if ((id + 1) * entry_size <= size)
-    {
-      if (is_short) {
-        ((OT::HBUINT16*) data) [id].set (offset / 2);
-      } else {
-        ((OT::HBUINT32*) data) [id].set (offset);
-      }
-      return true;
-    }
-
-    // Offset was not written because the write is out of bounds.
-    DEBUG_MSG(SUBSET,
-              nullptr,
-              "WARNING: Attempted to write an out of bounds loca entry at index %d. Loca size is %d.",
-              id,
-              size);
-    return false;
-  }
-};
-
-/**
- * If hints are being dropped find the range which in glyf at which
- * the hinting instructions are located. Add them to the instruction_ranges
- * vector.
- */
-static bool
-_add_instructions_range (const OT::glyf::accelerator_t &glyf,
-                         hb_codepoint_t                 glyph_id,
-                         unsigned int                   glyph_start_offset,
-                         unsigned int                   glyph_end_offset,
-                         bool                           drop_hints,
-                         hb_vector_t<unsigned int>     *instruction_ranges /* OUT */)
-{
-  if (!instruction_ranges->resize (instruction_ranges->length + 2))
-  {
-    DEBUG_MSG(SUBSET, nullptr, "Failed to resize instruction_ranges.");
-    return false;
-  }
-  unsigned int *instruction_start = &(*instruction_ranges)[instruction_ranges->length - 2];
-  *instruction_start = 0;
-  unsigned int *instruction_end = &(*instruction_ranges)[instruction_ranges->length - 1];
-  *instruction_end = 0;
-
-  if (drop_hints)
-  {
-    if (unlikely (!glyf.get_instruction_offsets (glyph_start_offset, glyph_end_offset,
-                                                 instruction_start, instruction_end)))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", glyph_id);
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static bool
-_calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
-                                     const hb_subset_plan_t        *plan,
-                                     loca_data_t                   *loca_data, /* OUT */
-				     unsigned int                  *glyf_size /* OUT */,
-				     hb_vector_t<unsigned int>     *instruction_ranges /* OUT */)
-{
-  unsigned int total = 0;
-
-  hb_codepoint_t next_glyph = HB_SET_VALUE_INVALID;
-  while (plan->glyphset ()->next (&next_glyph))
-  {
-    unsigned int start_offset, end_offset;
-    if (unlikely (!(glyf.get_offsets (next_glyph, &start_offset, &end_offset) &&
-		    glyf.remove_padding (start_offset, &end_offset))))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
-      start_offset = end_offset = 0;
-    }
-
-    bool is_zero_length = end_offset - start_offset < OT::glyf::GlyphHeader::static_size;
-    if (!_add_instructions_range (glyf,
-                                  next_glyph,
-                                  start_offset,
-                                  end_offset,
-                                  plan->drop_hints && !is_zero_length,
-                                  instruction_ranges))
-      return false;
-
-    if (is_zero_length)
-      continue; /* 0-length glyph */
-
-    total += end_offset - start_offset
-             - ((*instruction_ranges)[instruction_ranges->length - 1]
-                - (*instruction_ranges)[instruction_ranges->length - 2]);
-    /* round2 so short loca will work */
-    total += total % 2;
-  }
-
-  *glyf_size = total;
-  loca_data->is_short = (total <= 131070);
-  loca_data->size = (plan->num_output_glyphs () + 1)
-      * (loca_data->is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32));
-
-  DEBUG_MSG(SUBSET, nullptr, "preparing to subset glyf: final size %d, loca size %d, using %s loca",
-	    total,
-	    loca_data->size,
-	    loca_data->is_short ? "short" : "long");
-  return true;
-}
-
-static void
-_update_components (const hb_subset_plan_t *plan,
-		    char                   *glyph_start,
-		    unsigned int            length)
-{
-  OT::glyf::CompositeGlyphHeader::Iterator iterator;
-  if (OT::glyf::CompositeGlyphHeader::get_iterator (glyph_start,
-						    length,
-						    &iterator))
-  {
-    do
-    {
-      hb_codepoint_t new_gid;
-      if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
-				      &new_gid))
-	continue;
-
-      ((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid);
-    } while (iterator.move_to_next ());
-  }
-}
-
-static bool _remove_composite_instruction_flag (char *glyf_prime, unsigned int length)
-{
-  /* remove WE_HAVE_INSTRUCTIONS from flags in dest */
-  OT::glyf::CompositeGlyphHeader::Iterator composite_it;
-  if (unlikely (!OT::glyf::CompositeGlyphHeader::get_iterator (glyf_prime, length, &composite_it))) return false;
-  const OT::glyf::CompositeGlyphHeader *glyph;
-  do {
-    glyph = composite_it.current;
-    OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&glyph->flags);
-    flags->set ( (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS);
-  } while (composite_it.move_to_next ());
-  return true;
-}
-
-static bool
-_write_glyf_and_loca_prime (const hb_subset_plan_t        *plan,
-			    const OT::glyf::accelerator_t &glyf,
-			    const char                    *glyf_data,
-			    hb_vector_t<unsigned int>     &instruction_ranges,
-			    unsigned int                   glyf_prime_size,
-			    char                          *glyf_prime_data /* OUT */,
-			    loca_data_t                   *loca_prime /* OUT */)
-{
-  char *glyf_prime_data_next = glyf_prime_data;
-
-  bool success = true;
-
-
-  unsigned int i = 0;
-  hb_codepoint_t new_gid;
-  for (new_gid = 0; new_gid < plan->num_output_glyphs (); new_gid++)
-  {
-    hb_codepoint_t old_gid;
-    if (!plan->old_gid_for_new_gid (new_gid, &old_gid))
-    {
-      // Empty glyph, add a loca entry and carry on.
-      loca_prime->_write_loca_entry (new_gid,
-                                     glyf_prime_data_next - glyf_prime_data);
-      continue;
-    }
-
-
-    unsigned int start_offset, end_offset;
-    if (unlikely (!(glyf.get_offsets (old_gid, &start_offset, &end_offset) &&
-		    glyf.remove_padding (start_offset, &end_offset))))
-      end_offset = start_offset = 0;
-
-    unsigned int instruction_start = instruction_ranges[i * 2];
-    unsigned int instruction_end = instruction_ranges[i * 2 + 1];
-
-    int length = end_offset - start_offset - (instruction_end - instruction_start);
-
-    if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size)
-    {
-      DEBUG_MSG(SUBSET,
-                nullptr,
-                "WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)",
-                i, length);
-      return false;
-    }
-
-    if (instruction_start == instruction_end)
-      memcpy (glyf_prime_data_next, glyf_data + start_offset, length);
-    else
-    {
-      memcpy (glyf_prime_data_next, glyf_data + start_offset, instruction_start - start_offset);
-      memcpy (glyf_prime_data_next + instruction_start - start_offset, glyf_data + instruction_end, end_offset - instruction_end);
-      /* if the instructions end at the end this was a composite glyph, else simple */
-      if (instruction_end == end_offset)
-      {
-	if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false;
-      }
-      else
-	/* zero instruction length, which is just before instruction_start */
-	memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);
-    }
-
-    success = success && loca_prime->_write_loca_entry (new_gid,
-                                                        glyf_prime_data_next - glyf_prime_data);
-    _update_components (plan, glyf_prime_data_next, length);
-
-    // TODO: don't align to two bytes if using long loca.
-    glyf_prime_data_next += length + (length % 2); // Align to 2 bytes for short loca.
-
-    i++;
-  }
-
-  // loca table has n+1 entries where the last entry signifies the end location of the last
-  // glyph.
-  success = success && loca_prime->_write_loca_entry (new_gid,
-                                                      glyf_prime_data_next - glyf_prime_data);
-  return success;
-}
-
-static bool
-_hb_subset_glyf_and_loca (const OT::glyf::accelerator_t  &glyf,
-			  const char                     *glyf_data,
-			  hb_subset_plan_t               *plan,
-			  bool                           *use_short_loca,
-			  hb_blob_t                     **glyf_prime_blob /* OUT */,
-			  hb_blob_t                     **loca_prime_blob /* OUT */)
-{
-  // TODO(grieger): Sanity check allocation size for the new table.
-  loca_data_t loca_prime;
-  unsigned int glyf_prime_size;
-  hb_vector_t<unsigned int> instruction_ranges;
-  instruction_ranges.init ();
-
-  if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
-                                                      plan,
-                                                      &loca_prime,
-						      &glyf_prime_size,
-						      &instruction_ranges))) {
-    instruction_ranges.fini ();
-    return false;
-  }
-  *use_short_loca = loca_prime.is_short;
-
-  char *glyf_prime_data = (char *) calloc (1, glyf_prime_size);
-  loca_prime.data = (void *) calloc (1, loca_prime.size);
-  if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data,
-					     instruction_ranges,
-					     glyf_prime_size, glyf_prime_data,
-					     &loca_prime))) {
-    free (glyf_prime_data);
-    free (loca_prime.data);
-    instruction_ranges.fini ();
-    return false;
-  }
-  instruction_ranges.fini ();
-
-  *glyf_prime_blob = hb_blob_create (glyf_prime_data,
-                                     glyf_prime_size,
-                                     HB_MEMORY_MODE_READONLY,
-                                     glyf_prime_data,
-                                     free);
-  *loca_prime_blob = hb_blob_create ((char *) loca_prime.data,
-                                     loca_prime.size,
-                                     HB_MEMORY_MODE_READONLY,
-                                     loca_prime.data,
-                                     free);
-  return true;
-}
-
-/**
- * hb_subset_glyf:
- * Subsets the glyph table according to a provided plan.
- *
- * Return value: subsetted glyf table.
- *
- * Since: 1.7.5
- **/
-bool
-hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
-			 bool             *use_short_loca, /* OUT */
-			 hb_blob_t       **glyf_prime, /* OUT */
-			 hb_blob_t       **loca_prime /* OUT */)
-{
-  hb_blob_t *glyf_blob = hb_sanitize_context_t ().reference_table<OT::glyf> (plan->source);
-  const char *glyf_data = hb_blob_get_data (glyf_blob, nullptr);
-
-  OT::glyf::accelerator_t glyf;
-  glyf.init (plan->source);
-  bool result = _hb_subset_glyf_and_loca (glyf,
-					  glyf_data,
-					  plan,
-					  use_short_loca,
-					  glyf_prime,
-					  loca_prime);
-
-  hb_blob_destroy (glyf_blob);
-  glyf.fini ();
-
-  return result;
-}

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -1,40 +0,0 @@
-/*
- * Copyright © 2018  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Garret Rieger
- */
-
-#ifndef HB_SUBSET_GLYF_HH
-#define HB_SUBSET_GLYF_HH
-
-#include "hb.hh"
-
-#include "hb-subset.hh"
-
-HB_INTERNAL bool
-hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
-			 bool             *use_short_loca, /* OUT */
-			 hb_blob_t       **glyf_prime      /* OUT */,
-			 hb_blob_t       **loca_prime      /* OUT */);
-
-#endif /* HB_SUBSET_GLYF_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -44,11 +44,45 @@
 
   input->unicodes = hb_set_create ();
   input->glyphs = hb_set_create ();
+  input->name_ids = hb_set_create ();
+  hb_set_add_range (input->name_ids, 0, 6);
+  input->drop_tables = hb_set_create ();
   input->drop_hints = false;
-  input->drop_layout = true;
   input->desubroutinize = false;
   input->retain_gids = false;
 
+  hb_tag_t default_drop_tables[] = {
+    // Layout disabled by default
+    HB_TAG ('G', 'S', 'U', 'B'),
+    HB_TAG ('G', 'P', 'O', 'S'),
+    HB_TAG ('G', 'D', 'E', 'F'),
+    HB_TAG ('m', 'o', 'r', 'x'),
+    HB_TAG ('m', 'o', 'r', 't'),
+    HB_TAG ('k', 'e', 'r', 'x'),
+    HB_TAG ('k', 'e', 'r', 'n'),
+
+    // Copied from fontTools:
+    HB_TAG ('B', 'A', 'S', 'E'),
+    HB_TAG ('J', 'S', 'T', 'F'),
+    HB_TAG ('D', 'S', 'I', 'G'),
+    HB_TAG ('E', 'B', 'D', 'T'),
+    HB_TAG ('E', 'B', 'L', 'C'),
+    HB_TAG ('E', 'B', 'S', 'C'),
+    HB_TAG ('S', 'V', 'G', ' '),
+    HB_TAG ('P', 'C', 'L', 'T'),
+    HB_TAG ('L', 'T', 'S', 'H'),
+    // Graphite tables
+    HB_TAG ('F', 'e', 'a', 't'),
+    HB_TAG ('G', 'l', 'a', 't'),
+    HB_TAG ('G', 'l', 'o', 'c'),
+    HB_TAG ('S', 'i', 'l', 'f'),
+    HB_TAG ('S', 'i', 'l', 'l'),
+    // Colour
+    HB_TAG ('s', 'b', 'i', 'x')
+  };
+
+  input->drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
+
   return input;
 }
 
@@ -81,6 +115,8 @@
 
   hb_set_destroy (subset_input->unicodes);
   hb_set_destroy (subset_input->glyphs);
+  hb_set_destroy (subset_input->name_ids);
+  hb_set_destroy (subset_input->drop_tables);
 
   free (subset_input);
 }
@@ -109,30 +145,29 @@
   return subset_input->glyphs;
 }
 
-HB_EXTERN void
-hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
-				hb_bool_t drop_hints)
+HB_EXTERN hb_set_t *
+hb_subset_input_nameid_set (hb_subset_input_t *subset_input)
 {
-  subset_input->drop_hints = drop_hints;
+  return subset_input->name_ids;
 }
 
-HB_EXTERN hb_bool_t
-hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input)
+HB_EXTERN hb_set_t *
+hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input)
 {
-  return subset_input->drop_hints;
+  return subset_input->drop_tables;
 }
 
 HB_EXTERN void
-hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
-				 hb_bool_t drop_layout)
+hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
+				hb_bool_t drop_hints)
 {
-  subset_input->drop_layout = drop_layout;
+  subset_input->drop_hints = drop_hints;
 }
 
 HB_EXTERN hb_bool_t
-hb_subset_input_get_drop_layout (hb_subset_input_t *subset_input)
+hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input)
 {
-  return subset_input->drop_layout;
+  return subset_input->drop_hints;
 }
 
 HB_EXTERN void
@@ -152,7 +187,7 @@
  * hb_subset_input_set_retain_gids:
  * @subset_input: a subset_input.
  * @retain_gids: If true the subsetter will not renumber glyph ids.
- * Since: REPLACEME
+ * Since: 2.4.0
  **/
 HB_EXTERN void
 hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input,
@@ -164,7 +199,7 @@
 /**
  * hb_subset_input_get_retain_gids:
  * Returns: value of retain_gids.
- * Since: REPLACEME
+ * Since: 2.4.0
  **/
 HB_EXTERN hb_bool_t
 hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -40,16 +40,17 @@
 
   hb_set_t *unicodes;
   hb_set_t *glyphs;
+  hb_set_t *name_ids;
+  hb_set_t *drop_tables;
 
-  bool drop_hints : 1;
-  bool drop_layout : 1;
-  bool desubroutinize : 1;
-  bool retain_gids : 1;
+  bool drop_hints;
+  bool desubroutinize;
+  bool retain_gids;
   /* TODO
    *
    * features
    * lookups
-   * nameIDs
+   * name_ids
    * ...
    */
 };

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	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -31,8 +31,10 @@
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
 #include "hb-ot-cff1-table.hh"
+#include "hb-ot-var-fvar-table.hh"
+#include "hb-ot-stat-table.hh"
 
-static void
+static inline void
 _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
 		       hb_codepoint_t gid,
 		       hb_set_t *gids_to_retain)
@@ -53,7 +55,8 @@
   }
 }
 
-static void
+#ifndef HB_NO_SUBSET_CFF
+static inline void
 _add_cff_seac_components (const OT::cff1::accelerator_t &cff,
            hb_codepoint_t gid,
            hb_set_t *gids_to_retain)
@@ -65,8 +68,10 @@
     hb_set_add (gids_to_retain, accent_gid);
   }
 }
+#endif
 
-static void
+#ifndef HB_NO_SUBSET_LAYOUT
+static inline void
 _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
 {
   hb_set_t lookup_indices;
@@ -80,8 +85,9 @@
 					   &lookup_indices,
 					   gids_to_retain);
 }
+#endif
 
-static void
+static inline void
 _remove_invalid_gids (hb_set_t *glyphs,
 		      unsigned int num_glyphs)
 {
@@ -93,24 +99,21 @@
   }
 }
 
-static hb_set_t *
-_populate_gids_to_retain (hb_face_t *face,
+static void
+_populate_gids_to_retain (hb_subset_plan_t* plan,
 			  const hb_set_t *unicodes,
                           const hb_set_t *input_glyphs_to_retain,
-			  bool close_over_gsub,
-			  hb_set_t *unicodes_to_retain,
-			  hb_map_t *codepoint_to_glyph)
+			  bool close_over_gsub)
 {
   OT::cmap::accelerator_t cmap;
   OT::glyf::accelerator_t glyf;
   OT::cff1::accelerator_t cff;
-  cmap.init (face);
-  glyf.init (face);
-  cff.init (face);
+  cmap.init (plan->source);
+  glyf.init (plan->source);
+  cff.init (plan->source);
 
-  hb_set_t *initial_gids_to_retain = hb_set_create ();
-  initial_gids_to_retain->add (0); // Not-def
-  hb_set_union (initial_gids_to_retain, input_glyphs_to_retain);
+  plan->_glyphset_gsub->add (0); // Not-def
+  hb_set_union (plan->_glyphset_gsub, input_glyphs_to_retain);
 
   hb_codepoint_t cp = HB_SET_VALUE_INVALID;
   while (unicodes->next (&cp))
@@ -121,67 +124,92 @@
       DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp);
       continue;
     }
-    unicodes_to_retain->add (cp);
-    codepoint_to_glyph->set (cp, gid);
-    initial_gids_to_retain->add (gid);
+    plan->unicodes->add (cp);
+    plan->codepoint_to_glyph->set (cp, gid);
+    plan->_glyphset_gsub->add (gid);
   }
 
+#ifndef HB_NO_SUBSET_LAYOUT
   if (close_over_gsub)
     // Add all glyphs needed for GSUB substitutions.
-    _gsub_closure (face, initial_gids_to_retain);
+    _gsub_closure (plan->source, plan->_glyphset_gsub);
+#endif
+  _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
 
   // Populate a full set of glyphs to retain by adding all referenced
   // composite glyphs.
   hb_codepoint_t gid = HB_SET_VALUE_INVALID;
-  hb_set_t *all_gids_to_retain = hb_set_create ();
-  while (initial_gids_to_retain->next (&gid))
+  while (plan->_glyphset_gsub->next (&gid))
   {
-    _add_gid_and_children (glyf, gid, all_gids_to_retain);
+    _add_gid_and_children (glyf, gid, plan->_glyphset);
+#ifndef HB_NO_SUBSET_CFF
     if (cff.is_valid ())
-      _add_cff_seac_components (cff, gid, all_gids_to_retain);
+      _add_cff_seac_components (cff, gid, plan->_glyphset);
+#endif
   }
-  hb_set_destroy (initial_gids_to_retain);
 
-  _remove_invalid_gids (all_gids_to_retain, face->get_num_glyphs ());
+  _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
 
-
   cff.fini ();
   glyf.fini ();
   cmap.fini ();
-
-  return all_gids_to_retain;
 }
 
 static void
-_create_old_gid_to_new_gid_map (const hb_face_t                   *face,
-                                bool                               retain_gids,
-				hb_set_t                          *all_gids_to_retain,
-                                hb_map_t                          *glyph_map, /* OUT */
-                                hb_map_t                          *reverse_glyph_map, /* OUT */
-                                unsigned int                      *num_glyphs /* OUT */)
+_create_old_gid_to_new_gid_map (const hb_face_t *face,
+                                bool             retain_gids,
+				const hb_set_t  *all_gids_to_retain,
+                                hb_map_t        *glyph_map, /* OUT */
+                                hb_map_t        *reverse_glyph_map, /* OUT */
+                                unsigned int    *num_glyphs /* OUT */)
 {
-  hb_codepoint_t gid = HB_SET_VALUE_INVALID;
-  unsigned int length = 0;
-  for (unsigned int i = 0; all_gids_to_retain->next (&gid); i++) {
-    if (!retain_gids)
-    {
-      glyph_map->set (gid, i);
-      reverse_glyph_map->set (i, gid);
-    }
-    else
-    {
-      glyph_map->set (gid, gid);
-      reverse_glyph_map->set (gid, gid);
-    }
-    ++length;
-  }
-  if (!retain_gids || length == 0)
+  if (!retain_gids)
   {
-    *num_glyphs = length;
+    + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0)
+    | hb_sink (reverse_glyph_map)
+    ;
+    *num_glyphs = reverse_glyph_map->get_population ();
+  } else {
+    + hb_iter (all_gids_to_retain)
+    | hb_map ([] (hb_codepoint_t _) {
+		return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, _);
+	      })
+    | hb_sink (reverse_glyph_map)
+    ;
+
+    unsigned max_glyph =
+    + hb_iter (all_gids_to_retain)
+    | hb_reduce (hb_max, 0)
+    ;
+    *num_glyphs = max_glyph + 1;
   }
-  else
+
+  + reverse_glyph_map->iter ()
+  | hb_map (&hb_pair_t<hb_codepoint_t, hb_codepoint_t>::reverse)
+  | hb_sink (glyph_map)
+  ;
+}
+
+static void
+_nameid_closure (hb_face_t           *face,
+                 hb_set_t            *nameids)
+{
+  hb_tag_t table_tags[32];
+  unsigned count = ARRAY_LENGTH (table_tags);
+  hb_face_get_table_tags (face, 0, &count, table_tags);
+  for (unsigned int i = 0; i < count; i++)
   {
-    *num_glyphs = face->get_num_glyphs ();
+    hb_tag_t tag = table_tags[i];
+    switch (tag) {
+      case HB_OT_TAG_STAT:
+        face->table.STAT->collect_name_ids (nameids);
+        break;
+      case HB_OT_TAG_fvar:
+        face->table.fvar->collect_name_ids (nameids);
+        break;
+      default:
+        break;
+    }
   }
 }
 
@@ -202,21 +230,26 @@
   hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
 
   plan->drop_hints = input->drop_hints;
-  plan->drop_layout = input->drop_layout;
   plan->desubroutinize = input->desubroutinize;
-  plan->unicodes = hb_set_create();
+  plan->retain_gids = input->retain_gids;
+  plan->unicodes = hb_set_create ();
+  plan->name_ids = hb_set_reference (input->name_ids);
+  _nameid_closure (face, plan->name_ids);
+  plan->drop_tables = hb_set_reference (input->drop_tables);
   plan->source = hb_face_reference (face);
   plan->dest = hb_face_builder_create ();
-  plan->codepoint_to_glyph = hb_map_create();
-  plan->glyph_map = hb_map_create();
-  plan->reverse_glyph_map = hb_map_create();
-  plan->_glyphset = _populate_gids_to_retain (face,
-                                              input->unicodes,
-                                              input->glyphs,
-                                              !plan->drop_layout,
-                                              plan->unicodes,
-                                              plan->codepoint_to_glyph);
 
+  plan->_glyphset = hb_set_create ();
+  plan->_glyphset_gsub = hb_set_create ();
+  plan->codepoint_to_glyph = hb_map_create ();
+  plan->glyph_map = hb_map_create ();
+  plan->reverse_glyph_map = hb_map_create ();
+
+  _populate_gids_to_retain (plan,
+                            input->unicodes,
+                            input->glyphs,
+                            !input->drop_tables->has (HB_OT_TAG_GSUB));
+
   _create_old_gid_to_new_gid_map (face,
                                   input->retain_gids,
 				  plan->_glyphset,
@@ -238,6 +271,8 @@
   if (!hb_object_destroy (plan)) return;
 
   hb_set_destroy (plan->unicodes);
+  hb_set_destroy (plan->name_ids);
+  hb_set_destroy (plan->drop_tables);
   hb_face_destroy (plan->source);
   hb_face_destroy (plan->dest);
   hb_map_destroy (plan->codepoint_to_glyph);
@@ -244,6 +279,7 @@
   hb_map_destroy (plan->glyph_map);
   hb_map_destroy (plan->reverse_glyph_map);
   hb_set_destroy (plan->_glyphset);
+  hb_set_destroy (plan->_glyphset_gsub);
 
   free (plan);
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -40,12 +40,18 @@
   hb_object_header_t header;
 
   bool drop_hints : 1;
-  bool drop_layout : 1;
   bool desubroutinize : 1;
+  bool retain_gids : 1;
 
   // For each cp that we'd like to retain maps to the corresponding gid.
   hb_set_t *unicodes;
 
+  // name_ids we would like to retain
+  hb_set_t *name_ids;
+
+  // Tables which should be dropped.
+  hb_set_t *drop_tables;
+
   // The glyph subset
   hb_map_t *codepoint_to_glyph;
 
@@ -59,11 +65,14 @@
 
   unsigned int _num_output_glyphs;
   hb_set_t *_glyphset;
+  hb_set_t *_glyphset_gsub;
 
  public:
 
   /*
    * The set of input glyph ids which will be retained in the subset.
+   * Does NOT include ids kept due to retain_gids. You probably want to use
+   * glyph_map/reverse_glyph_map.
    */
   inline const hb_set_t *
   glyphset () const
@@ -72,6 +81,15 @@
   }
 
   /*
+   * The set of input glyph ids which will be retained in the subset.
+   */
+  inline const hb_set_t *
+  glyphset_gsub () const
+  {
+    return _glyphset_gsub;
+  }
+
+  /*
    * The total number of output glyphs in the final subset.
    */
   inline unsigned int

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2019-05-24 23:03:55 UTC (rev 51218)
@@ -28,7 +28,6 @@
 #include "hb-open-type.hh"
 
 #include "hb-subset.hh"
-#include "hb-subset-glyf.hh"
 
 #include "hb-open-file.hh"
 #include "hb-ot-cmap-table.hh"
@@ -43,12 +42,16 @@
 #include "hb-ot-cff1-table.hh"
 #include "hb-ot-cff2-table.hh"
 #include "hb-ot-vorg-table.hh"
+#include "hb-ot-name-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
 
 
-static unsigned int
+HB_UNUSED static inline unsigned int
 _plan_estimate_subset_table_size (hb_subset_plan_t *plan,
+				  unsigned int table_len);
+static inline unsigned int
+_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
 				  unsigned int table_len)
 {
   unsigned int src_glyphs = plan->source->get_num_glyphs ();
@@ -64,14 +67,16 @@
 static bool
 _subset2 (hb_subset_plan_t *plan)
 {
+  bool result = true;
   hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
   const TableType *table = source_blob->as<TableType> ();
 
   hb_tag_t tag = TableType::tableTag;
-  hb_bool_t result = false;
   if (source_blob->data)
   {
     hb_vector_t<char> buf;
+    /* TODO Not all tables are glyph-related.  'name' table size for example should not be
+     * affected by number of glyphs.  Accommodate that. */
     unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length);
     DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
     if (unlikely (!buf.alloc (buf_size)))
@@ -81,9 +86,10 @@
     }
   retry:
     hb_serialize_context_t serializer ((void *) buf, buf_size);
+    serializer.start_serialize<TableType> ();
     hb_subset_context_t c (plan, &serializer);
-    result = table->subset (&c);
-    if (serializer.in_error ())
+    bool needed = table->subset (&c);
+    if (serializer.ran_out_of_room)
     {
       buf_size += (buf_size >> 1) + 32;
       DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
@@ -94,18 +100,24 @@
       }
       goto retry;
     }
+    serializer.end_serialize ();
+
+    result = !serializer.in_error ();
+
     if (result)
     {
-      hb_blob_t *dest_blob = serializer.copy_blob ();
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
-      result = c.plan->add_table (tag, dest_blob);
-      hb_blob_destroy (dest_blob);
+      if (needed)
+      {
+	hb_blob_t *dest_blob = serializer.copy_blob ();
+	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
+	result = c.plan->add_table (tag, dest_blob);
+	hb_blob_destroy (dest_blob);
+      }
+      else
+      {
+	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
+      }
     }
-    else
-    {
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
-      result = true;
-    }
   }
   else
     DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
@@ -143,11 +155,14 @@
   bool result = true;
   switch (tag) {
     case HB_OT_TAG_glyf:
-      result = _subset<const OT::glyf> (plan);
+      result = _subset2<const OT::glyf> (plan);
       break;
     case HB_OT_TAG_hdmx:
-      result = _subset<const OT::hdmx> (plan);
+      result = _subset2<const OT::hdmx> (plan);
       break;
+    case HB_OT_TAG_name:
+      result = _subset2<const OT::name> (plan);
+      break;
     case HB_OT_TAG_head:
       // TODO that won't work well if there is no glyf
       DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf");
@@ -180,6 +195,8 @@
     case HB_OT_TAG_post:
       result = _subset<const OT::post> (plan);
       break;
+
+#ifndef HB_NO_SUBSET_CFF
     case HB_OT_TAG_cff1:
       result = _subset<const OT::cff1> (plan);
       break;
@@ -189,6 +206,9 @@
     case HB_OT_TAG_VORG:
       result = _subset<const OT::VORG> (plan);
       break;
+#endif
+
+#ifndef HB_NO_SUBSET_LAYOUT
     case HB_OT_TAG_GDEF:
       result = _subset2<const OT::GDEF> (plan);
       break;
@@ -198,6 +218,7 @@
     case HB_OT_TAG_GPOS:
       result = _subset2<const OT::GPOS> (plan);
       break;
+#endif
 
     default:
       hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
@@ -215,6 +236,9 @@
 static bool
 _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
 {
+  if (plan->drop_tables->has (tag))
+    return true;
+
   switch (tag) {
     case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
     case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */
@@ -223,31 +247,19 @@
     case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
     case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
       return plan->drop_hints;
+
+#ifdef HB_NO_SUBSET_LAYOUT
     // Drop Layout Tables if requested.
     case HB_OT_TAG_GDEF:
     case HB_OT_TAG_GPOS:
     case HB_OT_TAG_GSUB:
-      return plan->drop_layout;
-    // Drop these tables below by default, list pulled
-    // from fontTools:
-    case HB_TAG ('B', 'A', 'S', 'E'):
-    case HB_TAG ('J', 'S', 'T', 'F'):
-    case HB_TAG ('D', 'S', 'I', 'G'):
-    case HB_TAG ('E', 'B', 'D', 'T'):
-    case HB_TAG ('E', 'B', 'L', 'C'):
-    case HB_TAG ('E', 'B', 'S', 'C'):
-    case HB_TAG ('S', 'V', 'G', ' '):
-    case HB_TAG ('P', 'C', 'L', 'T'):
-    case HB_TAG ('L', 'T', 'S', 'H'):
-    // Graphite tables:
-    case HB_TAG ('F', 'e', 'a', 't'):
-    case HB_TAG ('G', 'l', 'a', 't'):
-    case HB_TAG ('G', 'l', 'o', 'c'):
-    case HB_TAG ('S', 'i', 'l', 'f'):
-    case HB_TAG ('S', 'i', 'l', 'l'):
-    // Colour
-    case HB_TAG ('s', 'b', 'i', 'x'):
+    case HB_TAG ('m', 'o', 'r', 'x'):
+    case HB_TAG ('m', 'o', 'r', 't'):
+    case HB_TAG ('k', 'e', 'r', 'x'):
+    case HB_TAG ('k', 'e', 'r', 'n'):
       return true;
+#endif
+
     default:
       return false;
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2019-05-24 23:03:55 UTC (rev 51218)
@@ -54,6 +54,12 @@
 HB_EXTERN hb_set_t *
 hb_subset_input_glyph_set (hb_subset_input_t *subset_input);
 
+HB_EXTERN hb_set_t *
+hb_subset_input_nameid_set (hb_subset_input_t *subset_input);
+
+HB_EXTERN hb_set_t *
+hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input);
+
 HB_EXTERN void
 hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
 				hb_bool_t drop_hints);
@@ -61,12 +67,6 @@
 hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input);
 
 HB_EXTERN void
-hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
-				 hb_bool_t drop_layout);
-HB_EXTERN hb_bool_t
-hb_subset_input_get_drop_layout (hb_subset_input_t *subset_input);
-
-HB_EXTERN void
 hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input,
         hb_bool_t desubroutinize);
 HB_EXTERN hb_bool_t

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh	2019-05-24 21:47:41 UTC (rev 51217)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -40,10 +40,20 @@
        hb_dispatch_context_t<hb_subset_context_t, bool, HB_DEBUG_SUBSET>
 {
   const char *get_name () { return "SUBSET"; }
-  template <typename T>
-  bool dispatch (const T &obj) { return obj.subset (this); }
-  static bool default_return_value () { return true; }
+  static return_t default_return_value () { return true; }
 
+  private:
+  template <typename T, typename ...Ts> auto
+  _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
+  ( obj.subset (this, hb_forward<Ts> (ds)...) )
+  template <typename T, typename ...Ts> auto
+  _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
+  ( obj.dispatch (this, hb_forward<Ts> (ds)...) )
+  public:
+  template <typename T, typename ...Ts> auto
+  dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
+  ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) )
+
   hb_subset_plan_t *plan;
   hb_serialize_context_t *serializer;
   unsigned int debug_depth;

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd-table.hh	2019-05-24 23:03:55 UTC (rev 51218)
@@ -0,0 +1,5160 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ *   ./gen-ucd-table.py ucd.nonunihan.grouped.xml
+ *
+ * on file with this description: Unicode 12.1.0
+ */
+
+#ifndef HB_UCD_TABLE_HH
+#define HB_UCD_TABLE_HH
+
+
+#include "hb.hh"
+
+static const hb_script_t
+_hb_ucd_sc_map[138] =
+{
+                   HB_SCRIPT_COMMON,              HB_SCRIPT_INHERITED,
+                  HB_SCRIPT_UNKNOWN,                 HB_SCRIPT_ARABIC,
+                 HB_SCRIPT_ARMENIAN,                HB_SCRIPT_BENGALI,
+                 HB_SCRIPT_CYRILLIC,             HB_SCRIPT_DEVANAGARI,
+                 HB_SCRIPT_GEORGIAN,                  HB_SCRIPT_GREEK,
+                 HB_SCRIPT_GUJARATI,               HB_SCRIPT_GURMUKHI,
+                   HB_SCRIPT_HANGUL,                    HB_SCRIPT_HAN,
+                   HB_SCRIPT_HEBREW,               HB_SCRIPT_HIRAGANA,
+                  HB_SCRIPT_KANNADA,               HB_SCRIPT_KATAKANA,
+                      HB_SCRIPT_LAO,                  HB_SCRIPT_LATIN,
+                HB_SCRIPT_MALAYALAM,                  HB_SCRIPT_ORIYA,
+                    HB_SCRIPT_TAMIL,                 HB_SCRIPT_TELUGU,
+                     HB_SCRIPT_THAI,                HB_SCRIPT_TIBETAN,
+                 HB_SCRIPT_BOPOMOFO,                HB_SCRIPT_BRAILLE,
+       HB_SCRIPT_CANADIAN_SYLLABICS,               HB_SCRIPT_CHEROKEE,
+                 HB_SCRIPT_ETHIOPIC,                  HB_SCRIPT_KHMER,
+                HB_SCRIPT_MONGOLIAN,                HB_SCRIPT_MYANMAR,
+                    HB_SCRIPT_OGHAM,                  HB_SCRIPT_RUNIC,
+                  HB_SCRIPT_SINHALA,                 HB_SCRIPT_SYRIAC,
+                   HB_SCRIPT_THAANA,                     HB_SCRIPT_YI,
+                  HB_SCRIPT_DESERET,                 HB_SCRIPT_GOTHIC,
+               HB_SCRIPT_OLD_ITALIC,                  HB_SCRIPT_BUHID,
+                  HB_SCRIPT_HANUNOO,                HB_SCRIPT_TAGALOG,
+                 HB_SCRIPT_TAGBANWA,                HB_SCRIPT_CYPRIOT,
+                    HB_SCRIPT_LIMBU,               HB_SCRIPT_LINEAR_B,
+                  HB_SCRIPT_OSMANYA,                HB_SCRIPT_SHAVIAN,
+                   HB_SCRIPT_TAI_LE,               HB_SCRIPT_UGARITIC,
+                 HB_SCRIPT_BUGINESE,                 HB_SCRIPT_COPTIC,
+               HB_SCRIPT_GLAGOLITIC,             HB_SCRIPT_KHAROSHTHI,
+              HB_SCRIPT_NEW_TAI_LUE,            HB_SCRIPT_OLD_PERSIAN,
+             HB_SCRIPT_SYLOTI_NAGRI,               HB_SCRIPT_TIFINAGH,
+                 HB_SCRIPT_BALINESE,              HB_SCRIPT_CUNEIFORM,
+                      HB_SCRIPT_NKO,               HB_SCRIPT_PHAGS_PA,
+               HB_SCRIPT_PHOENICIAN,                 HB_SCRIPT_CARIAN,
+                     HB_SCRIPT_CHAM,               HB_SCRIPT_KAYAH_LI,
+                   HB_SCRIPT_LEPCHA,                 HB_SCRIPT_LYCIAN,
+                   HB_SCRIPT_LYDIAN,               HB_SCRIPT_OL_CHIKI,
+                   HB_SCRIPT_REJANG,             HB_SCRIPT_SAURASHTRA,
+                HB_SCRIPT_SUNDANESE,                    HB_SCRIPT_VAI,
+                  HB_SCRIPT_AVESTAN,                  HB_SCRIPT_BAMUM,
+     HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,       HB_SCRIPT_IMPERIAL_ARAMAIC,
+    HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
+                 HB_SCRIPT_JAVANESE,                 HB_SCRIPT_KAITHI,
+                     HB_SCRIPT_LISU,           HB_SCRIPT_MEETEI_MAYEK,
+        HB_SCRIPT_OLD_SOUTH_ARABIAN,             HB_SCRIPT_OLD_TURKIC,
+                HB_SCRIPT_SAMARITAN,               HB_SCRIPT_TAI_THAM,
+                 HB_SCRIPT_TAI_VIET,                  HB_SCRIPT_BATAK,
+                   HB_SCRIPT_BRAHMI,                HB_SCRIPT_MANDAIC,
+                   HB_SCRIPT_CHAKMA,       HB_SCRIPT_MEROITIC_CURSIVE,
+     HB_SCRIPT_MEROITIC_HIEROGLYPHS,                   HB_SCRIPT_MIAO,
+                  HB_SCRIPT_SHARADA,           HB_SCRIPT_SORA_SOMPENG,
+                    HB_SCRIPT_TAKRI,              HB_SCRIPT_BASSA_VAH,
+       HB_SCRIPT_CAUCASIAN_ALBANIAN,               HB_SCRIPT_DUPLOYAN,
+                  HB_SCRIPT_ELBASAN,                HB_SCRIPT_GRANTHA,
+                   HB_SCRIPT_KHOJKI,              HB_SCRIPT_KHUDAWADI,
+                 HB_SCRIPT_LINEAR_A,               HB_SCRIPT_MAHAJANI,
+               HB_SCRIPT_MANICHAEAN,          HB_SCRIPT_MENDE_KIKAKUI,
+                     HB_SCRIPT_MODI,                    HB_SCRIPT_MRO,
+                HB_SCRIPT_NABATAEAN,      HB_SCRIPT_OLD_NORTH_ARABIAN,
+               HB_SCRIPT_OLD_PERMIC,           HB_SCRIPT_PAHAWH_HMONG,
+                HB_SCRIPT_PALMYRENE,            HB_SCRIPT_PAU_CIN_HAU,
+          HB_SCRIPT_PSALTER_PAHLAVI,                HB_SCRIPT_SIDDHAM,
+                  HB_SCRIPT_TIRHUTA,            HB_SCRIPT_WARANG_CITI,
+                     HB_SCRIPT_AHOM,  HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,
+                   HB_SCRIPT_HATRAN,                HB_SCRIPT_MULTANI,
+            HB_SCRIPT_OLD_HUNGARIAN,            HB_SCRIPT_SIGNWRITING,
+                    HB_SCRIPT_ADLAM,              HB_SCRIPT_BHAIKSUKI,
+                  HB_SCRIPT_MARCHEN,                  HB_SCRIPT_OSAGE,
+                   HB_SCRIPT_TANGUT,                   HB_SCRIPT_NEWA,
+};
+static const hb_codepoint_t
+_hb_ucd_dm1_map[935] =
+{
+   0x003Bu, 0x004Bu, 0x0060u, 0x00B4u, 0x00B7u, 0x00C5u, 0x02B9u, 0x0300u,
+   0x0301u, 0x0313u, 0x0385u, 0x0386u, 0x0388u, 0x0389u, 0x038Au, 0x038Cu,
+   0x038Eu, 0x038Fu, 0x0390u, 0x03A9u, 0x03ACu, 0x03ADu, 0x03AEu, 0x03AFu,
+   0x03B0u, 0x03B9u, 0x03CCu, 0x03CDu, 0x03CEu, 0x2002u, 0x2003u, 0x3008u,
+   0x3009u, 0x349Eu, 0x34B9u, 0x34BBu, 0x34DFu, 0x3515u, 0x36EEu, 0x36FCu,
+   0x3781u, 0x382Fu, 0x3862u, 0x387Cu, 0x38C7u, 0x38E3u, 0x391Cu, 0x393Au,
+   0x3A2Eu, 0x3A6Cu, 0x3AE4u, 0x3B08u, 0x3B19u, 0x3B49u, 0x3B9Du, 0x3C18u,
+   0x3C4Eu, 0x3D33u, 0x3D96u, 0x3EACu, 0x3EB8u, 0x3F1Bu, 0x3FFCu, 0x4008u,
+   0x4018u, 0x4039u, 0x4046u, 0x4096u, 0x40E3u, 0x412Fu, 0x4202u, 0x4227u,
+   0x42A0u, 0x4301u, 0x4334u, 0x4359u, 0x43D5u, 0x43D9u, 0x440Bu, 0x446Bu,
+   0x452Bu, 0x455Du, 0x4561u, 0x456Bu, 0x45D7u, 0x45F9u, 0x4635u, 0x46BEu,
+   0x46C7u, 0x4995u, 0x49E6u, 0x4A6Eu, 0x4A76u, 0x4AB2u, 0x4B33u, 0x4BCEu,
+   0x4CCEu, 0x4CEDu, 0x4CF8u, 0x4D56u, 0x4E0Du, 0x4E26u, 0x4E32u, 0x4E38u,
+   0x4E39u, 0x4E3Du, 0x4E41u, 0x4E82u, 0x4E86u, 0x4EAEu, 0x4EC0u, 0x4ECCu,
+   0x4EE4u, 0x4F60u, 0x4F80u, 0x4F86u, 0x4F8Bu, 0x4FAEu, 0x4FBBu, 0x4FBFu,
+   0x5002u, 0x502Bu, 0x507Au, 0x5099u, 0x50CFu, 0x50DAu, 0x50E7u, 0x5140u,
+   0x5145u, 0x514Du, 0x5154u, 0x5164u, 0x5167u, 0x5168u, 0x5169u, 0x516Du,
+   0x5177u, 0x5180u, 0x518Du, 0x5192u, 0x5195u, 0x5197u, 0x51A4u, 0x51ACu,
+   0x51B5u, 0x51B7u, 0x51C9u, 0x51CCu, 0x51DCu, 0x51DEu, 0x51F5u, 0x5203u,
+   0x5207u, 0x5217u, 0x5229u, 0x523Au, 0x523Bu, 0x5246u, 0x5272u, 0x5277u,
+   0x5289u, 0x529Bu, 0x52A3u, 0x52B3u, 0x52C7u, 0x52C9u, 0x52D2u, 0x52DEu,
+   0x52E4u, 0x52F5u, 0x52FAu, 0x5305u, 0x5306u, 0x5317u, 0x533Fu, 0x5349u,
+   0x5351u, 0x535Au, 0x5373u, 0x5375u, 0x537Du, 0x537Fu, 0x53C3u, 0x53CAu,
+   0x53DFu, 0x53E5u, 0x53EBu, 0x53F1u, 0x5406u, 0x540Fu, 0x541Du, 0x5438u,
+   0x5442u, 0x5448u, 0x5468u, 0x549Eu, 0x54A2u, 0x54BDu, 0x54F6u, 0x5510u,
+   0x5553u, 0x5555u, 0x5563u, 0x5584u, 0x5587u, 0x5599u, 0x559Du, 0x55ABu,
+   0x55B3u, 0x55C0u, 0x55C2u, 0x55E2u, 0x5606u, 0x5651u, 0x5668u, 0x5674u,
+   0x56F9u, 0x5716u, 0x5717u, 0x578Bu, 0x57CEu, 0x57F4u, 0x580Du, 0x5831u,
+   0x5832u, 0x5840u, 0x585Au, 0x585Eu, 0x58A8u, 0x58ACu, 0x58B3u, 0x58D8u,
+   0x58DFu, 0x58EEu, 0x58F2u, 0x58F7u, 0x5906u, 0x591Au, 0x5922u, 0x5944u,
+   0x5948u, 0x5951u, 0x5954u, 0x5962u, 0x5973u, 0x59D8u, 0x59ECu, 0x5A1Bu,
+   0x5A27u, 0x5A62u, 0x5A66u, 0x5AB5u, 0x5B08u, 0x5B28u, 0x5B3Eu, 0x5B85u,
+   0x5BC3u, 0x5BD8u, 0x5BE7u, 0x5BEEu, 0x5BF3u, 0x5BFFu, 0x5C06u, 0x5C22u,
+   0x5C3Fu, 0x5C60u, 0x5C62u, 0x5C64u, 0x5C65u, 0x5C6Eu, 0x5C8Du, 0x5CC0u,
+   0x5D19u, 0x5D43u, 0x5D50u, 0x5D6Bu, 0x5D6Eu, 0x5D7Cu, 0x5DB2u, 0x5DBAu,
+   0x5DE1u, 0x5DE2u, 0x5DFDu, 0x5E28u, 0x5E3Du, 0x5E69u, 0x5E74u, 0x5EA6u,
+   0x5EB0u, 0x5EB3u, 0x5EB6u, 0x5EC9u, 0x5ECAu, 0x5ED2u, 0x5ED3u, 0x5ED9u,
+   0x5EECu, 0x5EFEu, 0x5F04u, 0x5F22u, 0x5F53u, 0x5F62u, 0x5F69u, 0x5F6Bu,
+   0x5F8Bu, 0x5F9Au, 0x5FA9u, 0x5FADu, 0x5FCDu, 0x5FD7u, 0x5FF5u, 0x5FF9u,
+   0x6012u, 0x601Cu, 0x6075u, 0x6081u, 0x6094u, 0x60C7u, 0x60D8u, 0x60E1u,
+   0x6108u, 0x6144u, 0x6148u, 0x614Cu, 0x614Eu, 0x6160u, 0x6168u, 0x617Au,
+   0x618Eu, 0x6190u, 0x61A4u, 0x61AFu, 0x61B2u, 0x61DEu, 0x61F2u, 0x61F6u,
+   0x6200u, 0x6210u, 0x621Bu, 0x622Eu, 0x6234u, 0x625Du, 0x62B1u, 0x62C9u,
+   0x62CFu, 0x62D3u, 0x62D4u, 0x62FCu, 0x62FEu, 0x633Du, 0x6350u, 0x6368u,
+   0x637Bu, 0x6383u, 0x63A0u, 0x63A9u, 0x63C4u, 0x63C5u, 0x63E4u, 0x641Cu,
+   0x6422u, 0x6452u, 0x6469u, 0x6477u, 0x647Eu, 0x649Au, 0x649Du, 0x64C4u,
+   0x654Fu, 0x6556u, 0x656Cu, 0x6578u, 0x6599u, 0x65C5u, 0x65E2u, 0x65E3u,
+   0x6613u, 0x6649u, 0x6674u, 0x6688u, 0x6691u, 0x669Cu, 0x66B4u, 0x66C6u,
+   0x66F4u, 0x66F8u, 0x6700u, 0x6717u, 0x671Bu, 0x6721u, 0x674Eu, 0x6753u,
+   0x6756u, 0x675Eu, 0x677Bu, 0x6785u, 0x6797u, 0x67F3u, 0x67FAu, 0x6817u,
+   0x681Fu, 0x6852u, 0x6881u, 0x6885u, 0x688Eu, 0x68A8u, 0x6914u, 0x6942u,
+   0x69A3u, 0x69EAu, 0x6A02u, 0x6A13u, 0x6AA8u, 0x6AD3u, 0x6ADBu, 0x6B04u,
+   0x6B21u, 0x6B54u, 0x6B72u, 0x6B77u, 0x6B79u, 0x6B9Fu, 0x6BAEu, 0x6BBAu,
+   0x6BBBu, 0x6C4Eu, 0x6C67u, 0x6C88u, 0x6CBFu, 0x6CCCu, 0x6CCDu, 0x6CE5u,
+   0x6D16u, 0x6D1Bu, 0x6D1Eu, 0x6D34u, 0x6D3Eu, 0x6D41u, 0x6D69u, 0x6D6Au,
+   0x6D77u, 0x6D78u, 0x6D85u, 0x6DCBu, 0x6DDAu, 0x6DEAu, 0x6DF9u, 0x6E1Au,
+   0x6E2Fu, 0x6E6Eu, 0x6E9Cu, 0x6EBAu, 0x6EC7u, 0x6ECBu, 0x6ED1u, 0x6EDBu,
+   0x6F0Fu, 0x6F22u, 0x6F23u, 0x6F6Eu, 0x6FC6u, 0x6FEBu, 0x6FFEu, 0x701Bu,
+   0x701Eu, 0x7039u, 0x704Au, 0x7070u, 0x7077u, 0x707Du, 0x7099u, 0x70ADu,
+   0x70C8u, 0x70D9u, 0x7145u, 0x7149u, 0x716Eu, 0x719Cu, 0x71CEu, 0x71D0u,
+   0x7210u, 0x721Bu, 0x7228u, 0x722Bu, 0x7235u, 0x7250u, 0x7262u, 0x7280u,
+   0x7295u, 0x72AFu, 0x72C0u, 0x72FCu, 0x732Au, 0x7375u, 0x737Au, 0x7387u,
+   0x738Bu, 0x73A5u, 0x73B2u, 0x73DEu, 0x7406u, 0x7409u, 0x7422u, 0x7447u,
+   0x745Cu, 0x7469u, 0x7471u, 0x7485u, 0x7489u, 0x7498u, 0x74CAu, 0x7506u,
+   0x7524u, 0x753Bu, 0x753Eu, 0x7559u, 0x7565u, 0x7570u, 0x75E2u, 0x7610u,
+   0x761Du, 0x761Fu, 0x7642u, 0x7669u, 0x76CAu, 0x76DBu, 0x76E7u, 0x76F4u,
+   0x7701u, 0x771Eu, 0x771Fu, 0x7740u, 0x774Au, 0x778Bu, 0x77A7u, 0x784Eu,
+   0x786Bu, 0x788Cu, 0x7891u, 0x78CAu, 0x78CCu, 0x78FBu, 0x792Au, 0x793Cu,
+   0x793Eu, 0x7948u, 0x7949u, 0x7950u, 0x7956u, 0x795Du, 0x795Eu, 0x7965u,
+   0x797Fu, 0x798Du, 0x798Eu, 0x798Fu, 0x79AEu, 0x79CAu, 0x79EBu, 0x7A1Cu,
+   0x7A40u, 0x7A4Au, 0x7A4Fu, 0x7A81u, 0x7AB1u, 0x7ACBu, 0x7AEEu, 0x7B20u,
+   0x7BC0u, 0x7BC6u, 0x7BC9u, 0x7C3Eu, 0x7C60u, 0x7C7Bu, 0x7C92u, 0x7CBEu,
+   0x7CD2u, 0x7CD6u, 0x7CE3u, 0x7CE7u, 0x7CE8u, 0x7D00u, 0x7D10u, 0x7D22u,
+   0x7D2Fu, 0x7D5Bu, 0x7D63u, 0x7DA0u, 0x7DBEu, 0x7DC7u, 0x7DF4u, 0x7E02u,
+   0x7E09u, 0x7E37u, 0x7E41u, 0x7E45u, 0x7F3Eu, 0x7F72u, 0x7F79u, 0x7F7Au,
+   0x7F85u, 0x7F95u, 0x7F9Au, 0x7FBDu, 0x7FFAu, 0x8001u, 0x8005u, 0x8046u,
+   0x8060u, 0x806Fu, 0x8070u, 0x807Eu, 0x808Bu, 0x80ADu, 0x80B2u, 0x8103u,
+   0x813Eu, 0x81D8u, 0x81E8u, 0x81EDu, 0x8201u, 0x8204u, 0x8218u, 0x826Fu,
+   0x8279u, 0x828Bu, 0x8291u, 0x829Du, 0x82B1u, 0x82B3u, 0x82BDu, 0x82E5u,
+   0x82E6u, 0x831Du, 0x8323u, 0x8336u, 0x8352u, 0x8353u, 0x8363u, 0x83ADu,
+   0x83BDu, 0x83C9u, 0x83CAu, 0x83CCu, 0x83DCu, 0x83E7u, 0x83EFu, 0x83F1u,
+   0x843Du, 0x8449u, 0x8457u, 0x84EEu, 0x84F1u, 0x84F3u, 0x84FCu, 0x8516u,
+   0x8564u, 0x85CDu, 0x85FAu, 0x8606u, 0x8612u, 0x862Du, 0x863Fu, 0x8650u,
+   0x865Cu, 0x8667u, 0x8669u, 0x8688u, 0x86A9u, 0x86E2u, 0x870Eu, 0x8728u,
+   0x876Bu, 0x8779u, 0x8786u, 0x87BAu, 0x87E1u, 0x8801u, 0x881Fu, 0x884Cu,
+   0x8860u, 0x8863u, 0x88C2u, 0x88CFu, 0x88D7u, 0x88DEu, 0x88E1u, 0x88F8u,
+   0x88FAu, 0x8910u, 0x8941u, 0x8964u, 0x8986u, 0x898Bu, 0x8996u, 0x8AA0u,
+   0x8AAAu, 0x8ABFu, 0x8ACBu, 0x8AD2u, 0x8AD6u, 0x8AEDu, 0x8AF8u, 0x8AFEu,
+   0x8B01u, 0x8B39u, 0x8B58u, 0x8B80u, 0x8B8Au, 0x8C48u, 0x8C55u, 0x8CABu,
+   0x8CC1u, 0x8CC2u, 0x8CC8u, 0x8CD3u, 0x8D08u, 0x8D1Bu, 0x8D77u, 0x8DBCu,
+   0x8DCBu, 0x8DEFu, 0x8DF0u, 0x8ECAu, 0x8ED4u, 0x8F26u, 0x8F2Au, 0x8F38u,
+   0x8F3Bu, 0x8F62u, 0x8F9Eu, 0x8FB0u, 0x8FB6u, 0x9023u, 0x9038u, 0x9072u,
+   0x907Cu, 0x908Fu, 0x9094u, 0x90CEu, 0x90DEu, 0x90F1u, 0x90FDu, 0x9111u,
+   0x911Bu, 0x916Au, 0x9199u, 0x91B4u, 0x91CCu, 0x91CFu, 0x91D1u, 0x9234u,
+   0x9238u, 0x9276u, 0x927Cu, 0x92D7u, 0x92D8u, 0x9304u, 0x934Au, 0x93F9u,
+   0x9415u, 0x958Bu, 0x95ADu, 0x95B7u, 0x962Eu, 0x964Bu, 0x964Du, 0x9675u,
+   0x9678u, 0x967Cu, 0x9686u, 0x96A3u, 0x96B7u, 0x96B8u, 0x96C3u, 0x96E2u,
+   0x96E3u, 0x96F6u, 0x96F7u, 0x9723u, 0x9732u, 0x9748u, 0x9756u, 0x97DBu,
+   0x97E0u, 0x97FFu, 0x980Bu, 0x9818u, 0x9829u, 0x983Bu, 0x985Eu, 0x98E2u,
+   0x98EFu, 0x98FCu, 0x9928u, 0x9929u, 0x99A7u, 0x99C2u, 0x99F1u, 0x99FEu,
+   0x9A6Au, 0x9B12u, 0x9B6Fu, 0x9C40u, 0x9C57u, 0x9CFDu, 0x9D67u, 0x9DB4u,
+   0x9DFAu, 0x9E1Eu, 0x9E7Fu, 0x9E97u, 0x9E9Fu, 0x9EBBu, 0x9ECEu, 0x9EF9u,
+   0x9EFEu, 0x9F05u, 0x9F0Fu, 0x9F16u, 0x9F3Bu, 0x9F43u, 0x9F8Du, 0x9F8Eu,
+   0x9F9Cu,0x20122u,0x2051Cu,0x20525u,0x2054Bu,0x2063Au,0x20804u,0x208DEu,
+  0x20A2Cu,0x20B63u,0x214E4u,0x216A8u,0x216EAu,0x219C8u,0x21B18u,0x21D0Bu,
+  0x21DE4u,0x21DE6u,0x22183u,0x2219Fu,0x22331u,0x226D4u,0x22844u,0x2284Au,
+  0x22B0Cu,0x22BF1u,0x2300Au,0x232B8u,0x2335Fu,0x23393u,0x2339Cu,0x233C3u,
+  0x233D5u,0x2346Du,0x236A3u,0x238A7u,0x23A8Du,0x23AFAu,0x23CBCu,0x23D1Eu,
+  0x23ED1u,0x23F5Eu,0x23F8Eu,0x24263u,0x242EEu,0x243ABu,0x24608u,0x24735u,
+  0x24814u,0x24C36u,0x24C92u,0x24FA1u,0x24FB8u,0x25044u,0x250F2u,0x250F3u,
+  0x25119u,0x25133u,0x25249u,0x2541Du,0x25626u,0x2569Au,0x256C5u,0x2597Cu,
+  0x25AA7u,0x25BABu,0x25C80u,0x25CD0u,0x25F86u,0x261DAu,0x26228u,0x26247u,
+  0x262D9u,0x2633Eu,0x264DAu,0x26523u,0x265A8u,0x267A7u,0x267B5u,0x26B3Cu,
+  0x26C36u,0x26CD5u,0x26D6Bu,0x26F2Cu,0x26FB1u,0x270D2u,0x273CAu,0x27667u,

@@ Diff output truncated at 1234567 characters. @@


More information about the tex-live-commits mailing list