texlive[48949] Build/source/libs: harfbuzz 2.0.0

commits+kakuto at tug.org commits+kakuto at tug.org
Sat Oct 20 01:02:01 CEST 2018


Revision: 48949
          http://tug.org/svn/texlive?view=revision&revision=48949
Author:   kakuto
Date:     2018-10-20 01:02:01 +0200 (Sat, 20 Oct 2018)
Log Message:
-----------
harfbuzz 2.0.0

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/harfbuzz/ChangeLog
    trunk/Build/source/libs/harfbuzz/Makefile.am
    trunk/Build/source/libs/harfbuzz/Makefile.in
    trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
    trunk/Build/source/libs/harfbuzz/configure
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/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/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/TODO
    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-static-inits.sh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-khmer-data.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
    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-kerx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-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-atomic.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
    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.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.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-dsalgs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.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-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-svg-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-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-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
    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-os2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.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-default.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-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-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl
    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.hh
    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.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh
    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-tag.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.h
    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-hvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot.h
    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.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h
    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.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc
    trunk/Build/source/libs/harfbuzz/include/Makefile.am
    trunk/Build/source/libs/harfbuzz/include/Makefile.in
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/README	2018-10-19 23:02:01 UTC (rev 48949)
@@ -25,7 +25,7 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 1.8.8 - checked 15aug18
+harfbuzz 2.0.0 - checked 20oct18
   http://www.freedesktop.org/software/harfbuzz/release/
 
 icu 61.1 - checked 29mar18

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,3 +1,8 @@
+2018-10-20  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	Import harfbuzz-2.0.0.
+	* version.ac, Makefile.am, include/Makefile.am: Adjusted.
+
 2018-10-20  Khaled Hosny  <khaledhosny at eglug.org>
 
 	* configure.ac: Set HAVE_ICU_BUILTIN.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2018-10-19 23:02:01 UTC (rev 48949)
@@ -37,6 +37,7 @@
 	@HARFBUZZ_TREE@/src/hb-buffer.hh \
 	@HARFBUZZ_TREE@/src/hb-buffer-serialize.cc \
 	@HARFBUZZ_TREE@/src/hb-buffer.cc \
+	@HARFBUZZ_TREE@/src/hb-cache.hh \
 	@HARFBUZZ_TREE@/src/hb-common.cc \
 	@HARFBUZZ_TREE@/src/hb-debug.hh \
 	@HARFBUZZ_TREE@/src/hb-dsalgs.hh \
@@ -70,6 +71,7 @@
 	@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-set-digest.hh \
 	@HARFBUZZ_TREE@/src/hb-set.hh \
 	@HARFBUZZ_TREE@/src/hb-set.cc \
@@ -86,6 +88,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset.hh \
 	@HARFBUZZ_TREE@/src/hb-unicode.hh \
 	@HARFBUZZ_TREE@/src/hb-unicode.cc \
+	@HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \
 	@HARFBUZZ_TREE@/src/hb-vector.hh \
 	@HARFBUZZ_TREE@/src/hb-utf.hh \
 	@HARFBUZZ_TREE@/src/hb-warning.cc \
@@ -142,7 +145,6 @@
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-thai.cc \
-	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-tibetan.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-use.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-use-table.cc \

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2018-10-19 23:02:01 UTC (rev 48949)
@@ -153,7 +153,6 @@
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-khmer.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-thai.$(OBJEXT) \
-	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-tibetan.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-use.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-use-table.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-normalize.$(OBJEXT) \
@@ -212,7 +211,6 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-khmer.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-myanmar.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-thai.Po \
-	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-tibetan.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use-table.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-fallback.Po \
@@ -703,6 +701,7 @@
 	@HARFBUZZ_TREE@/src/hb-buffer.hh \
 	@HARFBUZZ_TREE@/src/hb-buffer-serialize.cc \
 	@HARFBUZZ_TREE@/src/hb-buffer.cc \
+	@HARFBUZZ_TREE@/src/hb-cache.hh \
 	@HARFBUZZ_TREE@/src/hb-common.cc \
 	@HARFBUZZ_TREE@/src/hb-debug.hh \
 	@HARFBUZZ_TREE@/src/hb-dsalgs.hh \
@@ -732,6 +731,7 @@
 	@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-set-digest.hh \
 	@HARFBUZZ_TREE@/src/hb-set.hh @HARFBUZZ_TREE@/src/hb-set.cc \
 	@HARFBUZZ_TREE@/src/hb-shape.cc \
@@ -747,6 +747,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset.hh \
 	@HARFBUZZ_TREE@/src/hb-unicode.hh \
 	@HARFBUZZ_TREE@/src/hb-unicode.cc \
+	@HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \
 	@HARFBUZZ_TREE@/src/hb-vector.hh @HARFBUZZ_TREE@/src/hb-utf.hh \
 	@HARFBUZZ_TREE@/src/hb-warning.cc \
 	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-json.hh \
@@ -798,7 +799,6 @@
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-myanmar.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-thai.cc \
-	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-tibetan.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-use.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-shape-complex-use-table.cc \
@@ -1003,9 +1003,6 @@
 @HARFBUZZ_TREE@/src/hb-ot-shape-complex-thai.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
- at HARFBUZZ_TREE@/src/hb-ot-shape-complex-tibetan.$(OBJEXT):  \
-	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
-	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-ot-shape-complex-use.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1072,7 +1069,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-khmer.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-myanmar.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-thai.Po at am__quote@ # am--include-marker
- at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-tibetan.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use-table.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-fallback.Po at am__quote@ # am--include-marker
@@ -1706,7 +1702,6 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-khmer.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-myanmar.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-thai.Po
-	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-tibetan.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use-table.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-fallback.Po
@@ -1796,7 +1791,6 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-khmer.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-myanmar.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-thai.Po
-	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-tibetan.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use-table.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-complex-use.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shape-fallback.Po

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,3 +1,8 @@
+2018-10-20  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	Imported harfbuzz-2.0.0 source tree from:
+	  http://www.freedesktop.org/software/harfbuzz/release/
+
 2018-09-11  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	Imported harfbuzz-1.9.0 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,4 +1,4 @@
-Changes applied to the harfbuzz-1.9.0/ tree as obtained from:
+Changes applied to the harfbuzz-2.0.0/ tree as obtained from:
 	http://www.freedesktop.org/software/harfbuzz/release/
 
 Removed:

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/configure	2018-10-19 23:02:01 UTC (rev 48949)
@@ -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) 1.9.0.
+# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.0.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='1.9.0'
-PACKAGE_STRING='harfbuzz (TeX Live) 1.9.0'
+PACKAGE_VERSION='2.0.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 2.0.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) 1.9.0 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 2.0.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) 1.9.0:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.0.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 1.9.0
+harfbuzz (TeX Live) configure 2.0.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 1.9.0, which was
+It was created by harfbuzz (TeX Live) $as_me 2.0.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4054,7 +4054,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='1.9.0'
+ VERSION='2.0.0'
 
 
 # Some tools Automake needs.
@@ -4246,10 +4246,10 @@
 
 
 
-HB_VERSION_MAJOR=1
-HB_VERSION_MINOR=9
+HB_VERSION_MAJOR=2
+HB_VERSION_MINOR=0
 HB_VERSION_MICRO=0
-HB_VERSION=1.9.0
+HB_VERSION=2.0.0
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8143,7 +8143,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 1.9.0, which was
+This file was extended by harfbuzz (TeX Live) $as_me 2.0.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8209,7 +8209,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 1.9.0
+harfbuzz (TeX Live) config.status 2.0.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/AUTHORS	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,9 +1,11 @@
 Behdad Esfahbod
-Simon Hausmann
-Martin Hosken
+David Turner
+Ebrahim Byagowi
 Jonathan Kew
+Khaled Hosny
 Lars Knoll
+Martin Hosken
+Owen Taylor
+Roozbeh Pournader
+Simon Hausmann
 Werner Lemberg
-Roozbeh Pournader
-Owen Taylor
-David Turner

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2018-10-19 23:02:01 UTC (rev 48949)
@@ -82,12 +82,21 @@
   endif ()
 endif ()
 
+set (HB_DISABLE_SUBSET OFF)
+set (HB_DISABLE_TESTS OFF)
+option(HB_IOS "Apply iOS specific build flags" OFF)
+if (HB_IOS)
+  # We should fix their issue and enable them
+  set (HB_DISABLE_SUBSET ON)
+  set (HB_DISABLE_TESTS ON)
+  set (HB_HAVE_CORETEXT OFF)
+endif ()
+
 include_directories(AFTER
   ${PROJECT_SOURCE_DIR}/src
   ${PROJECT_BINARY_DIR}/src
 )
 
-add_definitions(-DHAVE_OT)
 add_definitions(-DHAVE_FALLBACK)
 
 # We need PYTHON_EXECUTABLE to be set for running the tests...
@@ -359,12 +368,32 @@
   list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
 
-  find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
-  if (APPLICATION_SERVICES_FRAMEWORK)
-    list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
-  endif (APPLICATION_SERVICES_FRAMEWORK)
+  if (HB_IOS)
+    find_library(COREFOUNDATION CoreFoundation)
+    if (COREFOUNDATION)
+      list(APPEND THIRD_PARTY_LIBS ${COREFOUNDATION})
+    endif ()
+    mark_as_advanced(COREFOUNDATION)
 
-  mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
+    find_library(CORETEXT CoreText)
+    if (CORETEXT)
+      list(APPEND THIRD_PARTY_LIBS ${CORETEXT})
+    endif ()
+    mark_as_advanced(CORETEXT)
+
+    find_library(COREGRAPHICS CoreGraphics)
+    if (COREGRAPHICS)
+      list(APPEND THIRD_PARTY_LIBS ${COREGRAPHICS})
+    endif ()
+    mark_as_advanced(COREGRAPHICS)
+  else ()
+    find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
+    if (APPLICATION_SERVICES_FRAMEWORK)
+      list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
+    endif ()
+
+    mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
+  endif ()
 endif ()
 
 if (WIN32 AND HB_HAVE_UNISCRIBE)
@@ -527,12 +556,14 @@
 target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
 
 ## Define harfbuzz-subset library
-add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
-add_dependencies(harfbuzz-subset harfbuzz)
-target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
+if (NOT HB_DISABLE_SUBSET)
+  add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
+  add_dependencies(harfbuzz-subset harfbuzz)
+  target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
 
-if (BUILD_SHARED_LIBS)
-  set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+  endif ()
 endif ()
 
 if (UNIX OR MINGW)
@@ -549,7 +580,9 @@
     set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm
     set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
     set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C)
-    set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C)
+    if (NOT HB_DISABLE_SUBSET)
+      set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C)
+    endif ()
 
     # No threadsafe statics as we do it ourselves
     set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics")
@@ -574,7 +607,7 @@
 endif ()
 
 if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW)
-  add_definitions("-DHB_EXTERN=__declspec(dllexport) extern")
+  add_definitions("-DHB_DLL_EXPORT")
 endif ()
 
 # On Windows, g-ir-scanner requires a DLL build in order for it to work
@@ -761,12 +794,22 @@
 
 if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
   install(TARGETS harfbuzz
+    EXPORT harfbuzzConfig
     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
     FRAMEWORK DESTINATION Library/Frameworks
   )
+  install(EXPORT harfbuzzConfig
+      NAMESPACE harfbuzz::
+      DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/harfbuzz
+  )
   if (HB_BUILD_UTILS)
+    if (WIN32 AND BUILD_SHARED_LIBS)
+      install(TARGETS harfbuzz-subset
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+      )
+    endif ()
     install(TARGETS hb-view
       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
     )
@@ -818,51 +861,53 @@
 endif ()
 
 
-## src/ executables
-foreach (prog main test test-would-substitute test-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
-    set (prog_name test-test)
-  endif ()
-  add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
-  target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
-endforeach ()
-set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
+if (NOT HB_DISABLE_TESTS)
+  ## src/ executables
+  foreach (prog main test test-would-substitute test-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
+      set (prog_name test-test)
+    endif ()
+    add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
+    target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
+  endforeach ()
+  set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
 
-## Tests
-if (UNIX OR MINGW)
-  if (BUILD_SHARED_LIBS)
-    # generate harfbuzz.def after build completion
-    add_custom_command(TARGET harfbuzz POST_BUILD
-      COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers}
-      WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
+  ## Tests
+  if (UNIX OR MINGW)
+    if (BUILD_SHARED_LIBS)
+      # generate harfbuzz.def after build completion
+      add_custom_command(TARGET harfbuzz POST_BUILD
+        COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers}
+        WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
 
-    add_test(NAME check-static-inits.sh
-      COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh
-      WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack
-    )
-    add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh)
-    add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh)
+      add_test(NAME check-static-inits.sh
+        COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh
+        WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack
+      )
+      add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh)
+      add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh)
 
+      set_tests_properties(
+        check-static-inits.sh check-libstdc++.sh check-symbols.sh
+        PROPERTIES
+          ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src"
+          SKIP_RETURN_CODE 77)
+    endif ()
+
+    add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh)
+    add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh)
+    add_test(NAME check-externs.sh COMMAND ./check-externs.sh)
+    add_test(NAME check-includes.sh COMMAND ./check-includes.sh)
     set_tests_properties(
-      check-static-inits.sh check-libstdc++.sh check-symbols.sh
+      check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh
       PROPERTIES
-        ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src"
+        WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src
         SKIP_RETURN_CODE 77)
   endif ()
 
-  add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh)
-  add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh)
-  add_test(NAME check-externs.sh COMMAND ./check-externs.sh)
-  add_test(NAME check-includes.sh COMMAND ./check-includes.sh)
-  set_tests_properties(
-    check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh
-    PROPERTIES
-      WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src
-      SKIP_RETURN_CODE 77)
+  # Needs to come last so that variables defined above are passed to
+  # subdirectories.
+  add_subdirectory(test)
 endif ()
-
-# Needs to come last so that variables defined above are passed to
-# subdirectories.
-add_subdirectory(test)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,3 +1,6680 @@
+commit 3d9a0306ebb48706778fd2c487c3cacc7d508d6c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 18 05:58:17 2018 -0700
+
+    2.0.0
+
+ NEWS                | 68
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ configure.ac        |  2 +-
+ src/hb-buffer.cc    |  4 ++--
+ src/hb-common.h     |  4 ++--
+ src/hb-deprecated.h | 18 +++++++-------
+ src/hb-font.cc      |  6 ++---
+ src/hb-font.h       |  2 +-
+ src/hb-ot-layout.cc |  8 +++----
+ src/hb-ot-name.h    |  4 ++--
+ src/hb-ot-tag.cc    |  4 ++--
+ src/hb-ot-tag.h     |  4 ++--
+ src/hb-version.h    |  6 ++---
+ 12 files changed, 99 insertions(+), 31 deletions(-)
+
+commit 535ca678bf9c8ab470ebf5ad84a090328d79d42b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 18 05:58:04 2018 -0700
+
+    [test] Don't use newer glib API
+
+ test/api/test-ot-tag.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 03e144135b5c691e3942d1aef917fe2246665fb6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 18 11:06:37 2018 +0330
+
+    [ubsan] Use unsigned int instead enum where needed (#1270)
+
+    Actually the check is right,
+
+    On -myanmar.hh, on that particular switch, OT_C is indic_category_t
+    but OT_D is myanmar_category_t so we are mixing the types in one
+    variable.
+
+    And on -arabic.cc, step can goes one number higher than step_t enum
+    in the
+    loop so we are actually using it as an unsinged int.
+
+ .circleci/config.yml               |  2 +-
+ src/hb-ot-shape-complex-arabic.cc  |  4 ++--
+ src/hb-ot-shape-complex-myanmar.hh | 48
+ +++++++++++++++++++-------------------
+ 3 files changed, 27 insertions(+), 27 deletions(-)
+
+commit 64df6b0b0f9d221e14811084f2412a01cf4deb46
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 18 00:35:01 2018 -0700
+
+    [AUTHORS] Add Ebrahim and Khaled
+
+ AUTHORS | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit f1ced9be378d7c7ad3ea35a1cee6f9aff7a44a13
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 23:06:53 2018 -0700
+
+    More warning fix
+
+    Okay, let's see if the gods are happy now...
+
+ src/hb-static.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 40606abd0cd40faf3973d0a8c30af90d36ae8231
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 23:06:37 2018 -0700
+
+    Fix build
+
+ src/hb-static.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c406aca19303e61fa5ba15d215386cfc6d920124
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 22:58:43 2018 -0700
+
+    Fix warning
+
+ src/hb-machinery.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 270a37c3244b32dd839a99eb379be241613ee895
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 22:42:47 2018 -0700
+
+    Kick bots
+
+ src/hb-aat-layout-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 6da8ef3f9f4706fe88715fabdba7904ff279539b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 22:37:34 2018 -0700
+
+    Fix some wierdness...
+
+ src/hb-static.cc | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 83780308b41b029513ac2568b6688d3eaad77338
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 22:34:16 2018 -0700
+
+    [aat] Fix sanitize slowdown
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11034
+
+ src/hb-aat-layout-common.hh | 4 ++++
+ src/hb-machinery.hh         | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit b9478e28ac4361353e4920d749cc5d29e5bfef67
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 21:52:14 2018 -0700
+
+    Revert "[test] Remove not-fixed yet testcases (#1268)"
+
+    This reverts commit 191eef823fe95355425621f8e002dfe7fe632383.
+
+ ...rfuzz-testcase-minimized-hb-fuzzer-4548492505645056 | Bin 0 ->
+ 122 bytes
+ ...rfuzz-testcase-minimized-hb-fuzzer-6210176798425088 | Bin 0 ->
+ 1420 bytes
+ ...testcase-minimized-hb-shape-fuzzer-5738888765636608 | Bin 0 ->
+ 267731 bytes
+ 3 files changed, 0 insertions(+), 0 deletions(-)
+
+commit af99b20dfddbca75e68f84c5aa465a54728990a6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 18 08:35:20 2018 +0330
+
+    [ci/ubsan] Disable enum sanitization
+
+    Behdad apparently not interested on them
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9e8a9b846ec24e9124d61706272a0e5fa58d7a24
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 21:41:25 2018 -0700
+
+    [aat] Another try at fixing Lookup null objects...
+
+    Ugly as hell, and don't even understand why some bits are needed.
+    But the logic is sound.
+
+ src/hb-aat-layout-common.hh | 23 ++++++++++++++++++++---
+ src/hb-static.cc            |  4 ++++
+ 2 files changed, 24 insertions(+), 3 deletions(-)
+
+commit 191eef823fe95355425621f8e002dfe7fe632383
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 18 08:04:18 2018 +0330
+
+    [test] Remove not-fixed yet testcases (#1268)
+
+    I added them but now that I think, it is a bad idea to have them as
+    fuzzing bots will find good seeds to tweak in order to find easy new
+    testcases which causes duplicated issues.
+
+ ...rfuzz-testcase-minimized-hb-fuzzer-4548492505645056 | Bin 122 ->
+ 0 bytes
+ ...rfuzz-testcase-minimized-hb-fuzzer-6210176798425088 | Bin 1420 ->
+ 0 bytes
+ ...testcase-minimized-hb-shape-fuzzer-5738888765636608 | Bin 267731 ->
+ 0 bytes
+ 3 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 392e1f4ddd7eb649e1a71755b9bcf6431739f98f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 18 07:42:20 2018 +0330
+
+    [test/shape-fuzzer] fail on timeout and ubsan errors (#1267)
+
+ test/fuzzing/run-shape-fuzzer-tests.py | 38
+ ++++++++++++++++++++++++++++++----
+ 1 file changed, 34 insertions(+), 4 deletions(-)
+
+commit eeddda3ec6c28b411d33c74938ec6198c7f6888d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 18 07:38:47 2018 +0330
+
+    [util] Better file-not-found error from hb-shape / hb-view
+
+    fixes #1266
+
+ util/options.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 751c10e55e43e2266a5bba024d560c5127fae4b8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 18 06:36:48 2018 +0330
+
+    [fuzz] Add more new testcases
+
+ ...testcase-minimized-hb-shape-fuzzer-5718464350650368 | Bin 0 ->
+ 41 bytes
+ ...testcase-minimized-hb-shape-fuzzer-5738888765636608 | Bin 0 ->
+ 267731 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit fd282eb3285e6d20f77e8a3a7237b677433ccbb4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 18 06:33:39 2018 +0330
+
+    [fuzz] Add a new testcase
+
+ .../clusterfuzz-testcase-hb-shape-fuzzer-5634395566768128 | Bin 0 ->
+ 106 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 9d42d70269b879e67f3c7724beab8e4cdbfc877a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 17:55:47 2018 -0700
+
+    [trak] Fix calc
+
+    We were getting the first track record always.  Ie. this line:
+
+           if (trackTable[i].get_track_value () == 0.f)
+           {
+    -       trackTableEntry = &trackTable[0];
+    +       trackTableEntry = &trackTable[i];
+            break;
+           }
+
+    The rest is cleanup.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1263 for the
+    most part.
+
+ src/hb-aat-layout-trak-table.hh | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+commit 3341c7fbfb9bc8e137afd9f16da8cf18eb67b25b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 17 15:04:35 2018 -0700
+
+    [fuzzing] Move fuzzing fonts from api/ here
+
+ ...estcase-minimized-hb-subset-fuzzer-5521982557782016 | Bin 1228 ->
+ 0 bytes
+ ...estcase-minimized-hb-subset-fuzzer-5542653037903872 | Bin 160249 ->
+ 0 bytes
+ ...estcase-minimized-hb-subset-fuzzer-5609911946838016 | Bin 313 ->
+ 0 bytes
+ ...estcase-minimized-hb-subset-fuzzer-5670861909524480 | Bin 1298 ->
+ 0 bytes
+ ...estcase-minimized-hb-subset-fuzzer-5750092395970560 | Bin 72435 ->
+ 0 bytes
+ ...estcase-minimized-hb-subset-fuzzer-6651660668502016 | Bin 15229 ->
+ 0 bytes
+ ...ed-hb-subset-get-codepoints-fuzzer-5973295416475648 | Bin 109 ->
+ 0 bytes
+ ...ed-hb-subset-get-codepoints-fuzzer-6136125075750912 | Bin 65816 ->
+ 0 bytes
+ test/api/test-subset-glyf.c                            |   2 +-
+ test/api/test-subset-hdmx.c                            |   4 ++--
+ test/api/test-subset-hmtx.c                            |   2 +-
+ test/api/test-subset.c                                 |   6 +++---
+ .../crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249     | Bin
+ .../crash-b577db318b30f2851828a4c9ef97cb30678b1b54     | Bin
+ .../crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a     | Bin
+ .../crash-e4e0bb1458a91b692eba492c907ae1f94e635480     | Bin
+ .../fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 | Bin
+ .../fonts/oom-ccc61c92d589f895174cdef6ff2e3b20e9999a1a | Bin
+ 18 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 2e7c716511e8b2cfcd059fa2a2ed4cdd48b351bf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 18:35:03 2018 -0700
+
+    [buffer] Add an assert
+
+    See if it helps debugging
+    https://bugs.chromium.org/p/chromium/issues/detail?id=895117
+
+ src/hb-buffer.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 5842756b1398253d38749c4c8a23a1450e642caf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 18:28:55 2018 -0700
+
+    [fuzzing] Delete blink fuzzed data
+
+    These are text, not font.
+
+ ...minimized-blink_harfbuzz_shaper_fuzzer-5099655095123968 | Bin 88 ->
+ 0 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 25fe7e7e1031401d38db1efed360cd75ea7910b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 18:22:54 2018 -0700
+
+    [aat] Comment
+
+ src/hb-aat-layout-common.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 26092bb3d1aa239de5e933700e0371619d147f65
+Author: HinTak <htl10 at users.sourceforge.net>
+Date:   Wed Oct 17 00:54:39 2018 +0100
+
+    "allow-none" annotation for "out" parameters
+
+    Fixes the following warnings:
+    hb-ot-tag.cc:330: Warning: HarfBuzz: invalid "allow-none" annotation:
+    only valid for pointer types and out parameters
+    hb-ot-tag.cc:334: Warning: HarfBuzz: invalid "allow-none" annotation:
+    only valid for pointer types and out parameters
+
+ src/hb-ot-tag.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ba42651608da1be0d152e03ad42ea96fc8476ac7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 17:35:46 2018 -0700
+
+    Fix indent
+
+ test/fuzzing/run-shape-fuzzer-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 49bdb54427b17d439eadf31732a5f2a0add46bf5
+Author: HinTak <htl10 at users.sourceforge.net>
+Date:   Wed Oct 17 00:36:04 2018 +0100
+
+    typo in gobject annotation - "in/out" should be "inout"
+
+    "in/out" should be "inout"
+
+ src/hb-ot-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c0c190c16a2c1b281f40dacdcf515dc5a59ab3bb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 16:39:29 2018 -0700
+
+    [fuzzing] Run tests against fuzzing fonts
+
+    Some disable.
+
+ test/fuzzing/run-shape-fuzzer-tests.py        | 12 ++--
+ test/fuzzing/run-subset-fuzzer-tests.py       | 35 ++++++-----
+ test/shaping/data/in-house/Makefile.sources   |  1 -
+ test/shaping/data/in-house/tests/fuzzed.tests | 84
+ ---------------------------
+ 4 files changed, 24 insertions(+), 108 deletions(-)
+
+commit 7b37705fb579a39334be0618c6215c1b887bf9fc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 16:33:06 2018 -0700
+
+    [fuzzing] Rename
+
+ ...ebdebc6.ttf => 0509e80afb379d16560e9e47bdd7d888bebdebc6} | Bin
+ ...63b6daf.ttf => 1a6f1687b7a221f9f2c834b0b360d3c8463b6daf} | Bin
+ ...28b22cb.ttf => 205edd09bd3d141cc9580f650109556cc28b22cb} | Bin
+ ...f026462.ttf => 217a934cfe15c548b572c203dceb2befdf026462} | Bin
+ ...ac34f18.ttf => 3511ff5c1647150595846ac414c595cccac34f18} | Bin
+ ...675d5a3.ttf => 375d6ae32a3cbe52fbf81a4e5777e3377675d5a3} | Bin
+ ...9c9a56b.ttf => 43979b90b2dd929723cf4fe1715990bcb9c9a56b} | Bin
+ ...1a8e2b0.ttf => 558661aa659912f4d30ecd27bd09835171a8e2b0} | Bin
+ ...0655fa8.ttf => 5a5daf5eb5a4db77a2baa3ad9c7a6ed6e0655fa8} | Bin
+ ...c149ddc.ttf => 641bd9db850193064d17575053ae2bf8ec149ddc} | Bin
+ ...bcf861f.ttf => 8240789f6d12d4cfc4b5e8e6f246c3701bcf861f} | Bin
+ ...1386016.ttf => a34a9191d9376bda419836effeef7e75c1386016} | Bin
+ ...bdae30e.ttf => a69118c2c2ada48ff803d9149daa54c9ebdae30e} | Bin
+ ...6b31fe2.ttf => b9e2aaa0d75fcef6971ec3a96d806ba4a6b31fe2} | Bin
+ ...14a0467.ttf => e88c339237f52d21e01c55f01b9c1b4cc14a0467} | Bin
+ ...1395725.ttf => fab39d60d758cb586db5a504f218442cd1395725} | Bin
+ 16 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 3676c685d407cc7b9b813b4a08e7c5bcd9a47ea1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 16:32:26 2018 -0700
+
+    [fuzzing] Move rest of fuzzing tests here
+
+ .../fonts/0509e80afb379d16560e9e47bdd7d888bebdebc6.ttf  | Bin
+ .../fonts/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf  | Bin
+ .../fonts/205edd09bd3d141cc9580f650109556cc28b22cb.ttf  | Bin
+ .../fonts/217a934cfe15c548b572c203dceb2befdf026462.ttf  | Bin
+ .../fonts/3511ff5c1647150595846ac414c595cccac34f18.ttf  | Bin
+ .../fonts/375d6ae32a3cbe52fbf81a4e5777e3377675d5a3.ttf  | Bin
+ .../fonts/43979b90b2dd929723cf4fe1715990bcb9c9a56b.ttf  | Bin
+ .../fonts/558661aa659912f4d30ecd27bd09835171a8e2b0.ttf  | Bin
+ .../fonts/5a5daf5eb5a4db77a2baa3ad9c7a6ed6e0655fa8.ttf  | Bin
+ .../fonts/641bd9db850193064d17575053ae2bf8ec149ddc.ttf  | Bin
+ .../fonts/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf  | Bin
+ .../fonts/a34a9191d9376bda419836effeef7e75c1386016.ttf  | Bin
+ .../fonts/a69118c2c2ada48ff803d9149daa54c9ebdae30e.ttf  | Bin
+ .../fonts/b9e2aaa0d75fcef6971ec3a96d806ba4a6b31fe2.ttf  | Bin
+ .../fonts/e88c339237f52d21e01c55f01b9c1b4cc14a0467.ttf  | Bin
+ .../fonts/fab39d60d758cb586db5a504f218442cd1395725.ttf  | Bin
+ test/shaping/data/in-house/tests/fuzzed.tests           |  16
+ ----------------
+ 17 files changed, 16 deletions(-)
+
+commit 1487173dcf4137fb210b15d9a869aa1f0c626d15
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 16:30:38 2018 -0700
+
+    [fuzzing] Delete duplicate fonts
+
+ .../233c1e252e737ca79e03a9fd56b71aaa4a230f2b.ttf      | Bin 1048576 ->
+ 0 bytes
+ .../243798dd281c1c77c065958e1ff467420faa9bde.ttf      | Bin 225 ->
+ 0 bytes
+ .../9d8a94a67932a3ab75a596fc8b5c6d0392ca9e49.ttf      | Bin 4545 ->
+ 0 bytes
+ .../b6acef662e0beb8d5fcf5b61c6b0ca69537b7402.ttf      | Bin 3301 ->
+ 0 bytes
+ .../bbf4a308c402f0678c3e82844892a4da2ebe598f.ttf      | Bin 204 ->
+ 0 bytes
+ .../dd9f0c7c7c36f75a18be0cab1cddf8f3ab0f366b.ttf      | Bin 2786 ->
+ 0 bytes
+ .../ef2511f215aa3ca847cbfffbf861793b42170875.ttf      | Bin 1152 ->
+ 0 bytes
+ test/shaping/data/in-house/tests/fuzzed.tests         |   7 -------
+ 8 files changed, 7 deletions(-)
+
+commit 49c041f7c5b135cbcbd1663e18047afd54fc948b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 16:25:24 2018 -0700
+
+    Minor
+
+ test/fuzzing/clusterfuzz-testcase-6107935408390144 | Bin 16800 -> 0 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 36f38ea7033b4e52c6cd94a8a0d686a95c0cc148
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 16:24:03 2018 -0700
+
+    [gpos] Protect mark attachment against out-of-bounds
+
+    Not sure how can happen, but does...
+
+ src/hb-ot-layout-gpos-table.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit 1147ce2392ac6b3d12fdabe69ac5da9bae97e30d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 16:18:32 2018 -0700
+
+    [fuzzing] Add more tests
+
+ .../fuzzing/fonts/clusterfuzz-testcase-6107935408390144 | Bin 0 ->
+ 16800 bytes
+ ...-testcase-minimized-harfbuzz_fuzzer-5973566991106048 | Bin 0 ->
+ 4047 bytes
+ ...-testcase-minimized-hb-shape-fuzzer-5633985665826816 | Bin 0 ->
+ 73 bytes
+ 3 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 12cbe195ae65656dbc9e32b4d50696bc4223136b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 16:13:53 2018 -0700
+
+    [aat] Another non-null offset
+
+ src/hb-aat-layout-ankr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 87205ef935ede70365187549d133014669ea47f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 15:40:44 2018 -0700
+
+    [aat] Make sure Lookup offset is never nulled
+
+    It has unbounded size...
+
+    Fixes https://oss-fuzz.com/v2/testcase-detail/5718889451749376
+
+ src/hb-aat-layout-ankr-table.hh |  2 +-
+ src/hb-aat-layout-common.hh     |  3 ++-
+ src/hb-aat-layout-kerx-table.hh | 18 ++++++++----------
+ src/hb-aat-layout-morx-table.hh |  4 ++--
+ src/hb-open-type.hh             | 12 ++++++------
+ 5 files changed, 19 insertions(+), 20 deletions(-)
+
+commit 1aa353e4fc79dfa880559ff75113ed58fac8392b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 15:26:51 2018 -0700
+
+    Fix tests
+
+ test/shaping/data/in-house/tests/fuzzed.tests | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 98d4ad02b97628e5a9a7bfe3187ccc3851c00b18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 15:17:31 2018 -0700
+
+    [fuzzing] One more
+
+ test/fuzzing/clusterfuzz-testcase-6107935408390144 | Bin 0 -> 16800 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit e6f267c3dfe3e93dfc726266672da5a235fbd930
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 15:16:20 2018 -0700
+
+    [fuzzing] Add more clusterfuzz tests I had lying around
+
+ .../fonts/clusterfuzz-testcase-5517117891805184       | Bin 0 ->
+ 178 bytes
+ ...sterfuzz-testcase-hb-shape-fuzzer-5746142327865344 | Bin 0 ->
+ 219 bytes
+ ...sterfuzz-testcase-hb-shape-fuzzer-5750379279548416 | Bin 0 ->
+ 317 bytes
+ .../clusterfuzz-testcase-minimized-4884742786777088   | Bin 0 ->
+ 393 bytes
+ .../clusterfuzz-testcase-minimized-5255344882188288   | Bin 0 -> 65 bytes
+ .../clusterfuzz-testcase-minimized-5720051798769664   | Bin 0 ->
+ 1048576 bytes
+ .../clusterfuzz-testcase-minimized-5924299061854208   | Bin 0 ->
+ 2786 bytes
+ .../clusterfuzz-testcase-minimized-6460279560863744   | Bin 0 ->
+ 589 bytes
+ ...ized-blink_harfbuzz_shaper_fuzzer-5099655095123968 | Bin 0 -> 88 bytes
+ ...estcase-minimized-hb-shape-fuzzer-5650286710882304 | Bin 0 -> 76 bytes
+ ...stcase-minimized-hb-shape-fuzzer-5672261407735808} | Bin
+ 11 files changed, 0 insertions(+), 0 deletions(-)
+
+commit e53206271db4a83834433ab5f82d16815a18b998
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Oct 17 01:42:04 2018 +0330
+
+    Add all the fonts found by fuzzers to the repo (#1258)
+
+ test/fuzzing/Makefile.am                           |   1 +
+ ...clusterfuzz-testcase-hb-fuzzer-4666056377368576 | Bin 0 -> 1152 bytes
+ ...clusterfuzz-testcase-hb-fuzzer-5662671558934528 | Bin 0 -> 242272
+ bytes
+ ...clusterfuzz-testcase-hb-fuzzer-6243458541944832 | Bin 0 -> 370187
+ bytes
+ ...clusterfuzz-testcase-hb-fuzzer-6303297511096320 | Bin 0 -> 4545 bytes
+ ...clusterfuzz-testcase-hb-fuzzer-6696647723581440 | Bin 0 -> 3266 bytes
+ ...z-testcase-minimized-hb-fuzzer-4523479581851648 | Bin 0 -> 322 bytes
+ ...z-testcase-minimized-hb-fuzzer-4535496598355968 | Bin 0 -> 2786 bytes
+ ...z-testcase-minimized-hb-fuzzer-4548492505645056 | Bin 0 -> 122 bytes
+ ...z-testcase-minimized-hb-fuzzer-4595692015190016 | Bin 0 -> 225 bytes
+ ...z-testcase-minimized-hb-fuzzer-4687441845813248 | Bin 0 -> 162 bytes
+ ...z-testcase-minimized-hb-fuzzer-4706238090706944 | Bin 0 -> 350 bytes
+ ...z-testcase-minimized-hb-fuzzer-4769173588672512 | Bin 0 -> 37 bytes
+ ...z-testcase-minimized-hb-fuzzer-4827735151083520 | Bin 0 -> 1384 bytes
+ ...z-testcase-minimized-hb-fuzzer-4841745322868736 | Bin 0 -> 660 bytes
+ ...z-testcase-minimized-hb-fuzzer-4884742786777088 | Bin 0 -> 393 bytes
+ ...z-testcase-minimized-hb-fuzzer-5216838347653120 | Bin 0 -> 157600
+ bytes
+ ...z-testcase-minimized-hb-fuzzer-5255344882188288 | Bin 0 -> 65 bytes
+ ...z-testcase-minimized-hb-fuzzer-5294584596791296 | Bin 0 -> 1602 bytes
+ ...z-testcase-minimized-hb-fuzzer-5303930168803328 | Bin 0 -> 7321 bytes
+ ...z-testcase-minimized-hb-fuzzer-5331901587914752 | Bin 0 -> 3301 bytes
+ ...z-testcase-minimized-hb-fuzzer-5388906574905344 | Bin 0 -> 9937 bytes
+ ...z-testcase-minimized-hb-fuzzer-5517117891805184 | Bin 0 -> 178 bytes
+ ...z-testcase-minimized-hb-fuzzer-5617496443846656 | Bin 0 -> 195 bytes
+ ...z-testcase-minimized-hb-fuzzer-5672141338968064 | Bin 0 -> 176 bytes
+ ...z-testcase-minimized-hb-fuzzer-5700697074958336 | Bin 0 -> 878 bytes
+ ...z-testcase-minimized-hb-fuzzer-5720051798769664 | Bin 0 -> 1048576
+ bytes
+ ...z-testcase-minimized-hb-fuzzer-5924299061854208 | Bin 0 -> 2786 bytes
+ ...z-testcase-minimized-hb-fuzzer-6023178755244032 | Bin 0 -> 2261 bytes
+ ...z-testcase-minimized-hb-fuzzer-6111685556305920 | Bin 0 -> 586 bytes
+ ...z-testcase-minimized-hb-fuzzer-6160439919509504 | Bin 0 -> 204 bytes
+ ...z-testcase-minimized-hb-fuzzer-6210176798425088 | Bin 0 -> 1420 bytes
+ ...z-testcase-minimized-hb-fuzzer-6260579246276608 | Bin 0 -> 700 bytes
+ ...z-testcase-minimized-hb-fuzzer-6264625609834496 | Bin 0 -> 1731 bytes
+ ...z-testcase-minimized-hb-fuzzer-6424351550210048 | Bin 0 -> 73 bytes
+ ...z-testcase-minimized-hb-fuzzer-6460279560863744 | Bin 0 -> 589 bytes
+ ...z-testcase-minimized-hb-fuzzer-6576177596596224 | Bin 0 -> 385 bytes
+ ...z-testcase-minimized-hb-fuzzer-6595199411159040 | Bin 0 -> 1862 bytes
+ ...z-testcase-minimized-hb-fuzzer-6624904746106880 | Bin 0 -> 42 bytes
+ ...z-testcase-minimized-hb-fuzzer-6723367514144768 | Bin 0 -> 1074 bytes
+ ...case-minimized-hb-shape-fuzzer-5630246225707008 | Bin 0 -> 109 bytes
+ ...case-minimized-hb-shape-fuzzer-5635082459545600 | Bin 0 -> 52 bytes
+ ...case-minimized-hb-shape-fuzzer-5652019562414080 | Bin 0 -> 49 bytes
+ ...case-minimized-hb-shape-fuzzer-5656511058018304 | Bin 0 -> 28 bytes
+ ...case-minimized-hb-shape-fuzzer-5659641787187200 | Bin 0 -> 3498 bytes
+ ...case-minimized-hb-shape-fuzzer-5668791174823936 | Bin 0 -> 3608 bytes
+ ...ase-minimized-hb-shape-fuzzer-56722614077358084 | Bin 0 -> 192 bytes
+ ...case-minimized-hb-shape-fuzzer-5674361600606208 | Bin 0 -> 518 bytes
+ ...case-minimized-hb-shape-fuzzer-5677421274071040 | Bin 0 -> 3608 bytes
+ ...case-minimized-hb-shape-fuzzer-5679244475105280 | Bin 0 -> 256 bytes
+ ...case-minimized-hb-shape-fuzzer-5685596677210112 | Bin 0 -> 58 bytes
+ ...case-minimized-hb-shape-fuzzer-5695615258853376 | Bin 0 -> 194 bytes
+ ...case-minimized-hb-shape-fuzzer-5696686572175360 | Bin 0 -> 256 bytes
+ ...case-minimized-hb-shape-fuzzer-5718889451749376 | Bin 0 -> 1680 bytes
+ ...case-minimized-hb-shape-fuzzer-5719982789361664 | Bin 0 -> 3608 bytes
+ ...case-minimized-hb-shape-fuzzer-5725129603022848 | Bin 0 -> 3608 bytes
+ ...case-minimized-hb-shape-fuzzer-5726089628876800 | Bin 0 -> 76 bytes
+ ...case-minimized-hb-shape-fuzzer-5729361857085440 | Bin 0 -> 2250 bytes
+ ...case-minimized-hb-shape-fuzzer-5733166795456512 | Bin 0 -> 78 bytes
+ ...case-minimized-hb-shape-fuzzer-5734736291430400 | Bin 0 -> 66 bytes
+ ...case-minimized-hb-shape-fuzzer-5740171484463104 | Bin 0 -> 186 bytes
+ ...case-minimized-hb-shape-fuzzer-5750379279548416 | Bin 0 -> 219 bytes
+ ...case-minimized-hb-shape-fuzzer-5762490181353472 | Bin 0 -> 101 bytes
+ ...ase-minimized-hb-subset-fuzzer-5359635656605696 | Bin 0 -> 393270
+ bytes
+ ...ase-minimized-hb-subset-fuzzer-5521982557782016 | Bin 0 -> 1228 bytes
+ ...ase-minimized-hb-subset-fuzzer-5542653037903872 | Bin 0 -> 160249
+ bytes
+ ...ase-minimized-hb-subset-fuzzer-5609911946838016 | Bin 0 -> 313 bytes
+ ...ase-minimized-hb-subset-fuzzer-5629878397829120 | Bin 0 -> 3746 bytes
+ ...ase-minimized-hb-subset-fuzzer-5651059347816448 | Bin 0 -> 2648 bytes
+ ...ase-minimized-hb-subset-fuzzer-5669437462544384 | Bin 0 -> 284427
+ bytes
+ ...ase-minimized-hb-subset-fuzzer-5670861909524480 | Bin 0 -> 1298 bytes
+ ...ase-minimized-hb-subset-fuzzer-5696607199166464 | Bin 0 -> 28 bytes
+ ...ase-minimized-hb-subset-fuzzer-5711951464759296 | Bin 0 -> 284521
+ bytes
+ ...ase-minimized-hb-subset-fuzzer-5747265633779712 | Bin 0 -> 177090
+ bytes
+ ...ase-minimized-hb-subset-fuzzer-5750092395970560 | Bin 0 -> 72435 bytes
+ ...ase-minimized-hb-subset-fuzzer-5758598970343424 | Bin 0 -> 64 bytes
+ ...ase-minimized-hb-subset-fuzzer-6543700493598720 | Bin 0 -> 138425
+ bytes
+ ...ase-minimized-hb-subset-fuzzer-6651660668502016 | Bin 0 -> 15229 bytes
+ ...b-subset-get-codepoints-fuzzer-5203067375976448 | Bin 0 -> 16310 bytes
+ ...b-subset-get-codepoints-fuzzer-5630904853069824 | Bin 0 -> 580 bytes
+ ...b-subset-get-codepoints-fuzzer-5687638085337088 | Bin 0 -> 1206 bytes
+ ...b-subset-get-codepoints-fuzzer-5736539338833920 | Bin 0 -> 512 bytes
+ ...b-subset-get-codepoints-fuzzer-5973295416475648 | Bin 0 -> 109 bytes
+ ...b-subset-get-codepoints-fuzzer-6136125075750912 | Bin 0 -> 65816 bytes
+ ...b-subset-get-codepoints-fuzzer-6394290358976512 | Bin 0 -> 1868 bytes
+ test/fuzzing/run-shape-fuzzer-tests.py             |   4 +
+ test/shaping/data/in-house/tests/fuzzed.tests      |  84
+ +++++++++++++++++++++
+ 87 files changed, 89 insertions(+)
+
+commit 2137582c9696b6e38d70b4a0d4199b315c9fd4ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 14:46:07 2018 -0700
+
+    [morx] Reword ligation
+
+    Still fails MORX-41.  Am talking to Sascha to better understand
+    what CoreText
+    is doing.
+
+ src/hb-aat-layout-morx-table.hh                    | 25
+ ++++++++++++----------
+ test/shaping/data/text-rendering-tests/DISABLED    |  2 ++
+ .../data/text-rendering-tests/Makefile.sources     |  2 +-
+ 3 files changed, 17 insertions(+), 12 deletions(-)
+
+commit c53a25c6579a4d3fe8e6a6fc198d70add41035ec
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 13:57:35 2018 -0700
+
+    [morx] Comment
+
+ src/hb-aat-layout-morx-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c46d42f8f2c303817467c6a4e19d69d0e433dba6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 13:39:54 2018 -0700
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/Makefile.sources  |   1 +
+ .../text-rendering-tests/fonts/TestMORXFourtyone.ttf     | Bin 0 ->
+ 2248 bytes
+ .../data/text-rendering-tests/tests/MORX-41.tests        |   4 ++++
+ 3 files changed, 5 insertions(+)
+
+commit 5eb7e7f6461bcf5b1e1d8ccb49eb904382762533
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 13:32:52 2018 -0700
+
+    Revert "[vector] Simplify Sort" and "More of the same"
+
+    This reverts commit de0b9a466490c2c13d6ec6f59d5122b0a87d3180.
+    This reverts commit 921f0e6ec722940a1e37660e1291aa69f9f39db8.
+
+    Annnnd, revert.  MSVC doesn't like it.
+
+ src/hb-vector.hh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit 661340c475dc928f227d54b3f36eaf6f41c2b6e3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 16 13:24:29 2018 -0700
+
+    [kern] Scale kern pairs before applying
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1255
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1252
+
+ src/hb-ot-kern-table.hh     | 18 ++++++++++++------
+ src/hb-ot-shape-fallback.cc |  2 +-
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+commit de0b9a466490c2c13d6ec6f59d5122b0a87d3180
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 15 22:20:26 2018 -0700
+
+    [vector] More of the same
+
+ src/hb-vector.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 921f0e6ec722940a1e37660e1291aa69f9f39db8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 15 22:19:17 2018 -0700
+
+    [vector] Simplify sort
+
+    Hopefully this fits fine with SFINAE with all our compilers.
+
+ src/hb-vector.hh | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit 61510b63c15e91d80e36a497260db0e2d6d36c66
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Oct 16 14:17:21 2018 +0330
+
+    [test] Minor cleanup in test-multithread and test-ot-name (#1256)
+
+ test/api/CMakeLists.txt                       |  2 +-
+ test/api/Makefile.am                          |  2 +-
+ test/api/test-multithread.c                   |  6 ++-
+ test/api/{test-ot-nameid.c => test-ot-name.c} | 58
+ ++++++++++++++-------------
+ 4 files changed, 36 insertions(+), 32 deletions(-)
+
+commit 42b75dc3a701b13665115e2a234bfa5dedafef3f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Oct 16 10:58:09 2018 +0330
+
+    [kerx] Minor, remove debug bit
+
+ src/hb-aat-layout-kerx-table.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 11703afce6cebbb4c5e7cdea59ca59a1787608b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 15 21:16:58 2018 -0700
+
+    [kerx] Fix Format6 sanitize
+
+    Fixes https://oss-fuzz.com/v2/testcase-detail/5650286710882304
+
+ src/hb-aat-layout-kerx-table.hh | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+commit 4c27da7638f6d072c3ff93223488c4ab316236c1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 15 19:46:45 2018 -0700
+
+    [CBDT] Fix more offsetting
+
+    Fixes https://oss-fuzz.com/v2/testcase-detail/5750379279548416
+
+ src/hb-ot-color-cbdt-table.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 0f85edb7781f4d5ec2de676979be75a0f6559d80
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 15 11:15:54 2018 -0700
+
+    [morx] Another end-of-text corner case
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10990
+
+ src/hb-aat-layout-morx-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 55d5ea666c25f75e9b1bc2eb43cfb104a16ebe04
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 15 11:04:49 2018 -0700
+
+    [kerx] Merge clusters in Ligature
+
+ src/hb-aat-layout-morx-table.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit bb35725cd760f07fdb0586453512a106e534b739
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 15 10:20:39 2018 -0700
+
+    [kerx/morx] More end-of-text protection
+
+ src/hb-aat-layout-kerx-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 8f3048a1f838484babc4948754c16dda8f53daf1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Oct 15 12:16:47 2018 +0330
+
+    [dump-emoji] minor
+
+ src/dump-emoji.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 27e095a613ed0a753231405cab887da19e9aecd1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Oct 15 12:04:14 2018 +0330
+
+    [dump-emoji] better explaination of the usage
+
+ src/dump-emoji.cc | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+commit 8dc6296818e3a52c003852aa185f2b7eb6afa5d3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 15 01:09:05 2018 -0700
+
+    [ot-font] Implement TrueType v_origin
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/537
+
+ src/hb-ot-font.cc                               | 31 +++++++++++++++++-
+ src/hb-ot-hmtx-table.hh                         | 43
+ ++++++++++++++++---------
+ test/shaping/data/in-house/tests/vertical.tests |  2 +-
+ 3 files changed, 59 insertions(+), 17 deletions(-)
+
+commit 6e07076fd094afc8c9c8ad8f08453e7882294592
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 22:22:45 2018 -0700
+
+    [blob] Fix UBSan error
+
+ src/hb-blob.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit fc812faaa96aa4e67814a92376b2da751d5a0aba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 21:32:09 2018 -0700
+
+    [CBDT] Fix more offsetting issues
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/960
+
+    dump-emoji still segfaults.  Needs debugging.
+
+ src/hb-ot-color-cbdt-table.hh | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+commit 6aee3bb87cee88525b745a640df294cb721245f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 21:08:42 2018 -0700
+
+    [CBDT] Fix offset handling
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/960
+
+ src/hb-ot-color-cbdt-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit da744c6b3e79b778f414ec9f4d9070d06ec2a706
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 20:49:21 2018 -0700
+
+    [CBDT] More UnsizedArrayOf cleanup
+
+ src/hb-ot-color-cbdt-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2995b4465bce52b30de2cb6ba24cc80d8602413d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 20:37:57 2018 -0700
+
+    [CBDT] Simplify sanitize
+
+ src/hb-ot-color-cbdt-table.hh | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit 1c76c8f6ff7877e486f6e94d04b2dc65348b26d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 19:39:31 2018 -0700
+
+    [morx] Handle end-of-text conditions in Insertion
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10955
+
+ src/hb-aat-layout-morx-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 60c13976733ea05e71c66c486d62e31ffbb71bac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 19:36:46 2018 -0700
+
+    [buffer] Fix output_glyph at end of buffer
+
+    Part of https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10955
+
+ src/hb-buffer.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 7efa38257b6f79d1c6e2a9bad29c33af276abe29
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 19:30:44 2018 -0700
+
+    [aat] More protection against buffer fail
+
+ src/hb-aat-layout-common.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit e1add2a275a8afa5efc22aa44a4e62646f0b0ba4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 16:26:03 2018 -0700
+
+    [hmtx] Whitespace
+
+ src/hb-ot-hmtx-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 62376a7d983442408059b0b8987e7ca8d1de154e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 15:20:50 2018 -0700
+
+    Ignore signed-integer-overflow while kerning
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1247
+
+ src/hb-ot-kern-table.hh | 1 +
+ src/hb.hh               | 9 +++++++++
+ 2 files changed, 10 insertions(+)
+
+commit 40f2b9355cf827c7b82ea5e55b112ce0032a9abf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 14:56:32 2018 -0700
+
+    [kerx] Fix Format1 sanitize
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10948
+
+ src/hb-aat-layout-kerx-table.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 44af1f93ee32e236a5c14085c72d3fa102a14f5e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 14 14:52:17 2018 -0700
+
+    [aat] Whitespace
+
+ src/hb-aat-layout-common.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 56b8dd17f677ffe97e4d917c47924e1ac7632c71
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 19:03:33 2018 -0400
+
+    [aat] Finish off massaging table
+
+ src/hb-aat-layout.cc | 163
+ +++++++++++++++++++++++++--------------------------
+ 1 file changed, 81 insertions(+), 82 deletions(-)
+
+commit e0c5e0d91bbc0c8b2bb547ba5cb118989affc617
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 18:37:14 2018 -0400
+
+    [aat] WIP remove feature mapping here from hb-coretext
+
+    Need to map enum values to numerics since we don't have CoreText
+    headers.
+
+ src/hb-aat-layout.cc |  94 +++++++++++++++++++++++++
+ src/hb-aat-layout.hh |  22 ++++++
+ src/hb-coretext.cc   | 189
+ +--------------------------------------------------
+ 3 files changed, 117 insertions(+), 188 deletions(-)
+
+commit cb057749131826dd89bc3b92527116a974ae3bbe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 17:03:32 2018 -0400
+
+    [coretext] Prepare AAT feature mapping to be moved
+
+ src/hb-coretext.cc | 39 ++++++++++++++++++++++-----------------
+ 1 file changed, 22 insertions(+), 17 deletions(-)
+
+commit de6e414c565de5f27b9da8c7b8b11f88659a4c42
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 13:48:22 2018 -0400
+
+    [kerx] Sanitize more
+
+ src/hb-aat-layout-kerx-table.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 71f76f2f39c88998b430b171c99b85818d4fa0ab
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 13:36:27 2018 -0400
+
+    [kerx] Fix-up previous commit
+
+    A "&" was missing.  Go back to using pointers that are less
+    error-prone.
+
+ src/hb-aat-layout-kerx-table.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 6d4b054234b4736ca9927268ee3e2d9a0f8f6ead
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 12:20:33 2018 -0400
+
+    [kerx] Use sanitizer instead of handcoded runtime sanitization
+
+ src/hb-aat-layout-kerx-table.hh | 24 +++++++++---------------
+ 1 file changed, 9 insertions(+), 15 deletions(-)
+
+commit 5733113662e668a25187e0042935d955e44fb488
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 12:16:12 2018 -0400
+
+    [kerx] Wire up context down to get_kerning
+
+ src/hb-aat-layout-kerx-table.hh | 32 ++++++++++++++------------------
+ 1 file changed, 14 insertions(+), 18 deletions(-)
+
+commit c4502833b711a76cce1af0c5bf075692b965c991
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 11:48:49 2018 -0400
+
+    [kerx] Use sanitizer.get_num_glyphs() instead of
+    face->get_num_glyphs()
+
+ src/hb-aat-layout-kerx-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit fc45e698f2d8a6d577f33b1e69a83714aceae528
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 11:39:12 2018 -0400
+
+    [kerx] Protext against overflows
+
+ src/hb-aat-layout-kerx-table.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit ed2ee78136c40de8e7b915dfdfd3ca92880912c3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 13 09:47:51 2018 -0400
+
+    [hangul] Fix use-after-free issue
+
+    out_info might have moved since we copied it's position into local
+    info var.
+
+    Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=894937
+
+ src/hb-ot-shape-complex-hangul.cc | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+commit 63109432cf61333e01af4ef5163d4202bb43f84d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Oct 13 14:00:05 2018 +0330
+
+    Cosmetic and minor changes
+
+ src/hb-buffer-serialize.cc   |   4 +-
+ src/hb-ot-cmap-table.hh      |   4 +-
+ src/hb-ot-layout-common.hh   |   4 +-
+ src/hb-ot-layout-gsubgpos.hh |   8 +--
+ src/hb-ot-layout.cc          | 127
+ +++++++++++++++++++------------------------
+ src/hb-ot-layout.h           |  25 +++++----
+ src/hb-ot-math-table.hh      |   8 +--
+ src/hb-ot-name.h             |   1 -
+ src/hb-ot-shape-complex.hh   |  18 +++---
+ 9 files changed, 93 insertions(+), 106 deletions(-)
+
+commit c0a6814b49e376984a0cae9d385a6f6ba8c73579
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 12 16:05:56 2018 -0400
+
+    Touch up new API
+
+    New API:
+    +hb_ot_layout_feature_get_name_ids()
+    +hb_ot_layout_feature_get_characters()
+
+ src/hb-ot-layout.cc       | 16 +++++++++-------
+ src/hb-ot-layout.h        |  2 --
+ test/api/test-ot-nameid.c | 16 ++++++++++------
+ 3 files changed, 19 insertions(+), 15 deletions(-)
+
+commit 477bc9aafeaf89708d13a436869126351e2d9b50
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 12 15:52:31 2018 -0400
+
+    Add hb-ot-name.h
+
+    Actual name-fetching API to come later.
+
+    New API:
+    hb_name_id_t
+    HB_NAME_ID_INVALID
+
+ src/Makefile.sources       |  1 +
+ src/hb-ot-layout-common.hh |  2 +-
+ src/hb-ot-layout.h         | 12 ++---------
+ src/hb-ot-name.h           | 54
+ ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot.h                |  1 +
+ 5 files changed, 59 insertions(+), 11 deletions(-)
+
+commit dc49bd8d813571fe16d9e5342e4a3926ff947bd6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Oct 12 03:00:59 2018 +0330
+
+    Add two APIs for getting stylistic set labels
+
+    * hb_ot_layout_feature_get_characters
+    * hb_ot_layout_feature_get_name_ids
+
+    However HarfBuzz currently doesn't expose an API for retrieving
+    the actual
+    information associated with NameId from the `name` table and that
+    should be
+    done separately.
+
+ docs/harfbuzz-sections.txt |   2 +
+ src/hb-ot-layout-common.hh |  14 +++++
+ src/hb-ot-layout.cc        | 133
+ +++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout.h         |  29 ++++++++++
+ test/api/CMakeLists.txt    |   2 +
+ test/api/Makefile.am       |   1 +
+ test/api/fonts/cv01.otf    | Bin 0 -> 1956 bytes
+ test/api/test-ot-nameid.c  |  96 ++++++++++++++++++++++++++++++++
+ 8 files changed, 277 insertions(+)
+
+commit e9f9c0d81c73d8b6d87700aadb5b886bd289769a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 21:37:45 2018 -0400
+
+    [sanitize] Reorder condition to silence bogus gcc warning
+
+    Was givin a dozen of:
+
+    ../../src/hb-machinery.hh: In member function ‘bool
+    AAT::ankr::sanitize(hb_sanitize_context_t*) const’:
+    ../../src/hb-machinery.hh:307:23: warning: missed loop optimization,
+    the loop counter may overflow [-Wunsafe-loop-optimizations]
+         bool ok = --this->max_ops > 0 &&
+                   ~~~~~~~~~~~~~~~~~~~~~~
+            this->start <= p &&
+            ~~~~~~~~~~~~~~~~~~~
+            p <= this->end &&
+            ~~~~~~~~~~~~~~~^~
+            (unsigned int) (this->end - p) >= len;
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    I believe those are bogus, but this silences them and does not
+    introduce
+    logic issues I believe.
+
+ src/hb-machinery.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 1a6b5ac6c300ed2ccdcd8eadde433120f6e07f2a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 21:22:49 2018 -0400
+
+    Add HB_DEPRECATED_FOR and mark relevant symbols
+
+ src/hb-common.h     |  8 ++++++++
+ src/hb-deprecated.h | 10 +++++-----
+ src/hb-graphite2.h  |  2 +-
+ 3 files changed, 14 insertions(+), 6 deletions(-)
+
+commit c9413d7bb575093411b39ac21974795b6ad91454
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 21:19:39 2018 -0400
+
+    [graphite] Add HB_DEPRECATED annotation
+
+ src/hb-graphite2.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 68c86af187ff645a1305ac3b64832f3bb2350519
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 21:18:20 2018 -0400
+
+    Always compile deprecated symbols
+
+    We haven't been keeping this updated.  So, while we don't expose the
+    symbols in the headers if HB_DISABLE_DEPRECATED is defined, we still
+    always build them.
+
+ src/hb-font.cc | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit c55100000bc20d7c8319cfc54294215a923ffc25
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Thu Oct 11 22:08:14 2018 -0400
+
+    Add missing colons to GObject annotations
+
+ src/hb-ot-tag.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1e816d62efe1b3540ef605092b97794e68ec0832
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Thu Oct 11 20:37:49 2018 -0400
+
+    Fix Indic script tags in Graphite
+
+ src/hb-graphite2.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit bf8469be9a8932cc407b60daf4d494fef46e233b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 20:45:00 2018 -0400
+
+    Attach CursivePositioning backwards, not forward
+
+    This is how Uniscribe does it.  So, adjust.  This is only relevant
+    to fonts that apply cursive positioning from a contextual lookup.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1181
+
+ src/hb-ot-layout-gpos-table.hh                      |  20
+ ++++++++++----------
+ .../9fc3e6960b3520e5304033ef5fd540285f72f14d.ttf    | Bin 0 -> 2380 bytes
+ .../data/in-house/tests/cursive-positioning.tests   |   1 +
+ 3 files changed, 11 insertions(+), 10 deletions(-)
+
+commit bdb53ca24a5ad9671d8e29e17d1d8981505bd882
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 20:20:00 2018 -0400
+
+    [myanmar] Implement Zawgyi shaper
+
+    Enabled if script tag 'Qaag' is passed to HarfBuzz.  Disables mark
+    advance-zeroing and fallback mark-positioning.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1162
+
+ src/hb-ot-shape-complex-myanmar.cc                 |  22
+ +++++++++++++++++++++
+ src/hb-ot-shape-complex.hh                         |   5 +++++
+ src/hb.hh                                          |   8 ++++++++
+ test/shaping/data/in-house/Makefile.sources        |   1 +
+ .../ab14b4eb9d7a67e293f51d30d719add06c9d6e06.ttf   | Bin 0 -> 1792 bytes
+ .../data/in-house/tests/myanmar-zawgyi.tests       |   1 +
+ 6 files changed, 37 insertions(+)
+
+commit 00c5c4a79dfb352a679a5c56bf9c756ab0fa98d2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 20:15:31 2018 -0400
+
+    [myanmar] Shuffle
+
+ src/hb-ot-shape-complex-myanmar.cc | 33 +++++++++++++++++----------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+commit ec8f493bf9fefc33f027db24c4b175990b2d751c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 20:15:00 2018 -0400
+
+    [graphite] Remove assert
+
+ src/hb-graphite2.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 5646dcbd1125049c3af342fadfcfcbd523ce53d3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 19:39:07 2018 -0400
+
+    Minor
+
+ src/hb-ot-tag.cc | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 788e1478557603d30966f12449eef0d0bd51c880
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 19:24:52 2018 -0400
+
+    [test] Add test for USE indic3
+
+ test/shaping/data/in-house/Makefile.sources              |   1 +
+ .../fonts/3c96e7a303c58475a8c750bf4289bbe73784f37d.ttf   | Bin 0 ->
+ 3364 bytes
+ test/shaping/data/in-house/tests/use-indic3.tests        |   1 +
+ 3 files changed, 2 insertions(+)
+
+commit a11972787a2a90b541f92cc56bb885859390a0c0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 19:23:36 2018 -0400
+
+    Minor
+
+ test/shaping/record-test.sh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 654365dc894326f04abaaba415f48ca5ba2d1286
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 17:51:21 2018 -0400
+
+    Pass indic3 tags to USE shaper
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/539
+
+ src/hb-ot-shape-complex.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 28d091d045b042506a1ec2cdefe7cf0d718e8b22
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Thu Oct 11 17:15:22 2018 -0400
+
+    Parse Indic3 tags
+
+ src/hb-ot-tag.cc       | 11 ++++++++---
+ test/api/test-ot-tag.c | 44 +++++++++++++++++++++++++-------------------
+ 2 files changed, 33 insertions(+), 22 deletions(-)
+
+commit 211cd3691ba01b1cb2eeb8a91ac3532181791a8a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 17:31:29 2018 -0400
+
+    Remove remains of get-codepoint-fuzzer
+
+ test/fuzzing/CMakeLists.txt             |  7 +------
+ test/fuzzing/run-subset-fuzzer-tests.py | 12 ------------
+ 2 files changed, 1 insertion(+), 18 deletions(-)
+
+commit 120ed0272569e6a34172a511d4a5a70a3a18f1d2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 17:08:12 2018 -0400
+
+    [fuzzing] Fold get-codepoints-fuzzer into subset-fuzzer
+
+ test/fuzzing/Makefile.am                        | 16 ----------------
+ test/fuzzing/hb-subset-fuzzer.cc                |  5 +++++
+ test/fuzzing/hb-subset-get-codepoints-fuzzer.cc | 23
+ -----------------------
+ 3 files changed, 5 insertions(+), 39 deletions(-)
+
+commit 2c824d3644e16643c2bbe85fb88f9fb6fed53ce7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 16:41:01 2018 -0400
+
+    [aat] Fix two wrongs that made a right before!
+
+    Unfortunately our static asserts (DEFINE_SIZE_STATIC) don't actually
+    fail when used in templates, thanks to SFINAE.  Le sighs.
+
+    Probably fixes
+    https://oss-fuzz.com/v2/testcase-detail/5740171484463104
+
+ src/hb-aat-layout-common.hh | 4 ++--
+ src/hb-open-type.hh         | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit e940530c9723c3a581a5d5b31e5f419865dd6cc7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 15:56:17 2018 -0400
+
+    [aat] Fix mul overflow
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10897
+
+ src/hb-aat-layout-common.hh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit 1d995a340b9e17fc8dca7a3e88e0918de2d8f02c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 15:42:54 2018 -0400
+
+    Minor
+
+ test/api/hb-subset-test.h   | 6 ++----
+ test/api/test-multithread.c | 5 +----
+ test/fuzzing/main.cc        | 2 +-
+ 3 files changed, 4 insertions(+), 9 deletions(-)
+
+commit 0744a02cb12e4d800abb611dfa5d268bb2dfd9f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 15:14:18 2018 -0400
+
+    [arabic] Update to latest UTR#53
+
+    From Lorna Evans: "That was a new character added to Unicode 11.0"
+
+ src/hb-ot-shape-complex-arabic.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 57b05210b1a8968d18ccbbe70879b2e11b6a09f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 15:03:21 2018 -0400
+
+    [test] Fix use of deprecated symbols
+
+ test/api/test-ot-tag.c | 60
+ ++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 46 insertions(+), 14 deletions(-)
+
+commit 4f9e36e8cf5d9d3d3e5a1ed46149355ee5f5e9fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 14:32:59 2018 -0400
+
+    [graphite] Remove deprecated symbol use
+
+ src/hb-graphite2.cc | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+commit da591f2a9d2ae2a5878d3b2ef78a6d589b19aab0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 14:30:15 2018 -0400
+
+    Whitespace
+
+ src/hb-ot-tag.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 4d205f0462b19f371df495b9cc12c0128f507de9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 14:25:48 2018 -0400
+
+    [graphite] Fix deva/dev2 resolution
+
+    See
+    https://github.com/harfbuzz/harfbuzz/pull/730#issuecomment-428277800
+
+ src/hb-graphite2.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8061664ad1a5933098adc3bc1dca0b5be48586ef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 14:16:55 2018 -0400
+
+    Add doc stubs for recently added API
+
+    Thanks to David Corbett who revamped our script and language
+    processing
+    and implemented full BCP 47 support.
+
+    https://github.com/harfbuzz/harfbuzz/pull/730
+
+    New API:
+    +hb_ot_layout_table_select_script()
+    +hb_ot_layout_script_select_language()
+    +HB_OT_MAX_TAGS_PER_SCRIPT
+    +HB_OT_MAX_TAGS_PER_LANGUAGE
+    +hb_ot_tags_from_script_and_language()
+    +hb_ot_tags_to_script_and_language()
+
+    Deprecated API:
+    -hb_ot_layout_table_choose_script()
+    -hb_ot_layout_script_find_language()
+    -hb_ot_tags_from_script()
+    -hb_ot_tag_from_language()
+
+ src/hb-ot-layout.cc | 10 ++++++++++
+ src/hb-ot-tag.cc    | 21 ++++++++++++++++-----
+ src/hb-ot-tag.h     | 10 ++++++++++
+ src/hb-unicode.h    |  2 +-
+ 4 files changed, 37 insertions(+), 6 deletions(-)
+
+commit cf975ac653bff369f4ed7ba7fc04fae6ce2cec95
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 14:07:44 2018 -0400
+
+    Remove use of deprecated function
+
+ src/hb-ot-layout.cc | 23 ++++++++++++-----------
+ src/hb-ot-layout.h  | 12 ++++++------
+ 2 files changed, 18 insertions(+), 17 deletions(-)
+
+commit 66790d64c7120b75c72bf91c769dc52d95858909
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Mon Sep 10 13:15:00 2018 -0400
+
+    Increase HB_OT_MAX_TAGS_PER_SCRIPT to 3
+
+    No script has 3 tags yet, but the plan is for the Indic scripts
+    to each
+    get a third tag someday.
+
+ src/hb-ot-tag.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit bca7a16938609539e4adb5cdf943734b7dfa1561
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Mon Sep 10 12:05:51 2018 -0400
+
+    Update language system tag registry to OT 1.8.3
+
+ src/gen-tag-table.py   | 10 +++++++++-
+ src/hb-ot-tag-table.hh | 44 +++++++++++++++++++++++++++++++++-----------
+ 2 files changed, 42 insertions(+), 12 deletions(-)
+
+commit 7f1fbfe2e312f397db9271dd17a8e701489ffc79
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Mon Jul 23 21:19:23 2018 -0400
+
+    Add hb_ot_tags_to_script_and_language
+
+ docs/harfbuzz-sections.txt |  3 +-
+ src/hb-ot-map.cc           |  2 +-
+ src/hb-ot-tag.cc           | 75
+ ++++++++++++++++++++++++++++++++++++++++------
+ src/hb-ot-tag.h            | 18 +++++++----
+ test/api/test-ot-tag.c     | 33 ++++++++++++++++++--
+ 5 files changed, 112 insertions(+), 19 deletions(-)
+
+commit 3f8877473fb4c72a6f3edfcfc927b9993a5f3616
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Thu Jul 19 13:48:07 2018 -0400
+
+    Switch on the first char of a complex language tag
+
+    This results in a tenfold speed-up for the common case of tags
+    that are
+    not complex, in the sense of `hb_ot_tags_from_complex_language`.
+
+ src/gen-tag-table.py   |  171 ++++--
+ src/hb-ot-tag-table.hh | 1580
+ ++++++++++++++++++++++++------------------------
+ 2 files changed, 922 insertions(+), 829 deletions(-)
+
+commit a754d44195021603306af2a296d06187eda95409
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Mon Jul 16 21:14:48 2018 -0400
+
+    Map Quechua languages to closest ones with tags
+
+    OpenType only officially maps four ISO 639 codes to Quechua languages,
+    but prior versions of HarfBuzz also mapped qu to 'QUZ '. Because qu
+    is a
+    macrolanguage, the mapping now applies to all individual Quechua
+    languages. OpenType calls 'QUZ ' "Quechua", but it really corresponds
+    to
+    Cusco Quechua, so the individual Quechua languages should not all
+    necessarily be mapped to it.
+
+ src/gen-tag-table.py   | 32 ++++++++++++++++++++++++++
+ src/hb-ot-tag-table.hh | 62
+ +++++++++++++++++++++++++++-----------------------
+ 2 files changed, 65 insertions(+), 29 deletions(-)
+
+commit 65d01f77552a5102ee114d9917fd2ecf091a35c3
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Thu Jan 18 16:33:39 2018 -0500
+
+    Test deprecated tag fallback in a font
+
+    The font supports the deprecated tag 'DHV ' instead of 'DIV '. dv is
+    mapped to 'DIV ' and 'DHV ', in that order. The test specifies
+    `--language=dv`, demonstrating that if a font does not support
+    the first
+    OpenType tag mapped to a BCP 47 tag, it will fall back to the
+    next tag.
+
+ .../fonts/d3129450fafe5e5c98cfc25a4e71809b1b4d2855.ttf    | Bin 0 ->
+ 956 bytes
+ test/shaping/data/in-house/tests/language-tags.tests      |   1 +
+ 2 files changed, 1 insertion(+)
+
+commit 7c7cb2a98907d99ca86bdbfca0bf9c48bfa4ed49
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Sat Jan 20 15:53:09 2018 -0500
+
+    Match extlang subtags
+
+    If the second subtag of a BCP 47 tag is three letters long, it denotes
+    an extended language. The tag converter ignores the language
+    subtag and
+    uses the extended language instead.
+
+    There are some grandfathered exceptions, which are handled earlier.
+
+ src/gen-tag-table.py   |  2 +-
+ src/hb-ot-tag-table.hh | 21 +++++++++++++++++++++
+ src/hb-ot-tag.cc       | 10 +++++++++-
+ test/api/test-ot-tag.c |  7 +++++++
+ 4 files changed, 38 insertions(+), 2 deletions(-)
+
+commit 2f1f961cc0f0f907916b4b00342d8a2dda8b4ee1
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri Dec 8 22:45:52 2017 -0500
+
+    Autogenerate the BCP 47 to OpenType mappings
+
+    The new script, gen-tag-table.py, generates `ot_languages`
+    automatically
+    from the [OpenType language system tag registry][ot] and the [IANA
+    Language Subtag Registry][bcp47] with some manual modifications. If an
+    OpenType tag maps to a BCP 47 macrolanguage, all the macrolanguage's
+    individual languages are mapped to the same OpenType tag, except for
+    individual languages with their own OpenType mappings. Deprecated
+    BCP 47 tags are canonicalized.
+
+    [ot]:
+    https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags
+    [bcp47]:
+    https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
+
+    Some OpenType tags correspond to multiple ISO 639 codes. The mapping
+    from ISO 639 codes lists OpenType tags in priority order, such
+    that more
+    specific or more likely tags appear first.
+
+    Some OpenType tags have no corresponding ISO 639 code in the
+    registry so
+    their mappings use BCP 47 subtags besides the language. For example,
+    any
+    BCP 47 tag with a fonipa variant subtag is mapped to 'IPPH', and
+    'IPPH'
+    is mapped back to und-fonipa.
+
+    Other OpenType tags have no corresponding ISO 639 code because it
+    is not
+    clear what they are for. HarfBuzz just ignores these tags.
+
+    One such ignored tag is 'ZHP ' (Chinese Phonetic). It probably means
+    zh-Latn. However, it is used in Microsoft JhengHei and Microsoft YaHei
+    with the script tag 'hani', implying that it is not a romanization
+    scheme after all. It would be simple enough to add this mapping to
+    gen-tag-table.py once a definitive mapping is determined.
+
+    The manual modifications are mainly either obvious mappings that the
+    OpenType registry omits or mappings for compatibility with previous
+    versions of HarfBuzz. Some of the old mappings were discarded, though,
+    for homophonous language names. For example, OpenType maps 'KUI ' to
+    kxu; previous versions of HarfBuzz also mapped it to kvd, because kvd
+    and kxu both happen to be called "Kui".
+
+    gen-tag-table.py also generates a function to convert multi-subtag
+    tags
+    like el-polyton and zh-HK to OpenType tags, replacing
+    `ot_languages_zh`
+    and the hard-coded list of special cases in
+    `hb_ot_tags_from_language`.
+    It also generates a function to convert OpenType tags to BCP 47,
+    replacing the hard-coded list of special cases in
+    `hb_ot_tag_to_language`.
+
+ src/Makefile.am        |    9 +-
+ src/Makefile.sources   |    1 +
+ src/gen-tag-table.py   | 1013 ++++++++++++++++++++++++
+ src/hb-ot-tag-table.hh | 1997
+ ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-tag.cc       |  842 +-------------------
+ src/hb-ot-tag.h        |    2 +-
+ test/api/test-ot-tag.c |   66 +-
+ 7 files changed, 3092 insertions(+), 838 deletions(-)
+
+commit 2c7d4db7af16e228bb30eddf7334a524b74ae26c
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri Dec 29 20:19:05 2017 +0800
+
+    Deprecate obsolete functions
+
+    `hb_ot_tags` replaces `hb_ot_tags_from_script` and
+    `hb_ot_tag_from_language`.
+
+    `hb_ot_layout_table_select_script` replaces
+    `hb_ot_layout_table_choose_script`.
+
+    `hb_ot_layout_script_select_language` replaces
+    `hb_ot_layout_script_find_language`.
+
+ docs/harfbuzz-sections.txt |  8 ++++----
+ src/hb-deprecated.h        | 23 +++++++++++++++++++++++
+ src/hb-ot-layout.h         | 15 ---------------
+ src/hb-ot-tag.h            |  8 --------
+ 4 files changed, 27 insertions(+), 27 deletions(-)
+
+commit 91067716f5e7b15d9a642f69019246c83fc7c108
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri Dec 8 11:21:14 2017 -0500
+
+    Refactor the selection of script and language tags
+
+    The old hb-ot-tag.cc functions, `hb_ot_tags_from_script` and
+    `hb_ot_tag_from_language`, are now wrappers around a new function:
+    `hb_ot_tags`. It converts a script and a language to arrays of script
+    tags and language tags. This will make it easier to add new script
+    tags
+    to scripts, like 'dev3'. It also allows for language fallback chains;
+    nothing produces more than one language yet though.
+
+    Where the old functions return the default tags 'DFLT' and 'dflt',
+    `hb_ot_tags` returns an empty array. The caller is responsible for
+    using the default tag in that case.
+
+    The new function also adds a new private use subtag syntax for script
+    overrides: "x-hbscabcd" requests a script tag of 'abcd'.
+
+    The old hb-ot-layout.cc functions,`hb_ot_layout_table_choose_script`
+    and
+    `hb_ot_layout_script_find_language` are now wrappers around the new
+    functions `hb_ot_layout_table_select_script` and
+    `hb_ot_layout_script_select_language`. They are essentially the
+    same as
+    the old ones plus a tag count parameter.
+
+    Closes #495.
+
+ docs/harfbuzz-sections.txt |    5 +
+ src/hb-ot-layout.cc        |   43 +-
+ src/hb-ot-layout.h         |   16 +
+ src/hb-ot-map.cc           |   13 +-
+ src/hb-ot-tag.cc           | 1639
+ ++++++++++++++++++++++++--------------------
+ src/hb-ot-tag.h            |   11 +
+ test/api/test-ot-tag.c     |  107 +++
+ 7 files changed, 1070 insertions(+), 764 deletions(-)
+
+commit a03f5f4dfbbf885db567c3909241a55eb5869fce
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Thu Dec 28 22:59:29 2017 +0800
+
+    Replace "ISO 639" with "BCP 47"
+
+    `hb_language_from_string` accepts not only ISO 639 but also BCP
+    47. Not
+    all ISO 639 codes are valid BCP 47 tags but the function does
+    not accept
+    overlong language subtags anyway.
+
+ src/hb-buffer.cc | 2 +-
+ src/hb-common.cc | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 0b9d60e1a1c4b7867ac907bbd7c004191a14e697
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 13:26:58 2018 -0400
+
+    [aat] Apply kerx if GPOS kern was not applied
+
+    Ned tells me this is what Apple does.
+
+ src/hb-ot-shape.cc | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+commit b59a428af08d6451a47f40ed01e594815ebf6303
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 13:24:17 2018 -0400
+
+    Minor
+
+ src/hb-ot-shape.cc | 6 +++++-
+ src/hb-ot-shape.hh | 5 +++--
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+commit 100e95f48e3d137c654d206e858d6419ea62a12c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 11:30:45 2018 -0400
+
+    [trak] Add tests
+
+ test/shaping/data/in-house/Makefile.sources     |   1 +
+ test/shaping/data/in-house/fonts/TestTRAK.ttf   | Bin 0 -> 2456 bytes
+ test/shaping/data/in-house/tests/aat-trak.tests |   8 ++++++++
+ 3 files changed, 9 insertions(+)
+
+commit 04f72e8990ea61ffc6b62105c75e0a3e1b1ebab4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 11:25:07 2018 -0400
+
+    [trak] Implement extrapolation
+
+    This concludes trak, as well as AAT shaping support!
+
+ src/hb-aat-layout-trak-table.hh | 39
+ ++++++++++++++++++++-------------------
+ 1 file changed, 20 insertions(+), 19 deletions(-)
+
+commit d6a12dba6da6262fd9e5d8397b46ac8516136cae
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 11:10:06 2018 -0400
+
+    [trak] Fix, and hook up
+
+    Works beautifully!  Test coming.
+
+ src/hb-aat-layout-common.hh     |  4 ++--
+ src/hb-aat-layout-trak-table.hh |  6 ++++--
+ src/hb-aat-layout.cc            | 25 ++++++++++++++++++++++++-
+ src/hb-aat-layout.hh            |  8 ++++++++
+ src/hb-ot-shape.cc              |  2 ++
+ 5 files changed, 40 insertions(+), 5 deletions(-)
+
+commit 3d7dea6dfdc9e75dcca100a79525aa3736dbe29c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 10:32:08 2018 -0400
+
+    [trak] Handle nSizes=0 and 1
+
+ src/hb-aat-layout-trak-table.hh | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+commit 451f3de521ff1b7f4d3b8ebb2cc0b95d88c9314a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 10:30:32 2018 -0400
+
+    [trak] Fix counting
+
+ src/hb-aat-layout-trak-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit a5be380cae9b49ed85c8620f1921209ef61a72ad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 10:29:02 2018 -0400
+
+    [trak] More
+
+ src/hb-aat-layout-trak-table.hh | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+commit d06c4a867f0d383d8c27f2957e646d9e3fe6853b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 10:22:01 2018 -0400
+
+    [trak] Only adjust around first glyph
+
+    Assumes graphemes only have one base glyph.
+
+ src/hb-aat-layout-trak-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 071a2cbcddcbafae9458e674c21db5001b39518d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 10:18:46 2018 -0400
+
+    [trak] Clean up
+
+ src/hb-aat-layout-trak-table.hh | 67
+ +++++++++++++++++++++++------------------
+ 1 file changed, 37 insertions(+), 30 deletions(-)
+
+commit fbbd926dba163d9a2a6a62f380951f03363c2b14
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 01:22:29 2018 -0400
+
+    [kerx] Implement Format4 action_type=1 contour-point-based attachment
+
+    Untested.
+
+    This concludes kerx table support!
+
+ src/hb-aat-layout-kerx-table.hh | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+commit b6bc0d4ff62e4509643db3b304306a72bbcb2c38
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 01:17:57 2018 -0400
+
+    [kerx] Implement Format4 action_type=2 coordinate-based attachment
+
+    Untested.
+
+ src/hb-aat-layout-kerx-table.hh | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+commit 1622ba5943d14b2d50d45dc17fb723f4c9ddb0bb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 01:14:18 2018 -0400
+
+    [kerx] Implement Format4 'ankr'-based mark attachment
+
+    Tested with Kannada MN:
+
+    $ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0CCD,0C95,0CD6
+    [kn_ka.vattu=0+230|kn_ai_length_mark=1 at 326,0+607]
+
+ src/hb-aat-layout-common.hh     |  8 ++++++--
+ src/hb-aat-layout-kerx-table.hh | 20 +++++++++++++++++---
+ src/hb-aat-layout.cc            | 20 ++++++++++++++++----
+ src/hb-ot-layout-gpos-table.hh  |  4 ----
+ 4 files changed, 39 insertions(+), 13 deletions(-)
+
+commit 7bb4da7d9538f3d4b1d28030d43e0c3d720d821b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 00:52:07 2018 -0400
+
+    [aat] Wire up 'ankr' table to apply context
+
+ src/hb-aat-layout-common.hh | 7 +++++--
+ src/hb-aat-layout.cc        | 8 +++++++-
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+commit 28f0367aab648c486d6e8d0e13dbbb2af1b65dcc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 11 00:12:49 2018 -0400
+
+    [kerx] Flesh out Format4
+
+    Doesn't apply actions yet.
+
+ src/hb-aat-layout-kerx-table.hh | 122
+ ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 118 insertions(+), 4 deletions(-)
+
+commit 947962a287d9aca2cb509c11f44cb5150aa6daf1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 23:07:03 2018 -0400
+
+    [ankr] Implement table access
+
+ src/hb-aat-layout-ankr-table.hh | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit 7281cb3eeb00091c6e6085895afd4a38a0516f35
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 22:56:52 2018 -0400
+
+    [ankr] Start fixing
+
+ src/hb-aat-layout-ankr-table.hh | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+commit 34caadc5c78e3d09faf11ef60bfade8f64f55de2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 22:17:07 2018 -0400
+
+    Ugh. Re-enable accidentally disabled GPOS
+
+ src/hb-ot-shape.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f7c45bc33ec1559c960a039b770d5c37bd82f057
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 22:15:13 2018 -0400
+
+    [kerx] Allow granularly disabling kerning
+
+ src/hb-aat-layout-kerx-table.hh | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit 2b72c4b63d29eea39b646c8a1a1cfc2db732e1a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 21:53:14 2018 -0400
+
+    [kerx] Comment
+
+ src/hb-aat-layout-kerx-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 9f450f07b0a1593962e3b45d00f2cf93916f3466
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 21:46:58 2018 -0400
+
+    [kerx] Make Format1 work
+
+    Tested using Kannada MN:
+
+    $ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0C95,0CCd,C95,CCD
+    [kn_ka.virama=0+1299|kn_ka.vattu=0+115|_blank=0 at -115,0+385]
+
+    $ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0C95,0CCd,C95,CCD
+    --features=-kern
+    [kn_ka.virama=0+1799|kn_ka.vattu=0+230|_blank=0+0]
+
+    I don't see the GPOS table in the font do the same.  ¯\_(ツ)_/¯
+
+ src/hb-aat-layout-kerx-table.hh | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+commit 504cb68fc972c7f606bf9fc62015376382f78f45
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 21:29:46 2018 -0400
+
+    Disable mark advance zeroing as well as mark fallback positioning
+    if doing kerx
+
+ src/hb-ot-shape.cc | 50
+ ++++++++++++++++++++++++++------------------------
+ 1 file changed, 26 insertions(+), 24 deletions(-)
+
+commit 84967537966a76297c89460d95e7336f1bfc332d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 21:18:37 2018 -0400
+
+    [kerx] Implement Format1
+
+    Untested.
+
+ src/hb-aat-layout-kerx-table.hh | 62
+ +++++++++++++++++++++++++++++++++--------
+ src/hb-aat-layout-morx-table.hh |  2 +-
+ 2 files changed, 52 insertions(+), 12 deletions(-)
+
+commit c9165f5450b99e6d93e2a168b198384a221eef58
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 20:43:21 2018 -0400
+
+    [kerx] More UnsizedArrayOf<>
+
+ src/hb-aat-layout-kerx-table.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit ca54eba4846d0afda4601929556617a7ebe51714
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 20:41:16 2018 -0400
+
+    [kerx] Fix bound-checking error introduced a couple commits past
+
+ src/hb-aat-layout-kerx-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 339036dd970625e03696b4533ced1e25fc4fd131
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 20:37:22 2018 -0400
+
+    [kerx] Start fleshing out Format1
+
+ src/hb-aat-layout-kerx-table.hh | 59
+ +++++++++++++++++++++++++++++++++++------
+ src/hb-aat-layout-morx-table.hh |  2 +-
+ 2 files changed, 52 insertions(+), 9 deletions(-)
+
+commit ab1f30bd059f1d2270793e9726b60666b328d2b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 20:10:20 2018 -0400
+
+    [kerx] Implement Format6
+
+    Untested.  The only Apple font shipping with this format is San
+    Francisco fonts
+    that use this for their kerx variation tables, which we don't support.
+
+ src/hb-aat-layout-kerx-table.hh | 73
+ +++++++++++++++++++++++++++++++++--------
+ 1 file changed, 60 insertions(+), 13 deletions(-)
+
+commit c9a2ce9e05f91730a2150b9214dc6a49f31555c1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 20:00:44 2018 -0400
+
+    [kerx] Move bounds-checking to subtable length itself
+
+ src/hb-aat-layout-kerx-table.hh | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+commit 22955b23cdeb48e46cdffd0eb906a855a420c4d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 19:58:20 2018 -0400
+
+    [kerx] Start fleshing out Format6
+
+ src/hb-aat-layout-kerx-table.hh | 42
+ ++++++++++++++++++++++++++++++++---------
+ src/hb-open-type.hh             |  3 +++
+ 2 files changed, 36 insertions(+), 9 deletions(-)
+
+commit f6aaad9b4ffb42e6cd8398f6439fe420e393c8f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 19:20:06 2018 -0400
+
+    [kerx] When rejecting variable kerning, also check for tupleCount
+
+ src/hb-aat-layout-kerx-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 7ed5366d3cfca9c533250cb419e8cc878f32505d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 19:11:30 2018 -0400
+
+    [kerx] No-op
+
+    Tested that Format0 works with Kannada MN font:
+
+    $ make -j5 lib -s && HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc
+    -u 0C95,0CC2
+    [kn_ka=0+1000|kn_matra_uu=0 at -30,0+1345]
+
+    $ make -j5 lib -s && HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u
+    0C95,0CC2 --features=-kern
+    [kn_ka=0+1030|kn_matra_uu=0+1375]
+
+    Note that GPOS does the same with 'dist' feature, and applies the
+    whole difference to the
+    same glyph:
+
+    $ make -j5 lib -s && ./hb-shape Kannada\ MN.ttc -u 0C95,0CC2
+    [kn_ka=0+970|kn_matra_uu=0+1375]
+
+    $ make -j5 lib -s && ./hb-shape Kannada\ MN.ttc -u 0C95,0CC2
+    --features=-dist
+    [kn_ka=0+1030|kn_matra_uu=0+1375]
+
+ src/hb-aat-layout-kerx-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 7fa69e92ca3dd9d8fa92aba0e01098165d2b7975
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 19:02:32 2018 -0400
+
+    Comment
+
+ src/hb-machinery.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 7e6e5bf6147596d6d096e2ba37f3a6eefd7429cd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 18:59:07 2018 -0400
+
+    Fix option string matching
+
+ src/hb-common.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5d34164d98f04816aafaa0abfc44cd899c7d70b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 18:14:41 2018 -0400
+
+    [kern/kerx] Fix offset base
+
+    Disable kern Format2.
+
+    Fix kerx Format2.  Manually tested this with Tamil MN font and
+    it works:
+
+    $ HB_OPTIONS=aat ./hb-shape Tamil\ MN.ttc -u 0B94,0B95
+    [tgv_au=0+3435|tgc_ka=1 at -75,0+1517]
+
+     HB_OPTIONS=aat ./hb-shape Tamil\ MN.ttc -u 0B94,0B95 --features=-kern
+    [tgv_au=0+3510|tgc_ka=1+1592]
+
+ src/hb-aat-layout-kerx-table.hh | 73
+ +++++++++++++++++++++++++----------------
+ src/hb-ot-kern-table.hh         |  7 ++++
+ 2 files changed, 52 insertions(+), 28 deletions(-)
+
+commit 60f86d32d7c735ccf783b382e18ecdc096eaa682
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 18:10:05 2018 -0400
+
+    [kerx] Don't loop over kerning subtables if kerning disabled
+
+ src/hb-aat-layout-kerx-table.hh | 12 ++++++++++++
+ src/hb-ot-shape.cc              |  4 ++--
+ src/hb-ot-shape.hh              |  1 +
+ 3 files changed, 15 insertions(+), 2 deletions(-)
+
+commit 38a7a8a89ed035a1d1fc34a675a1860ad660b6ff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 17:44:46 2018 -0400
+
+    Allow HB_OPTIONS=aat to prefer AAT tables over OT
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/322
+
+ src/hb-common.cc   | 23 +++++++++++++++++++++--
+ src/hb-debug.hh    |  7 ++++---
+ src/hb-ot-shape.cc | 24 ++++++++++++++++--------
+ 3 files changed, 41 insertions(+), 13 deletions(-)
+
+commit 44f09afd5bd4f4f1ea47ca54ac9d605219b06910
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 17:32:32 2018 -0400
+
+    [kerx] Skip variation subtables
+
+ src/hb-aat-layout-kerx-table.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 1e8fdd285f90b7b715b6d9ca9222a3c91cbea6b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 16:32:35 2018 -0400
+
+    Remove HAVE_OT
+
+    We never tested compiling without it.  Just kill it.  We always build
+    our own shaper.
+
+ CMakeLists.txt        | 1 -
+ configure.ac          | 6 ------
+ src/Makefile.am       | 2 --
+ src/hb-shaper-list.hh | 2 --
+ src/hb.hh             | 2 --
+ test/api/Makefile.am  | 4 +---
+ test/api/test-c.c     | 5 +----
+ util/Makefile.am      | 4 ----
+ util/options.cc       | 4 ----
+ util/options.hh       | 2 --
+ 10 files changed, 2 insertions(+), 30 deletions(-)
+
+commit 7727e737566ddc826647e19fc645b296ad5a0cac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 13:24:51 2018 -0400
+
+    [kerx] Actually hook up, and fix crash
+
+ src/hb-aat-layout-common.hh     | 6 ++++++
+ src/hb-aat-layout-kerx-table.hh | 4 ++--
+ src/hb-ot-shape.cc              | 4 ++--
+ 3 files changed, 10 insertions(+), 4 deletions(-)
+
+commit b3390990f508def9c375716614b92fc7b0038228
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 12:07:49 2018 -0400
+
+    Add per-subtable set-digests
+
+    This speeds up Roboto shaping by ~10%.  I was hoping for more.
+    Still, good defense against lookups with many subtables.
+
+ src/hb-null.hh               |   2 +-
+ src/hb-ot-layout-gsubgpos.hh | 108
+ +++++++++++++++++++++++--------------------
+ 2 files changed, 59 insertions(+), 51 deletions(-)
+
+commit e78549edfb4df617128a5f5ddd12692f1d0af4bf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 11:54:48 2018 -0400
+
+    Move apply down into subtables accel
+
+ src/hb-ot-layout-gsubgpos.hh | 10 +++++++++-
+ src/hb-ot-layout.cc          | 17 +++--------------
+ 2 files changed, 12 insertions(+), 15 deletions(-)
+
+commit 78c09bf21335a0f2b538b37de6647af08e3b1161
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 11:50:46 2018 -0400
+
+    Move subtable array into lookup accel
+
+ src/hb-null.hh               |  2 +-
+ src/hb-ot-layout-gsubgpos.hh | 14 +++++++++++---
+ src/hb-ot-layout.cc          | 16 ++++++----------
+ 3 files changed, 18 insertions(+), 14 deletions(-)
+
+commit 97e5913d5ac2cd313fb3923e9602358d7f75f11d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 11:41:05 2018 -0400
+
+    Move more code
+
+ src/hb-ot-layout-gsubgpos.hh               | 17 +++++++++++++++++
+ src/hb-ot-layout.cc                        | 12 ++++++------
+ src/hb-ot-layout.hh                        | 20 ++------------------
+ src/hb-ot-shape-complex-arabic-fallback.hh |  2 +-
+ 4 files changed, 26 insertions(+), 25 deletions(-)
+
+commit c8f2d9334c0f91ec30f1c7821eb44bb5149bd31c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 11:36:28 2018 -0400
+
+    Move code
+
+    In preparation to move add per-subtable set digests...
+
+ src/hb-ot-layout-gsubgpos.hh | 50 ++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout.cc          | 57
+ ++++----------------------------------------
+ 2 files changed, 54 insertions(+), 53 deletions(-)
+
+commit a03850a3567d532c3a4d7655aa71bfe73dfb0e33
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 10:57:28 2018 -0400
+
+    Fix GPOS/kern interaction
+
+    Oops.  Was checking for kern feature in GSUB, not GPOS.
+
+ src/hb-ot-shape.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d1be805e784dfaadf2ce9caa830a3f851fdd67da
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 10:49:45 2018 -0400
+
+    More rewriting plan compile
+
+    Hopefully more clear.
+
+ src/hb-ot-shape.cc | 55
+ ++++++++++++++++++++++++++++++++++++++----------------
+ src/hb-ot-shape.hh |  1 -
+ 2 files changed, 39 insertions(+), 17 deletions(-)
+
+commit 961ab46b24ca9f3ef42a56398646191f106bf5bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 10:42:10 2018 -0400
+
+    More reshuffle plan compile
+
+ src/hb-ot-shape.cc | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 2091b509e3e3b7fb7315539679fae81da2879280
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 10:41:08 2018 -0400
+
+    [kerx] Hook up to shaper
+
+ src/hb-aat-layout.cc | 31 ++++++++++++++++++++++++-------
+ src/hb-aat-layout.hh |  3 +++
+ src/hb-ot-shape.cc   |  6 ++++--
+ src/hb-ot-shape.hh   |  1 +
+ 4 files changed, 32 insertions(+), 9 deletions(-)
+
+commit 8d00c39bfc558895c63e22148d88db51cde39164
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 10:18:39 2018 -0400
+
+    [kern] Minor
+
+ src/hb-ot-shape-fallback.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit e655fd38cf20eefb1c071a52282a4caccb6f08ea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 10:16:09 2018 -0400
+
+    Apply TT or fallback kerning when GPOS does not have kern feature
+
+    Previously we only did if there was no GPOS whatsoever.  This applies
+    to Arial, Times New Roman, etc in Win7.  Was not kerning before.  It
+    is now.
+
+ src/hb-ot-shape.cc | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+commit 754cf440bf80ced36461a98a5d4607a700f44fd3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 10 10:04:05 2018 -0400
+
+    Minor
+
+ src/hb-ot-shape-fallback.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 187df7d7a9a1d9cd67cb2f72d4d6ed8cae1eed61
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Oct 10 17:12:52 2018 +0330
+
+    [circleci] Add an iOS bot (#1233)
+
+ .circleci/config.yml |  12 +++++
+ CMakeLists.txt       | 140
+ ++++++++++++++++++++++++++++++++-------------------
+ 2 files changed, 100 insertions(+), 52 deletions(-)
+
+commit 0537a40193e803d50a99cd6b993d6d9301e84ebf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 23:35:07 2018 -0400
+
+    [kerx] Comment
+
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ src/hb-ot-kern-table.hh         | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit 362d3241195bb7054c395fb4b029b6d55da4612a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 23:27:00 2018 -0400
+
+    [aat] Rename
+
+ src/hb-aat-layout-kerx-table.hh | 4 ++--
+ src/hb-aat-layout-morx-table.hh | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 54c9ecb92d196e62901eef3f8bc025c024ed16bb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 23:18:19 2018 -0400
+
+    [morx] Use subtable range for embedded sanitizer here as well
+
+ src/hb-aat-layout-morx-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit d35315cc028e70dd1b3ffc8cb079a2336b22a0c3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 23:17:32 2018 -0400
+
+    [aat] Fixup recent commit
+
+    For 329f2401082011007d9ce12b15ce0225cd267c57
+
+    max_ops is signed.
+
+ src/hb-aat-layout-common.hh | 2 +-
+ src/hb-machinery.hh         | 5 ++++-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+commit 948f59a13a4c643ae310f5fc643e29fefd6c3787
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 23:07:47 2018 -0400
+
+    [kerx] Use subtable range for runtime checks
+
+ src/hb-aat-layout-kerx-table.hh | 4 +++-
+ src/hb-machinery.hh             | 8 ++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+commit 329f2401082011007d9ce12b15ce0225cd267c57
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 23:02:53 2018 -0400
+
+    [aat] Set embedded sanitizer max ops really high
+
+    Since we consume it legitimately during shaping.
+
+ src/hb-aat-layout-common.hh | 1 +
+ src/hb-machinery.hh         | 2 ++
+ 2 files changed, 3 insertions(+)
+
+commit ad763074861da60ed51211931788ca5b27fc1512
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:57:00 2018 -0400
+
+    [kerx] Comment
+
+ src/hb-aat-layout-kerx-table.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit db9600bbe15035cea6c2d4e8e9d184a5e23e357e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:55:47 2018 -0400
+
+    [kerx] Remove junk
+
+ src/hb-aat-layout-kerx-table.hh | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+commit 27db859416c0362f211e2b42dc9a2ebb53b0e0f4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:52:41 2018 -0400
+
+    [kern/kerx] Adjust bounds check
+
+ src/hb-aat-layout-kerx-table.hh | 8 +++-----
+ src/hb-ot-kern-table.hh         | 8 +++-----
+ 2 files changed, 6 insertions(+), 10 deletions(-)
+
+commit c66f7f8c5deaac109e34bf65fc16cff92b74e69a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:49:33 2018 -0400
+
+    [kerx] Implement Format2 apply()
+
+    Still, not hooked.
+
+ src/hb-aat-layout-kerx-table.hh | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+commit 4b461785bdf356e4b5586cb6e5b226f47da04b7d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:46:30 2018 -0400
+
+    Fix check
+
+ src/hb-aat-layout-kerx-table.hh | 2 ++
+ src/hb-aat-layout.cc            | 4 +++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 4df8eb200def767d342762654b96d5d9314e5b21
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:46:12 2018 -0400
+
+    [kern] Use kern subtable length for sanitizing in the accelerator
+
+ src/hb-ot-kern-table.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 8bff1d2994876a5202c8605d1cc37522431c6c84
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:39:31 2018 -0400
+
+    [kern] Minor
+
+ src/hb-ot-kern-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 53e55945000347fb19168bb4c13a470d30d46251
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:35:22 2018 -0400
+
+    [kerx] Implement Format0 apply()
+
+    Not hooked up to be called yet.
+
+ src/hb-aat-layout-common.hh     |  6 ++++--
+ src/hb-aat-layout-kerx-table.hh | 29 ++++++++++++++++++++++++++---
+ src/hb-aat-layout.cc            |  6 ++++--
+ src/hb-aat-layout.hh            | 12 +++++++-----
+ src/hb-ot-shape.cc              |  2 +-
+ 5 files changed, 42 insertions(+), 13 deletions(-)
+
+commit 60318f87153b559e5da103f0bfcce6bad8bab3b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 22:25:53 2018 -0400
+
+    Minor
+
+ src/hb-mutex.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 210f899acad1959d60892538ac1968a36dbbb51b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 21:56:37 2018 -0400
+
+    [kern] Sanitize 4 bytes, not 2
+
+ src/hb-ot-kern-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit be2f148da474d6dd30132c22dd467ea33a942edf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 16:24:50 2018 -0400
+
+    [ft] Use mutex to lock access to FT_Face
+
+    Makes our FT-backed hb_font_t safe to use from multiple threads.
+    Still,
+    the underlying FT_Face should NOT be used from other threads by client
+    or other libraries.
+
+    Maybe I add a lock()/unlock() public API ala PangoFT2 and cairo-ft.
+    Maybe not.
+
+ src/hb-ft.cc                | 18 +++++++++++++++++-
+ src/hb-mutex.hh             |  8 ++++++++
+ test/api/test-multithread.c |  7 ++-----
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+commit d18c3c5861d40291077eb8b8667dc2f12b649cf2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 16:07:55 2018 -0400
+
+    [ft] Remove (probably) stale comment
+
+ src/hb-ft.cc | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit 7003b601afd02b0ba7e839510a7d0b886da09aaa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 15:55:26 2018 -0400
+
+    Minor
+
+ src/hb-ot-shape-complex-arabic.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 07899435b8065d494e563f83e0a35300c828eefe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 15:39:51 2018 -0400
+
+    Install ot-funcs on newly created funcs
+
+    **Finally**!  Casual users can stop caring about font-funcs
+    completely now,
+    like they haven't been needing to care re unicode-funcs for a
+    few years.
+
+ src/hb-font.cc | 39 ++++++++++++++++++++++++++-------------
+ 1 file changed, 26 insertions(+), 13 deletions(-)
+
+commit 55153553675445e8aad06e363295d399aa79c54f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 15:12:09 2018 -0400
+
+    [ot-font] Don't pre-load cmap table
+
+    Now that we have get_h_advances() and get_nominal_glyphs()
+    implemented, the
+    overhead of doing a proper atomic load would be once per run, NOT
+    once per
+    glyph.  So, no need to pre-load the tables to avoid that overhead.
+
+    As such, hb_ot_font_set_funcs() has become really cheap.
+    Can *finally* make
+    it be default font functions on all newly created fonts!
+
+ src/hb-ot-font.cc | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+commit ec84460e46fdaa5f8a3c16c8d48dabe2b0c869da
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 15:07:04 2018 -0400
+
+    [ot/ft] Implement get_nominal_glyphs() callback
+
+    Some more measurable speedup.  The recent commits' speedups are
+    as follows:
+
+    Testing with Roboto, ****when disabling kern and liga****:
+
+    Before:
+
+    FT --features=-kern,-liga
+    user↦   0m0.521s
+
+    OT --features=-liga,-kern
+    user↦   0m0.568s
+
+    After:
+
+    FT --features=-liga,-kern
+    user↦   0m0.428s
+
+    OT --features=-liga,-kern
+    user↦   0m0.470s
+
+    So, 17% speedup.
+
+    Note that FT callbacks are faster than OT these days since we added
+    an advance
+    cache to FT.  I don't think the difference is enough to justify
+    adding a cache
+    to OT.
+
+    When not disabling kern, the thing is three times slower, so the
+    speedups
+    are three times less impressive...  Still, 5% not bad for a codebase
+    that I
+    otherwise thought is optimized out.
+
+    Note that, because of this and other optimiztions in our main shaper,
+    disabling kern and liga, the OT shaper is now *faster* than the
+    fallback
+    shaper.  So, that's my recommendation to clients that need the
+    absolute
+    fastest...
+
+ src/hb-ft.cc      | 26 ++++++++++++++++++++++++++
+ src/hb-ot-font.cc | 24 ++++++++++++++++++++++++
+ 2 files changed, 50 insertions(+)
+
+commit e883f52732a25f5495ec30656489954afd8cc3a4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 14:50:57 2018 -0400
+
+    Call get_nominal_glyphs() for runs of simple clusters at a time
+
+    Even without FT or OT font funcs implementing get_nominal_glyphs(),
+    there's measurable
+    speedup.
+
+ src/hb-buffer.hh             | 20 +++++++++++++++++++-
+ src/hb-ot-shape-normalize.cc |  9 +++++++++
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+commit 8008bca83b0bb310fc434dbdd339545af951193b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 14:38:23 2018 -0400
+
+    Whitespace
+
+ src/hb-font.hh               |  2 +-
+ src/hb-ot-shape-normalize.cc | 52
+ ++++++++++++++++++++++++--------------------
+ 2 files changed, 29 insertions(+), 25 deletions(-)
+
+commit 30c114ffec335770452e60729224b1634586c5b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 14:37:08 2018 -0400
+
+    Avoid sort and recompose stages if all clusters simple
+
+    Even has measurable speedup...
+
+ src/hb-ot-shape-normalize.cc | 52
+ ++++++++++++++++++++++++--------------------
+ 1 file changed, 29 insertions(+), 23 deletions(-)
+
+commit 9f79365c3b183278d14352ba6241c7d4ec274984
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 14:36:25 2018 -0400
+
+    Fix warning
+
+    How come this one is not generated by clang everything bot?!
+
+    ../../../test/api/test-multithread.c:37:26: warning: initialization
+    discards ‘const’ qualifier from pointer target type
+    [-Wdiscarded-qualifiers]
+     static char *font_path = "fonts/Inconsolata-Regular.abc.ttf";
+                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    ../../../test/api/test-multithread.c:38:21: warning: initialization
+    discards ‘const’ qualifier from pointer target type
+    [-Wdiscarded-qualifiers]
+
+ test/api/test-multithread.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 24382debe893450088acd1e4b387ac31145d4553
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 14:33:24 2018 -0400
+
+    Rewrite main normalizer loop to isolate runs of simple clusters
+
+ src/hb-ot-shape-normalize.cc | 24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+commit b5371f18effbeb91565fd8c554c120b911641f0b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 14:12:59 2018 -0400
+
+    Inline decompose_cluster
+
+    Towards separating the common case into its own loop.
+
+ src/hb-ot-shape-normalize.cc | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+commit b314c4e9abf4236c6650a63d1287471b61f64885
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 09:23:51 2018 -0400
+
+    [font] Add get_nominal_glyphs() callback (note the plural)
+
+    Unused as of now.  To be wired up to normalizer, which would remove
+    overhead and allow hb-ot-font initialization to become a no-op, so
+    we can enable it by default.
+
+ docs/harfbuzz-sections.txt |  3 +++
+ src/hb-font.cc             | 33 +++++++++++++++++++++++++++++++++
+ src/hb-font.h              | 24 ++++++++++++++++++++++++
+ src/hb-font.hh             | 13 +++++++++++++
+ 4 files changed, 73 insertions(+)
+
+commit ca6a317012a13ee84b58a69e14e74c94c5b158ff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 09:06:07 2018 -0400
+
+    Minor
+
+ src/hb-font.cc | 6 +++---
+ src/hb-font.h  | 8 ++++----
+ src/hb-font.hh | 2 +-
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 4035158de46ce373b7521daf61c5b6df83312968
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Wed Jul 25 18:26:10 2018 +0800
+
+    test/api/test-subset-*.c: Fix build on pre-C99
+
+    Ensure that we have the variables at the beginning of the block.
+    These
+    are the only fixes that we need for building HarfBuzz on older
+    compilers.
+
+ test/api/test-collect-unicodes.c |  9 ++++++---
+ test/api/test-subset-glyf.c      | 19 +++++++++++++------
+ test/api/test-subset-hdmx.c      |  8 ++++++--
+ test/api/test-subset-hmtx.c      |  3 ++-
+ test/api/test-subset-post.c      |  3 ++-
+ test/api/test-subset-vmtx.c      |  6 ++++--
+ test/api/test-subset.c           | 12 +++++++++---
+ 7 files changed, 42 insertions(+), 18 deletions(-)
+
+commit 8e4ad1d7a0a35298ca04828ef1ef18b4c019ec03
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Wed Jul 25 18:12:34 2018 +0800
+
+    builds: Fix and clean up MSVC DLL builds
+
+    Instead of passing a CFLAG/CXXFLAG to define HB_EXTERN, define it
+    directly in src/hb.hh as __declspec(dllexport) extern when we are
+    building HarfBuzz as DLLs on Visual Studio.  Define HB_INTERNAL
+    as nothing without defining HB_NO_VISIBILITY when building HarfBuzz as
+    DLLs to avoid linker errors on Visual Studio builds.
+
+    Also "install" harfbuzz-subset.dll into $(PREFIX)\bin as the
+    hb-subset utility will depend on that DLL at runtime, when HarfBuzz is
+    built as DLLs.  Since it consists of private APIs that are subject to
+    change, we do not install its headers nor .lib file.
+
+ CMakeLists.txt |  7 ++++++-
+ src/hb.hh      | 10 ++++++++--
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+commit e640f3a6b16f41cee5f7868ec738fda01244e96a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 08:28:07 2018 -0400
+
+    Another old bot fix
+
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e4f27f368f8f0509fa47f6a28f3984e90b40588f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 08:20:10 2018 -0400
+
+    Try fixing older bots
+
+ src/hb-ot-shape-fallback.cc | 42
+ +++++++++++++++++++++---------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+commit bee93e269711a3eda4e7d762b730522564fe6e87
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 08:01:49 2018 -0400
+
+    Add const to get_*_advances API
+
+    Ouch!
+
+ src/hb-font.cc    | 10 +++++-----
+ src/hb-font.h     |  8 ++++----
+ src/hb-font.hh    |  6 +++---
+ src/hb-ft.cc      |  2 +-
+ src/hb-ot-font.cc |  4 ++--
+ 5 files changed, 15 insertions(+), 15 deletions(-)
+
+commit eb2be97f864c726feaa2434e290f962ddfa97069
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 07:48:52 2018 -0400
+
+    Port test off deprecated API
+
+ test/api/test-shape.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit cc126f2817844a2e83e973129e5b2caa18de599f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 01:10:15 2018 -0400
+
+    Minor
+
+ src/Makefile.am          | 2 +-
+ test/shaping/Makefile.am | 2 ++
+ test/subset/Makefile.am  | 2 +-
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+commit b2fbe55b828ea5864bc0aed54db7109a2e189de2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 01:07:36 2018 -0400
+
+    [icu] Unbreak
+
+ src/hb-icu.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a353c1768dc1d7934b8ac293761620f561304bb2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 01:05:28 2018 -0400
+
+    Remove test for deprecated hb_set_invert()
+
+ test/api/test-set.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit a52bc039c33b3c01dbb96b815dc24df7f03bc4be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 00:56:33 2018 -0400
+
+    Properly remove deprecated stuff
+
+ src/hb-glib.cc | 15 ++++++---------
+ src/hb-icu.cc  | 15 ++++++---------
+ src/hb-ucdn.cc | 15 ++++++---------
+ 3 files changed, 18 insertions(+), 27 deletions(-)
+
+commit fc50916589a300e49183b5ee598e64ca28d0bd9a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 00:39:42 2018 -0400
+
+    Remove deprecated decompose_compatibility stuff
+
+ src/hb-glib.cc          | 31 +-----------------------------
+ src/hb-icu.cc           | 33 +-------------------------------
+ src/hb-ucdn.cc          |  8 +-------
+ test/api/test-unicode.c | 51
+ -------------------------------------------------
+ 4 files changed, 3 insertions(+), 120 deletions(-)
+
+commit eed737f6726d3408191a4e64592805b70d8bb247
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 00:33:30 2018 -0400
+
+    Remove deprecated eastasian_width
+
+ src/hb-glib.cc          |  8 +------
+ src/hb-icu.cc           | 19 +--------------
+ src/hb-ucdn.cc          |  9 +------
+ test/api/test-unicode.c | 64
+ -------------------------------------------------
+ 4 files changed, 3 insertions(+), 97 deletions(-)
+
+commit 47030b1855f04c0d75899ffb6f5021fea3c19b90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 00:30:45 2018 -0400
+
+    [ft/ot] Remove implementation of deprecated kerning funcs
+
+ src/hb-ft.cc      | 19 -------------------
+ src/hb-ot-font.cc | 13 -------------
+ 2 files changed, 32 deletions(-)
+
+commit 977c8a8e5c811995f47b0eb721199d0dc3689e48
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 00:22:08 2018 -0400
+
+    [kern] Minor
+
+ src/hb-ot-kern-table.hh | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+commit ed5cfa42c7fb8d5ff2d74bdb452a0590174f4e19
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 00:20:35 2018 -0400
+
+    [kern] Minor
+
+ src/hb-aat-layout-kerx-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit d219f899f4b2fb4b39ebc1dff9fb648fc5d6d112
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 9 00:01:09 2018 -0400
+
+    Deprecate font kern API
+
+ docs/harfbuzz-sections.txt | 16 +++++++-------
+ src/hb-deprecated.h        | 54
+ ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-font.cc             |  3 +++
+ src/hb-font.h              | 51
+ -------------------------------------------
+ 4 files changed, 65 insertions(+), 59 deletions(-)
+
+commit a51958819fcf51ade3f8eb38001e680a419ebbba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 23:57:45 2018 -0400
+
+    Apply TrueType/OpenType kern table when GPOS kern feature is not
+    available
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/250
+
+ src/hb-ot-kern-table.hh     | 24 +++++++++++--------
+ src/hb-ot-layout.cc         | 57
+ ++++++++++++++++++++-------------------------
+ src/hb-ot-layout.hh         | 13 +++++++++++
+ src/hb-ot-shape-fallback.cc |  4 ++--
+ src/hb-ot-shape.cc          | 10 +++++---
+ src/hb-ot-shape.hh          |  1 +
+ 6 files changed, 62 insertions(+), 47 deletions(-)
+
+commit 09ad2613c8d8a60dac69a878c2d568adfea054c8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 23:30:24 2018 -0400
+
+    Separate fallback kern vs mark positioning
+
+ src/hb-ot-shape-fallback.cc | 12 ++++++------
+ src/hb-ot-shape-fallback.hh | 12 ++++++------
+ src/hb-ot-shape.cc          | 15 ++++++++-------
+ src/hb-ot-shape.hh          |  4 ++--
+ 4 files changed, 22 insertions(+), 21 deletions(-)
+
+commit 3c23ff9b7c4241ec23054a95f1fdfbdef2c51f40
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 23:26:26 2018 -0400
+
+    [kern] Add kerning driver to TT kern table
+
+ src/hb-ot-kern-table.hh     | 19 +++++++++++++++++--
+ src/hb-ot-shape-fallback.cc |  2 +-
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+commit 683c3a95330928129cfbb1488650f708414d68ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 23:09:48 2018 -0400
+
+    [kern] Abstract away kerning machine
+
+ src/hb-font.hh              |  2 +-
+ src/hb-ot-kern-table.hh     | 71
+ +++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-shape-fallback.cc | 67
+ +++++++++++-------------------------------
+ 3 files changed, 89 insertions(+), 51 deletions(-)
+
+commit fb4f43838154a77912a9fc3437110c81e9d34aac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 22:44:16 2018 -0400
+
+    Add HB_DEPRECATED
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1232
+
+ src/hb-common.h     |  9 +++++++++
+ src/hb-deprecated.h | 12 ++++++------
+ 2 files changed, 15 insertions(+), 6 deletions(-)
+
+commit 80e3102b8a216f9a751d073f9a2f7900ca758086
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 22:41:08 2018 -0400
+
+    [kerx] Process coverage flags
+
+ src/hb-aat-layout-kerx-table.hh | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+commit 26d7305da7a7e2cf765b068f565836442872ffe7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 22:31:35 2018 -0400
+
+    Deprecate decompose_compatibility stuff
+
+ docs/harfbuzz-sections.txt |  7 +++---
+ src/hb-deprecated.h        | 63
+ ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-unicode.h           | 47 ----------------------------------
+ 3 files changed, 67 insertions(+), 50 deletions(-)
+
+commit 42b51eee54f143854b7c6c3be5d84bfbbd895100
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 22:26:39 2018 -0400
+
+    Deprecate eastasian_width stuff
+
+ docs/harfbuzz-sections.txt |  5 +++--
+ src/hb-deprecated.h        | 37 +++++++++++++++++++++++++++++++++++++
+ src/hb-unicode.h           | 28 ----------------------------
+ 3 files changed, 40 insertions(+), 30 deletions(-)
+
+commit 286a45641fc6732bb7cab02f06c90396834541b1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 16:41:08 2018 -0400
+
+    Minor
+
+ src/hb-ot-shape-normalize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c0d3bf1bafe7b6d2e8f2798c1f55aaec71350d90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 16:32:44 2018 -0400
+
+    Minor
+
+ src/hb-ot-shape.cc | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit 9c1bb81f5c5ca64ad1c665edd16947e4bc6f6c46
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 8 16:10:54 2018 -0400
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/DISABLED            | 3 ---
+ test/shaping/data/text-rendering-tests/Makefile.sources    | 2 +-
+ test/shaping/data/text-rendering-tests/tests/MORX-35.tests | 4 ++--
+ 3 files changed, 3 insertions(+), 6 deletions(-)
+
+commit 1a5a3325a26f4989ab8c4bb91515d4898ffa4631
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 23:08:39 2018 -0400
+
+    [kerx] Minor
+
+ src/hb-aat-layout-kerx-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d62b4011cc600ade2b130f81a077dd08d4e4464f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 22:58:06 2018 -0400
+
+    [kern] Shout less
+
+ src/hb-ot-kern-table.hh | 36 +++++++++++++++++++-----------------
+ 1 file changed, 19 insertions(+), 17 deletions(-)
+
+commit c6bb3a588f493630b40d8823532b482f407bacbf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 22:52:53 2018 -0400
+
+    [kerx] Clean up Format2
+
+ src/hb-aat-layout-kerx-table.hh | 48
+ ++++++++---------------------------------
+ 1 file changed, 9 insertions(+), 39 deletions(-)
+
+commit 8aa83d97f9e7f63e2fcb4ae965b75a39961c7d87
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 22:43:59 2018 -0400
+
+    [kern/kerx] Fix Format2 offsetting
+
+    "The values in the right class table are stored pre-multiplied by the
+    number of bytes in a single kerning value, and the values in the left
+    class table are stored pre-multiplied by the number of bytes in one
+    row. This eliminates needing to multiply the row and column values
+    together to determine the location of the kerning value. The array can
+    be indexed by doing the right- and left-hand class mappings,
+    adding the
+    class values to the address of the array, and fetching the kerning
+    value to which the new address points."
+
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ src/hb-ot-kern-table.hh         | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit ed2a404272bc99234c6f71f22b5a642834e59e6c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 22:33:41 2018 -0400
+
+    [kerx] Clean up Format0
+
+ src/hb-aat-layout-kerx-table.hh | 48
+ +++++++++++------------------------------
+ 1 file changed, 12 insertions(+), 36 deletions(-)
+
+commit 4c3b19d52ec7a1fa46f8d0971e377a7d29b87e27
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 22:30:42 2018 -0400
+
+    Support HBUINT32 BinSearchArrayOf
+
+ src/hb-open-type.hh | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+commit 456a68c506238e9c6b019244237d4443bd3589af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 22:28:45 2018 -0400
+
+    Move code
+
+ src/hb-aat-layout-common.hh | 105
+ --------------------------------------------
+ src/hb-open-type.hh         | 105
+ +++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 104 insertions(+), 106 deletions(-)
+
+commit 3515c8b187e2316dcf3abaefc84917b09449d485
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 22:27:00 2018 -0400
+
+    [aat] Rename
+
+ src/hb-aat-layout-common.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit e42cd58c997adafca5517faa9aacf651b90520f5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 20:46:11 2018 -0400
+
+    Rename invisible_codepoint to invisible_glyph in API
+
+    Deleted recently added API:
+        hb_buffer_set_invisible_codepoint()
+        hb_buffer_get_invisible_codepoint()
+
+        hb-shape / hb-view --invisible-codepoint
+
+    New API:
+        hb_buffer_set_invisible_glyph()
+        hb_buffer_get_invisible_glyph()
+
+        hb-shape / hb-view --invisible-glyph
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1216
+
+ docs/harfbuzz-sections.txt |  4 ++--
+ src/hb-buffer.cc           | 12 ++++++------
+ src/hb-buffer.h            |  6 +++---
+ util/options.cc            |  2 +-
+ util/options.hh            |  6 +++---
+ 5 files changed, 15 insertions(+), 15 deletions(-)
+
+commit 2a5cb37fdb43230217e055f3d7c770a35cfd5c21
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 20:36:46 2018 -0400
+
+    Revert "[morx] Fix MORX-35"
+
+    This reverts commit f62f6e90ad1f1a83f77771ad65ee1ffb79470a8a.
+
+ src/hb-aat-layout-morx-table.hh                         | 14
+ +++++---------
+ test/shaping/data/text-rendering-tests/DISABLED         |  3 +++
+ test/shaping/data/text-rendering-tests/Makefile.sources |  2 +-
+ 3 files changed, 9 insertions(+), 10 deletions(-)
+
+commit 14ebf8af0c04efcae6ca788ac85601bfe462f28d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 20:35:06 2018 -0400
+
+    [buffer] Improve shift_forward()
+
+    "Improve" is a strong word in this case though, I understand.
+
+ src/hb-buffer.cc | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+commit f62f6e90ad1f1a83f77771ad65ee1ffb79470a8a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 18:06:53 2018 -0400
+
+    [morx] Fix MORX-35
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1224
+
+ src/hb-aat-layout-morx-table.hh                         | 14
+ ++++++++++----
+ test/shaping/data/text-rendering-tests/DISABLED         |  3 ---
+ test/shaping/data/text-rendering-tests/Makefile.sources |  2 +-
+ 3 files changed, 11 insertions(+), 8 deletions(-)
+
+commit 94368855c6bd7201d562cab3d2107685589e69c8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 18:52:12 2018 -0400
+
+    Remove some code
+
+    We use scratch-flags to short-circuit this function.  No need for
+    previous
+    early loop.
+
+ src/hb-ot-shape.cc | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+commit c07b91b812dc66b38b11329cd6a93258a3769f9e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 18:00:14 2018 -0400
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/Makefile.sources  |   6 +++++-
+ .../data/text-rendering-tests/fonts/TestMORXForty.ttf    | Bin 0 ->
+ 2408 bytes
+ .../text-rendering-tests/fonts/TestMORXThirtyeight.ttf   | Bin 0 ->
+ 2444 bytes
+ .../text-rendering-tests/fonts/TestMORXThirtynine.ttf    | Bin 0 ->
+ 2436 bytes
+ .../text-rendering-tests/fonts/TestMORXThirtyseven.ttf   | Bin 0 ->
+ 2444 bytes
+ .../data/text-rendering-tests/tests/MORX-35.tests        |   4 ++--
+ .../data/text-rendering-tests/tests/MORX-37.tests        |   4 ++++
+ .../data/text-rendering-tests/tests/MORX-38.tests        |   4 ++++
+ .../data/text-rendering-tests/tests/MORX-39.tests        |   4 ++++
+ .../data/text-rendering-tests/tests/MORX-40.tests        |   4 ++++
+ 10 files changed, 23 insertions(+), 3 deletions(-)
+
+commit fdce1e15434f14b7f4802edd67f7af737cf2b075
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 14:01:33 2018 -0400
+
+    [kerx] Clean up kerx and KerxTable structures
+
+ src/hb-aat-layout-kerx-table.hh | 169
+ ++++++++++++++++++++++++++--------------
+ src/hb-aat-layout-morx-table.hh |   2 +-
+ 2 files changed, 113 insertions(+), 58 deletions(-)
+
+commit 71b65eb27dd0867f51d9906887b9e372eb37f54a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 18:41:52 2018 +0200
+
+    Add API for setting invisible-codepoint
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1216
+
+    New API:
+    hb_buffer_set_invisible_codepoint()
+    hb_buffer_get_invisible_codepoint()
+
+    hb-shape / hb-view --invisible-codepoint
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-buffer.cc           | 42
+ ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-buffer.h            |  7 +++++++
+ src/hb-buffer.hh           |  1 +
+ src/hb-ot-shape.cc         |  8 ++++----
+ util/options.cc            |  1 +
+ util/options.hh            |  3 +++
+ 7 files changed, 60 insertions(+), 4 deletions(-)
+
+commit 13da3be0b342e8e2f060eba8753c6957c477c4ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 18:23:45 2018 +0200
+
+    [ot-font] Load hmtx/vmtx lazily
+
+    Since we have get_*_advanes() API now, the overhead is once per shape,
+    not once per glyph.
+
+    Only cmap is warmed-up at set_funcs() time now.
+
+ src/hb-ot-font.cc | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit 856db4c9184e39c0457cc07c815f90058937c8a2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 18:21:15 2018 +0200
+
+    Minor
+
+ src/hb-ot-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f92330b5e0b1a5a61768494bd7081e3fc235b182
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 17:51:50 2018 +0200
+
+    Minor
+
+ test/api/test-multithread.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit b2e398c077cf9437298bfe2ee53b7407a5865c14
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Oct 7 16:31:33 2018 +0200
+
+    [coretext] Fix OS X check
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1230
+
+ src/hb-coretext.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 7ee50af8366547c382047a30a94f7f5f739aabcb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 6 21:31:44 2018 +0200
+
+    [morx] Fix memory access issues with unsafe_to_break
+
+ src/hb-aat-layout-common.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit f58c5175890e666503b6f140d238e1abca91598e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Oct 6 22:42:56 2018 +0330
+
+    Make msan output a little more readable
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e9abe33963739f753cdfb007eed40101ce33f550
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Oct 6 12:19:33 2018 +0330
+
+    Use tempfile in run-tests as a fix for Windows CI fails (#1228)
+
+ test/shaping/run-tests.py | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 0816a549789a1b647443c2b33cfda3f4400a0f87
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Oct 6 02:40:57 2018 +0200
+
+    [uniscribe/coretext] Fix for previous change
+
+ src/hb-coretext.cc  |  2 +-
+ src/hb-uniscribe.cc | 12 ++++++------
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 341206eb609202e4b2f0d03d29cb577ebe8390b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 5 18:39:48 2018 +0200
+
+    [vector] Make hb_vector_t relocatable / nestable
+
+    Ugly, but...
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1227
+
+ src/hb-face.cc          |  2 +-
+ src/hb-machinery.hh     |  2 +-
+ src/hb-ot-cmap-table.hh |  2 +-
+ src/hb-ot-post-table.hh |  2 +-
+ src/hb-set.hh           |  4 +--
+ src/hb-subset.cc        |  2 +-
+ src/hb-vector.hh        | 94
+ +++++++++++++++++++++++++++++++------------------
+ 7 files changed, 66 insertions(+), 42 deletions(-)
+
+commit 5469d80707d32c733b1c60f79ab2f217e879de55
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 5 18:21:08 2018 +0200
+
+    Add hb_vector_t::fini_deep ()
+
+ src/hb-vector.hh | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit 4831e615d173be9c7e140be0fa9017e4d9e499af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 5 18:14:13 2018 +0200
+
+    [morx] Fix memory access issue
+
+    If buffer was enlarged, info was being outdated.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1225
+
+ src/hb-aat-layout-common.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 5a41cf6be69adb0b5b29976a33c4c6dd6ce7afc5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 5 11:33:19 2018 +0200
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/DISABLED          |   3 +++
+ test/shaping/data/text-rendering-tests/Makefile.sources  |   2 ++
+ .../text-rendering-tests/fonts/TestMORXThirtyfive.ttf    | Bin 0 ->
+ 1968 bytes
+ .../text-rendering-tests/fonts/TestMORXThirtysix.ttf     | Bin 0 ->
+ 1836 bytes
+ .../data/text-rendering-tests/tests/MORX-35.tests        |   2 ++
+ .../data/text-rendering-tests/tests/MORX-36.tests        |   1 +
+ 6 files changed, 8 insertions(+)
+
+commit a62f37d6fa412b799b7247b813f6e65a968e7645
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Oct 5 02:49:29 2018 +0200
+
+    Change vendor features from Harf/Buzz to HARF/BUZZ
+
+    https://github.com/harfbuzz/harfbuzz/commit/a01194aaf4c15160330b4042066263b2c963b658#commitcomment-30772041
+
+    "The tag space of tags consisting of four uppercase letters (A-Z)
+    with no punctuation,
+    spaces, or numbers, is reserved as a vendor space. Font vendors may
+    use such tags to
+    identify private features."
+
+ src/hb-ot-shape.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 7b3ae5ffd202346cb3742fe0f8cfafe8c36a4bd5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 16:36:42 2018 +0200
+
+    More bot fixes
+
+ test/shaping/run-tests.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 310bdac4a08b99a25de6a16a20464873f90b52e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 16:31:14 2018 +0200
+
+    Fix a warning
+
+ util/view-cairo.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0abce58139bb58b8b97171db6387d2ac7eebdee0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 16:23:42 2018 +0200
+
+    [test] Choose 'ot' shaper specifically
+
+    Now that we added morx support, our OS X bot is running them through
+    CoreText
+    and failing (with a DoS / infinite loop no less!).  Always run
+    tests through
+    our own shaper.
+
+ test/shaping/run-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c93d379bf2414eb6ee6d38fb9753ddf818a777ea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 13:28:13 2018 +0200
+
+    [TODO] Clean up
+
+ TODO | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+commit a01194aaf4c15160330b4042066263b2c963b658
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 13:00:37 2018 +0200
+
+    Enable two OpenType features, 'Harf' and 'Buzz'
+
+    One early, before script-specific features, one late, after.
+    Allows font
+    developers to detect us and behave differently if needed.
+
+ src/hb-ot-shape.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 55468ca01b4cdf274900fb752fbf9ae05a78705e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 12:13:55 2018 +0200
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/Makefile.sources  |   6 +++++-
+ test/shaping/data/text-rendering-tests/extract-tests.py  |  12
+ ++++++++++++
+ .../data/text-rendering-tests/fonts/TestGSUBThree.ttf    | Bin 0 ->
+ 1504 bytes
+ .../text-rendering-tests/fonts/TestMORXThirtyfour.ttf    | Bin 0 ->
+ 3608 bytes
+ .../text-rendering-tests/fonts/TestMORXThirtythree.ttf   | Bin 0 ->
+ 1520 bytes
+ .../text-rendering-tests/fonts/TestMORXTwentyfour.ttf    | Bin 0 ->
+ 1828 bytes
+ .../shaping/data/text-rendering-tests/tests/GSUB-3.tests |   1 +
+ .../data/text-rendering-tests/tests/MORX-24.tests        |   1 +
+ .../data/text-rendering-tests/tests/MORX-32.tests        |   8 ++++----
+ .../data/text-rendering-tests/tests/MORX-33.tests        |   3 +++
+ .../data/text-rendering-tests/tests/MORX-34.tests        |   1 +
+ test/shaping/run-tests.py                                |  15
+ +++++++++------
+ 12 files changed, 36 insertions(+), 11 deletions(-)
+
+commit 6ff8a8a10b62a54a87d53b0af66ccaba5d58b107
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 12:09:45 2018 +0200
+
+    Minor
+
+ test/shaping/data/text-rendering-tests/extract-tests.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 14ff3cbe0f30dea24e1bb175b1e8e41039f6afdc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 11:34:21 2018 +0200
+
+    Apply morx if there's no GSUB!
+
+ src/hb-ot-shape.cc                                 | 23 ++++++++++++----
+ src/hb-ot-shape.hh                                 |  5 ++++
+ test/shaping/data/text-rendering-tests/DISABLED    | 32
+ ----------------------
+ .../data/text-rendering-tests/Makefile.sources     | 14 +++++-----
+ 4 files changed, 29 insertions(+), 45 deletions(-)
+
+commit 3417037eb13a59dce6add0b1691ddb1b2b54c1e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 4 11:08:15 2018 +0200
+
+    [aat] Add +hb_aat_layout_has_substitution
+
+ src/hb-aat-layout-morx-table.hh | 2 ++
+ src/hb-aat-layout.cc            | 6 ++++++
+ src/hb-aat-layout.hh            | 2 ++
+ 3 files changed, 10 insertions(+)
+
+commit 1f14107f71a6c3da8270ed21c3588f945fa91733
+Author: Sascha Brawer <sascha at brawer.ch>
+Date:   Thu Oct 4 09:17:08 2018 +0200
+
+    Minor: Fix autoconf warning
+
+    Before this change, autoconf was emitting the following warnings:
+
+    ```
+    configure.ac:22: warning: AC_COMPILE_IFELSE was called before
+    AC_USE_SYSTEM_EXTENSIONS
+    ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is
+    expanded from...
+    configure.ac:22: the top level
+    configure.ac:22: warning: AC_RUN_IFELSE was called before
+    AC_USE_SYSTEM_EXTENSIONS
+    ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is
+    expanded from...
+    configure.ac:22: the top level
+    configure.ac:22: warning: AC_COMPILE_IFELSE was called before
+    AC_USE_SYSTEM_EXTENSIONS
+    ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is
+    expanded from...
+    configure.ac:22: the top level
+    configure.ac:22: warning: AC_RUN_IFELSE was called before
+    AC_USE_SYSTEM_EXTENSIONS
+    ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is
+    expanded from...
+    configure.ac:22: the top level
+    configure.ac:22: warning: AC_COMPILE_IFELSE was called before
+    AC_USE_SYSTEM_EXTENSIONS
+    ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is
+    expanded from...
+    configure.ac:22: the top level
+    configure.ac:22: warning: AC_RUN_IFELSE was called before
+    AC_USE_SYSTEM_EXTENSIONS
+    ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is
+    expanded from...
+    configure.ac:22: the top level
+    configure.ac:22: warning: AC_COMPILE_IFELSE was called before
+    AC_USE_SYSTEM_EXTENSIONS
+    ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is
+    expanded from...
+    configure.ac:22: the top level
+    configure.ac:22: warning: AC_RUN_IFELSE was called before
+    AC_USE_SYSTEM_EXTENSIONS
+    ../../lib/autoconf/specific.m4:368: AC_USE_SYSTEM_EXTENSIONS is
+    expanded from...
+    configure.ac:22: the top level
+    ```
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7810bb1a59ea71afeed7ea489400801ebdf642e4
+Author: Sascha Brawer <sascha at brawer.ch>
+Date:   Thu Oct 4 09:24:08 2018 +0200
+
+    [morx] Only insert glyphs at mark when a mark has been set before
+
+    This reverts commit f4072e8cb81072cd6d51a2607efedb76c02e7db1.
+    https://github.com/harfbuzz/harfbuzz/issues/1195
+
+ src/hb-aat-layout-morx-table.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 5de2d9cdbdca870901c0ba9472f5b78c48ba0a58
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 4 02:14:18 2018 +0330
+
+    Minor, fix double-promotion warnings (#1221)
+
+ .circleci/config.yml        | 2 +-
+ src/dump-emoji.cc           | 2 +-
+ src/hb-common.cc            | 2 +-
+ src/hb-ot-var-fvar-table.hh | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+commit c2c7e6471ca912c91c82f6d71338082978f13dc6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 4 00:29:40 2018 +0330
+
+    State our graphite2 dependency no-deprecated compile flag (#1220)
+
+ .circleci/config.yml | 2 +-
+ .travis.yml          | 2 --
+ configure.ac         | 2 +-
+ 3 files changed, 2 insertions(+), 4 deletions(-)
+
+commit e4e74c2751ac24178086cce2811d34d8019b6f85
+Author: mhosken <mhosken at users.noreply.github.com>
+Date:   Thu Oct 4 02:33:26 2018 +0700
+
+    Update Graphite API to latest (#1215)
+
+ src/hb-graphite2.cc | 28 +++++++++++++++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+commit 81f5eb09eca010337ffb3369000a3d5c1e8e2cda
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 21:30:48 2018 +0200
+
+    Add emoji test for recent work
+
+ test/shaping/data/in-house/Makefile.sources             |   2 +-
+ .../fonts/3cf6f8ac6d647473a43a3100e7494b202b2cfafe.ttf  | Bin 0 ->
+ 16596 bytes
+ test/shaping/data/in-house/tests/emoji-flag-tags.tests  |   2 --
+ test/shaping/data/in-house/tests/emoji.tests            |   4 ++++
+ 4 files changed, 5 insertions(+), 3 deletions(-)
+
+commit 9e2824cca0e42a53fafda7b2feb095986df40675
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Oct 3 22:49:02 2018 +0330
+
+    [ci] Delete azure-pipelines
+
+    End of experiment, we might get back to it later
+
+ azure-pipelines.yml | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+commit b710ea4fdeb1a620b396bd07665fc129fe5fc074
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 21:17:59 2018 +0200
+
+    Clean Fitzpatrick hack
+
+ src/hb-ot-layout.hh |  2 +-
+ src/hb-ot-shape.cc  |  9 +++++++--
+ src/hb-unicode.hh   | 20 --------------------
+ 3 files changed, 8 insertions(+), 23 deletions(-)
+
+commit 95e5f1ae69036108f318b93b11d85b2ebc19109b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 21:11:13 2018 +0200
+
+    Unbreak Fitzpatrick
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1159
+
+ src/hb-ot-layout.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 03fb6dd4c7d12a98cc0ef325432658c3c76ab208
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 21:02:16 2018 +0200
+
+    Rewrite grapheme-formation in terms of new work
+
+    Also, don't attach ZWNJ to previous cluster.  Closer to Unicode
+    graphemes.
+
+ src/hb-coretext.cc                                 |  2 +-
+ src/hb-ot-shape.cc                                 | 48
+ ++++++----------------
+ .../in-house/tests/indic-joiner-candrabindu.tests  |  2 +-
+ .../data/in-house/tests/indic-joiners.tests        |  6 +--
+ 4 files changed, 18 insertions(+), 40 deletions(-)
+
+commit 68106b1d9b96caf79b0a778a7da75caf54e7d44a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 20:50:12 2018 +0200
+
+    Minor
+
+ src/hb-ot-layout.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 3f1c741b7a85d9c2d66e7f2446e988470c538b49
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 20:45:19 2018 +0200
+
+    [test] Split a test
+
+ .../fonts/4d4206e30b2dbf1c1ef492a8eae1c9e7829ebad8.ttf | Bin 0 ->
+ 51924 bytes
+ .../fonts/bb29ce50df2bdba2d10726427c6b7609bf460e04.ttf | Bin 74856 ->
+ 0 bytes
+ .../in-house/tests/mongolian-variation-selector.tests  |  17
+ ++++++++++++++++-
+ 3 files changed, 16 insertions(+), 1 deletion(-)
+
+commit ba813aab0909375af0c8f8e0c34595680c2762a4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Oct 3 21:52:15 2018 +0330
+
+    Update azure-pipelines.yml
+
+ azure-pipelines.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 06922acbc4558699e43a4ed98ffb21f1e84abfc6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 20:19:17 2018 +0200
+
+    Fix distcheck
+
+ src/Makefile.sources | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 4eea2e279b019ac627b2b9e2234a194957971022
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 20:16:03 2018 +0200
+
+    [thai] Set continuation on decomposed nikhahit
+
+ src/hb-ot-shape-complex-thai.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 8edc91022c3943fb306cee26ed6eb85381b5ea76
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 20:13:20 2018 +0200
+
+    [indic] Reset continuation on inserted dottedcircle
+
+ src/hb-ot-shape-complex-indic.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 2a6f15213ec30e5eb07465dd9dc81c2c386cb1e0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 20:09:14 2018 +0200
+
+    [buffer] Inline some more
+
+ src/hb-buffer.cc | 44 --------------------------------------------
+ src/hb-buffer.hh | 52
+ ++++++++++++++++++++++++++++++++++++++++++++--------
+ 2 files changed, 44 insertions(+), 52 deletions(-)
+
+commit 6f39c22029867c6d00cf70d7df242a28ca8f12bc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 20:06:32 2018 +0200
+
+    Add code
+
+ src/hb-ot-layout.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 19d50aa2620f1464da8e00185b746e46fb0d80c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 20:05:28 2018 +0200
+
+    [indic] Simplify dottedcircle
+
+ src/hb-ot-shape-complex-indic.cc | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+commit 3b7831851052ecf2611a115cc2b80ef970d83df8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 19:44:15 2018 +0200
+
+    [emoji] Mark emoji contination sequences as continuation
+
+    This adds a new grapheme bit.  Not used yet.
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1159
+
+ src/hb-ot-layout.hh | 83
+ +++++++++++++++++++++++++----------------------------
+ src/hb-ot-shape.cc  | 24 ++++++++++++++++
+ src/hb-unicode.hh   |  5 ----
+ 3 files changed, 63 insertions(+), 49 deletions(-)
+
+commit 123326e20a30a51e25339c2eca272e4e6c847742
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 19:19:51 2018 +0200
+
+    Dotted-circle all marks, not just non-spacing, at text beginning
+
+ src/hb-ot-shape.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 4146c00caa29e53ee9a29def151f12792ac76596
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Oct 3 21:26:58 2018 +0330
+
+    [test] Use an in-repo font for test-multithread (#1218)
+
+    As Khaled's suggestion, hard-coded font paths was only for my own
+    testing.
+
+ test/api/hb-subset-test.h   | 13 +++++++++----
+ test/api/test-multithread.c | 41
+ ++++++++++++++++++++++++++---------------
+ test/fuzzing/main.cc        |  6 ++++++
+ 3 files changed, 41 insertions(+), 19 deletions(-)
+
+commit fde9b8852d7cd6224afeffcfe363f4b445ab1ece
+Author: azure-pipelines[bot]
+<azure-pipelines[bot]@users.noreply.github.com>
+Date:   Wed Oct 3 17:47:05 2018 +0000
+
+    [ci] Add a test Azure Pipelines Linux bot
+
+    Related #1219
+
+ azure-pipelines.yml | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 674560cf244054a7e8c16073a59aa1b01e1ba5ea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 19:10:28 2018 +0200
+
+    Fix build
+
+ src/test-unicode-ranges.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 45e55f70801e2ccd28e1ee30bdf5341b1ac6efe5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 18:07:49 2018 +0200
+
+    [indic] Fix clang everything
+
+ src/hb-ot-shape-complex-indic.cc | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit 4df02e3240ada0734748a47572baa2fc1c6afbd1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 17:54:09 2018 +0200
+
+    Minor
+
+ src/hb-ot-os2-unicode-ranges.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1e8f195b96765480007808da60789de9ac501c3b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 17:46:48 2018 +0200
+
+    [emoji] Add emoji Extended_Pictographic table and function
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1159
+
+    .
+
+ src/Makefile.am                 |  12 +-
+ src/gen-emoji-table.py          |  64 ++++++++++
+ src/hb-ot-os2-table.hh          |   2 +-
+ src/hb-ot-os2-unicode-ranges.hh |   6 +-
+ src/hb-unicode-emoji-table.hh   | 269
+ ++++++++++++++++++++++++++++++++++++++++
+ src/hb-unicode.cc               |  16 +++
+ src/hb-unicode.hh               |  37 +++++-
+ 7 files changed, 398 insertions(+), 8 deletions(-)
+
+commit 1dc601b04a816a5b5ed12ae1c01ddcfd60a8398f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 17:27:46 2018 +0200
+
+    [os2] Minor rename/shuffle
+
+ ...unicode-ranges.py => gen-os2-unicode-ranges.py} |  2 +-
+ src/hb-ot-os2-unicode-ranges.hh                    | 45
+ +++++++++++-----------
+ 2 files changed, 24 insertions(+), 23 deletions(-)
+
+commit 7a1ab0464d3ee1ca5c9b31215fbffb8601ae860d
+Author: lantw44 <lantw44 at gmail.com>
+Date:   Wed Oct 3 23:22:43 2018 +0800
+
+    Fix test-multithread build on FreeBSD (#1217)
+
+    Add the default font path used by FreeBSD ports.
+
+ test/api/test-multithread.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit df32eaae42b505b00de4a8b5efce9ab948bed847
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 14:44:25 2018 +0200
+
+    [indic] Disallow vowel mark combinations that spoof other vowel marks
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1019
+
+    New numbers:
+
+    BENGALI: 353725 out of 354188 tests passed. 463 failed (0.130722%)
+    DEVANAGARI: 707261 out of 707394 tests passed. 133 failed (0.0188014%)
+    GUJARATI: 366353 out of 366457 tests passed. 104 failed (0.0283799%)
+    GURMUKHI: 60729 out of 60747 tests passed. 18 failed (0.0296311%)
+    KANNADA: 951300 out of 951913 tests passed. 613 failed (0.0643966%)
+    MALAYALAM: 1048136 out of 1048334 tests passed. 198 failed
+    (0.0188871%)
+    ORIYA: 42327 out of 42329 tests passed. 2 failed (0.00472489%)
+    SINHALA: 271596 out of 271847 tests passed. 251 failed (0.0923313%)
+    TAMIL: 1091754 out of 1091754 tests passed. 0 failed (0%)
+    TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%)
+
+    Devanagari regressed because Uniscribe doesn't enforce the full set.
+
+    Tests added with the *-vowel-letters.txt files in tree and Noto fonts.
+
+ src/hb-ot-shape-complex-indic.cc                   | 256
+ ++++++++++++++++++++-
+ test/shaping/data/in-house/Makefile.sources        |   1 +
+ .../03e3f463c3a985bc42096620cc415342818454fb.ttf   | Bin 0 -> 2904 bytes
+ .../1a5face3fcbd929d228235c2f72bbd6f8eb37424.ttf   | Bin 0 -> 8188 bytes
+ .../2c25beb56d9c556622d56b0b5d02b4670c034f89.ttf   | Bin 0 -> 2460 bytes
+ .../604026ae5aaca83c49cd8416909d71ba3e1c1194.ttf   | Bin 0 -> 4120 bytes
+ .../738d9f3b8c2dfd03875bf35a61d28fd78faf17c8.ttf   | Bin 0 -> 2336 bytes
+ .../7d18685e1529e4ceaad5b6095dfab2f9789e5bce.ttf   | Bin 0 -> 3452 bytes
+ .../881642af1667ae30a54e58de8be904566d00508f.ttf   | Bin 0 -> 2760 bytes
+ .../af85624080af5627fb050f570d148a62f04fda74.ttf   | Bin 0 -> 2656 bytes
+ .../tests/indic-vowel-letter-spoofing.tests        |  53 +++++
+ 11 files changed, 309 insertions(+), 1 deletion(-)
+
+commit 1b8d5e999192035c08f918aa1fcfcebdea67d82e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 14:44:19 2018 +0200
+
+    [thai] Minor
+
+ src/hb-ot-shape-complex-thai.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit d3d0cbd27831a6ea41b89f50d380296565c0016d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 13:54:21 2018 +0200
+
+    Typo
+
+ .../{bengali-vowel-leters.txt => bengali-vowel-letters.txt}
+ | 0
+ .../{gujarati-vowel-letter.txt => gujarati-vowel-letters.txt}
+ | 0
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 0dd9101fd0ddff80fff10ba98e93523aed95c8f5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 13:26:26 2018 +0200
+
+    Minor
+
+ src/hb-ot-shape-complex-indic.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 9c4ffd10c4040ada9b1ffeb13c35f1330336359e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 12:53:54 2018 +0200
+
+    Minor
+
+ src/hb-ot-shape-complex.hh | 11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+commit bd1be8738fc4c73635cab7d77965264748d747cc
+Author: HinTak <htl10 at users.sourceforge.net>
+Date:   Wed Oct 3 07:11:22 2018 +0800
+
+    Missing colon for gobject annotation
+
+    There should be a colon separating "(transfer full)" and the
+    rest. Warned by g-ir-scanner.
+
+ src/hb-face.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 75114e01d29b90f72a9398ed5dbc4298aba5a6b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Oct 3 12:29:56 2018 +0200
+
+    [use] Add Halant_Or_Vowel_Modifier category
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1102
+
+ src/gen-use-table.py                               |   7 +-
+ src/hb-ot-shape-complex-use-machine.hh             | 518
+ +++++++++++----------
+ src/hb-ot-shape-complex-use-machine.rl             |   9 +-
+ src/hb-ot-shape-complex-use-table.cc               |   4 +-
+ src/hb-ot-shape-complex-use.hh                     |   5 +-
+ .../28f497629c04ceb15546c9a70e0730125ed6698d.ttf   | Bin 0 -> 1496 bytes
+ .../shaping/data/in-house/tests/use-syllable.tests |   3 +
+ 7 files changed, 301 insertions(+), 245 deletions(-)
+
+commit 6353cc1f83c862910860976411a1157f7ed571bc
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Oct 2 21:39:19 2018 +0330
+
+    [circleci] Fix some of warnings from clang-everything bot (#1211)
+
+    * -Wshift-sign-overflow
+    * -Wmissing-prototypes
+
+ .circleci/config.yml             |  4 ++--
+ src/dump-emoji.cc                | 19 ++++++++++---------
+ src/hb-ucdn.cc                   |  3 +++
+ src/test-unicode-ranges.cc       |  4 ++--
+ test/fuzzing/hb-subset-fuzzer.cc | 32 +++++++++++++++++---------------
+ util/ansi-print.cc               |  4 ++--
+ 6 files changed, 36 insertions(+), 30 deletions(-)
+
+commit 9f1dee32fbad3b1486725c18570199156b57a94d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 18:56:20 2018 +0200
+
+    [tests] Allow test-runner to ignore shaping output
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1212
+
+ test/shaping/data/in-house/tests/fuzzed.tests | 46
+ +++++++++++++--------------
+ test/shaping/run-tests.py                     |  2 +-
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+commit fef7af1e22efb399517137b35d0ba9f307411ca3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 18:46:13 2018 +0200
+
+    [tibetan] Remove unused Tibetan shaper
+
+ src/Makefile.sources               |  1 -
+ src/hb-ot-shape-complex-tibetan.cc | 63
+ --------------------------------------
+ src/hb-ot-shape-complex.hh         |  1 -
+ 3 files changed, 65 deletions(-)
+
+commit 32a438166fbccac6e0d9a615a492fc8cabfd21ab
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 18:43:29 2018 +0200
+
+    [tibetan] Route Tibetan through USE
+
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/933
+    https://github.com/harfbuzz/harfbuzz/issues/1012
+
+    Tibetan failures go from 0 to 2:
+
+    TIBETAN: 208467 out of 208469 tests passed. 2 failed (0.000959375%)
+
+ src/gen-use-table.py                 | 30 ++++++++++------
+ src/hb-ot-shape-complex-use-table.cc | 70
+ ++++++++++++++++++++++--------------
+ src/hb-ot-shape-complex.hh           |  8 +----
+ 3 files changed, 65 insertions(+), 43 deletions(-)
+
+commit 77792187be1405599e6aecfc3ed1fc771d505ddb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 18:20:16 2018 +0200
+
+    [khmer] Remove unused khmer_position()
+
+ src/dump-khmer-data.cc           | 8 +++-----
+ src/hb-ot-shape-complex-khmer.hh | 1 -
+ 2 files changed, 3 insertions(+), 6 deletions(-)
+
+commit 5101abd42f4027edf182eddfa58c629b11c2a7f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 17:49:06 2018 +0200
+
+    [indic/use] Factor common expressions in ragel machine
+
+    No machine change.
+
+ src/hb-ot-shape-complex-indic-machine.hh | 46
+ ++++++++++++++++----------------
+ src/hb-ot-shape-complex-indic-machine.rl | 10 ++++---
+ src/hb-ot-shape-complex-use-machine.hh   | 38 +++++++++++++-------------
+ src/hb-ot-shape-complex-use-machine.rl   | 20 +++++++-------
+ 4 files changed, 58 insertions(+), 56 deletions(-)
+
+commit 6f457f8370de5d96452ee3a2d1b0a97b025ef1d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 17:46:27 2018 +0200
+
+    [indic] Minor flip grammar around
+
+    No behavior change.
+
+ src/hb-ot-shape-complex-indic-machine.rl | 2 +-
+ src/hb-ot-shape-complex-use-machine.rl   | 1 -
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+commit d992982d23ef0c39ea42595ed0e8a4752977d1a5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 17:16:01 2018 +0200
+
+    [indic] Add some confusable sequences from Unicode Standard
+
+ .../script-bengali/bengali-vowel-leters.txt        |  3 ++
+ .../devanagari-atomic-consonants.txt               | 33
+ ++++++++++++++++++++++
+ .../script-devanagari/devanagari-vowel-letters.txt | 17 +++++++++++
+ .../script-gujarati/gujarati-vowel-letter.txt      |  8 ++++++
+ .../script-gurmukhi/gurmukhi-vowel-letters.txt     |  9 ++++++
+ .../script-kannada/kannada-vowel-letters.txt       |  3 ++
+ .../script-malayalam/malayalam-vowel-letters.txt   |  5 ++++
+ .../script-oriya/oriya-vowel-letters.txt           |  3 ++
+ .../script-telugu/telugu-vowel-letters.txt         |  5 ++++
+ 9 files changed, 86 insertions(+)
+
+commit 40d5d19d5b875eef526a2a66892c3f638f633fa3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 17:04:05 2018 +0200
+
+    [ragel] Use ts/te (token-start / token-end) instead of manual tracking
+
+ src/hb-ot-shape-complex-indic-machine.hh   | 22 ++++++++++------------
+ src/hb-ot-shape-complex-indic-machine.rl   |  8 +++-----
+ src/hb-ot-shape-complex-khmer-machine.hh   | 22 ++++++++++------------
+ src/hb-ot-shape-complex-khmer-machine.rl   |  8 +++-----
+ src/hb-ot-shape-complex-myanmar-machine.hh | 22 ++++++++++------------
+ src/hb-ot-shape-complex-myanmar-machine.rl |  8 +++-----
+ src/hb-ot-shape-complex-use-machine.hh     | 22 ++++++++++------------
+ src/hb-ot-shape-complex-use-machine.rl     |  8 +++-----
+ 8 files changed, 52 insertions(+), 68 deletions(-)
+
+commit 9efddb9de821fc909a3ea8354f3dfd39c823e97b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 16:05:26 2018 +0200
+
+    Treat a base+mark... ligature as base, not ligature
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/746
+
+ src/hb-ot-layout-gsubgpos.hh | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+commit 3cca978723db43233d25402254d297dfccf991a3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 15:02:16 2018 +0200
+
+    Move code around
+
+ src/hb-ot-layout-gsub-table.hh |  3 ---
+ src/hb-ot-layout-gsubgpos.hh   | 22 +++++++++++-----------
+ 2 files changed, 11 insertions(+), 14 deletions(-)
+
+commit 0a371fee4d22ed63207aa76c00b05b75bbc95f5f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 14:48:39 2018 +0200
+
+    Minor
+
+ src/hb-ot-map.hh                   | 6 ++++--
+ src/hb-ot-shape-complex-arabic.cc  | 6 +++---
+ src/hb-ot-shape-complex-myanmar.cc | 4 ++--
+ src/hb-ot-shape-complex-use.cc     | 8 ++++----
+ src/hb-ot-shape.cc                 | 4 ++--
+ 5 files changed, 15 insertions(+), 13 deletions(-)
+
+commit 94d15528f80dbb7110d816fb5845f257f605a0be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 14:45:09 2018 +0200
+
+    Minor
+
+ src/hb-ot-map.hh   |  1 +
+ src/hb-ot-shape.cc | 39 ++++++++++++++++++---------------------
+ 2 files changed, 19 insertions(+), 21 deletions(-)
+
+commit 729f634728fb553300021d52089495271dfb19fd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 14:40:14 2018 +0200
+
+    Disable joiner-skipping when looking back for base to attach mark to
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1189
+
+ src/hb-ot-shape.cc                                      |   5 ++++-
+ test/shaping/data/in-house/Makefile.sources             |   1 +
+ .../fonts/641ca9d7808b01cafa9a666c13811c9b56eb9c52.ttf  | Bin 0 ->
+ 11492 bytes
+ .../data/in-house/tests/arabic-mark-attach.tests        |   1 +
+ 4 files changed, 6 insertions(+), 1 deletion(-)
+
+commit c36f3f5bef52e660541933f003fafa6e3a14785d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 14:34:29 2018 +0200
+
+    [arabic] Use manual-zwj instead of flipping joiners
+
+ src/hb-buffer.hh                  |  3 +--
+ src/hb-ot-layout.hh               | 12 ++----------
+ src/hb-ot-shape-complex-arabic.cc | 41
+ ++++++---------------------------------
+ 3 files changed, 9 insertions(+), 47 deletions(-)
+
+commit 48c513fec978819927535bc86b43be74315f746c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 14:17:42 2018 +0200
+
+    Minor
+
+ src/hb-ot-shape-complex-arabic.cc  |  2 +-
+ src/hb-ot-shape-complex-default.cc |  2 +-
+ src/hb-ot-shape-complex-hangul.cc  |  2 +-
+ src/hb-ot-shape-complex-hebrew.cc  | 14 +-------------
+ src/hb-ot-shape-complex-indic.cc   |  2 +-
+ src/hb-ot-shape-complex-indic.hh   |  2 --
+ src/hb-ot-shape-complex-khmer.cc   |  2 +-
+ src/hb-ot-shape-complex-myanmar.cc |  4 ++--
+ src/hb-ot-shape-complex-thai.cc    |  2 +-
+ src/hb-ot-shape-complex-tibetan.cc |  2 +-
+ src/hb-ot-shape-complex-use.cc     |  2 +-
+ src/hb-ot-shape-complex.hh         | 11 ++++-------
+ src/hb-ot-shape.cc                 |  8 ++++----
+ 13 files changed, 19 insertions(+), 36 deletions(-)
+
+commit cca757ae56d6a82cfad35edc6dbae58049a34f91
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 13:27:11 2018 +0200
+
+    Minor
+
+ src/hb-ot-shape.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 96eca87f89588126d3fa5c7f3884ae2f302a91e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 13:24:40 2018 +0200
+
+    Move things
+
+ src/hb-ot-shape.cc | 22 ++++++++++------------
+ src/hb-ot-shape.hh |  3 +++
+ 2 files changed, 13 insertions(+), 12 deletions(-)
+
+commit 588a4ac8bc9fd20464c7a77ead27ae34478c9bc8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 13:13:47 2018 +0200
+
+    Rename
+
+ src/hb-ot-face.cc | 20 +++++++-------
+ src/hb-ot-face.hh | 78
+ +++++++++++++++++++++++++++----------------------------
+ 2 files changed, 49 insertions(+), 49 deletions(-)
+
+commit 10b6c7c63870fa04cd8adcf9f38644c2a799db8a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 13:11:18 2018 +0200
+
+    Minor include cleanup
+
+ src/hb-ot-shape-complex.hh | 1 +
+ src/hb-ot-shape.cc         | 4 +---
+ src/hb-ot-shape.hh         | 2 +-
+ 3 files changed, 3 insertions(+), 4 deletions(-)
+
+commit 1d1734e985e1f2a746b4fff0cd82d96d477577d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Oct 2 13:04:05 2018 +0200
+
+    Shuffle code around
+
+ src/hb-ot-shape-complex-hebrew.cc |  2 +-
+ src/hb-ot-shape-fallback.cc       |  2 +-
+ src/hb-ot-shape-normalize.cc      |  2 +-
+ src/hb-ot-shape.cc                | 32 ++++++++++++++++++++++++++++----
+ src/hb-ot-shape.hh                | 29 ++++++-----------------------
+ 5 files changed, 37 insertions(+), 30 deletions(-)
+
+commit bf5088b3dcd94106937290c180f3f40bc8524b48
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Oct 2 11:07:06 2018 +0330
+
+    Minor, fix -Weverthing bot warnings (#1210)
+
+ test/api/test-buffer.c      | 8 ++++----
+ test/api/test-multithread.c | 3 +--
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+commit d27e5ec3a236b8eb37ef9ce558ad54077e46b003
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Tue Oct 2 08:25:29 2018 +0200
+
+    Skip BOM in the Python sample file
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1208
+
+ src/sample.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit f9ea3dc4c6e85c417dd4c8546e5ebe02b67131b9
+Author: HinTak <htl10 at users.sourceforge.net>
+Date:   Tue Oct 2 06:43:06 2018 +0100
+
+    Missing "out" indicator (#1209)
+
+    Missing "out" indicator. Affect gobject introspection.
+
+ src/hb-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9742679b8253919f8bfec8a77532092044e951aa
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Oct 2 03:20:48 2018 +0330
+
+    [circleci] Remove some of the not needed flags
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f72b748371da2d7ce327a5d15feea46960aa7dd3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Oct 2 00:16:08 2018 +0330
+
+    [circleci] Fix "msan" and "everything" bots (#1205)
+
+ .circleci/config.yml                    | 13 ++++++-------
+ src/check-symbols.sh                    |  2 --
+ test/fuzzing/main.cc                    | 22 +++++++++-------------
+ test/fuzzing/run-shape-fuzzer-tests.py  |  2 --
+ test/fuzzing/run-subset-fuzzer-tests.py |  2 --
+ 5 files changed, 15 insertions(+), 26 deletions(-)
+
+commit 8bf4027d23318c7e1ff7fe9f5e7ad8b0380e5415
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 20:05:00 2018 +0200
+
+    [indic] Remove Consonant_Medial from grammar and code
+
+    The only Indic CM is U+0A75 GURMUKHI SIGN YAKASH, which Uniscribe
+    doesn't treat
+    specially, and font designers design for that.  So, do the same.
+
+ src/hb-ot-shape-complex-indic-machine.hh | 1244
+ ++++++++++++++----------------
+ src/hb-ot-shape-complex-indic-machine.rl |   10 +-
+ src/hb-ot-shape-complex-indic.cc         |    2 +-
+ src/hb-ot-shape-complex-indic.hh         |    6 +-
+ 4 files changed, 589 insertions(+), 673 deletions(-)
+
+commit ab4c37f73a7d4fcf48584cda3fff94e98a672086
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 19:35:48 2018 +0200
+
+    [khmer] Add mark-ordering tests
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/667
+
+ test/shaping/data/in-house/Makefile.sources        |   2 ++
+ .../b6031119874ae9ff1dd65383a335e361c0962220.ttf   | Bin 0 -> 2564 bytes
+ .../data/in-house/tests/khmer-mark-order.tests     |  25
+ +++++++++++++++++++++
+ 3 files changed, 27 insertions(+)
+
+commit 51436547162a18e88144e7125ad6ce4a69a08d4b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 19:09:58 2018 +0200
+
+    [khmer] Rewrite grammar completely
+
+    Based on experimenting with Uniscribe to extract grammar and
+    categories.
+
+    Failures down from 44 to 35:
+
+    KHMER: 299089 out of 299124 tests passed. 35 failed (0.0117008%)
+
+    We still don't enforce the one-matra rule pre-decomposition,
+    but enforce
+    an order and one-matra-per-position post-decomposition.
+
+    https://github.com/harfbuzz/harfbuzz/issues/667
+
+ src/hb-ot-shape-complex-indic.hh         |   2 +-
+ src/hb-ot-shape-complex-khmer-machine.hh | 300
+ ++++++++++++++++++++-----------
+ src/hb-ot-shape-complex-khmer-machine.rl |  42 +++--
+ src/hb-ot-shape-complex-khmer.cc         |   4 +-
+ src/hb-ot-shape-complex-khmer.hh         |  99 +++++-----
+ 5 files changed, 270 insertions(+), 177 deletions(-)
+
+commit aaaa65baa7fcfb65ae814528bdd93cc5c4ea540d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 16:59:48 2018 +0200
+
+    [khmer] Remove unused code
+
+ src/hb-ot-shape-complex-khmer.hh | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+commit eb1e60287732ede6040ce6f7498c10909448d248
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 15:31:50 2018 +0200
+
+    [test] Try import unicodedata2 as unicodedata
+
+ test/shaping/hb_test_tools.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 81afdbe803ca949d915d03cab4a6ed6c6e6ff304
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 15:01:04 2018 +0200
+
+    [use] Disable automatic ZWJ for 'akhn' feature
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/746
+
+ src/hb-ot-shape-complex-use.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ceef311dcaea7e1ecfedb4f1257a705572611f0f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 12:45:06 2018 +0200
+
+    [use] Change categories for Left_And_* matras
+
+    These are only relevant to Sinhala, because they decompose in other
+    cases.  The USE spec categorizes them all as VPst.  No idea why we
+    weren't following that before.
+
+ src/gen-use-table.py                 |  4 ++--
+ src/hb-ot-shape-complex-use-table.cc | 24 ++++++++++++------------
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+commit 3426a361571a1996b5a895fb9374ce3a4a7f9af3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 12:55:57 2018 +0200
+
+    Unbreak bots
+
+ src/hb-cache.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 98ac01d3b3deb7c7f5411f6f25c6e7588d84b5f9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 12:10:00 2018 +0200
+
+    [morx] Break out if buffer gets into error
+
+    Was getting stuck not making progress somehow.
+
+ src/hb-aat-layout-common.hh     | 2 ++
+ src/hb-aat-layout-morx-table.hh | 4 ++++
+ 2 files changed, 6 insertions(+)
+
+commit df827a6ab88cd8bde346176fc53a5c2d57eee808
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 1 11:34:20 2018 +0200
+
+    [cache] Fix cache coherency corner-case
+
+    If key_bits+value_bits-cache_bits==32 then -1 is ambiguous...
+
+ src/hb-cache.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 0fa1edbd3bbf825be078677dc46c3440f9802551
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Oct 1 09:40:29 2018 +0330
+
+    [circleci] Couple of fixes (#1200)
+
+    * Raise error on warnings on -everything
+    * Enable fontconfig to two bots
+    * Fix msan bot now that all of its real complain are gone
+
+ .circleci/config.yml                    | 14 ++++++--------
+ src/check-symbols.sh                    |  2 ++
+ src/hb-ucdn.cc                          |  2 ++
+ test/fuzzing/run-shape-fuzzer-tests.py  |  2 ++
+ test/fuzzing/run-subset-fuzzer-tests.py |  2 ++
+ util/helper-cairo.cc                    |  2 ++
+ 6 files changed, 16 insertions(+), 8 deletions(-)
+
+commit 3babb0813c69d2b419f06773f366a44a9ad32cdb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 20:02:30 2018 +0200
+
+    [msan] Disable icu explicitly
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dc9b47ae87096d34d146e50e44e742a76861976f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 18:35:12 2018 +0200
+
+    [msan] Remove uninstrumented libraries
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ad1c190ecfbac66ffeef69db769073a33331eed3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 18:26:45 2018 +0200
+
+    Correct fix for glib-mkenum warning
+
+ src/hb-buffer.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 1dd1e56bf42af5b11afc3e34f78869e93d39867e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 18:25:58 2018 +0200
+
+    Revert "Fix glib-mkenum warning"
+
+    This reverts commit 247756a7d89008ee6a7d1171dc07ba22454c6034.
+
+    Was wrong.  Right fix coming.
+
+ src/hb-buffer.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 3f08750fa6772e7e342b96192b84cb9963f7335b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 18:23:34 2018 +0200
+
+    Move _POSIX_SOURCE to hb.hh
+
+ src/hb-blob.cc | 5 -----
+ src/hb.hh      | 4 ++++
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+commit 90dd255e570bf8ea3436e2f29242068845256e55
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 18:19:54 2018 +0200
+
+    Change _HB_SCRIPT_MAX_VALUE from 0xFFFFFFFF to 0x7FFFFFFF
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/504
+
+ src/hb-common.h | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit dcfcb950b81a2865ef01f5a69087264b79ed1bfd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 18:14:50 2018 +0200
+
+    [test] Fix -Wunused-parameter warnings
+
+ test/api/hb-test.h          |  1 +
+ test/api/test-blob.c        |  2 +-
+ test/api/test-c.c           |  2 +-
+ test/api/test-font.c        | 16 ++++++++--------
+ test/api/test-multithread.c |  2 +-
+ test/api/test-ot-color.c    |  2 +-
+ test/api/test-shape.c       | 14 +++++++-------
+ test/api/test-unicode.c     | 10 +++++-----
+ 8 files changed, 25 insertions(+), 24 deletions(-)
+
+commit be0b2ed3162f465dbf44a0f018d4e2af5dcdf87c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 18:01:20 2018 +0200
+
+    More warning fixes
+
+ test/api/test-multithread.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 5c65ed800de4caef5ee9ad2111225fa5d8235737
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 17:48:55 2018 +0200
+
+    Fix bug introduced in 9b0b40b3c1ac8155c80ed5dc976228f4d3ec7e1f
+
+    Also discovered by msan bot.
+
+ src/hb-ot-shape-fallback.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 247756a7d89008ee6a7d1171dc07ba22454c6034
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 13:10:54 2018 +0200
+
+    Fix glib-mkenum warning
+
+      GEN      hb-gobject-enums.h
+    WARNING: Failed to parse "/*< private >*/" in ../../src/hb-buffer.h
+
+ src/hb-buffer.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 0a89f9572fe2d0d9fbf0297e0a69307f0ba1a17c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Sep 30 17:44:15 2018 +0330
+
+    [circleci] Pass ‌freetype compile flags to right place
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ad701f05cc86c22e8e53b7f5458887457e3a5e5f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Sep 30 17:30:42 2018 +0330
+
+    [circleci] Use an instrumented freetype on msan bot
+
+ .circleci/config.yml | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 57aabbc29ec6dfa7f1b57da7b6c62fdc547f8ef8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Sep 30 16:31:28 2018 +0330
+
+    [circleci] Another on fixing msan
+
+ .circleci/config.yml | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 24f148df3ecc899c9cf6d5359d3d35ee5e84a98c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Sep 30 14:46:56 2018 +0330
+
+    [circleci] minor
+
+ .circleci/config.yml | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 0a9aab672287149540e8d90b5063ad4c562c423c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Sep 30 14:45:43 2018 +0330
+
+    [circleci] Try to fix msan bot
+
+ .circleci/config.yml | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit b5285b34798cb7ee672343d00cbe066ea8a2ef83
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 12:23:01 2018 +0200
+
+    [util] Remove unneeded virtual
+
+    clang warning:
+
+    ../../util/options.hh:72:13: warning: destination for this 'memset'
+    call is a pointer to dynamic class
+          'option_parser_t'; vtable pointer will be overwritten
+          [-Wdynamic-class-memaccess]
+        memset (this, 0, sizeof (*this));
+        ~~~~~~  ^
+    ../../util/options.hh:72:13: note: explicitly cast the pointer to
+    silence this warning
+        memset (this, 0, sizeof (*this));
+                ^
+                (void*)
+
+ util/options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 89ed040b21b366c927199bedd0e4cb060389d076
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 06:06:26 2018 -0400
+
+    [util] Fix more non-virtual-destructor warnings
+
+ util/options.hh | 28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+commit 2382dd07fa6ff49638b146a523e9d2e93cf69ceb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 05:54:47 2018 -0400
+
+    Minor
+
+ util/options.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 9caa432d0c5c09c8151cfce1e2cc184fbdd89594
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 05:49:08 2018 -0400
+
+    [util] Use HB_FALLTHROUGH
+
+    Sure, gcc knows to warn about this as well:
+
+    ../../util/options.cc:175:17: warning: this statement may fall through
+    [-Wimplicit-fallthrough=]
+         case 1: m.r = m.t;
+                 ~~~~^~~~~
+    ../../util/options.cc:176:5: note: here
+         case 2: m.b = m.t;
+         ^~~~
+
+    But HOLY SMOKES, look at clang -Weverything bot message:
+
+    options.cc:176:5: warning: unannotated fall-through between switch
+    labels [-Wimplicit-fallthrough]
+        case 2: m.b = m.t;
+        ^
+    options.cc:176:5: note: insert 'HB_FALLTHROUGH;' to silence this
+    warning
+        case 2: m.b = m.t;
+        ^
+        HB_FALLTHROUGH;
+
+    Right, it's telling me to insert "HB_FALLTHROUGH;" there!!!!!!!!!
+
+ util/options.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 2e728a7d86c714d845524a0722c2b653feb9d915
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 05:47:36 2018 -0400
+
+    [util] Mark var static
+
+    From clang -Weverything bot:
+
+    options.cc:39:3: warning: no previous extern declaration
+    for non-static variable 'supported_font_funcs'
+    [-Wmissing-variable-declarations]
+
+ util/options.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e910a1aef4b2413c627240fc06d2a5696b24747a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 05:46:20 2018 -0400
+
+    [util] Add empty virtual destructor to option_group_t
+
+    From clang -Weverything bot:
+
+    ./options.hh:57:8: warning: 'option_group_t' has virtual functions
+    but non-virtual destructor [-Wnon-virtual-dtor]
+    struct option_group_t
+           ^
+
+ util/options.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit b1e07e1e6cc7a8e5445c7aeb9491ae629029011b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 05:43:22 2018 -0400
+
+    [indic/khmer] Remove use of global constructors
+
+    Alternative woul have been to resurrect F_COMBINE that I removed in
+    70136a78cb9eda244767f8e8a3d30d0f3c569d01
+
+    But this does it for now.  I'm not sure why check-static-inits.sh
+    didn't
+    catch this before.  Clang -Weverything bot did:
+
+      CXX      libharfbuzz_la-hb-ot-shape-complex-indic.lo
+    hb-ot-shape-complex-indic.cc:99:1: warning: declaration requires a
+    global constructor [-Wglobal-constructors]
+    indic_features[] =
+    ^
+    1 warning generated.
+      CXX      libharfbuzz_la-hb-ot-shape-complex-khmer.lo
+    hb-ot-shape-complex-khmer.cc:36:1: warning: declaration requires a
+    global constructor [-Wglobal-constructors]
+    khmer_features[] =
+    ^
+    1 warning generated.
+
+ src/hb-ot-map.hh                 |  2 ++
+ src/hb-ot-shape-complex-indic.cc | 34 +++++++++++++++++-----------------
+ src/hb-ot-shape-complex-khmer.cc | 18 +++++++++---------
+ 3 files changed, 28 insertions(+), 26 deletions(-)
+
+commit 00cd00e64130694ff7b49456d4bc421a153b4e6d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 05:34:30 2018 -0400
+
+    Tweak HB_TAG and HB_UNTAG
+
+    uint32_t was getting promoted to signed int, which is not what
+    we wanted...
+
+    Wow, clang has become good at generating warnings...
+
+    ../../src/hb-common.h:349:29: warning: signed shift result
+    (0xFF000000) sets the sign bit of the shift expression's type ('int')
+    and becomes negative [-Wshift-sign-overflow]
+      _HB_SCRIPT_MAX_VALUE                          = HB_TAG_MAX, /*<
+      skip >*/
+                                                      ^~~~~~~~~~
+    ../../src/hb-common.h:93:20: note: expanded from macro 'HB_TAG_MAX'
+     define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
+                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~
+    ../../src/hb-common.h:89:57: note: expanded from macro 'HB_TAG'
+     define HB_TAG(c1,c2,c3,c4)
+     ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
+                                             ~~~~~~~~~~~~~~~^ ~~
+    ../../src/hb-common.h:349:3: warning: ISO C restricts enumerator
+    values to range of 'int' (4294967295 is too large) [-Wpedantic]
+      _HB_SCRIPT_MAX_VALUE                          = HB_TAG_MAX, /*<
+      skip >*/
+      ^                                               ~~~~~~~~~~
+
+ src/hb-common.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 8a31e406291f4cb27480fc85049f08abd739cb59
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 05:27:39 2018 -0400
+
+    [font] Make *_advance() fallback to *_advances
+
+    And remove redundant implementations.
+
+ src/hb-font.cc    | 12 ++++++++++++
+ src/hb-ft.cc      | 19 -------------------
+ src/hb-ot-font.cc | 22 ----------------------
+ 3 files changed, 12 insertions(+), 41 deletions(-)
+
+commit bd07d2878ff28baecf7b4b587a18ffbb744b7eb1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 03:54:40 2018 -0400
+
+    Use buffer scratch_flags to remember if we had any joiners
+
+ src/hb-buffer.hh                  |  3 ++-
+ src/hb-ot-layout.hh               | 12 ++++++++++--
+ src/hb-ot-shape-complex-arabic.cc |  3 +++
+ 3 files changed, 15 insertions(+), 3 deletions(-)
+
+commit ba0f0f156fe05bda760efcb0c8d34f303fa26ab0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 30 03:49:52 2018 -0400
+
+    Document setlocale() threadsafety issue
+
+    "Fixes" //github.com/harfbuzz/harfbuzz/issues/1191
+
+ src/hb-buffer.cc | 2 ++
+ src/hb-common.cc | 7 +++++++
+ 2 files changed, 9 insertions(+)
+
+commit 06be2aa93fa6ea8cc32684a4b51bfe927c5202bb
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Sep 30 00:15:25 2018 +0330
+
+    [ci] Build glib and freetype and enable msan bot (#1198)
+
+ .circleci/config.yml | 41 +++++++++++++++++++++--------------------
+ 1 file changed, 21 insertions(+), 20 deletions(-)
+
+commit cefdef0247026f941eba8930c73b66b0498bb63c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 29 10:19:54 2018 +0330
+
+    Minor on test-multithread, align the actual and expected results
+
+ test/api/test-multithread.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 678beff64ca3b2963de25d8a76a2bf3710c3d7a6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 29 10:16:14 2018 +0330
+
+    [circleci] Add -Wno-reserved-id-macro to clang-everything
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c763b9440189b541316054ba4f623e728b5aae77
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 20:53:07 2018 -0400
+
+    [test-multithread] Disable FreeType funcs
+
+ test/api/test-multithread.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 9b0b40b3c1ac8155c80ed5dc976228f4d3ec7e1f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 11:16:18 2018 -0400
+
+    Fix fallback kerning to check for current glyph's mask
+
+ src/hb-ot-shape-fallback.cc | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+commit 909a07b587884e9cd1d92ba9f3d5b96d8774c67a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 29 03:10:13 2018 +0330
+
+    [circleci] Improve clang-everything bot log, more to come
+
+    #1196
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9be8062b4d241f02bb96df436e98f10f08bda4f8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 29 02:11:05 2018 +0330
+
+    [ci] Another try on mingw bot
+
+ appveyor.yml | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit d4d261a97723b27fb9ad9a69b8dc7fd8c560a98b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 29 01:57:50 2018 +0330
+
+    [ci] Another try on fixing mingw bots
+
+    Per
+    https://github.com/Alexpux/MSYS2-packages/issues/163#issuecomment-73555971
+
+ appveyor.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7b68edf2abc7680199360d52ed283cfc4f49b7d5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Sep 28 20:53:48 2018 +0330
+
+    [tests] Don't try to get glyph names on failures
+
+    As it may cause a race unrelated to the issue actually happened
+
+ test/api/test-multithread.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d289d6381864649504abfb1196ac20a1d4664a4e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Sep 28 20:47:21 2018 +0330
+
+    [ci] Trying to fix mingw bot
+
+    As https://github.com/Alexpux/MSYS2-packages/issues/702
+
+ appveyor.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 33231a855f0e3d2a14e5e2fcb921c6fc773ae6cf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 11:06:49 2018 -0400
+
+    Fix pthread fail for real
+
+    Using a hack...
+
+ test/api/Makefile.am | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 8cb8209c911a69442f23f744981e3ed01e44a3fc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 10:55:28 2018 -0400
+
+    Fix bot fails
+
+ test/api/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f4072e8cb81072cd6d51a2607efedb76c02e7db1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 10:14:23 2018 -0400
+
+    [morx] Remove mark_set from Insertion
+
+    text-rendering-tests test MORX-32 shows that for Insertion, an unset
+    mark is treated
+    as mark set at 0.  This is unlike the Reordering lookup where un
+    unset mark performs
+    nothing.
+
+    Fixes MORX-32.
+
+ src/hb-aat-layout-morx-table.hh | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit 0d18ec5467818fa8f763ec2871146a64d39987e7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 10:00:07 2018 -0400
+
+    [morx] unsafe-to-break in Insertion
+
+    Makes MORX-29, MORX-30, MORX-31 pass.
+
+ src/hb-aat-layout-morx-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 02bebe42c1ffbd8e11b232c943317c8cd8141afb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 09:51:35 2018 -0400
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/DISABLED          |   4 ++++
+ test/shaping/data/text-rendering-tests/Makefile.sources  |   4 ++++
+ .../text-rendering-tests/fonts/TestMORXThirtyone.ttf     | Bin 0 ->
+ 2964 bytes
+ .../text-rendering-tests/fonts/TestMORXThirtytwo.ttf     | Bin 0 ->
+ 2948 bytes
+ .../text-rendering-tests/fonts/TestMORXTwentynine.ttf    | Bin 0 ->
+ 3012 bytes
+ .../data/text-rendering-tests/tests/MORX-29.tests        |   4 ++++
+ .../data/text-rendering-tests/tests/MORX-30.tests        |   4 ++++
+ .../data/text-rendering-tests/tests/MORX-31.tests        |   8 ++++++++
+ .../data/text-rendering-tests/tests/MORX-32.tests        |   4 ++++
+ 9 files changed, 28 insertions(+)
+
+commit 4cd342baea323bf9709340bbabfc092c976c239c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 09:47:45 2018 -0400
+
+    Fix ubsan bot
+
+ test/api/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit b435df3a5b6f7fddc091c4362a36840305144a57
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 09:13:14 2018 -0400
+
+    More atomic tuneup
+
+ src/hb-atomic.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 7e6e094abd27fd022fe9aea1872ef82f6a0cdcec
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 08:45:57 2018 -0400
+
+    [test-multithread] Install ot funcs before filling ref buffer
+
+ test/api/test-multithread.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 21fbee831e0eab2c2f4513825c939158f4578156
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 08:43:37 2018 -0400
+
+    [test-multithread] Take num-threads and num-iters from command-line
+
+ test/api/test-multithread.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 598be3bb38fd11a288f8155b8c27ffef4ebdd8b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 28 08:33:26 2018 -0400
+
+    Minor
+
+ test/api/test-multithread.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c09bf3d50589c8eb95b322ef3e4eb8a288dacebe
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Sep 28 16:13:01 2018 +0330
+
+    test-multithread, check the results on every iteration (#1194)
+
+ test/api/test-multithread.c | 59
+ ++++++++++++++++++++++++---------------------
+ 1 file changed, 32 insertions(+), 27 deletions(-)
+
+commit dbc3070a15290310bb5aade11d04eb24fe958094
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Sep 28 16:01:15 2018 +0330
+
+    Make test-multithread pass the tsan bot test (#1193)
+
+ test/api/test-multithread.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit d2542cd28c70b2ba7ab28c0fe5459a1b4a873478
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 27 17:23:24 2018 -0400
+
+    More atomic fixup
+
+ src/hb-atomic.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3ee96984f4633852736b33640c89d1706bc77e0b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 27 17:20:26 2018 -0400
+
+    Fixup atomics from recent change
+
+ src/hb-atomic.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit 305468708dc9ce9dadad36c117c380f13bcc6a26
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 27 16:54:23 2018 -0400
+
+    [cache] Use atomic writes in clear()
+
+    To help TSan.
+
+ src/hb-cache.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 9e9a36ee651502b69717895385387951a2d0802a
+Author: Volker Krause <vkrause at kde.org>
+Date:   Thu Sep 27 16:33:49 2018 +0200
+
+    Fix infinite loop when walking up the directory hierarchy (#1183)
+
+    A single find_package(harfbuzz) line in user code resulted in
+    this loop
+    getting stuck when _harfbuzz_libdir_iter became "/".
+
+ src/harfbuzz-config.cmake.in | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 0c1d852bc41a4f69f890be4817c84bd7de56e07a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Sep 27 11:53:17 2018 +0330
+
+    Use clang for compiling freetype for tsan bot
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 662f7d7e8bfa77b21ffa05e853f61dda993dcc8a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 26 18:42:37 2018 -0400
+
+    [arabic] Do the joiner-flipping only for rlig feature
+
+    See comment.
+
+ src/hb-ot-shape-complex-arabic.cc | 24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+commit 7f30629cddcf0196d7b754df0cb2d4a8e5fed4b6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 26 16:40:23 2018 -0400
+
+    [ft] Make TSan happy
+
+ src/hb-ft.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit ec743fce2a72a1cb76ac9401747a442a03a051d9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 26 16:37:18 2018 -0400
+
+    Add more atomic intrinsics
+
+ src/hb-atomic.hh | 21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+commit d183b33c1dd42055a9432f4a756ea20856913201
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 26 16:29:35 2018 -0400
+
+    Rename test
+
+ test/api/Makefile.am                                           | 2 +-
+ test/api/{test-subset-codepoints.c => test-collect-unicodes.c} | 0
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit c9c75fe3d9eb36f166d594ceb5889a1dc0b14fe6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Sep 27 00:08:06 2018 +0330
+
+    [ci] Compile freetype on tsan and put sanitizer flags on correct
+    places (#1188)
+
+ .circleci/config.yml | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit 39da1914b4fd1c58d61cb29c78a0904ff6b905c6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Sep 26 23:32:45 2018 +0330
+
+    Test freetype funcs on test-multithread (#1187)
+
+ test/api/Makefile.am        |  6 ++++--
+ test/api/test-multithread.c | 25 +++++++++++++++++--------
+ 2 files changed, 21 insertions(+), 10 deletions(-)
+
+commit e88009a93f5d13ed31b6262f928761e9574dcef1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Sep 26 22:53:02 2018 +0330
+
+    Minor, remove the no longer needed comment on test-multithread
+
+ test/api/test-multithread.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 90a0f9fa0c020c268ac3ba31c7f1337eed85f35e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 26 15:03:07 2018 -0400
+
+    Make TSan happy with make_immutable()
+
+ src/hb-blob.cc    | 2 ++
+ src/hb-face.cc    | 2 ++
+ src/hb-font.cc    | 4 ++++
+ src/hb-unicode.cc | 2 ++
+ 4 files changed, 10 insertions(+)
+
+commit 34d5a2595331c568ae524057d031c9d5d2573978
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 26 15:02:21 2018 -0400
+
+    Fix test-multithread and increase num_threads to 30
+
+    What were you thinking? ;)
+
+ test/api/test-multithread.c | 56
+ +++++++++++++++++++++------------------------
+ 1 file changed, 26 insertions(+), 30 deletions(-)
+
+commit 8bb73dad7f3279e1f1362cf9a137504e8ef08985
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Sep 26 20:50:51 2018 +0330
+
+    Add a multithreaded test (#1184)
+
+ test/api/Makefile.am        |   6 ++
+ test/api/test-multithread.c | 146
+ ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 152 insertions(+)
+
+commit 04caf11608d2db13eb6ed2ecc3d406e284b4c13c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 26 12:13:47 2018 -0400
+
+    [hb-view] Change subpixel bits from 8 to 6
+
+    To match FreeType units, such that FreeType gets correct size from us.
+    This matters more now that we allow setting --ft-load-flags.
+
+ util/hb-view.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 824111d4842b9a7bbbdcd147325f8f372ed3d37c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 25 12:47:37 2018 -0400
+
+    Fix iOS build
+
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/1179
+
+ src/hb-coretext.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4b4be7701f635f8378e7f868cfbe8d4571fc841f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Sep 25 09:24:35 2018 +0330
+
+    [circle] Add an obsessive clang bot (#1178)
+
+ .circleci/config.yml | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit 8282e881b51363811078bce53fad6aa5b41f7b41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 19:43:01 2018 -0400
+
+    Disable msan bot again
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1175
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6c0e7eb6a6f3f888442c0a97ce6a771631990ed6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 19:07:23 2018 -0400
+
+    Minor
+
+ src/hb-ot-map.hh                 |  1 +
+ src/hb-ot-shape-complex-indic.cc | 34 +++++++++++++++++-----------------
+ src/hb-ot-shape-complex-khmer.cc | 18 +++++++++---------
+ 3 files changed, 27 insertions(+), 26 deletions(-)
+
+commit d748dc76644f28d4130f9cb1dee7a22cbe81c25d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 18:30:50 2018 -0400
+
+    More iter inits
+
+ src/hb-ot-layout-gsubgpos.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit d9867497d09af929554eaa89cc6fee865b018646
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 18:11:59 2018 -0400
+
+    Minor
+
+ src/hb-ot-shape.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 70136a78cb9eda244767f8e8a3d30d0f3c569d01
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 18:03:34 2018 -0400
+
+    Remove F_COMBINE
+
+    Now I wonder if any bots will be unhappy we calling | in static
+    const initializations...
+    Or would that cost runtime init?  Our tests don't detect any..
+
+ src/hb-ot-map.hh                  | 2 --
+ src/hb-ot-shape-complex-arabic.cc | 2 +-
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+commit f048ead84a4d3fe0bb712ed228c2f39c01ce9705
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 18:01:53 2018 -0400
+
+    Some more
+
+ src/hb-ot-map.cc                   |  5 +++--
+ src/hb-ot-map.hh                   | 13 +++++++------
+ src/hb-ot-shape-complex-arabic.cc  | 18 +++++++++---------
+ src/hb-ot-shape-complex-hangul.cc  |  2 +-
+ src/hb-ot-shape-complex-indic.cc   |  8 ++++----
+ src/hb-ot-shape-complex-khmer.cc   |  8 ++++----
+ src/hb-ot-shape-complex-myanmar.cc | 10 +++++-----
+ src/hb-ot-shape-complex-tibetan.cc |  2 +-
+ src/hb-ot-shape-complex-use.cc     | 20 ++++++++++----------
+ src/hb-ot-shape.cc                 | 30 +++++++++++++++---------------
+ 10 files changed, 59 insertions(+), 57 deletions(-)
+
+commit 1676f608c8e4f880789252ca448bb008f6dd51b4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 17:55:03 2018 -0400
+
+    Minor refactoring
+
+ src/hb-ot-map.hh                   | 15 ++++++++++-
+ src/hb-ot-shape-complex-hangul.cc  |  2 +-
+ src/hb-ot-shape-complex-indic.cc   | 52
+ +++++++++++++++-----------------------
+ src/hb-ot-shape-complex-khmer.cc   | 38 ++++++++++------------------
+ src/hb-ot-shape-complex-myanmar.cc |  2 +-
+ 5 files changed, 51 insertions(+), 58 deletions(-)
+
+commit 10203339600e85d6aaffba6034ac250e72fdfc12
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Sep 25 01:00:32 2018 +0330
+
+    [circleci] Update sanitizer bots with newer clang and Ubuntu version
+    (#1176)
+
+ .circleci/config.yml | 48
+ ++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 32 insertions(+), 16 deletions(-)
+
+commit 12b8baa7653741ba13a89cd40f1f36b8bac11666
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 17:22:39 2018 -0400
+
+    [msan] Enable again to get a build log, and try to play with
+    suppressions
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit aec0d3cbc923a8801c5bd9e9ae05801a31a7260c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 13:12:15 2018 -0400
+
+    [ubsan] Re-enable now that it passes locally
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4839807340cc73d5ba826dff4b4ba358775a213d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 13:11:34 2018 -0400
+
+    [check-static-inits.sh] Allow some if ubsan is in effect
+
+ src/check-static-inits.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e45ba31dc723988150ef766758fa89fecd50ca03
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 13:04:48 2018 -0400
+
+    [check-symbols.sh] Allow weak objects "V"
+
+    ubsan generates these.
+
+ src/check-symbols.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d07f3111b4bc38798e16a2459b80a16d7a9f9ff1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 13:01:35 2018 -0400
+
+    Link API test programs with C++ linker
+
+    Needed to make ubsan work.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1174
+
+ test/api/Makefile.am | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit a96508cfc9bd9013d24b18547fcd9c03e08fe2f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 12:52:42 2018 -0400
+
+    [msan] Add MSAN_OPTIONS=exitcode=42
+
+    Default exit value is 77, which causes autotools to "skip" test.
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 45f5aa97905996e3486c6dbba8493b11cfa0cf15
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 12:43:29 2018 -0400
+
+    [circleci] Disable msan and ubsan builds
+
+    https://github.com/harfbuzz/harfbuzz/issues/1174
+    https://github.com/harfbuzz/harfbuzz/issues/1175
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 2d93148a0f915bb52433ecc9d66845191a2f9135
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 11:52:22 2018 -0400
+
+    Ignore weak symbols in check-symbols.sh
+
+    Some clang versions leave a std::round(float) weak symbol around...
+
+ src/check-symbols.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 55bae6825ed2058255a512a73293e3cdff0e78a4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 10:43:06 2018 -0400
+
+    [docs] A few improvements
+
+    If we wrote just this much every day...
+
+ src/hb-buffer.cc |  4 ++++
+ src/hb-buffer.h  | 20 +++++++++++++++-----
+ src/hb-face.cc   | 11 +++++++----
+ src/hb-font.cc   | 12 +++++++-----
+ 4 files changed, 33 insertions(+), 14 deletions(-)
+
+commit 57fa2c23de8b6b66894d6872d192ac90ec8bf05a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 09:57:52 2018 -0400
+
+    Readjust Hebrew composition again
+
+ src/hb-ot-shape-complex-hebrew.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7f335390f3a498119319a0e6c3ce7656a3902066
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 09:56:18 2018 -0400
+
+    Revert change that would decompose text if GPOS mark feature is
+    available
+
+    https://github.com/harfbuzz/harfbuzz/issues/653#issuecomment-423905920
+
+ src/hb-ot-shape-normalize.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a6f4b2f7cd088aeb44e1aac672434641f4f9e484
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 24 09:54:37 2018 -0400
+
+    Fix normalization
+
+    https://github.com/harfbuzz/harfbuzz/commit/62d1e0852a5549a1b510ad46a4b89f12730bb708#commitcomment-30613091
+
+ src/hb-ot-shape-normalize.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 3583fb03b14a10ec5ab5f9c480e150934101fd0b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 23 22:33:38 2018 -0400
+
+    Simplify ZWJ-skipping a bit
+
+    Towards disabling ZWJ-skipping in certain GPOS contexts.
+
+    Part of https://github.com/flutter/flutter/issues/16886
+
+ src/hb-ot-layout-gsubgpos.hh       |  6 +++---
+ src/hb-ot-shape-complex-indic.cc   | 21 ++++++++++++++++-----
+ src/hb-ot-shape-complex-khmer.cc   | 21 ++++++++++++++-------
+ src/hb-ot-shape-complex-myanmar.cc | 15 ++++++++++++++-
+ src/hb-ot-shape-complex-use.cc     | 15 +++++++++++++--
+ 5 files changed, 60 insertions(+), 18 deletions(-)
+
+commit 9516cbd3df7ccdb40b27a7ba99a1e0da8a6b170c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 23 22:00:34 2018 -0400
+
+    Reinit skippy iters when auto_zwj / auto_zwnj change
+
+    Ouch.  How did we not hit this bug before...
+
+ src/hb-ot-layout-gsubgpos.hh | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+commit 62d1e0852a5549a1b510ad46a4b89f12730bb708
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 23 21:32:18 2018 -0400
+
+    Prefer decomposed form if font has GPOS mark feature
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/653
+
+ src/hb-ot-shape-complex-hebrew.cc |   2 +-
+ src/hb-ot-shape-normalize.cc      | 126
+ ++++++++++++++++++++------------------
+ src/hb-ot-shape-normalize.hh      |   7 ++-
+ 3 files changed, 72 insertions(+), 63 deletions(-)
+
+commit d7f21777e6a797758ab234555f5f7e07c87278f9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 23 19:12:52 2018 -0400
+
+    [ot-font] Fix leak
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1171
+
+    I'm glad we have leak-detector bots now.
+
+ src/hb-ot-post-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit ae39a53f55e6b812defb4c7b48562651c9eb13a3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 22 14:22:17 2018 +0330
+
+    Add bots with address- and thread-sanitizer
+
+ .circleci/config.yml | 52
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 52 insertions(+)
+
+commit 24dd6c1a9d8d571c30dce4d39c1975b1d1cedc2a
+Author: Matt Oliver <protogonoi at gmail.com>
+Date:   Sun Sep 23 18:08:30 2018 +1000
+
+    src/hb-blob.cc: Fix mmap functionality with UWP.
+
+ src/hb-blob.cc | 27 +++++++++++++++++++++++++++
+ src/hb.hh      |  4 +++-
+ 2 files changed, 30 insertions(+), 1 deletion(-)
+
+commit b7f1bbc2f8b14a402fa9e42e88919dc0173373ce
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Sat Sep 22 16:41:56 2018 +0200
+
+    [test] Fix printing subprocess error messages
+
+    Decode the string as Python 3 returns bytes string, and also don’t
+    assume that it ends with a new line.
+
+ test/shaping/run-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 403019482b0d7f17fbdb5def2be5f43e28bafcf3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 22 17:24:03 2018 +0330
+
+    Fix test-subset-* leak issues
+
+    See also https://github.com/harfbuzz/harfbuzz/pull/1169
+
+ test/api/hb-subset-test.h | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+commit f6ebe1f4dc95a7c4b3a0af23086873a11867c1d9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 22 17:05:52 2018 +0330
+
+    Fix test-ot-math leak issue
+
+    See also https://github.com/harfbuzz/harfbuzz/pull/1169
+
+ test/api/test-ot-math.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 669ac81ac52e9d559324db851a9ee46ef651e7b0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 22 16:49:23 2018 +0330
+
+    Fix test-set leak issue
+
+    See also https://github.com/harfbuzz/harfbuzz/pull/1169
+
+ test/api/test-set.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit ef9307fd2227bf0f750d8f7fafae466affc81454
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Sep 22 16:45:31 2018 +0330
+
+    Fix test-font leak issue
+
+    See also https://github.com/harfbuzz/harfbuzz/pull/1169
+
+ test/api/test-font.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 5fd8bce945e7efaa48d0c29eb8b2700027bd3c0b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 19 22:34:09 2018 -0400
+
+    [morx] Fix mark_set check
+
+ src/hb-aat-layout-morx-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 0739b28169eb63332b31420deb5bf58b5446f154
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 19 17:32:21 2018 -0400
+
+    [aat] Minor
+
+ src/hb-aat-layout-common.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 7671cb9b04770d50b1b2a05a24f6fadc35993cd1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 19 17:10:26 2018 -0400
+
+    [coretext] Minor
+
+ src/hb-coretext.cc | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit dc8ed45292ce4e522c3bda03fd83873da7b6591e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 19 16:46:41 2018 -0400
+
+    [morx] Implement forward/backward processing
+
+    We reverse too many times. Can be optimized. But I doubt many fonts
+    use reverse lookups, so doesn't matter.
+
+    Other than not applying user features, this completes morx table
+    implementation.
+
+ src/hb-aat-layout-morx-table.hh | 40
+ ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+commit 3bccd62196b5dff70d446c3fe053b1b47bb9c19e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 19 16:24:34 2018 -0400
+
+    [morx] Implement horiz-only/vert-only subtables
+
+ src/hb-aat-layout-morx-table.hh | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+commit 041a08de3d0ca74d3e2fdccfa5311ff26a8b97e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 19 16:02:56 2018 -0400
+
+    [morx] Improve buffer position in Insertion w DontAdvance and wo
+
+    Just speculation. Needs tests to determine which is correct behavior.
+
+ src/hb-aat-layout-morx-table.hh | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+commit 388ab91642734e1ba0d7a4a4f29a17b15f1b249d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 17 19:29:34 2018 +0200
+
+    [morx] Implement InsertionChain
+
+ src/hb-aat-layout-morx-table.hh | 87
+ ++++++++++++++++-------------------------
+ 1 file changed, 33 insertions(+), 54 deletions(-)
+
+commit d8d1e7df0057c79f54d855b7bfec2d21f59b09e8
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Mon Sep 17 11:09:51 2018 -0400
+
+    Don't enforce a native direction for Old Hungarian
+
+ src/hb-common.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6a97d0f3d377a35ea691d15ac142ce043f953e71
+Author: Simon Hausmann <hausmann at gmail.com>
+Date:   Mon Sep 17 10:33:34 2018 +0200
+
+    Fix installation of cmake config when building with cmake (#1161)
+
+    When building with the auto tools, the manually mantained
+    harfbuzz-config.cmake is installed. When building with cmake, we
+    can use
+    cmake to generate the correct config files for us and install them.
+
+ CMakeLists.txt | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 606bf57430370810f7bb62ba12b9685d8943685d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 16 19:33:48 2018 +0200
+
+    Revert forcing use of single-parameter static_assert()
+
+    Some clang versions define static_assert as a macro apparently,
+    so we cannot
+    redefine it...
+
+    This reverts commit 94bfea0ce6a7b4d5641c198d50751748a353df11.
+    This reverts commit 4e62627831e7457ed60ff87712570065b14b200a.
+
+ src/hb-atomic.hh                           |  4 ++--
+ src/hb-buffer.cc                           |  2 +-
+ src/hb-buffer.hh                           |  4 ++--
+ src/hb-cache.hh                            |  4 ++--
+ src/hb-coretext.cc                         |  2 +-
+ src/hb-debug.hh                            |  2 +-
+ src/hb-dsalgs.hh                           |  4 ++--
+ src/hb-machinery.hh                        |  4 ++--
+ src/hb-null.hh                             |  8 +++----
+ src/hb-open-type.hh                        |  4 ++--
+ src/hb-ot-layout-common.hh                 |  2 +-
+ src/hb-ot-layout-gdef-table.hh             |  6 +++---
+ src/hb-ot-layout.cc                        | 14 ++++++------
+ src/hb-ot-map.cc                           |  2 +-
+ src/hb-ot-math-table.hh                    |  2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh |  2 +-
+ src/hb-ot-shape-complex-indic.hh           |  2 +-
+ src/hb-ot-shape-complex-use.cc             |  2 +-
+ src/hb-set-digest.hh                       |  4 ++--
+ src/hb-set.hh                              |  6 +++---
+ src/hb-uniscribe.cc                        |  2 +-
+ src/hb.hh                                  | 34
+ +++++++++++++-----------------
+ util/options.cc                            |  3 ++-
+ 23 files changed, 58 insertions(+), 61 deletions(-)
+
+commit cbcaba6ffdf6b147d45baa95d62fd29cec67ed54
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 16 19:25:19 2018 +0200
+
+    One more bot fix
+
+ src/hb-unicode.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 94bfea0ce6a7b4d5641c198d50751748a353df11
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 16 19:12:19 2018 +0200
+
+    Fix build, another try
+
+ util/options.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 89dd4b959773d35981299551074ccc7a1eb332bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 16 18:11:46 2018 +0200
+
+    Fix bots
+
+    "Unused private member" warning turned error.  ugh.
+
+ src/hb-aat-layout-morx-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 4e62627831e7457ed60ff87712570065b14b200a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 16 18:09:36 2018 +0200
+
+    Enforce single-param static_assert() only
+
+    So we don't accidentally break it again.
+
+ src/hb-atomic.hh                           |  4 ++--
+ src/hb-buffer.cc                           |  2 +-
+ src/hb-buffer.hh                           |  4 ++--
+ src/hb-cache.hh                            |  4 ++--
+ src/hb-coretext.cc                         |  2 +-
+ src/hb-debug.hh                            |  2 +-
+ src/hb-dsalgs.hh                           |  4 ++--
+ src/hb-machinery.hh                        |  4 ++--
+ src/hb-null.hh                             |  8 +++----
+ src/hb-open-type.hh                        |  4 ++--
+ src/hb-ot-layout-common.hh                 |  2 +-
+ src/hb-ot-layout-gdef-table.hh             |  6 +++---
+ src/hb-ot-layout.cc                        | 14 ++++++------
+ src/hb-ot-map.cc                           |  2 +-
+ src/hb-ot-math-table.hh                    |  2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh |  2 +-
+ src/hb-ot-shape-complex-indic.hh           |  2 +-
+ src/hb-ot-shape-complex-use.cc             |  2 +-
+ src/hb-set-digest.hh                       |  4 ++--
+ src/hb-set.hh                              |  6 +++---
+ src/hb-uniscribe.cc                        |  2 +-
+ src/hb.hh                                  | 34
+ +++++++++++++++++-------------
+ 22 files changed, 60 insertions(+), 56 deletions(-)
+
+commit f1a86e1e6f3906f33fc89de694a4bbbc3e40d2bc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 16 18:01:32 2018 +0200
+
+    Remove unused try
+
+ src/hb-null.hh | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+commit ebd50b3c83a22a0fdba53271275b8619a23739aa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Sep 16 17:57:12 2018 +0200
+
+    Fix static_assert
+
+ src/hb-open-type.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 10642b3fbfbc1776e784b190c43a9e0693dd423a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Sep 15 19:43:33 2018 +0200
+
+    Disallow null-enabled offsets to unsized structures...
+
+    ...like UnsizedArrayOf<>.
+
+    This fixes a class of crasher bugs, mostly with color and AAT tables.
+    We
+    cannot use nullable offsets to varsized data that does not declare
+    min_size,
+    because it's nost safe to use our fixed-size null pool for types
+    that have
+    their size external.  So, use non_null'able offsets for these.
+
+    A further enhancement would be to make use of min_size in Null<>
+    itself.
+    Will try that after.
+
+ src/hb-aat-layout-common.hh     |  8 ++++----
+ src/hb-aat-layout-feat-table.hh |  2 +-
+ src/hb-aat-layout-morx-table.hh | 10 +++++-----
+ src/hb-aat-layout-trak-table.hh |  4 ++--
+ src/hb-aat-ltag-table.hh        |  2 +-
+ src/hb-open-type.hh             |  5 +++++
+ src/hb-ot-color-cbdt-table.hh   |  4 +---
+ src/hb-ot-color-colr-table.hh   |  4 ++--
+ src/hb-ot-color-cpal-table.hh   |  8 ++++----
+ src/hb-ot-color-svg-table.hh    |  2 +-
+ src/hb-ot-layout-common.hh      | 18 ++++++++++--------
+ src/hb-ot-layout-jstf-table.hh  |  4 ++--
+ 12 files changed, 38 insertions(+), 33 deletions(-)
+
+commit 9ff76c6025b55d184c96b193f23aa935ab32f1fc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Sep 15 18:31:14 2018 +0200
+
+    [morx] Respect default feature settings
+
+    Does NOT apply user-selected features.  But at least now enables
+    correct subtables.
+
+ src/hb-aat-layout-morx-table.hh | 34 +++++++++++++++++++++++-----------
+ 1 file changed, 23 insertions(+), 11 deletions(-)
+
+commit 2f97da6e2d6629e112789d399765d90f96952c0a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Sep 15 14:51:50 2018 +0200
+
+    [aat] Change version field
+
+ src/hb-aat-layout-morx-table.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 29c2bd1795b933a611512af50a14f25e25d43159
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Sep 15 14:47:18 2018 +0200
+
+    [morx] Add stub for InsertionChain
+
+ src/hb-aat-layout-morx-table.hh | 209
+ ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 200 insertions(+), 9 deletions(-)
+
+commit f8ccb545c47abe8f0f4ed318ff7b5bf176913893
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 14 18:59:53 2018 +0200
+
+    [dfont] Disable null-processsing for offsets
+
+    An offset to unsized arrayis not safe to be redirected to our
+    fixed-sized
+    null pool.  Plus, we want to reject, not repair, bad-looking dfonts.
+
+ src/hb-open-file.hh | 8 ++++----
+ src/hb-open-type.hh | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 01b9148d9ae7d18228538774243e49840cfd2499
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 14 14:23:09 2018 +0200
+
+    [unicode] Move Fitzpatrick hack from ot-layout into unicode.hh
+
+ src/hb-ot-layout.hh | 12 +-----------
+ src/hb-unicode.hh   | 36 +++++++++++++++++++++++++++---------
+ 2 files changed, 28 insertions(+), 20 deletions(-)
+
+commit 6ebbf514ac90712fe089b2b64f68d1cf681edd5d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 14 12:15:53 2018 +0200
+
+    Minor
+
+ src/hb-ot-layout.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 957dbed388fc3214248f6aca65902ad277d070fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 14 12:14:42 2018 +0200
+
+    Fix builds
+
+ src/hb-aat-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4653e6cf3c1ef5005886d901df30e952d57eed6c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 14 11:31:33 2018 +0200
+
+    [aat] Add enums for pre-defined state and classes
+
+    Not sure how I didn't add before...
+
+ src/hb-aat-layout-common.hh | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+commit 67449c39331babb88f7d29d737895d786cd5da33
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Sep 14 10:58:00 2018 +0200
+
+    Don't dereference offset before check_struct()
+
+ src/hb-open-file.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit ca746f261e1e54cec2f9c8bc7a6f930491e19418
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 20:35:21 2018 +0200
+
+    [dfont] Also check dataLen range in sanitize
+
+    Just to disagree with myself re being done with this code...
+
+ src/hb-open-file.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 3789c557ca06aef430726f4942cafecac6fe4eef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 20:30:04 2018 +0200
+
+    [dfont] Solve the mystery +2 offset thing!
+
+    Previously, ResourceForkHeader was defined as 30 bytes, having the
+    typeCountM1 as last member.
+    There was a mysterious offset-by-2 in the code, derived from FontTools
+    and JDK code this was
+    ported from.
+
+    In testing, I observed that typeListZ offset is actually 28.
+    Suggesting that the typeCountM1
+    does NOT actually belong to ResourceForkHeader, but belongs to the
+    array itself.  Adjusting for
+    that resolves the mystery +2 offset hack, so everything is clean
+    and good now.
+
+    This, concludes my dfont hacking.  The code looks great now, and
+    I'm happy to leave it.
+    Fuzzers might disagree though, we will see!
+
+ src/hb-open-file.hh | 30 ++++++++++++------------------
+ src/hb-open-type.hh | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 56 insertions(+), 18 deletions(-)
+
+commit effc7ced72a6ce0fea328a8b68dc3d55f09774f1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 20:21:54 2018 +0200
+
+    Rename HeadlessArrayOf::len to lenP1
+
+    So it doesn't accidentally match our templates, etc.
+
+ src/hb-open-type.hh            | 14 +++++++-------
+ src/hb-ot-layout-gsub-table.hh | 10 +++++-----
+ src/hb-ot-layout-gsubgpos.hh   | 10 +++++-----
+ 3 files changed, 17 insertions(+), 17 deletions(-)
+
+commit 180a88a96ce327e4103df3635c73559de65d1546
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 19:19:57 2018 +0200
+
+    [dfont] Some more
+
+ src/hb-open-file.hh | 21 ++++++++-------------
+ 1 file changed, 8 insertions(+), 13 deletions(-)
+
+commit 0ab0f1e5ac5ccb07c57364e9f5be0b991398eb6f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 19:13:01 2018 +0200
+
+    [dfont] Push methods further down
+
+ src/hb-open-file.hh | 58
+ ++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 33 insertions(+), 25 deletions(-)
+
+commit 8c9bdcc1feeab321a642bdaac50b716e48ce4263
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 19:08:22 2018 +0200
+
+    [dfont] Minor
+
+ src/hb-open-file.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 4479d3a2eda57d278700f5c78414ef6ef617d2a9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 19:05:59 2018 +0200
+
+    [dfon]t Sanitize OpenTypeFontFace
+
+ src/hb-dsalgs.hh    |  6 ------
+ src/hb-open-file.hh | 21 +++++++++------------
+ 2 files changed, 9 insertions(+), 18 deletions(-)
+
+commit 3fba41906fba28c5ea01cc0749654de862453bf4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 18:49:16 2018 +0200
+
+    [dfont] Minor
+
+ src/hb-open-file.hh | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+commit bf852f0e62a8bdbb809af6a975f8ae8eed708d70
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 18:47:53 2018 +0200
+
+    [dfont] Make test pass
+
+    Offset 0 is not null in this context.
+
+ src/hb-open-file.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 29faebe911a13916aa3d737e93d38deedc53567f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 18:45:35 2018 +0200
+
+    Allow Offset<>'s that have no 0==null
+
+ src/hb-open-type.hh | 43 +++++++++++++++++++++----------------------
+ 1 file changed, 21 insertions(+), 22 deletions(-)
+
+commit 82f4d776c21b7c1224dd7073ce69cdf76d85f16b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 18:27:20 2018 +0200
+
+    [dfont] Minor
+
+ src/hb-open-file.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 07e0ca930c29757217c2f9e4e0e6954657b6b82d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 17:39:09 2018 +0200
+
+    [bytes] Rename content to arrayZ
+
+ src/hb-dsalgs.hh        | 16 ++++++++--------
+ src/hb-ot-post-table.hh |  2 +-
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+commit dbb764dceb61365b7360a48d581ba5a4b3526e98
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 16:49:26 2018 +0200
+
+    [dfont] Clean up sanitize()
+
+    I don't think I broke anything.  Fuzzers will let me know..
+
+ src/hb-dsalgs.hh    |   8 ++++
+ src/hb-open-file.hh | 122
+ ++++++++++++++++++++++++----------------------------
+ 2 files changed, 64 insertions(+), 66 deletions(-)
+
+commit 361fc2686152ad8c0ebaf19e0522e0fc58ba3953
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 16:47:33 2018 +0200
+
+    Fix OffsetTo::sanitize() after reshuffling
+
+ src/hb-open-type.hh | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit 4c6b0fb5f6668a6e562260d16f629ad3c41e8961
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 16:39:30 2018 +0200
+
+    OffsetTo::sanitize() Add version with three user_data
+
+ src/hb-open-type.hh | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+commit a73bea69c599787b4cfeac92a3afd00749e00434
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 16:31:31 2018 +0200
+
+    OffsetTo::sanitize() more shuffling
+
+ src/hb-open-type.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit b482e5231cd5987082dd2c05fd649c3653f3c67a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 13 16:29:49 2018 +0200
+
+    OffsetTo::sanitize() reshuffling
+
+ src/hb-open-type.hh | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+commit bd75fd45cdbd0edb24568326bb7fde59d299a82c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 18:12:26 2018 +0200
+
+    [dfont] Some renaming, plus add link to reference doc
+
+ src/hb-open-file.hh | 79
+ ++++++++++++++++++++++++-----------------------------
+ 1 file changed, 35 insertions(+), 44 deletions(-)
+
+commit 4134ec1307bbaff24972e238bc5e4a403cd3f1c1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 17:56:03 2018 +0200
+
+    [dfont] Sanitize only sfnt resources as OpenTypeFontFile
+
+ src/hb-open-file.hh | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit 6b5e4d07adb6b739dc294da513c4a7acd03977f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 17:26:24 2018 +0200
+
+    [dfont] Minor
+
+ src/hb-open-file.hh | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit d5c509272f2fbd1b4c56e3b530da7e42e7f03901
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 17:18:21 2018 +0200
+
+    [dfont] Fix test expecatation and minor touch up
+
+    I have no way to authoritatively know, but looks like test font only
+    has one
+    face.  So, adjust test expectation instead.
+
+ src/hb-open-file.hh                                | 18
+ ++++++------------
+ test/shaping/data/in-house/tests/collections.tests |  2 +-
+ 2 files changed, 7 insertions(+), 13 deletions(-)
+
+commit 2b2ed1e536061cfd3a0f29522118f42b451678bd
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jul 2 17:26:43 2018 +0430
+
+    [dfont] Add test
+
+ test/shaping/data/in-house/Makefile.sources        |   1 +
+ test/shaping/data/in-house/fonts/TestDFONT.dfont   | Bin 0 -> 3505 bytes
+ test/shaping/data/in-house/fonts/TestTTC.ttc       | Bin 0 -> 2608 bytes
+ test/shaping/data/in-house/tests/collections.tests |   6 ++++++
+ 4 files changed, 7 insertions(+)
+
+commit 9479ffefbfa3ea4ee39747e34177d26ab1ebbec9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 16:41:26 2018 +0200
+
+    [dfont] Re-enable and fix offset handling
+
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/1085
+
+ src/hb-face.cc      |  5 +++--
+ src/hb-open-file.hh | 19 +++++++++++++------
+ 2 files changed, 16 insertions(+), 8 deletions(-)
+
+commit a1814e2bec3a43b9eeb4d50a67daae3fc52fd0a5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 14:45:23 2018 +0200
+
+    Whitespace
+
+ src/hb-open-file.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 383060cc3354e12611dec3082a6fe08fdb25f652
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 14:41:19 2018 +0200
+
+    [ft] Invalidate advance cache if font size changed
+
+ src/hb-ft.cc | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 54998befc43ef38e47b74b3153380adbcf6279d4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 14:35:26 2018 +0200
+
+    [ft] Cache advances
+
+    I decided to always use the cache, instead of my previous sketch
+    direction
+    that was to only allocate and use cache if fast advances are not
+    available.
+    The cache is a mere 1kb, so just use it...
+
+    TODO: Invalidate cache on font size change.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/651
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/1082
+
+ src/hb-cache.hh |  2 +-
+ src/hb-ft.cc    | 37 +++++++++++++++++--------------------
+ 2 files changed, 18 insertions(+), 21 deletions(-)
+
+commit f90bab8560816b60b4b3f2379b36c08756b21e6c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 14:21:15 2018 +0200
+
+    [util] Add --ft-load-flags
+
+    Useful for performance testing.
+
+    Not hooked to cairo yet.  Just changes shaping, not rasterization.
+
+ util/helper-cairo.cc | 2 +-
+ util/options.cc      | 4 ++++
+ util/options.hh      | 2 ++
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+commit 93f7596254808d567b9e1e01fb4855efcd34677c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 14:11:10 2018 +0200
+
+    [util] Add -n shorthand for --num-iterations
+
+    Meh.
+
+ util/options.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 047a84c5dd76cdfc072de25c572e30866f87a1f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 14:05:16 2018 +0200
+
+    [ft] Towards caching slow get_h_advance results
+
+    Related to https://github.com/harfbuzz/harfbuzz/pull/1082
+
+ src/hb-ft.cc | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+commit 237f21537842e6b471cdd6c86b98edfc0da0756c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 13:05:47 2018 +0200
+
+    [ft] Add advances() callback
+
+ src/hb-ft.cc | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+commit cbea7d49ab8d4765a2d72dcbf608d326bdf9af3d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 12:56:17 2018 +0200
+
+    [ot-font] Rename
+
+ src/hb-ot-font.cc | 74
+ +++++++++++++++++++++++++++----------------------------
+ 1 file changed, 37 insertions(+), 37 deletions(-)
+
+commit d8a67dac2a673138bb4d41cd7eab97c9ee987958
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 12:55:54 2018 +0200
+
+    [ot-font] Add advances() callbacks
+
+ src/hb-ot-font.cc | 43 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 42 insertions(+), 1 deletion(-)
+
+commit 0ea42e117ba2c76e118974fe114ae5d9ceef5743
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 12:22:42 2018 +0200
+
+    [cache] Minor
+
+ src/hb-cache.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0f520adaacca3c7b6d8e84a7722343184105f612
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 12:02:34 2018 +0200
+
+    Revert "Remove unused hb_cache_t"
+
+    This reverts commit 473b17af4d421f4ce7ac18c769731bb2aa4088f8.
+
+    Updates to recent changes.
+
+ src/Makefile.sources |  1 +
+ src/hb-cache.hh      | 75
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ft.cc         |  1 +
+ 3 files changed, 77 insertions(+)
+
+commit cfdea884754ed40ffa5cc00cb1ecaa86cb46a394
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 10:57:48 2018 +0200
+
+    [random] Switch to 32bit RNG
+
+ src/hb-ot-layout-gsubgpos.hh                | 7 ++++---
+ test/shaping/data/in-house/tests/rand.tests | 4 ++--
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+commit 08260c708ae6adc4efa9bde5e9ede01b7e4d42cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 10:51:19 2018 +0200
+
+    [random] Shuffle
+
+ src/hb-ot-layout-gsub-table.hh | 5 +----
+ src/hb-ot-layout-gsubgpos.hh   | 6 ++++++
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+commit 71c9f84e7c0afe41a8987b8a4ebc2b45a22fac56
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 22:37:19 2018 +0200
+
+    Make --features rand=1 available to the user
+
+    Use rand=255 to mean "randomize".
+
+    Part of https://github.com/harfbuzz/harfbuzz/pull/803
+
+ src/hb-ot-layout-gsub-table.hh | 11 ++++-------
+ src/hb-ot-layout-gsubgpos.hh   |  1 +
+ src/hb-ot-map.cc               |  4 ++--
+ src/hb-ot-map.hh               |  3 +++
+ src/hb-ot-shape.cc             |  2 +-
+ 5 files changed, 11 insertions(+), 10 deletions(-)
+
+commit cc1c4fdf88f6953dcd07fb42ee963404657cdef4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 16:36:05 2018 +0200
+
+    Respect user's wish if they set rand feature manually
+
+    Except if the set it to 1, which would mean "randomize"... Ugly.
+
+ src/hb-ot-layout-gsub-table.hh | 30 ++++++++++++++++--------------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+commit 80de4bcd2677bfb0907ea7059524f918b109ac37
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 16:24:52 2018 +0200
+
+    Minor clean up of 'rand' patchset
+
+ src/hb-ot-layout-gsub-table.hh              |  7 +++++--
+ src/hb-ot-layout-gsubgpos.hh                |  7 ++++---
+ src/hb-ot-shape.cc                          | 13 ++++++-------
+ test/shaping/data/in-house/tests/rand.tests |  2 +-
+ 4 files changed, 16 insertions(+), 13 deletions(-)
+
+commit b545e27d8891f1e7f1fd034dd84abe44c839c380
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri Feb 23 12:22:32 2018 -0500
+
+    Don't seed the RNG from the contents of the buffer
+
+ src/hb-ot-layout-gsubgpos.hh                | 7 ++-----
+ src/hb-ot-layout.cc                         | 5 +----
+ test/shaping/data/in-house/tests/rand.tests | 2 +-
+ 3 files changed, 4 insertions(+), 10 deletions(-)
+
+commit 2de96e846844d21888af6893378b21a33fc19232
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Sat Jan 27 19:48:38 2018 -0500
+
+    Test 'rand'
+
+ test/shaping/data/in-house/Makefile.sources              |   1 +
+ .../fonts/5bb74492f5e0ffa1fbb72e4c881be035120b6513.ttf   | Bin 0 ->
+ 1352 bytes
+ test/shaping/data/in-house/tests/rand.tests              |   3 +++
+ 3 files changed, 4 insertions(+)
+
+commit f05df643b44d9bbfd742e93f02c235fc821190d0
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri Jan 26 21:36:15 2018 -0500
+
+    Allow requesting a specific glyph for 'rand'
+
+    Randomization only happens by default. If the user specifies a
+    value for
+    'rand', that value is respected.
+
+ src/hb-ot-map.cc   | 3 ++-
+ src/hb-ot-map.hh   | 4 +++-
+ src/hb-ot-shape.cc | 7 ++++++-
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+commit c2a75e07e54314f6c611dda0f050ed5f09909e43
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Thu Jan 25 14:22:03 2018 -0500
+
+    Implement 'rand'
+
+ src/hb-ot-layout-gsub-table.hh | 19 ++++++++++++-------
+ src/hb-ot-layout-gsubgpos.hh   |  8 ++++++++
+ src/hb-ot-layout.cc            |  8 ++++++++
+ src/hb-ot-map.cc               |  7 +++++--
+ src/hb-ot-map.hh               |  4 +++-
+ src/hb-ot-shape.cc             |  1 +
+ 6 files changed, 37 insertions(+), 10 deletions(-)
+
+commit 96471fe8593575deceb44d3757c227f65f10a25e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 01:39:23 2018 +0200
+
+    [uniscribe] Fix build
+
+ src/hb-uniscribe.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit becd84aa2f2902ea9d2d1677b28945e103a68816
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 01:26:18 2018 +0200
+
+    Add HB_FEATURE_GLOBAL_START/END
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1141
+
+    New API:
+    HB_FEATURE_GLOBAL_START
+    HB_FEATURE_GLOBAL_END
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-common.cc           |  4 ++--
+ src/hb-common.h            | 13 +++++++++++++
+ 3 files changed, 17 insertions(+), 2 deletions(-)
+
+commit 13a8786c7c580651d8a6db9345b9aa85ca8ed956
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 01:07:06 2018 +0200
+
+    Add (unused) hb_array_t<>
+
+ src/hb-dsalgs.hh | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+commit bccf3e1827eec07433340eea705597201b6d0a32
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 11 01:04:50 2018 +0200
+
+    Minor
+
+ src/hb-open-type.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit dff2c45f1e2a30767f6813d3cb6a70978d98d424
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 23:29:26 2018 +0200
+
+    Port rest from VAR to UnsizedArrayOf<>
+
+ src/hb-aat-layout-common.hh     | 14 +++++++-------
+ src/hb-aat-layout-morx-table.hh | 16 ++++++++--------
+ src/hb-open-type.hh             | 10 +++++-----
+ src/hb-ot-cmap-table.hh         |  8 +++++---
+ src/hb-ot-color-cbdt-table.hh   | 16 ++++++++--------
+ src/hb-ot-glyf-table.hh         | 10 +++++-----
+ src/hb-ot-hdmx-table.hh         | 30 +++++++++++++-----------------
+ src/hb-ot-hmtx-table.hh         |  8 ++++----
+ src/hb-ot-kern-table.hh         | 20 ++++++++++----------
+ src/hb-ot-layout-common.hh      |  9 +++++----
+ src/hb-ot-layout-gpos-table.hh  | 26 +++++++++++++-------------
+ src/hb-ot-math-table.hh         | 36 +++++++++++++++++++-----------------
+ src/hb-ot-maxp-table.hh         |  2 +-
+ src/hb-ot-name-table.hh         | 13 +++++++------
+ src/hb-ot-post-table.hh         |  5 +++--
+ 15 files changed, 113 insertions(+), 110 deletions(-)
+
+commit 9507b05a7a65962d5d02eb424e4f5d8570976f4e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 23:18:07 2018 +0200
+
+    Simplify sanitize->check_array()
+
+    Fix a bug in CBDT sanitize, and redundant check in avar.
+
+ src/hb-aat-layout-common.hh     | 10 ++++------
+ src/hb-aat-layout-morx-table.hh |  2 +-
+ src/hb-machinery.hh             |  3 ++-
+ src/hb-open-type.hh             |  6 +++---
+ src/hb-ot-color-cbdt-table.hh   |  4 ++--
+ src/hb-ot-kern-table.hh         |  2 +-
+ src/hb-ot-layout-common.hh      |  2 +-
+ src/hb-ot-layout-gpos-table.hh  |  8 ++++----
+ src/hb-ot-layout-gsubgpos.hh    |  4 ++--
+ src/hb-ot-math-table.hh         |  8 ++------
+ src/hb-ot-name-table.hh         |  2 +-
+ src/hb-ot-var-avar-table.hh     |  4 ++--
+ src/hb-ot-var-fvar-table.hh     |  2 +-
+ src/hb-ot-var-hvar-table.hh     |  2 +-
+ src/hb-ot-var-mvar-table.hh     |  2 +-
+ 15 files changed, 28 insertions(+), 33 deletions(-)
+
+commit bc485a98122131efc4768fef9147823f2bce146b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 23:02:24 2018 +0200
+
+    Port some VAR arrays to UnsizedArrayOf<>
+
+    Fix avar sanitize().
+
+ src/hb-ot-layout-gsubgpos.hh | 59
+ +++++++++++++++++++++++---------------------
+ src/hb-ot-var-avar-table.hh  | 10 +++++---
+ src/hb-ot-var-fvar-table.hh  |  7 +++---
+ src/hb-ot-var-hvar-table.hh  |  9 ++++---
+ src/hb-ot-var-mvar-table.hh  |  9 ++++---
+ 5 files changed, 51 insertions(+), 43 deletions(-)
+
+commit 1bc7a8d6c4deb9fa6e010d7be08b68cad88579ae
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 22:51:26 2018 +0200
+
+    [indic] Cache hb_options().uniscribe_bug_compatible on indic_plan
+
+ src/hb-ot-shape-complex-indic.cc | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+commit 24f1d9622489a016904314a5d4e3c637da2e1c77
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 18:19:37 2018 +0200
+
+    Unbreak HB_OPTIONS
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1154
+
+ src/hb-debug.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit e46c51f1e985ac9c0ffa90fda4ea436d54b4009c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 17:38:19 2018 +0200
+
+    [indic] Do NOT allow matra after Halant,ZWJ
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/556
+
+    Devanagari regresses 12 tests, and Gujarati 2.  See:
+
+      https://github.com/harfbuzz/harfbuzz/issues/556#issuecomment-419957472
+
+    New numbers:
+
+    BENGALI: 353725 out of 354188 tests passed. 463 failed (0.130722%)
+    DEVANAGARI: 707299 out of 707394 tests passed. 95 failed (0.0134296%)
+    GUJARATI: 366353 out of 366457 tests passed. 104 failed (0.0283799%)
+    GURMUKHI: 60729 out of 60747 tests passed. 18 failed (0.0296311%)
+    KANNADA: 951300 out of 951913 tests passed. 613 failed (0.0643966%)
+    MALAYALAM: 1048136 out of 1048334 tests passed. 198 failed
+    (0.0188871%)
+    ORIYA: 42327 out of 42329 tests passed. 2 failed (0.00472489%)
+    SINHALA: 271596 out of 271847 tests passed. 251 failed (0.0923313%)
+    TAMIL: 1091754 out of 1091754 tests passed. 0 failed (0%)
+    TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%)
+
+ src/hb-ot-shape-complex-indic-machine.hh | 1688
+ ++++++++++++++----------------
+ src/hb-ot-shape-complex-indic-machine.rl |    2 +-
+ 2 files changed, 784 insertions(+), 906 deletions(-)
+
+commit 5dfd6e07626a9022a995eb7fa16767eff66c6047
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 15:45:32 2018 +0200
+
+    Fix sanitize or Context Rule
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1110
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 20a11a824d2a07a8544649477ad03e809bdd8e19
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 13:56:28 2018 +0200
+
+    Revert "[subset] Disable GSUB/GPOS subsetting for now"
+
+    This reverts commit 616fd34a69bb69bc35c7e4ea939e71c3ea2e92cb.
+
+ src/hb-subset.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 54d332dd9b0263821376161cdffb60ffb3c7847f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Sep 10 11:37:24 2018 +0200
+
+    1.9.0
+
+ NEWS             | 19 +++++++++++++++++++
+ configure.ac     |  2 +-
+ src/hb-face.cc   | 10 +++++-----
+ src/hb-unicode.h |  5 +++++
+ src/hb-version.h |  6 +++---
+ 5 files changed, 33 insertions(+), 9 deletions(-)
+
 commit 616fd34a69bb69bc35c7e4ea939e71c3ea2e92cb
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Mon Sep 10 11:19:49 2018 +0200

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,3 +1,71 @@
+Overview of changes leading to 2.0.0
+Wednesday, October 17, 2018
+====================================
+- Added AAT shaping support (morx/kerx/trak).
+  Automatically used if GSUB/GPOS are not available respectively.
+  Set HB_OPTIONS=aat env var to have morx/kerx preferred over
+  GSUB/GPOS.
+- Apply TrueType kern table internally, instead of relying on
+  hb_font_t callbacks.
+- Khmer shaper significantly rewritten to better match Uniscribe.
+- Indic3 tags ('dev3', etc) are passed to USE shaper.
+- .dfont Mac font containers implemented.
+- Script- and language-mapping revamped to better use BCP 47.
+- Misc USE and Indic fixes.
+- Misc everything fixes.
+- Too many things to list.  Biggest release since 0.9.1, with
+  over 500 commits in just over 5 weeks!  Didn't intend it to
+  be a big release.  Just happened to become.
+- hb-ft now locks underlying FT_Face during use.
+
+API changes:
+
+- Newly-created hb_font_t's now have our internal "hb-ot-font"
+  callbacks set on them, so they should work out of the box
+  without any callbacks set.  If callbacks are set, everything
+  is back to what it was before, the fallback callbacks are
+  null.  If you to get the internal implementation modified,
+  sub_font it.
+
+- New hb_font_funcs_set_nominal_glyphs_func() allows speeding
+  up character to glyph mapping.
+
+New API:
++HB_FEATURE_GLOBAL_START
++HB_FEATURE_GLOBAL_END
++hb_buffer_set_invisible_glyph()
++hb_buffer_get_invisible_glyph()
++hb_font_funcs_set_nominal_glyphs_func()
++hb_ot_layout_table_select_script()
++hb_ot_layout_script_select_language()
++hb_ot_layout_feature_get_name_ids()
++hb_ot_layout_feature_get_characters()
++hb_name_id_t
++HB_NAME_ID_INVALID
++HB_OT_MAX_TAGS_PER_SCRIPT
++hb_ot_tags_from_script_and_language()
++hb_ot_tags_to_script_and_language()
+
+Deprecated API:
+-hb_font_funcs_set_glyph_func()
+-hb_unicode_eastasian_width_func_t
+-hb_unicode_funcs_set_eastasian_width_func()
+-hb_unicode_eastasian_width()
+-hb_unicode_decompose_compatibility_func_t
+-HB_UNICODE_MAX_DECOMPOSITION_LEN
+-hb_unicode_funcs_set_decompose_compatibility_func()
+-hb_unicode_decompose_compatibility()
+-hb_font_funcs_set_glyph_h_kerning_func()
+-hb_font_funcs_set_glyph_v_kerning_func()
+-hb_font_get_glyph_h_kerning()
+-hb_font_get_glyph_v_kerning()
+-hb_font_get_glyph_kerning_for_direction()
+-hb_ot_layout_table_choose_script()
+-hb_ot_layout_script_find_language()
+-hb_ot_tags_from_script()
+-hb_ot_tag_from_language()
+
+
 Overview of changes leading to 1.9.0
 Monday, September 10, 2018
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/TODO
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/TODO	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/TODO	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,9 +1,3 @@
-General fixes:
-=============
-
-- Implement 'rand' feature.
-
-
 API issues:
 ===========
 
@@ -19,12 +13,10 @@
 
 - Add hb-cairo glue
 
-- Add sanitize API (and a cached version, that saves result on blob user-data)
+- Add sanitize API.
 
 - BCP 47 language handling / API (language_matches?)
 
-- Add hb_font_create_unscaled()?
-
 - Add query / enumeration API for aalt-like features?
 
 - Add segmentation API

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2018-10-19 23:02:01 UTC (rev 48949)
@@ -85,9 +85,6 @@
 /* Define to 1 if you have the `newlocale' function. */
 #undef HAVE_NEWLOCALE
 
-/* Have native OpenType Layout backend */
-#undef HAVE_OT
-
 /* Define to 1 if you have the `posix_memalign' function. */
 #undef HAVE_POSIX_MEMALIGN
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [1.9.0],
+        [2.0.0],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
@@ -12,6 +12,7 @@
 AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability])
 AM_SILENT_RULES([yes])
 AX_CODE_COVERAGE
+AC_USE_SYSTEM_EXTENSIONS
 
 # Initialize libtool
 m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
@@ -19,7 +20,6 @@
 LT_INIT([disable-static])
 
 # Check for programs
-AC_USE_SYSTEM_EXTENSIONS
 AC_PROG_CC
 AC_PROG_CC_C99
 AM_PROG_CC_C_O
@@ -148,12 +148,6 @@
 
 dnl ==========================================================================
 
-have_ot=true
-if $have_ot; then
-	AC_DEFINE(HAVE_OT, 1, [Have native OpenType Layout backend])
-fi
-AM_CONDITIONAL(HAVE_OT, $have_ot)
-
 have_fallback=true
 if $have_fallback; then
 	AC_DEFINE(HAVE_FALLBACK, 1, [Have simple TrueType Layout backend])
@@ -330,7 +324,7 @@
 			[Use the graphite2 library @<:@default=no@:>@])],,
 	[with_graphite2=no])
 have_graphite2=false
-GRAPHITE2_DEPS="graphite2"
+GRAPHITE2_DEPS="graphite2 >= 1.2.0"
 AC_SUBST(GRAPHITE2_DEPS)
 if test "x$with_graphite2" = "xyes" -o "x$with_graphite2" = "xauto"; then
 	PKG_CHECK_MODULES(GRAPHITE2, $GRAPHITE2_DEPS, have_graphite2=true, :)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2018-10-19 23:02:01 UTC (rev 48949)
@@ -13,7 +13,7 @@
 check_PROGRAMS =
 
 # Convenience targets:
-lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la
+lib: $(BUILT_SOURCES) libharfbuzz.la
 libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES)
 fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la
 
@@ -29,11 +29,9 @@
 HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
 HBHEADERS = $(HB_BASE_headers)
 
-if HAVE_OT
 HBSOURCES += $(HB_OT_sources)
 HBSOURCES += $(HB_OT_RAGEL_GENERATED_sources)
 HBHEADERS += $(HB_OT_headers)
-endif
 
 if HAVE_FALLBACK
 HBSOURCES += $(HB_FALLBACK_sources)
@@ -289,13 +287,16 @@
 
 GENERATORS = \
 	gen-arabic-table.py \
+	gen-def.py \
+	gen-emoji-table.py \
 	gen-indic-table.py \
+	gen-os2-unicode-ranges.py \
+	gen-tag-table.py \
 	gen-use-table.py \
-	gen-def.py \
 	$(NULL)
 EXTRA_DIST += $(GENERATORS)
 
-unicode-tables: arabic-table indic-table use-table
+unicode-tables: arabic-table indic-table tag-table use-table emoji-table
 
 arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
 	$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \
@@ -305,13 +306,21 @@
 	$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \
 	|| ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false)
 
+tag-table: gen-tag-table.py languagetags language-subtag-registry
+	$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-tag-table.hh \
+	|| ($(RM) $(srcdir)/hb-ot-tag-table.hh; false)
+
 use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
 	$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
 	|| ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
 
+emoji-table: gen-emoji-table.py emoji-data.txt
+	$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
+	|| ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
+
 built-sources: $(BUILT_SOURCES)
 
-.PHONY: unicode-tables arabic-table indic-table use-table built-sources
+.PHONY: unicode-tables arabic-table indic-table tag-table use-table emoji-table built-sources
 
 RAGEL_GENERATED = \
 	$(patsubst %,$(srcdir)/%,$(HB_BASE_RAGEL_GENERATED_sources)) \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2018-10-19 23:02:01 UTC (rev 48949)
@@ -7,6 +7,7 @@
 	hb-buffer.hh \
 	hb-buffer-serialize.cc \
 	hb-buffer.cc \
+	hb-cache.hh \
 	hb-common.cc \
 	hb-debug.hh \
 	hb-dsalgs.hh \
@@ -37,6 +38,7 @@
 	hb-ot-os2-unicode-ranges.hh \
 	hb-ot-post-macroman.hh \
 	hb-ot-post-table.hh \
+	hb-ot-tag-table.hh \
 	hb-ot-tag.cc \
 	hb.hh \
 	hb-set-digest.hh \
@@ -52,6 +54,7 @@
 	hb-static.cc \
 	hb-string-array.hh \
 	hb-unicode.hh \
+	hb-unicode-emoji-table.hh \
 	hb-unicode.cc \
 	hb-vector.hh \
 	hb-utf.hh \
@@ -136,7 +139,6 @@
 	hb-ot-shape-complex-myanmar.hh \
 	hb-ot-shape-complex-myanmar.cc \
 	hb-ot-shape-complex-thai.cc \
-	hb-ot-shape-complex-tibetan.cc \
 	hb-ot-shape-complex-use.cc \
 	hb-ot-shape-complex-use.hh \
 	hb-ot-shape-complex-use-table.cc \
@@ -171,6 +173,7 @@
 	hb-ot-font.h \
 	hb-ot-layout.h \
 	hb-ot-math.h \
+	hb-ot-name.h \
 	hb-ot-shape.h \
 	hb-ot-tag.h \
 	hb-ot-var.h \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -7,7 +7,6 @@
 test -z "$libs" && libs=.libs
 stat=0
 
-
 if which objdump 2>/dev/null >/dev/null; then
 	:
 else
@@ -31,7 +30,8 @@
 
 echo "Checking that no object file has lazy static C++ constructors/destructors or other such stuff"
 for obj in $OBJS; do
-	if objdump -t "$obj" | grep '__cxa_'; then
+	if objdump -t "$obj" | grep -q '__cxa_' && ! objdump -t "$obj" | grep -q __ubsan_handle; then
+		objdump -t "$obj" | grep '__cxa_'
 		echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff"
 		stat=1
 	fi

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -26,7 +26,7 @@
 		symprefix=
 		if test $suffix = dylib; then symprefix=_; fi
 
-		EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`"
+		EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRST] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`"
 
 		prefix=$symprefix`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'`
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -45,8 +45,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 
-void cbdt_callback (const uint8_t* data, unsigned int length,
-                    unsigned int group, unsigned int gid)
+static void cbdt_callback (const uint8_t* data, unsigned int length,
+			   unsigned int group, unsigned int gid)
 {
   char output_path[255];
   sprintf (output_path, "out/cbdt-%d-%d.png", group, gid);
@@ -55,8 +55,8 @@
   fclose (f);
 }
 
-void sbix_callback (const uint8_t* data, unsigned int length,
-                    unsigned int group, unsigned int gid)
+static void sbix_callback (const uint8_t* data, unsigned int length,
+			   unsigned int group, unsigned int gid)
 {
   char output_path[255];
   sprintf (output_path, "out/sbix-%d-%d.png", group, gid);
@@ -65,8 +65,8 @@
   fclose (f);
 }
 
-void svg_callback (const uint8_t* data, unsigned int length,
-                   unsigned int start_glyph, unsigned int end_glyph)
+static void svg_callback (const uint8_t* data, unsigned int length,
+			  unsigned int start_glyph, unsigned int end_glyph)
 {
   char output_path[255];
   if (start_glyph == end_glyph)
@@ -83,8 +83,8 @@
   fclose (f);
 }
 
-void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs,
-			  const OT::COLR *colr, const OT::CPAL *cpal)
+static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs,
+				 const OT::COLR *colr, const OT::CPAL *cpal)
 {
   for (unsigned int i = 0; i < num_glyphs; ++i)
   {
@@ -146,7 +146,7 @@
 	  int r = (color >> 8) & 0xFF;
 	  int g = (color >> 16) & 0xFF;
 	  int b = (color >> 24) & 0xFF;
-	  cairo_set_source_rgba (cr, r / 255.f, g / 255.f, b / 255.f, alpha);
+	  cairo_set_source_rgba (cr, r / 255., g / 255., b / 255., alpha);
 
 	  cairo_glyph_t glyph;
 	  glyph.index = glyph_id;
@@ -162,7 +162,8 @@
   }
 }
 
-void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs)
+static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
+			 unsigned int num_glyphs)
 {
   // Dump every glyph available on the font
   return; // disabled for now
@@ -210,10 +211,29 @@
 int main (int argc, char **argv)
 {
   if (argc != 2) {
-    fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
+    fprintf (stderr, "usage: %s font-file.ttf\n"
+		     "run it like `rm -rf out && mkdir out && %s font-file.ttf`\n",
+		     argv[0], argv[0]);
     exit (1);
   }
 
+
+  FILE *font_name_file = fopen ("out/_font_name_file.txt", "r");
+  if (font_name_file != nullptr)
+  {
+    fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n");
+    exit (1);
+  }
+
+  font_name_file = fopen ("out/_font_name_file.txt", "w");
+  if (font_name_file == nullptr)
+  {
+    fprintf (stderr, "./out is not accessible, create it please\n");
+    exit (1);
+  }
+  fwrite (argv[1], 1, strlen (argv[1]), font_name_file);
+  fclose (font_name_file);
+
   hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
   hb_face_t *face = hb_face_create (blob, 0);
   hb_font_t *font = hb_font_create (face);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-khmer-data.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-khmer-data.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-khmer-data.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -34,10 +34,8 @@
     hb_glyph_info_t info;
     info.codepoint = u;
     set_khmer_properties (info);
-    if (info.khmer_category() != INDIC_SYLLABIC_CATEGORY_OTHER ||
-	info.khmer_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE)
-      printf("U+%04X	%u	%u\n", u,
-	     info.khmer_category(),
-	     info.khmer_position());
+    if (info.khmer_category() != INDIC_SYLLABIC_CATEGORY_OTHER)
+      printf("U+%04X	%u\n", u,
+	     info.khmer_category());
   }
 }

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py	2018-10-19 23:02:01 UTC (rev 48949)
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+
+from __future__ import print_function, division, absolute_import
+import sys
+import os.path
+from collections import OrderedDict
+
+if len (sys.argv) != 2:
+	print("usage: ./gen-emoji-table.py emoji-data.txt", file=sys.stderr)
+	sys.exit (1)
+
+f = open(sys.argv[1])
+header = [f.readline () for _ in range(10)]
+
+sets = OrderedDict()
+for line in f.readlines():
+	line = line.strip()
+	if not line or line[0] == '#':
+		continue
+	rang, typ = [s.strip() for s in line.split('#')[0].split(';')[:2]]
+
+	rang = [int(s, 16) for s in rang.split('..')]
+	if len(rang) > 1:
+		start, end = rang
+	else:
+		start = end = rang[0]
+
+	if typ not in sets:
+		sets[typ] = set()
+	sets[typ].add((start, end))
+
+
+
+print ("/* == Start of generated table == */")
+print ("/*")
+print (" * The following tables are generated by running:")
+print (" *")
+print (" *   ./gen-emoji-table.py emoji-data.txt")
+print (" *")
+print (" * on file with this header:")
+print (" *")
+for l in header:
+	print (" * %s" % (l.strip()))
+print (" */")
+print ()
+print ("#ifndef HB_UNICODE_EMOJI_TABLE_HH")
+print ("#define HB_UNICODE_EMOJI_TABLE_HH")
+print ()
+print ('#include "hb-unicode.hh"')
+print ()
+
+for typ,s in sets.items():
+	if typ != "Extended_Pictographic": continue
+	print()
+	print("static const struct hb_unicode_range_t _hb_unicode_emoji_%s_table[] =" % typ)
+	print("{")
+	for pair in sorted(s):
+		print("  {0x%04X, 0x%04X}," % pair)
+	print("};")
+
+print ()
+print ("#endif /* HB_UNICODE_EMOJI_TABLE_HH */")
+print ()
+print ("/* == End of generated table == */")

Added: 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	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py	2018-10-19 23:02:01 UTC (rev 48949)
@@ -0,0 +1,54 @@
+# -*- 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).
+
+from __future__ import print_function, division, absolute_import
+
+import io
+import re
+import sys
+
+reload(sys)
+sys.setdefaultencoding('utf-8')
+
+print ("""static OS2Range _hb_os2_unicode_ranges[] =
+{""")
+
+args = sys.argv[1:]
+input_file = args[0]
+
+with io.open(input_file, mode="r", encoding="utf-8") as f:
+
+  all_ranges = [];
+  current_bit = 0
+  while True:
+    line = f.readline().strip()
+    if not line:
+      break
+    fields = re.split(r'\t+', line)
+    if len(fields) == 3:
+      current_bit = fields[0]
+      fields = fields[1:]
+    elif len(fields) > 3:
+      raise Error("bad input :(.")
+
+    name = fields[0]
+    ranges = re.split("-", fields[1])
+    if len(ranges) != 2:
+      raise Error("bad input :(.")
+
+    v = tuple((int(ranges[0], 16), int(ranges[1], 16), int(current_bit), name))
+    all_ranges.append(v)
+
+all_ranges = sorted(all_ranges, key=lambda t: t[0])
+
+for ranges in all_ranges:
+  start = ("0x%X" % ranges[0]).rjust(8)
+  end = ("0x%X" % ranges[1]).rjust(8)
+  bit = ("%s" % ranges[2]).rjust(3)
+
+  print ("  {%s, %s, %s}, // %s" % (start, end, bit, ranges[3]))
+
+print ("""};""")

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	2018-10-19 23:02:01 UTC (rev 48949)
@@ -0,0 +1,1126 @@
+#!/usr/bin/python
+
+"""Generator of the mapping from OpenType tags to BCP 47 tags and vice
+versa.
+
+It creates a ``const LangTag[]``, matching the tags from the OpenType
+languages system tag list to the language subtags of the BCP 47 language
+subtag registry, with some manual adjustments. The mappings are
+supplemented with macrolanguages' sublanguages and retired codes'
+replacements, according to BCP 47 and some manual additions where BCP 47
+omits a retired code entirely.
+
+Also generated is a function, ``hb_ot_ambiguous_tag_to_language``,
+intended for use by ``hb_ot_tag_to_language``. It maps OpenType tags
+back to BCP 47 tags. Ambiguous OpenType tags (those that correspond to
+multiple BCP 47 tags) are listed here, except when the alphabetically
+first BCP 47 tag happens to be the chosen disambiguated tag. In that
+case, the fallback behavior will choose the right tag anyway.
+"""
+
+from __future__ import absolute_import, division, print_function, unicode_literals
+
+import collections
+try:
+	from HTMLParser import HTMLParser
+	def write (s):
+		print (s.encode ('utf-8'), end='')
+except ImportError:
+	from html.parser import HTMLParser
+	def write (s):
+		sys.stdout.flush ()
+		sys.stdout.buffer.write (s.encode ('utf-8'))
+import io
+import itertools
+import re
+import sys
+import unicodedata
+
+if len (sys.argv) != 3:
+	print ('usage: ./gen-tag-table.py languagetags language-subtag-registry', file=sys.stderr)
+	sys.exit (1)
+
+try:
+	from html import unescape
+	def html_unescape (parser, entity):
+		return unescape (entity)
+except ImportError:
+	def html_unescape (parser, entity):
+		return parser.unescape (entity)
+
+def expect (condition, message=None):
+	if not condition:
+		if message is None:
+			raise AssertionError
+		raise AssertionError (message)
+
+# from http://www-01.sil.org/iso639-3/iso-639-3.tab
+ISO_639_3_TO_1 = {
+	'aar': 'aa',
+	'abk': 'ab',
+	'afr': 'af',
+	'aka': 'ak',
+	'amh': 'am',
+	'ara': 'ar',
+	'arg': 'an',
+	'asm': 'as',
+	'ava': 'av',
+	'ave': 'ae',
+	'aym': 'ay',
+	'aze': 'az',
+	'bak': 'ba',
+	'bam': 'bm',
+	'bel': 'be',
+	'ben': 'bn',
+	'bis': 'bi',
+	'bod': 'bo',
+	'bos': 'bs',
+	'bre': 'br',
+	'bul': 'bg',
+	'cat': 'ca',
+	'ces': 'cs',
+	'cha': 'ch',
+	'che': 'ce',
+	'chu': 'cu',
+	'chv': 'cv',
+	'cor': 'kw',
+	'cos': 'co',
+	'cre': 'cr',
+	'cym': 'cy',
+	'dan': 'da',
+	'deu': 'de',
+	'div': 'dv',
+	'dzo': 'dz',
+	'ell': 'el',
+	'eng': 'en',
+	'epo': 'eo',
+	'est': 'et',
+	'eus': 'eu',
+	'ewe': 'ee',
+	'fao': 'fo',
+	'fas': 'fa',
+	'fij': 'fj',
+	'fin': 'fi',
+	'fra': 'fr',
+	'fry': 'fy',
+	'ful': 'ff',
+	'gla': 'gd',
+	'gle': 'ga',
+	'glg': 'gl',
+	'glv': 'gv',
+	'grn': 'gn',
+	'guj': 'gu',
+	'hat': 'ht',
+	'hau': 'ha',
+	'hbs': 'sh',
+	'heb': 'he',
+	'her': 'hz',
+	'hin': 'hi',
+	'hmo': 'ho',
+	'hrv': 'hr',
+	'hun': 'hu',
+	'hye': 'hy',
+	'ibo': 'ig',
+	'ido': 'io',
+	'iii': 'ii',
+	'iku': 'iu',
+	'ile': 'ie',
+	'ina': 'ia',
+	'ind': 'id',
+	'ipk': 'ik',
+	'isl': 'is',
+	'ita': 'it',
+	'jav': 'jv',
+	'jpn': 'ja',
+	'kal': 'kl',
+	'kan': 'kn',
+	'kas': 'ks',
+	'kat': 'ka',
+	'kau': 'kr',
+	'kaz': 'kk',
+	'khm': 'km',
+	'kik': 'ki',
+	'kin': 'rw',
+	'kir': 'ky',
+	'kom': 'kv',
+	'kon': 'kg',
+	'kor': 'ko',
+	'kua': 'kj',
+	'kur': 'ku',
+	'lao': 'lo',
+	'lat': 'la',
+	'lav': 'lv',
+	'lim': 'li',
+	'lin': 'ln',
+	'lit': 'lt',
+	'ltz': 'lb',
+	'lub': 'lu',
+	'lug': 'lg',
+	'mah': 'mh',
+	'mal': 'ml',
+	'mar': 'mr',
+	'mkd': 'mk',
+	'mlg': 'mg',
+	'mlt': 'mt',
+	'mol': 'mo',
+	'mon': 'mn',
+	'mri': 'mi',
+	'msa': 'ms',
+	'mya': 'my',
+	'nau': 'na',
+	'nav': 'nv',
+	'nbl': 'nr',
+	'nde': 'nd',
+	'ndo': 'ng',
+	'nep': 'ne',
+	'nld': 'nl',
+	'nno': 'nn',
+	'nob': 'nb',
+	'nor': 'no',
+	'nya': 'ny',
+	'oci': 'oc',
+	'oji': 'oj',
+	'ori': 'or',
+	'orm': 'om',
+	'oss': 'os',
+	'pan': 'pa',
+	'pli': 'pi',
+	'pol': 'pl',
+	'por': 'pt',
+	'pus': 'ps',
+	'que': 'qu',
+	'roh': 'rm',
+	'ron': 'ro',
+	'run': 'rn',
+	'rus': 'ru',
+	'sag': 'sg',
+	'san': 'sa',
+	'sin': 'si',
+	'slk': 'sk',
+	'slv': 'sl',
+	'sme': 'se',
+	'smo': 'sm',
+	'sna': 'sn',
+	'snd': 'sd',
+	'som': 'so',
+	'sot': 'st',
+	'spa': 'es',
+	'sqi': 'sq',
+	'srd': 'sc',
+	'srp': 'sr',
+	'ssw': 'ss',
+	'sun': 'su',
+	'swa': 'sw',
+	'swe': 'sv',
+	'tah': 'ty',
+	'tam': 'ta',
+	'tat': 'tt',
+	'tel': 'te',
+	'tgk': 'tg',
+	'tgl': 'tl',
+	'tha': 'th',
+	'tir': 'ti',
+	'ton': 'to',
+	'tsn': 'tn',
+	'tso': 'ts',
+	'tuk': 'tk',
+	'tur': 'tr',
+	'twi': 'tw',
+	'uig': 'ug',
+	'ukr': 'uk',
+	'urd': 'ur',
+	'uzb': 'uz',
+	'ven': 've',
+	'vie': 'vi',
+	'vol': 'vo',
+	'wln': 'wa',
+	'wol': 'wo',
+	'xho': 'xh',
+	'yid': 'yi',
+	'yor': 'yo',
+	'zha': 'za',
+	'zho': 'zh',
+	'zul': 'zu',
+}
+
+class LanguageTag (object):
+	"""A BCP 47 language tag.
+
+	Attributes:
+		subtags (List[str]): The list of subtags in this tag.
+		grandfathered (bool): Whether this tag is grandfathered. If
+			``true``, the entire lowercased tag is the ``language``
+			and the other subtag fields are empty.
+		language (str): The language subtag.
+		script (str): The script subtag.
+		region (str): The region subtag.
+		variant (str): The variant subtag.
+
+	Args:
+		tag (str): A BCP 47 language tag.
+
+	"""
+	def __init__ (self, tag):
+		global bcp_47
+		self.subtags = tag.lower ().split ('-')
+		self.grandfathered = tag.lower () in bcp_47.grandfathered
+		if self.grandfathered:
+			self.language = tag.lower ()
+			self.script = ''
+			self.region = ''
+			self.variant = ''
+		else:
+			self.language = self.subtags[0]
+			self.script = self._find_first (lambda s: len (s) == 4 and s[0] > '9', self.subtags)
+			self.region = self._find_first (lambda s: len (s) == 2 and s[0] > '9' or len (s) == 3 and s[0] <= '9', self.subtags[1:])
+			self.variant = self._find_first (lambda s: len (s) > 4 or len (s) == 4 and s[0] <= '9', self.subtags)
+
+	def __str__(self):
+		return '-'.join(self.subtags)
+
+	def __repr__ (self):
+		return 'LanguageTag(%r)' % str(self)
+
+	@staticmethod
+	def _find_first (function, sequence):
+		try:
+			return next (iter (filter (function, sequence)))
+		except StopIteration:
+			return None
+
+	def is_complex (self):
+		"""Return whether this tag is too complex to represent as a
+		``LangTag`` in the generated code.
+
+		Complex tags need to be handled in
+		``hb_ot_tags_from_complex_language``.
+
+		Returns:
+			Whether this tag is complex.
+		"""
+		return not (len (self.subtags) == 1
+			or self.grandfathered
+			and len (self.subtags[1]) != 3
+			and ot.from_bcp_47[self.subtags[0]] == ot.from_bcp_47[self.language])
+
+	def get_group (self):
+		"""Return the group into which this tag should be categorized in
+		``hb_ot_tags_from_complex_language``.
+
+		The group is the first letter of the tag, or ``'und'`` if this tag
+		should not be matched in a ``switch`` statement in the generated
+		code.
+
+		Returns:
+			This tag's group.
+		"""
+		return ('und'
+			if (self.language == 'und'
+				or self.variant in bcp_47.prefixes and len (bcp_47.prefixes[self.variant]) == 1)
+			else self.language[0])
+
+class OpenTypeRegistryParser (HTMLParser):
+	"""A parser for the OpenType language system tag registry.
+
+	Attributes:
+		header (str): The "last updated" line of the registry.
+		names (Mapping[str, str]): A map of language system tags to the
+			names they are given in the registry.
+		ranks (DefaultDict[str, int]): A map of language system tags to
+			numbers. If a single BCP 47 tag corresponds to multiple
+			OpenType tags, the tags are ordered in increasing order by
+			rank. The rank is based on the number of BCP 47 tags
+			associated with a tag, though it may be manually modified.
+		to_bcp_47 (DefaultDict[str, AbstractSet[str]]): A map of
+			OpenType language system tags to sets of BCP 47 tags.
+		from_bcp_47 (DefaultDict[str, AbstractSet[str]]): ``to_bcp_47``
+			inverted. Its values start as unsorted sets;
+			``sort_languages`` converts them to sorted lists.
+
+	"""
+	def __init__ (self):
+		HTMLParser.__init__ (self)
+		self.header = ''
+		self.names = {}
+		self.ranks = collections.defaultdict (int)
+		self.to_bcp_47 = collections.defaultdict (set)
+		self.from_bcp_47 = collections.defaultdict (set)
+		# Whether the parser is in a <td> element
+		self._td = False
+		# The text of the <td> elements of the current <tr> element.
+		self._current_tr = []
+
+	def handle_starttag (self, tag, attrs):
+		if tag == 'meta':
+			for attr, value in attrs:
+				if attr == 'name' and value == 'updated_at':
+					self.header = self.get_starttag_text ()
+					break
+		elif tag == 'td':
+			self._td = True
+			self._current_tr.append ('')
+		elif tag == 'tr':
+			self._current_tr = []
+
+	def handle_endtag (self, tag):
+		if tag == 'td':
+			self._td = False
+		elif tag == 'tr' and self._current_tr:
+			expect (2 <= len (self._current_tr) <= 3)
+			name = self._current_tr[0].strip ()
+			tag = self._current_tr[1].strip ("\t\n\v\f\r '")
+			rank = 0
+			if len (tag) > 4:
+				expect (tag.endswith (' (deprecated)'), 'ill-formed OpenType tag: %s' % tag)
+				name += ' (deprecated)'
+				tag = tag.split (' ')[0]
+				rank = 1
+			self.names[tag] = re.sub (' languages$', '', name)
+			if not self._current_tr[2]:
+				return
+			iso_codes = self._current_tr[2].strip ()
+			self.to_bcp_47[tag].update (ISO_639_3_TO_1.get (code, code) for code in iso_codes.replace (' ', '').split (','))
+			rank += 2 * len (self.to_bcp_47[tag])
+			self.ranks[tag] = rank
+
+	def handle_data (self, data):
+		if self._td:
+			self._current_tr[-1] += data
+
+	def handle_charref (self, name):
+		self.handle_data (html_unescape (self, '&#%s;' % name))
+
+	def handle_entityref (self, name):
+		self.handle_data (html_unescape (self, '&%s;' % name))
+
+	def parse (self, filename):
+		"""Parse the OpenType language system tag registry.
+
+		Args:
+			filename (str): The file name of the registry.
+		"""
+		with io.open (filename, encoding='utf-8') as f:
+			self.feed (f.read ())
+		expect (self.header)
+		for tag, iso_codes in self.to_bcp_47.items ():
+			for iso_code in iso_codes:
+				self.from_bcp_47[iso_code].add (tag)
+
+	def add_language (self, bcp_47_tag, ot_tag):
+		"""Add a language as if it were in the registry.
+
+		Args:
+			bcp_47_tag (str): A BCP 47 tag. If the tag is more than just
+				a language subtag, and if the language subtag is a
+				macrolanguage, then new languages are added corresponding
+				to the macrolanguages' individual languages with the
+				remainder of the tag appended.
+			ot_tag (str): An OpenType language system tag.
+		"""
+		global bcp_47
+		self.to_bcp_47[ot_tag].add (bcp_47_tag)
+		self.from_bcp_47[bcp_47_tag].add (ot_tag)
+		if bcp_47_tag.lower () not in bcp_47.grandfathered:
+			try:
+				[macrolanguage, suffix] = bcp_47_tag.split ('-', 1)
+				if macrolanguage in bcp_47.macrolanguages:
+					s = set ()
+					for language in bcp_47.macrolanguages[macrolanguage]:
+						if language.lower () not in bcp_47.grandfathered:
+							s.add ('%s-%s' % (language, suffix))
+					bcp_47.macrolanguages['%s-%s' % (macrolanguage, suffix)] = s
+			except ValueError:
+				pass
+
+	@staticmethod
+	def _remove_language (tag_1, dict_1, dict_2):
+		for tag_2 in dict_1.pop (tag_1):
+			dict_2[tag_2].remove (tag_1)
+			if not dict_2[tag_2]:
+				del dict_2[tag_2]
+
+	def remove_language_ot (self, ot_tag):
+		"""Remove an OpenType tag from the registry.
+
+		Args:
+			ot_tag (str): An OpenType tag.
+		"""
+		self._remove_language (ot_tag, self.to_bcp_47, self.from_bcp_47)
+
+	def remove_language_bcp_47 (self, bcp_47_tag):
+		"""Remove a BCP 47 tag from the registry.
+
+		Args:
+			bcp_47_tag (str): A BCP 47 tag.
+		"""
+		self._remove_language (bcp_47_tag, self.from_bcp_47, self.to_bcp_47)
+
+	def inherit_from_macrolanguages (self):
+		"""Copy mappings from macrolanguages to individual languages.
+
+		If a BCP 47 tag for an individual mapping has no OpenType
+		mapping but its macrolanguage does, the mapping is copied to
+		the individual language. For example, als (Tosk Albanian) has no
+		explicit mapping, so it inherits from sq (Albanian) the mapping
+		to SQI.
+
+		If a BCP 47 tag for a macrolanguage has no OpenType mapping but
+		all of its individual languages do and they all map to the same
+		tags, the mapping is copied to the macrolanguage.
+		"""
+		global bcp_47
+		original_ot_from_bcp_47 = dict (self.from_bcp_47)
+		for macrolanguage, languages in dict (bcp_47.macrolanguages).items ():
+			ot_macrolanguages = set (original_ot_from_bcp_47.get (macrolanguage, set ()))
+			if ot_macrolanguages:
+				for ot_macrolanguage in ot_macrolanguages:
+					for language in languages:
+						# Remove the following condition if e.g. nn should map to NYN,NOR
+						# instead of just NYN.
+						if language not in original_ot_from_bcp_47:
+							self.add_language (language, ot_macrolanguage)
+							self.ranks[ot_macrolanguage] += 1
+			else:
+				for language in languages:
+					if language in original_ot_from_bcp_47:
+						if ot_macrolanguages:
+							ml = original_ot_from_bcp_47[language]
+							if ml:
+								ot_macrolanguages &= ml
+							else:
+								pass
+						else:
+							ot_macrolanguages |= original_ot_from_bcp_47[language]
+					else:
+						ot_macrolanguages.clear ()
+					if not ot_macrolanguages:
+						break
+				for ot_macrolanguage in ot_macrolanguages:
+					self.add_language (macrolanguage, ot_macrolanguage)
+
+	def sort_languages (self):
+		"""Sort the values of ``from_bcp_47`` in ascending rank order."""
+		for language, tags in self.from_bcp_47.items ():
+			self.from_bcp_47[language] = sorted (tags,
+					key=lambda t: (self.ranks[t] + rank_delta (language, t), t))
+
+ot = OpenTypeRegistryParser ()
+
+class BCP47Parser (object):
+	"""A parser for the BCP 47 subtag registry.
+
+	Attributes:
+		header (str): The "File-Date" line of the registry.
+		names (Mapping[str, str]): A map of subtags to the names they
+			are given in the registry. Each value is a
+			``'\\n'``-separated list of names.
+		scopes (Mapping[str, str]): A map of language subtags to strings
+			suffixed to language names, including suffixes to explain
+			language scopes.
+		macrolanguages (DefaultDict[str, AbstractSet[str]]): A map of
+			language subtags to the sets of language subtags which
+			inherit from them. See
+			``OpenTypeRegistryParser.inherit_from_macrolanguages``.
+		prefixes (DefaultDict[str, AbstractSet[str]]): A map of variant
+			subtags to their prefixes.
+		grandfathered (AbstractSet[str]): The set of grandfathered tags,
+			normalized to lowercase.
+
+	"""
+	def __init__ (self):
+		self.header = ''
+		self.names = {}
+		self.scopes = {}
+		self.macrolanguages = collections.defaultdict (set)
+		self.prefixes = collections.defaultdict (set)
+		self.grandfathered = set ()
+
+	def parse (self, filename):
+		"""Parse the BCP 47 subtag registry.
+
+		Args:
+			filename (str): The file name of the registry.
+		"""
+		with io.open (filename, encoding='utf-8') as f:
+			subtag_type = None
+			subtag = None
+			deprecated = False
+			has_preferred_value = False
+			line_buffer = ''
+			for line in itertools.chain (f, ['']):
+				line = line.rstrip ()
+				if line.startswith (' '):
+					line_buffer += line[1:]
+					continue
+				line, line_buffer = line_buffer, line
+				if line.startswith ('Type: '):
+					subtag_type = line.split (' ')[1]
+					deprecated = False
+					has_preferred_value = False
+				elif line.startswith ('Subtag: ') or line.startswith ('Tag: '):
+					subtag = line.split (' ')[1]
+					if subtag_type == 'grandfathered':
+						self.grandfathered.add (subtag.lower ())
+				elif line.startswith ('Description: '):
+					description = line.split (' ', 1)[1].replace (' (individual language)', '')
+					description = re.sub (' (\((individual |macro)language\)|languages)$', '',
+							description)
+					if subtag in self.names:
+						self.names[subtag] += '\n' + description
+					else:
+						self.names[subtag] = description
+				elif subtag_type == 'language' or subtag_type == 'grandfathered':
+					if line.startswith ('Scope: '):
+						scope = line.split (' ')[1]
+						if scope == 'macrolanguage':
+							scope = ' [macrolanguage]'
+						elif scope == 'collection':
+							scope = ' [family]'
+						else:
+							continue
+						self.scopes[subtag] = scope
+					elif line.startswith ('Deprecated: '):
+						self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '')
+						deprecated = True
+					elif deprecated and line.startswith ('Comments: see '):
+						# If a subtag is split into multiple replacement subtags,
+						# it essentially represents a macrolanguage.
+						for language in line.replace (',', '').split (' ')[2:]:
+							self._add_macrolanguage (subtag, language)
+					elif line.startswith ('Preferred-Value: '):
+						# If a subtag is deprecated in favor of a single replacement subtag,
+						# it is either a dialect or synonym of the preferred subtag. Either
+						# way, it is close enough to the truth to consider the replacement
+						# the macrolanguage of the deprecated language.
+						has_preferred_value = True
+						macrolanguage = line.split (' ')[1]
+						self._add_macrolanguage (macrolanguage, subtag)
+					elif not has_preferred_value and line.startswith ('Macrolanguage: '):
+						self._add_macrolanguage (line.split (' ')[1], subtag)
+				elif subtag_type == 'variant':
+					if line.startswith ('Prefix: '):
+						self.prefixes[subtag].add (line.split (' ')[1])
+				elif line.startswith ('File-Date: '):
+					self.header = line
+		expect (self.header)
+
+	def _add_macrolanguage (self, macrolanguage, language):
+		global ot
+		if language not in ot.from_bcp_47:
+			for l in self.macrolanguages.get (language, set ()):
+				self._add_macrolanguage (macrolanguage, l)
+		if macrolanguage not in ot.from_bcp_47:
+			for ls in list (self.macrolanguages.values ()):
+				if macrolanguage in ls:
+					ls.add (language)
+					return
+		self.macrolanguages[macrolanguage].add (language)
+
+	def remove_extra_macrolanguages (self):
+		"""Make every language have at most one macrolanguage."""
+		inverted = collections.defaultdict (list)
+		for macrolanguage, languages in self.macrolanguages.items ():
+			for language in languages:
+				inverted[language].append (macrolanguage)
+		for language, macrolanguages in inverted.items ():
+			if len (macrolanguages) > 1:
+				macrolanguages.sort (key=lambda ml: len (self.macrolanguages[ml]))
+				biggest_macrolanguage = macrolanguages.pop ()
+				for macrolanguage in macrolanguages:
+					self._add_macrolanguage (biggest_macrolanguage, macrolanguage)
+
+	def get_name (self, lt):
+		"""Return the names of the subtags in a language tag.
+
+		Args:
+			lt (LanguageTag): A BCP 47 language tag.
+
+		Returns:
+			The name form of ``lt``.
+		"""
+		name = self.names[lt.language].split ('\n')[0]
+		if lt.script:
+			name += '; ' + self.names[lt.script.title ()].split ('\n')[0]
+		if lt.region:
+			name += '; ' + self.names[lt.region.upper ()].split ('\n')[0]
+		if lt.variant:
+			name += '; ' + self.names[lt.variant].split ('\n')[0]
+		return name
+
+bcp_47 = BCP47Parser ()
+
+ot.parse (sys.argv[1])
+bcp_47.parse (sys.argv[2])
+
+ot.add_language ('ary', 'MOR')
+
+ot.add_language ('ath', 'ATH')
+
+ot.add_language ('bai', 'BML')
+
+ot.ranks['BAL'] = ot.ranks['KAR'] + 1
+
+ot.add_language ('ber', 'BBR')
+
+ot.remove_language_ot ('PGR')
+ot.add_language ('el-polyton', 'PGR')
+
+bcp_47.macrolanguages['et'] = {'ekk'}
+
+bcp_47.names['flm'] = 'Falam Chin'
+bcp_47.scopes['flm'] = ' (retired code)'
+bcp_47.macrolanguages['flm'] = {'cfm'}
+
+ot.ranks['FNE'] = ot.ranks['TNE'] + 1
+
+ot.add_language ('und-fonipa', 'IPPH')
+
+ot.add_language ('und-fonnapa', 'APPH')
+
+ot.remove_language_ot ('IRT')
+ot.add_language ('ga-Latg', 'IRT')
+
+ot.remove_language_ot ('KGE')
+ot.add_language ('und-Geok', 'KGE')
+
+ot.add_language ('guk', 'GUK')
+ot.names['GUK'] = 'Gumuz (SIL fonts)'
+ot.ranks['GUK'] = ot.ranks['GMZ'] + 1
+
+bcp_47.macrolanguages['id'] = {'in'}
+
+bcp_47.macrolanguages['ijo'] = {'ijc'}
+
+ot.add_language ('kht', 'KHN')
+ot.names['KHN'] = ot.names['KHT'] + ' (Microsoft fonts)'
+ot.names['KHT'] = ot.names['KHT'] + ' (OpenType spec and SIL fonts)'
+ot.ranks['KHN'] = ot.ranks['KHT']
+ot.ranks['KHT'] += 1
+
+ot.ranks['LCR'] = ot.ranks['MCR'] + 1
+
+ot.names['MAL'] = 'Malayalam Traditional'
+ot.ranks['MLR'] += 1
+
+bcp_47.names['mhv'] = 'Arakanese'
+bcp_47.scopes['mhv'] = ' (retired code)'
+
+ot.add_language ('no', 'NOR')
+
+ot.add_language ('oc-provenc', 'PRO')
+
+ot.add_language ('qu', 'QUZ')
+ot.add_language ('qub', 'QWH')
+ot.add_language ('qud', 'QVI')
+ot.add_language ('qug', 'QVI')
+ot.add_language ('qup', 'QVI')
+ot.add_language ('qur', 'QWH')
+ot.add_language ('qus', 'QUH')
+ot.add_language ('quw', 'QVI')
+ot.add_language ('qux', 'QWH')
+ot.add_language ('qva', 'QWH')
+ot.add_language ('qvh', 'QWH')
+ot.add_language ('qvj', 'QVI')
+ot.add_language ('qvl', 'QWH')
+ot.add_language ('qvm', 'QWH')
+ot.add_language ('qvn', 'QWH')
+ot.add_language ('qvo', 'QVI')
+ot.add_language ('qvp', 'QWH')
+ot.add_language ('qvw', 'QWH')
+ot.add_language ('qvz', 'QVI')
+ot.add_language ('qwa', 'QWH')
+ot.add_language ('qws', 'QWH')
+ot.add_language ('qxa', 'QWH')
+ot.add_language ('qxc', 'QWH')
+ot.add_language ('qxh', 'QWH')
+ot.add_language ('qxl', 'QVI')
+ot.add_language ('qxn', 'QWH')
+ot.add_language ('qxo', 'QWH')
+ot.add_language ('qxr', 'QVI')
+ot.add_language ('qxt', 'QWH')
+ot.add_language ('qxw', 'QWH')
+
+bcp_47.macrolanguages['ro'].remove ('mo')
+bcp_47.macrolanguages['ro-MD'].add ('mo')
+
+ot.add_language ('sgw', 'SGW')
+ot.names['SGW'] = ot.names['CHG'] + ' (SIL fonts)'
+ot.ranks['SGW'] = ot.ranks['CHG'] + 1
+
+ot.remove_language_ot ('SYRE')
+ot.remove_language_ot ('SYRJ')
+ot.remove_language_ot ('SYRN')
+ot.add_language ('und-Syre', 'SYRE')
+ot.add_language ('und-Syrj', 'SYRJ')
+ot.add_language ('und-Syrn', 'SYRN')
+
+bcp_47.names['xst'] = u"Silt'e"
+bcp_47.scopes['xst'] = ' (retired code)'
+bcp_47.macrolanguages['xst'] = {'stv', 'wle'}
+
+ot.add_language ('xwo', 'TOD')
+
+ot.remove_language_ot ('ZHH')
+ot.remove_language_ot ('ZHP')
+ot.remove_language_ot ('ZHT')
+bcp_47.macrolanguages['zh'].remove ('lzh')
+bcp_47.macrolanguages['zh'].remove ('yue')
+ot.add_language ('zh-Hant-MO', 'ZHH')
+ot.add_language ('zh-Hant-HK', 'ZHH')
+ot.add_language ('zh-Hans', 'ZHS')
+ot.add_language ('zh-Hant', 'ZHT')
+ot.add_language ('zh-HK', 'ZHH')
+ot.add_language ('zh-MO', 'ZHH')
+ot.add_language ('zh-TW', 'ZHT')
+ot.add_language ('lzh', 'ZHT')
+ot.add_language ('lzh-Hans', 'ZHS')
+ot.add_language ('yue', 'ZHH')
+ot.add_language ('yue-Hans', 'ZHS')
+
+bcp_47.macrolanguages['zom'] = {'yos'}
+
+def rank_delta (bcp_47, ot):
+	"""Return a delta to apply to a BCP 47 tag's rank.
+
+	Most OpenType tags have a constant rank, but a few have ranks that
+	depend on the BCP 47 tag.
+
+	Args:
+		bcp_47 (str): A BCP 47 tag.
+		ot (str): An OpenType tag to.
+
+	Returns:
+		A number to add to ``ot``'s rank when sorting ``bcp_47``'s
+		OpenType equivalents.
+	"""
+	if bcp_47 == 'ak' and ot == 'AKA':
+		return -1
+	if bcp_47 == 'tw' and ot == 'TWI':
+		return -1
+	return 0
+
+disambiguation = {
+	'ALT': 'alt',
+	'ARK': 'rki',
+	'BHI': 'bhb',
+	'BLN': 'bjt',
+	'BTI': 'beb',
+	'CCHN': 'cco',
+	'CMR': 'swb',
+	'CPP': 'crp',
+	'CRR': 'crx',
+	'DUJ': 'dwu',
+	'ECR': 'crj',
+	'HAL': 'cfm',
+	'HND': 'hnd',
+	'KIS': 'kqs',
+	'LRC': 'bqi',
+	'NDB': 'nd',
+	'NIS': 'njz',
+	'PLG': 'pce',
+	'PRO': 'pro',
+	'QIN': 'bgr',
+	'QUH': 'quh',
+	'QVI': 'qvi',
+	'QWH': 'qwh',
+	'SIG': 'stv',
+	'TNE': 'yrk',
+	'ZHH': 'zh-HK',
+	'ZHS': 'zh-Hans',
+	'ZHT': 'zh-Hant',
+}
+
+ot.inherit_from_macrolanguages ()
+bcp_47.remove_extra_macrolanguages ()
+ot.inherit_from_macrolanguages ()
+ot.sort_languages ()
+
+print ('/* == Start of generated table == */')
+print ('/*')
+print (' * The following table is generated by running:')
+print (' *')
+print (' *   %s languagetags language-subtag-registry' % sys.argv[0])
+print (' *')
+print (' * on files with these headers:')
+print (' *')
+print (' * %s' % ot.header.strip ())
+print (' * %s' % bcp_47.header)
+print (' */')
+print ()
+print ('#ifndef HB_OT_TAG_TABLE_HH')
+print ('#define HB_OT_TAG_TABLE_HH')
+print ()
+print ('static const LangTag ot_languages[] = {')
+
+def hb_tag (tag):
+	"""Convert a tag to ``HB_TAG`` form.
+
+	Args:
+		tag (str): An OpenType tag.
+
+	Returns:
+		A snippet of C++ representing ``tag``.
+	"""
+	return u"HB_TAG('%s','%s','%s','%s')" % tuple (('%-4s' % tag)[:4])
+
+def get_variant_set (name):
+	"""Return a set of variant language names from a name.
+
+	Args:
+		name (str): A list of language names from the BCP 47 registry,
+			joined on ``'\\n'``.
+
+	Returns:
+		A set of normalized language names.
+	"""
+	return set (unicodedata.normalize ('NFD', n.replace ('\u2019', u"'"))
+			.encode ('ASCII', 'ignore')
+			.strip ()
+			for n in re.split ('[\n(),]', name) if n)
+
+def language_name_intersection (a, b):
+	"""Return the names in common between two language names.
+
+	Args:
+		a (str): A list of language names from the BCP 47 registry,
+			joined on ``'\\n'``.
+		b (str): A list of language names from the BCP 47 registry,
+			joined on ``'\\n'``.
+
+	Returns:
+		The normalized language names shared by ``a`` and ``b``.
+	"""
+	return get_variant_set (a).intersection (get_variant_set (b))
+
+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
+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)
+	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='')
+		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])
+		scope = bcp_47.scopes.get (language, '')
+		if not intersection:
+			write ('%s%s -> %s' % (bcp_47_name_candidates[0], scope, ot.names[tag]))
+		else:
+			name = get_matching_language_name (intersection, bcp_47_name_candidates)
+			bcp_47.names[language] = name
+			write ('%s%s' % (name if len (name) > len (ot.names[tag]) else ot.names[tag], scope))
+		print (' */')
+
+print ('};')
+print ()
+print ('static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == %iu, "");' % maximum_tags)
+print ()
+
+print ('/**')
+print (' * hb_ot_tags_from_complex_language:')
+print (' * @lang_str: a BCP 47 language tag to convert.')
+print (' * @limit: a pointer to the end of the substring of @lang_str to consider for')
+print (' * conversion.')
+print (' * @count: maximum number of language tags to retrieve (IN) and actual number of')
+print (' * language tags retrieved (OUT). If no tags are retrieved, it is not modified.')
+print (' * @tags: array of size at least @language_count to store the language tag')
+print (' * results')
+print (' *')
+print (' * Converts a multi-subtag BCP 47 language tag to language tags.')
+print (' *')
+print (' * Return value: Whether any language systems were retrieved.')
+print (' **/')
+print ('static bool')
+print ('hb_ot_tags_from_complex_language (const char   *lang_str,')
+print ('\t\t\t\t  const char   *limit,')
+print ('\t\t\t\t  unsigned int *count /* IN/OUT */,')
+print ('\t\t\t\t  hb_tag_t     *tags /* OUT */)')
+print ('{')
+
+def print_subtag_matches (subtag, new_line):
+	if subtag:
+		if new_line:
+			print ()
+			print ('\t&& ', end='')
+		print ('subtag_matches (lang_str, limit, "-%s")' % subtag, end='')
+
+complex_tags = collections.defaultdict (list)
+for initial, group in itertools.groupby ((lt_tags for lt_tags in [
+			(LanguageTag (language), tags)
+			for language, tags in sorted (ot.from_bcp_47.items (),
+				key=lambda i: (-len (i[0]), i[0]))
+		] if lt_tags[0].is_complex ()),
+		key=lambda lt_tags: lt_tags[0].get_group ()):
+	complex_tags[initial] += group
+
+for initial, items in sorted (complex_tags.items ()):
+	if initial != 'und':
+		continue
+	for lt, tags in items:
+		if lt.variant in bcp_47.prefixes:
+			expect (next (iter (bcp_47.prefixes[lt.variant])) == lt.language,
+					'%s is not a valid prefix of %s' % (lt.language, lt.variant))
+		print ('  if (', end='')
+		print_subtag_matches (lt.script, False)
+		print_subtag_matches (lt.region, False)
+		print_subtag_matches (lt.variant, False)
+		print (')')
+		print ('  {')
+		write ('    /* %s */' % bcp_47.get_name (lt))
+		print ()
+		if len (tags) == 1:
+			write ('    tags[0] = %s;  /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]]))
+			print ()
+			print ('    *count = 1;')
+		else:
+			print ('    hb_tag_t possible_tags[] = {')
+			for tag in tags:
+				write ('      %s,  /* %s */' % (hb_tag (tag), ot.names[tag]))
+				print ()
+			print ('    };')
+			print ('    for (i = 0; i < %s && i < *count; i++)' % len (tags))
+			print ('      tags[i] = possible_tags[i];')
+			print ('    *count = i;')
+		print ('    return true;')
+		print ('  }')
+
+print ('  switch (lang_str[0])')
+print ('  {')
+for initial, items in sorted (complex_tags.items ()):
+	if initial == 'und':
+		continue
+	print ("  case '%s':" % initial)
+	for lt, tags in items:
+		print ('    if (', end='')
+		if lt.grandfathered:
+			print ('0 == strcmp (&lang_str[1], "%s")' % lt.language[1:], end='')
+		else:
+			string_literal = lt.language[1:] + '-'
+			if lt.script:
+				string_literal += lt.script
+				lt.script = None
+				if lt.region:
+					string_literal += '-' + lt.region
+					lt.region = None
+			if string_literal[-1] == '-':
+				print ('0 == strncmp (&lang_str[1], "%s", %i)' % (string_literal, len (string_literal)), end='')
+			else:
+				print ('lang_matches (&lang_str[1], "%s")' % string_literal, end='')
+		print_subtag_matches (lt.script, True)
+		print_subtag_matches (lt.region, True)
+		print_subtag_matches (lt.variant, True)
+		print (')')
+		print ('    {')
+		write ('      /* %s */' % bcp_47.get_name (lt))
+		print ()
+		if len (tags) == 1:
+			write ('      tags[0] = %s;  /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]]))
+			print ()
+			print ('      *count = 1;')
+		else:
+			print ('      unsigned int i;')
+			print ('      hb_tag_t possible_tags[] = {')
+			for tag in tags:
+				write ('\t%s,  /* %s */' % (hb_tag (tag), ot.names[tag]))
+				print ()
+			print ('      };')
+			print ('      for (i = 0; i < %s && i < *count; i++)' % len (tags))
+			print ('\ttags[i] = possible_tags[i];')
+			print ('      *count = i;')
+		print ('      return true;')
+		print ('    }')
+	print ('    break;')
+
+print ('  }')
+print ('  return false;')
+print ('}')
+print ()
+print ('/**')
+print (' * hb_ot_ambiguous_tag_to_language')
+print (' * @tag: A language tag.')
+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 (' *')
+print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,')
+print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.')
+print (' **/')
+print ('static hb_language_t')
+print ('hb_ot_ambiguous_tag_to_language (hb_tag_t tag)')
+print ('{')
+print ('  switch (tag)')
+print ('  {')
+
+def verify_disambiguation_dict ():
+	"""Verify and normalize ``disambiguation``.
+
+	``disambiguation`` is a map of ambiguous OpenType language system
+	tags to the particular BCP 47 tags they correspond to. This function
+	checks that all its keys really are ambiguous and that each key's
+	value is valid for that key. It checks that no ambiguous tag is
+	missing, except when it can figure out which BCP 47 tag is the best
+	by itself.
+
+	It modifies ``disambiguation`` to remove keys whose values are the
+	same as those that the fallback would return anyway, and to add
+	ambiguous keys whose disambiguations it determined automatically.
+
+	Raises:
+		AssertionError: Verification failed.
+	"""
+	global bcp_47
+	global disambiguation
+	global ot
+	for ot_tag, bcp_47_tags in ot.to_bcp_47.items ():
+		primary_tags = list (t for t in bcp_47_tags if t not in bcp_47.grandfathered and ot.from_bcp_47.get (t)[0] == ot_tag)
+		if len (primary_tags) == 1:
+			expect (ot_tag not in disambiguation, 'unnecessary disambiguation for OT tag: %s' % ot_tag)
+			if '-' in primary_tags[0]:
+				disambiguation[ot_tag] = primary_tags[0]
+		elif len (primary_tags) == 0:
+			expect (ot_tag not in disambiguation, 'There is no possible valid disambiguation for %s' % ot_tag)
+		else:
+			macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [macrolanguage]')
+			if len (macrolanguages) != 1:
+				macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [family]')
+			if len (macrolanguages) != 1:
+				macrolanguages = list (t for t in primary_tags if 'retired code' not in bcp_47.scopes.get (t, ''))
+			if len (macrolanguages) != 1:
+				expect (ot_tag in disambiguation, 'ambiguous OT tag: %s %s' % (ot_tag, str (macrolanguages)))
+				expect (disambiguation[ot_tag] in bcp_47_tags,
+						'%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]:
+				del disambiguation[ot_tag]
+	for ot_tag in disambiguation.keys ():
+		expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag)
+
+verify_disambiguation_dict ()
+for ot_tag, bcp_47_tag in sorted (disambiguation.items ()):
+	write ('  case %s:  /* %s */' % (hb_tag (ot_tag), ot.names[ot_tag]))
+	print ()
+	write ('    return hb_language_from_string (\"%s\", -1);  /* %s */' % (bcp_47_tag, bcp_47.get_name (LanguageTag (bcp_47_tag))))
+	print ()
+
+print ('  default:')
+print ('    return HB_LANGUAGE_INVALID;')
+print ('  }')
+print ('}')
+
+print ()
+print ('#endif /* HB_OT_TAG_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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2018-10-19 23:02:01 UTC (rev 48949)
@@ -8,7 +8,7 @@
 	print ("usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
 	sys.exit (1)
 
-BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"]
+BLACKLISTED_BLOCKS = ["Thai", "Lao"]
 
 files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]]
 
@@ -197,7 +197,10 @@
 def is_CONS_WITH_STACKER(U, UISC, UGC):
 	return UISC == Consonant_With_Stacker
 def is_HALANT(U, UISC, UGC):
-	return UISC in [Virama, Invisible_Stacker]
+	return UISC in [Virama, Invisible_Stacker] and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC)
+def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC):
+	# https://github.com/harfbuzz/harfbuzz/issues/1102
+	return U == 0x11046
 def is_HALANT_NUM(U, UISC, UGC):
 	return UISC == Number_Joiner
 def is_ZWNJ(U, UISC, UGC):
@@ -248,6 +251,7 @@
 	'SUB':	is_CONS_SUB,
 	'CS':	is_CONS_WITH_STACKER,
 	'H':	is_HALANT,
+	'HVM':	is_HALANT_OR_VOWEL_MODIFIER,
 	'HN':	is_HALANT_NUM,
 	'ZWNJ':	is_ZWNJ,
 	'ZWJ':	is_ZWJ,
@@ -281,8 +285,8 @@
 	'V': {
 		'Abv': [Top, Top_And_Bottom, Top_And_Bottom_And_Right, Top_And_Right],
 		'Blw': [Bottom, Overstruck, Bottom_And_Right],
-		'Pst': [Right],
-		'Pre': [Left, Top_And_Left, Top_And_Left_And_Right, Left_And_Right],
+		'Pst': [Right, Top_And_Left, Top_And_Left_And_Right, Left_And_Right],
+		'Pre': [Left],
 	},
 	'VM': {
 		'Abv': [Top],
@@ -295,6 +299,7 @@
 		'Blw': [Bottom],
 	},
 	'H': None,
+	'HVM': None,
 	'B': None,
 	'FM': None,
 	'SUB': None,
@@ -307,11 +312,28 @@
 
 		# Resolve Indic_Syllabic_Category
 
-		# TODO: These don't have UISC assigned in Unicode 8.0, but
-		# have UIPC
+		# TODO: These don't have UISC assigned in Unicode 8.0, but have UIPC
 		if U == 0x17DD: UISC = Vowel_Dependent
 		if 0x1CE2 <= U <= 0x1CE8: UISC = Cantillation_Mark
 
+		# Tibetan:
+		# TODO: These don't have UISC assigned in Unicode 11.0, but have UIPC
+		if 0x0F18 <= U <= 0x0F19 or 0x0F3E <= U <= 0x0F3F: UISC = Vowel_Dependent
+		if 0x0F86 <= U <= 0x0F87: UISC = Tone_Mark
+		# Overrides to allow NFC order matching syllable
+		# https://github.com/harfbuzz/harfbuzz/issues/1012
+		if UBlock == 'Tibetan' and is_VOWEL (U, UISC, UGC):
+			if UIPC == Top:
+				UIPC = Bottom
+
+		# TODO: https://github.com/harfbuzz/harfbuzz/pull/982
+		# also  https://github.com/harfbuzz/harfbuzz/issues/1012
+		if UBlock == 'Chakma' and is_VOWEL (U, UISC, UGC):
+			if UIPC == Top:
+				UIPC = Bottom
+			elif UIPC == Bottom:
+				UIPC = Top
+
 		# TODO: https://github.com/harfbuzz/harfbuzz/pull/627
 		if 0x1BF2 <= U <= 0x1BF3: UISC = Nukta; UIPC = Bottom
 
@@ -359,13 +381,6 @@
 		# https://github.com/roozbehp/unicode-data/issues/8
 		if U == 0x0A51: UIPC = Bottom
 
-		# TODO: https://github.com/harfbuzz/harfbuzz/pull/982
-		if UBlock == 'Chakma' and is_VOWEL (U, UISC, UGC):
-			if UIPC == Top:
-				UIPC = Bottom
-			elif UIPC == Bottom:
-				UIPC = Top
-
 		assert (UIPC in [Not_Applicable, Visual_Order_Left] or
 			USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC)
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in	2018-10-19 23:02:01 UTC (rev 48949)
@@ -12,7 +12,11 @@
 string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_libdir "${_harfbuzz_libdir}")
 set(_harfbuzz_libdir_iter "${_harfbuzz_libdir}")
 while (_harfbuzz_libdir_iter)
+  set(_harfbuzz_libdir_prev_iter "${_harfbuzz_libdir_iter}")
   get_filename_component(_harfbuzz_libdir_iter "${_harfbuzz_libdir_iter}" DIRECTORY)
+  if (_harfbuzz_libdir_prev_iter STREQUAL _harfbuzz_libdir_iter)
+    break()
+  endif ()
   get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY)
 endwhile ()
 unset(_harfbuzz_libdir_iter)

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -45,6 +45,7 @@
     return_trace (c->check_struct (this));
   }
 
+  public:
   FWORD		xCoordinate;
   FWORD		yCoordinate;
   public:
@@ -51,26 +52,40 @@
   DEFINE_SIZE_STATIC (4);
 };
 
+typedef LArrayOf<Anchor> GlyphAnchors;
+
 struct ankr
 {
   static const hb_tag_t tableTag = HB_AAT_TAG_ankr;
 
+  inline const Anchor &get_anchor (hb_codepoint_t glyph_id,
+				   unsigned int i,
+				   unsigned int num_glyphs,
+				   const char *end) const
+  {
+    unsigned int offset = (this+lookupTable).get_value_or_null (glyph_id, num_glyphs);
+    const GlyphAnchors &anchors = StructAtOffset<GlyphAnchors> (&(this+anchorData), offset);
+    /* TODO Use sanitizer; to avoid overflows and more. */
+    if (unlikely ((const char *) &anchors + anchors.get_size () > end))
+      return Null(Anchor);
+    return anchors[i];
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
 			  version == 0 &&
-			  lookupTable.sanitize (c, this) &&
-			  anchors.sanitize (c, this)));
+			  lookupTable.sanitize (c, this)));
   }
 
   protected:
   HBUINT16	version; 	/* Version number (set to zero) */
   HBUINT16	flags;		/* Flags (currently unused; set to zero) */
-  LOffsetTo<Lookup<HBUINT16> >
+  LOffsetTo<Lookup<Offset<HBUINT16, false> >, false>
 		lookupTable;	/* Offset to the table's lookup table */
-  LOffsetTo<LArrayOf<Anchor> >
-		anchors;	/* Offset to the glyph data table */
+  LOffsetTo<HBUINT8, false>
+		anchorData;	/* Offset to the glyph data table */
 
   public:
   DEFINE_SIZE_STATIC (12);

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -36,111 +36,6 @@
 
 
 /*
- * Binary Searching Tables
- */
-
-struct BinSearchHeader
-{
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  HBUINT16	unitSize;	/* Size of a lookup unit for this search in bytes. */
-  HBUINT16	nUnits;		/* Number of units of the preceding size to be searched. */
-  HBUINT16	searchRange;	/* The value of unitSize times the largest power of 2
-				 * that is less than or equal to the value of nUnits. */
-  HBUINT16	entrySelector;	/* The log base 2 of the largest power of 2 less than
-				 * or equal to the value of nUnits. */
-  HBUINT16	rangeShift;	/* The value of unitSize times the difference of the
-				 * value of nUnits minus the largest power of 2 less
-				 * than or equal to the value of nUnits. */
-  public:
-  DEFINE_SIZE_STATIC (10);
-};
-
-template <typename Type>
-struct BinSearchArrayOf
-{
-  inline const Type& operator [] (unsigned int i) const
-  {
-    if (unlikely (i >= header.nUnits)) return Null(Type);
-    return StructAtOffset<Type> (bytesZ, i * header.unitSize);
-  }
-  inline Type& operator [] (unsigned int i)
-  {
-    return StructAtOffset<Type> (bytesZ, i * header.unitSize);
-  }
-  inline unsigned int get_size (void) const
-  { return header.static_size + header.nUnits * header.unitSize; }
-
-  inline bool sanitize (hb_sanitize_context_t *c) 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);
-  }
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    unsigned int count = header.nUnits;
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(*this)[i].sanitize (c, base)))
-        return_trace (false);
-    return_trace (true);
-  }
-
-  template <typename T>
-  inline const Type *bsearch (const T &key) const
-  {
-    unsigned int size = header.unitSize;
-    int min = 0, max = (int) header.nUnits - 1;
-    while (min <= max)
-    {
-      int mid = (min + max) / 2;
-      const Type *p = (const Type *) (((const char *) bytesZ) + (mid * size));
-      int c = p->cmp (key);
-      if (c < 0)
-	max = mid - 1;
-      else if (c > 0)
-	min = mid + 1;
-      else
-	return p;
-    }
-    return nullptr;
-  }
-
-  private:
-  inline bool sanitize_shallow (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (header.sanitize (c) &&
-		  Type::static_size >= header.unitSize &&
-		  c->check_array (bytesZ, header.unitSize, header.nUnits));
-  }
-
-  protected:
-  BinSearchHeader	header;
-  HBUINT8		bytesZ[VAR];
-  public:
-  DEFINE_SIZE_ARRAY (10, bytesZ);
-};
-
-
-/*
  * Lookup Table
  */
 
@@ -213,7 +108,7 @@
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 2 */
-  BinSearchArrayOf<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). */
@@ -243,7 +138,7 @@
 
   GlyphID	last;		/* Last GlyphID in this segment */
   GlyphID	first;		/* First GlyphID in this segment */
-  OffsetTo<UnsizedArrayOf<T> >
+  OffsetTo<UnsizedArrayOf<T>, HBUINT16, false>
 		valuesZ;	/* A 16-bit offset from the start of
 				 * the table to the data. */
   public:
@@ -269,8 +164,8 @@
   }
 
   protected:
-  HBUINT16	format;		/* Format identifier--format = 2 */
-  BinSearchArrayOf<LookupSegmentArray<T> >
+  HBUINT16	format;		/* Format identifier--format = 4 */
+  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). */
@@ -292,7 +187,7 @@
   GlyphID	glyph;		/* Last GlyphID */
   T		value;		/* The lookup value (only one) */
   public:
-  DEFINE_SIZE_STATIC (4 + T::static_size);
+  DEFINE_SIZE_STATIC (2 + T::static_size);
 };
 
 template <typename T>
@@ -315,7 +210,7 @@
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 6 */
-  BinSearchArrayOf<LookupSingle<T> >
+  VarSizedBinSearchArrayOf<LookupSingle<T> >
 		entries;	/* The actual entries, sorted by glyph index. */
   public:
   DEFINE_SIZE_ARRAY (8, entries);
@@ -329,7 +224,8 @@
   private:
   inline const T* get_value (hb_codepoint_t glyph_id) const
   {
-    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? &valueArrayZ[glyph_id - firstGlyph] : nullptr;
+    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
+	   &valueArrayZ[glyph_id - firstGlyph] : nullptr;
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -339,7 +235,7 @@
   }
 
   protected:
-  HBUINT16	format;		/* Format identifier--format = 6 */
+  HBUINT16	format;		/* Format identifier--format = 8 */
   GlyphID	firstGlyph;	/* First glyph index included in the trimmed array. */
   HBUINT16	glyphCount;	/* Total number of glyphs (equivalent to the last
 				 * glyph minus the value of firstGlyph plus 1). */
@@ -365,6 +261,12 @@
     }
   }
 
+  inline const T& get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
+  {
+    const T *v = get_value (glyph_id, num_glyphs);
+    return v ? *v : Null(T);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -391,6 +293,25 @@
   public:
   DEFINE_SIZE_UNION (2, format);
 };
+/* Lookup 0 has unbounded size (dependant on num_glyphs).  So we need to defined
+ * special NULL objects for Lookup<> objects, but since it's template our macros
+ * don't work.  So we have to hand-code them here.  UGLY. */
+} /* Close namespace. */
+/* Ugly hand-coded null objects for template Lookup<> :(. */
+extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2];
+template <>
+/*static*/ inline const AAT::Lookup<OT::HBUINT16>& Null<AAT::Lookup<OT::HBUINT16> > (void) {
+  return *reinterpret_cast<const AAT::Lookup<OT::HBUINT16> *> (_hb_Null_AAT_Lookup);
+}
+template <>
+/*static*/ inline const AAT::Lookup<OT::HBUINT32>& Null<AAT::Lookup<OT::HBUINT32> > (void) {
+  return *reinterpret_cast<const AAT::Lookup<OT::HBUINT32> *> (_hb_Null_AAT_Lookup);
+}
+template <>
+/*static*/ inline const AAT::Lookup<OT::Offset<OT::HBUINT16, false> >& Null<AAT::Lookup<OT::Offset<OT::HBUINT16, false> > > (void) {
+  return *reinterpret_cast<const AAT::Lookup<OT::Offset<OT::HBUINT16, false> > *> (_hb_Null_AAT_Lookup);
+}
+namespace AAT {
 
 
 /*
@@ -439,10 +360,23 @@
 template <typename Extra>
 struct StateTable
 {
+  enum State
+  {
+    STATE_START_OF_TEXT = 0,
+    STATE_START_OF_LINE = 1,
+  };
+  enum Class
+  {
+    CLASS_END_OF_TEXT = 0,
+    CLASS_OUT_OF_BOUNDS = 1,
+    CLASS_DELETED_GLYPH = 2,
+    CLASS_END_OF_LINE = 3,
+  };
+
   inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
   {
     const HBUINT16 *v = (this+classTable).get_value (glyph_id, num_glyphs);
-    return v ? *v : 1;
+    return v ? (unsigned) *v : (unsigned) CLASS_OUT_OF_BOUNDS;
   }
 
   inline const Entry<Extra> *get_entries () const
@@ -472,6 +406,8 @@
     const HBUINT16 *states = (this+stateArrayTable).arrayZ;
     const Entry<Extra> *entries = (this+entryTable).arrayZ;
 
+    unsigned int num_classes = nClasses;
+
     unsigned int num_states = 1;
     unsigned int num_entries = 0;
 
@@ -479,21 +415,26 @@
     unsigned int entry = 0;
     while (state < num_states)
     {
+      if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
+	return_trace (false);
+
       if (unlikely (!c->check_array (states,
-				     states[0].static_size * nClasses,
-				     num_states)))
+				     num_states,
+				     num_classes * states[0].static_size)))
 	return_trace (false);
+      if ((c->max_ops -= num_states - state) < 0)
+	return_trace (false);
       { /* Sweep new states. */
-	const HBUINT16 *stop = &states[num_states * nClasses];
-	for (const HBUINT16 *p = &states[state * nClasses]; p < stop; p++)
+	const HBUINT16 *stop = &states[num_states * num_classes];
+	for (const HBUINT16 *p = &states[state * num_classes]; p < stop; p++)
 	  num_entries = MAX<unsigned int> (num_entries, *p + 1);
 	state = num_states;
       }
 
-      if (unlikely (!c->check_array (entries,
-				     entries[0].static_size,
-				     num_entries)))
+      if (unlikely (!c->check_array (entries, num_entries)))
 	return_trace (false);
+      if ((c->max_ops -= num_entries - entry) < 0)
+	return_trace (false);
       { /* Sweep new entries. */
 	const Entry<Extra> *stop = &entries[num_entries];
 	for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
@@ -511,11 +452,11 @@
   protected:
   HBUINT32	nClasses;	/* Number of classes, which is the number of indices
 				 * in a single line in the state array. */
-  LOffsetTo<Lookup<HBUINT16> >
+  LOffsetTo<Lookup<HBUINT16>, false>
 		classTable;	/* Offset to the class table. */
-  LOffsetTo<UnsizedArrayOf<HBUINT16> >
+  LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
 		stateArrayTable;/* Offset to the state array. */
-  LOffsetTo<UnsizedArrayOf<Entry<Extra> > >
+  LOffsetTo<UnsizedArrayOf<Entry<Extra> >, false>
 		entryTable;	/* Offset to the entry array. */
 
   public:
@@ -535,31 +476,32 @@
   template <typename context_t>
   inline void drive (context_t *c)
   {
-    hb_glyph_info_t *info = buffer->info;
-
     if (!c->in_place)
       buffer->clear_output ();
 
-    unsigned int state = 0;
+    unsigned int state = StateTable<EntryData>::STATE_START_OF_TEXT;
     bool last_was_dont_advance = false;
     for (buffer->idx = 0;;)
     {
       unsigned int klass = buffer->idx < buffer->len ?
-			   machine.get_class (info[buffer->idx].codepoint, num_glyphs) :
-			   0 /* End of text */;
+			   machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) :
+			   (unsigned) StateTable<EntryData>::CLASS_END_OF_TEXT;
       const Entry<EntryData> *entry = machine.get_entryZ (state, klass);
       if (unlikely (!entry))
 	break;
 
       /* Unsafe-to-break before this if not in state 0, as things might
-       * go differently if we start from state 0 here. */
-      if (state && buffer->idx)
+       * go differently if we start from state 0 here.
+       *
+       * Ugh.  The indexing here is ugly... */
+      if (state && buffer->backtrack_len () && buffer->idx < buffer->len)
       {
 	/* If there's no action and we're just epsilon-transitioning to state 0,
 	 * safe to break. */
 	if (c->is_actionable (this, entry) ||
-	    !(entry->newState == 0 && entry->flags == context_t::DontAdvance))
-	  buffer->unsafe_to_break (buffer->idx - 1, buffer->idx + 1);
+	    !(entry->newState == StateTable<EntryData>::STATE_START_OF_TEXT &&
+	      entry->flags == context_t::DontAdvance))
+	  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
       }
 
       /* Unsafe-to-break if end-of-text would kick in here. */
@@ -573,6 +515,8 @@
       if (unlikely (!c->transition (this, entry)))
         break;
 
+      if (unlikely (!buffer->successful)) return;
+
       last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0;
 
       state = entry->newState;
@@ -586,9 +530,10 @@
 
     if (!c->in_place)
     {
-      for (; buffer->idx < buffer->len;)
-        buffer->next_glyph ();
-      buffer->swap_buffers ();
+      for (; buffer->successful && buffer->idx < buffer->len;)
+	buffer->next_glyph ();
+      if (likely (buffer->successful))
+	buffer->swap_buffers ();
     }
   }
 
@@ -599,6 +544,7 @@
 };
 
 
+struct ankr;
 
 struct hb_aat_apply_context_t :
        hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
@@ -609,24 +555,33 @@
   static return_t default_return_value (void) { return false; }
   bool stop_sublookup_iteration (return_t r) const { return r; }
 
+  hb_ot_shape_plan_t *plan;
   hb_font_t *font;
   hb_face_t *face;
   hb_buffer_t *buffer;
   hb_sanitize_context_t sanitizer;
+  const ankr &ankr_table;
+  const char *ankr_end;
 
   /* Unused. For debug tracing only. */
   unsigned int lookup_index;
   unsigned int debug_depth;
 
-  inline hb_aat_apply_context_t (hb_font_t *font_,
+  inline hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_,
+				 hb_font_t *font_,
 				 hb_buffer_t *buffer_,
-				 hb_blob_t *table) :
-		font (font_), face (font->face), buffer (buffer_),
-		sanitizer (), lookup_index (0), debug_depth (0)
+				 hb_blob_t *blob = const_cast<hb_blob_t *> (&Null(hb_blob_t)),
+				 const ankr &ankr_table_ = Null(ankr),
+				 const char *ankr_end_ = nullptr) :
+		plan (plan_), font (font_), face (font->face), buffer (buffer_),
+		sanitizer (),
+		ankr_table (ankr_table_), ankr_end (ankr_end_),
+		lookup_index (0), debug_depth (0)
   {
-    sanitizer.init (table);
+    sanitizer.init (blob);
     sanitizer.set_num_glyphs (face->get_num_glyphs ());
     sanitizer.start_processing ();
+    sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
   }
 
   inline void set_lookup_index (unsigned int i) { lookup_index = i; }

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -78,7 +78,7 @@
   protected:
   HBUINT16	feature;	/* Feature type. */
   HBUINT16	nSettings;	/* The number of records in the setting name array. */
-  LOffsetTo<UnsizedArrayOf<SettingName> >
+  LOffsetTo<UnsizedArrayOf<SettingName>, false>
 		settingTable;	/* Offset in bytes from the beginning of this table to
 				 * this feature's setting name array. The actual type of
 				 * record this offset refers to will depend on the

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -30,7 +30,8 @@
 
 #include "hb-open-type.hh"
 #include "hb-aat-layout-common.hh"
-#include "hb-aat-layout-ankr-table.hh"
+#include "hb-ot-layout-gpos-table.hh"
+#include "hb-ot-kern-table.hh"
 
 /*
  * kerx -- Extended Kerning
@@ -44,7 +45,7 @@
 using namespace OT;
 
 
-struct KerxFormat0Records
+struct KerxSubTableHeader
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -52,217 +53,565 @@
     return_trace (likely (c->check_struct (this)));
   }
 
-  protected:
-  GlyphID	left;
-  GlyphID	right;
-  FWORD		value;
   public:
-  DEFINE_SIZE_STATIC (6);
+  HBUINT32	length;
+  HBUINT32	coverage;
+  HBUINT32	tupleCount;
+  public:
+  DEFINE_SIZE_STATIC (12);
 };
 
 struct KerxSubTableFormat0
 {
-  // TODO(ebraminio) Enable when we got suitable BinSearchArrayOf
-  // inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-  // {
-  //   hb_glyph_pair_t pair = {left, right};
-  //   int i = pairs.bsearch (pair);
-  //   if (i == -1)
-  //     return 0;
-  //   return pairs[i].get_kerning ();
-  // }
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+  {
+    hb_glyph_pair_t pair = {left, right};
+    int i = pairs.bsearch (pair);
+    return i == -1 ? 0 : pairs[i].get_kerning ();
+  }
 
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    if (!c->plan->requested_kerning)
+      return false;
+
+    hb_kern_machine_t<KerxSubTableFormat0> machine (*this);
+
+    machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  recordsZ.sanitize (c, nPairs)));
+    return_trace (likely (pairs.sanitize (c)));
   }
 
   protected:
-  // TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is
-  // needed here to use HBUINT32 instead
-  HBUINT32	nPairs;		/* The number of kerning pairs in this subtable */
-  HBUINT32	searchRange;	/* The largest power of two less than or equal to the value of nPairs,
-				 * multiplied by the size in bytes of an entry in the subtable. */
-  HBUINT32	entrySelector;	/* This is calculated as log2 of the largest power of two less
-				 * than or equal to the value of nPairs. */
-  HBUINT32	rangeShift;	/* The value of nPairs minus the largest power of two less than or equal to nPairs. */
-  UnsizedArrayOf<KerxFormat0Records>
-		recordsZ;	/* VAR=nPairs */
+  KerxSubTableHeader	header;
+  BinSearchArrayOf<KernPair, HBUINT32>
+			pairs;	/* Sorted kern records. */
   public:
-  DEFINE_SIZE_ARRAY (16, recordsZ);
+  DEFINE_SIZE_ARRAY (28, pairs);
 };
 
 struct KerxSubTableFormat1
 {
-  inline bool sanitize (hb_sanitize_context_t *c) const
+  struct EntryData
   {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  stateHeader.sanitize (c)));
-  }
+    HBUINT16	kernActionIndex;/* Index into the kerning value array. If
+				 * this index is 0xFFFF, then no kerning
+				 * is to be performed. */
+    public:
+    DEFINE_SIZE_STATIC (2);
+  };
 
-  protected:
-  StateTable<HBUINT16>		stateHeader;
-  LOffsetTo<ArrayOf<HBUINT16> >	valueTable;
-  public:
-  DEFINE_SIZE_STATIC (20);
-};
+  struct driver_context_t
+  {
+    static const bool in_place = true;
+    enum Flags
+    {
+      Push		= 0x8000,	/* If set, push this glyph on the kerning stack. */
+      DontAdvance	= 0x4000,	/* If set, don't advance to the next glyph
+					 * before going to the new state. */
+      Reset		= 0x2000,	/* If set, reset the kerning data (clear the stack) */
+      Reserved		= 0x1FFF,	/* Not used; set to 0. */
+    };
 
-// TODO(ebraminio): Maybe this can be replaced with Lookup<HBUINT16>?
-struct KerxClassTable
-{
-  inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
+    inline driver_context_t (const KerxSubTableFormat1 *table,
+			     hb_aat_apply_context_t *c_) :
+	c (c_),
+	/* Apparently the offset kernAction is from the beginning of the state-machine,
+	 * similar to offsets in morx table, NOT from beginning of this table, like
+	 * other subtables in kerx.  Discovered via testing. */
+	kernAction (&table->machine + table->kernAction),
+	depth (0) {}
 
+    inline bool is_actionable (StateTableDriver<EntryData> *driver,
+			       const Entry<EntryData> *entry)
+    {
+      return entry->data.kernActionIndex != 0xFFFF;
+    }
+    inline bool transition (StateTableDriver<EntryData> *driver,
+			    const Entry<EntryData> *entry)
+    {
+      hb_buffer_t *buffer = driver->buffer;
+      unsigned int flags = entry->flags;
+
+      if (flags & Reset)
+      {
+        depth = 0;
+      }
+
+      if (flags & Push)
+      {
+        if (likely (depth < ARRAY_LENGTH (stack)))
+	  stack[depth++] = buffer->idx;
+	else
+	  depth = 0; /* Probably not what CoreText does, but better? */
+      }
+
+      if (entry->data.kernActionIndex != 0xFFFF)
+      {
+	const FWORD *actions = &kernAction[entry->data.kernActionIndex];
+        if (!c->sanitizer.check_array (actions, depth))
+	{
+	  depth = 0;
+	  return false;
+	}
+
+	hb_mask_t kern_mask = c->plan->kern_mask;
+        for (unsigned int i = 0; i < depth; i++)
+	{
+	  /* Apparently, when spec says "Each pops one glyph from the kerning stack
+	   * and applies the kerning value to it.", it doesn't mean it in that order.
+	   * The deepest item in the stack corresponds to the first item in the action
+	   * list.  Discovered by testing. */
+	  unsigned int idx = stack[i];
+	  int v = *actions++;
+	  if (idx < buffer->len && buffer->info[idx].mask & kern_mask)
+	  {
+	    /* XXX Non-forward direction... */
+	    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+	      buffer->pos[idx].x_advance += c->font->em_scale_x (v);
+	    else
+	      buffer->pos[idx].y_advance += c->font->em_scale_y (v);
+	  }
+	}
+	depth = 0;
+      }
+
+      return true;
+    }
+
+    private:
+    hb_aat_apply_context_t *c;
+    const UnsizedArrayOf<FWORD> &kernAction;
+    unsigned int stack[8];
+    unsigned int depth;
+  };
+
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    if (!c->plan->requested_kerning)
+      return false;
+
+    driver_context_t dc (this, c);
+
+    StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
+    driver.drive (&dc);
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (likely (firstGlyph.sanitize (c) &&
-			  classes.sanitize (c)));
+    /* The rest of array sanitizations are done at run-time. */
+    return_trace (likely (c->check_struct (this) &&
+			  machine.sanitize (c)));
   }
 
   protected:
-  HBUINT16		firstGlyph;	/* First glyph in class range. */
-  ArrayOf<HBUINT16>	classes;	/* Glyph classes. */
+  KerxSubTableHeader				header;
+  StateTable<EntryData>				machine;
+  LOffsetTo<UnsizedArrayOf<FWORD>, false>	kernAction;
   public:
-  DEFINE_SIZE_ARRAY (4, classes);
+  DEFINE_SIZE_STATIC (32);
 };
 
 struct KerxSubTableFormat2
 {
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
+			  hb_aat_apply_context_t *c) const
   {
-    unsigned int l = (this+leftClassTable).get_class (left);
-    unsigned int r = (this+leftClassTable).get_class (left);
-    unsigned int offset = l * rowWidth + r * sizeof (FWORD);
-    const FWORD *arr = &(this+array);
-    if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
-      return 0;
-    const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
-    if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
-      return 0;
+    unsigned int num_glyphs = c->sanitizer.get_num_glyphs ();
+    unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs);
+    unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs);
+    unsigned int offset = l + r;
+    const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
+    if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
     return *v;
   }
 
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    if (!c->plan->requested_kerning)
+      return false;
+
+    accelerator_t accel (*this, c);
+    hb_kern_machine_t<accelerator_t> machine (accel);
+    machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  rowWidth.sanitize (c) &&
+    return_trace (likely (rowWidth.sanitize (c) &&
 			  leftClassTable.sanitize (c, this) &&
 			  rightClassTable.sanitize (c, this) &&
-			  array.sanitize (c, this)));
+			  c->check_range (this, array)));
   }
 
+  struct accelerator_t
+  {
+    const KerxSubTableFormat2 &table;
+    hb_aat_apply_context_t *c;
+
+    inline accelerator_t (const KerxSubTableFormat2 &table_,
+			  hb_aat_apply_context_t *c_) :
+			    table (table_), c (c_) {}
+
+    inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+    { return table.get_kerning (left, right, c); }
+  };
+
   protected:
-  HBUINT32	rowWidth;	/* The width, in bytes, of a row in the table. */
-  LOffsetTo<KerxClassTable>
-		leftClassTable;	/* Offset from beginning of this subtable to
-				 * left-hand class table. */
-  LOffsetTo<KerxClassTable>
-		rightClassTable;/* Offset from beginning of this subtable to
-				 * right-hand class table. */
-  LOffsetTo<FWORD>
-		array;		/* Offset from beginning of this subtable to
-				 * the start of the kerning array. */
+  KerxSubTableHeader	header;
+  HBUINT32		rowWidth;	/* The width, in bytes, of a row in the table. */
+  LOffsetTo<Lookup<HBUINT16>, false>
+			leftClassTable;	/* Offset from beginning of this subtable to
+					 * left-hand class table. */
+  LOffsetTo<Lookup<HBUINT16>, false>
+			rightClassTable;/* Offset from beginning of this subtable to
+					 * right-hand class table. */
+  LOffsetTo<UnsizedArrayOf<FWORD>, false>
+			 array;		/* Offset from beginning of this subtable to
+					 * the start of the kerning array. */
   public:
-  DEFINE_SIZE_STATIC (16);
+  DEFINE_SIZE_STATIC (28);
 };
 
 struct KerxSubTableFormat4
 {
+  struct EntryData
+  {
+    HBUINT16	ankrActionIndex;/* Either 0xFFFF (for no action) or the index of
+				 * the action to perform. */
+    public:
+    DEFINE_SIZE_STATIC (2);
+  };
+
+  struct driver_context_t
+  {
+    static const bool in_place = true;
+    enum Flags
+    {
+      Mark		= 0x8000,	/* If set, remember this glyph as the marked glyph. */
+      DontAdvance	= 0x4000,	/* If set, don't advance to the next glyph before
+					 * going to the new state. */
+      Reserved		= 0x3FFF,	/* Not used; set to 0. */
+    };
+
+    enum SubTableFlags
+    {
+      ActionType	= 0xC0000000,	/* A two-bit field containing the action type. */
+      Unused		= 0x3F000000,	/* Unused - must be zero. */
+      Offset		= 0x00FFFFFF,	/* Masks the offset in bytes from the beginning
+					 * of the subtable to the beginning of the control
+					 * point table. */
+    };
+
+    inline driver_context_t (const KerxSubTableFormat4 *table,
+			     hb_aat_apply_context_t *c_) :
+	c (c_),
+	action_type ((table->flags & ActionType) >> 30),
+	ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))),
+	mark_set (false),
+	mark (0) {}
+
+    inline bool is_actionable (StateTableDriver<EntryData> *driver,
+			       const Entry<EntryData> *entry)
+    {
+      return entry->data.ankrActionIndex != 0xFFFF;
+    }
+    inline bool transition (StateTableDriver<EntryData> *driver,
+			    const Entry<EntryData> *entry)
+    {
+      hb_buffer_t *buffer = driver->buffer;
+      unsigned int flags = entry->flags;
+
+      if (mark_set && entry->data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len)
+      {
+	hb_glyph_position_t &o = buffer->cur_pos();
+	switch (action_type)
+	{
+	  case 0: /* Control Point Actions.*/
+	  {
+	    /* indexed into glyph outline. */
+	    const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex];
+	    if (!c->sanitizer.check_array (data, 2))
+	      return false;
+	    HB_UNUSED unsigned int markControlPoint = *data++;
+	    HB_UNUSED unsigned int currControlPoint = *data++;
+	    hb_position_t markX = 0;
+	    hb_position_t markY = 0;
+	    hb_position_t currX = 0;
+	    hb_position_t currY = 0;
+	    if (!c->font->get_glyph_contour_point_for_origin (c->buffer->info[mark].codepoint,
+							      markControlPoint,
+							      HB_DIRECTION_LTR /*XXX*/,
+							      &markX, &markY) ||
+		!c->font->get_glyph_contour_point_for_origin (c->buffer->cur ().codepoint,
+							      currControlPoint,
+							      HB_DIRECTION_LTR /*XXX*/,
+							      &currX, &currY))
+	      return true; /* True, such that the machine continues. */
+
+	    o.x_offset = markX - currX;
+	    o.y_offset = markY - currY;
+	  }
+	  break;
+
+	  case 1: /* Anchor Point Actions. */
+	  {
+	   /* Indexed into 'ankr' table. */
+	    const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex];
+	    if (!c->sanitizer.check_array (data, 2))
+	      return false;
+	    unsigned int markAnchorPoint = *data++;
+	    unsigned int currAnchorPoint = *data++;
+	    const Anchor markAnchor = c->ankr_table.get_anchor (c->buffer->info[mark].codepoint,
+								markAnchorPoint,
+								c->sanitizer.get_num_glyphs (),
+								c->ankr_end);
+	    const Anchor currAnchor = c->ankr_table.get_anchor (c->buffer->cur ().codepoint,
+								currAnchorPoint,
+								c->sanitizer.get_num_glyphs (),
+								c->ankr_end);
+
+	    o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate);
+	    o.y_offset = c->font->em_scale_y (markAnchor.yCoordinate) - c->font->em_scale_y (currAnchor.yCoordinate);
+	  }
+	  break;
+
+	  case 2: /* Control Point Coordinate Actions. */
+	  {
+	    const FWORD *data = (const FWORD *) &ankrData[entry->data.ankrActionIndex];
+	    if (!c->sanitizer.check_array (data, 4))
+	      return false;
+	    int markX = *data++;
+	    int markY = *data++;
+	    int currX = *data++;
+	    int currY = *data++;
+
+	    o.x_offset = c->font->em_scale_x (markX) - c->font->em_scale_x (currX);
+	    o.y_offset = c->font->em_scale_y (markY) - c->font->em_scale_y (currY);
+	  }
+	  break;
+	}
+	o.attach_type() = ATTACH_TYPE_MARK;
+	o.attach_chain() = (int) mark - (int) buffer->idx;
+	buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+      }
+
+      if (flags & Mark)
+      {
+	mark_set = true;
+	mark = buffer->idx;
+      }
+
+      return true;
+    }
+
+    private:
+    hb_aat_apply_context_t *c;
+    unsigned int action_type;
+    const HBUINT16 *ankrData;
+    bool mark_set;
+    unsigned int mark;
+  };
+
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    driver_context_t dc (this, c);
+
+    StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
+    driver.drive (&dc);
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
+    /* The rest of array sanitizations are done at run-time. */
     return_trace (likely (c->check_struct (this) &&
-			  rowWidth.sanitize (c) &&
-			  leftClassTable.sanitize (c, this) &&
-			  rightClassTable.sanitize (c, this) &&
-			  array.sanitize (c, this)));
+			  machine.sanitize (c)));
   }
 
   protected:
-  HBUINT32	rowWidth;	/* The width, in bytes, of a row in the table. */
-  LOffsetTo<KerxClassTable>
-		leftClassTable;	/* Offset from beginning of this subtable to
-				 * left-hand class table. */
-  LOffsetTo<KerxClassTable>
-		rightClassTable;/* Offset from beginning of this subtable to
-				 * right-hand class table. */
-  LOffsetTo<FWORD>
-		array;		/* Offset from beginning of this subtable to
-				 * the start of the kerning array. */
+  KerxSubTableHeader	header;
+  StateTable<EntryData>	machine;
+  HBUINT32		flags;
   public:
-  DEFINE_SIZE_STATIC (16);
+  DEFINE_SIZE_STATIC (32);
 };
 
 struct KerxSubTableFormat6
 {
+  enum Flags
+  {
+    ValuesAreLong	= 0x00000001,
+  };
+
+  inline bool is_long (void) const { return flags & ValuesAreLong; }
+
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
+			  hb_aat_apply_context_t *c) const
+  {
+    unsigned int num_glyphs = c->sanitizer.get_num_glyphs ();
+    if (is_long ())
+    {
+      const U::Long &t = u.l;
+      unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs);
+      unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs);
+      unsigned int offset = l + r;
+      if (unlikely (offset < l)) return 0; /* Addition overflow. */
+      if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0;
+      const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32));
+      if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
+      return *v;
+    }
+    else
+    {
+      const U::Short &t = u.s;
+      unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs);
+      unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs);
+      unsigned int offset = l + r;
+      const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD));
+      if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
+      return *v;
+    }
+  }
+
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    if (!c->plan->requested_kerning)
+      return false;
+
+    accelerator_t accel (*this, c);
+    hb_kern_machine_t<accelerator_t> machine (accel);
+    machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-			  rowIndexTable.sanitize (c, this) &&
-			  columnIndexTable.sanitize (c, this) &&
-			  kerningArray.sanitize (c, this) &&
-			  kerningVector.sanitize (c, this)));
+			  (is_long () ?
+			   (
+			     u.l.rowIndexTable.sanitize (c, this) &&
+			     u.l.columnIndexTable.sanitize (c, this) &&
+			     c->check_range (this, u.l.array)
+			   ) : (
+			     u.s.rowIndexTable.sanitize (c, this) &&
+			     u.s.columnIndexTable.sanitize (c, this) &&
+			     c->check_range (this, u.s.array)
+			   ))));
   }
 
+  struct accelerator_t
+  {
+    const KerxSubTableFormat6 &table;
+    hb_aat_apply_context_t *c;
+
+    inline accelerator_t (const KerxSubTableFormat6 &table_,
+			  hb_aat_apply_context_t *c_) :
+			    table (table_), c (c_) {}
+
+    inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+    { return table.get_kerning (left, right, c); }
+  };
+
   protected:
-  HBUINT32	flags;
-  HBUINT16	rowCount;
-  HBUINT16	columnCount;
-  LOffsetTo<Lookup<HBUINT16> >	rowIndexTable;
-  LOffsetTo<Lookup<HBUINT16> >	columnIndexTable;
-  LOffsetTo<Lookup<HBUINT16> >	kerningArray;
-  LOffsetTo<Lookup<HBUINT16> >	kerningVector;
+  KerxSubTableHeader		header;
+  HBUINT32			flags;
+  HBUINT16			rowCount;
+  HBUINT16			columnCount;
+  union U
+  {
+    struct Long
+    {
+      LOffsetTo<Lookup<HBUINT32>, false>	rowIndexTable;
+      LOffsetTo<Lookup<HBUINT32>, false>	columnIndexTable;
+      LOffsetTo<UnsizedArrayOf<FWORD32>, false>	array;
+    } l;
+    struct Short
+    {
+      LOffsetTo<Lookup<HBUINT16>, false>	rowIndexTable;
+      LOffsetTo<Lookup<HBUINT16>, false>	columnIndexTable;
+      LOffsetTo<UnsizedArrayOf<FWORD>, false>	array;
+    } s;
+  } u;
   public:
-  DEFINE_SIZE_STATIC (24);
+  DEFINE_SIZE_STATIC (32);
 };
 
-enum coverage_flags_t
+struct KerxTable
 {
-  COVERAGE_VERTICAL_FLAG	= 0x80u,
-  COVERAGE_CROSSSTREAM_FLAG	= 0x40u,
-  COVERAGE_VARIATION_FLAG	= 0x20u,
-  COVERAGE_PROCESS_DIRECTION	= 0x10u,
-};
+  friend struct kerx;
 
-struct KerxTable
-{
-  inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const
+  inline unsigned int get_size (void) const { return u.header.length; }
+  inline unsigned int get_type (void) const { return u.header.coverage & SubtableType; }
+
+  enum Coverage
   {
-    TRACE_APPLY (this);
-    /* TODO */
-    return_trace (false);
+    Vertical		= 0x80000000,	/* Set if table has vertical kerning values. */
+    CrossStream		= 0x40000000,	/* Set if table has cross-stream kerning values. */
+    Variation		= 0x20000000,	/* Set if table has variation kerning values. */
+    Backwards		= 0x10000000,	/* If clear, process the glyphs forwards, that
+					 * is, from first to last in the glyph stream.
+					 * If we, process them from last to first.
+					 * This flag only applies to state-table based
+					 * 'kerx' subtables (types 1 and 4). */
+    Reserved		= 0x0FFFFF00,	/* Reserved, set to zero. */
+    SubtableType	= 0x000000FF,	/* Subtable type. */
+  };
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) 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));
+    default:			return_trace (c->default_return_value ());
+    }
   }
 
-  inline unsigned int get_size (void) const { return length; }
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!c->check_struct (this)))
+    if (!u.header.sanitize (c) ||
+	!c->check_range (this, u.header.length))
       return_trace (false);
 
-    switch (format) {
-    case 0: return u.format0.sanitize (c);
-    case 1: return u.format1.sanitize (c);
-    case 2: return u.format2.sanitize (c);
-    case 4: return u.format4.sanitize (c);
-    case 6: return u.format6.sanitize (c);
-    default:return_trace (false);
-    }
+    return_trace (dispatch (c));
   }
 
 protected:
-  HBUINT32	length;
-  HBUINT8	coverage;
-  HBUINT16	unused;
-  HBUINT8	format;
-  HBUINT32	tupleIndex;
   union {
+  KerxSubTableHeader	header;
   KerxSubTableFormat0	format0;
   KerxSubTableFormat1	format1;
   KerxSubTableFormat2	format2;
@@ -273,71 +622,91 @@
   DEFINE_SIZE_MIN (12);
 };
 
-struct SubtableGlyphCoverageArray
-{
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this)));
-  }
 
-  protected:
-  HBUINT32	length;
-  HBUINT32	coverage;
-  HBUINT32	tupleCount;
-  public:
-  DEFINE_SIZE_STATIC (12);
-};
+/*
+ * The 'kerx' Table
+ */
 
 struct kerx
 {
   static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
 
-  inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const
+  inline bool has_data (void) const { return version != 0; }
+
+  inline void apply (hb_aat_apply_context_t *c) const
   {
-    TRACE_APPLY (this);
-    const KerxTable &table = StructAfter<KerxTable> (*this);
-    return_trace (table.apply (c, ankr));
+    c->set_lookup_index (0);
+    const KerxTable *table = &firstTable;
+    unsigned int count = tableCount;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      bool reverse;
+
+      if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation) ||
+	  table->u.header.tupleCount)
+	goto skip; /* We do NOT handle cross-stream or variation kerning. */
+
+      if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
+	  bool (table->u.header.coverage & KerxTable::Vertical))
+	goto skip;
+
+      reverse = bool (table->u.header.coverage & KerxTable::Backwards) !=
+		HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
+
+      if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
+	goto skip;
+
+      if (reverse)
+	c->buffer->reverse ();
+
+      c->sanitizer.set_object (*table);
+
+      /* XXX Reverse-kern is not working yet...
+       * hb_kern_machine_t would need to know that it's reverse-kerning.
+       * Or better yet, make it work in reverse as well, so we don't have
+       * to reverse and reverse back? */
+      table->dispatch (c);
+
+      if (reverse)
+	c->buffer->reverse ();
+
+      (void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index);
+
+    skip:
+      table = &StructAfter<KerxTable> (*table);
+    }
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!(c->check_struct (this))))
-     return_trace (false);
-
-    /* TODO: Something like `morx`s ChainSubtable should be done here instead */
-    const KerxTable *table = &StructAfter<KerxTable> (*this);
-    if (unlikely (!(table->sanitize (c))))
+    if (!version.sanitize (c) || version < 2 ||
+	!tableCount.sanitize (c))
       return_trace (false);
 
-    for (unsigned int i = 0; i < nTables - 1; ++i)
+    const KerxTable *table = &firstTable;
+    unsigned int count = tableCount;
+    for (unsigned int i = 0; i < count; i++)
     {
+      if (!table->sanitize (c))
+	return_trace (false);
       table = &StructAfter<KerxTable> (*table);
-      if (unlikely (!(table->sanitize (c))))
-        return_trace (false);
     }
 
-    // If version is less than 3, we are done here; otherwise better to check footer also
-    if (version < 3)
-      return_trace (true);
-
-    // TODO: Investigate why this just work on some fonts no matter of version
-    // const SubtableGlyphCoverageArray &footer =
-    //   StructAfter<SubtableGlyphCoverageArray> (*table);
-    // return_trace (footer.sanitize (c));
-
     return_trace (true);
   }
 
   protected:
-  HBUINT16		version;
-  HBUINT16		padding;
-  HBUINT32		nTables;
-/*KerxTable tablesZ[VAR]; XXX ArrayOf??? */
-/*SubtableGlyphCoverageArray coverage_array;*/
+  HBUINT16	version;	/* The version number of the extended kerning table
+				 * (currently 2, 3, or 4). */
+  HBUINT16	unused;		/* Set to 0. */
+  HBUINT32	tableCount;	/* The number of subtables included in the extended kerning
+				 * table. */
+  KerxTable	firstTable;	/* Subtables. */
+/*subtableGlyphCoverageArray*/	/* Only if version >= 3. We don't use. */
+
   public:
-  DEFINE_SIZE_STATIC (8);
+  DEFINE_SIZE_MIN (8);
 };
 
 } /* namespace AAT */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -50,7 +50,8 @@
   struct driver_context_t
   {
     static const bool in_place = true;
-    enum Flags {
+    enum Flags
+    {
       MarkFirst		= 0x8000,	/* If set, make the current glyph the first
 					 * glyph to be rearranged. */
       DontAdvance	= 0x4000,	/* If set, don't advance to the next glyph
@@ -163,7 +164,7 @@
 
     driver_context_t dc (this);
 
-    StateTableDriver<void> driver (machine, c->buffer, c->face);
+    StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
     driver.drive (&dc);
 
     return_trace (dc.ret);
@@ -196,7 +197,8 @@
   struct driver_context_t
   {
     static const bool in_place = true;
-    enum Flags {
+    enum Flags
+    {
       SetMark		= 0x8000,	/* If set, make the current glyph the marked glyph. */
       DontAdvance	= 0x4000,	/* If set, don't advance to the next glyph before
 					 * going to the new state. */
@@ -268,7 +270,7 @@
     private:
     bool mark_set;
     unsigned int mark;
-    const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> &subs;
+    const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32, false> &subs;
   };
 
   inline bool apply (hb_aat_apply_context_t *c) const
@@ -309,7 +311,7 @@
   protected:
   StateTable<EntryData>
 		machine;
-  LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> >
+  LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32, false>, false>
 		substitutionTables;
   public:
   DEFINE_SIZE_STATIC (20);
@@ -329,7 +331,8 @@
   struct driver_context_t
   {
     static const bool in_place = false;
-    enum Flags {
+    enum Flags
+    {
       SetComponent	= 0x8000,	/* Push this glyph onto the component stack for
 					 * eventual processing. */
       DontAdvance	= 0x4000,	/* Leave the glyph pointer at this glyph for the
@@ -338,7 +341,8 @@
 					 * group. */
       Reserved		= 0x1FFF,	/* These bits are reserved and should be set to 0. */
     };
-    enum LigActionFlags {
+    enum LigActionFlags
+    {
       LigActionLast	= 0x80000000,	/* This is the last action in the list. This also
 					 * implies storage. */
       LigActionStore	= 0x40000000,	/* Store the ligature at the current cumulated index
@@ -361,7 +365,7 @@
     inline bool is_actionable (StateTableDriver<EntryData> *driver,
 			       const Entry<EntryData> *entry)
     {
-      return !!(entry->flags & PerformAction);
+      return entry->flags & PerformAction;
     }
     inline bool transition (StateTableDriver<EntryData> *driver,
 			    const Entry<EntryData> *entry)
@@ -387,12 +391,20 @@
 	unsigned int action_idx = entry->data.ligActionIndex;
 	unsigned int action;
 	unsigned int ligature_idx = 0;
+
+	if (unlikely (!match_length))
+	  return true;
+
+	/* TODO Only when ligation happens? */
+	buffer->merge_out_clusters (match_positions[0], buffer->out_len);
+
+	unsigned int cursor = match_length;
         do
 	{
-	  if (unlikely (!match_length))
-	    return false;
+	  if (unlikely (!cursor))
+	    break;
 
-	  buffer->move_to (match_positions[--match_length]);
+	  buffer->move_to (match_positions[--cursor]);
 
 	  const HBUINT32 &actionData = ligAction[action_idx];
 	  if (unlikely (!actionData.sanitize (&c->sanitizer))) return false;
@@ -400,8 +412,10 @@
 
 	  uint32_t uoffset = action & LigActionOffset;
 	  if (uoffset & 0x20000000)
-	    uoffset += 0xC0000000;
+	    uoffset |= 0xC0000000; /* Sign-extend. */
 	  int32_t offset = (int32_t) uoffset;
+	  if (buffer->idx >= buffer->len)
+	    return false; // TODO Work on previous instead?
 	  unsigned int component_idx = buffer->cur().codepoint + offset;
 
 	  const HBUINT16 &componentData = component[component_idx];
@@ -414,21 +428,21 @@
 	    if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false;
 	    hb_codepoint_t lig = ligatureData;
 
-	    match_positions[match_length++] = buffer->out_len;
 	    buffer->replace_glyph (lig);
 
-	    //ligature_idx = 0; // XXX Yes or no?
+	    /* Now go and delete all subsequent components. */
+	    while (match_length - 1 > cursor)
+	    {
+	      buffer->move_to (match_positions[--match_length]);
+	      buffer->skip_glyph ();
+	      end--;
+	    }
 	  }
-	  else
-	  {
-	    buffer->skip_glyph ();
-	    end--;
-	  }
-	  /* TODO merge_clusters / unsafe_to_break */
 
 	  action_idx++;
 	}
 	while (!(action & LigActionLast));
+	match_length = 0;
 	buffer->move_to (end);
       }
 
@@ -469,11 +483,11 @@
   protected:
   StateTable<EntryData>
 		machine;
-  LOffsetTo<UnsizedArrayOf<HBUINT32> >
+  LOffsetTo<UnsizedArrayOf<HBUINT32>, false>
 		ligAction;	/* Offset to the ligature action table. */
-  LOffsetTo<UnsizedArrayOf<HBUINT16> >
+  LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
 		component;	/* Offset to the component table. */
-  LOffsetTo<UnsizedArrayOf<GlyphID> >
+  LOffsetTo<UnsizedArrayOf<GlyphID>, false>
 		ligature;	/* Offset to the actual ligature lists. */
   public:
   DEFINE_SIZE_STATIC (28);
@@ -517,19 +531,201 @@
 
 struct InsertionSubtable
 {
+  struct EntryData
+  {
+    HBUINT16	currentInsertIndex;	/* Zero-based index into the insertion glyph table.
+					 * The number of glyphs to be inserted is contained
+					 * in the currentInsertCount field in the flags.
+					 * A value of 0xFFFF indicates no insertion is to
+					 * be done. */
+    HBUINT16	markedInsertIndex;	/* Zero-based index into the insertion glyph table.
+					 * The number of glyphs to be inserted is contained
+					 * in the markedInsertCount field in the flags.
+					 * A value of 0xFFFF indicates no insertion is to
+					 * be done. */
+    public:
+    DEFINE_SIZE_STATIC (4);
+  };
+
+  struct driver_context_t
+  {
+    static const bool in_place = false;
+    enum Flags
+    {
+      SetMark		= 0x8000,	/* If set, mark the current glyph. */
+      DontAdvance	= 0x4000,	/* If set, don't advance to the next glyph before
+					 * going to the new state.  This does not mean
+					 * that the glyph pointed to is the same one as
+					 * before. If you've made insertions immediately
+					 * downstream of the current glyph, the next glyph
+					 * processed would in fact be the first one
+					 * inserted. */
+      CurrentIsKashidaLike= 0x2000,	/* If set, and the currentInsertList is nonzero,
+					 * then the specified glyph list will be inserted
+					 * as a kashida-like insertion, either before or
+					 * after the current glyph (depending on the state
+					 * of the currentInsertBefore flag). If clear, and
+					 * the currentInsertList is nonzero, then the
+					 * specified glyph list will be inserted as a
+					 * split-vowel-like insertion, either before or
+					 * after the current glyph (depending on the state
+					 * of the currentInsertBefore flag). */
+      MarkedIsKashidaLike= 0x1000,	/* If set, and the markedInsertList is nonzero,
+					 * then the specified glyph list will be inserted
+					 * as a kashida-like insertion, either before or
+					 * after the marked glyph (depending on the state
+					 * of the markedInsertBefore flag). If clear, and
+					 * the markedInsertList is nonzero, then the
+					 * specified glyph list will be inserted as a
+					 * split-vowel-like insertion, either before or
+					 * after the marked glyph (depending on the state
+					 * of the markedInsertBefore flag). */
+      CurrentInsertBefore= 0x0800,	/* If set, specifies that insertions are to be made
+					 * to the left of the current glyph. If clear,
+					 * they're made to the right of the current glyph. */
+      MarkedInsertBefore= 0x0400,	/* If set, specifies that insertions are to be
+					 * made to the left of the marked glyph. If clear,
+					 * they're made to the right of the marked glyph. */
+      CurrentInsertCount= 0x3E0,	/* This 5-bit field is treated as a count of the
+					 * number of glyphs to insert at the current
+					 * position. Since zero means no insertions, the
+					 * largest number of insertions at any given
+					 * current location is 31 glyphs. */
+      MarkedInsertCount= 0x001F,	/* This 5-bit field is treated as a count of the
+					 * number of glyphs to insert at the marked
+					 * position. Since zero means no insertions, the
+					 * largest number of insertions at any given
+					 * marked location is 31 glyphs. */
+    };
+
+    inline driver_context_t (const InsertionSubtable *table,
+			     hb_aat_apply_context_t *c_) :
+	ret (false),
+	c (c_),
+	mark_set (false),
+	mark (0),
+	insertionAction (table+table->insertionAction) {}
+
+    inline bool is_actionable (StateTableDriver<EntryData> *driver,
+			       const Entry<EntryData> *entry)
+    {
+      return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) &&
+	     (entry->data.currentInsertIndex != 0xFFFF ||entry->data.markedInsertIndex != 0xFFFF);
+    }
+    inline bool transition (StateTableDriver<EntryData> *driver,
+			    const Entry<EntryData> *entry)
+    {
+      hb_buffer_t *buffer = driver->buffer;
+      unsigned int flags = entry->flags;
+
+      if (entry->data.markedInsertIndex != 0xFFFF && mark_set)
+      {
+	unsigned int count = (flags & MarkedInsertCount);
+	unsigned int start = entry->data.markedInsertIndex;
+	const GlyphID *glyphs = &insertionAction[start];
+	if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
+
+	bool before = flags & MarkedInsertBefore;
+
+	unsigned int end = buffer->out_len;
+	buffer->move_to (mark);
+
+	if (buffer->idx < buffer->len && !before)
+	  buffer->copy_glyph ();
+	/* TODO We ignore KashidaLike setting. */
+	for (unsigned int i = 0; i < count; i++)
+	  buffer->output_glyph (glyphs[i]);
+	if (buffer->idx < buffer->len && !before)
+	  buffer->skip_glyph ();
+
+	buffer->move_to (end + count);
+
+	buffer->unsafe_to_break_from_outbuffer (mark, MIN (buffer->idx + 1, buffer->len));
+      }
+
+      if (entry->data.currentInsertIndex != 0xFFFF)
+      {
+	unsigned int count = (flags & CurrentInsertCount) >> 5;
+	unsigned int start = entry->data.currentInsertIndex;
+	const GlyphID *glyphs = &insertionAction[start];
+	if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
+
+	bool before = flags & CurrentInsertBefore;
+
+	unsigned int end = buffer->out_len;
+
+	if (buffer->idx < buffer->len && !before)
+	  buffer->copy_glyph ();
+	/* TODO We ignore KashidaLike setting. */
+	for (unsigned int i = 0; i < count; i++)
+	  buffer->output_glyph (glyphs[i]);
+	if (buffer->idx < buffer->len && !before)
+	  buffer->skip_glyph ();
+
+	/* Humm. Not sure where to move to.  There's this wording under
+	 * DontAdvance flag:
+	 *
+	 * "If set, don't update the glyph index before going to the new state.
+	 * This does not mean that the glyph pointed to is the same one as
+	 * before. If you've made insertions immediately downstream of the
+	 * current glyph, the next glyph processed would in fact be the first
+	 * one inserted."
+	 *
+	 * This suggests that if DontAdvance is NOT set, we should move to
+	 * end+count.  If it *was*, then move to end, such that newly inserted
+	 * glyphs are now visible.
+	 *
+	 * https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417
+	 */
+	buffer->move_to ((flags & DontAdvance) ? end : end + count);
+      }
+
+      if (flags & SetMark)
+      {
+	mark_set = true;
+	mark = buffer->out_len;
+      }
+
+      return true;
+    }
+
+    public:
+    bool ret;
+    private:
+    hb_aat_apply_context_t *c;
+    bool mark_set;
+    unsigned int mark;
+    const UnsizedArrayOf<GlyphID> &insertionAction;
+  };
+
   inline bool apply (hb_aat_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    /* TODO */
-    return_trace (false);
+
+    driver_context_t dc (this, c);
+
+    StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
+    driver.drive (&dc);
+
+    return_trace (dc.ret);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    /* TODO */
-    return_trace (true);
+    /* The rest of array sanitizations are done at run-time. */
+    return_trace (c->check_struct (this) && machine.sanitize (c) &&
+		  insertionAction);
   }
+
+  protected:
+  StateTable<EntryData>
+		machine;
+  LOffsetTo<UnsizedArrayOf<GlyphID>, false>
+		insertionAction;	/* Byte offset from stateHeader to the start of
+					 * the insertion glyph table. */
+  public:
+  DEFINE_SIZE_STATIC (20);
 };
 
 
@@ -559,9 +755,27 @@
   friend struct Chain;
 
   inline unsigned int get_size (void) const { return length; }
-  inline unsigned int get_type (void) const { return coverage & 0xFF; }
+  inline unsigned int get_type (void) const { return coverage & SubtableType; }
 
-  enum Type {
+  enum Coverage
+  {
+    Vertical		= 0x80000000,	/* If set, this subtable will only be applied
+					 * to vertical text. If clear, this subtable
+					 * will only be applied to horizontal text. */
+    Backwards		= 0x40000000,	/* If set, this subtable will process glyphs
+					 * in descending order. If clear, it will
+					 * process the glyphs in ascending order. */
+    AllDirections	= 0x20000000,	/* If set, this subtable will be applied to
+					 * both horizontal and vertical text (i.e.
+					 * the state of bit 0x80000000 is ignored). */
+    Logical		= 0x10000000,	/* If set, this subtable will process glyphs
+					 * in logical order (or reverse logical order,
+					 * depending on the value of bit 0x80000000). */
+    Reserved		= 0x0FFFFF00,	/* Reserved, set to zero. */
+    SubtableType	= 0x000000FF,	/* Subtable type; see following table. */
+  };
+  enum Type
+  {
     Rearrangement	= 0,
     Contextual		= 1,
     Ligature		= 2,
@@ -569,11 +783,6 @@
     Insertion		= 5
   };
 
-  inline void apply (hb_aat_apply_context_t *c) const
-  {
-    dispatch (c);
-  }
-
   template <typename context_t>
   inline typename context_t::return_t dispatch (context_t *c) const
   {
@@ -619,21 +828,87 @@
 {
   inline void apply (hb_aat_apply_context_t *c) const
   {
-    const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount);
+    uint32_t flags = defaultFlags;
+    {
+      /* Compute applicable flags.  TODO Should move this to planning
+       * stage and take user-requested features into account. */
+      unsigned int count = featureCount;
+      for (unsigned i = 0; i < count; i++)
+      {
+        const Feature &feature = featureZ[i];
+	if (false) /* XXX Check if feature enabled... */
+	{
+	  flags &= feature.disableFlags;
+	  flags |= feature.enableFlags;
+	}
+      }
+    }
+
+    const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount);
     unsigned int count = subtableCount;
     for (unsigned int i = 0; i < count; i++)
     {
+      bool reverse;
+
+      if (!(subtable->subFeatureFlags & flags))
+        goto skip;
+
+      if (!(subtable->coverage & ChainSubtable::AllDirections) &&
+	  HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
+	  bool (subtable->coverage & ChainSubtable::Vertical))
+        goto skip;
+
+      /* Buffer contents is always in logical direction.  Determine if
+       * we need to reverse before applying this subtable.  We reverse
+       * back after if we did reverse indeed.
+       *
+       * Quoting the spac:
+       * """
+       * Bits 28 and 30 of the coverage field control the order in which
+       * glyphs are processed when the subtable is run by the layout engine.
+       * Bit 28 is used to indicate if the glyph processing direction is
+       * the same as logical order or layout order. Bit 30 is used to
+       * indicate whether glyphs are processed forwards or backwards within
+       * that order.
+
+		Bit 30	Bit 28	Interpretation for Horizontal Text
+		0	0	The subtable is processed in layout order
+				(the same order as the glyphs, which is
+				always left-to-right).
+		1	0	The subtable is processed in reverse layout order
+				(the order opposite that of the glyphs, which is
+				always right-to-left).
+		0	1	The subtable is processed in logical order
+				(the same order as the characters, which may be
+				left-to-right or right-to-left).
+		1	1	The subtable is processed in reverse logical order
+				(the order opposite that of the characters, which
+				may be right-to-left or left-to-right).
+       */
+      reverse = subtable->coverage & ChainSubtable::Logical ?
+		bool (subtable->coverage & ChainSubtable::Backwards) :
+		bool (subtable->coverage & ChainSubtable::Backwards) !=
+		HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
+
       if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
-      {
-	c->set_lookup_index (c->lookup_index + 1);
-	continue;
-      }
+        goto skip;
 
-      subtable->apply (c);
-      subtable = &StructAfter<ChainSubtable> (*subtable);
+      if (reverse)
+        c->buffer->reverse ();
 
+      c->sanitizer.set_object (*subtable);
+
+      subtable->dispatch (c);
+
+      if (reverse)
+        c->buffer->reverse ();
+
       (void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index);
 
+      if (unlikely (!c->buffer->successful)) return;
+
+    skip:
+      subtable = &StructAfter<ChainSubtable> (*subtable);
       c->set_lookup_index (c->lookup_index + 1);
     }
   }
@@ -640,7 +915,7 @@
 
   inline unsigned int get_size (void) const { return length; }
 
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int major) const
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int version) const
   {
     TRACE_SANITIZE (this);
     if (!length.sanitize (c) ||
@@ -648,10 +923,10 @@
 	!c->check_range (this, length))
       return_trace (false);
 
-    if (!c->check_array (featureZ, featureZ[0].static_size, featureCount))
+    if (!c->check_array (featureZ.arrayZ, featureCount))
       return_trace (false);
 
-    const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount);
+    const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount);
     unsigned int count = subtableCount;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -669,9 +944,9 @@
   HBUINT32	featureCount;	/* Number of feature subtable entries. */
   HBUINT32	subtableCount;	/* The number of subtables in the chain. */
 
-  Feature	featureZ[VAR];	/* Features. */
-/*ChainSubtable	subtableX[VAR];*//* Subtables. */
-/*subtableGlyphCoverageArray*/	/* Only if major == 3. */
+  UnsizedArrayOf<Feature>	featureZ;	/* Features. */
+/*ChainSubtable	firstSubtable;*//* Subtables. */
+/*subtableGlyphCoverageArray*/	/* Only if version >= 3. We don't use. */
 
   public:
   DEFINE_SIZE_MIN (16);
@@ -679,7 +954,7 @@
 
 
 /*
- * The 'mort'/'morx' Tables
+ * The 'morx' Table
  */
 
 struct morx
@@ -686,14 +961,18 @@
 {
   static const hb_tag_t tableTag = HB_AAT_TAG_morx;
 
+  inline bool has_data (void) const { return version != 0; }
+
   inline void apply (hb_aat_apply_context_t *c) const
   {
+    if (unlikely (!c->buffer->successful)) return;
     c->set_lookup_index (0);
-    const Chain *chain = chainsZ;
+    const Chain *chain = &firstChain;
     unsigned int count = chainCount;
     for (unsigned int i = 0; i < count; i++)
     {
       chain->apply (c);
+      if (unlikely (!c->buffer->successful)) return;
       chain = &StructAfter<Chain> (*chain);
     }
   }
@@ -701,16 +980,15 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!version.sanitize (c) ||
-	(version.major >> (sizeof (HBUINT32) == 4 ? 1 : 0)) != 1 ||
+    if (!version.sanitize (c) || version < 2 ||
 	!chainCount.sanitize (c))
       return_trace (false);
 
-    const Chain *chain = chainsZ;
+    const Chain *chain = &firstChain;
     unsigned int count = chainCount;
     for (unsigned int i = 0; i < count; i++)
     {
-      if (!chain->sanitize (c, version.major))
+      if (!chain->sanitize (c, version))
 	return_trace (false);
       chain = &StructAfter<Chain> (*chain);
     }
@@ -719,11 +997,12 @@
   }
 
   protected:
-  FixedVersion<>version;	/* Version number of the glyph metamorphosis table.
-				 * 1 for mort, 2 or 3 for morx. */
+  HBUINT16	version;	/* Version number of the glyph metamorphosis table.
+				 * 2 or 3. */
+  HBUINT16	unused;		/* Set to 0. */
   HBUINT32	chainCount;	/* Number of metamorphosis chains contained in this
 				 * table. */
-  Chain		chainsZ[VAR];	/* Chains. */
+  Chain		firstChain;	/* Chains. */
 
   public:
   DEFINE_SIZE_MIN (8);

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -46,29 +46,33 @@
 {
   friend struct TrackData;
 
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base,
-			unsigned int size) const
+  inline float get_track_value () const
   {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  (valuesZ.sanitize (c, base, size))));
+    return track.to_float ();
   }
 
-  private:
-  inline float get_track_value () const
+  inline int get_value (const void *base,
+			unsigned int index,
+			unsigned int nSizes) const
   {
-    return track.to_float ();
+    return hb_array_t<FWORD> ((base+valuesZ).arrayZ, nSizes)[index];
   }
 
-  inline int get_value (const void *base, unsigned int index) const
+  public:
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base,
+			unsigned int nSizes) const
   {
-    return (base+valuesZ)[index];
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  (valuesZ.sanitize (c, base, nSizes))));
   }
 
   protected:
   Fixed		track;		/* Track value for this record. */
-  NameID	trackNameID;	/* The 'name' table index for this track */
-  OffsetTo<UnsizedArrayOf<FWORD> >
+  NameID	trackNameID;	/* The 'name' table index for this track.
+				 * (a short word or phrase like "loose"
+				 * or "very tight") */
+  OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false>
 		valuesZ;	/* Offset from start of tracking table to
 				 * per-size tracking values for this track. */
 
@@ -78,15 +82,22 @@
 
 struct TrackData
 {
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  inline float interpolate_at (unsigned int idx,
+			       float target_size,
+			       const TrackTableEntry &trackTableEntry,
+			       const void *base) const
   {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  sizeTable.sanitize (c, base, nSizes) &&
-		  trackTable.sanitize (c, nTracks, base, nSizes));
+    unsigned int sizes = nSizes;
+    hb_array_t<Fixed> size_table ((base+sizeTable).arrayZ, sizes);
+
+    float s0 = size_table[idx].to_float ();
+    float s1 = size_table[idx + 1].to_float ();
+    float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0);
+    return t * trackTableEntry.get_value (base, idx + 1, sizes) +
+	   (1.f - t) * trackTableEntry.get_value (base, idx, sizes);
   }
 
-  inline float get_tracking (const void *base, float ptem) const
+  inline int get_tracking (const void *base, float ptem) const
   {
     /* CoreText points are CSS pixels (96 per inch),
      * NOT typographic points (72 per inch).
@@ -94,48 +105,59 @@
      * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
      */
     float csspx = ptem * 96.f / 72.f;
-    Fixed fixed_size;
-    fixed_size.set_float (csspx);
 
-    /* XXX Clean this up. Make it work with nSizes==1 and 0. */
+    /*
+     * Choose track.
+     */
+    const TrackTableEntry *trackTableEntry = nullptr;
+    unsigned int count = nTracks;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      /* Note: Seems like the track entries are sorted by values.  But the
+       * spec doesn't explicitly say that.  It just mentions it in the example. */
 
-    unsigned int sizes = nSizes;
+      /* For now we only seek for track entries with zero tracking value */
 
-    const TrackTableEntry *trackTableEntry = nullptr;
-    for (unsigned int i = 0; i < sizes; ++i)
-      // For now we only seek for track entries with zero tracking value
       if (trackTable[i].get_track_value () == 0.f)
-        trackTableEntry = &trackTable[0];
-
-    // We couldn't match any, exit
+      {
+	trackTableEntry = &trackTable[i];
+	break;
+      }
+    }
     if (!trackTableEntry) return 0.;
 
+    /*
+     * Choose size.
+     */
+    unsigned int sizes = nSizes;
+    if (!sizes) return 0.;
+    if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
+
     /* TODO bfind() */
+    hb_array_t<Fixed> size_table ((base+sizeTable).arrayZ, sizes);
     unsigned int size_index;
-    UnsizedArrayOf<Fixed> size_table = base+sizeTable;
-    for (size_index = 0; size_index < sizes; ++size_index)
-      if (size_table[size_index] >= fixed_size)
+    for (size_index = 0; size_index < sizes; size_index++)
+      if (size_table[size_index].to_float () >= csspx)
         break;
 
-    // TODO(ebraminio): We don't attempt to extrapolate to larger or
-    // smaller values for now but we should do, per spec
-    if (size_index == sizes)
-      return trackTableEntry->get_value (base, sizes - 1);
-    if (size_index == 0 || size_table[size_index] == fixed_size)
-      return trackTableEntry->get_value (base, size_index);
+    return round (interpolate_at (size_index ? size_index - 1 : 0, csspx,
+				  *trackTableEntry, base));
+  }
 
-    float s0 = size_table[size_index - 1].to_float ();
-    float s1 = size_table[size_index].to_float ();
-    float t = (csspx - s0) / (s1 - s0);
-    return (float) t * trackTableEntry->get_value (base, size_index) +
-	   ((float) 1.0 - t) * trackTableEntry->get_value (base, size_index - 1);
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  sizeTable.sanitize (c, base, nSizes) &&
+		  trackTable.sanitize (c, nTracks, base, nSizes));
   }
 
   protected:
   HBUINT16	nTracks;	/* Number of separate tracks included in this table. */
   HBUINT16	nSizes;		/* Number of point sizes included in this table. */
-  LOffsetTo<UnsizedArrayOf<Fixed> >
-		sizeTable;	/* Offset to array[nSizes] of size values. */
+  LOffsetTo<UnsizedArrayOf<Fixed>, false>
+		sizeTable;	/* Offset from start of the tracking table to
+				 * Array[nSizes] of size values.. */
   UnsizedArrayOf<TrackTableEntry>
 		trackTable;	/* Array[nTracks] of TrackTableEntry records. */
 
@@ -147,6 +169,8 @@
 {
   static const hb_tag_t tableTag = HB_AAT_TAG_trak;
 
+  inline bool has_data (void) const { return version.to_int () != 0; }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -168,25 +192,25 @@
     if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
     {
       const TrackData &trackData = this+horizData;
-      float tracking = trackData.get_tracking (this, ptem);
-      hb_position_t advance_to_add = c->font->em_scalef_x (tracking / 2);
+      int tracking = trackData.get_tracking (this, ptem);
+      hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2);
+      hb_position_t advance_to_add = c->font->em_scalef_x (tracking);
       foreach_grapheme (buffer, start, end)
       {
-	buffer->pos[start].x_offset += advance_to_add;
 	buffer->pos[start].x_advance += advance_to_add;
-	buffer->pos[end].x_advance += advance_to_add;
+	buffer->pos[start].x_offset += offset_to_add;
       }
     }
     else
     {
       const TrackData &trackData = this+vertData;
-      float tracking = trackData.get_tracking (this, ptem);
-      hb_position_t advance_to_add = c->font->em_scalef_y (tracking / 2);
+      int tracking = trackData.get_tracking (this, ptem);
+      hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2);
+      hb_position_t advance_to_add = c->font->em_scalef_y (tracking);
       foreach_grapheme (buffer, start, end)
       {
-	buffer->pos[start].y_offset += advance_to_add;
 	buffer->pos[start].y_advance += advance_to_add;
-	buffer->pos[end].y_advance += advance_to_add;
+	buffer->pos[start].y_offset += offset_to_add;
       }
     }
 
@@ -194,15 +218,17 @@
   }
 
   protected:
-  FixedVersion<>	version;	/* Version of the tracking table--currently
-					 * 0x00010000u for version 1.0. */
-  HBUINT16		format; 	/* Format of the tracking table */
-  OffsetTo<TrackData>	horizData;	/* TrackData for horizontal text */
-  OffsetTo<TrackData>	vertData;	/* TrackData for vertical text */
+  FixedVersion<>	version;	/* Version of the tracking table
+					 * (0x00010000u for version 1.0). */
+  HBUINT16		format; 	/* Format of the tracking table (set to 0). */
+  OffsetTo<TrackData>	horizData;	/* Offset from start of tracking table to TrackData
+					 * for horizontal text (or 0 if none). */
+  OffsetTo<TrackData>	vertData;	/* Offset from start of tracking table to TrackData
+					 * for vertical text (or 0 if none). */
   HBUINT16		reserved;	/* Reserved. Set to 0. */
 
   public:
-  DEFINE_SIZE_MIN (12);
+  DEFINE_SIZE_STATIC (12);
 };
 
 } /* namespace AAT */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -36,8 +36,101 @@
 #include "hb-aat-layout-trak-table.hh"
 #include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise.
 
+
+/* Table data courtesy of Apple.  Converted from mnemonics to integers
+ * when moving to this file. */
+static const hb_aat_feature_mapping_t feature_mappings[] =
+{
+  {HB_TAG ('c','2','p','c'),	38/*kUpperCaseType*/,			2/*kUpperCasePetiteCapsSelector*/,		0/*kDefaultUpperCaseSelector*/},
+  {HB_TAG ('c','2','s','c'),	38/*kUpperCaseType*/,			1/*kUpperCaseSmallCapsSelector*/,		0/*kDefaultUpperCaseSelector*/},
+  {HB_TAG ('c','a','l','t'),	36/*kContextualAlternatesType*/,	0/*kContextualAlternatesOnSelector*/,		1/*kContextualAlternatesOffSelector*/},
+  {HB_TAG ('c','a','s','e'),	33/*kCaseSensitiveLayoutType*/,		0/*kCaseSensitiveLayoutOnSelector*/,		1/*kCaseSensitiveLayoutOffSelector*/},
+  {HB_TAG ('c','l','i','g'),	1/*kLigaturesType*/,			18/*kContextualLigaturesOnSelector*/,		19/*kContextualLigaturesOffSelector*/},
+  {HB_TAG ('c','p','s','p'),	33/*kCaseSensitiveLayoutType*/,		2/*kCaseSensitiveSpacingOnSelector*/,		3/*kCaseSensitiveSpacingOffSelector*/},
+  {HB_TAG ('c','s','w','h'),	36/*kContextualAlternatesType*/,	4/*kContextualSwashAlternatesOnSelector*/,	5/*kContextualSwashAlternatesOffSelector*/},
+  {HB_TAG ('d','l','i','g'),	1/*kLigaturesType*/,			4/*kRareLigaturesOnSelector*/,			5/*kRareLigaturesOffSelector*/},
+  {HB_TAG ('e','x','p','t'),	20/*kCharacterShapeType*/,		10/*kExpertCharactersSelector*/,		16},
+  {HB_TAG ('f','r','a','c'),	11/*kFractionsType*/,			2/*kDiagonalFractionsSelector*/,		0/*kNoFractionsSelector*/},
+  {HB_TAG ('f','w','i','d'),	22/*kTextSpacingType*/,			1/*kMonospacedTextSelector*/,			7},
+  {HB_TAG ('h','a','l','t'),	22/*kTextSpacingType*/,			6/*kAltHalfWidthTextSelector*/,			7},
+  {HB_TAG ('h','i','s','t'),	1/*kLigaturesType*/,			20/*kHistoricalLigaturesOnSelector*/,		21/*kHistoricalLigaturesOffSelector*/},
+  {HB_TAG ('h','k','n','a'),	34/*kAlternateKanaType*/,		0/*kAlternateHorizKanaOnSelector*/,		1/*kAlternateHorizKanaOffSelector*/,	},
+  {HB_TAG ('h','l','i','g'),	1/*kLigaturesType*/,			20/*kHistoricalLigaturesOnSelector*/,		21/*kHistoricalLigaturesOffSelector*/},
+  {HB_TAG ('h','n','g','l'),	23/*kTransliterationType*/,		1/*kHanjaToHangulSelector*/,			0/*kNoTransliterationSelector*/},
+  {HB_TAG ('h','o','j','o'),	20/*kCharacterShapeType*/,		12/*kHojoCharactersSelector*/,			16},
+  {HB_TAG ('h','w','i','d'),	22/*kTextSpacingType*/,			2/*kHalfWidthTextSelector*/,			7},
+  {HB_TAG ('i','t','a','l'),	32/*kItalicCJKRomanType*/,		2/*kCJKItalicRomanOnSelector*/,			3/*kCJKItalicRomanOffSelector*/},
+  {HB_TAG ('j','p','0','4'),	20/*kCharacterShapeType*/,		11/*kJIS2004CharactersSelector*/,		16},
+  {HB_TAG ('j','p','7','8'),	20/*kCharacterShapeType*/,		2/*kJIS1978CharactersSelector*/,		16},
+  {HB_TAG ('j','p','8','3'),	20/*kCharacterShapeType*/,		3/*kJIS1983CharactersSelector*/,		16},
+  {HB_TAG ('j','p','9','0'),	20/*kCharacterShapeType*/,		4/*kJIS1990CharactersSelector*/,		16},
+  {HB_TAG ('l','i','g','a'),	1/*kLigaturesType*/,			2/*kCommonLigaturesOnSelector*/,		3/*kCommonLigaturesOffSelector*/},
+  {HB_TAG ('l','n','u','m'),	21/*kNumberCaseType*/,			1/*kUpperCaseNumbersSelector*/,			2},
+  {HB_TAG ('m','g','r','k'),	15/*kMathematicalExtrasType*/,		10/*kMathematicalGreekOnSelector*/,		11/*kMathematicalGreekOffSelector*/},
+  {HB_TAG ('n','l','c','k'),	20/*kCharacterShapeType*/,		13/*kNLCCharactersSelector*/,			16},
+  {HB_TAG ('o','n','u','m'),	21/*kNumberCaseType*/,			0/*kLowerCaseNumbersSelector*/,			2},
+  {HB_TAG ('o','r','d','n'),	10/*kVerticalPositionType*/,		3/*kOrdinalsSelector*/,				0/*kNormalPositionSelector*/},
+  {HB_TAG ('p','a','l','t'),	22/*kTextSpacingType*/,			5/*kAltProportionalTextSelector*/,		7},
+  {HB_TAG ('p','c','a','p'),	37/*kLowerCaseType*/,			2/*kLowerCasePetiteCapsSelector*/,		0/*kDefaultLowerCaseSelector*/},
+  {HB_TAG ('p','k','n','a'),	22/*kTextSpacingType*/,			0/*kProportionalTextSelector*/,			7},
+  {HB_TAG ('p','n','u','m'),	6/*kNumberSpacingType*/,		1/*kProportionalNumbersSelector*/,		4},
+  {HB_TAG ('p','w','i','d'),	22/*kTextSpacingType*/,			0/*kProportionalTextSelector*/,			7},
+  {HB_TAG ('q','w','i','d'),	22/*kTextSpacingType*/,			4/*kQuarterWidthTextSelector*/,			7},
+  {HB_TAG ('r','u','b','y'),	28/*kRubyKanaType*/,			2/*kRubyKanaOnSelector*/,			3/*kRubyKanaOffSelector*/},
+  {HB_TAG ('s','i','n','f'),	10/*kVerticalPositionType*/,		4/*kScientificInferiorsSelector*/,		0/*kNormalPositionSelector*/},
+  {HB_TAG ('s','m','c','p'),	37/*kLowerCaseType*/,			1/*kLowerCaseSmallCapsSelector*/,		0/*kDefaultLowerCaseSelector*/},
+  {HB_TAG ('s','m','p','l'),	20/*kCharacterShapeType*/,		1/*kSimplifiedCharactersSelector*/,		16},
+  {HB_TAG ('s','s','0','1'),	35/*kStylisticAlternativesType*/,	2/*kStylisticAltOneOnSelector*/,		3/*kStylisticAltOneOffSelector*/},
+  {HB_TAG ('s','s','0','2'),	35/*kStylisticAlternativesType*/,	4/*kStylisticAltTwoOnSelector*/,		5/*kStylisticAltTwoOffSelector*/},
+  {HB_TAG ('s','s','0','3'),	35/*kStylisticAlternativesType*/,	6/*kStylisticAltThreeOnSelector*/,		7/*kStylisticAltThreeOffSelector*/},
+  {HB_TAG ('s','s','0','4'),	35/*kStylisticAlternativesType*/,	8/*kStylisticAltFourOnSelector*/,		9/*kStylisticAltFourOffSelector*/},
+  {HB_TAG ('s','s','0','5'),	35/*kStylisticAlternativesType*/,	10/*kStylisticAltFiveOnSelector*/,		11/*kStylisticAltFiveOffSelector*/},
+  {HB_TAG ('s','s','0','6'),	35/*kStylisticAlternativesType*/,	12/*kStylisticAltSixOnSelector*/,		13/*kStylisticAltSixOffSelector*/},
+  {HB_TAG ('s','s','0','7'),	35/*kStylisticAlternativesType*/,	14/*kStylisticAltSevenOnSelector*/,		15/*kStylisticAltSevenOffSelector*/},
+  {HB_TAG ('s','s','0','8'),	35/*kStylisticAlternativesType*/,	16/*kStylisticAltEightOnSelector*/,		17/*kStylisticAltEightOffSelector*/},
+  {HB_TAG ('s','s','0','9'),	35/*kStylisticAlternativesType*/,	18/*kStylisticAltNineOnSelector*/,		19/*kStylisticAltNineOffSelector*/},
+  {HB_TAG ('s','s','1','0'),	35/*kStylisticAlternativesType*/,	20/*kStylisticAltTenOnSelector*/,		21/*kStylisticAltTenOffSelector*/},
+  {HB_TAG ('s','s','1','1'),	35/*kStylisticAlternativesType*/,	22/*kStylisticAltElevenOnSelector*/,		23/*kStylisticAltElevenOffSelector*/},
+  {HB_TAG ('s','s','1','2'),	35/*kStylisticAlternativesType*/,	24/*kStylisticAltTwelveOnSelector*/,		25/*kStylisticAltTwelveOffSelector*/},
+  {HB_TAG ('s','s','1','3'),	35/*kStylisticAlternativesType*/,	26/*kStylisticAltThirteenOnSelector*/,		27/*kStylisticAltThirteenOffSelector*/},
+  {HB_TAG ('s','s','1','4'),	35/*kStylisticAlternativesType*/,	28/*kStylisticAltFourteenOnSelector*/,		29/*kStylisticAltFourteenOffSelector*/},
+  {HB_TAG ('s','s','1','5'),	35/*kStylisticAlternativesType*/,	30/*kStylisticAltFifteenOnSelector*/,		31/*kStylisticAltFifteenOffSelector*/},
+  {HB_TAG ('s','s','1','6'),	35/*kStylisticAlternativesType*/,	32/*kStylisticAltSixteenOnSelector*/,		33/*kStylisticAltSixteenOffSelector*/},
+  {HB_TAG ('s','s','1','7'),	35/*kStylisticAlternativesType*/,	34/*kStylisticAltSeventeenOnSelector*/,		35/*kStylisticAltSeventeenOffSelector*/},
+  {HB_TAG ('s','s','1','8'),	35/*kStylisticAlternativesType*/,	36/*kStylisticAltEighteenOnSelector*/,		37/*kStylisticAltEighteenOffSelector*/},
+  {HB_TAG ('s','s','1','9'),	35/*kStylisticAlternativesType*/,	38/*kStylisticAltNineteenOnSelector*/,		39/*kStylisticAltNineteenOffSelector*/},
+  {HB_TAG ('s','s','2','0'),	35/*kStylisticAlternativesType*/,	40/*kStylisticAltTwentyOnSelector*/,		41/*kStylisticAltTwentyOffSelector*/},
+  {HB_TAG ('s','u','b','s'),	10/*kVerticalPositionType*/,		2/*kInferiorsSelector*/,			0/*kNormalPositionSelector*/},
+  {HB_TAG ('s','u','p','s'),	10/*kVerticalPositionType*/,		1/*kSuperiorsSelector*/,			0/*kNormalPositionSelector*/},
+  {HB_TAG ('s','w','s','h'),	36/*kContextualAlternatesType*/,	2/*kSwashAlternatesOnSelector*/,		3/*kSwashAlternatesOffSelector*/},
+  {HB_TAG ('t','i','t','l'),	19/*kStyleOptionsType*/,		4/*kTitlingCapsSelector*/,			0/*kNoStyleOptionsSelector*/},
+  {HB_TAG ('t','n','a','m'),	20/*kCharacterShapeType*/,		14/*kTraditionalNamesCharactersSelector*/,	16},
+  {HB_TAG ('t','n','u','m'),	6/*kNumberSpacingType*/,		0/*kMonospacedNumbersSelector*/,		4},
+  {HB_TAG ('t','r','a','d'),	20/*kCharacterShapeType*/,		0/*kTraditionalCharactersSelector*/,		16},
+  {HB_TAG ('t','w','i','d'),	22/*kTextSpacingType*/,			3/*kThirdWidthTextSelector*/,			7},
+  {HB_TAG ('u','n','i','c'),	3/*kLetterCaseType*/,			14,						15},
+  {HB_TAG ('v','a','l','t'),	22/*kTextSpacingType*/,			5/*kAltProportionalTextSelector*/,		7},
+  {HB_TAG ('v','e','r','t'),	4/*kVerticalSubstitutionType*/,		0/*kSubstituteVerticalFormsOnSelector*/,	1/*kSubstituteVerticalFormsOffSelector*/},
+  {HB_TAG ('v','h','a','l'),	22/*kTextSpacingType*/,			6/*kAltHalfWidthTextSelector*/,			7},
+  {HB_TAG ('v','k','n','a'),	34/*kAlternateKanaType*/,		2/*kAlternateVertKanaOnSelector*/,		3/*kAlternateVertKanaOffSelector*/},
+  {HB_TAG ('v','p','a','l'),	22/*kTextSpacingType*/,			5/*kAltProportionalTextSelector*/,		7},
+  {HB_TAG ('v','r','t','2'),	4/*kVerticalSubstitutionType*/,		0/*kSubstituteVerticalFormsOnSelector*/,	1/*kSubstituteVerticalFormsOffSelector*/},
+  {HB_TAG ('z','e','r','o'),	14/*kTypographicExtrasType*/,		4/*kSlashedZeroOnSelector*/,			5/*kSlashedZeroOffSelector*/},
+};
+
+const hb_aat_feature_mapping_t *
+hb_aat_layout_find_feature_mapping (hb_tag_t tag)
+{
+  return (const hb_aat_feature_mapping_t *) bsearch (&tag,
+						     feature_mappings,
+						     ARRAY_LENGTH (feature_mappings),
+						     sizeof (feature_mappings[0]),
+						     hb_aat_feature_mapping_t::cmp);
+}
+
+
 /*
- * morx/kerx/trak/ankr
+ * morx/kerx/trak
  */
 
 static inline const AAT::morx&
@@ -54,28 +147,96 @@
     *blob = hb_ot_face_data (face)->morx.get_blob ();
   return morx;
 }
+static inline const AAT::kerx&
+_get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
+  {
+    if (blob)
+      *blob = hb_blob_get_empty ();
+    return Null(AAT::kerx);
+  }
+  const AAT::kerx& kerx = *(hb_ot_face_data (face)->kerx.get ());
+  if (blob)
+    *blob = hb_ot_face_data (face)->kerx.get_blob ();
+  return kerx;
+}
+static inline const AAT::ankr&
+_get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
+  {
+    if (blob)
+      *blob = hb_blob_get_empty ();
+    return Null(AAT::ankr);
+  }
+  const AAT::ankr& ankr = *(hb_ot_face_data (face)->ankr.get ());
+  if (blob)
+    *blob = hb_ot_face_data (face)->ankr.get_blob ();
+  return ankr;
+}
+static inline const AAT::trak&
+_get_trak (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::trak);
+  return *(hb_ot_face_data (face)->trak.get ());
+}
 
+
+hb_bool_t
+hb_aat_layout_has_substitution (hb_face_t *face)
+{
+  return _get_morx (face).has_data ();
+}
+
 void
-hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
+hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
+			  hb_font_t *font,
+			  hb_buffer_t *buffer)
 {
   hb_blob_t *blob;
   const AAT::morx& morx = _get_morx (font->face, &blob);
 
-  AAT::hb_aat_apply_context_t c (font, buffer, blob);
+  AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
   morx.apply (&c);
 }
 
+
+hb_bool_t
+hb_aat_layout_has_positioning (hb_face_t *face)
+{
+  return _get_kerx (face).has_data ();
+}
+
 void
-hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer)
+hb_aat_layout_position (hb_ot_shape_plan_t *plan,
+			hb_font_t *font,
+			hb_buffer_t *buffer)
 {
-#if 0
   hb_blob_t *blob;
-  const AAT::ankr& ankr = _get_ankr (font->face, &blob);
   const AAT::kerx& kerx = _get_kerx (font->face, &blob);
-  const AAT::trak& trak = _get_trak (font->face, &blob);
 
-  AAT::hb_aat_apply_context_t c (font, buffer, blob);
-  kerx.apply (&c, &ankr);
+  hb_blob_t *ankr_blob;
+  const AAT::ankr& ankr = _get_ankr (font->face, &ankr_blob);
+
+  AAT::hb_aat_apply_context_t c (plan, font, buffer, blob,
+				 ankr, ankr_blob->data + ankr_blob->length);
+  kerx.apply (&c);
+}
+
+hb_bool_t
+hb_aat_layout_has_tracking (hb_face_t *face)
+{
+  return _get_trak (face).has_data ();
+}
+
+void
+hb_aat_layout_track (hb_ot_shape_plan_t *plan,
+		     hb_font_t *font,
+		     hb_buffer_t *buffer)
+{
+  const AAT::trak& trak = _get_trak (font->face);
+
+  AAT::hb_aat_apply_context_t c (plan, font, buffer);
   trak.apply (&c);
-#endif
 }

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -29,15 +29,52 @@
 
 #include "hb.hh"
 
-#include "hb-font.hh"
-#include "hb-buffer.hh"
-#include "hb-open-type.hh"
+#include "hb-ot-shape.hh"
 
 
+struct hb_aat_feature_mapping_t
+{
+  hb_tag_t otFeatureTag;
+  uint16_t aatFeatureType;
+  uint16_t selectorToEnable;
+  uint16_t selectorToDisable;
+
+  static inline 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_;
+    return key < entry->otFeatureTag ? -1 :
+	   key > entry->otFeatureTag ? 1 :
+	   0;
+  }
+};
+
+HB_INTERNAL const hb_aat_feature_mapping_t *
+hb_aat_layout_find_feature_mapping (hb_tag_t tag);
+
+
+HB_INTERNAL hb_bool_t
+hb_aat_layout_has_substitution (hb_face_t *face);
+
 HB_INTERNAL void
-hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer);
+hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
+			  hb_font_t *font,
+			  hb_buffer_t *buffer);
 
+HB_INTERNAL hb_bool_t
+hb_aat_layout_has_positioning (hb_face_t *face);
+
 HB_INTERNAL void
-hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer);
+hb_aat_layout_position (hb_ot_shape_plan_t *plan,
+			hb_font_t *font,
+			hb_buffer_t *buffer);
 
+HB_INTERNAL hb_bool_t
+hb_aat_layout_has_tracking (hb_face_t *face);
+
+HB_INTERNAL void
+hb_aat_layout_track (hb_ot_shape_plan_t *plan,
+		     hb_font_t *font,
+		     hb_buffer_t *buffer);
+
 #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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-ltag-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -46,7 +46,7 @@
   }
 
   protected:
-  OffsetTo<UnsizedArrayOf<HBUINT8> >
+  OffsetTo<UnsizedArrayOf<HBUINT8>, HBUINT16, false>
 		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-atomic.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -49,17 +49,21 @@
 /* Defined externally, i.e. in config.h. */
 
 
-#elif !defined(HB_NO_MT) && defined(__ATOMIC_CONSUME)
+#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE)
 
 /* C++11-style GCC primitives. */
 
+#define _hb_memory_barrier()			__sync_synchronize ()
+
 #define hb_atomic_int_impl_add(AI, V)		__atomic_fetch_add ((AI), (V), __ATOMIC_ACQ_REL)
 #define hb_atomic_int_impl_set_relaxed(AI, V)	__atomic_store_n ((AI), (V), __ATOMIC_RELAXED)
+#define hb_atomic_int_impl_set(AI, V)		__atomic_store_n ((AI), (V), __ATOMIC_RELEASE)
 #define hb_atomic_int_impl_get_relaxed(AI)	__atomic_load_n ((AI), __ATOMIC_RELAXED)
+#define hb_atomic_int_impl_get(AI)		__atomic_load_n ((AI), __ATOMIC_ACQUIRE)
 
 #define hb_atomic_ptr_impl_set_relaxed(P, V)	__atomic_store_n ((P), (V), __ATOMIC_RELAXED)
 #define hb_atomic_ptr_impl_get_relaxed(P)	__atomic_load_n ((P), __ATOMIC_RELAXED)
-#define hb_atomic_ptr_impl_get(P)		__atomic_load_n ((P), __ATOMIC_CONSUME)
+#define hb_atomic_ptr_impl_get(P)		__atomic_load_n ((P), __ATOMIC_ACQUIRE)
 static inline bool
 _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
 {
@@ -74,13 +78,19 @@
 
 #include <atomic>
 
+#define _hb_memory_barrier()			std::atomic_thread_fence(std::memory_order_ack_rel)
+#define _hb_memory_r_barrier()			std::atomic_thread_fence(std::memory_order_acquire)
+#define _hb_memory_w_barrier()			std::atomic_thread_fence(std::memory_order_release)
+
 #define hb_atomic_int_impl_add(AI, V)		(reinterpret_cast<std::atomic<int> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
 #define hb_atomic_int_impl_set_relaxed(AI, V)	(reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_relaxed))
+#define hb_atomic_int_impl_set(AI, V)		(reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_release))
 #define hb_atomic_int_impl_get_relaxed(AI)	(reinterpret_cast<std::atomic<int> *> (AI)->load (std::memory_order_relaxed))
+#define hb_atomic_int_impl_get(AI)		(reinterpret_cast<std::atomic<int> *> (AI)->load (std::memory_order_acquire))
 
 #define hb_atomic_ptr_impl_set_relaxed(P, V)	(reinterpret_cast<std::atomic<void*> *> (P)->store ((V), std::memory_order_relaxed))
 #define hb_atomic_ptr_impl_get_relaxed(P)	(reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_relaxed))
-#define hb_atomic_ptr_impl_get(P)		(reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_consume))
+#define hb_atomic_ptr_impl_get(P)		(reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_acquire))
 static inline bool
 _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
 {
@@ -109,7 +119,7 @@
 #define hb_atomic_int_impl_add(AI, V)		InterlockedExchangeAdd ((LONG *) (AI), (V))
 static_assert ((sizeof (LONG) == sizeof (int)), "");
 
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)	(InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)	(InterlockedCompareExchangePointer ((P), (N), (O)) == (O))
 
 
 #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
@@ -137,10 +147,10 @@
   _hb_memory_r_barrier ();
   return result;
 }
-static inline bool _hb_compare_and_swap_ptr (const void **P, const void *O, const void *N)
+static inline bool _hb_compare_and_swap_ptr (void **P, void *O, void *N)
 {
   _hb_memory_w_barrier ();
-  int result = atomic_cas_ptr ((void **) P, (void *) O, (void *) N) == (void *) O;
+  bool result = atomic_cas_ptr (P, O, N) == O;
   _hb_memory_r_barrier ();
   return result;
 }
@@ -147,7 +157,7 @@
 
 #define hb_atomic_int_impl_add(AI, V)           _hb_fetch_and_add ((AI), (V))
 
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)       _hb_compare_and_swap_ptr ((const void **) (P), (O), (N))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       _hb_compare_and_swap_ptr ((P), (O), (N))
 
 
 #elif !defined(HB_NO_MT) && defined(__APPLE__)
@@ -164,12 +174,12 @@
 #define hb_atomic_int_impl_add(AI, V)		(OSAtomicAdd32Barrier ((V), (AI)) - (V))
 
 #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((O), (N), (P))
 #else
 #if __ppc64__ || __x86_64__ || __aarch64__
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)	OSAtomicCompareAndSwap64Barrier ((int64_t) (void *) (O), (int64_t) (void *) (N), (int64_t*) (P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)	OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
 #else
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)	OSAtomicCompareAndSwap32Barrier ((int32_t) (void *) (O), (int32_t) (void *) (N), (int32_t*) (P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)	OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
 #endif
 #endif
 
@@ -243,6 +253,12 @@
 #ifndef hb_atomic_ptr_impl_get_relaxed
 #define hb_atomic_ptr_impl_get_relaxed(P)	(*(P))
 #endif
+#ifndef hb_atomic_int_impl_set
+inline void hb_atomic_int_impl_set (int *AI, int v)	{ _hb_memory_w_barrier (); *AI = v; }
+#endif
+#ifndef hb_atomic_int_impl_get
+inline int hb_atomic_int_impl_get (int *AI)	{ int v = *AI; _hb_memory_r_barrier (); return v; }
+#endif
 #ifndef hb_atomic_ptr_impl_get
 inline void *hb_atomic_ptr_impl_get (void **P)	{ void *v = *P; _hb_memory_r_barrier (); return v; }
 #endif
@@ -252,7 +268,9 @@
 struct hb_atomic_int_t
 {
   inline void set_relaxed (int v_) const { hb_atomic_int_impl_set_relaxed (&v, v_); }
+  inline void set (int v_) const { hb_atomic_int_impl_set (&v, v_); }
   inline int get_relaxed (void) const { return hb_atomic_int_impl_get_relaxed (&v); }
+  inline int get (void) const { return hb_atomic_int_impl_get (&v); }
   inline int inc (void) { return hb_atomic_int_impl_add (&v,  1); }
   inline int dec (void) { return hb_atomic_int_impl_add (&v, -1); }
 
@@ -271,9 +289,9 @@
 
   inline void init (T* v_ = nullptr) { set_relaxed (v_); }
   inline void set_relaxed (T* v_) const { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
-  inline T *get_relaxed (void) const { return hb_atomic_ptr_impl_get_relaxed (&v); }
+  inline T *get_relaxed (void) const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); }
   inline T *get (void) const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); }
-  inline bool cmpexch (const T *old, T *new_) const{ return hb_atomic_ptr_impl_cmpexch (&v, old, new_); }
+  inline bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); }
 
   mutable T *v;
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -25,11 +25,6 @@
  * Red Hat Author(s): Behdad Esfahbod
  */
 
-/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
-#ifndef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 200809L
-#endif
-
 #include "hb.hh"
 #include "hb-blob.hh"
 
@@ -293,6 +288,8 @@
 {
   if (hb_object_is_inert (blob))
     return;
+  if (blob->immutable)
+    return;
 
   blob->immutable = true;
 }
@@ -510,8 +507,9 @@
 
 #if (defined(HAVE_MMAP) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP)
 static void
-_hb_mapped_file_destroy (hb_mapped_file_t *file)
+_hb_mapped_file_destroy (void *file_)
 {
+  hb_mapped_file_t *file = (hb_mapped_file_t *) file_;
 #ifdef HAVE_MMAP
   munmap (file->contents, file->length);
 #elif defined(_WIN32) || defined(__CYGWIN__)
@@ -574,18 +572,45 @@
   wchar_t * wchar_file_name = (wchar_t *) malloc (sizeof (wchar_t) * size);
   if (unlikely (wchar_file_name == nullptr)) goto fail_without_close;
   mbstowcs (wchar_file_name, file_name, size);
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+  {
+    CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 };
+    ceparams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
+    ceparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0xFFFF;
+    ceparams.dwFileFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0xFFF00000;
+    ceparams.dwSecurityQosFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0x000F0000;
+    ceparams.lpSecurityAttributes = nullptr;
+    ceparams.hTemplateFile = nullptr;
+    fd = CreateFile2 (wchar_file_name, GENERIC_READ, FILE_SHARE_READ,
+                      OPEN_EXISTING, &ceparams);
+  }
+#else
   fd = CreateFileW (wchar_file_name, GENERIC_READ, FILE_SHARE_READ, nullptr,
 		    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
 		    nullptr);
+#endif
   free (wchar_file_name);
 
   if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close;
 
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+  {
+    LARGE_INTEGER length;
+    GetFileSizeEx (fd, &length);
+    file->length = length.LowPart;
+    file->mapping = CreateFileMappingFromApp (fd, nullptr, PAGE_READONLY, length.QuadPart, nullptr);
+  }
+#else
   file->length = (unsigned long) GetFileSize (fd, nullptr);
   file->mapping = CreateFileMapping (fd, nullptr, PAGE_READONLY, 0, 0, nullptr);
+#endif
   if (unlikely (file->mapping == nullptr)) goto fail;
 
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+  file->contents = (char *) MapViewOfFileFromApp (file->mapping, FILE_MAP_READ, 0, 0);
+#else
   file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0);
+#endif
   if (unlikely (file->contents == nullptr)) goto fail;
 
   CloseHandle (fd);

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -440,8 +440,8 @@
 hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
 			      const char *buf,
 			      int buf_len, /* -1 means nul-terminated */
-			      const char **end_ptr, /* May be nullptr */
-			      hb_font_t *font, /* May be nullptr */
+			      const char **end_ptr, /* May be NULL */
+			      hb_font_t *font, /* May be NULL */
 			      hb_buffer_serialize_format_t format)
 {
   const char *end;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -182,7 +182,11 @@
   if (idx + count > len)
   {
     /* Under memory failure we might expose this area.  At least
-     * clean it up.  Oh well... */
+     * clean it up.  Oh well...
+     *
+     * Ideally, we should at least set Default_Ignorable bits on
+     * these, as well as consistent cluster values.  But the former
+     * is layering violation... */
     memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
   }
   len += count;
@@ -219,6 +223,7 @@
   unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ());
   flags = HB_BUFFER_FLAG_DEFAULT;
   replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+  invisible = 0;
 
   clear ();
 }
@@ -354,6 +359,8 @@
 {
   if (unlikely (!make_room_for (num_in, num_out))) return;
 
+  assert (idx + num_in <= len);
+
   merge_clusters (idx, idx + num_in);
 
   hb_glyph_info_t orig_info = info[idx];
@@ -369,37 +376,6 @@
   out_len += num_out;
 }
 
-void
-hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
-{
-  if (unlikely (!make_room_for (0, 1))) return;
-
-  out_info[out_len] = info[idx];
-  out_info[out_len].codepoint = glyph_index;
-
-  out_len++;
-}
-
-void
-hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info)
-{
-  if (unlikely (!make_room_for (0, 1))) return;
-
-  out_info[out_len] = glyph_info;
-
-  out_len++;
-}
-
-void
-hb_buffer_t::copy_glyph (void)
-{
-  if (unlikely (!make_room_for (0, 1))) return;
-
-  out_info[out_len] = info[idx];
-
-  out_len++;
-}
-
 bool
 hb_buffer_t::move_to (unsigned int i)
 {
@@ -429,8 +405,14 @@
     unsigned int count = out_len - i;
 
     /* This will blow in our face if memory allocation fails later
-     * in this same lookup... */
-    if (unlikely (idx < count && !shift_forward (count + 32))) return false;
+     * in this same lookup...
+     *
+     * We used to shift with extra 32 items, instead of the 0 below.
+     * But that would leave empty slots in the buffer in case of allocation
+     * failures.  Setting to zero for now to avoid other problems (see
+     * comments in shift_forward().  This can cause O(N^2) behavior more
+     * severely than adding 32 empty slots can... */
+    if (unlikely (idx < count && !shift_forward (count + 0))) return false;
 
     assert (idx >= count);
 
@@ -442,20 +424,7 @@
   return true;
 }
 
-void
-hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
-{
-  if (unlikely (out_info != info || out_len != idx)) {
-    if (unlikely (!make_room_for (1, 1))) return;
-    out_info[out_len] = info[idx];
-  }
-  out_info[out_len].codepoint = glyph_index;
 
-  idx++;
-  out_len++;
-}
-
-
 void
 hb_buffer_t::set_masks (hb_mask_t    value,
 			hb_mask_t    mask,
@@ -709,6 +678,7 @@
   HB_BUFFER_FLAG_DEFAULT,
   HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
   HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
+  0, /* invisible */
   HB_BUFFER_SCRATCH_FLAG_DEFAULT,
   HB_BUFFER_MAX_LEN_DEFAULT,
   HB_BUFFER_MAX_OPS_DEFAULT,
@@ -1028,7 +998,7 @@
  * are orthogonal to the scripts, and though they are related, they are
  * different concepts and should not be confused with each other.
  *
- * Use hb_language_from_string() to convert from ISO 639 language codes to
+ * Use hb_language_from_string() to convert from BCP 47 language tags to
  * #hb_language_t.
  *
  * Since: 0.9.2
@@ -1211,6 +1181,46 @@
 
 
 /**
+ * hb_buffer_set_invisible_glyph:
+ * @buffer: an #hb_buffer_t.
+ * @invisible: the invisible #hb_codepoint_t
+ *
+ * Sets the #hb_codepoint_t that replaces invisible characters in
+ * the shaping result.  If set to zero (default), the glyph for the
+ * U+0020 SPACE character is used.  Otherwise, this value is used
+ * verbatim.
+ *
+ * Since: 2.0.0
+ **/
+void
+hb_buffer_set_invisible_glyph (hb_buffer_t    *buffer,
+			       hb_codepoint_t  invisible)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->invisible = invisible;
+}
+
+/**
+ * hb_buffer_get_invisible_glyph:
+ * @buffer: an #hb_buffer_t.
+ *
+ * See hb_buffer_set_invisible_glyph().
+ *
+ * Return value: 
+ * The @buffer invisible #hb_codepoint_t.
+ *
+ * Since: 2.0.0
+ **/
+hb_codepoint_t
+hb_buffer_get_invisible_glyph (hb_buffer_t    *buffer)
+{
+  return buffer->invisible;
+}
+
+
+/**
  * hb_buffer_reset:
  * @buffer: an #hb_buffer_t.
  *
@@ -1499,6 +1509,8 @@
  * it will be set to the process's default language as returned by
  * hb_language_get_default().  This may change in the future by
  * taking buffer script into consideration when choosing a language.
+ * Note that hb_language_get_default() is NOT threadsafe the first time
+ * it is called.  See documentation for that function for details.
  *
  * Since: 0.9.7
  **/
@@ -1887,6 +1899,10 @@
 
 /**
  * hb_buffer_diff:
+ * @buffer: a buffer.
+ * @reference: other buffer to compare to.
+ * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1.
+ * @position_fuzz: allowed absolute difference in position values.
  *
  * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
  * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned.  This should be used by most

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -44,7 +44,6 @@
  * hb_glyph_info_t:
  * @codepoint: either a Unicode code point (before shaping) or a glyph index
  *             (after shaping).
- * @mask: 
  * @cluster: the index of the character in the original text that corresponds
  *           to this #hb_glyph_info_t, or whatever the client passes to
  *           hb_buffer_add(). More than one #hb_glyph_info_t can have the same
@@ -59,11 +58,13 @@
  *
  * The #hb_glyph_info_t is the structure that holds information about the
  * glyphs and their relation to input text.
- *
  */
-typedef struct hb_glyph_info_t {
+typedef struct hb_glyph_info_t
+{
   hb_codepoint_t codepoint;
-  hb_mask_t      mask; /* Holds hb_glyph_flags_t after hb_shape(), plus other things. */
+  /*< private >*/
+  hb_mask_t      mask;
+  /*< public >*/
   uint32_t       cluster;
 
   /*< private >*/
@@ -92,7 +93,7 @@
 typedef enum { /*< flags >*/
   HB_GLYPH_FLAG_UNSAFE_TO_BREAK		= 0x00000001,
 
-  HB_GLYPH_FLAG_DEFINED			= 0x00000001 /* OR of all defined flags */
+  HB_GLYPH_FLAG_DEFINED			= 0x00000001 /*< skip >*/ /* OR of all defined flags */
 } hb_glyph_flags_t;
 
 HB_EXTERN hb_glyph_flags_t
@@ -298,7 +299,15 @@
 HB_EXTERN hb_buffer_flags_t
 hb_buffer_get_flags (hb_buffer_t *buffer);
 
-/*
+/**
+ * hb_buffer_cluster_level_t:
+ * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES: Return cluster values grouped by graphemes into
+ *   monotone order.
+ * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS: Return cluster values grouped into monotone order.
+ * @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values.
+ * @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level,
+ *   equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES.
+ *
  * Since: 0.9.42
  */
 typedef enum {
@@ -332,7 +341,14 @@
 HB_EXTERN hb_codepoint_t
 hb_buffer_get_replacement_codepoint (hb_buffer_t    *buffer);
 
+HB_EXTERN void
+hb_buffer_set_invisible_glyph (hb_buffer_t    *buffer,
+			       hb_codepoint_t  invisible);
 
+HB_EXTERN hb_codepoint_t
+hb_buffer_get_invisible_glyph (hb_buffer_t    *buffer);
+
+
 HB_EXTERN void
 hb_buffer_reset (hb_buffer_t *buffer);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -93,6 +93,7 @@
   hb_buffer_flags_t flags; /* BOT / EOT / etc. */
   hb_buffer_cluster_level_t cluster_level;
   hb_codepoint_t replacement; /* U+FFFD or something else. */
+  hb_codepoint_t invisible; /* 0 or something else. */
   hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
   unsigned int max_len; /* Maximum allowed len. */
   int max_ops; /* Maximum allowed operations. */
@@ -212,13 +213,49 @@
 				   unsigned int num_out,
 				   const hb_codepoint_t *glyph_data);
 
-  HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
+  inline void replace_glyph (hb_codepoint_t glyph_index)
+  {
+    if (unlikely (out_info != info || out_len != idx)) {
+      if (unlikely (!make_room_for (1, 1))) return;
+      out_info[out_len] = info[idx];
+    }
+    out_info[out_len].codepoint = glyph_index;
+
+    idx++;
+    out_len++;
+  }
   /* Makes a copy of the glyph at idx to output and replace glyph_index */
-  HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
-  HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
+  inline hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index)
+  {
+    if (unlikely (!make_room_for (0, 1))) return Crap(hb_glyph_info_t);
+
+    if (unlikely (idx == len && !out_len))
+      return Crap(hb_glyph_info_t);
+
+    out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1];
+    out_info[out_len].codepoint = glyph_index;
+
+    out_len++;
+
+    return out_info[out_len - 1];
+  }
+  inline void output_info (const hb_glyph_info_t &glyph_info)
+  {
+    if (unlikely (!make_room_for (0, 1))) return;
+
+    out_info[out_len] = glyph_info;
+
+    out_len++;
+  }
   /* Copies glyph at idx to output but doesn't advance idx */
-  HB_INTERNAL void copy_glyph (void);
-  HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
+  inline void copy_glyph (void)
+  {
+    if (unlikely (!make_room_for (0, 1))) return;
+
+    out_info[out_len] = info[idx];
+
+    out_len++;
+  }
   /* Copies glyph at idx to output and advance idx.
    * If there's no output, just advance idx. */
   inline void
@@ -226,7 +263,8 @@
   {
     if (have_output)
     {
-      if (unlikely (out_info != info || out_len != idx)) {
+      if (out_info != info || out_len != idx)
+      {
 	if (unlikely (!make_room_for (1, 1))) return;
 	out_info[out_len] = info[idx];
       }
@@ -235,10 +273,28 @@
 
     idx++;
   }
+  /* Copies n glyphs at idx to output and advance idx.
+   * If there's no output, just advance idx. */
+  inline void
+  next_glyphs (unsigned int n)
+  {
+    if (have_output)
+    {
+      if (out_info != info || out_len != idx)
+      {
+	if (unlikely (!make_room_for (n, n))) return;
+	memmove (out_info + out_len, info + idx, n * sizeof (out_info[0]));
+      }
+      out_len += n;
+    }
 
+    idx += n;
+  }
   /* Advance idx without copying to output. */
-  inline void skip_glyph (void) { idx++; }
-
+  inline void skip_glyph (void)
+  {
+    idx++;
+  }
   inline void reset_masks (hb_mask_t mask)
   {
     for (unsigned int j = 0; j < len; j++)
@@ -275,6 +331,8 @@
 
 
   /* Internal methods */
+  HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
+
   HB_INTERNAL bool enlarge (unsigned int size);
 
   inline bool ensure (unsigned int size)

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2012  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_CACHE_HH
+#define HB_CACHE_HH
+
+#include "hb.hh"
+
+
+/* Implements a lock-free cache for int->int functions. */
+
+template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
+struct hb_cache_t
+{
+  static_assert ((key_bits >= cache_bits), "");
+  static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (hb_atomic_int_t)), "");
+  static_assert (sizeof (hb_atomic_int_t) == sizeof (unsigned int), "");
+
+  inline void init (void) { clear (); }
+  inline void fini (void) {}
+
+  inline void clear (void)
+  {
+    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
+      values[i].set_relaxed (-1);
+  }
+
+  inline bool get (unsigned int key, unsigned int *value) const
+  {
+    unsigned int k = key & ((1u<<cache_bits)-1);
+    unsigned int v = values[k].get_relaxed ();
+    if ((key_bits + value_bits - cache_bits == 8 * sizeof (hb_atomic_int_t) && v == (unsigned int) -1) ||
+	(v >> value_bits) != (key >> cache_bits))
+      return false;
+    *value = v & ((1u<<value_bits)-1);
+    return true;
+  }
+
+  inline bool set (unsigned int key, unsigned int value)
+  {
+    if (unlikely ((key >> key_bits) || (value >> value_bits)))
+      return false; /* Overflows */
+    unsigned int k = key & ((1u<<cache_bits)-1);
+    unsigned int v = ((key>>cache_bits)<<value_bits) | value;
+    values[k].set_relaxed (v);
+    return true;
+  }
+
+  private:
+  hb_atomic_int_t values[1u<<cache_bits];
+};
+
+typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t;
+typedef hb_cache_t<16, 24, 8> hb_advance_cache_t;
+
+
+#endif /* HB_CACHE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -47,9 +47,28 @@
   u.i = 0;
   u.opts.initialized = 1;
 
-  char *c = getenv ("HB_OPTIONS");
-  u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
+  const char *c = getenv ("HB_OPTIONS");
+  if (c)
+  {
+    while (*c)
+    {
+      const char *p = strchr (c, ':');
+      if (!p)
+        p = c + strlen (c);
 
+#define OPTION(name, symbol) \
+	if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) u.opts.symbol = true;
+
+      OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
+      OPTION ("aat", aat);
+
+#undef OPTION
+
+      c = *p ? p + 1 : p;
+    }
+
+  }
+
   /* This is idempotent and threadsafe. */
   _hb_options.set_relaxed (u.i);
 }
@@ -306,14 +325,14 @@
 /**
  * hb_language_from_string:
  * @str: (array length=len) (element-type uint8_t): a string representing
- *       ISO 639 language code
+ *       a BCP 47 language tag
  * @len: length of the @str, or -1 if it is %NULL-terminated.
  *
- * Converts @str representing an ISO 639 language code to the corresponding
+ * Converts @str representing a BCP 47 language tag to the corresponding
  * #hb_language_t.
  *
  * Return value: (transfer none):
- * The #hb_language_t corresponding to the ISO 639 language code.
+ * The #hb_language_t corresponding to the BCP 47 language tag.
  *
  * Since: 0.9.2
  **/
@@ -361,7 +380,14 @@
 /**
  * hb_language_get_default:
  *
+ * Get default language from current locale.
  *
+ * Note that the first time this function is called, it calls
+ * "setlocale (LC_CTYPE, nullptr)" to fetch current locale.  The underlying
+ * setlocale function is, in many implementations, NOT threadsafe.  To avoid
+ * problems, call this function once before multiple threads can call it.
+ * This function is only used from hb_buffer_guess_segment_properties() by
+ * HarfBuzz itself.
  *
  * Return value: (transfer none):
  *
@@ -531,7 +557,6 @@
 
     /* Unicode-8.0 additions */
     case HB_SCRIPT_HATRAN:
-    case HB_SCRIPT_OLD_HUNGARIAN:
 
     /* Unicode-9.0 additions */
     case HB_SCRIPT_ADLAM:
@@ -545,6 +570,7 @@
 
 
     /* https://github.com/harfbuzz/harfbuzz/issues/1000 */
+    case HB_SCRIPT_OLD_HUNGARIAN:
     case HB_SCRIPT_OLD_ITALIC:
     case HB_SCRIPT_RUNIC:
 
@@ -877,8 +903,8 @@
 
   bool has_start;
 
-  feature->start = 0;
-  feature->end = (unsigned int) -1;
+  feature->start = HB_FEATURE_GLOBAL_START;
+  feature->end = HB_FEATURE_GLOBAL_END;
 
   if (!parse_char (pp, end, '['))
     return true;
@@ -1065,7 +1091,7 @@
   while (len && s[len - 1] == ' ')
     len--;
   s[len++] = '=';
-  len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", variation->value));
+  len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
 
   assert (len < ARRAY_LENGTH (s));
   len = MIN (len, size - 1);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -63,6 +63,23 @@
 #  include <stdint.h>
 #endif
 
+#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+#define HB_DEPRECATED __attribute__((__deprecated__))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+#define HB_DEPRECATED __declspec(deprecated)
+#else
+#define HB_DEPRECATED
+#endif
+
+#if    __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#define HB_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead")))
+#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
+#define HB_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead"))
+#else
+#define HB_DEPRECATED_FOR(f) HB_DEPRECATED
+#endif
+
+
 HB_BEGIN_DECLS
 
 
@@ -86,8 +103,8 @@
 
 typedef uint32_t hb_tag_t;
 
-#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
-#define HB_UNTAG(tag)   ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
+#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint32_t)(c1)&0xFF)<<24)|(((uint32_t)(c2)&0xFF)<<16)|(((uint32_t)(c3)&0xFF)<<8)|((uint32_t)(c4)&0xFF)))
+#define HB_UNTAG(tag)   (((tag)>>24)&0xFF), (((tag)>>16)&0xFF), (((tag)>>8)&0xFF), ((tag)&0xFF)
 
 #define HB_TAG_NONE HB_TAG(0,0,0,0)
 #define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
@@ -340,13 +357,15 @@
   HB_SCRIPT_INVALID				= HB_TAG_NONE,
 
   /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
-   * without risking undefined behavior.  Include both a signed and unsigned max,
-   * since technically enums are int, and indeed, hb_script_t ends up being signed.
+   * without risking undefined behavior.  We have two, for historical reasons.
+   * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed
+   * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well.
+   *
    * See this thread for technicalities:
    *
    *   https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
    */
-  _HB_SCRIPT_MAX_VALUE				= HB_TAG_MAX, /*< skip >*/
+  _HB_SCRIPT_MAX_VALUE				= HB_TAG_MAX_SIGNED, /*< skip >*/
   _HB_SCRIPT_MAX_VALUE_SIGNED			= HB_TAG_MAX_SIGNED /*< skip >*/
 
 } hb_script_t;
@@ -379,6 +398,19 @@
 
 /* Font features and variations. */
 
+/**
+ * HB_FEATURE_GLOBAL_START
+ *
+ * Since: 2.0.0
+ */
+#define HB_FEATURE_GLOBAL_START	0
+/**
+ * HB_FEATURE_GLOBAL_END
+ *
+ * Since: 2.0.0
+ */
+#define HB_FEATURE_GLOBAL_END	((unsigned int) -1)
+
 typedef struct hb_feature_t {
   hb_tag_t      tag;
   uint32_t      value;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -32,6 +32,7 @@
 #include "hb-shaper-impl.hh"
 
 #include "hb-coretext.h"
+#include "hb-aat-layout.hh"
 #include <math.h>
 
 /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
@@ -210,7 +211,7 @@
   }
 
   CFURLRef original_url = nullptr;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+#if TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
   ATSFontRef atsFont;
   FSRef fsref;
   OSStatus status;
@@ -240,7 +241,7 @@
        * process in Blink. This can be detected by the new file URL location
        * that the newly found font points to. */
       CFURLRef new_url = nullptr;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+#if TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
       atsFont = CTFontGetPlatformFont (new_ct_font, NULL);
       status = ATSFontGetFileReference (atsFont, &fsref);
       if (status == noErr)
@@ -431,183 +432,6 @@
 };
 
 
-/* The following enum members are added in OS X 10.8. */
-#define kAltHalfWidthTextSelector		6
-#define kAltProportionalTextSelector		5
-#define kAlternateHorizKanaOffSelector		1
-#define kAlternateHorizKanaOnSelector		0
-#define kAlternateKanaType			34
-#define kAlternateVertKanaOffSelector		3
-#define kAlternateVertKanaOnSelector		2
-#define kCaseSensitiveLayoutOffSelector		1
-#define kCaseSensitiveLayoutOnSelector		0
-#define kCaseSensitiveLayoutType		33
-#define kCaseSensitiveSpacingOffSelector	3
-#define kCaseSensitiveSpacingOnSelector		2
-#define kContextualAlternatesOffSelector	1
-#define kContextualAlternatesOnSelector		0
-#define kContextualAlternatesType		36
-#define kContextualLigaturesOffSelector		19
-#define kContextualLigaturesOnSelector		18
-#define kContextualSwashAlternatesOffSelector	5
-#define kContextualSwashAlternatesOnSelector	4
-#define kDefaultLowerCaseSelector		0
-#define kDefaultUpperCaseSelector		0
-#define kHistoricalLigaturesOffSelector		21
-#define kHistoricalLigaturesOnSelector		20
-#define kHojoCharactersSelector			12
-#define kJIS2004CharactersSelector		11
-#define kLowerCasePetiteCapsSelector		2
-#define kLowerCaseSmallCapsSelector		1
-#define kLowerCaseType				37
-#define kMathematicalGreekOffSelector		11
-#define kMathematicalGreekOnSelector		10
-#define kNLCCharactersSelector			13
-#define kQuarterWidthTextSelector		4
-#define kScientificInferiorsSelector		4
-#define kStylisticAltEightOffSelector		17
-#define kStylisticAltEightOnSelector		16
-#define kStylisticAltEighteenOffSelector	37
-#define kStylisticAltEighteenOnSelector		36
-#define kStylisticAltElevenOffSelector		23
-#define kStylisticAltElevenOnSelector		22
-#define kStylisticAltFifteenOffSelector		31
-#define kStylisticAltFifteenOnSelector		30
-#define kStylisticAltFiveOffSelector		11
-#define kStylisticAltFiveOnSelector		10
-#define kStylisticAltFourOffSelector		9
-#define kStylisticAltFourOnSelector		8
-#define kStylisticAltFourteenOffSelector	29
-#define kStylisticAltFourteenOnSelector		28
-#define kStylisticAltNineOffSelector		19
-#define kStylisticAltNineOnSelector		18
-#define kStylisticAltNineteenOffSelector	39
-#define kStylisticAltNineteenOnSelector		38
-#define kStylisticAltOneOffSelector		3
-#define kStylisticAltOneOnSelector		2
-#define kStylisticAltSevenOffSelector		15
-#define kStylisticAltSevenOnSelector		14
-#define kStylisticAltSeventeenOffSelector	35
-#define kStylisticAltSeventeenOnSelector	34
-#define kStylisticAltSixOffSelector		13
-#define kStylisticAltSixOnSelector		12
-#define kStylisticAltSixteenOffSelector		33
-#define kStylisticAltSixteenOnSelector		32
-#define kStylisticAltTenOffSelector		21
-#define kStylisticAltTenOnSelector		20
-#define kStylisticAltThirteenOffSelector	27
-#define kStylisticAltThirteenOnSelector		26
-#define kStylisticAltThreeOffSelector		7
-#define kStylisticAltThreeOnSelector		6
-#define kStylisticAltTwelveOffSelector		25
-#define kStylisticAltTwelveOnSelector		24
-#define kStylisticAltTwentyOffSelector		41
-#define kStylisticAltTwentyOnSelector		40
-#define kStylisticAltTwoOffSelector		5
-#define kStylisticAltTwoOnSelector		4
-#define kStylisticAlternativesType		35
-#define kSwashAlternatesOffSelector		3
-#define kSwashAlternatesOnSelector		2
-#define kThirdWidthTextSelector			3
-#define kTraditionalNamesCharactersSelector	14
-#define kUpperCasePetiteCapsSelector		2
-#define kUpperCaseSmallCapsSelector		1
-#define kUpperCaseType				38
-
-/* Table data courtesy of Apple. */
-static const struct feature_mapping_t {
-    FourCharCode otFeatureTag;
-    uint16_t aatFeatureType;
-    uint16_t selectorToEnable;
-    uint16_t selectorToDisable;
-} feature_mappings[] = {
-    { 'c2pc',   kUpperCaseType,             kUpperCasePetiteCapsSelector,           kDefaultUpperCaseSelector },
-    { 'c2sc',   kUpperCaseType,             kUpperCaseSmallCapsSelector,            kDefaultUpperCaseSelector },
-    { 'calt',   kContextualAlternatesType,  kContextualAlternatesOnSelector,        kContextualAlternatesOffSelector },
-    { 'case',   kCaseSensitiveLayoutType,   kCaseSensitiveLayoutOnSelector,         kCaseSensitiveLayoutOffSelector },
-    { 'clig',   kLigaturesType,             kContextualLigaturesOnSelector,         kContextualLigaturesOffSelector },
-    { 'cpsp',   kCaseSensitiveLayoutType,   kCaseSensitiveSpacingOnSelector,        kCaseSensitiveSpacingOffSelector },
-    { 'cswh',   kContextualAlternatesType,  kContextualSwashAlternatesOnSelector,   kContextualSwashAlternatesOffSelector },
-    { 'dlig',   kLigaturesType,             kRareLigaturesOnSelector,               kRareLigaturesOffSelector },
-    { 'expt',   kCharacterShapeType,        kExpertCharactersSelector,              16 },
-    { 'frac',   kFractionsType,             kDiagonalFractionsSelector,             kNoFractionsSelector },
-    { 'fwid',   kTextSpacingType,           kMonospacedTextSelector,                7 },
-    { 'halt',   kTextSpacingType,           kAltHalfWidthTextSelector,              7 },
-    { 'hist',   kLigaturesType,             kHistoricalLigaturesOnSelector,         kHistoricalLigaturesOffSelector },
-    { 'hkna',   kAlternateKanaType,         kAlternateHorizKanaOnSelector,          kAlternateHorizKanaOffSelector, },
-    { 'hlig',   kLigaturesType,             kHistoricalLigaturesOnSelector,         kHistoricalLigaturesOffSelector },
-    { 'hngl',   kTransliterationType,       kHanjaToHangulSelector,                 kNoTransliterationSelector },
-    { 'hojo',   kCharacterShapeType,        kHojoCharactersSelector,                16 },
-    { 'hwid',   kTextSpacingType,           kHalfWidthTextSelector,                 7 },
-    { 'ital',   kItalicCJKRomanType,        kCJKItalicRomanOnSelector,              kCJKItalicRomanOffSelector },
-    { 'jp04',   kCharacterShapeType,        kJIS2004CharactersSelector,             16 },
-    { 'jp78',   kCharacterShapeType,        kJIS1978CharactersSelector,             16 },
-    { 'jp83',   kCharacterShapeType,        kJIS1983CharactersSelector,             16 },
-    { 'jp90',   kCharacterShapeType,        kJIS1990CharactersSelector,             16 },
-    { 'liga',   kLigaturesType,             kCommonLigaturesOnSelector,             kCommonLigaturesOffSelector },
-    { 'lnum',   kNumberCaseType,            kUpperCaseNumbersSelector,              2 },
-    { 'mgrk',   kMathematicalExtrasType,    kMathematicalGreekOnSelector,           kMathematicalGreekOffSelector },
-    { 'nlck',   kCharacterShapeType,        kNLCCharactersSelector,                 16 },
-    { 'onum',   kNumberCaseType,            kLowerCaseNumbersSelector,              2 },
-    { 'ordn',   kVerticalPositionType,      kOrdinalsSelector,                      kNormalPositionSelector },
-    { 'palt',   kTextSpacingType,           kAltProportionalTextSelector,           7 },
-    { 'pcap',   kLowerCaseType,             kLowerCasePetiteCapsSelector,           kDefaultLowerCaseSelector },
-    { 'pkna',   kTextSpacingType,           kProportionalTextSelector,              7 },
-    { 'pnum',   kNumberSpacingType,         kProportionalNumbersSelector,           4 },
-    { 'pwid',   kTextSpacingType,           kProportionalTextSelector,              7 },
-    { 'qwid',   kTextSpacingType,           kQuarterWidthTextSelector,              7 },
-    { 'ruby',   kRubyKanaType,              kRubyKanaOnSelector,                    kRubyKanaOffSelector },
-    { 'sinf',   kVerticalPositionType,      kScientificInferiorsSelector,           kNormalPositionSelector },
-    { 'smcp',   kLowerCaseType,             kLowerCaseSmallCapsSelector,            kDefaultLowerCaseSelector },
-    { 'smpl',   kCharacterShapeType,        kSimplifiedCharactersSelector,          16 },
-    { 'ss01',   kStylisticAlternativesType, kStylisticAltOneOnSelector,             kStylisticAltOneOffSelector },
-    { 'ss02',   kStylisticAlternativesType, kStylisticAltTwoOnSelector,             kStylisticAltTwoOffSelector },
-    { 'ss03',   kStylisticAlternativesType, kStylisticAltThreeOnSelector,           kStylisticAltThreeOffSelector },
-    { 'ss04',   kStylisticAlternativesType, kStylisticAltFourOnSelector,            kStylisticAltFourOffSelector },
-    { 'ss05',   kStylisticAlternativesType, kStylisticAltFiveOnSelector,            kStylisticAltFiveOffSelector },
-    { 'ss06',   kStylisticAlternativesType, kStylisticAltSixOnSelector,             kStylisticAltSixOffSelector },
-    { 'ss07',   kStylisticAlternativesType, kStylisticAltSevenOnSelector,           kStylisticAltSevenOffSelector },
-    { 'ss08',   kStylisticAlternativesType, kStylisticAltEightOnSelector,           kStylisticAltEightOffSelector },
-    { 'ss09',   kStylisticAlternativesType, kStylisticAltNineOnSelector,            kStylisticAltNineOffSelector },
-    { 'ss10',   kStylisticAlternativesType, kStylisticAltTenOnSelector,             kStylisticAltTenOffSelector },
-    { 'ss11',   kStylisticAlternativesType, kStylisticAltElevenOnSelector,          kStylisticAltElevenOffSelector },
-    { 'ss12',   kStylisticAlternativesType, kStylisticAltTwelveOnSelector,          kStylisticAltTwelveOffSelector },
-    { 'ss13',   kStylisticAlternativesType, kStylisticAltThirteenOnSelector,        kStylisticAltThirteenOffSelector },
-    { 'ss14',   kStylisticAlternativesType, kStylisticAltFourteenOnSelector,        kStylisticAltFourteenOffSelector },
-    { 'ss15',   kStylisticAlternativesType, kStylisticAltFifteenOnSelector,         kStylisticAltFifteenOffSelector },
-    { 'ss16',   kStylisticAlternativesType, kStylisticAltSixteenOnSelector,         kStylisticAltSixteenOffSelector },
-    { 'ss17',   kStylisticAlternativesType, kStylisticAltSeventeenOnSelector,       kStylisticAltSeventeenOffSelector },
-    { 'ss18',   kStylisticAlternativesType, kStylisticAltEighteenOnSelector,        kStylisticAltEighteenOffSelector },
-    { 'ss19',   kStylisticAlternativesType, kStylisticAltNineteenOnSelector,        kStylisticAltNineteenOffSelector },
-    { 'ss20',   kStylisticAlternativesType, kStylisticAltTwentyOnSelector,          kStylisticAltTwentyOffSelector },
-    { 'subs',   kVerticalPositionType,      kInferiorsSelector,                     kNormalPositionSelector },
-    { 'sups',   kVerticalPositionType,      kSuperiorsSelector,                     kNormalPositionSelector },
-    { 'swsh',   kContextualAlternatesType,  kSwashAlternatesOnSelector,             kSwashAlternatesOffSelector },
-    { 'titl',   kStyleOptionsType,          kTitlingCapsSelector,                   kNoStyleOptionsSelector },
-    { 'tnam',   kCharacterShapeType,        kTraditionalNamesCharactersSelector,    16 },
-    { 'tnum',   kNumberSpacingType,         kMonospacedNumbersSelector,             4 },
-    { 'trad',   kCharacterShapeType,        kTraditionalCharactersSelector,         16 },
-    { 'twid',   kTextSpacingType,           kThirdWidthTextSelector,                7 },
-    { 'unic',   kLetterCaseType,            14,                                     15 },
-    { 'valt',   kTextSpacingType,           kAltProportionalTextSelector,           7 },
-    { 'vert',   kVerticalSubstitutionType,  kSubstituteVerticalFormsOnSelector,     kSubstituteVerticalFormsOffSelector },
-    { 'vhal',   kTextSpacingType,           kAltHalfWidthTextSelector,              7 },
-    { 'vkna',   kAlternateKanaType,         kAlternateVertKanaOnSelector,           kAlternateVertKanaOffSelector },
-    { 'vpal',   kTextSpacingType,           kAltProportionalTextSelector,           7 },
-    { 'vrt2',   kVerticalSubstitutionType,  kSubstituteVerticalFormsOnSelector,     kSubstituteVerticalFormsOffSelector },
-    { 'zero',   kTypographicExtrasType,     kSlashedZeroOnSelector,                 kSlashedZeroOffSelector },
-};
-
-static int
-_hb_feature_mapping_cmp (const void *key_, const void *entry_)
-{
-  unsigned int key = * (unsigned int *) key_;
-  const feature_mapping_t * entry = (const feature_mapping_t *) entry_;
-  return key < entry->otFeatureTag ? -1 :
-	 key > entry->otFeatureTag ? 1 :
-	 0;
-}
-
 hb_bool_t
 _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
 		    hb_font_t          *font,
@@ -624,7 +448,7 @@
   CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
 
   /* Attach marks to their bases, to match the 'ot' shaper.
-   * Adapted from hb-ot-shape:hb_form_clusters().
+   * Adapted from a very old version of hb-ot-shape:hb_form_clusters().
    * Note that this only makes us be closer to the 'ot' shaper,
    * but by no means the same.  For example, if there's
    * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will
@@ -653,11 +477,7 @@
     hb_auto_t<hb_vector_t<feature_event_t> > feature_events;
     for (unsigned int i = 0; i < num_features; i++)
     {
-      const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag,
-									       feature_mappings,
-									       ARRAY_LENGTH (feature_mappings),
-									       sizeof (feature_mappings[0]),
-									       _hb_feature_mapping_cmp);
+      const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag);
       if (!mapping)
         continue;
 
@@ -766,7 +586,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());
       }
     }
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -43,9 +43,10 @@
 
 struct hb_options_t
 {
-  unsigned int unused : 1; /* In-case sign bit is here. */
-  unsigned int initialized : 1;
-  unsigned int uniscribe_bug_compatible : 1;
+  bool unused : 1; /* In-case sign bit is here. */
+  bool initialized : 1;
+  bool uniscribe_bug_compatible : 1;
+  bool aat : 1;
 };
 
 union hb_options_union_t {
@@ -67,7 +68,10 @@
   u.i = _hb_options.get_relaxed ();
 
   if (unlikely (!u.i))
+  {
     _hb_options_init ();
+    u.i = _hb_options.get_relaxed ();
+  }
 
   return u.opts;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -50,14 +50,191 @@
 					       hb_codepoint_t *glyph,
 					       void *user_data);
 
-HB_EXTERN void
+HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func or 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);
 
-HB_EXTERN void
+HB_EXTERN HB_DEPRECATED void
 hb_set_invert (hb_set_t *set);
 
+/**
+ * hb_unicode_eastasian_width_func_t:
+ *
+ * Deprecated: 2.0.0
+ */
+typedef unsigned int			(*hb_unicode_eastasian_width_func_t)	(hb_unicode_funcs_t *ufuncs,
+										 hb_codepoint_t      unicode,
+										 void               *user_data);
+
+/**
+ * hb_unicode_funcs_set_eastasian_width_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ * 
+ *
+ * Since: 0.9.2
+ * Deprecated: 2.0.0
+ **/
+HB_EXTERN HB_DEPRECATED void
+hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
+					   hb_unicode_eastasian_width_func_t func,
+					   void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_eastasian_width:
+ *
+ * Since: 0.9.2
+ * Deprecated: 2.0.0
+ **/
+HB_EXTERN HB_DEPRECATED unsigned int
+hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
+			    hb_codepoint_t unicode);
+
+
+/**
+ * hb_unicode_decompose_compatibility_func_t:
+ * @ufuncs: a Unicode function structure
+ * @u: codepoint to decompose
+ * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
+ * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
+ *
+ * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
+ * The complete length of the decomposition will be returned.
+ *
+ * If @u has no compatibility decomposition, zero should be returned.
+ *
+ * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
+ * compatibility decomposition plus an terminating value of 0.  Consequently, @decompose must be allocated by the caller to be at least this length.  Implementations
+ * of this function type must ensure that they do not write past the provided array.
+ *
+ * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
+ *
+ * Deprecated: 2.0.0
+ */
+typedef unsigned int			(*hb_unicode_decompose_compatibility_func_t)	(hb_unicode_funcs_t *ufuncs,
+											 hb_codepoint_t      u,
+											 hb_codepoint_t     *decomposed,
+											 void               *user_data);
+
+/**
+ * HB_UNICODE_MAX_DECOMPOSITION_LEN:
+ *
+ * See Unicode 6.1 for details on the maximum decomposition length.
+ *
+ * Deprecated: 2.0.0
+ */
+#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
+
+/**
+ * hb_unicode_funcs_set_decompose_compatibility_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ * 
+ *
+ * Since: 0.9.2
+ * Deprecated: 2.0.0
+ **/
+HB_EXTERN HB_DEPRECATED void
+hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
+						   hb_unicode_decompose_compatibility_func_t func,
+						   void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_decompose_compatibility:
+ * 
+ *
+ * Deprecated: 2.0.0
+ **/
+HB_EXTERN HB_DEPRECATED unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+				    hb_codepoint_t      u,
+				    hb_codepoint_t     *decomposed);
+
+
+typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
+							   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+							   void *user_data);
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
+
+/**
+ * hb_font_funcs_set_glyph_h_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ * 
+ *
+ * Since: 0.9.2
+ * Deprecated: 2.0.0
+ **/
+HB_EXTERN void
+hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_h_kerning_func_t func,
+					void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ * 
+ *
+ * Since: 0.9.2
+ * Deprecated: 2.0.0
+ **/
+HB_EXTERN void
+hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_v_kerning_func_t func,
+					void *user_data, hb_destroy_func_t destroy);
+
+HB_EXTERN hb_position_t
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
+HB_EXTERN hb_position_t
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
+
+HB_EXTERN void
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+					 hb_direction_t direction,
+					 hb_position_t *x, hb_position_t *y);
+
+/* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) hb_bool_t
+hb_ot_layout_table_choose_script (hb_face_t      *face,
+				  hb_tag_t        table_tag,
+				  const hb_tag_t *script_tags,
+				  unsigned int   *script_index,
+				  hb_tag_t       *chosen_script);
+
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_script_select_language) hb_bool_t
+hb_ot_layout_script_find_language (hb_face_t    *face,
+				   hb_tag_t      table_tag,
+				   unsigned int  script_index,
+				   hb_tag_t      language_tag,
+				   unsigned int *language_index);
+
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) void
+hb_ot_tags_from_script (hb_script_t  script,
+			hb_tag_t    *script_tag_1,
+			hb_tag_t    *script_tag_2);
+
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t
+hb_ot_tag_from_language (hb_language_t language);
+
+
 #endif
 
 HB_END_DECLS

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -29,7 +29,9 @@
 
 #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)
@@ -507,13 +509,33 @@
   void fini (void) {}
 };
 
+template <typename T>
+struct hb_array_t
+{
+  inline hb_array_t (void) : arrayZ (nullptr), len (0) {}
+  inline hb_array_t (const T *array_, unsigned int len_) : arrayZ (array_), len (len_) {}
+
+  inline const T& operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= len)) return Null(T);
+    return arrayZ[i];
+  }
+
+  inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
+
+  const T *arrayZ;
+  unsigned int len;
+};
+
 struct hb_bytes_t
 {
-  inline hb_bytes_t (void) : bytes (nullptr), len (0) {}
-  inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
-  inline hb_bytes_t (const void *bytes_, unsigned int len_) : bytes ((const char *) bytes_), len (len_) {}
+  inline hb_bytes_t (void) : arrayZ (nullptr), len (0) {}
+  inline hb_bytes_t (const char *bytes_, unsigned int len_) : arrayZ (bytes_), len (len_) {}
+  inline hb_bytes_t (const void *bytes_, unsigned int len_) : arrayZ ((const char *) bytes_), len (len_) {}
+  template <typename T>
+  inline hb_bytes_t (const T& array) : arrayZ ((const char *) array.arrayZ), len (array.len) {}
 
-  inline void free (void) { ::free ((void *) bytes); bytes = nullptr; len = 0; }
+  inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
 
   inline int cmp (const hb_bytes_t &a) const
   {
@@ -520,7 +542,7 @@
     if (len != a.len)
       return (int) a.len - (int) len;
 
-    return memcmp (a.bytes, bytes, len);
+    return memcmp (a.arrayZ, arrayZ, len);
   }
   static inline int cmp (const void *pa, const void *pb)
   {
@@ -529,7 +551,7 @@
     return b->cmp (*a);
   }
 
-  const char *bytes;
+  const char *arrayZ;
   unsigned int len;
 };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -36,13 +36,13 @@
 
 
 /**
- * hb_face_count: Get number of faces on the blob
- * @blob:
+ * hb_face_count:
+ * @blob: a blob.
  *
+ * Get number of faces in a blob.
  *
+ * Return value: Number of faces in @blob
  *
- * Return value: Number of faces on the blob
- *
  * Since: 1.7.7
  **/
 unsigned int
@@ -163,11 +163,12 @@
     return hb_blob_reference (data->blob);
 
   const OT::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> ();
-  const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
+  unsigned int base_offset;
+  const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index, &base_offset);
 
   const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag);
 
-  hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
+  hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, base_offset + table.offset, table.length);
 
   return blob;
 }
@@ -324,6 +325,8 @@
 {
   if (unlikely (hb_object_is_inert (face)))
     return;
+  if (face->immutable)
+    return;
 
   face->immutable = true;
 }
@@ -487,6 +490,9 @@
 /**
  * hb_face_get_table_tags:
  * @face: a face.
+ * @start_offset: index of first tag to return.
+ * @table_count: input length of @table_tags array, output number of items written.
+ * @table_tags: array to write tags into.
  *
  * Retrieves table tags for a face, if possible.
  *
@@ -628,7 +634,7 @@
   unsigned int face_length = table_count * 16 + 12;
 
   for (unsigned int i = 0; i < table_count; i++)
-    face_length += hb_ceil_to_4 (hb_blob_get_length (data->tables.arrayZ[i].blob));
+    face_length += hb_ceil_to_4 (hb_blob_get_length (data->tables[i].blob));
 
   char *buf = (char *) malloc (face_length);
   if (unlikely (!buf))
@@ -682,7 +688,7 @@
  * After tables are added to the face, it can be compiled to a binary
  * font file by calling hb_face_reference_blob().
  *
- * Return value: (transfer full) New face.
+ * Return value: (transfer full): New face.
  *
  * Since: 1.9.0
  **/

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -31,7 +31,9 @@
 #include "hb-font.hh"
 #include "hb-machinery.hh"
 
+#include "hb-ot.h"
 
+
 /*
  * hb_font_funcs_t
  */
@@ -101,9 +103,42 @@
 				   hb_codepoint_t *glyph,
 				   void *user_data HB_UNUSED)
 {
+  if (font->has_nominal_glyphs_func ())
+  {
+    return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0);
+  }
   return font->parent->get_nominal_glyph (unicode, glyph);
 }
 
+#define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
+static unsigned int
+hb_font_get_nominal_glyphs_default (hb_font_t *font,
+				    void *font_data HB_UNUSED,
+				    unsigned int count,
+				    const hb_codepoint_t *first_unicode,
+				    unsigned int unicode_stride,
+				    hb_codepoint_t *first_glyph,
+				    unsigned int glyph_stride,
+				    void *user_data HB_UNUSED)
+{
+  if (font->has_nominal_glyph_func ())
+  {
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (!font->get_nominal_glyph (*first_unicode, first_glyph))
+        return i;
+
+      first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride);
+      first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
+    }
+    return count;
+  }
+
+  return font->parent->get_nominal_glyphs (count,
+					   first_unicode, unicode_stride,
+					   first_glyph, glyph_stride);
+}
+
 static hb_bool_t
 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
@@ -141,6 +176,12 @@
 				     hb_codepoint_t glyph,
 				     void *user_data HB_UNUSED)
 {
+  if (font->has_glyph_h_advances_func ())
+  {
+    hb_position_t ret;
+    font->get_glyph_h_advances (1, &glyph, 0, &ret, 0);
+    return ret;
+  }
   return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
 }
 
@@ -159,6 +200,12 @@
 				     hb_codepoint_t glyph,
 				     void *user_data HB_UNUSED)
 {
+  if (font->has_glyph_v_advances_func ())
+  {
+    hb_position_t ret;
+    font->get_glyph_v_advances (1, &glyph, 0, &ret, 0);
+    return ret;
+  }
   return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
 }
 
@@ -167,7 +214,7 @@
 hb_font_get_glyph_h_advances_default (hb_font_t* font,
 				      void* font_data HB_UNUSED,
 				      unsigned int count,
-				      hb_codepoint_t *first_glyph,
+				      const hb_codepoint_t *first_glyph,
 				      unsigned int glyph_stride,
 				      hb_position_t *first_advance,
 				      unsigned int advance_stride,
@@ -199,7 +246,7 @@
 hb_font_get_glyph_v_advances_default (hb_font_t* font,
 				      void* font_data HB_UNUSED,
 				      unsigned int count,
-				      hb_codepoint_t *first_glyph,
+				      const hb_codepoint_t *first_glyph,
 				      unsigned int glyph_stride,
 				      hb_position_t *first_advance,
 				      unsigned int advance_stride,
@@ -586,6 +633,8 @@
 {
   if (unlikely (hb_object_is_inert (ffuncs)))
     return;
+  if (ffuncs->immutable)
+    return;
 
   ffuncs->immutable = true;
 }
@@ -793,8 +842,8 @@
  **/
 void
 hb_font_get_glyph_h_advances (hb_font_t* font,
-			      unsigned count,
-			      hb_codepoint_t *first_glyph,
+			      unsigned int count,
+			      const hb_codepoint_t *first_glyph,
 			      unsigned glyph_stride,
 			      hb_position_t *first_advance,
 			      unsigned advance_stride)
@@ -811,8 +860,8 @@
  **/
 void
 hb_font_get_glyph_v_advances (hb_font_t* font,
-			      unsigned count,
-			      hb_codepoint_t *first_glyph,
+			      unsigned int count,
+			      const hb_codepoint_t *first_glyph,
 			      unsigned glyph_stride,
 			      hb_position_t *first_advance,
 			      unsigned advance_stride)
@@ -873,6 +922,7 @@
  * Return value: 
  *
  * Since: 0.9.2
+ * Deprecated: 2.0.0
  **/
 hb_position_t
 hb_font_get_glyph_h_kerning (hb_font_t *font,
@@ -892,6 +942,7 @@
  * Return value: 
  *
  * Since: 0.9.2
+ * Deprecated: 2.0.0
  **/
 hb_position_t
 hb_font_get_glyph_v_kerning (hb_font_t *font,
@@ -991,7 +1042,7 @@
  * hb_font_get_extents_for_direction:
  * @font: a font.
  * @direction:
- * @extents:
+ * @extents: (out):
  *
  *
  *
@@ -1036,8 +1087,8 @@
 HB_EXTERN void
 hb_font_get_glyph_advances_for_direction (hb_font_t* font,
 					  hb_direction_t direction,
-					  unsigned count,
-					  hb_codepoint_t *first_glyph,
+					  unsigned int count,
+					  const hb_codepoint_t *first_glyph,
 					  unsigned glyph_stride,
 					  hb_position_t *first_advance,
 					  unsigned advance_stride)
@@ -1120,6 +1171,7 @@
  * 
  *
  * Since: 0.9.2
+ * Deprecated: 2.0.0
  **/
 void
 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
@@ -1254,18 +1306,8 @@
 };
 
 
-/**
- * hb_font_create: (Xconstructor)
- * @face: a face.
- *
- * 
- *
- * Return value: (transfer full): 
- *
- * Since: 0.9.2
- **/
-hb_font_t *
-hb_font_create (hb_face_t *face)
+static hb_font_t *
+_hb_font_create (hb_face_t *face)
 {
   hb_font_t *font;
 
@@ -1285,6 +1327,27 @@
 }
 
 /**
+ * hb_font_create: (Xconstructor)
+ * @face: a face.
+ *
+ * 
+ *
+ * Return value: (transfer full): 
+ *
+ * Since: 0.9.2
+ **/
+hb_font_t *
+hb_font_create (hb_face_t *face)
+{
+  hb_font_t *font = _hb_font_create (face);
+
+  /* Install our in-house, very lightweight, funcs. */
+  hb_ot_font_set_funcs (font);
+
+  return font;
+}
+
+/**
  * hb_font_create_sub_font:
  * @parent: parent font.
  *
@@ -1300,7 +1363,7 @@
   if (unlikely (!parent))
     parent = hb_font_get_empty ();
 
-  hb_font_t *font = hb_font_create (parent->face);
+  hb_font_t *font = _hb_font_create (parent->face);
 
   if (unlikely (hb_object_is_inert (font)))
     return font;
@@ -1444,6 +1507,8 @@
 {
   if (unlikely (hb_object_is_inert (font)))
     return;
+  if (font->immutable)
+    return;
 
   if (font->parent)
     hb_font_make_immutable (font->parent);
@@ -1703,10 +1768,12 @@
 /**
  * hb_font_set_ptem:
  * @font: a font.
- * @ptem: 
+ * @ptem: font size in points.
  *
- * Sets "point size" of the font.
+ * Sets "point size" of the font.  Set to 0 to unset.
  *
+ * There are 72 points in an inch.
+ *
  * Since: 1.6.0
  **/
 void
@@ -1843,8 +1910,6 @@
 }
 
 
-#ifndef HB_DISABLE_DEPRECATED
-
 /*
  * Deprecated get_glyph_func():
  */
@@ -1931,9 +1996,9 @@
 /**
  * hb_font_funcs_set_glyph_func:
  * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
+ * @func: (closure user_data) (destroy destroy) (scope notified): callback function.
+ * @user_data: data to pass to @func.
+ * @destroy: function to call when @user_data is not needed anymore.
  *
  * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
  * hb_font_funcs_set_variation_glyph_func() instead.
@@ -1967,5 +2032,3 @@
 					  trampoline,
 					  trampoline_destroy);
 }
-
-#endif /* HB_DISABLE_DEPRECATED */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -125,7 +125,15 @@
 							 hb_codepoint_t *glyph,
 							 void *user_data);
 
+typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void *font_data,
+							   unsigned int count,
+							   const hb_codepoint_t *first_unicode,
+							   unsigned int unicode_stride,
+							   hb_codepoint_t *first_glyph,
+							   unsigned int glyph_stride,
+							   void *user_data);
 
+
 typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
 							   hb_codepoint_t glyph,
 							   void *user_data);
@@ -133,8 +141,8 @@
 typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
 
 typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_data,
-						   unsigned count,
-						   hb_codepoint_t *first_glyph,
+						   unsigned int count,
+						   const hb_codepoint_t *first_glyph,
 						   unsigned glyph_stride,
 						   hb_position_t *first_advance,
 						   unsigned advance_stride,
@@ -149,13 +157,7 @@
 typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
 typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
 
-typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
-							   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-							   void *user_data);
-typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
-typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
 
-
 typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
 						       hb_codepoint_t glyph,
 						       hb_glyph_extents_t *extents,
@@ -227,6 +229,22 @@
 				      void *user_data, hb_destroy_func_t destroy);
 
 /**
+ * hb_font_funcs_set_nominal_glyphs_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 2.0.0
+ **/
+HB_EXTERN void
+hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs,
+				       hb_font_get_nominal_glyphs_func_t func,
+				       void *user_data, hb_destroy_func_t destroy);
+
+/**
  * hb_font_funcs_set_variation_glyph_func:
  * @ffuncs: font functions.
  * @func: (closure user_data) (destroy destroy) (scope notified):
@@ -339,38 +357,6 @@
 				       void *user_data, hb_destroy_func_t destroy);
 
 /**
- * hb_font_funcs_set_glyph_h_kerning_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
-					hb_font_get_glyph_h_kerning_func_t func,
-					void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_font_funcs_set_glyph_v_kerning_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
-					hb_font_get_glyph_v_kerning_func_t func,
-					void *user_data, hb_destroy_func_t destroy);
-
-/**
  * hb_font_funcs_set_glyph_extents_func:
  * @ffuncs: font functions.
  * @func: (closure user_data) (destroy destroy) (scope notified):
@@ -461,15 +447,15 @@
 
 HB_EXTERN void
 hb_font_get_glyph_h_advances (hb_font_t* font,
-			      unsigned count,
-			      hb_codepoint_t *first_glyph,
+			      unsigned int count,
+			      const hb_codepoint_t *first_glyph,
 			      unsigned glyph_stride,
 			      hb_position_t *first_advance,
 			      unsigned advance_stride);
 HB_EXTERN void
 hb_font_get_glyph_v_advances (hb_font_t* font,
-			      unsigned count,
-			      hb_codepoint_t *first_glyph,
+			      unsigned int count,
+			      const hb_codepoint_t *first_glyph,
 			      unsigned glyph_stride,
 			      hb_position_t *first_advance,
 			      unsigned advance_stride);
@@ -483,13 +469,6 @@
 			    hb_codepoint_t glyph,
 			    hb_position_t *x, hb_position_t *y);
 
-HB_EXTERN hb_position_t
-hb_font_get_glyph_h_kerning (hb_font_t *font,
-			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
-HB_EXTERN hb_position_t
-hb_font_get_glyph_v_kerning (hb_font_t *font,
-			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
-
 HB_EXTERN hb_bool_t
 hb_font_get_glyph_extents (hb_font_t *font,
 			   hb_codepoint_t glyph,
@@ -531,8 +510,8 @@
 HB_EXTERN void
 hb_font_get_glyph_advances_for_direction (hb_font_t* font,
 					  hb_direction_t direction,
-					  unsigned count,
-					  hb_codepoint_t *first_glyph,
+					  unsigned int count,
+					  const hb_codepoint_t *first_glyph,
 					  unsigned glyph_stride,
 					  hb_position_t *first_advance,
 					  unsigned advance_stride);
@@ -552,12 +531,6 @@
 					     hb_direction_t direction,
 					     hb_position_t *x, hb_position_t *y);
 
-HB_EXTERN void
-hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
-					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-					 hb_direction_t direction,
-					 hb_position_t *x, hb_position_t *y);
-
 HB_EXTERN hb_bool_t
 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
 				      hb_codepoint_t glyph,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -43,6 +43,7 @@
   HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
   HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
   HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
+  HB_FONT_FUNC_IMPLEMENT (nominal_glyphs) \
   HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
   HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
   HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
@@ -212,6 +213,18 @@
 				       unicode, glyph,
 				       klass->user_data.nominal_glyph);
   }
+  inline unsigned int get_nominal_glyphs (unsigned int count,
+					  const hb_codepoint_t *first_unicode,
+					  unsigned int unicode_stride,
+					  hb_codepoint_t *first_glyph,
+					  unsigned int glyph_stride)
+  {
+    return klass->get.f.nominal_glyphs (this, user_data,
+					count,
+					first_unicode, unicode_stride,
+					first_glyph, glyph_stride,
+					klass->user_data.nominal_glyphs);
+  }
 
   inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
 					hb_codepoint_t *glyph)
@@ -237,7 +250,7 @@
   }
 
   inline void get_glyph_h_advances (unsigned int count,
-				    hb_codepoint_t *first_glyph,
+				    const hb_codepoint_t *first_glyph,
 				    unsigned int glyph_stride,
 				    hb_position_t *first_advance,
 				    unsigned int advance_stride)
@@ -250,7 +263,7 @@
   }
 
   inline void get_glyph_v_advances (unsigned int count,
-				    hb_codepoint_t *first_glyph,
+				    const hb_codepoint_t *first_glyph,
 				    unsigned int glyph_stride,
 				    hb_position_t *first_advance,
 				    unsigned int advance_stride)
@@ -377,8 +390,8 @@
       *y = get_glyph_v_advance (glyph);
   }
   inline void get_glyph_advances_for_direction (hb_direction_t direction,
-						unsigned count,
-						hb_codepoint_t *first_glyph,
+						unsigned int count,
+						const hb_codepoint_t *first_glyph,
 						unsigned glyph_stride,
 						hb_position_t *first_advance,
 						unsigned advance_stride)
@@ -502,8 +515,8 @@
 					       hb_position_t *x, hb_position_t *y)
   {
     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+      *y = 0;
       *x = get_glyph_h_kerning (first_glyph, second_glyph);
-      *y = 0;
     } else {
       *x = 0;
       *y = get_glyph_v_kerning (first_glyph, second_glyph);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -33,6 +33,7 @@
 
 #include "hb-font.hh"
 #include "hb-machinery.hh"
+#include "hb-cache.hh"
 
 #include FT_ADVANCES_H
 #include FT_MULTIPLE_MASTERS_H
@@ -44,30 +45,29 @@
  * In general, this file does a fine job of what it's supposed to do.
  * There are, however, things that need more work:
  *
- *   - I remember seeing FT_Get_Advance() without the NO_HINTING flag to be buggy.
- *     Have not investigated.
- *
  *   - FreeType works in 26.6 mode.  Clients can decide to use that mode, and everything
  *     would work fine.  However, we also abuse this API for performing in font-space,
  *     but don't pass the correct flags to FreeType.  We just abuse the no-hinting mode
  *     for that, such that no rounding etc happens.  As such, we don't set ppem, and
  *     pass NO_HINTING as load_flags.  Would be much better to use NO_SCALE, and scale
- *     ourselves, like we do in uniscribe, etc.
+ *     ourselves.
  *
  *   - We don't handle / allow for emboldening / obliqueing.
  *
  *   - In the future, we should add constructors to create fonts in font space?
- *
- *   - FT_Load_Glyph() is extremely costly.  Do something about it?
  */
 
 
 struct hb_ft_font_t
 {
+  mutable hb_mutex_t lock;
   FT_Face ft_face;
   int load_flags;
   bool symbol; /* Whether selected cmap is symbol cmap. */
   bool unref; /* Whether to destroy ft_face when done. */
+
+  mutable hb_atomic_int_t cached_x_scale;
+  mutable hb_advance_cache_t advance_cache;
 };
 
 static hb_ft_font_t *
@@ -78,6 +78,7 @@
   if (unlikely (!ft_font))
     return nullptr;
 
+  ft_font->lock.init ();
   ft_font->ft_face = ft_face;
   ft_font->symbol = symbol;
   ft_font->unref = unref;
@@ -84,6 +85,9 @@
 
   ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
 
+  ft_font->cached_x_scale.set (0);
+  ft_font->advance_cache.init ();
+
   return ft_font;
 }
 
@@ -98,9 +102,13 @@
 {
   hb_ft_font_t *ft_font = (hb_ft_font_t *) data;
 
+  ft_font->advance_cache.fini ();
+
   if (ft_font->unref)
     _hb_ft_face_destroy (ft_font->ft_face);
 
+  ft_font->lock.fini ();
+
   free (ft_font);
 }
 
@@ -168,6 +176,7 @@
 			 void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
   unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode);
 
   if (unlikely (!g))
@@ -191,6 +200,32 @@
   return true;
 }
 
+static unsigned int
+hb_ft_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
+			  void *font_data,
+			  unsigned int count,
+			  const hb_codepoint_t *first_unicode,
+			  unsigned int unicode_stride,
+			  hb_codepoint_t *first_glyph,
+			  unsigned int glyph_stride,
+			  void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
+  unsigned int done;
+  for (done = 0;
+       done < count && (*first_glyph = FT_Get_Char_Index (ft_font->ft_face, *first_unicode));
+       done++)
+  {
+    first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride);
+    first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
+  }
+  /* We don't need to do ft_font->symbol dance here, since HB calls the singular
+   * nominal_glyph() for what we don't handle here. */
+  return done;
+}
+
+
 static hb_bool_t
 hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
 			   void *font_data,
@@ -200,6 +235,7 @@
 			   void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
   unsigned int g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
 
   if (unlikely (!g))
@@ -209,22 +245,45 @@
   return true;
 }
 
-static hb_position_t
-hb_ft_get_glyph_h_advance (hb_font_t *font,
-			   void *font_data,
-			   hb_codepoint_t glyph,
-			   void *user_data HB_UNUSED)
+static void
+hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
+			    unsigned count,
+			    const hb_codepoint_t *first_glyph,
+			    unsigned glyph_stride,
+			    hb_position_t *first_advance,
+			    unsigned advance_stride,
+			    void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
-  FT_Fixed v;
+  hb_lock_t lock (ft_font->lock);
+  FT_Face ft_face = ft_font->ft_face;
+  int load_flags = ft_font->load_flags;
+  int mult = font->x_scale < 0 ? -1 : +1;
 
-  if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags, &v)))
-    return 0;
+  if (font->x_scale != ft_font->cached_x_scale.get ())
+  {
+    ft_font->advance_cache.clear ();
+    ft_font->cached_x_scale.set (font->x_scale);
+  }
 
-  if (font->x_scale < 0)
-    v = -v;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    FT_Fixed v = 0;
+    hb_codepoint_t glyph = *first_glyph;
 
-  return (v + (1<<9)) >> 10;
+    unsigned int cv;
+    if (ft_font->advance_cache.get (glyph, &cv))
+      v = cv;
+    else
+    {
+      FT_Get_Advance (ft_face, glyph, load_flags, &v);
+      ft_font->advance_cache.set (glyph, v);
+    }
+
+    *first_advance = (v * mult + (1<<9)) >> 10;
+    first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
+    first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
+  }
 }
 
 static hb_position_t
@@ -234,6 +293,7 @@
 			   void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
   FT_Fixed v;
 
   if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v)))
@@ -256,6 +316,7 @@
 			  void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
   FT_Face ft_face = ft_font->ft_face;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
@@ -274,23 +335,6 @@
   return true;
 }
 
-static hb_position_t
-hb_ft_get_glyph_h_kerning (hb_font_t *font,
-			   void *font_data,
-			   hb_codepoint_t left_glyph,
-			   hb_codepoint_t right_glyph,
-			   void *user_data HB_UNUSED)
-{
-  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
-  FT_Vector kerningv;
-
-  FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
-  if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
-    return 0;
-
-  return kerningv.x;
-}
-
 static hb_bool_t
 hb_ft_get_glyph_extents (hb_font_t *font,
 			 void *font_data,
@@ -299,6 +343,7 @@
 			 void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
   FT_Face ft_face = ft_font->ft_face;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
@@ -331,6 +376,7 @@
 			       void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
   FT_Face ft_face = ft_font->ft_face;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
@@ -356,8 +402,10 @@
 		      void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
+  FT_Face ft_face = ft_font->ft_face;
 
-  hb_bool_t ret = !FT_Get_Glyph_Name (ft_font->ft_face, glyph, name, size);
+  hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size);
   if (ret && (size && !*name))
     ret = false;
 
@@ -372,6 +420,7 @@
 			   void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
   FT_Face ft_face = ft_font->ft_face;
 
   if (len < 0)
@@ -404,6 +453,7 @@
 			  void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
   FT_Face ft_face = ft_font->ft_face;
   metrics->ascender = ft_face->size->metrics.ascender;
   metrics->descender = ft_face->size->metrics.descender;
@@ -430,13 +480,12 @@
     hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr);
     //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr);
     hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr);
+    hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ft_get_nominal_glyphs, nullptr, nullptr);
     hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr);
-    hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, nullptr, nullptr);
+    hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr);
     hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
     //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr);
     hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr);
-    hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr);
-    //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr);
     hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr);
     hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr);
     hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -30,7 +30,6 @@
 
 #include "hb-glib.h"
 
-#include "hb-unicode.hh"
 #include "hb-machinery.hh"
 
 
@@ -202,14 +201,6 @@
   return (hb_unicode_combining_class_t) g_unichar_combining_class (unicode);
 }
 
-static unsigned int
-hb_glib_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
-				 hb_codepoint_t      unicode,
-				 void               *user_data HB_UNUSED)
-{
-  return g_unichar_iswide (unicode) ? 2 : 1;
-}
-
 static hb_unicode_general_category_t
 hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
 				  hb_codepoint_t      unicode,
@@ -334,38 +325,7 @@
   return ret;
 }
 
-static unsigned int
-hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
-					 hb_codepoint_t      u,
-					 hb_codepoint_t     *decomposed,
-					 void               *user_data HB_UNUSED)
-{
-#if GLIB_CHECK_VERSION(2,29,12)
-  return g_unichar_fully_decompose (u, true, decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN);
-#endif
 
-  /* If the user doesn't have GLib >= 2.29.12 we have to perform
-   * a round trip to UTF-8 and the associated memory management dance. */
-  gchar utf8[6];
-  gchar *utf8_decomposed, *c;
-  gsize utf8_len, utf8_decomposed_len, i;
-
-  /* Convert @u to UTF-8 and normalise it in NFKD mode. This performs the compatibility decomposition. */
-  utf8_len = g_unichar_to_utf8 (u, utf8);
-  utf8_decomposed = g_utf8_normalize (utf8, utf8_len, G_NORMALIZE_NFKD);
-  utf8_decomposed_len = g_utf8_strlen (utf8_decomposed, -1);
-
-  assert (utf8_decomposed_len <= HB_UNICODE_MAX_DECOMPOSITION_LEN);
-
-  for (i = 0, c = utf8_decomposed; i < utf8_decomposed_len; i++, c = g_utf8_next_char (c))
-    *decomposed++ = g_utf8_get_char (c);
-
-  g_free (utf8_decomposed);
-
-  return utf8_decomposed_len;
-}
-
-
 #ifdef HB_USE_ATEXIT
 static void free_static_glib_funcs (void);
 #endif
@@ -376,10 +336,12 @@
   {
     hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
 
-#define HB_UNICODE_FUNC_IMPLEMENT(name) \
-    hb_unicode_funcs_set_##name##_func (funcs, hb_glib_unicode_##name, nullptr, nullptr);
-      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_UNICODE_FUNC_IMPLEMENT
+    hb_unicode_funcs_set_combining_class_func (funcs, hb_glib_unicode_combining_class, nullptr, nullptr);
+    hb_unicode_funcs_set_general_category_func (funcs, hb_glib_unicode_general_category, nullptr, nullptr);
+    hb_unicode_funcs_set_mirroring_func (funcs, hb_glib_unicode_mirroring, nullptr, nullptr);
+    hb_unicode_funcs_set_script_func (funcs, hb_glib_unicode_script, nullptr, nullptr);
+    hb_unicode_funcs_set_compose_func (funcs, hb_glib_unicode_compose, nullptr, nullptr);
+    hb_unicode_funcs_set_decompose_func (funcs, hb_glib_unicode_decompose, nullptr, nullptr);
 
     hb_unicode_funcs_make_immutable (funcs);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -33,7 +33,9 @@
 
 #include <graphite2/Segment.h>
 
+#include "hb-ot-tag.h"
 
+
 HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face)
 HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, font)
 
@@ -95,6 +97,32 @@
   return d;
 }
 
+static void hb_graphite2_release_table(const void *data, const void *table_buffer)
+{
+  hb_graphite2_face_data_t *face_data = (hb_graphite2_face_data_t *) data;
+  hb_graphite2_tablelist_t *tlist = face_data->tlist.get();
+
+  hb_graphite2_tablelist_t *prev = nullptr;
+  hb_graphite2_tablelist_t *curr = tlist;
+  while (curr)
+  {
+    if (hb_blob_get_data(curr->blob, nullptr) == table_buffer)
+    {
+      if (prev == nullptr)
+        face_data->tlist.cmpexch(tlist, curr->next);
+      else
+        prev->next = curr->next;
+      hb_blob_destroy(curr->blob);
+      free(curr);
+      break;
+    }
+    prev = curr;
+    curr = curr->next;
+  }
+}
+
+static gr_face_ops hb_graphite2_face_ops = { sizeof(gr_face_ops), hb_graphite2_get_table, hb_graphite2_release_table };
+
 hb_graphite2_face_data_t *
 _hb_graphite2_shaper_face_data_create (hb_face_t *face)
 {
@@ -113,7 +141,7 @@
     return nullptr;
 
   data->face = face;
-  data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll);
+  data->grface = gr_make_face_with_ops (data, &hb_graphite2_face_ops, gr_face_preloadAll);
 
   if (unlikely (!data->grface)) {
     free (data);
@@ -251,11 +279,16 @@
 
   /* TODO ensure_native_direction. */
 
-  hb_tag_t script_tag[2];
-  hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]);
+  hb_tag_t script_tag[HB_OT_MAX_TAGS_PER_SCRIPT];
+  unsigned int count = HB_OT_MAX_TAGS_PER_SCRIPT;
+  hb_ot_tags_from_script_and_language (hb_buffer_get_script (buffer),
+				       HB_LANGUAGE_INVALID,
+				       &count,
+				       script_tag,
+				       nullptr, nullptr);
 
   seg = gr_make_seg (nullptr, grface,
-		     script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1],
+		     count ? script_tag[count - 1] : HB_OT_TAG_DEFAULT_SCRIPT,
 		     feats,
 		     gr_utf32, chars, buffer->len,
 		     2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -41,7 +41,7 @@
 
 #ifndef HB_DISABLE_DEPRECATED
 
-HB_EXTERN gr_font *
+HB_EXTERN HB_DEPRECATED_FOR (hb_graphite2_face_get_gr_face) gr_font *
 hb_graphite2_font_get_gr_font (hb_font_t *font);
 
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -31,7 +31,6 @@
 
 #include "hb-icu.h"
 
-#include "hb-unicode.hh"
 #include "hb-machinery.hh"
 
 #include <unicode/uchar.h>
@@ -73,25 +72,6 @@
   return (hb_unicode_combining_class_t) u_getCombiningClass (unicode);
 }
 
-static unsigned int
-hb_icu_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
-				hb_codepoint_t      unicode,
-				void               *user_data HB_UNUSED)
-{
-  switch (u_getIntPropertyValue(unicode, UCHAR_EAST_ASIAN_WIDTH))
-  {
-  case U_EA_WIDE:
-  case U_EA_FULLWIDTH:
-    return 2;
-  case U_EA_NEUTRAL:
-  case U_EA_AMBIGUOUS:
-  case U_EA_HALFWIDTH:
-  case U_EA_NARROW:
-    return 1;
-  }
-  return 1;
-}
-
 static hb_unicode_general_category_t
 hb_icu_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
 				 hb_codepoint_t      unicode,
@@ -309,40 +289,7 @@
   return ret;
 }
 
-static unsigned int
-hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
-					hb_codepoint_t      u,
-					hb_codepoint_t     *decomposed,
-					void               *user_data HB_UNUSED)
-{
-  UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
-  unsigned int len;
-  int32_t utf32_len;
-  hb_bool_t err;
-  UErrorCode icu_err;
 
-  /* Copy @u into a UTF-16 array to be passed to ICU. */
-  len = 0;
-  err = false;
-  U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err);
-  if (err)
-    return 0;
-
-  /* Normalise the codepoint using NFKD mode. */
-  icu_err = U_ZERO_ERROR;
-  len = unorm2_normalize (unorm2_getNFKDInstance (&icu_err), utf16, len, normalized, ARRAY_LENGTH (normalized), &icu_err);
-  if (U_FAILURE (icu_err))
-    return 0;
-
-  /* Convert the decomposed form from UTF-16 to UTF-32. */
-  icu_err = U_ZERO_ERROR;
-  u_strToUTF32 ((UChar32*) decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN, &utf32_len, normalized, len, &icu_err);
-  if (U_FAILURE (icu_err))
-    return 0;
-
-  return utf32_len;
-}
-
 #ifdef HB_USE_ATEXIT
 static void free_static_icu_funcs (void);
 #endif
@@ -360,10 +307,12 @@
 
     hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
 
-#define HB_UNICODE_FUNC_IMPLEMENT(name) \
-    hb_unicode_funcs_set_##name##_func (funcs, hb_icu_unicode_##name, user_data, nullptr);
-      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_UNICODE_FUNC_IMPLEMENT
+    hb_unicode_funcs_set_combining_class_func (funcs, hb_icu_unicode_combining_class, nullptr, nullptr);
+    hb_unicode_funcs_set_general_category_func (funcs, hb_icu_unicode_general_category, nullptr, nullptr);
+    hb_unicode_funcs_set_mirroring_func (funcs, hb_icu_unicode_mirroring, nullptr, nullptr);
+    hb_unicode_funcs_set_script_func (funcs, hb_icu_unicode_script, nullptr, nullptr);
+    hb_unicode_funcs_set_compose_func (funcs, hb_icu_unicode_compose, user_data, nullptr);
+    hb_unicode_funcs_set_decompose_func (funcs, hb_icu_unicode_decompose, user_data, nullptr);
 
     hb_unicode_funcs_make_immutable (funcs);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -217,6 +217,9 @@
 #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>
@@ -224,7 +227,8 @@
   inline hb_sanitize_context_t (void) :
 	debug_depth (0),
 	start (nullptr), end (nullptr),
-	writable (false), edit_count (0), max_ops (0),
+	max_ops (0),
+	writable (false), edit_count (0),
 	blob (nullptr),
 	num_glyphs (65536),
 	num_glyphs_set (false) {}
@@ -252,6 +256,23 @@
   }
   inline unsigned int get_num_glyphs (void) { return num_glyphs; }
 
+  inline void set_max_ops (int max_ops_) { max_ops = max_ops_; }
+
+  /* TODO
+   * This set_object() thing is to use sanitize at runtime lookup
+   * application time.  This is very distinct from the regular
+   * sanitizer operation, so, eventually, separate into another
+   * type and make hb_aat_apply_context_t use that one instead
+   * of abusing this one.
+   */
+  template <typename T>
+  inline void set_object (const T& obj)
+  {
+    this->start = (const char *) &obj;
+    this->end = (const char *) &obj + obj.get_size ();
+    assert (this->start <= this->end); /* Must not overflow. */
+  }
+
   inline void start_processing (void)
   {
     this->start = this->blob->data;
@@ -282,10 +303,10 @@
   inline bool check_range (const void *base, unsigned int len) const
   {
     const char *p = (const char *) base;
-    bool ok = this->max_ops-- > 0 &&
-	      this->start <= p &&
+    bool ok = this->start <= p &&
 	      p <= this->end &&
-	      (unsigned int) (this->end - p) >= len;
+	      (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",
@@ -296,7 +317,8 @@
     return likely (ok);
   }
 
-  inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const
+  template <typename T>
+  inline bool check_array (const T *base, unsigned int len, unsigned int record_size = T::static_size) const
   {
     const char *p = (const char *) base;
     bool overflows = hb_unsigned_mul_overflows (len, record_size);
@@ -422,10 +444,10 @@
 
   mutable unsigned int debug_depth;
   const char *start, *end;
+  mutable int max_ops;
   private:
   bool writable;
   unsigned int edit_count;
-  mutable int max_ops;
   hb_blob_t *blob;
   unsigned int num_glyphs;
   bool  num_glyphs_set;
@@ -590,7 +612,7 @@
   }
   inline Supplier (const hb_vector_t<Type> *v)
   {
-    head = v->arrayZ;
+    head = v->arrayZ();
     len = v->len;
     stride = sizeof (Type);
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -137,5 +137,13 @@
   inline void fini (void) { hb_mutex_impl_finish (&m); }
 };
 
+struct hb_lock_t
+{
+  inline hb_lock_t (hb_mutex_t &mutex_) : mutex (mutex_) { mutex.lock (); }
+  inline ~hb_lock_t (void) { mutex.unlock (); }
+  private:
+  hb_mutex_t &mutex;
+};
 
+
 #endif /* HB_MUTEX_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -36,7 +36,7 @@
 
 /* Global nul-content Null pool.  Enlarge as necessary. */
 
-#define HB_NULL_POOL_SIZE 264
+#define HB_NULL_POOL_SIZE 1024
 
 extern HB_INTERNAL
 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)];
@@ -73,19 +73,6 @@
 #define DEFINE_NULL_INSTANCE(Type) \
 	const Type _hb_Null_##Type
 
-/* Specializaiton to disallow Null objects. */
-#define DECLARE_NULL_DISALLOW(Type) \
-	template <> inline const Type& Null<Type> (void)
-#define DECLARE_NULL_NAMSPACE_DISALLOW(Namespace, Type) \
-	} /* Close namespace. */ \
-	template <> \
-	/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \
-	  extern void *_hb_undefined; \
-	  return *reinterpret_cast<const Namespace::Type *> (_hb_undefined); \
-	} \
-	namespace Namespace { \
-	static_assert (true, "Just so we take semicolon after.")
-
 /* Global writable pool.  Enlarge as necessary. */
 
 /* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -287,22 +287,31 @@
 
 /*
  * Mac Resource Fork
+ *
+ * http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html
  */
 
-struct ResourceRefItem
+struct ResourceRecord
 {
-  inline bool sanitize (hb_sanitize_context_t *c) const
+  inline const OpenTypeFontFace & get_face (const void *data_base) const
+  { return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
+
+  inline bool sanitize (hb_sanitize_context_t *c,
+			const void *data_base) const
   {
     TRACE_SANITIZE (this);
-    // actual data sanitization is done on ResourceForkHeader sanitizer
-    return_trace (likely (c->check_struct (this)));
+    return_trace (c->check_struct (this) &&
+		  offset.sanitize (c, data_base) &&
+		  get_face (data_base).sanitize (c));
   }
 
-  HBINT16	id;		/* Resource ID, is really should be signed? */
+  protected:
+  HBUINT16	id;		/* Resource ID. */
   HBINT16	nameOffset;	/* Offset from beginning of resource name list
-				 * to resource name, minus means there is no */
-  HBUINT8	attr;		/* Resource attributes */
-  HBUINT24	dataOffset;	/* Offset from beginning of resource data to
+				 * to resource name, -1 means there is none. */
+  HBUINT8	attrs;		/* Resource attributes */
+  OffsetTo<LArrayOf<HBUINT8>, HBUINT24, false>
+		offset;		/* Offset from beginning of data block to
 				 * data for this resource */
   HBUINT32	reserved;	/* Reserved for handle to resource */
   public:
@@ -309,37 +318,39 @@
   DEFINE_SIZE_STATIC (12);
 };
 
-struct ResourceTypeItem
+#define HB_TAG_sfnt HB_TAG ('s','f','n','t')
+
+struct ResourceTypeRecord
 {
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    // RefList sanitization is done on ResourceMap sanitizer
-    return_trace (likely (c->check_struct (this)));
-  }
+  inline unsigned int get_resource_count (void) const
+  { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; }
 
-  inline unsigned int get_resource_count () const
-  {
-    return numRes + 1;
-  }
+  inline bool is_sfnt (void) const { return tag == HB_TAG_sfnt; }
 
-  inline bool is_sfnt () const
+  inline const ResourceRecord& get_resource_record (unsigned int i,
+						    const void *type_base) const
   {
-    return type == HB_TAG ('s','f','n','t');
+    return hb_array_t<ResourceRecord> ((type_base+resourcesZ).arrayZ,
+				       get_resource_count ()) [i];
   }
 
-  inline const ResourceRefItem& get_ref_item (const void *base,
-					      unsigned int i) const
+  inline bool sanitize (hb_sanitize_context_t *c,
+			const void *type_base,
+			const void *data_base) const
   {
-    return (base+refList)[i];
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  resourcesZ.sanitize (c, type_base,
+				       get_resource_count (),
+				       data_base));
   }
 
   protected:
-  Tag		type;		/* Resource type */
-  HBUINT16	numRes;		/* Number of resource this type in map minus 1 */
-  OffsetTo<UnsizedArrayOf<ResourceRefItem> >
-		refList;	/* Offset from beginning of resource type list
-				 * to reference list for this type */
+  Tag		tag;		/* Resource type. */
+  HBUINT16	resCountM1;	/* Number of resources minus 1. */
+  OffsetTo<UnsizedArrayOf<ResourceRecord>, HBUINT16, false>
+		resourcesZ;	/* Offset from beginning of resource type list
+				 * to reference item list for this type. */
   public:
   DEFINE_SIZE_STATIC (8);
 };
@@ -346,129 +357,89 @@
 
 struct ResourceMap
 {
-  inline bool sanitize (hb_sanitize_context_t *c) const
+  inline unsigned int get_face_count (void) const
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!c->check_struct (this)))
-      return_trace (false);
-    for (unsigned int i = 0; i < get_types_count (); ++i)
+    unsigned int count = get_type_count ();
+    for (unsigned int i = 0; i < count; i++)
     {
-      const ResourceTypeItem& type = get_type (i);
-      if (unlikely (!type.sanitize (c)))
-        return_trace (false);
-      for (unsigned int j = 0; j < type.get_resource_count (); ++j)
-	if (unlikely (!get_ref_item (type, j).sanitize (c)))
-	  return_trace (false);
+      const ResourceTypeRecord& type = get_type_record (i);
+      if (type.is_sfnt ())
+	return type.get_resource_count ();
     }
-    return_trace (true);
+    return 0;
   }
 
-  inline const ResourceTypeItem& get_type (unsigned int i) const
+  inline const OpenTypeFontFace& get_face (unsigned int idx,
+					   const void *data_base) const
   {
-    // Why offset from the second byte of the object? I'm not sure
-    return ((&reserved[2])+typeList)[i];
+    unsigned int count = get_type_count ();
+    for (unsigned int i = 0; i < count; i++)
+    {
+      const ResourceTypeRecord& type = get_type_record (i);
+      /* The check for idx < count is here because ResourceRecord is NOT null-safe.
+       * Because an offset of 0 there does NOT mean null. */
+      if (type.is_sfnt () && idx < type.get_resource_count ())
+	return type.get_resource_record (idx, &(this+typeList)).get_face (data_base);
+    }
+    return Null (OpenTypeFontFace);
   }
 
-  inline unsigned int get_types_count () const
+  inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const
   {
-    return nTypes + 1;
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  typeList.sanitize (c, this,
+				     &(this+typeList),
+				     data_base));
   }
 
-  inline const ResourceRefItem &get_ref_item (const ResourceTypeItem &type,
-					      unsigned int i) const
-  {
-    return type.get_ref_item (&(this+typeList), i);
-  }
+  private:
+  inline unsigned int get_type_count (void) const { return (this+typeList).lenM1 + 1; }
 
-  inline const PString& get_name (const ResourceRefItem &item,
-				  unsigned int i) const
-  {
-    if (item.nameOffset == -1)
-      return Null (PString);
+  inline const ResourceTypeRecord& get_type_record (unsigned int i) const
+  { return (this+typeList)[i]; }
 
-    return StructAtOffset<PString> (this, nameList + item.nameOffset);
-  }
-
   protected:
-  HBUINT8	reserved[16];	/* Reserved for copy of resource header */
-  LOffsetTo<ResourceMap>
-		reserved1;	/* Reserved for handle to next resource map */
-  HBUINT16	reserved2;	/* Reserved for file reference number */
-  HBUINT16	attr;		/* Resource fork attribute */
-  OffsetTo<UnsizedArrayOf<ResourceTypeItem> >
+  HBUINT8	reserved0[16];	/* Reserved for copy of resource header */
+  HBUINT32	reserved1;	/* Reserved for handle to next resource map */
+  HBUINT16	resreved2;	/* Reserved for file reference number */
+  HBUINT16	attrs;		/* Resource fork attribute */
+  OffsetTo<ArrayOfM1<ResourceTypeRecord>, HBUINT16, false>
 		typeList;	/* Offset from beginning of map to
 				 * resource type list */
-  HBUINT16	nameList;	/* Offset from beginning of map to
+  Offset16	nameList;	/* Offset from beginning of map to
 				 * resource name list */
-  HBUINT16	nTypes;		/* Number of types in the map minus 1 */
   public:
-  DEFINE_SIZE_STATIC (30);
+  DEFINE_SIZE_STATIC (28);
 };
 
 struct ResourceForkHeader
 {
-  inline unsigned int get_face_count () const
-  {
-    const ResourceMap &resource_map = this+map;
-    for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
-    {
-      const ResourceTypeItem& type = resource_map.get_type (i);
-      if (type.is_sfnt ())
-	return type.get_resource_count ();
-    }
-    return 0;
-  }
+  inline unsigned int get_face_count (void) const
+  { return (this+map).get_face_count (); }
 
-  inline const LArrayOf<HBUINT8>& get_data (const ResourceTypeItem& type,
-					    unsigned int idx) const
+  inline const OpenTypeFontFace& get_face (unsigned int idx,
+					   unsigned int *base_offset = nullptr) const
   {
-    const ResourceMap &resource_map = this+map;
-    unsigned int offset = dataOffset;
-    offset += resource_map.get_ref_item (type, idx).dataOffset;
-    return StructAtOffset<LArrayOf<HBUINT8> > (this, offset);
+    const OpenTypeFontFace &face = (this+map).get_face (idx, &(this+data));
+    if (base_offset)
+      *base_offset = (const char *) &face - (const char *) this;
+    return face;
   }
 
-  inline const OpenTypeFontFace& get_face (unsigned int idx) const
-  {
-    const ResourceMap &resource_map = this+map;
-    for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
-    {
-      const ResourceTypeItem& type = resource_map.get_type (i);
-      if (type.is_sfnt () && idx < type.get_resource_count ())
-	return (OpenTypeFontFace&) get_data (type, idx).arrayZ;
-    }
-    return Null (OpenTypeFontFace);
-  }
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!c->check_struct (this)))
-      return_trace (false);
-
-    const ResourceMap &resource_map = this+map;
-    if (unlikely (!resource_map.sanitize (c)))
-      return_trace (false);
-
-    for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
-    {
-      const ResourceTypeItem& type = resource_map.get_type (i);
-      for (unsigned int j = 0; j < type.get_resource_count (); ++j)
-      {
-        const LArrayOf<HBUINT8>& data = get_data (type, j);
-	if (unlikely (!(data.sanitize (c) &&
-			((OpenTypeFontFace&) data.arrayZ).sanitize (c))))
-	  return_trace (false);
-      }
-    }
-
-    return_trace (true);
+    return_trace (c->check_struct (this) &&
+		  data.sanitize (c, this, dataLen) &&
+		  map.sanitize (c, this, &(this+data)));
   }
 
   protected:
-  HBUINT32	dataOffset;	/* Offset from beginning of resource fork
+  LOffsetTo<UnsizedArrayOf<HBUINT8>, false>
+		data;		/* Offset from beginning of resource fork
 				 * to resource data */
-  LOffsetTo<ResourceMap>
+  LOffsetTo<ResourceMap, false>
 		map;		/* Offset from beginning of resource fork
 				 * to resource map */
   HBUINT32	dataLen;	/* Length of resource data */
@@ -485,7 +456,7 @@
 {
   enum {
     CFFTag		= HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */
-    TrueTypeTag	= HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */
+    TrueTypeTag		= HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */
     TTCTag		= HB_TAG ('t','t','c','f'), /* TrueType Collection */
     DFontTag		= HB_TAG ( 0 , 0 , 1 , 0 ), /* DFont Mac Resource Fork */
     TrueTag		= HB_TAG ('t','r','u','e'), /* Obsolete Apple TrueType */
@@ -502,12 +473,14 @@
     case Typ1Tag:
     case TrueTypeTag:	return 1;
     case TTCTag:	return u.ttcHeader.get_face_count ();
-//    case DFontTag:	return u.rfHeader.get_face_count ();
+    case DFontTag:	return u.rfHeader.get_face_count ();
     default:		return 0;
     }
   }
-  inline const OpenTypeFontFace& get_face (unsigned int i) const
+  inline const OpenTypeFontFace& get_face (unsigned int i, unsigned int *base_offset = nullptr) const
   {
+    if (base_offset)
+      *base_offset = 0;
     switch (u.tag) {
     /* Note: for non-collection SFNT data we ignore index.  This is because
      * Apple dfont container is a container of SFNT's.  So each SFNT is a
@@ -517,7 +490,7 @@
     case Typ1Tag:
     case TrueTypeTag:	return u.fontFace;
     case TTCTag:	return u.ttcHeader.get_face (i);
-//    case DFontTag:	return u.rfHeader.get_face (i);
+    case DFontTag:	return u.rfHeader.get_face (i, base_offset);
     default:		return Null(OpenTypeFontFace);
     }
   }
@@ -544,7 +517,7 @@
     case Typ1Tag:
     case TrueTypeTag:	return_trace (u.fontFace.sanitize (c));
     case TTCTag:	return_trace (u.ttcHeader.sanitize (c));
-//    case DFontTag:	return_trace (u.rfHeader.sanitize (c));
+    case DFontTag:	return_trace (u.rfHeader.sanitize (c));
     default:		return_trace (true);
     }
   }

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -92,6 +92,9 @@
 /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
 typedef HBINT16 FWORD;
 
+/* 32-bit signed integer (HBINT32) that describes a quantity in FUnits. */
+typedef HBINT32 FWORD32;
+
 /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
 typedef HBUINT16 UFWORD;
 
@@ -155,10 +158,10 @@
 DECLARE_NULL_NAMESPACE_BYTES (OT, Index);
 
 /* Offset, Null offset = 0 */
-template <typename Type>
+template <typename Type, bool has_null=true>
 struct Offset : Type
 {
-  inline bool is_null (void) const { return 0 == *this; }
+  inline bool is_null (void) const { return has_null && 0 == *this; }
 
   inline void *serialize (hb_serialize_context_t *c, const void *base)
   {
@@ -226,20 +229,23 @@
  * Use: (base+offset)
  */
 
-template <typename Type, typename OffsetType=HBUINT16>
-struct OffsetTo : Offset<OffsetType>
+template <typename Type, bool has_null_> struct assert_has_min_size { static_assert (Type::min_size > 0, ""); };
+template <typename Type> struct assert_has_min_size<Type, false> {};
+
+template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
+struct OffsetTo : Offset<OffsetType, has_null>
 {
+  static_assert (sizeof (assert_has_min_size<Type, has_null>) || true, "");
+
   inline const Type& operator () (const void *base) const
   {
-    unsigned int offset = *this;
-    if (unlikely (!offset)) return Null(Type);
-    return StructAtOffset<const Type> (base, offset);
+    if (unlikely (this->is_null ())) return Null(Type);
+    return StructAtOffset<const Type> (base, *this);
   }
   inline Type& operator () (void *base) const
   {
-    unsigned int offset = *this;
-    if (unlikely (!offset)) return Crap(Type);
-    return StructAtOffset<Type> (base, offset);
+    if (unlikely (this->is_null ())) return Crap(Type);
+    return StructAtOffset<Type> (base, *this);
   }
 
   inline Type& serialize (hb_serialize_context_t *c, const void *base)
@@ -260,39 +266,64 @@
       this->set (0);
   }
 
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  inline bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!c->check_struct (this))) return_trace (false);
-    unsigned int offset = *this;
-    if (unlikely (!offset)) return_trace (true);
-    if (unlikely (!c->check_range (base, offset))) return_trace (false);
-    const Type &obj = StructAtOffset<Type> (base, offset);
-    return_trace (likely (obj.sanitize (c)) || neuter (c));
+    if (unlikely (this->is_null ())) return_trace (true);
+    if (unlikely (!c->check_range (base, *this))) return_trace (false);
+    return_trace (true);
   }
-  template <typename T>
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!c->check_struct (this))) return_trace (false);
-    unsigned int offset = *this;
-    if (unlikely (!offset)) return_trace (true);
-    if (unlikely (!c->check_range (base, offset))) return_trace (false);
-    const Type &obj = StructAtOffset<Type> (base, offset);
-    return_trace (likely (obj.sanitize (c, user_data)) || neuter (c));
+    return_trace (sanitize_shallow (c, base) &&
+		  (this->is_null () ||
+		   StructAtOffset<Type> (base, *this).sanitize (c) ||
+		   neuter (c)));
   }
+  template <typename T1>
+  inline 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>
+  inline 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>
+  inline 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 */
-  inline bool neuter (hb_sanitize_context_t *c) const {
+  inline bool neuter (hb_sanitize_context_t *c) const
+  {
+    if (!has_null) return false;
     return c->try_set (this, 0);
   }
   DEFINE_SIZE_STATIC (sizeof(OffsetType));
 };
-template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {};
-template <typename Base, typename OffsetType, typename Type>
-static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
-template <typename Base, typename OffsetType, typename Type>
-static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); }
+template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {};
+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); }
 
 
 /*
@@ -299,7 +330,6 @@
  * Array Types
  */
 
-/* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */
 template <typename Type>
 struct UnsizedArrayOf
 {
@@ -345,22 +375,22 @@
   inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count));
+    return_trace (c->check_array (arrayZ, count));
   }
 
   public:
-  Type	arrayZ[VAR];
+  Type		arrayZ[VAR];
   public:
   DEFINE_SIZE_ARRAY (0, arrayZ);
 };
 
 /* Unsized array of offset's */
-template <typename Type, typename OffsetType>
-struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {};
+template <typename Type, typename OffsetType, bool has_null=true>
+struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null> > {};
 
 /* Unsized array of offsets relative to the beginning of the array itself. */
-template <typename Type, typename OffsetType>
-struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType>
+template <typename Type, typename OffsetType, bool has_null=true>
+struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null>
 {
   inline const Type& operator [] (unsigned int i) const
   {
@@ -370,13 +400,13 @@
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
   {
     TRACE_SANITIZE (this);
-    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this)));
+    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>::sanitize (c, count, this)));
   }
   template <typename T>
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const
   {
     TRACE_SANITIZE (this);
-    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data)));
+    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>::sanitize (c, count, this, user_data)));
   }
 };
 
@@ -487,12 +517,12 @@
   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (len.sanitize (c) && c->check_array (arrayZ, Type::static_size, len));
+    return_trace (len.sanitize (c) && c->check_array (arrayZ, len));
   }
 
   public:
-  LenType len;
-  Type arrayZ[VAR];
+  LenType	len;
+  Type		arrayZ[VAR];
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
@@ -548,16 +578,16 @@
 {
   inline const Type& operator [] (unsigned int i) const
   {
-    if (unlikely (i >= len || !i)) return Null(Type);
+    if (unlikely (i >= lenP1 || !i)) return Null(Type);
     return arrayZ[i-1];
   }
   inline Type& operator [] (unsigned int i)
   {
-    if (unlikely (i >= len || !i)) return Crap(Type);
+    if (unlikely (i >= lenP1 || !i)) return Crap(Type);
     return arrayZ[i-1];
   }
   inline unsigned int get_size (void) const
-  { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
+  { return lenP1.static_size + (lenP1 ? lenP1 - 1 : 0) * Type::static_size; }
 
   inline bool serialize (hb_serialize_context_t *c,
 			 Supplier<Type> &items,
@@ -565,7 +595,7 @@
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    len.set (items_len); /* TODO(serialize) Overflow? */
+    lenP1.set (items_len); /* TODO(serialize) Overflow? */
     if (unlikely (!items_len)) return_trace (true);
     if (unlikely (!c->extend (*this))) return_trace (false);
     for (unsigned int i = 0; i < items_len - 1; i++)
@@ -595,17 +625,61 @@
   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (len.sanitize (c) &&
-		  (!len || c->check_array (arrayZ, Type::static_size, len - 1)));
+    return_trace (lenP1.sanitize (c) &&
+		  (!lenP1 || c->check_array (arrayZ, lenP1 - 1)));
   }
 
   public:
-  LenType len;
-  Type arrayZ[VAR];
+  LenType	lenP1;
+  Type		arrayZ[VAR];
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
 
+/* An array storing length-1. */
+template <typename Type, typename LenType=HBUINT16>
+struct ArrayOfM1
+{
+  inline const Type& operator [] (unsigned int i) const
+  {
+    if (unlikely (i > lenM1)) return Null(Type);
+    return arrayZ[i];
+  }
+  inline Type& operator [] (unsigned int i)
+  {
+    if (unlikely (i > lenM1)) return Crap(Type);
+    return arrayZ[i];
+  }
+  inline unsigned int get_size (void) const
+  { return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
+
+  template <typename T>
+  inline 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 = lenM1 + 1;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+        return_trace (false);
+    return_trace (true);
+  }
+
+  private:
+  inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (lenM1.sanitize (c) &&
+		  (c->check_array (arrayZ, lenM1 + 1)));
+  }
+
+  public:
+  LenType	lenM1;
+  Type		arrayZ[VAR];
+  public:
+  DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
+};
+
 /* An array with sorted elements.  Supports binary searching. */
 template <typename Type, typename LenType=HBUINT16>
 struct SortedArrayOf : ArrayOf<Type, LenType>
@@ -631,7 +705,11 @@
   }
 };
 
-/* Binary-search arrays */
+/*
+ * Binary-search arrays
+ */
+
+template <typename LenType=HBUINT16>
 struct BinSearchHeader
 {
   inline operator uint32_t (void) const { return len; }
@@ -654,19 +732,119 @@
   }
 
   protected:
-  HBUINT16	len;
-  HBUINT16	searchRange;
-  HBUINT16	entrySelector;
-  HBUINT16	rangeShift;
+  LenType	len;
+  LenType	searchRange;
+  LenType	entrySelector;
+  LenType	rangeShift;
 
   public:
   DEFINE_SIZE_STATIC (8);
 };
 
+template <typename Type, typename LenType=HBUINT16>
+struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader<LenType> > {};
+
+struct VarSizedBinSearchHeader
+{
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBUINT16	unitSize;	/* Size of a lookup unit for this search in bytes. */
+  HBUINT16	nUnits;		/* Number of units of the preceding size to be searched. */
+  HBUINT16	searchRange;	/* The value of unitSize times the largest power of 2
+				 * that is less than or equal to the value of nUnits. */
+  HBUINT16	entrySelector;	/* The log base 2 of the largest power of 2 less than
+				 * or equal to the value of nUnits. */
+  HBUINT16	rangeShift;	/* The value of unitSize times the difference of the
+				 * value of nUnits minus the largest power of 2 less
+				 * than or equal to the value of nUnits. */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
 template <typename Type>
-struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
+struct VarSizedBinSearchArrayOf
+{
+  inline const Type& operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= header.nUnits)) return Null(Type);
+    return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
+  }
+  inline Type& operator [] (unsigned int i)
+  {
+    return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
+  }
+  inline unsigned int get_size (void) const
+  { return header.static_size + header.nUnits * header.unitSize; }
 
+  inline bool sanitize (hb_sanitize_context_t *c) 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);
+  }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    unsigned int count = header.nUnits;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!(*this)[i].sanitize (c, base)))
+        return_trace (false);
+    return_trace (true);
+  }
+
+  template <typename T>
+  inline const Type *bsearch (const T &key) const
+  {
+    unsigned int size = header.unitSize;
+    int min = 0, max = (int) header.nUnits - 1;
+    while (min <= max)
+    {
+      int mid = (min + max) / 2;
+      const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
+      int c = p->cmp (key);
+      if (c < 0)
+	max = mid - 1;
+      else if (c > 0)
+	min = mid + 1;
+      else
+	return p;
+    }
+    return nullptr;
+  }
+
+  private:
+  inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (header.sanitize (c) &&
+		  Type::static_size <= header.unitSize &&
+		  c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize));
+  }
+
+  protected:
+  VarSizedBinSearchHeader	header;
+  UnsizedArrayOf<HBUINT8>	bytesZ;
+  public:
+  DEFINE_SIZE_ARRAY (10, bytesZ);
+};
+
+
 } /* namespace OT */
 
 

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -231,7 +231,7 @@
     inline void init (const CmapSubtableFormat4 *subtable)
     {
       segCount = subtable->segCountX2 / 2;
-      endCount = subtable->values;
+      endCount = subtable->values.arrayZ;
       startCount = endCount + segCount + 1;
       idDelta = startCount + segCount;
       idRangeOffset = idDelta + segCount;
@@ -369,7 +369,8 @@
   HBUINT16	entrySelector;	/* log2(searchRange/2) */
   HBUINT16	rangeShift;	/* 2 x segCount - searchRange */
 
-  HBUINT16	values[VAR];
+  UnsizedArrayOf<HBUINT16>
+		values;
 #if 0
   HBUINT16	endCount[segCount];	/* End characterCode for each segment,
 					 * last=0xFFFFu. */
@@ -377,7 +378,8 @@
   HBUINT16	startCount[segCount];	/* Start character code for each segment. */
   HBINT16		idDelta[segCount];	/* Delta for all character codes in segment. */
   HBUINT16	idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
-  HBUINT16	glyphIdArray[VAR];	/* Glyph index array (arbitrary length) */
+  UnsizedArrayOf<HBUINT16>
+		glyphIdArray;	/* Glyph index array (arbitrary length) */
 #endif
 
   public:
@@ -493,7 +495,7 @@
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ, group_data.len);
+    Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ(), group_data.len);
     if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false);
     return true;
   }
@@ -707,9 +709,9 @@
 
   HBUINT24	varSelector;	/* Variation selector. */
   LOffsetTo<DefaultUVS>
-		defaultUVS;	/* Offset to Default UVS Table. May be 0. */
+		defaultUVS;	/* Offset to Default UVS Table.  May be 0. */
   LOffsetTo<NonDefaultUVS>
-		nonDefaultUVS;	/* Offset to Non-Default UVS Table. May be 0. */
+		nonDefaultUVS;	/* Offset to Non-Default UVS Table.  May be 0. */
   public:
   DEFINE_SIZE_STATIC (11);
 };

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -128,7 +128,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1));
+		  offsetArrayZ.sanitize (c, glyph_count + 1));
   }
 
   bool get_image_data (unsigned int idx,
@@ -144,7 +144,8 @@
   }
 
   IndexSubtableHeader	header;
-  Offset<OffsetType>	offsetArrayZ[VAR];
+  UnsizedArrayOf<Offset<OffsetType> >
+ 			offsetArrayZ;
   public:
   DEFINE_SIZE_ARRAY(8, offsetArrayZ);
 };
@@ -205,24 +206,23 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
 		  firstGlyphIndex <= lastGlyphIndex &&
-		  offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1));
+		  offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1));
   }
 
-  inline bool get_extents (hb_glyph_extents_t *extents) const
+  inline bool get_extents (hb_glyph_extents_t *extents,
+			   const void *base) const
   {
-    return (this+offsetToSubtable).get_extents (extents);
+    return (base+offsetToSubtable).get_extents (extents);
   }
 
-  bool get_image_data (unsigned int gid,
+  bool get_image_data (unsigned int  gid,
+		       const void   *base,
 		       unsigned int *offset,
 		       unsigned int *length,
 		       unsigned int *format) const
   {
-    if (gid < firstGlyphIndex || gid > lastGlyphIndex)
-    {
-      return false;
-    }
-    return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
+    if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false;
+    return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
 						   offset, length, format);
   }
 
@@ -240,12 +240,7 @@
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count)))
-      return_trace (false);
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
-	return_trace (false);
-    return_trace (true);
+    return_trace (indexSubtablesZ.sanitize (c, count, this));
   }
 
   public:
@@ -255,17 +250,14 @@
     {
       unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
       unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
-      if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
+      if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex)
         return &indexSubtablesZ[i];
-      }
     }
     return nullptr;
   }
 
   protected:
-  IndexSubtableRecord	indexSubtablesZ[VAR];
-  public:
-  DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
+  UnsizedArrayOf<IndexSubtableRecord>	indexSubtablesZ;
 };
 
 struct BitmapSizeTable
@@ -278,18 +270,20 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
 		  indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
-		  c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) &&
 		  horizontal.sanitize (c) &&
 		  vertical.sanitize (c));
   }
 
-  const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const
+  const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
+					 const void *base,
+					 const void **out_base) const
   {
+    *out_base = &(base+indexSubtableArrayOffset);
     return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
   }
 
   protected:
-  LOffsetTo<IndexSubtableArray>
+  LOffsetTo<IndexSubtableArray, false>
 			indexSubtableArrayOffset;
   HBUINT32		indexTablesSize;
   HBUINT32		numberOfIndexSubtables;
@@ -350,7 +344,8 @@
 
   protected:
   const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
-					 unsigned int *x_ppem, unsigned int *y_ppem) const
+					 unsigned int *x_ppem, unsigned int *y_ppem,
+					 const void **base) const
   {
     /* TODO: Make it possible to select strike. */
 
@@ -363,7 +358,7 @@
       {
 	*x_ppem = sizeTables[i].ppemX;
 	*y_ppem = sizeTables[i].ppemY;
-	return sizeTables[i].find_table (glyph, this);
+	return sizeTables[i].find_table (glyph, this, base);
       }
     }
 
@@ -421,15 +416,16 @@
       if (!cblc)
 	return false;  // Not a color bitmap font.
 
-      const IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem);
+      const void *base;
+      const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph, &x_ppem, &y_ppem, &base);
       if (!subtable_record || !x_ppem || !y_ppem)
 	return false;
 
-      if (subtable_record->get_extents (extents))
+      if (subtable_record->get_extents (extents, base))
 	return true;
 
       unsigned int image_offset = 0, image_length = 0, image_format = 0;
-      if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
+      if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
 	return false;
 
       {
@@ -480,7 +476,7 @@
           {
             unsigned int image_offset = 0, image_length = 0, image_format = 0;
 
-            if (!subtable_record.get_image_data (gid,
+            if (!subtable_record.get_image_data (gid, &subtable_array,
                   &image_offset, &image_length, &image_format))
               continue;
 
@@ -527,8 +523,8 @@
 
 
   protected:
-  FixedVersion<>	version;
-  HBUINT8		dataZ[VAR];
+  FixedVersion<>		version;
+  UnsizedArrayOf<HBUINT8>	dataZ;
   public:
   DEFINE_SIZE_ARRAY(4, dataZ);
 };

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -129,9 +129,9 @@
   protected:
   HBUINT16	version;	/* Table version number */
   HBUINT16	numBaseGlyphs;	/* Number of Base Glyph Records */
-  LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> >
+  LOffsetTo<UnsizedArrayOf<BaseGlyphRecord>, false>
 		baseGlyphsZ;	/* Offset to Base Glyph records. */
-  LOffsetTo<UnsizedArrayOf<LayerRecord> >
+  LOffsetTo<UnsizedArrayOf<LayerRecord>, false>
 		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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -118,15 +118,15 @@
   }
 
   protected:
-  LOffsetTo<UnsizedArrayOf<HBUINT32> >
+  LOffsetTo<UnsizedArrayOf<HBUINT32>, false>
 		paletteFlagsZ;		/* Offset from the beginning of CPAL table to
 					 * the Palette Type Array. Set to 0 if no array
 					 * is provided. */
-  LOffsetTo<UnsizedArrayOf<HBUINT16> >
+  LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
 		paletteLabelZ;		/* Offset from the beginning of CPAL table to
 					 * the Palette Labels Array. Set to 0 if no
 					 * array is provided. */
-  LOffsetTo<UnsizedArrayOf<HBUINT16> >
+  LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
 		paletteEntryLabelZ;	/* Offset from the beginning of CPAL table to
 					 * the Palette Entry Label Array. Set to 0
 					 * if no array is provided. */
@@ -207,7 +207,7 @@
   HBUINT16	numPalettes;		/* Number of palettes in the table. */
   HBUINT16	numColorRecords;	/* Total number of color records, combined for
 					 * all palettes. */
-  LOffsetTo<UnsizedArrayOf<BGRAColor> >
+  LOffsetTo<UnsizedArrayOf<BGRAColor>, false>
 		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-svg-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -54,7 +54,7 @@
 				 * this index entry. */
   HBUINT16	endGlyphID;	/* The last glyph ID in the range described by
 				 * this index entry. Must be >= startGlyphID. */
-  LOffsetTo<UnsizedArrayOf<HBUINT8> >
+  LOffsetTo<UnsizedArrayOf<HBUINT8>, false>
 		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.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -40,19 +40,19 @@
 void hb_ot_face_data_t::init0 (hb_face_t *face)
 {
   this->face = face;
-#define HB_OT_LAYOUT_TABLE(Namespace, Type) Type.init0 ();
-#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) HB_OT_LAYOUT_TABLE (Namespace, Type)
-  HB_OT_LAYOUT_TABLES
-#undef HB_OT_LAYOUT_ACCELERATOR
-#undef HB_OT_LAYOUT_TABLE
+#define HB_OT_TABLE(Namespace, Type) Type.init0 ();
+#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
+  HB_OT_TABLES
+#undef HB_OT_ACCELERATOR
+#undef HB_OT_TABLE
 }
 void hb_ot_face_data_t::fini (void)
 {
-#define HB_OT_LAYOUT_TABLE(Namespace, Type) Type.fini ();
-#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) HB_OT_LAYOUT_TABLE (Namespace, Type)
-  HB_OT_LAYOUT_TABLES
-#undef HB_OT_LAYOUT_ACCELERATOR
-#undef HB_OT_LAYOUT_TABLE
+#define HB_OT_TABLE(Namespace, Type) Type.fini ();
+#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
+  HB_OT_TABLES
+#undef HB_OT_ACCELERATOR
+#undef HB_OT_TABLE
 }
 
 hb_ot_face_data_t *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -43,40 +43,40 @@
 
 /* Most of these tables are NOT needed for shaping.  But we need to hook them *somewhere*.
  * This is as good as any place. */
-#define HB_OT_LAYOUT_TABLES \
+#define HB_OT_TABLES \
     /* OpenType shaping. */ \
-    HB_OT_LAYOUT_TABLE(OT, JSTF) \
-    HB_OT_LAYOUT_TABLE(OT, BASE) \
+    HB_OT_TABLE(OT, JSTF) \
+    HB_OT_TABLE(OT, BASE) \
     /* AAT shaping. */ \
-    HB_OT_LAYOUT_TABLE(AAT, morx) \
-    HB_OT_LAYOUT_TABLE(AAT, kerx) \
-    HB_OT_LAYOUT_TABLE(AAT, ankr) \
-    HB_OT_LAYOUT_TABLE(AAT, trak) \
+    HB_OT_TABLE(AAT, morx) \
+    HB_OT_TABLE(AAT, kerx) \
+    HB_OT_TABLE(AAT, ankr) \
+    HB_OT_TABLE(AAT, trak) \
     /* OpenType variations. */ \
-    HB_OT_LAYOUT_TABLE(OT, fvar) \
-    HB_OT_LAYOUT_TABLE(OT, avar) \
-    HB_OT_LAYOUT_TABLE(OT, MVAR) \
+    HB_OT_TABLE(OT, fvar) \
+    HB_OT_TABLE(OT, avar) \
+    HB_OT_TABLE(OT, MVAR) \
     /* OpenType math. */ \
-    HB_OT_LAYOUT_TABLE(OT, MATH) \
+    HB_OT_TABLE(OT, MATH) \
     /* OpenType fundamentals. */ \
-    HB_OT_LAYOUT_ACCELERATOR(OT, GDEF) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, GSUB) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, GPOS) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, cmap) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, hmtx) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, vmtx) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, post) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, kern) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, glyf) \
-    HB_OT_LAYOUT_ACCELERATOR(OT, CBDT) \
+    HB_OT_ACCELERATOR(OT, GDEF) \
+    HB_OT_ACCELERATOR(OT, GSUB) \
+    HB_OT_ACCELERATOR(OT, GPOS) \
+    HB_OT_ACCELERATOR(OT, cmap) \
+    HB_OT_ACCELERATOR(OT, hmtx) \
+    HB_OT_ACCELERATOR(OT, vmtx) \
+    HB_OT_ACCELERATOR(OT, post) \
+    HB_OT_ACCELERATOR(OT, kern) \
+    HB_OT_ACCELERATOR(OT, glyf) \
+    HB_OT_ACCELERATOR(OT, CBDT) \
     /* */
 
 /* Declare tables. */
-#define HB_OT_LAYOUT_TABLE(Namespace, Type) namespace Namespace { struct Type; }
-#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) HB_OT_LAYOUT_TABLE (Namespace, Type##_accelerator_t)
-HB_OT_LAYOUT_TABLES
-#undef HB_OT_LAYOUT_ACCELERATOR
-#undef HB_OT_LAYOUT_TABLE
+#define HB_OT_TABLE(Namespace, Type) namespace Namespace { struct Type; }
+#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type##_accelerator_t)
+HB_OT_TABLES
+#undef HB_OT_ACCELERATOR
+#undef HB_OT_TABLE
 
 struct hb_ot_face_data_t
 {
@@ -83,26 +83,26 @@
   HB_INTERNAL void init0 (hb_face_t *face);
   HB_INTERNAL void fini (void);
 
-#define HB_OT_LAYOUT_TABLE_ORDER(Namespace, Type) \
+#define HB_OT_TABLE_ORDER(Namespace, Type) \
     HB_PASTE (ORDER_, HB_PASTE (Namespace, HB_PASTE (_, Type)))
   enum order_t
   {
     ORDER_ZERO,
-#define HB_OT_LAYOUT_TABLE(Namespace, Type) HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type),
-#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) HB_OT_LAYOUT_TABLE (Namespace, Type)
-    HB_OT_LAYOUT_TABLES
-#undef HB_OT_LAYOUT_ACCELERATOR
-#undef HB_OT_LAYOUT_TABLE
+#define HB_OT_TABLE(Namespace, Type) HB_OT_TABLE_ORDER (Namespace, Type),
+#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
+    HB_OT_TABLES
+#undef HB_OT_ACCELERATOR
+#undef HB_OT_TABLE
   };
 
   hb_face_t *face; /* MUST be JUST before the lazy loaders. */
-#define HB_OT_LAYOUT_TABLE(Namespace, Type) \
-  hb_table_lazy_loader_t<Namespace::Type, HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type)> Type;
-#define HB_OT_LAYOUT_ACCELERATOR(Namespace, Type) \
-  hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type)> Type;
-  HB_OT_LAYOUT_TABLES
-#undef HB_OT_LAYOUT_ACCELERATOR
-#undef HB_OT_LAYOUT_TABLE
+#define HB_OT_TABLE(Namespace, Type) \
+  hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
+#define HB_OT_ACCELERATOR(Namespace, Type) \
+  hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
+  HB_OT_TABLES
+#undef HB_OT_ACCELERATOR
+#undef HB_OT_TABLE
 };
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -46,10 +46,32 @@
 			 hb_codepoint_t unicode,
 			 hb_codepoint_t *glyph,
 			 void *user_data HB_UNUSED)
+{
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  return ot_face->cmap.get ()->get_nominal_glyph (unicode, glyph);
+}
 
+static unsigned int
+hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
+			  void *font_data,
+			  unsigned int count,
+			  const hb_codepoint_t *first_unicode,
+			  unsigned int unicode_stride,
+			  hb_codepoint_t *first_glyph,
+			  unsigned int glyph_stride,
+			  void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  return ot_font->cmap.get_relaxed()->get_nominal_glyph (unicode, glyph);
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const OT::cmap_accelerator_t &cmap = *ot_face->cmap.get ();
+  unsigned int done;
+  for (done = 0;
+       done < count && cmap.get_nominal_glyph (*first_unicode, first_glyph);
+       done++)
+  {
+    first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride);
+    first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
+  }
+  return done;
 }
 
 static hb_bool_t
@@ -60,39 +82,77 @@
 			   hb_codepoint_t *glyph,
 			   void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  return ot_font->cmap.get_relaxed ()->get_variation_glyph (unicode, variation_selector, glyph);
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  return ot_face->cmap.get ()->get_variation_glyph (unicode, variation_selector, glyph);
 }
 
-static hb_position_t
-hb_ot_get_glyph_h_advance (hb_font_t *font,
-			   void *font_data,
-			   hb_codepoint_t glyph,
-			   void *user_data HB_UNUSED)
+static void
+hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
+			    unsigned count,
+			    const hb_codepoint_t *first_glyph,
+			    unsigned glyph_stride,
+			    hb_position_t *first_advance,
+			    unsigned advance_stride,
+			    void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  return font->em_scale_x (ot_font->hmtx.get_relaxed ()->get_advance (glyph, font));
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx.get ();
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font));
+    first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
+    first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
+  }
 }
 
-static hb_position_t
-hb_ot_get_glyph_v_advance (hb_font_t *font,
-			   void *font_data,
-			   hb_codepoint_t glyph,
-			   void *user_data HB_UNUSED)
+static void
+hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
+			    unsigned count,
+			    const hb_codepoint_t *first_glyph,
+			    unsigned glyph_stride,
+			    hb_position_t *first_advance,
+			    unsigned advance_stride,
+			    void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  return font->em_scale_y (-(int) ot_font->vmtx.get_relaxed ()->get_advance (glyph, font));
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get ();
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font));
+    first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
+    first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
+  }
 }
 
-static hb_position_t
-hb_ot_get_glyph_h_kerning (hb_font_t *font,
-			   void *font_data,
-			   hb_codepoint_t left_glyph,
-			   hb_codepoint_t right_glyph,
-			   void *user_data HB_UNUSED)
+static hb_bool_t
+hb_ot_get_glyph_v_origin (hb_font_t *font,
+			  void *font_data,
+			  hb_codepoint_t glyph,
+			  hb_position_t *x,
+			  hb_position_t *y,
+			  void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph));
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+
+  *x = font->get_glyph_h_advance (glyph) / 2;
+
+  hb_glyph_extents_t extents = {0};
+  bool ret = ot_face->glyf->get_extents (glyph, &extents);
+  if (ret)
+  {
+    const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get ();
+    hb_position_t tsb = vmtx.get_side_bearing (glyph);
+    *y = font->em_scale_y (extents.y_bearing + tsb);
+    return true;
+  }
+
+  hb_font_extents_t font_extents;
+  font->get_h_extents_with_fallback (&font_extents);
+  *y = font_extents.ascender;
+
+  return true;
 }
 
 static hb_bool_t
@@ -102,10 +162,10 @@
 			 hb_glyph_extents_t *extents,
 			 void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  bool ret = ot_font->glyf->get_extents (glyph, extents);
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  bool ret = ot_face->glyf->get_extents (glyph, extents);
   if (!ret)
-    ret = ot_font->CBDT->get_extents (glyph, extents);
+    ret = ot_face->CBDT->get_extents (glyph, extents);
   // 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);
@@ -121,8 +181,8 @@
                       char *name, unsigned int size,
                       void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  return ot_font->post->get_glyph_name (glyph, name, size);
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  return ot_face->post->get_glyph_name (glyph, name, size);
 }
 
 static hb_bool_t
@@ -132,8 +192,8 @@
                            hb_codepoint_t *glyph,
                            void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  return ot_font->post->get_glyph_from_name (name, len, glyph);
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  return ot_face->post->get_glyph_from_name (name, len, glyph);
 }
 
 static hb_bool_t
@@ -142,12 +202,13 @@
 			  hb_font_extents_t *metrics,
 			  void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  metrics->ascender = font->em_scale_y (ot_font->hmtx.get_relaxed ()->ascender);
-  metrics->descender = font->em_scale_y (ot_font->hmtx.get_relaxed ()->descender);
-  metrics->line_gap = font->em_scale_y (ot_font->hmtx.get_relaxed ()->line_gap);
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx.get ();
+  metrics->ascender = font->em_scale_y (hmtx.ascender);
+  metrics->descender = font->em_scale_y (hmtx.descender);
+  metrics->line_gap = font->em_scale_y (hmtx.line_gap);
   // TODO Hook up variations.
-  return ot_font->hmtx.get_relaxed ()->has_font_extents;
+  return hmtx.has_font_extents;
 }
 
 static hb_bool_t
@@ -156,12 +217,13 @@
 			  hb_font_extents_t *metrics,
 			  void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
-  metrics->ascender = font->em_scale_x (ot_font->vmtx.get_relaxed ()->ascender);
-  metrics->descender = font->em_scale_x (ot_font->vmtx.get_relaxed ()->descender);
-  metrics->line_gap = font->em_scale_x (ot_font->vmtx.get_relaxed ()->line_gap);
+  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get ();
+  metrics->ascender = font->em_scale_x (vmtx.ascender);
+  metrics->descender = font->em_scale_x (vmtx.descender);
+  metrics->line_gap = font->em_scale_x (vmtx.line_gap);
   // TODO Hook up variations.
-  return ot_font->vmtx.get_relaxed ()->has_font_extents;
+  return vmtx.has_font_extents;
 }
 
 #ifdef HB_USE_ATEXIT
@@ -177,13 +239,12 @@
     hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
     hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
     hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
+    hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr);
     hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
-    hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, nullptr, nullptr);
-    hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr);
+    hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr);
+    hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
     //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
-    //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
-    hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr);
-    //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr);
+    hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
     hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
     //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
     hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
@@ -223,15 +284,10 @@
 hb_ot_font_set_funcs (hb_font_t *font)
 {
   if (unlikely (!hb_ot_shaper_face_data_ensure (font->face))) return;
-  hb_ot_face_data_t *ot_font = hb_ot_face_data (font->face);
+  hb_ot_face_data_t *ot_face = hb_ot_face_data (font->face);
 
-  /* Load them lazies.  We access them with get_relaxed() for performance. */
-  ot_font->cmap.get ();
-  ot_font->hmtx.get ();
-  ot_font->vmtx.get ();
-
   hb_font_set_funcs (font,
 		     _hb_ot_get_font_funcs (),
-		     ot_font,
+		     ot_face,
 		     nullptr);
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -54,7 +54,7 @@
   }
 
   protected:
-  HBUINT8		dataZ[VAR];		/* Location data. */
+  UnsizedArrayOf<HBUINT8>	dataZ;		/* Location data. */
   DEFINE_SIZE_ARRAY (0, dataZ);
 };
 
@@ -375,13 +375,13 @@
 
       if (short_offset)
       {
-        const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ;
+        const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
 	*start_offset = 2 * offsets[glyph];
 	*end_offset   = 2 * offsets[glyph + 1];
       }
       else
       {
-        const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ;
+        const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
 
 	*start_offset = offsets[glyph];
 	*end_offset   = offsets[glyph + 1];
@@ -418,7 +418,7 @@
         } while (composite_it.move_to_next());
 
         if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
-          *instruction_start = ((char *) last - (char *) glyf_table->dataZ) + last->get_size();
+          *instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size();
         else
           *instruction_start = end_offset;
         *instruction_end = end_offset;
@@ -483,7 +483,7 @@
   };
 
   protected:
-  HBUINT8		dataZ[VAR];		/* Glyphs data. */
+  UnsizedArrayOf<HBUINT8>	dataZ;		/* Glyphs data. */
 
   DEFINE_SIZE_ARRAY (0, dataZ);
 };

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -66,7 +66,7 @@
       if (unlikely (i >= len())) return nullptr;
       hb_codepoint_t gid = this->subset_plan->glyphs [i];
 
-      const HBUINT8* width = &(this->source_device_record->widths[gid]);
+      const HBUINT8* width = &(this->source_device_record->widthsZ[gid]);
 
       if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record)
 	return width;
@@ -77,11 +77,7 @@
 
   static inline unsigned int get_size (unsigned int count)
   {
-    unsigned int raw_size = min_size + count * HBUINT8::static_size;
-    if (raw_size % 4)
-      /* Align to 32 bits */
-      return raw_size + (4 - (raw_size % 4));
-    return raw_size;
+    return hb_ceil_to_4 (min_size + count * HBUINT8::static_size);
   }
 
   inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view)
@@ -107,7 +103,7 @@
 	DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i);
 	return_trace (false);
       }
-      widths[i].set (*width);
+      widthsZ[i].set (*width);
     }
 
     return_trace (true);
@@ -120,11 +116,11 @@
 			  c->check_range (this, size_device_record)));
   }
 
-  HBUINT8 pixel_size;   /* Pixel size for following widths (as ppem). */
-  HBUINT8 max_width;    /* Maximum width. */
-  HBUINT8 widths[VAR];  /* Array of widths (numGlyphs is from the 'maxp' table). */
+  HBUINT8			pixel_size;   /* Pixel size for following widths (as ppem). */
+  HBUINT8			max_width;    /* Maximum width. */
+  UnsizedArrayOf<HBUINT8>	widthsZ;  /* Array of widths (numGlyphs is from the 'maxp' table). */
   public:
-  DEFINE_SIZE_ARRAY (2, widths);
+  DEFINE_SIZE_ARRAY (2, widthsZ);
 };
 
 
@@ -140,7 +136,7 @@
   inline const DeviceRecord& operator [] (unsigned int i) const
   {
     if (unlikely (i >= num_records)) return Null(DeviceRecord);
-    return StructAtOffset<DeviceRecord> (this->data, i * size_device_record);
+    return StructAtOffset<DeviceRecord> (&this->dataZ, i * size_device_record);
   }
 
   inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
@@ -211,12 +207,12 @@
   }
 
   protected:
-  HBUINT16	version;		/* Table version number (0) */
-  HBUINT16	num_records;		/* Number of device records. */
-  HBUINT32	size_device_record;	/* Size of a device record, 32-bit aligned. */
-  HBUINT8	data[VAR];		/* Array of device records. */
+  HBUINT16			version;		/* Table version number (0) */
+  HBUINT16			num_records;		/* Number of device records. */
+  HBUINT32			size_device_record;	/* Size of a device record, 32-bit aligned. */
+  UnsizedArrayOf<HBUINT8>	dataZ;			/* Array of device records. */
   public:
-  DEFINE_SIZE_ARRAY (8, data);
+  DEFINE_SIZE_ARRAY (8, dataZ);
 };
 
 } /* namespace OT */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -48,7 +48,7 @@
 struct LongMetric
 {
   UFWORD	advance; /* Advance width/height. */
-  FWORD		lsb; /* Leading (left/top) side bearing. */
+  FWORD		sb; /* Leading (left/top) side bearing. */
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -134,8 +134,8 @@
         }
         else
         {
-          /* dest just lsb */
-          *((FWORD *) dest_pos) = src_metric->lsb;
+          /* dest just sb */
+          *((FWORD *) dest_pos) = src_metric->sb;
         }
       }
       else
@@ -147,18 +147,18 @@
 	  failed = true;
 	  break;
 	}
-	FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances);
+	FWORD src_sb = *(lsbs + gids[i] - _mtx.num_advances);
         if (i < num_advances)
         {
           /* dest needs a full LongMetric */
           LongMetric *metric = (LongMetric *)dest_pos;
           metric->advance = src_metric->advance;
-          metric->lsb = src_lsb;
+          metric->sb = src_sb;
         }
         else
         {
-          /* dest just needs an lsb */
-          *((FWORD *) dest_pos) = src_lsb;
+          /* dest just needs an sb */
+          *((FWORD *) dest_pos) = src_sb;
         }
       }
       dest_pos += (i < num_advances ? 4 : 2);
@@ -249,20 +249,33 @@
       hb_blob_destroy (var_blob);
     }
 
-    inline unsigned int get_advance (hb_codepoint_t  glyph) const
+    /* TODO Add variations version. */
+    inline unsigned int get_side_bearing (hb_codepoint_t glyph) const
     {
+      if (glyph < num_advances)
+        return table->longMetricZ[glyph].sb;
+
+      if (unlikely (glyph > num_metrics))
+        return 0;
+
+      const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances];
+      return bearings[glyph - num_advances];
+    }
+
+    inline unsigned int get_advance (hb_codepoint_t glyph) const
+    {
       if (unlikely (glyph >= num_metrics))
       {
-        /* If num_metrics is zero, it means we don't have the metrics table
-         * for this direction: return default advance.  Otherwise, it means that the
-         * glyph index is out of bound: return zero. */
-        if (num_metrics)
-          return 0;
-        else
-          return default_advance;
+	/* If num_metrics is zero, it means we don't have the metrics table
+	 * for this direction: return default advance.  Otherwise, it means that the
+	 * glyph index is out of bound: return zero. */
+	if (num_metrics)
+	  return 0;
+	else
+	  return default_advance;
       }
 
-      return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance;
+      return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance;
     }
 
     inline unsigned int get_advance (hb_codepoint_t  glyph,
@@ -271,7 +284,7 @@
       unsigned int advance = get_advance (glyph);
       if (likely(glyph < num_metrics))
       {
-        advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
+	advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
       }
       return advance;
     }
@@ -295,7 +308,7 @@
   };
 
   protected:
-  LongMetric	longMetric[VAR];	/* Paired advance width and leading
+  UnsizedArrayOf<LongMetric>longMetricZ;/* Paired advance width and leading
 					 * bearing values for each glyph. The
 					 * value numOfHMetrics comes from
 					 * the 'hhea' table. If the font is
@@ -303,7 +316,7 @@
 					 * be in the array, but that entry is
 					 * required. The last entry applies to
 					 * all subsequent glyphs. */
-/*FWORD		leadingBearingX[VAR];*/	/* Here the advance is assumed
+/*UnsizedArrayOf<FWORD>	leadingBearingX;*//* Here the advance is assumed
 					 * to be the same as the advance
 					 * for the last entry above. The
 					 * number of entries in this array is
@@ -317,7 +330,7 @@
 					 * font to vary the side bearing
 					 * values for each glyph. */
   public:
-  DEFINE_SIZE_ARRAY (0, longMetric);
+  DEFINE_SIZE_ARRAY (0, longMetricZ);
 };
 
 struct hmtx : hmtxvmtx<hmtx, hhea> {

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -28,7 +28,89 @@
 #define HB_OT_KERN_TABLE_HH
 
 #include "hb-open-type.hh"
+#include "hb-ot-shape.hh"
+#include "hb-ot-layout-gsubgpos.hh"
 
+
+template <typename Driver>
+struct hb_kern_machine_t
+{
+  hb_kern_machine_t (const Driver &driver_) : driver (driver_) {}
+
+  HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
+  inline void kern (hb_font_t   *font,
+		    hb_buffer_t *buffer,
+		    hb_mask_t    kern_mask,
+		    bool         scale = true) const
+  {
+    OT::hb_ot_apply_context_t c (1, font, buffer);
+    c.set_lookup_mask (kern_mask);
+    c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
+    OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
+    skippy_iter.init (&c);
+
+    bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction);
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    hb_glyph_position_t *pos = buffer->pos;
+    for (unsigned int idx = 0; idx < count;)
+    {
+      if (!(info[idx].mask & kern_mask))
+      {
+	idx++;
+	continue;
+      }
+
+      skippy_iter.reset (idx, 1);
+      if (!skippy_iter.next ())
+      {
+	idx++;
+	continue;
+      }
+
+      unsigned int i = idx;
+      unsigned int j = skippy_iter.idx;
+
+      hb_position_t kern = driver.get_kerning (info[i].codepoint,
+					       info[j].codepoint);
+
+
+      if (likely (!kern))
+        goto skip;
+
+
+      if (horizontal)
+      {
+        if (scale)
+	  kern = font->em_scale_x (kern);
+	hb_position_t kern1 = kern >> 1;
+	hb_position_t kern2 = kern - kern1;
+	pos[i].x_advance += kern1;
+	pos[j].x_advance += kern2;
+	pos[j].x_offset += kern2;
+      }
+      else
+      {
+        if (scale)
+	  kern = font->em_scale_y (kern);
+	hb_position_t kern1 = kern >> 1;
+	hb_position_t kern2 = kern - kern1;
+	pos[i].y_advance += kern1;
+	pos[j].y_advance += kern2;
+	pos[j].y_offset += kern2;
+      }
+
+      buffer->unsafe_to_break (i, j + 1);
+
+    skip:
+      idx = skippy_iter.idx;
+    }
+  }
+
+  const Driver &driver;
+};
+
+
 /*
  * kern -- Kerning
  * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
@@ -116,15 +198,19 @@
 {
   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
   {
+    /* This subtable is disabled.  It's not cleaer to me *exactly* where the offests are
+     * based from.  I *think* they should be based from beginning of kern subtable wrapper,
+     * *NOT* "this".  Since we know of no fonts that use this subtable, we are disabling
+     * it.  Someday fix it and re-enable.  Better yet, find fonts that use it... Meh,
+     * Windows doesn't implement it.  Maybe just remove... */
+    return 0;
     unsigned int l = (this+leftClassTable).get_class (left);
     unsigned int r = (this+rightClassTable).get_class (right);
-    unsigned int offset = l * rowWidth + r * sizeof (FWORD);
-    const FWORD *arr = &(this+array);
-    if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
+    unsigned int offset = l + r;
+    const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
+    if (unlikely ((const char *) v < (const char *) &array ||
+		  (const char *) v > (const char *) end - 2))
       return 0;
-    const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
-    if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
-      return 0;
     return *v;
   }
 
@@ -131,6 +217,7 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
+    return_trace (true); /* Disabled.  See above. */
     return_trace (rowWidth.sanitize (c) &&
 		  leftClassTable.sanitize (c, this) &&
 		  rightClassTable.sanitize (c, this) &&
@@ -190,10 +277,10 @@
   inline const T* thiz (void) const { return static_cast<const T *> (this); }
 
   inline bool is_horizontal (void) const
-  { return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; }
+  { return (thiz()->coverage & T::CheckFlags) == T::CheckHorizontal; }
 
   inline bool is_override (void) const
-  { return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); }
+  { return bool (thiz()->coverage & T::Override); }
 
   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
   { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
@@ -208,7 +295,7 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (thiz()) &&
 		  thiz()->length >= T::min_size &&
-		  c->check_array (thiz(), 1, thiz()->length) &&
+		  c->check_range (thiz(), thiz()->length) &&
 		  thiz()->subtable.sanitize (c, thiz()->format));
   }
 };
@@ -219,16 +306,16 @@
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
   inline const T* thiz (void) const { return static_cast<const T *> (this); }
 
-  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
+  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
     int v = 0;
-    const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
+    const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
     unsigned int count = thiz()->nTables;
     for (unsigned int i = 0; i < count; i++)
     {
       if (st->is_override ())
         v = 0;
-      v += st->get_h_kerning (left, right, table_length + (const char *) this);
+      v += st->get_h_kerning (left, right, st->length + (const char *) st);
       st = &StructAfter<typename T::SubTableWrapper> (*st);
     }
     return v;
@@ -241,7 +328,7 @@
 		  thiz()->version != T::VERSION))
       return_trace (false);
 
-    const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
+    const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
     unsigned int count = thiz()->nTables;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -262,18 +349,20 @@
 
   struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
   {
+    friend struct KernTable<KernOT>;
     friend struct KernSubTableWrapper<SubTableWrapper>;
 
-    enum coverage_flags_t {
-      COVERAGE_DIRECTION_FLAG	= 0x01u,
-      COVERAGE_MINIMUM_FLAG	= 0x02u,
-      COVERAGE_CROSSSTREAM_FLAG	= 0x04u,
-      COVERAGE_OVERRIDE_FLAG	= 0x08u,
+    enum Coverage
+    {
+      Direction		= 0x01u,
+      Minimum		= 0x02u,
+      CrossStream	= 0x04u,
+      Override		= 0x08u,
 
-      COVERAGE_VARIATION_FLAG	= 0x00u, /* Not supported. */
+      Variation		= 0x00u, /* Not supported. */
 
-      COVERAGE_CHECK_FLAGS	= 0x07u,
-      COVERAGE_CHECK_HORIZONTAL	= 0x01u
+      CheckFlags	= 0x07u,
+      CheckHorizontal	= 0x01u
     };
 
     protected:
@@ -287,11 +376,11 @@
   };
 
   protected:
-  HBUINT16	version;	/* Version--0x0000u */
-  HBUINT16	nTables;	/* Number of subtables in the kerning table. */
-  HBUINT8		data[VAR];
+  HBUINT16			version;	/* Version--0x0000u */
+  HBUINT16			nTables;	/* Number of subtables in the kerning table. */
+  UnsizedArrayOf<HBUINT8>	dataZ;
   public:
-  DEFINE_SIZE_ARRAY (4, data);
+  DEFINE_SIZE_ARRAY (4, dataZ);
 };
 
 struct KernAAT : KernTable<KernAAT>
@@ -302,17 +391,19 @@
 
   struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
   {
+    friend struct KernTable<KernAAT>;
     friend struct KernSubTableWrapper<SubTableWrapper>;
 
-    enum coverage_flags_t {
-      COVERAGE_DIRECTION_FLAG	= 0x80u,
-      COVERAGE_CROSSSTREAM_FLAG	= 0x40u,
-      COVERAGE_VARIATION_FLAG	= 0x20u,
+    enum Coverage
+    {
+      Direction		= 0x80u,
+      CrossStream	= 0x40u,
+      Variation		= 0x20u,
 
-      COVERAGE_OVERRIDE_FLAG	= 0x00u, /* Not supported. */
+      Override		= 0x00u, /* Not supported. */
 
-      COVERAGE_CHECK_FLAGS	= 0xE0u,
-      COVERAGE_CHECK_HORIZONTAL	= 0x00u
+      CheckFlags	= 0xE0u,
+      CheckHorizontal	= 0x00u
     };
 
     protected:
@@ -327,11 +418,11 @@
   };
 
   protected:
-  HBUINT32		version;	/* Version--0x00010000u */
-  HBUINT32		nTables;	/* Number of subtables in the kerning table. */
-  HBUINT8		data[VAR];
+  HBUINT32			version;	/* Version--0x00010000u */
+  HBUINT32			nTables;	/* Number of subtables in the kerning table. */
+  UnsizedArrayOf<HBUINT8>	dataZ;
   public:
-  DEFINE_SIZE_ARRAY (8, data);
+  DEFINE_SIZE_ARRAY (8, dataZ);
 };
 
 struct kern
@@ -338,11 +429,14 @@
 {
   static const hb_tag_t tableTag = HB_OT_TAG_kern;
 
-  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
+  inline bool has_data (void) const
+  { return u.version32 != 0; }
+
+  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
     switch (u.major) {
-    case 0: return u.ot.get_h_kerning (left, right, table_length);
-    case 1: return u.aat.get_h_kerning (left, right, table_length);
+    case 0: return u.ot.get_h_kerning (left, right);
+    case 1: return u.aat.get_h_kerning (left, right);
     default:return 0;
     }
   }
@@ -350,7 +444,7 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!u.major.sanitize (c)) return_trace (false);
+    if (!u.version32.sanitize (c)) return_trace (false);
     switch (u.major) {
     case 0: return_trace (u.ot.sanitize (c));
     case 1: return_trace (u.aat.sanitize (c));
@@ -364,7 +458,6 @@
     {
       blob = hb_sanitize_context_t().reference_table<kern> (face);
       table = blob->as<kern> ();
-      table_length = blob->length;
     }
     inline void fini (void)
     {
@@ -371,23 +464,42 @@
       hb_blob_destroy (blob);
     }
 
+    inline bool has_data (void) const
+    { return table->has_data (); }
+
     inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-    { return table->get_h_kerning (left, right, table_length); }
+    { return table->get_h_kerning (left, right); }
 
+    inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
+    { return get_h_kerning (first, second); }
+
+    inline void apply (hb_font_t *font,
+		       hb_buffer_t  *buffer,
+		       hb_mask_t kern_mask) const
+    {
+      /* We only apply horizontal kerning in this table. */
+      if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+        return;
+
+      hb_kern_machine_t<accelerator_t> machine (*this);
+
+      machine.kern (font, buffer, kern_mask);
+    }
+
     private:
     hb_blob_t *blob;
     const kern *table;
-    unsigned int table_length;
   };
 
   protected:
   union {
+  HBUINT32		version32;
   HBUINT16		major;
   KernOT		ot;
   KernAAT		aat;
   } u;
   public:
-  DEFINE_SIZE_UNION (2, major);
+  DEFINE_SIZE_UNION (4, version32);
 };
 
 struct kern_accelerator_t : kern::accelerator_t {};

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -70,6 +70,11 @@
  * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
  */
 
+struct Record_sanitize_closure_t {
+  hb_tag_t tag;
+  const void *list_base;
+};
+
 template <typename Type>
 struct Record
 {
@@ -77,14 +82,10 @@
     return tag.cmp (a);
   }
 
-  struct sanitize_closure_t {
-    hb_tag_t tag;
-    const void *list_base;
-  };
   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
-    const sanitize_closure_t closure = {tag, base};
+    const Record_sanitize_closure_t closure = {tag, base};
     return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
   }
 
@@ -240,7 +241,7 @@
   }
 
   inline bool sanitize (hb_sanitize_context_t *c,
-			const Record<LangSys>::sanitize_closure_t * = nullptr) const
+			const Record_sanitize_closure_t * = nullptr) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) && featureIndex.sanitize (c));
@@ -291,7 +292,7 @@
   }
 
   inline bool sanitize (hb_sanitize_context_t *c,
-			const Record<Script>::sanitize_closure_t * = nullptr) const
+			const Record_sanitize_closure_t * = nullptr) const
   {
     TRACE_SANITIZE (this);
     return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
@@ -399,7 +400,7 @@
 				 * same subfamily value. If this value is
 				 * zero, the remaining fields in the array
 				 * will be ignored. */
-  HBUINT16	subfamilyNameID;/* If the preceding value is non-zero, this
+  NameID	subfamilyNameID;/* If the preceding value is non-zero, this
 				 * value must be set in the range 256 - 32767
 				 * (inclusive). It records the value of a
 				 * field in the name table, which must
@@ -472,7 +473,7 @@
 					 * specifies a string (or strings,
 					 * for multiple languages) for a
 					 * user-interface label for this
-					 * feature. (May be nullptr.) */
+					 * feature. (May be NULL.) */
   NameID	featUITooltipTextNameID;/* The ‘name’ table name ID that
 					 * specifies a string (or strings,
 					 * for multiple languages) that an
@@ -482,7 +483,7 @@
   NameID	sampleTextNameID;	/* The ‘name’ table name ID that
 					 * specifies sample text that
 					 * illustrates the effect of this
-					 * feature. (May be nullptr.) */
+					 * feature. (May be NULL.) */
   HBUINT16	numNamedParameters;	/* Number of named parameters. (May
 					 * be zero.) */
   NameID	firstParamUILabelNameID;/* The first ‘name’ table name ID
@@ -520,6 +521,20 @@
     return Null(FeatureParamsSize);
   }
 
+  inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
+  {
+    if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
+      return u.stylisticSet;
+    return Null(FeatureParamsStylisticSet);
+  }
+
+  inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
+  {
+    if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
+      return u.characterVariants;
+    return Null(FeatureParamsCharacterVariants);
+  }
+
   private:
   union {
   FeatureParamsSize			size;
@@ -526,6 +541,7 @@
   FeatureParamsStylisticSet		stylisticSet;
   FeatureParamsCharacterVariants	characterVariants;
   } u;
+  public:
   DEFINE_SIZE_STATIC (17);
 };
 
@@ -553,7 +569,7 @@
   }
 
   inline bool sanitize (hb_sanitize_context_t *c,
-			const Record<Feature>::sanitize_closure_t *closure = nullptr) const
+			const Record_sanitize_closure_t *closure = nullptr) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
@@ -1542,7 +1558,7 @@
 		  regionIndices.sanitize(c) &&
 		  shortCount <= regionIndices.len &&
 		  c->check_array (&StructAfter<HBUINT8> (regionIndices),
-				  get_row_size (), itemCount));
+				  itemCount, get_row_size ()));
   }
 
   protected:
@@ -1549,7 +1565,7 @@
   HBUINT16		itemCount;
   HBUINT16		shortCount;
   ArrayOf<HBUINT16>	regionIndices;
-  HBUINT8		bytesX[VAR];
+  UnsizedArrayOf<HBUINT8>bytesX;
   public:
   DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
 };
@@ -1844,7 +1860,7 @@
 
     unsigned int s = ppem_size - startSize;
 
-    unsigned int byte = deltaValue[s >> (4 - f)];
+    unsigned int byte = deltaValueZ[s >> (4 - f)];
     unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
     unsigned int mask = (0xFFFFu >> (16 - (1 << f)));
 
@@ -1864,9 +1880,10 @@
 					 * 2	Signed 4-bit value, 4 values per uint16
 					 * 3	Signed 8-bit value, 2 values per uint16
 					 */
-  HBUINT16	deltaValue[VAR];	/* Array of compressed data */
+  UnsizedArrayOf<HBUINT16>
+		deltaValueZ;		/* Array of compressed data */
   public:
-  DEFINE_SIZE_ARRAY (6, deltaValue);
+  DEFINE_SIZE_ARRAY (6, deltaValueZ);
 };
 
 struct VariationDevice

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -199,7 +199,7 @@
     TRACE_SANITIZE (this);
     unsigned int len = get_len ();
 
-    if (!c->check_array (values, get_size (), count)) return_trace (false);
+    if (!c->check_array (values, count, get_size ())) return_trace (false);
 
     if (!has_device ()) return_trace (true);
 
@@ -376,7 +376,7 @@
     if (!c->check_struct (this)) return_trace (false);
     if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
     unsigned int count = rows * cols;
-    if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false);
+    if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
     for (unsigned int i = 0; i < count; i++)
       if (!matrixZ[i].sanitize (c, this)) return_trace (false);
     return_trace (true);
@@ -384,8 +384,8 @@
 
   HBUINT16	rows;			/* Number of rows */
   protected:
-  OffsetTo<Anchor>
-		matrixZ[VAR];		/* Matrix of offsets to Anchor tables--
+  UnsizedArrayOf<OffsetTo<Anchor> >
+		matrixZ;		/* Matrix of offsets to Anchor tables--
 					 * from beginning of AnchorMatrix table */
   public:
   DEFINE_SIZE_ARRAY (2, matrixZ);
@@ -621,7 +621,7 @@
     unsigned int len2 = valueFormats[1].get_len ();
     unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
 
-    const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
+    const PairValueRecord *record = &firstPairValueRecord;
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -640,7 +640,7 @@
     unsigned int len2 = valueFormats[1].get_len ();
     unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
 
-    const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
+    const PairValueRecord *record = &firstPairValueRecord;
     c->input->add_array (&record->secondGlyph, len, record_size);
   }
 
@@ -654,7 +654,6 @@
     unsigned int len2 = valueFormats[1].get_len ();
     unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
 
-    const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
     unsigned int count = len;
 
     /* Hand-coded bsearch. */
@@ -665,7 +664,7 @@
     while (min <= max)
     {
       int mid = (min + max) / 2;
-      const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_array, record_size * mid);
+      const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid);
       hb_codepoint_t mid_x = record->secondGlyph;
       if (x < mid_x)
         max = mid - 1;
@@ -698,20 +697,21 @@
   {
     TRACE_SANITIZE (this);
     if (!(c->check_struct (this)
-       && c->check_array (arrayZ, HBUINT16::static_size * closure->stride, len))) return_trace (false);
+       && c->check_array (&firstPairValueRecord, len, HBUINT16::static_size * closure->stride))) return_trace (false);
 
     unsigned int count = len;
-    const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
+    const PairValueRecord *record = &firstPairValueRecord;
     return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) &&
 		  closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride));
   }
 
   protected:
-  HBUINT16	len;			/* Number of PairValueRecords */
-  HBUINT16	arrayZ[VAR];		/* Array of PairValueRecords--ordered
-					 * by GlyphID of the second glyph */
+  HBUINT16		len;	/* Number of PairValueRecords */
+  PairValueRecord	firstPairValueRecord;
+				/* Array of PairValueRecords--ordered
+				 * by GlyphID of the second glyph */
   public:
-  DEFINE_SIZE_ARRAY (2, arrayZ);
+  DEFINE_SIZE_MIN (2);
 };
 
 struct PairPosFormat1
@@ -869,7 +869,7 @@
     unsigned int stride = len1 + len2;
     unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
     unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
-    return_trace (c->check_array (values, record_size, count) &&
+    return_trace (c->check_array (values, count, record_size) &&
 		  valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
 		  valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
   }
@@ -973,22 +973,22 @@
     hb_buffer_t *buffer = c->buffer;
 
     const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage  (buffer->cur().codepoint)];
-    if (!this_record.exitAnchor) return_trace (false);
+    if (!this_record.entryAnchor) return_trace (false);
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
-    if (!skippy_iter.next ()) return_trace (false);
+    if (!skippy_iter.prev ()) return_trace (false);
 
-    const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint)];
-    if (!next_record.entryAnchor) return_trace (false);
+    const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint)];
+    if (!prev_record.exitAnchor) return_trace (false);
 
-    unsigned int i = buffer->idx;
-    unsigned int j = skippy_iter.idx;
+    unsigned int i = skippy_iter.idx;
+    unsigned int j = buffer->idx;
 
     buffer->unsafe_to_break (i, j);
     float entry_x, entry_y, exit_x, exit_y;
-    (this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
-    (this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
+    (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
+    (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
 
     hb_glyph_position_t *pos = buffer->pos;
 
@@ -1035,7 +1035,7 @@
      * parent.
      *
      * Optimize things for the case of RightToLeft, as that's most common in
-     * Arabinc. */
+     * Arabic. */
     unsigned int child  = i;
     unsigned int parent = j;
     hb_position_t x_offset = entry_x - exit_x;
@@ -1064,7 +1064,7 @@
     else
       pos[child].x_offset = x_offset;
 
-    buffer->idx = j;
+    buffer->idx++;
     return_trace (true);
   }
 
@@ -1658,7 +1658,10 @@
   pos[j].attach_type() = type;
 }
 static void
-propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
+propagate_attachment_offsets (hb_glyph_position_t *pos,
+			      unsigned int len,
+			      unsigned int i,
+			      hb_direction_t direction)
 {
   /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
    * offset of glyph they are attached to. */
@@ -1666,11 +1669,14 @@
   if (likely (!chain))
     return;
 
+  pos[i].attach_chain() = 0;
+
   unsigned int j = (int) i + chain;
 
-  pos[i].attach_chain() = 0;
+  if (unlikely (j >= len))
+    return;
 
-  propagate_attachment_offsets (pos, j, direction);
+  propagate_attachment_offsets (pos, len, j, direction);
 
   assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE));
 
@@ -1726,7 +1732,7 @@
   /* Handle attachments */
   if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
     for (unsigned int i = 0; i < len; i++)
-      propagate_attachment_offsets (pos, i, direction);
+      propagate_attachment_offsets (pos, len, i, direction);
 }
 
 
@@ -1755,10 +1761,6 @@
 struct GPOS_accelerator_t : GPOS::accelerator_t {};
 
 
-#undef attach_chain
-#undef attach_type
-
-
 } /* namespace OT */
 
 

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -541,6 +541,10 @@
     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 == HB_OT_MAP_MAX_VALUE && c->random)
+      alt_index = c->random_number () % count + 1;
+
     if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
 
     c->replace_glyph (alternates[alt_index - 1]);
@@ -706,7 +710,7 @@
 {
   inline bool intersects (const hb_set_t *glyphs) const
   {
-    unsigned int count = component.len;
+    unsigned int count = component.lenP1;
     for (unsigned int i = 1; i < count; i++)
       if (!glyphs->has (component[i]))
         return false;
@@ -716,7 +720,7 @@
   inline void closure (hb_closure_context_t *c) const
   {
     TRACE_CLOSURE (this);
-    unsigned int count = component.len;
+    unsigned int count = component.lenP1;
     for (unsigned int i = 1; i < count; i++)
       if (!c->glyphs->has (component[i]))
         return;
@@ -726,7 +730,7 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    c->input->add_array (component.arrayZ, component.len ? component.len - 1 : 0);
+    c->input->add_array (component.arrayZ, component.lenP1 ? component.lenP1 - 1 : 0);
     c->output->add (ligGlyph);
   }
 
@@ -733,7 +737,7 @@
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
     TRACE_WOULD_APPLY (this);
-    if (c->len != component.len)
+    if (c->len != component.lenP1)
       return_trace (false);
 
     for (unsigned int i = 1; i < c->len; i++)
@@ -746,7 +750,7 @@
   inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    unsigned int count = component.len;
+    unsigned int count = component.lenP1;
 
     if (unlikely (!count)) return_trace (false);
 
@@ -758,7 +762,6 @@
       return_trace (true);
     }
 
-    bool is_mark_ligature = false;
     unsigned int total_component_count = 0;
 
     unsigned int match_length = 0;
@@ -770,7 +773,6 @@
 			      nullptr,
 			      &match_length,
 			      match_positions,
-			      &is_mark_ligature,
 			      &total_component_count)))
       return_trace (false);
 
@@ -779,7 +781,6 @@
 		  match_positions,
 		  match_length,
 		  ligGlyph,
-		  is_mark_ligature,
 		  total_component_count);
 
     return_trace (true);

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -33,6 +33,7 @@
 #include "hb-buffer.hh"
 #include "hb-map.hh"
 #include "hb-set.hh"
+#include "hb-ot-map.hh"
 #include "hb-ot-layout-common.hh"
 #include "hb-ot-layout-gdef-table.hh"
 
@@ -213,10 +214,10 @@
   unsigned int debug_depth;
 
   hb_collect_glyphs_context_t (hb_face_t *face_,
-			       hb_set_t  *glyphs_before, /* OUT. May be nullptr */
-			       hb_set_t  *glyphs_input,  /* OUT. May be nullptr */
-			       hb_set_t  *glyphs_after,  /* OUT. May be nullptr */
-			       hb_set_t  *glyphs_output, /* OUT. May be nullptr */
+			       hb_set_t  *glyphs_before, /* OUT.  May be NULL */
+			       hb_set_t  *glyphs_input,  /* OUT.  May be NULL */
+			       hb_set_t  *glyphs_after,  /* OUT.  May be NULL */
+			       hb_set_t  *glyphs_output, /* OUT.  May be NULL */
 			       unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
 			      face (face_),
 			      before (glyphs_before ? glyphs_before : hb_set_get_empty ()),
@@ -343,10 +344,10 @@
       match_glyph_data = nullptr;
       matcher.set_match_func (nullptr, nullptr);
       matcher.set_lookup_props (c->lookup_props);
-      /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+      /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */
       matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj));
-      /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
-      matcher.set_ignore_zwj  (c->table_index == 1 || (context_match || c->auto_zwj));
+      /* Ignore ZWJ if we are matching context, or asked to. */
+      matcher.set_ignore_zwj  (context_match || c->auto_zwj);
       matcher.set_mask (context_match ? -1 : c->lookup_mask);
     }
     inline void set_lookup_props (unsigned int lookup_props)
@@ -478,11 +479,14 @@
   unsigned int nesting_level_left;
   unsigned int debug_depth;
 
+  bool has_glyph_classes;
   bool auto_zwnj;
   bool auto_zwj;
-  bool has_glyph_classes;
+  bool random;
 
+  uint32_t random_state;
 
+
   hb_ot_apply_context_t (unsigned int table_index_,
 		      hb_font_t *font_,
 		      hb_buffer_t *buffer_) :
@@ -498,22 +502,33 @@
 			lookup_props (0),
 			nesting_level_left (HB_MAX_NESTING_LEVEL),
 			debug_depth (0),
+			has_glyph_classes (gdef.has_glyph_classes ()),
 			auto_zwnj (true),
 			auto_zwj (true),
-			has_glyph_classes (gdef.has_glyph_classes ()) {}
+			random (false),
+			random_state (1) { init_iters (); }
 
-  inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
-  inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
-  inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; }
-  inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
-  inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
-  inline void set_lookup_props (unsigned int lookup_props_)
+  inline void init_iters (void)
   {
-    lookup_props = lookup_props_;
     iter_input.init (this, false);
     iter_context.init (this, true);
   }
 
+  inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; init_iters (); }
+  inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); }
+  inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); }
+  inline void set_random (bool random_) { random = random_; }
+  inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+  inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
+  inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; init_iters (); }
+
+  inline uint32_t random_number (void)
+  {
+    /* http://www.cplusplus.com/reference/random/minstd_rand/ */
+    random_state = random_state * 48271 % 2147483647;
+    return random_state;
+  }
+
   inline bool
   match_properties_mark (hb_codepoint_t  glyph,
 			 unsigned int    glyph_props,
@@ -606,7 +621,65 @@
 };
 
 
+struct hb_get_subtables_context_t :
+       hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
+{
+  template <typename Type>
+  static inline 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);
+  }
 
+  typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
+
+  struct hb_applicable_t
+  {
+    template <typename T>
+    inline void init (const T &obj_, hb_apply_func_t apply_func_)
+    {
+      obj = &obj_;
+      apply_func = apply_func_;
+      digest.init ();
+      obj_.get_coverage ().add_coverage (&digest);
+    }
+
+    inline bool apply (OT::hb_ot_apply_context_t *c) const
+    {
+      return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c);
+    }
+
+    private:
+    const void *obj;
+    hb_apply_func_t apply_func;
+    hb_set_digest_t digest;
+  };
+
+  typedef hb_vector_t<hb_applicable_t, 2> array_t;
+
+  /* Dispatch interface. */
+  inline const char *get_name (void) { return "GET_SUBTABLES"; }
+  template <typename T>
+  inline return_t dispatch (const T &obj)
+  {
+    hb_applicable_t *entry = array.push();
+    entry->init (obj, apply_to<T>);
+    return HB_VOID;
+  }
+  static return_t default_return_value (void) { return HB_VOID; }
+  bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
+
+  hb_get_subtables_context_t (array_t &array_) :
+			      array (array_),
+			      debug_depth (0) {}
+
+  array_t &array;
+  unsigned int debug_depth;
+};
+
+
+
+
 typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data);
 typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
@@ -716,7 +789,6 @@
 				const void *match_data,
 				unsigned int *end_offset,
 				unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
-				bool *p_is_mark_ligature = nullptr,
 				unsigned int *p_total_component_count = nullptr)
 {
   TRACE_APPLY (nullptr);
@@ -753,8 +825,6 @@
    *     https://github.com/harfbuzz/harfbuzz/issues/545
    */
 
-  bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
-
   unsigned int total_component_count = 0;
   total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
 
@@ -821,15 +891,11 @@
 	return_trace (false);
     }
 
-    is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
     total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
   }
 
   *end_offset = skippy_iter.idx - buffer->idx + 1;
 
-  if (p_is_mark_ligature)
-    *p_is_mark_ligature = is_mark_ligature;
-
   if (p_total_component_count)
     *p_total_component_count = total_component_count;
 
@@ -840,7 +906,6 @@
 				 unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
 				 unsigned int match_length,
 				 hb_codepoint_t lig_glyph,
-				 bool is_mark_ligature,
 				 unsigned int total_component_count)
 {
   TRACE_APPLY (nullptr);
@@ -849,11 +914,15 @@
 
   buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
 
-  /*
-   * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
+  /* - If a base and one or more marks ligate, consider that as a base, NOT
+   *   ligature, such that all following marks can still attach to it.
+   *   https://github.com/harfbuzz/harfbuzz/issues/1109
+   *
+   * - If all components of the ligature were marks, we call this a mark ligature.
+   *   If it *is* a mark ligature, we don't allocate a new ligature id, and leave
    *   the ligature to keep its old ligature id.  This will allow it to attach to
    *   a base ligature in GPOS.  Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH,
-   *   and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a
+   *   and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA with a
    *   ligature id and component value of 2.  Then if SHADDA,FATHA form a ligature
    *   later, we don't want them to lose their ligature id/component, otherwise
    *   GPOS will fail to correctly position the mark ligature on top of the
@@ -877,13 +946,24 @@
    *   https://bugzilla.gnome.org/show_bug.cgi?id=437633
    */
 
-  unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
-  unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer);
+  bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[match_positions[0]]);
+  bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[match_positions[0]]);
+  for (unsigned int i = 1; i < count; i++)
+    if (!_hb_glyph_info_is_mark (&buffer->info[match_positions[i]]))
+    {
+      is_base_ligature = false;
+      is_mark_ligature = false;
+      break;
+    }
+  bool is_ligature = !is_base_ligature && !is_mark_ligature;
+
+  unsigned int klass = is_ligature ? HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE : 0;
+  unsigned int lig_id = is_ligature ? _hb_allocate_lig_id (buffer) : 0;
   unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
   unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
   unsigned int components_so_far = last_num_components;
 
-  if (!is_mark_ligature)
+  if (is_ligature)
   {
     _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
     if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
@@ -897,7 +977,8 @@
   {
     while (buffer->idx < match_positions[i] && buffer->successful)
     {
-      if (!is_mark_ligature) {
+      if (is_ligature)
+      {
         unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
 	if (this_comp == 0)
 	  this_comp = last_num_components;
@@ -1222,7 +1303,7 @@
   inline bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const
   {
     return context_intersects (glyphs,
-			       inputCount, inputZ,
+			       inputCount, inputZ.arrayZ,
 			       lookup_context);
   }
 
@@ -1229,10 +1310,10 @@
   inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
   {
     TRACE_CLOSURE (this);
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
     context_closure_lookup (c,
-			    inputCount, inputZ,
-			    lookupCount, lookupRecord,
+			    inputCount, inputZ.arrayZ,
+			    lookupCount, lookupRecord.arrayZ,
 			    lookup_context);
   }
 
@@ -1239,10 +1320,10 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
     context_collect_glyphs_lookup (c,
-				   inputCount, inputZ,
-				   lookupCount, lookupRecord,
+				   inputCount, inputZ.arrayZ,
+				   lookupCount, lookupRecord.arrayZ,
 				   lookup_context);
   }
 
@@ -1249,15 +1330,15 @@
   inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
   {
     TRACE_WOULD_APPLY (this);
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
-    return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+    return_trace (context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
   }
 
   inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
-    return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+    return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
   }
 
   public:
@@ -1266,8 +1347,8 @@
     TRACE_SANITIZE (this);
     return_trace (inputCount.sanitize (c) &&
 		  lookupCount.sanitize (c) &&
-		  c->check_range (inputZ,
-				  inputZ[0].static_size * inputCount +
+		  c->check_range (inputZ.arrayZ,
+				  inputZ[0].static_size * (inputCount ? inputCount - 1 : 0) +
 				  LookupRecord::static_size * lookupCount));
   }
 
@@ -1276,9 +1357,11 @@
 					 * glyph sequence--includes the first
 					 * glyph */
   HBUINT16	lookupCount;		/* Number of LookupRecords */
-  HBUINT16	inputZ[VAR];		/* Array of match inputs--start with
+  UnsizedArrayOf<HBUINT16>
+ 		inputZ;			/* Array of match inputs--start with
 					 * second glyph */
-/*LookupRecord	lookupRecordX[VAR];*/	/* Array of LookupRecords--in
+/*UnsizedArrayOf<LookupRecord>
+		lookupRecordX;*/	/* Array of LookupRecords--in
 					 * design order */
   public:
   DEFINE_SIZE_ARRAY (4, inputZ);
@@ -1595,7 +1678,7 @@
       this
     };
     return context_intersects (glyphs,
-			       glyphCount, (const HBUINT16 *) (coverageZ + 1),
+			       glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
 			       lookup_context);
   }
 
@@ -1605,13 +1688,13 @@
     if (!(this+coverageZ[0]).intersects (c->glyphs))
       return;
 
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount);
     struct ContextClosureLookupContext lookup_context = {
       {intersects_coverage},
       this
     };
     context_closure_lookup (c,
-			    glyphCount, (const HBUINT16 *) (coverageZ + 1),
+			    glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
 			    lookupCount, lookupRecord,
 			    lookup_context);
   }
@@ -1621,7 +1704,7 @@
     TRACE_COLLECT_GLYPHS (this);
     (this+coverageZ[0]).add_coverage (c->input);
 
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount);
     struct ContextCollectGlyphsLookupContext lookup_context = {
       {collect_coverage},
       this
@@ -1628,7 +1711,7 @@
     };
 
     context_collect_glyphs_lookup (c,
-				   glyphCount, (const HBUINT16 *) (coverageZ + 1),
+				   glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
 				   lookupCount, lookupRecord,
 				   lookup_context);
   }
@@ -1637,12 +1720,12 @@
   {
     TRACE_WOULD_APPLY (this);
 
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount);
     struct ContextApplyLookupContext lookup_context = {
       {match_coverage},
       this
     };
-    return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+    return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1654,12 +1737,12 @@
     unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount);
     struct ContextApplyLookupContext lookup_context = {
       {match_coverage},
       this
     };
-    return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+    return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context));
   }
 
   inline bool subset (hb_subset_context_t *c) const
@@ -1675,11 +1758,11 @@
     if (!c->check_struct (this)) return_trace (false);
     unsigned int count = glyphCount;
     if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */
-    if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false);
+    if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false);
     for (unsigned int i = 0; i < count; i++)
       if (!coverageZ[i].sanitize (c, this)) return_trace (false);
-    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count);
-    return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * count);
+    return_trace (c->check_array (lookupRecord, lookupCount));
   }
 
   protected:
@@ -1687,10 +1770,11 @@
   HBUINT16	glyphCount;		/* Number of glyphs in the input glyph
 					 * sequence */
   HBUINT16	lookupCount;		/* Number of LookupRecords */
-  OffsetTo<Coverage>
-		coverageZ[VAR];		/* Array of offsets to Coverage
+  UnsizedArrayOf<OffsetTo<Coverage> >
+		coverageZ;		/* Array of offsets to Coverage
 					 * table in glyph sequence order */
-/*LookupRecord	lookupRecordX[VAR];*/	/* Array of LookupRecords--in
+/*UnsizedArrayOf<LookupRecord>
+		lookupRecordX;*/	/* Array of LookupRecords--in
 					 * design order */
   public:
   DEFINE_SIZE_ARRAY (6, coverageZ);
@@ -1862,7 +1946,7 @@
     const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     return chain_context_intersects (glyphs,
 				     backtrack.len, backtrack.arrayZ,
-				     input.len, input.arrayZ,
+				     input.lenP1, input.arrayZ,
 				     lookahead.len, lookahead.arrayZ,
 				     lookup_context);
   }
@@ -1875,7 +1959,7 @@
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     chain_context_closure_lookup (c,
 				  backtrack.len, backtrack.arrayZ,
-				  input.len, input.arrayZ,
+				  input.lenP1, input.arrayZ,
 				  lookahead.len, lookahead.arrayZ,
 				  lookup.len, lookup.arrayZ,
 				  lookup_context);
@@ -1889,7 +1973,7 @@
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     chain_context_collect_glyphs_lookup (c,
 					 backtrack.len, backtrack.arrayZ,
-					 input.len, input.arrayZ,
+					 input.lenP1, input.arrayZ,
 					 lookahead.len, lookahead.arrayZ,
 					 lookup.len, lookup.arrayZ,
 					 lookup_context);
@@ -1903,7 +1987,7 @@
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     return_trace (chain_context_would_apply_lookup (c,
 						    backtrack.len, backtrack.arrayZ,
-						    input.len, input.arrayZ,
+						    input.lenP1, input.arrayZ,
 						    lookahead.len, lookahead.arrayZ, lookup.len,
 						    lookup.arrayZ, lookup_context));
   }
@@ -1916,7 +2000,7 @@
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     return_trace (chain_context_apply_lookup (c,
 					      backtrack.len, backtrack.arrayZ,
-					      input.len, input.arrayZ,
+					      input.lenP1, input.arrayZ,
 					      lookahead.len, lookahead.arrayZ, lookup.len,
 					      lookup.arrayZ, lookup_context));
   }
@@ -2536,6 +2620,39 @@
  * GSUB/GPOS Common
  */
 
+struct hb_ot_layout_lookup_accelerator_t
+{
+  template <typename TLookup>
+  inline void init (const TLookup &lookup)
+  {
+    digest.init ();
+    lookup.add_coverage (&digest);
+
+    subtables.init ();
+    OT::hb_get_subtables_context_t c_get_subtables (subtables);
+    lookup.dispatch (&c_get_subtables);
+  }
+  inline void fini (void)
+  {
+    subtables.fini ();
+  }
+
+  inline bool may_have (hb_codepoint_t g) const
+  { return digest.may_have (g); }
+
+  inline bool apply (hb_ot_apply_context_t *c) const
+  {
+     for (unsigned int i = 0; i < subtables.len; i++)
+       if (subtables[i].apply (c))
+         return true;
+     return false;
+  }
+
+  private:
+  hb_set_digest_t digest;
+  hb_get_subtables_context_t::array_t subtables;
+};
+
 struct GSUBGPOS
 {
   inline bool has_data (void) const { return version.to_int () != 0; }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -124,7 +124,7 @@
 struct JstfLangSys : OffsetListOf<JstfPriority>
 {
   inline bool sanitize (hb_sanitize_context_t *c,
-			const Record<JstfLangSys>::sanitize_closure_t * = nullptr) const
+			const Record_sanitize_closure_t * = nullptr) const
   {
     TRACE_SANITIZE (this);
     return_trace (OffsetListOf<JstfPriority>::sanitize (c));
@@ -165,7 +165,7 @@
   inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
 
   inline bool sanitize (hb_sanitize_context_t *c,
-			const Record<JstfScript>::sanitize_closure_t * = nullptr) const
+			const Record_sanitize_closure_t * = nullptr) const
   {
     TRACE_SANITIZE (this);
     return_trace (extenderGlyphs.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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -45,17 +45,15 @@
 #include "hb-ot-color-cpal-table.hh"
 #include "hb-ot-color-sbix-table.hh"
 #include "hb-ot-color-svg-table.hh"
+#include "hb-ot-kern-table.hh"
 #include "hb-ot-name-table.hh"
 
 
-// static inline const OT::BASE&
-// _get_base (hb_face_t *face)
-// {
-//   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE);
-//   hb_ot_face_data_t *data = hb_ot_face_data (face);
-//   return *(data->base.get ());
-// }
-
+static const OT::kern::accelerator_t& _get_kern (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t);
+  return *hb_ot_face_data (face)->kern;
+}
 const OT::GDEF& _get_gdef (hb_face_t *face)
 {
   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF);
@@ -92,6 +90,25 @@
 
 
 /*
+ * kern
+ */
+
+hb_bool_t
+hb_ot_layout_has_kerning (hb_face_t *face)
+{
+  return _get_kern (face).has_data ();
+}
+
+void
+hb_ot_layout_kern (hb_font_t *font,
+		   hb_buffer_t  *buffer,
+		   hb_mask_t kern_mask)
+{
+  _get_kern (font->face).apply (font, buffer, kern_mask);
+}
+
+
+/*
  * GDEF
  */
 
@@ -305,7 +322,7 @@
 				    hb_tag_t      table_tag,
 				    unsigned int  start_offset,
 				    unsigned int *script_count /* IN/OUT */,
-				    hb_tag_t     *script_tags /* OUT */)
+				    hb_tag_t     *script_tags  /* OUT */)
 {
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
@@ -351,17 +368,36 @@
 				  unsigned int   *script_index,
 				  hb_tag_t       *chosen_script)
 {
+  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);
+}
+
+/**
+ * hb_ot_layout_table_select_script:
+ *
+ * Since: 2.0.0
+ **/
+hb_bool_t
+hb_ot_layout_table_select_script (hb_face_t      *face,
+				  hb_tag_t        table_tag,
+				  unsigned int    script_count,
+				  const hb_tag_t *script_tags,
+				  unsigned int   *script_index  /* OUT */,
+				  hb_tag_t       *chosen_script /* OUT */)
+{
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  unsigned int i;
 
-  while (*script_tags)
+  for (i = 0; i < script_count; i++)
   {
-    if (g.find_script_index (*script_tags, script_index)) {
+    if (g.find_script_index (script_tags[i], script_index))
+    {
       if (chosen_script)
-        *chosen_script = *script_tags;
+        *chosen_script = script_tags[i];
       return true;
     }
-    script_tags++;
   }
 
   /* try finding 'DFLT' */
@@ -397,7 +433,7 @@
 				     hb_tag_t      table_tag,
 				     unsigned int  start_offset,
 				     unsigned int *feature_count /* IN/OUT */,
-				     hb_tag_t     *feature_tags /* OUT */)
+				     hb_tag_t     *feature_tags  /* OUT */)
 {
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
@@ -433,7 +469,7 @@
 				       unsigned int  script_index,
 				       unsigned int  start_offset,
 				       unsigned int *language_count /* IN/OUT */,
-				       hb_tag_t     *language_tags /* OUT */)
+				       hb_tag_t     *language_tags  /* OUT */)
 {
   const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
 
@@ -447,13 +483,33 @@
 				   hb_tag_t      language_tag,
 				   unsigned int *language_index)
 {
+  return hb_ot_layout_script_select_language (face, table_tag, script_index, 1, &language_tag, language_index);
+}
+
+/**
+ * hb_ot_layout_script_select_language:
+ *
+ * Since: 2.0.0
+ **/
+hb_bool_t
+hb_ot_layout_script_select_language (hb_face_t      *face,
+				     hb_tag_t        table_tag,
+				     unsigned int    script_index,
+				     unsigned int    language_count,
+				     const hb_tag_t *language_tags,
+				     unsigned int   *language_index /* OUT */)
+{
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX), "");
   const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
+  unsigned int i;
 
-  if (s.find_lang_sys_index (language_tag, language_index))
-    return true;
+  for (i = 0; i < language_count; i++)
+  {
+    if (s.find_lang_sys_index (language_tags[i], language_index))
+      return true;
+  }
 
-  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
+  /* try finding 'dflt' */
   if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
     return false;
 
@@ -518,7 +574,7 @@
 					   unsigned int  script_index,
 					   unsigned int  language_index,
 					   unsigned int  start_offset,
-					   unsigned int *feature_count /* IN/OUT */,
+					   unsigned int *feature_count   /* IN/OUT */,
 					   unsigned int *feature_indexes /* OUT */)
 {
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -534,7 +590,7 @@
 					unsigned int  language_index,
 					unsigned int  start_offset,
 					unsigned int *feature_count /* IN/OUT */,
-					hb_tag_t     *feature_tags /* OUT */)
+					hb_tag_t     *feature_tags  /* OUT */)
 {
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
@@ -588,7 +644,7 @@
 				  hb_tag_t      table_tag,
 				  unsigned int  feature_index,
 				  unsigned int  start_offset,
-				  unsigned int *lookup_count /* IN/OUT */,
+				  unsigned int *lookup_count   /* IN/OUT */,
 				  unsigned int *lookup_indexes /* OUT */)
 {
   return hb_ot_layout_feature_with_variations_get_lookups (face,
@@ -726,11 +782,12 @@
     for (; *languages; languages++)
     {
       unsigned int language_index;
-      if (hb_ot_layout_script_find_language (face,
-					     table_tag,
-					     script_index,
-					     *languages,
-					     &language_index))
+      if (hb_ot_layout_script_select_language (face,
+					       table_tag,
+					       script_index,
+					       1,
+					       languages,
+					       &language_index))
         _hb_ot_layout_collect_features_features (face,
                                                  table_tag,
                                                  script_index,
@@ -815,10 +872,10 @@
 hb_ot_layout_lookup_collect_glyphs (hb_face_t    *face,
 				    hb_tag_t      table_tag,
 				    unsigned int  lookup_index,
-				    hb_set_t     *glyphs_before, /* OUT. May be nullptr */
-				    hb_set_t     *glyphs_input,  /* OUT. May be nullptr */
-				    hb_set_t     *glyphs_after,  /* OUT. May be nullptr */
-				    hb_set_t     *glyphs_output  /* OUT. May be nullptr */)
+				    hb_set_t     *glyphs_before, /* OUT.  May be NULL */
+				    hb_set_t     *glyphs_input,  /* OUT.  May be NULL */
+				    hb_set_t     *glyphs_after,  /* OUT.  May be NULL */
+				    hb_set_t     *glyphs_output  /* OUT.  May be NULL */)
 {
   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
 
@@ -1016,11 +1073,11 @@
  **/
 hb_bool_t
 hb_ot_layout_get_size_params (hb_face_t    *face,
-			      unsigned int *design_size,       /* OUT.  May be nullptr */
-			      unsigned int *subfamily_id,      /* OUT.  May be nullptr */
-			      unsigned int *subfamily_name_id, /* OUT.  May be nullptr */
-			      unsigned int *range_start,       /* OUT.  May be nullptr */
-			      unsigned int *range_end          /* OUT.  May be nullptr */)
+			      unsigned int *design_size,       /* OUT.  May be NULL */
+			      unsigned int *subfamily_id,      /* OUT.  May be NULL */
+			      unsigned int *subfamily_name_id, /* OUT.  May be NULL */
+			      unsigned int *range_start,       /* OUT.  May be NULL */
+			      unsigned int *range_end          /* OUT.  May be NULL */)
 {
   const OT::GPOS &gpos = _get_gpos (face);
   const hb_tag_t tag = HB_TAG ('s','i','z','e');
@@ -1035,13 +1092,11 @@
 
       if (params.designSize)
       {
-#define PARAM(a, A) if (a) *a = params.A
-	PARAM (design_size, designSize);
-	PARAM (subfamily_id, subfamilyID);
-	PARAM (subfamily_name_id, subfamilyNameID);
-	PARAM (range_start, rangeStart);
-	PARAM (range_end, rangeEnd);
-#undef PARAM
+	if (design_size) *design_size = params.designSize;
+	if (subfamily_id) *subfamily_id = params.subfamilyID;
+	if (subfamily_name_id) *subfamily_name_id = params.subfamilyNameID;
+	if (range_start) *range_start = params.rangeStart;
+	if (range_end) *range_end = params.rangeEnd;
 
 	return true;
       }
@@ -1048,18 +1103,142 @@
     }
   }
 
-#define PARAM(a, A) if (a) *a = 0
-  PARAM (design_size, designSize);
-  PARAM (subfamily_id, subfamilyID);
-  PARAM (subfamily_name_id, subfamilyNameID);
-  PARAM (range_start, rangeStart);
-  PARAM (range_end, rangeEnd);
-#undef PARAM
+  if (design_size) *design_size = 0;
+  if (subfamily_id) *subfamily_id = 0;
+  if (subfamily_name_id) *subfamily_name_id = 0;
+  if (range_start) *range_start = 0;
+  if (range_end) *range_end = 0;
 
   return false;
 }
 
+/**
+ * hb_ot_layout_feature_get_name_ids:
+ * @face: #hb_face_t to work upon
+ * @table_tag:
+ * @feature_index:
+ * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
+ *            for a user-interface label for this feature. (May be NULL.)
+ * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
+ *              that an application can use for tooltip text for this
+ *              feature. (May be NULL.)
+ * @sample_id: (out) (allow-none): The ‘name’ table name ID that specifies sample text
+ *             that illustrates the effect of this feature. (May be NULL.)
+ * @num_named_parameters: (out) (allow-none):  Number of named parameters. (May be zero.)
+ * @first_param_id: (out) (allow-none): The first ‘name’ table name ID used to specify
+ *                  strings for user-interface labels for the feature
+ *                  parameters. (Must be zero if numParameters is zero.)
+ *
+ * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or
+ * "Character Variant" ('cvXX') features.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ * Since: 2.0.0
+ **/
+hb_bool_t
+hb_ot_layout_feature_get_name_ids (hb_face_t    *face,
+				   hb_tag_t      table_tag,
+				   unsigned int  feature_index,
+				   hb_name_id_t *label_id,             /* OUT.  May be NULL */
+				   hb_name_id_t *tooltip_id,           /* OUT.  May be NULL */
+				   hb_name_id_t *sample_id,            /* OUT.  May be NULL */
+				   unsigned int *num_named_parameters, /* OUT.  May be NULL */
+				   hb_name_id_t *first_param_id        /* OUT.  May be NULL */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
+  hb_tag_t feature_tag = g.get_feature_tag (feature_index);
+  const OT::Feature &f = g.get_feature (feature_index);
+
+  const OT::FeatureParams &feature_params = f.get_feature_params ();
+  if (&feature_params != &Null (OT::FeatureParams))
+  {
+    const OT::FeatureParamsStylisticSet& ss_params =
+      feature_params.get_stylistic_set_params (feature_tag);
+    if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */
+    {
+      if (label_id) *label_id = ss_params.uiNameID;
+      // ssXX features don't have the rest
+      if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID;
+      if (sample_id) *sample_id = HB_NAME_ID_INVALID;
+      if (num_named_parameters) *num_named_parameters = 0;
+      if (first_param_id) *first_param_id = HB_NAME_ID_INVALID;
+      return true;
+    }
+    const OT::FeatureParamsCharacterVariants& cv_params =
+      feature_params.get_character_variants_params (feature_tag);
+    if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */
+    {
+      if (label_id) *label_id = cv_params.featUILableNameID;
+      if (tooltip_id) *tooltip_id = cv_params.featUITooltipTextNameID;
+      if (sample_id) *sample_id = cv_params.sampleTextNameID;
+      if (num_named_parameters) *num_named_parameters = cv_params.numNamedParameters;
+      if (first_param_id) *first_param_id = cv_params.firstParamUILabelNameID;
+      return true;
+    }
+  }
+
+  if (label_id) *label_id = HB_NAME_ID_INVALID;
+  if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID;
+  if (sample_id) *sample_id = HB_NAME_ID_INVALID;
+  if (num_named_parameters) *num_named_parameters = 0;
+  if (first_param_id) *first_param_id = HB_NAME_ID_INVALID;
+  return false;
+}
+
+/**
+ * hb_ot_layout_feature_get_characters::
+ * @face: #hb_face_t to work upon
+ * @table_tag:
+ * @feature_index:
+ * @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) (allow-none): A buffer pointer. The Unicode Scalar Value
+ *              of the characters for which this feature provides glyph variants.
+ *
+ * Fetches characters listed by designer under feature parameters for "Character
+ * Variant" ("cvXX") features.
+ *
+ * Return value: Number of total sample characters in the cvXX feature.
+ *
+ * Since: 2.0.0
+ **/
+unsigned int
+hb_ot_layout_feature_get_characters (hb_face_t      *face,
+				     hb_tag_t        table_tag,
+				     unsigned int    feature_index,
+				     unsigned int    start_offset,
+				     unsigned int   *char_count, /* IN/OUT.  May be NULL */
+				     hb_codepoint_t *characters  /* OUT.     May be NULL */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+  hb_tag_t feature_tag = g.get_feature_tag (feature_index);
+  const OT::Feature &f = g.get_feature (feature_index);
+
+  const OT::FeatureParams &feature_params = f.get_feature_params ();
+
+  const OT::FeatureParamsCharacterVariants& cv_params =
+    feature_params.get_character_variants_params(feature_tag);
+
+  unsigned int len = 0;
+  if (char_count && characters && start_offset < cv_params.characters.len)
+  {
+    len = 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];
+  }
+  if (char_count) *char_count = len;
+  return cv_params.characters.len;
+}
+
+
 /*
  * Parts of different types are implemented here such that they have direct
  * access to GSUB/GPOS lookups.
@@ -1077,7 +1256,7 @@
     accels (hb_ot_face_data (face)->GSUB->accels) {}
 
   const OT::GSUB &table;
-  const hb_ot_layout_lookup_accelerator_t *accels;
+  const OT::hb_ot_layout_lookup_accelerator_t *accels;
 };
 
 struct GPOSProxy
@@ -1091,63 +1270,13 @@
     accels (hb_ot_face_data (face)->GPOS->accels) {}
 
   const OT::GPOS &table;
-  const hb_ot_layout_lookup_accelerator_t *accels;
+  const OT::hb_ot_layout_lookup_accelerator_t *accels;
 };
 
 
-struct hb_get_subtables_context_t :
-       hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
-{
-  template <typename Type>
-  static inline 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);
-  }
-
-  typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
-
-  struct hb_applicable_t
-  {
-    inline void init (const void *obj_, hb_apply_func_t apply_func_)
-    {
-      obj = obj_;
-      apply_func = apply_func_;
-    }
-
-    inline bool apply (OT::hb_ot_apply_context_t *c) const { return apply_func (obj, c); }
-
-    private:
-    const void *obj;
-    hb_apply_func_t apply_func;
-  };
-
-  typedef hb_auto_t<hb_vector_t<hb_applicable_t> > array_t;
-
-  /* Dispatch interface. */
-  inline const char *get_name (void) { return "GET_SUBTABLES"; }
-  template <typename T>
-  inline return_t dispatch (const T &obj)
-  {
-    hb_applicable_t *entry = array.push();
-    entry->init (&obj, apply_to<T>);
-    return HB_VOID;
-  }
-  static return_t default_return_value (void) { return HB_VOID; }
-  bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
-
-  hb_get_subtables_context_t (array_t &array_) :
-			      array (array_),
-			      debug_depth (0) {}
-
-  array_t &array;
-  unsigned int debug_depth;
-};
-
 static inline bool
 apply_forward (OT::hb_ot_apply_context_t *c,
-	       const hb_ot_layout_lookup_accelerator_t &accel,
-	       const hb_get_subtables_context_t::array_t &subtables)
+	       const OT::hb_ot_layout_lookup_accelerator_t &accel)
 {
   bool ret = false;
   hb_buffer_t *buffer = c->buffer;
@@ -1158,12 +1287,7 @@
 	(buffer->cur().mask & c->lookup_mask) &&
 	c->check_glyph_property (&buffer->cur(), c->lookup_props))
      {
-       for (unsigned int i = 0; i < subtables.len; i++)
-         if (subtables[i].apply (c))
-	 {
-	   applied = true;
-	   break;
-	 }
+       applied = accel.apply (c);
      }
 
     if (applied)
@@ -1176,8 +1300,7 @@
 
 static inline bool
 apply_backward (OT::hb_ot_apply_context_t *c,
-	       const hb_ot_layout_lookup_accelerator_t &accel,
-	       const hb_get_subtables_context_t::array_t &subtables)
+	       const OT::hb_ot_layout_lookup_accelerator_t &accel)
 {
   bool ret = false;
   hb_buffer_t *buffer = c->buffer;
@@ -1187,12 +1310,8 @@
 	(buffer->cur().mask & c->lookup_mask) &&
 	c->check_glyph_property (&buffer->cur(), c->lookup_props))
     {
-     for (unsigned int i = 0; i < subtables.len; i++)
-       if (subtables[i].apply (c))
-       {
-	 ret = true;
-	 break;
-       }
+     if (accel.apply (c))
+       ret = true;
     }
     /* The reverse lookup doesn't "advance" cursor (for good reason). */
     buffer->idx--;
@@ -1206,7 +1325,7 @@
 static inline void
 apply_string (OT::hb_ot_apply_context_t *c,
 	      const typename Proxy::Lookup &lookup,
-	      const hb_ot_layout_lookup_accelerator_t &accel)
+	      const OT::hb_ot_layout_lookup_accelerator_t &accel)
 {
   hb_buffer_t *buffer = c->buffer;
 
@@ -1215,10 +1334,6 @@
 
   c->set_lookup_props (lookup.get_props ());
 
-  hb_get_subtables_context_t::array_t subtables;
-  hb_get_subtables_context_t c_get_subtables (subtables);
-  lookup.dispatch (&c_get_subtables);
-
   if (likely (!lookup.is_reverse ()))
   {
     /* in/out forward substitution/positioning */
@@ -1227,7 +1342,7 @@
     buffer->idx = 0;
 
     bool ret;
-    ret = apply_forward (c, accel, subtables);
+    ret = apply_forward (c, accel);
     if (ret)
     {
       if (!Proxy::inplace)
@@ -1243,7 +1358,7 @@
       buffer->remove_output ();
     buffer->idx = buffer->len - 1;
 
-    apply_backward (c, accel, subtables);
+    apply_backward (c, accel);
   }
 }
 
@@ -1268,6 +1383,11 @@
       c.set_lookup_mask (lookups[table_index][i].mask);
       c.set_auto_zwj (lookups[table_index][i].auto_zwj);
       c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
+      if (lookups[table_index][i].random)
+      {
+	c.set_random (true);
+	buffer->unsafe_to_break_all ();
+      }
       apply_string<Proxy> (&c,
 			   proxy.table.get_lookup (lookup_index),
 			   proxy.accels[lookup_index]);
@@ -1297,31 +1417,7 @@
 void
 hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
 				const OT::SubstLookup &lookup,
-				const hb_ot_layout_lookup_accelerator_t &accel)
+				const OT::hb_ot_layout_lookup_accelerator_t &accel)
 {
   apply_string<GSUBProxy> (c, lookup, accel);
 }
-
-
-
-
-/*
- * OT::BASE
- */
-
-// /**
-//  * hb_ot_base_has_data:
-//  * @face: #hb_face_t to test
-//  *
-//  * This function allows to verify the presence of an OpenType BASE table on the
-//  * face.
-//  *
-//  * Return value: true if face has a BASE table, false otherwise
-//  *
-//  * Since: XXX
-//  **/
-// hb_bool_t
-// hb_ot_base_has_data (hb_face_t *face)
-// {
-//   return _get_base (face).has_data ();
-// }

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -34,6 +34,7 @@
 #include "hb.h"
 
 #include "hb-ot-tag.h"
+#include "hb-ot-name.h"
 
 HB_BEGIN_DECLS
 
@@ -111,13 +112,13 @@
 				hb_tag_t      script_tag,
 				unsigned int *script_index);
 
-/* Like find_script, but takes zero-terminated array of scripts to test */
 HB_EXTERN hb_bool_t
-hb_ot_layout_table_choose_script (hb_face_t      *face,
+hb_ot_layout_table_select_script (hb_face_t      *face,
 				  hb_tag_t        table_tag,
+				  unsigned int    script_count,
 				  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 */);
 
 HB_EXTERN unsigned int
 hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
@@ -135,11 +136,12 @@
 				       hb_tag_t     *language_tags /* OUT */);
 
 HB_EXTERN hb_bool_t
-hb_ot_layout_script_find_language (hb_face_t    *face,
-				   hb_tag_t      table_tag,
-				   unsigned int  script_index,
-				   hb_tag_t      language_tag,
-				   unsigned int *language_index);
+hb_ot_layout_script_select_language (hb_face_t      *face,
+				     hb_tag_t        table_tag,
+				     unsigned int    script_index,
+				     unsigned int    language_count,
+				     const hb_tag_t *language_tags,
+				     unsigned int   *language_index /* OUT */);
 
 HB_EXTERN hb_bool_t
 hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
@@ -214,10 +216,10 @@
 hb_ot_layout_lookup_collect_glyphs (hb_face_t    *face,
 				    hb_tag_t      table_tag,
 				    unsigned int  lookup_index,
-				    hb_set_t     *glyphs_before, /* OUT. May be NULL */
-				    hb_set_t     *glyphs_input,  /* OUT. May be NULL */
-				    hb_set_t     *glyphs_after,  /* OUT. May be NULL */
-				    hb_set_t     *glyphs_output  /* OUT. May be NULL */);
+				    hb_set_t     *glyphs_before, /* OUT.  May be NULL */
+				    hb_set_t     *glyphs_input,  /* OUT.  May be NULL */
+				    hb_set_t     *glyphs_after,  /* OUT.  May be NULL */
+				    hb_set_t     *glyphs_output  /* OUT.  May be NULL */);
 
 #ifdef HB_NOT_IMPLEMENTED
 typedef struct
@@ -325,11 +327,30 @@
 hb_ot_layout_get_size_params (hb_face_t    *face,
 			      unsigned int *design_size,       /* OUT.  May be NULL */
 			      unsigned int *subfamily_id,      /* OUT.  May be NULL */
-			      unsigned int *subfamily_name_id, /* OUT.  May be NULL */
+			      hb_name_id_t *subfamily_name_id, /* OUT.  May be NULL */
 			      unsigned int *range_start,       /* OUT.  May be NULL */
 			      unsigned int *range_end          /* OUT.  May be NULL */);
 
 
+HB_EXTERN hb_bool_t
+hb_ot_layout_feature_get_name_ids (hb_face_t    *face,
+				   hb_tag_t      table_tag,
+				   unsigned int  feature_index,
+				   hb_name_id_t *label_id             /* OUT.  May be NULL */,
+				   hb_name_id_t *tooltip_id           /* OUT.  May be NULL */,
+				   hb_name_id_t *sample_id            /* OUT.  May be NULL */,
+				   unsigned int *num_named_parameters /* OUT.  May be NULL */,
+				   hb_name_id_t *first_param_id       /* OUT.  May be NULL */);
+
+
+HB_EXTERN unsigned int
+hb_ot_layout_feature_get_characters (hb_face_t      *face,
+				     hb_tag_t        table_tag,
+				     unsigned int    feature_index,
+				     unsigned int    start_offset,
+				     unsigned int   *char_count    /* IN/OUT.  May be NULL */,
+				     hb_codepoint_t *characters    /* OUT.     May be NULL */);
+
 /*
  * BASE
  */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -49,6 +49,19 @@
 HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face);
 
 
+/*
+ * kern
+ */
+
+HB_INTERNAL hb_bool_t
+hb_ot_layout_has_kerning (hb_face_t *face);
+
+HB_INTERNAL void
+hb_ot_layout_kern (hb_font_t *font,
+		   hb_buffer_t  *buffer,
+		   hb_mask_t kern_mask);
+
+
 /* Private API corresponding to hb-ot-layout.h: */
 
 HB_INTERNAL hb_bool_t
@@ -99,32 +112,16 @@
 			       hb_buffer_t  *buffer);
 
 
-struct hb_ot_layout_lookup_accelerator_t
-{
-  template <typename TLookup>
-  inline void init (const TLookup &lookup)
-  {
-    digest.init ();
-    lookup.add_coverage (&digest);
-  }
-  inline void fini (void) {}
-
-  inline bool may_have (hb_codepoint_t g) const
-  { return digest.may_have (g); }
-
-  private:
-  hb_set_digest_t digest;
-};
-
 namespace OT {
   struct hb_ot_apply_context_t;
   struct SubstLookup;
+  struct hb_ot_layout_lookup_accelerator_t;
 }
 
 HB_INTERNAL void
 hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
 				const OT::SubstLookup &lookup,
-				const hb_ot_layout_lookup_accelerator_t &accel);
+				const OT::hb_ot_layout_lookup_accelerator_t &accel);
 
 
 /* Should be called before all the position_lookup's are done. */
@@ -160,12 +157,12 @@
 #define foreach_syllable(buffer, start, end) \
   for (unsigned int \
        _count = buffer->len, \
-       start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \
+       start = 0, end = _count ? _hb_next_syllable (buffer, 0) : 0; \
        start < _count; \
-       start = end, end = _next_syllable (buffer, start))
+       start = end, end = _hb_next_syllable (buffer, start))
 
 static inline unsigned int
-_next_syllable (hb_buffer_t *buffer, unsigned int start)
+_hb_next_syllable (hb_buffer_t *buffer, unsigned int start)
 {
   hb_glyph_info_t *info = buffer->info;
   unsigned int count = buffer->len;
@@ -188,7 +185,7 @@
  *   * Whether it's one of the three Mongolian Free Variation Selectors,
  *     CGJ, or other characters that are hidden but should not be ignored
  *     like most other Default_Ignorable()s do during matching.
- *   * One free bit right now.
+ *   * Whether it's a grapheme continuation.
  *
  * The high-byte has different meanings, switched by the Gen-Cat:
  * - For Mn,Mc,Me: the modified Combining_Class.
@@ -200,8 +197,8 @@
 enum hb_unicode_props_flags_t {
   UPROPS_MASK_GEN_CAT	= 0x001Fu,
   UPROPS_MASK_IGNORABLE	= 0x0020u,
-  UPROPS_MASK_HIDDEN	= 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3,
-                                    * or TAG characters */
+  UPROPS_MASK_HIDDEN	= 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3, or TAG characters */
+  UPROPS_MASK_CONTINUATION=0x0080u,
 
   /* If GEN_CAT=FORMAT, top byte masks: */
   UPROPS_MASK_Cf_ZWJ	= 0x0100u,
@@ -220,6 +217,7 @@
   if (u >= 0x80)
   {
     buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII;
+
     if (unlikely (unicode->is_default_ignorable (u)))
     {
       buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
@@ -245,35 +243,11 @@
 	props |= UPROPS_MASK_HIDDEN;
       }
     }
-    else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat)))
+
+    if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)))
     {
-      /* The above check is just an optimization to let in only things we need further
-       * processing on. */
-
-      /* Only Mn and Mc can have non-zero ccc:
-       * https://unicode.org/policies/stability_policy.html#Property_Value
-       * """
-       * Canonical_Combining_Class, General_Category
-       * All characters other than those with General_Category property values
-       * Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining_Class
-       * property value 0.
-       * 1.1.5+
-       * """
-       *
-       * Also, all Mn's that are Default_Ignorable, have ccc=0, hence
-       * the "else if".
-       */
-      props |= unicode->modified_combining_class (info->codepoint)<<8;
-
-      /* Recategorize emoji skin-tone modifiers as Unicode mark, so they
-       * behave correctly in non-native directionality.  They originally
-       * are MODIFIER_SYMBOL.  Fixes:
-       * https://github.com/harfbuzz/harfbuzz/issues/169
-       */
-      if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu)))
-      {
-	props = gen_cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
-      }
+      props |= UPROPS_MASK_CONTINUATION;
+      props |= unicode->modified_combining_class (u)<<8;
     }
   }
 
@@ -312,29 +286,6 @@
 {
   return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
 }
-
-
-/* Loop over grapheme. Based on foreach_cluster(). */
-#define foreach_grapheme(buffer, start, end) \
-  for (unsigned int \
-       _count = buffer->len, \
-       start = 0, end = _count ? _next_grapheme (buffer, 0) : 0; \
-       start < _count; \
-       start = end, end = _next_grapheme (buffer, start))
-
-static inline unsigned int
-_next_grapheme (hb_buffer_t *buffer, unsigned int start)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-
-  while (++start < count && _hb_glyph_info_is_unicode_mark (&info[start]))
-    ;
-
-  return start;
-}
-
-
 #define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
 
 static inline bool
@@ -379,7 +330,42 @@
   info->unicode_props() &= ~ UPROPS_MASK_HIDDEN;
 }
 
+static inline void
+_hb_glyph_info_set_continuation (hb_glyph_info_t *info)
+{
+  info->unicode_props() |= UPROPS_MASK_CONTINUATION;
+}
+static inline void
+_hb_glyph_info_reset_continuation (hb_glyph_info_t *info)
+{
+  info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION;
+}
 static inline bool
+_hb_glyph_info_is_continuation (const hb_glyph_info_t *info)
+{
+  return info->unicode_props() & UPROPS_MASK_CONTINUATION;
+}
+/* Loop over grapheme. Based on foreach_cluster(). */
+#define foreach_grapheme(buffer, start, end) \
+  for (unsigned int \
+       _count = buffer->len, \
+       start = 0, end = _count ? _hb_next_grapheme (buffer, 0) : 0; \
+       start < _count; \
+       start = end, end = _hb_next_grapheme (buffer, start))
+
+static inline unsigned int
+_hb_next_grapheme (hb_buffer_t *buffer, unsigned int start)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+
+  while (++start < count && _hb_glyph_info_is_continuation (&info[start]))
+    ;
+
+  return start;
+}
+
+static inline bool
 _hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)
 {
   return _hb_glyph_info_get_general_category (info) ==

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -54,16 +54,17 @@
   /* Fetch script/language indices for GSUB/GPOS.  We need these later to skip
    * features not available in either table and not waste precious bits for them. */
 
-  hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE};
-  hb_tag_t language_tag;
+  unsigned int script_count = HB_OT_MAX_TAGS_PER_SCRIPT;
+  unsigned int language_count = HB_OT_MAX_TAGS_PER_LANGUAGE;
+  hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT];
+  hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
 
-  hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]);
-  language_tag = hb_ot_tag_from_language (props.language);
+  hb_ot_tags_from_script_and_language (props.script, props.language, &script_count, script_tags, &language_count, language_tags);
 
   for (unsigned int table_index = 0; table_index < 2; table_index++) {
     hb_tag_t table_tag = table_tags[table_index];
-    found_script[table_index] = (bool) hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]);
-    hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
+    found_script[table_index] = (bool) hb_ot_layout_table_select_script (face, table_tag, script_count, script_tags, &script_index[table_index], &chosen_script[table_index]);
+    hb_ot_layout_script_select_language (face, table_tag, script_index[table_index], language_count, language_tags, &language_index[table_index]);
   }
 }
 
@@ -74,8 +75,9 @@
     stages[table_index].fini ();
 }
 
-void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
-				       hb_ot_map_feature_flags_t flags)
+void hb_ot_map_builder_t::add_feature (hb_tag_t tag,
+				       hb_ot_map_feature_flags_t flags,
+				       unsigned int value)
 {
   feature_info_t *info = feature_infos.push();
   if (unlikely (!tag)) return;
@@ -95,7 +97,8 @@
 				  unsigned int  variations_index,
 				  hb_mask_t     mask,
 				  bool          auto_zwnj,
-				  bool          auto_zwj)
+				  bool          auto_zwj,
+				  bool          random)
 {
   unsigned int lookup_indices[32];
   unsigned int offset, len;
@@ -122,6 +125,7 @@
       lookup->index = lookup_indices[i];
       lookup->auto_zwnj = auto_zwnj;
       lookup->auto_zwj = auto_zwj;
+      lookup->random = random;
     }
 
     offset += len;
@@ -208,8 +212,8 @@
       /* Uses the global bit */
       bits_needed = 0;
     else
-      /* Limit to 8 bits per feature. */
-      bits_needed = MIN(8u, hb_bit_storage (info->max_value));
+      /* Limit bits per feature. */
+      bits_needed = 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. */
@@ -252,6 +256,7 @@
     map->stage[1] = info->stage[1];
     map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ);
     map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
+    map->random = !!(info->flags & F_RANDOM);
     if ((info->flags & F_GLOBAL) && info->max_value == 1) {
       /* Uses the global bit */
       map->shift = global_bit_shift;
@@ -301,7 +306,8 @@
 		       variations_index,
 		       m.features[i].mask,
 		       m.features[i].auto_zwnj,
-		       m.features[i].auto_zwj);
+		       m.features[i].auto_zwj,
+		       m.features[i].random);
 
       /* Sort lookups and merge duplicates */
       if (last_num_lookups < m.lookups[table_index].len)

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -32,6 +32,9 @@
 #include "hb-buffer.hh"
 
 
+#define HB_OT_MAP_MAX_BITS 8u
+#define HB_OT_MAP_MAX_VALUE ((1u << HB_OT_MAP_MAX_BITS) - 1u)
+
 struct hb_ot_shape_plan_t;
 
 static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
@@ -52,6 +55,7 @@
     unsigned int needs_fallback : 1;
     unsigned int auto_zwnj : 1;
     unsigned int auto_zwj : 1;
+    unsigned int random : 1;
 
     inline int cmp (const hb_tag_t *tag_) const
     { return *tag_ < tag ? -1 : *tag_ > tag ? 1 : 0; }
@@ -61,6 +65,7 @@
     unsigned short index;
     unsigned short auto_zwnj : 1;
     unsigned short auto_zwj : 1;
+    unsigned short random : 1;
     hb_mask_t mask;
 
     static int cmp (const void *pa, const void *pb)
@@ -161,19 +166,29 @@
   hb_vector_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
 };
 
-enum hb_ot_map_feature_flags_t {
+enum hb_ot_map_feature_flags_t
+{
   F_NONE		= 0x0000u,
   F_GLOBAL		= 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */
   F_HAS_FALLBACK	= 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */
   F_MANUAL_ZWNJ		= 0x0004u, /* Don't skip over ZWNJ when matching **context**. */
   F_MANUAL_ZWJ		= 0x0008u, /* Don't skip over ZWJ when matching **input**. */
-  F_GLOBAL_SEARCH	= 0x0010u  /* If feature not found in LangSys, look for it in global feature list and pick one. */
+  F_MANUAL_JOINERS	= F_MANUAL_ZWNJ | F_MANUAL_ZWJ,
+  F_GLOBAL_MANUAL_JOINERS= F_GLOBAL | F_MANUAL_JOINERS,
+  F_GLOBAL_HAS_FALLBACK = F_GLOBAL | F_HAS_FALLBACK,
+  F_GLOBAL_SEARCH	= 0x0010u, /* If feature not found in LangSys, look for it in global feature list and pick one. */
+  F_RANDOM		= 0x0020u  /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
 };
 HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t);
-/* Macro version for where const is desired. */
-#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
 
 
+struct hb_ot_map_feature_t
+{
+  hb_tag_t tag;
+  hb_ot_map_feature_flags_t flags;
+};
+
+
 struct hb_ot_map_builder_t
 {
   public:
@@ -183,12 +198,21 @@
 
   HB_INTERNAL ~hb_ot_map_builder_t (void);
 
-  HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
-				hb_ot_map_feature_flags_t flags);
+  HB_INTERNAL void add_feature (hb_tag_t tag,
+				hb_ot_map_feature_flags_t flags=F_NONE,
+				unsigned int value=1);
 
-  inline void add_global_bool_feature (hb_tag_t tag)
-  { add_feature (tag, 1, F_GLOBAL); }
+  inline void add_feature (const hb_ot_map_feature_t &feat)
+  { add_feature (feat.tag, feat.flags); }
 
+  inline void enable_feature (hb_tag_t tag,
+			      hb_ot_map_feature_flags_t flags=F_NONE,
+			      unsigned int value=1)
+  { add_feature (tag, F_GLOBAL | flags, value); }
+
+  inline void disable_feature (hb_tag_t tag)
+  { add_feature (tag, F_GLOBAL, 0); }
+
   inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
   { add_pause (0, pause_func); }
   inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
@@ -206,7 +230,8 @@
 				unsigned int  variations_index,
 				hb_mask_t     mask,
 				bool          auto_zwnj = true,
-				bool          auto_zwj = true);
+				bool          auto_zwj = true,
+				bool          random = false);
 
   struct feature_info_t {
     hb_tag_t tag;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -50,7 +50,7 @@
   protected:
   HBINT16			value;		/* The X or Y value in design units */
   OffsetTo<Device>	deviceTable;	/* Offset to the device table - from the
-					 * beginning of parent table. May be nullptr.
+					 * beginning of parent table.  May be NULL.
 					 * Suggested format for device table is 1. */
 
   public:
@@ -234,7 +234,7 @@
     TRACE_SANITIZE (this);
     unsigned int count = 2 * heightCount + 1;
     for (unsigned int i = 0; i < count; i++)
-      if (!mathValueRecords[i].sanitize (c, this)) return_trace (false);
+      if (!mathValueRecordsZ.arrayZ[i].sanitize (c, this)) return_trace (false);
     return_trace (true);
   }
 
@@ -242,16 +242,14 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  c->check_array (mathValueRecords,
-				  mathValueRecords[0].static_size,
-				  2 * heightCount + 1) &&
+		  c->check_array (mathValueRecordsZ.arrayZ, 2 * heightCount + 1) &&
 		  sanitize_math_value_records (c));
   }
 
   inline hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const
   {
-    const MathValueRecord* correctionHeight = mathValueRecords;
-    const MathValueRecord* kernValue = mathValueRecords + heightCount;
+    const MathValueRecord* correctionHeight = mathValueRecordsZ.arrayZ;
+    const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount;
     int sign = font->y_scale < 0 ? -1 : +1;
 
     /* The description of the MathKern table is a ambiguous, but interpreting
@@ -279,18 +277,19 @@
   }
 
   protected:
-  HBUINT16	  heightCount;
-  MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at
-					  * which the kern value changes.
-					  * Sorted by the height value in
-					  * design units (heightCount entries),
-					  * Followed by:
-					  * Array of kern values corresponding
-					  * to heights. (heightCount+1 entries).
-					  */
+  HBUINT16	heightCount;
+  UnsizedArrayOf<MathValueRecord>
+		mathValueRecordsZ;	/* Array of correction heights at
+					 * which the kern value changes.
+					 * Sorted by the height value in
+					 * design units (heightCount entries),
+					 * Followed by:
+					 * Array of kern values corresponding
+					 * to heights. (heightCount+1 entries).
+					 */
 
   public:
-  DEFINE_SIZE_ARRAY (2, mathValueRecords);
+  DEFINE_SIZE_ARRAY (2, mathValueRecordsZ);
 };
 
 struct MathKernInfoRecord
@@ -319,7 +318,7 @@
 
   protected:
   /* Offset to MathKern table for each corner -
-   * from the beginning of MathKernInfo table. May be nullptr. */
+   * from the beginning of MathKernInfo table.  May be NULL. */
   OffsetTo<MathKern> mathKern[4];
 
   public:
@@ -402,7 +401,7 @@
    * from the beginning of MathGlyphInfo table. When the left or right glyph of
    * a box is an extended shape variant, the (ink) box (and not the default
    * position defined by values in MathConstants table) should be used for
-   * vertical positioning purposes. May be nullptr.. */
+   * vertical positioning purposes.  May be NULL.. */
   OffsetTo<Coverage> extendedShapeCoverage;
 
    /* Offset to MathKernInfo table -
@@ -571,7 +570,7 @@
 
   protected:
   /* Offset to MathGlyphAssembly table for this shape - from the beginning of
-     MathGlyphConstruction table. May be nullptr. */
+     MathGlyphConstruction table.  May be NULL. */
   OffsetTo<MathGlyphAssembly>	  glyphAssembly;
 
   /* MathGlyphVariantRecords for alternative variants of the glyphs. */
@@ -588,7 +587,7 @@
     TRACE_SANITIZE (this);
     unsigned int count = vertGlyphCount + horizGlyphCount;
     for (unsigned int i = 0; i < count; i++)
-      if (!glyphConstruction[i].sanitize (c, this)) return_trace (false);
+      if (!glyphConstruction.arrayZ[i].sanitize (c, this)) return_trace (false);
     return_trace (true);
   }
 
@@ -598,9 +597,7 @@
     return_trace (c->check_struct (this) &&
 		  vertGlyphCoverage.sanitize (c, this) &&
 		  horizGlyphCoverage.sanitize (c, this) &&
-		  c->check_array (glyphConstruction,
-				  glyphConstruction[0].static_size,
-				  vertGlyphCount + horizGlyphCount) &&
+		  c->check_array (glyphConstruction.arrayZ, vertGlyphCount + horizGlyphCount) &&
 		  sanitize_offsets (c));
   }
 
@@ -670,7 +667,8 @@
   /* Array of offsets to MathGlyphConstruction tables - from the beginning of
      the MathVariants table, for shapes growing in vertical/horizontal
      direction. */
-  OffsetTo<MathGlyphConstruction> glyphConstruction[VAR];
+  UnsizedArrayOf<OffsetTo<MathGlyphConstruction> >
+ 			glyphConstruction;
 
   public:
   DEFINE_SIZE_ARRAY (10, glyphConstruction);

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -136,7 +136,7 @@
   FixedVersion<>version;		/* Version of the maxp table (0.5 or 1.0),
 					 * 0x00005000u or 0x00010000u. */
   HBUINT16	numGlyphs;		/* The number of glyphs in the font. */
-/*maxpV1Tail v1Tail[VAR]; */
+/*maxpV1Tail	v1Tail[VAR]; */
   public:
   DEFINE_SIZE_STATIC (6);
 };

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -91,7 +91,7 @@
     key.encodingID.set (encoding_id);
     key.languageID.set (language_id);
     key.nameID.set (name_id);
-    NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), NameRecord::cmp);
+    NameRecord *match = (NameRecord *) bsearch (&key, nameRecordZ.arrayZ, count, sizeof (nameRecordZ[0]), NameRecord::cmp);
 
     if (!match)
       return 0;
@@ -102,7 +102,7 @@
   }
 
   inline unsigned int get_size (void) const
-  { return min_size + count * nameRecord[0].min_size; }
+  { return min_size + count * nameRecordZ[0].min_size; }
 
   inline bool sanitize_records (hb_sanitize_context_t *c) const {
     TRACE_SANITIZE (this);
@@ -109,7 +109,7 @@
     char *string_pool = (char *) this + stringOffset;
     unsigned int _count = count;
     for (unsigned int i = 0; i < _count; i++)
-      if (!nameRecord[i].sanitize (c, string_pool)) return_trace (false);
+      if (!nameRecordZ[i].sanitize (c, string_pool)) return_trace (false);
     return_trace (true);
   }
 
@@ -118,7 +118,7 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
 		  likely (format == 0 || format == 1) &&
-		  c->check_array (nameRecord, nameRecord[0].static_size, count) &&
+		  c->check_array (nameRecordZ.arrayZ, count) &&
 		  sanitize_records (c));
   }
 
@@ -126,9 +126,10 @@
   HBUINT16	format;			/* Format selector (=0/1). */
   HBUINT16	count;			/* Number of name records. */
   Offset16	stringOffset;		/* Offset to start of string storage (from start of table). */
-  NameRecord	nameRecord[VAR];	/* The name records where count is the number of records. */
+  UnsizedArrayOf<NameRecord>
+		nameRecordZ;		/* The name records where count is the number of records. */
   public:
-  DEFINE_SIZE_ARRAY (6, nameRecord);
+  DEFINE_SIZE_ARRAY (6, nameRecordZ);
 };
 
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_NAME_H
+#define HB_OT_NAME_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+
+/**
+ * hb_name_id_t:
+ *
+ * Since: 2.0.0
+ */
+typedef unsigned int hb_name_id_t;
+
+/**
+ * HB_NAME_ID_INVALID
+ *
+ * Since: 2.0.0
+ **/
+#define HB_NAME_ID_INVALID 0xFFFF
+
+HB_END_DECLS
+
+#endif /* HB_OT_NAME_H */


Property changes on: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -81,7 +81,7 @@
 
     hb_codepoint_t cp = HB_SET_VALUE_INVALID;
     while (codepoints->next (&cp)) {
-      unsigned int bit = hb_get_unicode_range_bit (cp);
+      unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp);
       if (bit < 128)
       {
         unsigned int block = bit / 32;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -31,14 +31,29 @@
 
 namespace OT {
 
-struct Range {
+struct OS2Range
+{
+  static int
+  cmp (const void *_key, const void *_item, void *_arg)
+  {
+    hb_codepoint_t cp = *((hb_codepoint_t *) _key);
+    const OS2Range *range = (OS2Range *) _item;
+
+    if (cp < range->start)
+      return -1;
+    else if (cp <= range->end)
+      return 0;
+    else
+      return +1;
+  }
+
   hb_codepoint_t start;
   hb_codepoint_t end;
   unsigned int bit;
 };
 
-/* Note: The contents of this array was generated using src/gen-unicode-ranges.py. */
-static Range os2UnicodeRangesSorted[] =
+/* Note: The contents of this array was generated using gen-os2-unicode-ranges.py. */
+static const OS2Range _hb_os2_unicode_ranges[] =
 {
   {     0x0,     0x7F,   0}, // Basic Latin
   {    0x80,     0xFF,   1}, // Latin-1 Supplement
@@ -211,31 +226,17 @@
   {0x100000, 0x10FFFD,  90}, // Private Use (plane 16)
 };
 
-static int
-_compare_range (const void *_key, const void *_item, void *_arg)
-{
-  hb_codepoint_t cp = *((hb_codepoint_t *) _key);
-  const Range *range = (Range *) _item;
-
-  if (cp < range->start)
-    return -1;
-  else if (cp <= range->end)
-    return 0;
-  else
-    return 1;
-}
-
 /**
- * hb_get_unicode_range_bit:
- * Returns the bit to be set in os/2 ulUnicodeRange for a given codepoint.
+ * _hb_ot_os2_get_unicode_range_bit:
+ * Returns the bit to be set in os/2 ulUnicodeOS2Range for a given codepoint.
  **/
 static unsigned int
-hb_get_unicode_range_bit (hb_codepoint_t cp)
+_hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp)
 {
-  Range *range = (Range*) hb_bsearch_r (&cp, os2UnicodeRangesSorted,
-                                        sizeof (os2UnicodeRangesSorted) / sizeof(Range),
-                                        sizeof(Range),
-                                        _compare_range, nullptr);
+  OS2Range *range = (OS2Range*) hb_bsearch_r (&cp, _hb_os2_unicode_ranges,
+					      ARRAY_LENGTH (_hb_os2_unicode_ranges),
+					      sizeof (OS2Range),
+					      OS2Range::cmp, nullptr);
   if (range != nullptr)
     return range->bit;
   return -1;

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -55,10 +55,11 @@
     return_trace (glyphNameIndex.sanitize (c));
   }
 
-  ArrayOf<HBUINT16>glyphNameIndex;	/* This is not an offset, but is the
+  ArrayOf<HBUINT16>	glyphNameIndex;	/* This is not an offset, but is the
 					 * ordinal number of the glyph in 'post'
 					 * string tables. */
-  HBUINT8		namesX[VAR];		/* Glyph names with length bytes [variable]
+  UnsizedArrayOf<HBUINT8>
+			namesX;		/* Glyph names with length bytes [variable]
 					 * (a Pascal string). */
 
   DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
@@ -130,6 +131,7 @@
     {
       index_to_offset.fini ();
       free (gids_sorted_by_name.get ());
+      hb_blob_destroy (blob);
     }
 
     inline bool get_glyph_name (hb_codepoint_t glyph,
@@ -142,7 +144,7 @@
 	return true;
       if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
         return false;
-      strncpy (buf, s.bytes, s.len);
+      strncpy (buf, s.arrayZ, s.len);
       buf[s.len] = '\0';
       return true;
     }
@@ -240,7 +242,7 @@
 
       if (index >= index_to_offset.len)
 	return hb_bytes_t ();
-      unsigned int offset = index_to_offset.arrayZ[index];
+      unsigned int offset = index_to_offset[index];
 
       const uint8_t *data = pool + offset;
       unsigned int name_length = *data;

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -201,7 +201,7 @@
 
   hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
   OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
-  hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
+  OT::hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
 };
 
 #if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256)

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -159,11 +159,6 @@
 
 
 static void
-nuke_joiners (const hb_ot_shape_plan_t *plan,
-	      hb_font_t *font,
-	      hb_buffer_t *buffer);
-
-static void
 arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer);
@@ -200,13 +195,12 @@
    * work correctly.  See https://github.com/harfbuzz/harfbuzz/issues/505
    */
 
-  map->add_gsub_pause (nuke_joiners);
 
-  map->add_global_bool_feature (HB_TAG('s','t','c','h'));
+  map->enable_feature (HB_TAG('s','t','c','h'));
   map->add_gsub_pause (record_stch);
 
-  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
-  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+  map->enable_feature (HB_TAG('c','c','m','p'));
+  map->enable_feature (HB_TAG('l','o','c','l'));
 
   map->add_gsub_pause (nullptr);
 
@@ -213,19 +207,26 @@
   for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
   {
     bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
-    map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
+    map->add_feature (arabic_features[i], has_fallback ? F_HAS_FALLBACK : F_NONE);
     map->add_gsub_pause (nullptr);
   }
 
-  map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
+  /* Normally, Unicode says a ZWNJ means "don't ligate".  In Arabic script
+   * however, it says a ZWJ should also mean "don't ligate".  So we run
+   * the main ligating features as MANUAL_ZWJ. */
+
+  map->enable_feature (HB_TAG('r','l','i','g'), F_MANUAL_ZWJ | F_HAS_FALLBACK);
+
   if (plan->props.script == HB_SCRIPT_ARABIC)
     map->add_gsub_pause (arabic_fallback_shape);
 
   /* No pause after rclt.  See 98460779bae19e4d64d29461ff154b3527bf8420. */
-  map->add_global_bool_feature (HB_TAG('r','c','l','t'));
-  map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+  map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ);
+  map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ);
   map->add_gsub_pause (nullptr);
 
+  /* And undo here. */
+
   /* The spec includes 'cswh'.  Earlier versions of Windows
    * used to enable this by default, but testing suggests
    * that Windows 8 and later do not enable it by default,
@@ -234,8 +235,8 @@
    * Note that IranNastaliq uses this feature extensively
    * to fixup broken glyph sequences.  Oh well...
    * Test case: U+0643,U+0640,U+0631. */
-  //map->add_global_bool_feature (HB_TAG('c','s','w','h'));
-  map->add_global_bool_feature (HB_TAG('m','s','e','t'));
+  //map->enable_feature (HB_TAG('c','s','w','h'));
+  map->enable_feature (HB_TAG('m','s','e','t'));
 }
 
 #include "hb-ot-shape-complex-arabic-fallback.hh"
@@ -379,20 +380,7 @@
   setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
 }
 
-
 static void
-nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
-	      hb_font_t *font HB_UNUSED,
-	      hb_buffer_t *buffer)
-{
-  unsigned int count = buffer->len;
-  hb_glyph_info_t *info = buffer->info;
-  for (unsigned int i = 0; i < count; i++)
-    if (_hb_glyph_info_is_zwj (&info[i]))
-      _hb_glyph_info_flip_joiners (&info[i]);
-}
-
-static void
 arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
 		       hb_font_t *font,
 		       hb_buffer_t *buffer)
@@ -470,9 +458,9 @@
 
   int sign = font->x_scale < 0 ? -1 : +1;
   unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT
-  typedef enum { MEASURE, CUT } step_t;
+  enum { MEASURE, CUT } /* step_t */;
 
-  for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1))
+  for (unsigned int step = MEASURE; step <= CUT; step = step + 1)
   {
     unsigned int count = buffer->len;
     hb_glyph_info_t *info = buffer->info;
@@ -611,7 +599,7 @@
   HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
 }
 
-/* https://unicode.org/reports/tr53/tr53-1.pdf */
+/* http://www.unicode.org/reports/tr53/ */
 
 static hb_codepoint_t
 modifier_combining_marks[] =
@@ -623,6 +611,7 @@
   0x06E3u, /* ARABIC SMALL LOW SEEN */
   0x06E7u, /* ARABIC SMALL HIGH YEH */
   0x06E8u, /* ARABIC SMALL HIGH NOON */
+  0x08D3u, /* ARABIC SMALL LOW WAW */
   0x08F3u, /* ARABIC SMALL HIGH WAW */
 };
 
@@ -714,7 +703,7 @@
   nullptr, /* decompose */
   nullptr, /* compose */
   setup_masks_arabic,
-  nullptr, /* disable_otl */
+  HB_TAG_NONE, /* gpos_tag */
   reorder_marks_arabic,
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -39,7 +39,7 @@
   nullptr, /* decompose */
   nullptr, /* compose */
   nullptr, /* setup_masks */
-  nullptr, /* disable_otl */
+  HB_TAG_NONE, /* gpos_tag */
   nullptr, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hangul.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -56,7 +56,7 @@
   hb_ot_map_builder_t *map = &plan->map;
 
   for (unsigned int i = FIRST_HANGUL_FEATURE; i < HANGUL_FEATURE_COUNT; i++)
-    map->add_feature (hangul_features[i], 1, F_NONE);
+    map->add_feature (hangul_features[i]);
 }
 
 static void
@@ -65,7 +65,7 @@
   /* Uniscribe does not apply 'calt' for Hangul, and certain fonts
    * (Noto Sans CJK, Source Sans Han, etc) apply all of jamo lookups
    * in calt, which is not desirable. */
-  plan->map.add_feature (HB_TAG('c','a','l','t'), 0, F_GLOBAL);
+  plan->map.disable_feature (HB_TAG('c','a','l','t'));
 }
 
 struct hangul_shape_plan_t
@@ -345,14 +345,7 @@
 	{
 	  unsigned int s_len = tindex ? 3 : 2;
 	  buffer->replace_glyphs (1, s_len, decomposed);
-	  if (unlikely (!buffer->successful))
-	    return;
 
-	  /* We decomposed S: apply jamo features to the individual glyphs
-	   * that are now in buffer->out_info.
-	   */
-	  hb_glyph_info_t *info = buffer->out_info;
-
 	  /* If we decomposed an LV because of a non-combining T following,
 	   * we want to include this T in the syllable.
 	   */
@@ -361,6 +354,14 @@
             buffer->next_glyph ();
             s_len++;
           }
+
+	  if (unlikely (!buffer->successful))
+	    return;
+
+	  /* We decomposed S: apply jamo features to the individual glyphs
+	   * that are now in buffer->out_info.
+	   */
+	  hb_glyph_info_t *info = buffer->out_info;
           end = start + s_len;
 
 	  unsigned int i = start;
@@ -368,6 +369,7 @@
 	  info[i++].hangul_shaping_feature() = VJMO;
 	  if (i < end)
 	    info[i++].hangul_shaping_feature() = TJMO;
+
 	  if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
 	    buffer->merge_out_clusters (start, end);
 	  continue;
@@ -424,7 +426,7 @@
   nullptr, /* decompose */
   nullptr, /* compose */
   setup_masks_hangul,
-  nullptr, /* disable_otl */
+  HB_TAG_NONE, /* gpos_tag */
   nullptr, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-hebrew.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -70,7 +70,7 @@
 
   bool found = (bool) c->unicode->compose (a, b, ab);
 
-  if (!found && !c->plan->has_mark)
+  if (!found && !c->plan->has_gpos_mark)
   {
       /* Special-case Hebrew presentation forms that are excluded from
        * standard normalization, but wanted for old fonts. */
@@ -154,19 +154,7 @@
   return found;
 }
 
-static bool
-disable_otl_hebrew (const hb_ot_shape_plan_t *plan)
-{
-  /* For Hebrew shaper, use fallback if GPOS does not have 'hebr'
-   * script.  This matches Uniscribe better, and makes fonts like
-   * Arial that have GSUB/GPOS/GDEF but no data for Hebrew work.
-   * See:
-   * https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368
-   */
-  return plan->map.chosen_script[1] != HB_TAG ('h','e','b','r');
-}
 
-
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
 {
   nullptr, /* collect_features */
@@ -179,7 +167,7 @@
   nullptr, /* decompose */
   compose_hebrew,
   nullptr, /* setup_masks */
-  disable_otl_hebrew,
+  HB_TAG ('h','e','b','r'), /* gpos_tag. https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368 */
   nullptr, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -34,887 +34,709 @@
 
 #line 36 "hb-ot-shape-complex-indic-machine.hh"
 static const unsigned char _indic_syllable_machine_trans_keys[] = {
-	8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 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, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 
-	4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 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, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 
-	4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 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, 8u, 
-	4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 
-	8u, 8u, 5u, 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, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 
-	4u, 13u, 4u, 8u, 4u, 13u, 4u, 13u, 5u, 8u, 5u, 8u, 5u, 7u, 5u, 8u, 
-	5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 
-	8u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 
-	6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 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, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 
+	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, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 
+	3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 
+	3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 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, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 
+	3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 
+	1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 
+	3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 
+	3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 
+	3u, 13u, 3u, 10u, 4u, 10u, 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, 3u, 10u, 
+	3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 
+	1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 
+	1u, 16u, 1u, 16u, 1u, 16u, 4u, 8u, 3u, 10u, 3u, 10u, 4u, 10u, 1u, 16u, 
+	3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 
+	3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 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, 
-	3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 
-	1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 
-	1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 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, 3u, 10u, 4u, 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, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
-	1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 
-	3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 
-	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, 3u, 10u, 
-	4u, 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, 3u, 17u, 3u, 17u, 1u, 16u, 
-	1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
-	1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 
-	3u, 17u, 1u, 16u, 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, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 
+	5u, 10u, 3u, 10u, 4u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 
+	3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 
+	1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 13u, 
+	3u, 10u, 4u, 8u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 
+	4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 
+	4u, 10u, 1u, 16u, 3u, 13u, 3u, 10u, 4u, 10u, 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, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 
-	3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 
-	1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 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, 4u, 10u, 5u, 10u, 3u, 10u, 
-	4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 
+	4u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 
+	1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 
+	3u, 10u, 3u, 13u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 1u, 16u, 3u, 13u, 
+	1u, 16u, 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
 };
 
 static const char _indic_syllable_machine_key_spans[] = {
-	1, 4, 3, 1, 4, 3, 1, 4, 
+	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, 5, 10, 5, 10, 5, 10, 5, 
-	10, 5, 10, 1, 4, 3, 1, 4, 
-	3, 1, 4, 3, 1, 4, 3, 1, 
-	5, 1, 1, 5, 1, 1, 5, 1, 
-	1, 5, 1, 1, 5, 10, 5, 10, 
-	5, 10, 5, 10, 5, 10, 1, 4, 
-	3, 1, 4, 3, 1, 4, 3, 1, 
-	4, 3, 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, 
-	10, 5, 10, 5, 10, 5, 10, 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, 4, 3, 1, 5, 1, 1, 
-	5, 1, 1, 5, 1, 1, 5, 1, 
-	1, 5, 10, 5, 10, 5, 10, 5, 
-	10, 5, 10, 10, 4, 4, 3, 4, 
-	3, 1, 4, 3, 1, 4, 3, 1, 
-	1, 5, 1, 1, 5, 1, 1, 5, 
-	1, 1, 5, 1, 1, 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, 8, 7, 6, 8, 7, 6, 
+	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, 11, 8, 7, 16, 11, 
+	8, 7, 16, 11, 8, 7, 16, 11, 
+	8, 7, 16, 11, 8, 7, 6, 6, 
+	6, 1, 1, 1, 6, 8, 6, 8, 
+	7, 6, 8, 7, 6, 8, 7, 6, 
+	8, 7, 8, 11, 16, 16, 16, 8, 
+	11, 16, 16, 16, 8, 11, 16, 16, 
+	16, 8, 11, 16, 16, 16, 8, 11, 
+	11, 8, 7, 16, 11, 8, 7, 16, 
+	11, 8, 7, 16, 11, 8, 7, 16, 
+	11, 8, 7, 6, 6, 6, 1, 1, 
+	1, 6, 8, 6, 8, 7, 6, 8, 
+	7, 6, 8, 7, 6, 8, 7, 8, 
+	11, 16, 16, 16, 8, 11, 16, 16, 
+	16, 8, 11, 16, 16, 16, 8, 11, 
+	16, 16, 16, 5, 8, 8, 7, 16, 
+	11, 8, 7, 16, 11, 8, 7, 16, 
+	11, 8, 7, 16, 11, 8, 7, 6, 
+	6, 6, 1, 1, 1, 6, 8, 6, 
 	8, 7, 6, 8, 7, 6, 8, 7, 
-	15, 15, 16, 16, 16, 16, 15, 15, 
-	16, 16, 16, 16, 15, 15, 16, 16, 
-	16, 16, 15, 15, 16, 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, 8, 7, 6, 
-	8, 7, 6, 8, 7, 6, 8, 7, 
-	6, 8, 7, 15, 15, 16, 16, 16, 
-	16, 15, 15, 16, 16, 16, 16, 15, 
-	15, 16, 16, 16, 16, 15, 15, 16, 
-	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, 8, 
-	7, 6, 8, 7, 6, 8, 7, 6, 
-	8, 7, 6, 8, 7, 15, 15, 16, 
-	16, 16, 16, 15, 15, 16, 16, 16, 
-	16, 15, 15, 16, 16, 16, 16, 15, 
-	15, 16, 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, 8, 7, 6, 8, 7, 
+	6, 8, 7, 8, 11, 16, 16, 16, 
+	8, 11, 16, 16, 16, 8, 11, 16, 
+	16, 16, 8, 11, 16, 16, 16, 10, 
+	8, 5, 11, 8, 7, 16, 11, 8, 
+	7, 16, 11, 8, 7, 16, 11, 8, 
+	7, 16, 11, 8, 7, 6, 6, 6, 
+	1, 1, 1, 6, 8, 6, 8, 7, 
 	6, 8, 7, 6, 8, 7, 6, 8, 
-	7, 15, 15, 16, 16, 16, 16, 15, 
-	15, 16, 16, 16, 16, 15, 15, 16, 
-	16, 16, 16, 15, 15, 16, 16, 16, 
-	16, 15, 17, 15, 17, 10, 6, 1, 
-	1, 1, 6, 16, 8, 7, 6, 8, 
-	7, 6, 8, 7, 6, 8, 7, 6, 
+	7, 8, 11, 16, 16, 16, 8, 11, 
+	16, 16, 16, 8, 11, 16, 16, 16, 
+	8, 11, 16, 16, 16, 8, 16, 11, 
+	16, 10, 6, 1, 1, 1, 6, 16, 
 	8, 6, 6, 1, 1, 1, 6, 16
 };
 
 static const short _indic_syllable_machine_index_offsets[] = {
-	0, 2, 7, 11, 13, 18, 22, 24, 
-	29, 33, 35, 40, 44, 46, 52, 54, 
-	56, 62, 64, 66, 72, 74, 76, 82, 
-	84, 86, 92, 103, 109, 120, 126, 137, 
-	143, 154, 160, 171, 173, 178, 182, 184, 
-	189, 193, 195, 200, 204, 206, 211, 215, 
-	217, 223, 225, 227, 233, 235, 237, 243, 
-	245, 247, 253, 255, 257, 263, 274, 280, 
-	291, 297, 308, 314, 325, 331, 342, 344, 
-	349, 353, 355, 360, 364, 366, 371, 375, 
-	377, 382, 386, 388, 394, 396, 398, 404, 
-	406, 408, 414, 416, 418, 424, 426, 428, 
-	434, 445, 451, 462, 468, 479, 485, 496, 
-	502, 504, 509, 513, 515, 520, 524, 526, 
-	531, 535, 537, 542, 546, 548, 554, 556, 
-	558, 564, 566, 568, 574, 576, 578, 584, 
-	586, 588, 594, 605, 611, 622, 628, 639, 
-	645, 656, 662, 673, 684, 689, 694, 698, 
-	703, 707, 709, 714, 718, 720, 725, 729, 
-	731, 733, 739, 741, 743, 749, 751, 753, 
-	759, 761, 763, 769, 771, 773, 775, 795, 
-	811, 827, 842, 859, 875, 891, 906, 923, 
-	939, 955, 970, 987, 1003, 1019, 1034, 1051, 
-	1067, 1083, 1098, 1105, 1112, 1119, 1121, 1123, 
-	1125, 1132, 1141, 1150, 1158, 1165, 1174, 1182, 
-	1189, 1198, 1206, 1213, 1222, 1230, 1237, 1246, 
-	1254, 1270, 1286, 1303, 1320, 1337, 1354, 1370, 
-	1386, 1403, 1420, 1437, 1454, 1470, 1486, 1503, 
-	1520, 1537, 1554, 1570, 1586, 1603, 1620, 1637, 
-	1654, 1670, 1686, 1702, 1718, 1733, 1750, 1766, 
-	1782, 1797, 1814, 1830, 1846, 1861, 1878, 1894, 
-	1910, 1925, 1942, 1958, 1974, 1989, 1996, 2003, 
-	2010, 2012, 2014, 2016, 2023, 2032, 2041, 2049, 
-	2056, 2065, 2073, 2080, 2089, 2097, 2104, 2113, 
-	2121, 2128, 2137, 2145, 2161, 2177, 2194, 2211, 
-	2228, 2245, 2261, 2277, 2294, 2311, 2328, 2345, 
-	2361, 2377, 2394, 2411, 2428, 2445, 2461, 2477, 
-	2494, 2511, 2528, 2545, 2551, 2567, 2583, 2598, 
-	2615, 2631, 2647, 2662, 2679, 2695, 2711, 2726, 
-	2743, 2759, 2775, 2790, 2807, 2823, 2839, 2854, 
-	2861, 2868, 2875, 2877, 2879, 2881, 2888, 2897, 
-	2906, 2914, 2921, 2930, 2938, 2945, 2954, 2962, 
-	2969, 2978, 2986, 2993, 3002, 3010, 3026, 3042, 
-	3059, 3076, 3093, 3110, 3126, 3142, 3159, 3176, 
-	3193, 3210, 3226, 3242, 3259, 3276, 3293, 3310, 
-	3326, 3342, 3359, 3376, 3393, 3410, 3421, 3437, 
-	3443, 3459, 3475, 3490, 3507, 3523, 3539, 3554, 
-	3571, 3587, 3603, 3618, 3635, 3651, 3667, 3682, 
-	3699, 3715, 3731, 3746, 3753, 3760, 3767, 3769, 
-	3771, 3773, 3780, 3789, 3798, 3806, 3813, 3822, 
-	3830, 3837, 3846, 3854, 3861, 3870, 3878, 3885, 
-	3894, 3902, 3918, 3934, 3951, 3968, 3985, 4002, 
-	4018, 4034, 4051, 4068, 4085, 4102, 4118, 4134, 
-	4151, 4168, 4185, 4202, 4218, 4234, 4251, 4268, 
-	4285, 4302, 4318, 4336, 4352, 4370, 4381, 4388, 
-	4390, 4392, 4394, 4401, 4418, 4427, 4435, 4442, 
-	4451, 4459, 4466, 4475, 4483, 4490, 4499, 4507, 
-	4514, 4523, 4530, 4537, 4539, 4541, 4543, 4550
+	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, 703, 712, 720, 737, 
+	749, 758, 766, 783, 795, 804, 812, 829, 
+	841, 850, 858, 875, 887, 896, 904, 911, 
+	918, 925, 927, 929, 931, 938, 947, 954, 
+	963, 971, 978, 987, 995, 1002, 1011, 1019, 
+	1026, 1035, 1043, 1052, 1064, 1081, 1098, 1115, 
+	1124, 1136, 1153, 1170, 1187, 1196, 1208, 1225, 
+	1242, 1259, 1268, 1280, 1297, 1314, 1331, 1340, 
+	1352, 1364, 1373, 1381, 1398, 1410, 1419, 1427, 
+	1444, 1456, 1465, 1473, 1490, 1502, 1511, 1519, 
+	1536, 1548, 1557, 1565, 1572, 1579, 1586, 1588, 
+	1590, 1592, 1599, 1608, 1615, 1624, 1632, 1639, 
+	1648, 1656, 1663, 1672, 1680, 1687, 1696, 1704, 
+	1713, 1725, 1742, 1759, 1776, 1785, 1797, 1814, 
+	1831, 1848, 1857, 1869, 1886, 1903, 1920, 1929, 
+	1941, 1958, 1975, 1992, 1998, 2007, 2016, 2024, 
+	2041, 2053, 2062, 2070, 2087, 2099, 2108, 2116, 
+	2133, 2145, 2154, 2162, 2179, 2191, 2200, 2208, 
+	2215, 2222, 2229, 2231, 2233, 2235, 2242, 2251, 
+	2258, 2267, 2275, 2282, 2291, 2299, 2306, 2315, 
+	2323, 2330, 2339, 2347, 2356, 2368, 2385, 2402, 
+	2419, 2428, 2440, 2457, 2474, 2491, 2500, 2512, 
+	2529, 2546, 2563, 2572, 2584, 2601, 2618, 2635, 
+	2646, 2655, 2661, 2673, 2682, 2690, 2707, 2719, 
+	2728, 2736, 2753, 2765, 2774, 2782, 2799, 2811, 
+	2820, 2828, 2845, 2857, 2866, 2874, 2881, 2888, 
+	2895, 2897, 2899, 2901, 2908, 2917, 2924, 2933, 
+	2941, 2948, 2957, 2965, 2972, 2981, 2989, 2996, 
+	3005, 3013, 3022, 3034, 3051, 3068, 3085, 3094, 
+	3106, 3123, 3140, 3157, 3166, 3178, 3195, 3212, 
+	3229, 3238, 3250, 3267, 3284, 3301, 3310, 3327, 
+	3339, 3356, 3367, 3374, 3376, 3378, 3380, 3387, 
+	3404, 3413, 3420, 3427, 3429, 3431, 3433, 3440
 };
 
 static const short _indic_syllable_machine_indicies[] = {
-	1, 0, 2, 2, 3, 1, 0, 4, 
-	4, 3, 0, 3, 0, 5, 5, 6, 
-	1, 0, 7, 7, 6, 0, 6, 0, 
-	8, 8, 9, 1, 0, 10, 10, 9, 
-	0, 9, 0, 11, 11, 12, 1, 0, 
-	13, 13, 12, 0, 12, 0, 14, 0, 
-	0, 0, 1, 0, 15, 0, 16, 0, 
-	17, 11, 11, 12, 1, 0, 18, 0, 
-	19, 0, 20, 8, 8, 9, 1, 0, 
-	21, 0, 22, 0, 23, 5, 5, 6, 
-	1, 0, 24, 0, 25, 0, 26, 2, 
-	2, 3, 1, 0, 26, 2, 2, 3, 
-	1, 0, 0, 0, 0, 27, 0, 28, 
-	2, 2, 3, 1, 0, 28, 2, 2, 
-	3, 1, 0, 0, 0, 0, 29, 0, 
-	30, 2, 2, 3, 1, 0, 30, 2, 
-	2, 3, 1, 0, 0, 0, 0, 31, 
-	0, 32, 2, 2, 3, 1, 0, 32, 
-	2, 2, 3, 1, 0, 0, 0, 0, 
-	33, 0, 34, 2, 2, 3, 1, 0, 
-	34, 2, 2, 3, 1, 0, 0, 0, 
-	0, 35, 0, 37, 36, 38, 38, 39, 
-	37, 36, 40, 40, 39, 36, 39, 36, 
-	41, 41, 42, 37, 36, 43, 43, 42, 
-	36, 42, 36, 44, 44, 45, 37, 36, 
-	46, 46, 45, 36, 45, 36, 47, 47, 
-	48, 37, 36, 49, 49, 48, 36, 48, 
-	36, 50, 36, 36, 36, 37, 36, 51, 
-	36, 52, 36, 53, 47, 47, 48, 37, 
-	36, 54, 36, 55, 36, 56, 44, 44, 
-	45, 37, 36, 57, 36, 58, 36, 59, 
-	41, 41, 42, 37, 36, 60, 36, 61, 
-	36, 62, 38, 38, 39, 37, 36, 62, 
-	38, 38, 39, 37, 36, 36, 36, 36, 
-	63, 36, 64, 38, 38, 39, 37, 36, 
-	64, 38, 38, 39, 37, 36, 36, 36, 
-	36, 65, 36, 66, 38, 38, 39, 37, 
-	36, 66, 38, 38, 39, 37, 36, 36, 
-	36, 36, 67, 36, 68, 38, 38, 39, 
-	37, 36, 68, 38, 38, 39, 37, 36, 
-	36, 36, 36, 69, 36, 70, 38, 38, 
-	39, 37, 36, 70, 38, 38, 39, 37, 
-	36, 36, 36, 36, 71, 36, 73, 72, 
-	74, 74, 75, 73, 72, 77, 77, 75, 
-	76, 75, 76, 78, 78, 79, 73, 72, 
-	80, 80, 79, 72, 79, 72, 81, 81, 
-	82, 73, 72, 83, 83, 82, 72, 82, 
-	72, 84, 84, 85, 73, 72, 86, 86, 
-	85, 72, 85, 72, 87, 72, 72, 72, 
-	73, 72, 88, 72, 89, 72, 90, 84, 
-	84, 85, 73, 72, 91, 72, 92, 72, 
-	93, 81, 81, 82, 73, 72, 94, 72, 
-	95, 72, 96, 78, 78, 79, 73, 72, 
-	97, 72, 98, 72, 99, 74, 74, 75, 
-	73, 72, 99, 74, 74, 75, 73, 72, 
-	72, 72, 72, 100, 72, 101, 74, 74, 
-	75, 73, 72, 101, 74, 74, 75, 73, 
-	72, 72, 72, 72, 102, 72, 103, 74, 
-	74, 75, 73, 72, 103, 74, 74, 75, 
-	73, 72, 72, 72, 72, 104, 72, 105, 
-	74, 74, 75, 73, 72, 105, 74, 74, 
-	75, 73, 72, 72, 72, 72, 106, 72, 
-	107, 74, 74, 75, 73, 72, 109, 108, 
-	110, 110, 111, 109, 108, 112, 112, 111, 
-	108, 111, 108, 113, 113, 114, 109, 108, 
-	115, 115, 114, 108, 114, 108, 116, 116, 
-	117, 109, 108, 118, 118, 117, 108, 117, 
-	108, 119, 119, 120, 109, 108, 121, 121, 
-	120, 108, 120, 108, 122, 108, 108, 108, 
-	109, 108, 123, 108, 124, 108, 125, 119, 
-	119, 120, 109, 108, 126, 108, 127, 108, 
-	128, 116, 116, 117, 109, 108, 129, 108, 
-	130, 108, 131, 113, 113, 114, 109, 108, 
-	132, 108, 133, 108, 134, 110, 110, 111, 
-	109, 108, 134, 110, 110, 111, 109, 108, 
-	108, 108, 108, 135, 108, 136, 110, 110, 
-	111, 109, 108, 136, 110, 110, 111, 109, 
-	108, 108, 108, 108, 137, 108, 138, 110, 
-	110, 111, 109, 108, 138, 110, 110, 111, 
-	109, 108, 108, 108, 108, 139, 108, 140, 
-	110, 110, 111, 109, 108, 140, 110, 110, 
-	111, 109, 108, 108, 108, 108, 141, 108, 
-	142, 110, 110, 111, 109, 108, 142, 110, 
-	110, 111, 109, 108, 108, 108, 108, 143, 
-	108, 107, 74, 74, 75, 73, 72, 72, 
-	72, 72, 144, 72, 77, 77, 75, 1, 
-	0, 145, 145, 146, 1, 0, 4, 4, 
-	146, 0, 147, 147, 148, 149, 0, 150, 
-	150, 148, 0, 148, 0, 151, 151, 152, 
-	149, 0, 153, 153, 152, 0, 152, 0, 
-	154, 154, 155, 149, 0, 156, 156, 155, 
-	0, 155, 0, 149, 0, 157, 0, 0, 
-	0, 149, 0, 158, 0, 159, 0, 160, 
-	154, 154, 155, 149, 0, 161, 0, 162, 
-	0, 163, 151, 151, 152, 149, 0, 164, 
-	0, 165, 0, 166, 147, 147, 148, 149, 
-	0, 167, 0, 168, 0, 170, 169, 172, 
-	173, 174, 175, 176, 177, 75, 73, 171, 
-	178, 179, 179, 144, 171, 180, 181, 182, 
-	183, 184, 171, 186, 187, 188, 189, 3, 
-	1, 185, 190, 185, 185, 35, 185, 185, 
-	185, 191, 185, 192, 187, 193, 193, 3, 
-	1, 185, 190, 185, 185, 185, 185, 185, 
-	185, 191, 185, 187, 193, 193, 3, 1, 
-	185, 190, 185, 185, 185, 185, 185, 185, 
-	191, 185, 194, 185, 185, 185, 16, 195, 
-	185, 1, 185, 190, 185, 185, 185, 185, 
-	185, 194, 185, 196, 197, 198, 199, 3, 
-	1, 185, 190, 185, 185, 33, 185, 185, 
-	185, 191, 185, 200, 197, 201, 201, 3, 
-	1, 185, 190, 185, 185, 185, 185, 185, 
-	185, 191, 185, 197, 201, 201, 3, 1, 
-	185, 190, 185, 185, 185, 185, 185, 185, 
-	191, 185, 202, 185, 185, 185, 16, 203, 
-	185, 1, 185, 190, 185, 185, 185, 185, 
-	185, 202, 185, 204, 205, 206, 207, 3, 
-	1, 185, 190, 185, 185, 31, 185, 185, 
-	185, 191, 185, 208, 205, 209, 209, 3, 
-	1, 185, 190, 185, 185, 185, 185, 185, 
-	185, 191, 185, 205, 209, 209, 3, 1, 
-	185, 190, 185, 185, 185, 185, 185, 185, 
-	191, 185, 210, 185, 185, 185, 16, 211, 
-	185, 1, 185, 190, 185, 185, 185, 185, 
-	185, 210, 185, 212, 213, 214, 215, 3, 
-	1, 185, 190, 185, 185, 29, 185, 185, 
-	185, 191, 185, 216, 213, 217, 217, 3, 
-	1, 185, 190, 185, 185, 185, 185, 185, 
-	185, 191, 185, 213, 217, 217, 3, 1, 
-	185, 190, 185, 185, 185, 185, 185, 185, 
-	191, 185, 218, 185, 185, 185, 16, 219, 
-	185, 1, 185, 190, 185, 185, 185, 185, 
-	185, 218, 185, 220, 221, 222, 223, 3, 
-	1, 185, 190, 185, 185, 27, 185, 185, 
-	185, 191, 185, 224, 221, 225, 225, 3, 
-	1, 185, 190, 185, 185, 185, 185, 185, 
-	185, 191, 185, 221, 225, 225, 3, 1, 
-	185, 190, 185, 185, 185, 185, 185, 185, 
-	191, 185, 16, 226, 185, 1, 185, 190, 
-	185, 227, 227, 185, 1, 185, 190, 185, 
-	228, 185, 185, 229, 185, 190, 185, 190, 
-	185, 230, 185, 231, 185, 228, 185, 185, 
-	185, 185, 190, 185, 16, 185, 232, 232, 
-	3, 1, 185, 190, 185, 233, 25, 234, 
-	235, 6, 1, 185, 190, 185, 25, 234, 
-	235, 6, 1, 185, 190, 185, 234, 234, 
-	6, 1, 185, 190, 185, 236, 22, 237, 
-	238, 9, 1, 185, 190, 185, 22, 237, 
-	238, 9, 1, 185, 190, 185, 237, 237, 
-	9, 1, 185, 190, 185, 239, 19, 240, 
-	241, 12, 1, 185, 190, 185, 19, 240, 
-	241, 12, 1, 185, 190, 185, 240, 240, 
-	12, 1, 185, 190, 185, 242, 16, 227, 
-	243, 185, 1, 185, 190, 185, 16, 227, 
-	243, 185, 1, 185, 190, 185, 227, 244, 
-	185, 1, 185, 190, 185, 16, 185, 227, 
-	227, 185, 1, 185, 190, 185, 221, 225, 
-	225, 3, 1, 185, 190, 185, 220, 221, 
-	225, 225, 3, 1, 185, 190, 185, 185, 
-	185, 185, 185, 185, 191, 185, 220, 221, 
-	222, 225, 3, 1, 185, 190, 185, 185, 
-	27, 185, 185, 185, 191, 185, 218, 185, 
-	245, 185, 232, 232, 3, 1, 185, 190, 
-	185, 185, 185, 185, 185, 218, 185, 218, 
-	185, 185, 185, 227, 227, 185, 1, 185, 
-	190, 185, 185, 185, 185, 185, 218, 185, 
-	218, 185, 185, 185, 227, 246, 185, 1, 
-	185, 190, 185, 185, 185, 185, 185, 218, 
-	185, 218, 185, 245, 185, 227, 227, 185, 
-	1, 185, 190, 185, 185, 185, 185, 185, 
-	218, 185, 212, 213, 217, 217, 3, 1, 
-	185, 190, 185, 185, 185, 185, 185, 185, 
-	191, 185, 212, 213, 214, 217, 3, 1, 
-	185, 190, 185, 185, 29, 185, 185, 185, 
-	191, 185, 210, 185, 247, 185, 232, 232, 
-	3, 1, 185, 190, 185, 185, 185, 185, 
-	185, 210, 185, 210, 185, 185, 185, 227, 
-	227, 185, 1, 185, 190, 185, 185, 185, 
-	185, 185, 210, 185, 210, 185, 185, 185, 
-	227, 248, 185, 1, 185, 190, 185, 185, 
-	185, 185, 185, 210, 185, 210, 185, 247, 
-	185, 227, 227, 185, 1, 185, 190, 185, 
-	185, 185, 185, 185, 210, 185, 204, 205, 
-	209, 209, 3, 1, 185, 190, 185, 185, 
-	185, 185, 185, 185, 191, 185, 204, 205, 
-	206, 209, 3, 1, 185, 190, 185, 185, 
-	31, 185, 185, 185, 191, 185, 202, 185, 
-	249, 185, 232, 232, 3, 1, 185, 190, 
-	185, 185, 185, 185, 185, 202, 185, 202, 
-	185, 185, 185, 227, 227, 185, 1, 185, 
-	190, 185, 185, 185, 185, 185, 202, 185, 
-	202, 185, 185, 185, 227, 250, 185, 1, 
-	185, 190, 185, 185, 185, 185, 185, 202, 
-	185, 202, 185, 249, 185, 227, 227, 185, 
-	1, 185, 190, 185, 185, 185, 185, 185, 
-	202, 185, 196, 197, 201, 201, 3, 1, 
-	185, 190, 185, 185, 185, 185, 185, 185, 
-	191, 185, 196, 197, 198, 201, 3, 1, 
-	185, 190, 185, 185, 33, 185, 185, 185, 
-	191, 185, 194, 185, 251, 185, 232, 232, 
-	3, 1, 185, 190, 185, 185, 185, 185, 
-	185, 194, 185, 194, 185, 185, 185, 227, 
-	227, 185, 1, 185, 190, 185, 185, 185, 
-	185, 185, 194, 185, 194, 185, 185, 185, 
-	227, 252, 185, 1, 185, 190, 185, 185, 
-	185, 185, 185, 194, 185, 194, 185, 251, 
-	185, 227, 227, 185, 1, 185, 190, 185, 
-	185, 185, 185, 185, 194, 185, 186, 187, 
-	193, 193, 3, 1, 185, 190, 185, 185, 
-	185, 185, 185, 185, 191, 185, 186, 187, 
-	188, 193, 3, 1, 185, 190, 185, 185, 
-	35, 185, 185, 185, 191, 185, 254, 255, 
-	256, 257, 39, 37, 253, 258, 253, 253, 
-	71, 253, 253, 253, 259, 253, 260, 255, 
-	261, 257, 39, 37, 253, 258, 253, 253, 
-	253, 253, 253, 253, 259, 253, 255, 261, 
-	257, 39, 37, 253, 258, 253, 253, 253, 
-	253, 253, 253, 259, 253, 262, 253, 253, 
-	253, 52, 263, 253, 37, 253, 258, 253, 
-	253, 253, 253, 253, 262, 253, 264, 265, 
-	266, 267, 39, 37, 253, 258, 253, 253, 
-	69, 253, 253, 253, 259, 253, 268, 265, 
-	269, 269, 39, 37, 253, 258, 253, 253, 
-	253, 253, 253, 253, 259, 253, 265, 269, 
-	269, 39, 37, 253, 258, 253, 253, 253, 
-	253, 253, 253, 259, 253, 270, 253, 253, 
-	253, 52, 271, 253, 37, 253, 258, 253, 
-	253, 253, 253, 253, 270, 253, 272, 273, 
-	274, 275, 39, 37, 253, 258, 253, 253, 
-	67, 253, 253, 253, 259, 253, 276, 273, 
-	277, 277, 39, 37, 253, 258, 253, 253, 
-	253, 253, 253, 253, 259, 253, 273, 277, 
-	277, 39, 37, 253, 258, 253, 253, 253, 
-	253, 253, 253, 259, 253, 278, 253, 253, 
-	253, 52, 279, 253, 37, 253, 258, 253, 
-	253, 253, 253, 253, 278, 253, 280, 281, 
-	282, 283, 39, 37, 253, 258, 253, 253, 
-	65, 253, 253, 253, 259, 253, 284, 281, 
-	285, 285, 39, 37, 253, 258, 253, 253, 
-	253, 253, 253, 253, 259, 253, 281, 285, 
-	285, 39, 37, 253, 258, 253, 253, 253, 
-	253, 253, 253, 259, 253, 286, 253, 253, 
-	253, 52, 287, 253, 37, 253, 258, 253, 
-	253, 253, 253, 253, 286, 253, 288, 289, 
-	290, 291, 39, 37, 253, 258, 253, 253, 
-	63, 253, 253, 253, 259, 253, 292, 289, 
-	293, 293, 39, 37, 253, 258, 253, 253, 
-	253, 253, 253, 253, 259, 253, 289, 293, 
-	293, 39, 37, 253, 258, 253, 253, 253, 
-	253, 253, 253, 259, 253, 52, 294, 253, 
-	37, 253, 258, 253, 295, 295, 253, 37, 
-	253, 258, 253, 296, 253, 253, 297, 253, 
-	258, 253, 258, 253, 298, 253, 299, 253, 
-	296, 253, 253, 253, 253, 258, 253, 52, 
-	253, 300, 300, 39, 37, 253, 258, 253, 
-	301, 61, 302, 303, 42, 37, 253, 258, 
-	253, 61, 302, 303, 42, 37, 253, 258, 
-	253, 302, 302, 42, 37, 253, 258, 253, 
-	304, 58, 305, 306, 45, 37, 253, 258, 
-	253, 58, 305, 306, 45, 37, 253, 258, 
-	253, 305, 305, 45, 37, 253, 258, 253, 
-	307, 55, 308, 309, 48, 37, 253, 258, 
-	253, 55, 308, 309, 48, 37, 253, 258, 
-	253, 308, 308, 48, 37, 253, 258, 253, 
-	310, 52, 295, 311, 253, 37, 253, 258, 
-	253, 52, 295, 311, 253, 37, 253, 258, 
-	253, 295, 312, 253, 37, 253, 258, 253, 
-	52, 253, 295, 295, 253, 37, 253, 258, 
-	253, 289, 293, 293, 39, 37, 253, 258, 
-	253, 288, 289, 293, 293, 39, 37, 253, 
-	258, 253, 253, 253, 253, 253, 253, 259, 
-	253, 288, 289, 290, 293, 39, 37, 253, 
-	258, 253, 253, 63, 253, 253, 253, 259, 
-	253, 286, 253, 313, 253, 300, 300, 39, 
-	37, 253, 258, 253, 253, 253, 253, 253, 
-	286, 253, 286, 253, 253, 253, 295, 295, 
-	253, 37, 253, 258, 253, 253, 253, 253, 
-	253, 286, 253, 286, 253, 253, 253, 295, 
-	314, 253, 37, 253, 258, 253, 253, 253, 
-	253, 253, 286, 253, 286, 253, 313, 253, 
-	295, 295, 253, 37, 253, 258, 253, 253, 
-	253, 253, 253, 286, 253, 280, 281, 285, 
-	285, 39, 37, 253, 258, 253, 253, 253, 
-	253, 253, 253, 259, 253, 280, 281, 282, 
-	285, 39, 37, 253, 258, 253, 253, 65, 
-	253, 253, 253, 259, 253, 278, 253, 315, 
-	253, 300, 300, 39, 37, 253, 258, 253, 
-	253, 253, 253, 253, 278, 253, 278, 253, 
-	253, 253, 295, 295, 253, 37, 253, 258, 
-	253, 253, 253, 253, 253, 278, 253, 278, 
-	253, 253, 253, 295, 316, 253, 37, 253, 
-	258, 253, 253, 253, 253, 253, 278, 253, 
-	278, 253, 315, 253, 295, 295, 253, 37, 
-	253, 258, 253, 253, 253, 253, 253, 278, 
-	253, 272, 273, 277, 277, 39, 37, 253, 
-	258, 253, 253, 253, 253, 253, 253, 259, 
-	253, 272, 273, 274, 277, 39, 37, 253, 
-	258, 253, 253, 67, 253, 253, 253, 259, 
-	253, 270, 253, 317, 253, 300, 300, 39, 
-	37, 253, 258, 253, 253, 253, 253, 253, 
-	270, 253, 270, 253, 253, 253, 295, 295, 
-	253, 37, 253, 258, 253, 253, 253, 253, 
-	253, 270, 253, 270, 253, 253, 253, 295, 
-	318, 253, 37, 253, 258, 253, 253, 253, 
-	253, 253, 270, 253, 270, 253, 317, 253, 
-	295, 295, 253, 37, 253, 258, 253, 253, 
-	253, 253, 253, 270, 253, 264, 265, 269, 
-	269, 39, 37, 253, 258, 253, 253, 253, 
-	253, 253, 253, 259, 253, 264, 265, 266, 
-	269, 39, 37, 253, 258, 253, 253, 69, 
-	253, 253, 253, 259, 253, 262, 253, 319, 
-	253, 300, 300, 39, 37, 253, 258, 253, 
-	253, 253, 253, 253, 262, 253, 262, 253, 
-	253, 253, 295, 295, 253, 37, 253, 258, 
-	253, 253, 253, 253, 253, 262, 253, 262, 
-	253, 253, 253, 295, 320, 253, 37, 253, 
-	258, 253, 253, 253, 253, 253, 262, 253, 
-	262, 253, 319, 253, 295, 295, 253, 37, 
-	253, 258, 253, 253, 253, 253, 253, 262, 
-	253, 70, 38, 38, 39, 37, 253, 254, 
-	255, 261, 257, 39, 37, 253, 258, 253, 
-	253, 253, 253, 253, 253, 259, 253, 322, 
-	175, 323, 323, 75, 73, 321, 178, 321, 
-	321, 321, 321, 321, 321, 182, 321, 175, 
-	323, 323, 75, 73, 321, 178, 321, 321, 
-	321, 321, 321, 321, 182, 321, 324, 321, 
-	321, 321, 89, 325, 321, 73, 321, 178, 
-	321, 321, 321, 321, 321, 324, 321, 326, 
-	327, 328, 329, 75, 73, 321, 178, 321, 
-	321, 106, 321, 321, 321, 182, 321, 330, 
-	327, 331, 331, 75, 73, 321, 178, 321, 
-	321, 321, 321, 321, 321, 182, 321, 327, 
-	331, 331, 75, 73, 321, 178, 321, 321, 
-	321, 321, 321, 321, 182, 321, 332, 321, 
-	321, 321, 89, 333, 321, 73, 321, 178, 
-	321, 321, 321, 321, 321, 332, 321, 334, 
-	335, 336, 337, 75, 73, 321, 178, 321, 
-	321, 104, 321, 321, 321, 182, 321, 338, 
-	335, 339, 339, 75, 73, 321, 178, 321, 
-	321, 321, 321, 321, 321, 182, 321, 335, 
-	339, 339, 75, 73, 321, 178, 321, 321, 
-	321, 321, 321, 321, 182, 321, 340, 321, 
-	321, 321, 89, 341, 321, 73, 321, 178, 
-	321, 321, 321, 321, 321, 340, 321, 342, 
-	343, 344, 345, 75, 73, 321, 178, 321, 
-	321, 102, 321, 321, 321, 182, 321, 346, 
-	343, 347, 347, 75, 73, 321, 178, 321, 
-	321, 321, 321, 321, 321, 182, 321, 343, 
-	347, 347, 75, 73, 321, 178, 321, 321, 
-	321, 321, 321, 321, 182, 321, 348, 321, 
-	321, 321, 89, 349, 321, 73, 321, 178, 
-	321, 321, 321, 321, 321, 348, 321, 350, 
-	351, 352, 353, 75, 73, 321, 178, 321, 
-	321, 100, 321, 321, 321, 182, 321, 354, 
-	351, 355, 355, 75, 73, 321, 178, 321, 
-	321, 321, 321, 321, 321, 182, 321, 351, 
-	355, 355, 75, 73, 321, 178, 321, 321, 
-	321, 321, 321, 321, 182, 321, 89, 356, 
-	321, 73, 321, 178, 321, 357, 357, 321, 
-	73, 321, 178, 321, 358, 321, 321, 359, 
-	321, 178, 321, 178, 321, 360, 321, 361, 
-	321, 358, 321, 321, 321, 321, 178, 321, 
-	89, 321, 362, 362, 75, 73, 321, 178, 
-	321, 363, 98, 364, 365, 79, 73, 321, 
-	178, 321, 98, 364, 365, 79, 73, 321, 
-	178, 321, 364, 364, 79, 73, 321, 178, 
-	321, 366, 95, 367, 368, 82, 73, 321, 
-	178, 321, 95, 367, 368, 82, 73, 321, 
-	178, 321, 367, 367, 82, 73, 321, 178, 
-	321, 369, 92, 370, 371, 85, 73, 321, 
-	178, 321, 92, 370, 371, 85, 73, 321, 
-	178, 321, 370, 370, 85, 73, 321, 178, 
-	321, 372, 89, 357, 373, 321, 73, 321, 
-	178, 321, 89, 357, 373, 321, 73, 321, 
-	178, 321, 357, 374, 321, 73, 321, 178, 
-	321, 89, 321, 357, 357, 321, 73, 321, 
-	178, 321, 351, 355, 355, 75, 73, 321, 
-	178, 321, 350, 351, 355, 355, 75, 73, 
-	321, 178, 321, 321, 321, 321, 321, 321, 
-	182, 321, 350, 351, 352, 355, 75, 73, 
-	321, 178, 321, 321, 100, 321, 321, 321, 
-	182, 321, 348, 321, 375, 321, 362, 362, 
-	75, 73, 321, 178, 321, 321, 321, 321, 
-	321, 348, 321, 348, 321, 321, 321, 357, 
-	357, 321, 73, 321, 178, 321, 321, 321, 
-	321, 321, 348, 321, 348, 321, 321, 321, 
-	357, 376, 321, 73, 321, 178, 321, 321, 
-	321, 321, 321, 348, 321, 348, 321, 375, 
-	321, 357, 357, 321, 73, 321, 178, 321, 
-	321, 321, 321, 321, 348, 321, 342, 343, 
-	347, 347, 75, 73, 321, 178, 321, 321, 
-	321, 321, 321, 321, 182, 321, 342, 343, 
-	344, 347, 75, 73, 321, 178, 321, 321, 
-	102, 321, 321, 321, 182, 321, 340, 321, 
-	377, 321, 362, 362, 75, 73, 321, 178, 
-	321, 321, 321, 321, 321, 340, 321, 340, 
-	321, 321, 321, 357, 357, 321, 73, 321, 
-	178, 321, 321, 321, 321, 321, 340, 321, 
-	340, 321, 321, 321, 357, 378, 321, 73, 
-	321, 178, 321, 321, 321, 321, 321, 340, 
-	321, 340, 321, 377, 321, 357, 357, 321, 
-	73, 321, 178, 321, 321, 321, 321, 321, 
-	340, 321, 334, 335, 339, 339, 75, 73, 
-	321, 178, 321, 321, 321, 321, 321, 321, 
-	182, 321, 334, 335, 336, 339, 75, 73, 
-	321, 178, 321, 321, 104, 321, 321, 321, 
-	182, 321, 332, 321, 379, 321, 362, 362, 
-	75, 73, 321, 178, 321, 321, 321, 321, 
-	321, 332, 321, 332, 321, 321, 321, 357, 
-	357, 321, 73, 321, 178, 321, 321, 321, 
-	321, 321, 332, 321, 332, 321, 321, 321, 
-	357, 380, 321, 73, 321, 178, 321, 321, 
-	321, 321, 321, 332, 321, 332, 321, 379, 
-	321, 357, 357, 321, 73, 321, 178, 321, 
-	321, 321, 321, 321, 332, 321, 326, 327, 
-	331, 331, 75, 73, 321, 178, 321, 321, 
-	321, 321, 321, 321, 182, 321, 326, 327, 
-	328, 331, 75, 73, 321, 178, 321, 321, 
-	106, 321, 321, 321, 182, 321, 324, 321, 
-	381, 321, 362, 362, 75, 73, 321, 178, 
-	321, 321, 321, 321, 321, 324, 321, 324, 
-	321, 321, 321, 357, 357, 321, 73, 321, 
-	178, 321, 321, 321, 321, 321, 324, 321, 
-	324, 321, 321, 321, 357, 382, 321, 73, 
-	321, 178, 321, 321, 321, 321, 321, 324, 
-	321, 324, 321, 381, 321, 357, 357, 321, 
-	73, 321, 178, 321, 321, 321, 321, 321, 
-	324, 321, 107, 74, 74, 75, 73, 383, 
-	383, 383, 383, 144, 383, 174, 175, 323, 
-	323, 75, 73, 321, 178, 321, 321, 321, 
-	321, 321, 321, 182, 321, 107, 74, 74, 
-	75, 73, 383, 385, 386, 387, 388, 111, 
-	109, 384, 389, 384, 384, 143, 384, 384, 
-	384, 390, 384, 391, 386, 388, 388, 111, 
-	109, 384, 389, 384, 384, 384, 384, 384, 
-	384, 390, 384, 386, 388, 388, 111, 109, 
-	384, 389, 384, 384, 384, 384, 384, 384, 
-	390, 384, 392, 384, 384, 384, 124, 393, 
-	384, 109, 384, 389, 384, 384, 384, 384, 
-	384, 392, 384, 394, 395, 396, 397, 111, 
-	109, 384, 389, 384, 384, 141, 384, 384, 
-	384, 390, 384, 398, 395, 399, 399, 111, 
-	109, 384, 389, 384, 384, 384, 384, 384, 
-	384, 390, 384, 395, 399, 399, 111, 109, 
-	384, 389, 384, 384, 384, 384, 384, 384, 
-	390, 384, 400, 384, 384, 384, 124, 401, 
-	384, 109, 384, 389, 384, 384, 384, 384, 
-	384, 400, 384, 402, 403, 404, 405, 111, 
-	109, 384, 389, 384, 384, 139, 384, 384, 
-	384, 390, 384, 406, 403, 407, 407, 111, 
-	109, 384, 389, 384, 384, 384, 384, 384, 
-	384, 390, 384, 403, 407, 407, 111, 109, 
-	384, 389, 384, 384, 384, 384, 384, 384, 
-	390, 384, 408, 384, 384, 384, 124, 409, 
-	384, 109, 384, 389, 384, 384, 384, 384, 
-	384, 408, 384, 410, 411, 412, 413, 111, 
-	109, 384, 389, 384, 384, 137, 384, 384, 
-	384, 390, 384, 414, 411, 415, 415, 111, 
-	109, 384, 389, 384, 384, 384, 384, 384, 
-	384, 390, 384, 411, 415, 415, 111, 109, 
-	384, 389, 384, 384, 384, 384, 384, 384, 
-	390, 384, 416, 384, 384, 384, 124, 417, 
-	384, 109, 384, 389, 384, 384, 384, 384, 
-	384, 416, 384, 418, 419, 420, 421, 111, 
-	109, 384, 389, 384, 384, 135, 384, 384, 
-	384, 390, 384, 422, 419, 423, 423, 111, 
-	109, 384, 389, 384, 384, 384, 384, 384, 
-	384, 390, 384, 419, 423, 423, 111, 109, 
-	384, 389, 384, 384, 384, 384, 384, 384, 
-	390, 384, 124, 424, 384, 109, 384, 389, 
-	384, 425, 425, 384, 109, 384, 389, 384, 
-	426, 384, 384, 427, 384, 389, 384, 389, 
-	384, 428, 384, 429, 384, 426, 384, 384, 
-	384, 384, 389, 384, 124, 384, 430, 430, 
-	111, 109, 384, 389, 384, 431, 133, 432, 
-	433, 114, 109, 384, 389, 384, 133, 432, 
-	433, 114, 109, 384, 389, 384, 432, 432, 
-	114, 109, 384, 389, 384, 434, 130, 435, 
-	436, 117, 109, 384, 389, 384, 130, 435, 
-	436, 117, 109, 384, 389, 384, 435, 435, 
-	117, 109, 384, 389, 384, 437, 127, 438, 
-	439, 120, 109, 384, 389, 384, 127, 438, 
-	439, 120, 109, 384, 389, 384, 438, 438, 
-	120, 109, 384, 389, 384, 440, 124, 425, 
-	441, 384, 109, 384, 389, 384, 124, 425, 
-	441, 384, 109, 384, 389, 384, 425, 442, 
-	384, 109, 384, 389, 384, 124, 384, 425, 
-	425, 384, 109, 384, 389, 384, 419, 423, 
-	423, 111, 109, 384, 389, 384, 418, 419, 
-	423, 423, 111, 109, 384, 389, 384, 384, 
-	384, 384, 384, 384, 390, 384, 418, 419, 
-	420, 423, 111, 109, 384, 389, 384, 384, 
-	135, 384, 384, 384, 390, 384, 416, 384, 
-	443, 384, 430, 430, 111, 109, 384, 389, 
-	384, 384, 384, 384, 384, 416, 384, 416, 
-	384, 384, 384, 425, 425, 384, 109, 384, 
-	389, 384, 384, 384, 384, 384, 416, 384, 
-	416, 384, 384, 384, 425, 444, 384, 109, 
-	384, 389, 384, 384, 384, 384, 384, 416, 
-	384, 416, 384, 443, 384, 425, 425, 384, 
-	109, 384, 389, 384, 384, 384, 384, 384, 
-	416, 384, 410, 411, 415, 415, 111, 109, 
-	384, 389, 384, 384, 384, 384, 384, 384, 
-	390, 384, 410, 411, 412, 415, 111, 109, 
-	384, 389, 384, 384, 137, 384, 384, 384, 
-	390, 384, 408, 384, 445, 384, 430, 430, 
-	111, 109, 384, 389, 384, 384, 384, 384, 
-	384, 408, 384, 408, 384, 384, 384, 425, 
-	425, 384, 109, 384, 389, 384, 384, 384, 
-	384, 384, 408, 384, 408, 384, 384, 384, 
-	425, 446, 384, 109, 384, 389, 384, 384, 
-	384, 384, 384, 408, 384, 408, 384, 445, 
-	384, 425, 425, 384, 109, 384, 389, 384, 
-	384, 384, 384, 384, 408, 384, 402, 403, 
-	407, 407, 111, 109, 384, 389, 384, 384, 
-	384, 384, 384, 384, 390, 384, 402, 403, 
-	404, 407, 111, 109, 384, 389, 384, 384, 
-	139, 384, 384, 384, 390, 384, 400, 384, 
-	447, 384, 430, 430, 111, 109, 384, 389, 
-	384, 384, 384, 384, 384, 400, 384, 400, 
-	384, 384, 384, 425, 425, 384, 109, 384, 
-	389, 384, 384, 384, 384, 384, 400, 384, 
-	400, 384, 384, 384, 425, 448, 384, 109, 
-	384, 389, 384, 384, 384, 384, 384, 400, 
-	384, 400, 384, 447, 384, 425, 425, 384, 
-	109, 384, 389, 384, 384, 384, 384, 384, 
-	400, 384, 394, 395, 399, 399, 111, 109, 
-	384, 389, 384, 384, 384, 384, 384, 384, 
-	390, 384, 394, 395, 396, 399, 111, 109, 
-	384, 389, 384, 384, 141, 384, 384, 384, 
-	390, 384, 392, 384, 449, 384, 430, 430, 
-	111, 109, 384, 389, 384, 384, 384, 384, 
-	384, 392, 384, 392, 384, 384, 384, 425, 
-	425, 384, 109, 384, 389, 384, 384, 384, 
-	384, 384, 392, 384, 392, 384, 384, 384, 
-	425, 450, 384, 109, 384, 389, 384, 384, 
-	384, 384, 384, 392, 384, 392, 384, 449, 
-	384, 425, 425, 384, 109, 384, 389, 384, 
-	384, 384, 384, 384, 392, 384, 385, 386, 
-	388, 388, 111, 109, 384, 389, 384, 384, 
-	384, 384, 384, 384, 390, 384, 172, 173, 
-	174, 175, 451, 323, 75, 73, 321, 178, 
-	179, 179, 144, 321, 321, 172, 182, 321, 
-	186, 452, 188, 189, 3, 1, 185, 190, 
-	185, 185, 35, 185, 185, 185, 191, 185, 
-	194, 173, 174, 175, 453, 454, 75, 149, 
-	185, 455, 185, 179, 144, 185, 185, 194, 
-	182, 185, 107, 456, 456, 75, 149, 185, 
-	190, 185, 185, 144, 185, 457, 185, 185, 
-	458, 185, 455, 185, 455, 185, 459, 185, 
-	231, 185, 457, 185, 185, 185, 185, 455, 
-	185, 194, 185, 251, 107, 460, 460, 146, 
-	149, 185, 190, 185, 185, 185, 185, 185, 
-	194, 185, 461, 168, 462, 463, 148, 149, 
-	185, 455, 185, 168, 462, 463, 148, 149, 
-	185, 455, 185, 462, 462, 148, 149, 185, 
-	455, 185, 464, 165, 465, 466, 152, 149, 
-	185, 455, 185, 165, 465, 466, 152, 149, 
-	185, 455, 185, 465, 465, 152, 149, 185, 
-	455, 185, 467, 162, 468, 469, 155, 149, 
-	185, 455, 185, 162, 468, 469, 155, 149, 
-	185, 455, 185, 468, 468, 155, 149, 185, 
-	455, 185, 470, 159, 471, 472, 185, 149, 
-	185, 455, 185, 159, 471, 472, 185, 149, 
-	185, 455, 185, 471, 471, 185, 149, 185, 
-	455, 185, 474, 473, 475, 475, 473, 170, 
-	473, 476, 473, 475, 475, 473, 170, 473, 
-	476, 473, 477, 473, 473, 478, 473, 476, 
-	473, 476, 473, 479, 473, 480, 473, 477, 
-	473, 473, 473, 473, 476, 473, 172, 383, 
-	383, 383, 383, 383, 383, 383, 383, 383, 
-	179, 383, 383, 383, 383, 172, 383, 0
+	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, 147, 
+	158, 159, 147, 161, 162, 163, 164, 4, 
+	1, 160, 165, 160, 160, 35, 160, 166, 
+	162, 167, 167, 4, 1, 160, 165, 160, 
+	162, 167, 167, 4, 1, 160, 165, 160, 
+	168, 160, 160, 160, 17, 169, 160, 1, 
+	160, 165, 160, 160, 160, 160, 160, 168, 
+	160, 170, 171, 172, 173, 4, 1, 160, 
+	165, 160, 160, 33, 160, 174, 171, 175, 
+	175, 4, 1, 160, 165, 160, 171, 175, 
+	175, 4, 1, 160, 165, 160, 176, 160, 
+	160, 160, 17, 177, 160, 1, 160, 165, 
+	160, 160, 160, 160, 160, 176, 160, 178, 
+	179, 180, 181, 4, 1, 160, 165, 160, 
+	160, 31, 160, 182, 179, 183, 183, 4, 
+	1, 160, 165, 160, 179, 183, 183, 4, 
+	1, 160, 165, 160, 184, 160, 160, 160, 
+	17, 185, 160, 1, 160, 165, 160, 160, 
+	160, 160, 160, 184, 160, 186, 187, 188, 
+	189, 4, 1, 160, 165, 160, 160, 29, 
+	160, 190, 187, 191, 191, 4, 1, 160, 
+	165, 160, 187, 191, 191, 4, 1, 160, 
+	165, 160, 192, 160, 160, 160, 17, 193, 
+	160, 1, 160, 165, 160, 160, 160, 160, 
+	160, 192, 160, 194, 195, 196, 197, 4, 
+	1, 160, 165, 160, 160, 27, 160, 198, 
+	195, 199, 199, 4, 1, 160, 165, 160, 
+	195, 199, 199, 4, 1, 160, 165, 160, 
+	17, 200, 160, 1, 160, 165, 160, 201, 
+	201, 160, 1, 160, 165, 160, 202, 160, 
+	160, 203, 160, 165, 160, 165, 160, 204, 
+	160, 205, 160, 202, 160, 160, 160, 160, 
+	165, 160, 17, 160, 201, 201, 160, 1, 
+	160, 165, 160, 201, 200, 160, 1, 160, 
+	165, 160, 206, 26, 207, 208, 7, 1, 
+	160, 165, 160, 26, 207, 208, 7, 1, 
+	160, 165, 160, 207, 207, 7, 1, 160, 
+	165, 160, 209, 23, 210, 211, 10, 1, 
+	160, 165, 160, 23, 210, 211, 10, 1, 
+	160, 165, 160, 210, 210, 10, 1, 160, 
+	165, 160, 212, 20, 213, 214, 13, 1, 
+	160, 165, 160, 20, 213, 214, 13, 1, 
+	160, 165, 160, 213, 213, 13, 1, 160, 
+	165, 160, 215, 17, 201, 216, 160, 1, 
+	160, 165, 160, 17, 201, 216, 160, 1, 
+	160, 165, 160, 194, 195, 199, 199, 4, 
+	1, 160, 165, 160, 194, 195, 196, 199, 
+	4, 1, 160, 165, 160, 160, 27, 160, 
+	192, 160, 217, 160, 201, 201, 160, 1, 
+	160, 165, 160, 160, 160, 160, 160, 192, 
+	160, 192, 160, 160, 160, 201, 201, 160, 
+	1, 160, 165, 160, 160, 160, 160, 160, 
+	192, 160, 192, 160, 160, 160, 201, 193, 
+	160, 1, 160, 165, 160, 160, 160, 160, 
+	160, 192, 160, 186, 187, 191, 191, 4, 
+	1, 160, 165, 160, 186, 187, 188, 191, 
+	4, 1, 160, 165, 160, 160, 29, 160, 
+	184, 160, 218, 160, 201, 201, 160, 1, 
+	160, 165, 160, 160, 160, 160, 160, 184, 
+	160, 184, 160, 160, 160, 201, 201, 160, 
+	1, 160, 165, 160, 160, 160, 160, 160, 
+	184, 160, 184, 160, 160, 160, 201, 185, 
+	160, 1, 160, 165, 160, 160, 160, 160, 
+	160, 184, 160, 178, 179, 183, 183, 4, 
+	1, 160, 165, 160, 178, 179, 180, 183, 
+	4, 1, 160, 165, 160, 160, 31, 160, 
+	176, 160, 219, 160, 201, 201, 160, 1, 
+	160, 165, 160, 160, 160, 160, 160, 176, 
+	160, 176, 160, 160, 160, 201, 201, 160, 
+	1, 160, 165, 160, 160, 160, 160, 160, 
+	176, 160, 176, 160, 160, 160, 201, 177, 
+	160, 1, 160, 165, 160, 160, 160, 160, 
+	160, 176, 160, 170, 171, 175, 175, 4, 
+	1, 160, 165, 160, 170, 171, 172, 175, 
+	4, 1, 160, 165, 160, 160, 33, 160, 
+	168, 160, 220, 160, 201, 201, 160, 1, 
+	160, 165, 160, 160, 160, 160, 160, 168, 
+	160, 168, 160, 160, 160, 201, 201, 160, 
+	1, 160, 165, 160, 160, 160, 160, 160, 
+	168, 160, 168, 160, 160, 160, 201, 169, 
+	160, 1, 160, 165, 160, 160, 160, 160, 
+	160, 168, 160, 161, 162, 167, 167, 4, 
+	1, 160, 165, 160, 161, 162, 163, 167, 
+	4, 1, 160, 165, 160, 160, 35, 160, 
+	222, 223, 224, 225, 40, 37, 221, 226, 
+	221, 221, 71, 221, 227, 223, 228, 225, 
+	40, 37, 221, 226, 221, 223, 228, 225, 
+	40, 37, 221, 226, 221, 229, 221, 221, 
+	221, 53, 230, 221, 37, 221, 226, 221, 
+	221, 221, 221, 221, 229, 221, 231, 232, 
+	233, 234, 40, 37, 221, 226, 221, 221, 
+	69, 221, 235, 232, 236, 236, 40, 37, 
+	221, 226, 221, 232, 236, 236, 40, 37, 
+	221, 226, 221, 237, 221, 221, 221, 53, 
+	238, 221, 37, 221, 226, 221, 221, 221, 
+	221, 221, 237, 221, 239, 240, 241, 242, 
+	40, 37, 221, 226, 221, 221, 67, 221, 
+	243, 240, 244, 244, 40, 37, 221, 226, 
+	221, 240, 244, 244, 40, 37, 221, 226, 
+	221, 245, 221, 221, 221, 53, 246, 221, 
+	37, 221, 226, 221, 221, 221, 221, 221, 
+	245, 221, 247, 248, 249, 250, 40, 37, 
+	221, 226, 221, 221, 65, 221, 251, 248, 
+	252, 252, 40, 37, 221, 226, 221, 248, 
+	252, 252, 40, 37, 221, 226, 221, 253, 
+	221, 221, 221, 53, 254, 221, 37, 221, 
+	226, 221, 221, 221, 221, 221, 253, 221, 
+	255, 256, 257, 258, 40, 37, 221, 226, 
+	221, 221, 63, 221, 259, 256, 260, 260, 
+	40, 37, 221, 226, 221, 256, 260, 260, 
+	40, 37, 221, 226, 221, 53, 261, 221, 
+	37, 221, 226, 221, 262, 262, 221, 37, 
+	221, 226, 221, 263, 221, 221, 264, 221, 
+	226, 221, 226, 221, 265, 221, 266, 221, 
+	263, 221, 221, 221, 221, 226, 221, 53, 
+	221, 262, 262, 221, 37, 221, 226, 221, 
+	262, 261, 221, 37, 221, 226, 221, 267, 
+	62, 268, 269, 43, 37, 221, 226, 221, 
+	62, 268, 269, 43, 37, 221, 226, 221, 
+	268, 268, 43, 37, 221, 226, 221, 270, 
+	59, 271, 272, 46, 37, 221, 226, 221, 
+	59, 271, 272, 46, 37, 221, 226, 221, 
+	271, 271, 46, 37, 221, 226, 221, 273, 
+	56, 274, 275, 49, 37, 221, 226, 221, 
+	56, 274, 275, 49, 37, 221, 226, 221, 
+	274, 274, 49, 37, 221, 226, 221, 276, 
+	53, 262, 277, 221, 37, 221, 226, 221, 
+	53, 262, 277, 221, 37, 221, 226, 221, 
+	255, 256, 260, 260, 40, 37, 221, 226, 
+	221, 255, 256, 257, 260, 40, 37, 221, 
+	226, 221, 221, 63, 221, 253, 221, 278, 
+	221, 262, 262, 221, 37, 221, 226, 221, 
+	221, 221, 221, 221, 253, 221, 253, 221, 
+	221, 221, 262, 262, 221, 37, 221, 226, 
+	221, 221, 221, 221, 221, 253, 221, 253, 
+	221, 221, 221, 262, 254, 221, 37, 221, 
+	226, 221, 221, 221, 221, 221, 253, 221, 
+	247, 248, 252, 252, 40, 37, 221, 226, 
+	221, 247, 248, 249, 252, 40, 37, 221, 
+	226, 221, 221, 65, 221, 245, 221, 279, 
+	221, 262, 262, 221, 37, 221, 226, 221, 
+	221, 221, 221, 221, 245, 221, 245, 221, 
+	221, 221, 262, 262, 221, 37, 221, 226, 
+	221, 221, 221, 221, 221, 245, 221, 245, 
+	221, 221, 221, 262, 246, 221, 37, 221, 
+	226, 221, 221, 221, 221, 221, 245, 221, 
+	239, 240, 244, 244, 40, 37, 221, 226, 
+	221, 239, 240, 241, 244, 40, 37, 221, 
+	226, 221, 221, 67, 221, 237, 221, 280, 
+	221, 262, 262, 221, 37, 221, 226, 221, 
+	221, 221, 221, 221, 237, 221, 237, 221, 
+	221, 221, 262, 262, 221, 37, 221, 226, 
+	221, 221, 221, 221, 221, 237, 221, 237, 
+	221, 221, 221, 262, 238, 221, 37, 221, 
+	226, 221, 221, 221, 221, 221, 237, 221, 
+	231, 232, 236, 236, 40, 37, 221, 226, 
+	221, 231, 232, 233, 236, 40, 37, 221, 
+	226, 221, 221, 69, 221, 229, 221, 281, 
+	221, 262, 262, 221, 37, 221, 226, 221, 
+	221, 221, 221, 221, 229, 221, 229, 221, 
+	221, 221, 262, 262, 221, 37, 221, 226, 
+	221, 221, 221, 221, 221, 229, 221, 229, 
+	221, 221, 221, 262, 230, 221, 37, 221, 
+	226, 221, 221, 221, 221, 221, 229, 221, 
+	70, 39, 39, 40, 37, 221, 222, 223, 
+	228, 225, 40, 37, 221, 226, 221, 283, 
+	151, 284, 284, 76, 73, 282, 154, 282, 
+	151, 284, 284, 76, 73, 282, 154, 282, 
+	285, 282, 282, 282, 90, 286, 282, 73, 
+	282, 154, 282, 282, 282, 282, 282, 285, 
+	282, 287, 288, 289, 290, 76, 73, 282, 
+	154, 282, 282, 106, 282, 291, 288, 292, 
+	292, 76, 73, 282, 154, 282, 288, 292, 
+	292, 76, 73, 282, 154, 282, 293, 282, 
+	282, 282, 90, 294, 282, 73, 282, 154, 
+	282, 282, 282, 282, 282, 293, 282, 295, 
+	296, 297, 298, 76, 73, 282, 154, 282, 
+	282, 104, 282, 299, 296, 300, 300, 76, 
+	73, 282, 154, 282, 296, 300, 300, 76, 
+	73, 282, 154, 282, 301, 282, 282, 282, 
+	90, 302, 282, 73, 282, 154, 282, 282, 
+	282, 282, 282, 301, 282, 303, 304, 305, 
+	306, 76, 73, 282, 154, 282, 282, 102, 
+	282, 307, 304, 308, 308, 76, 73, 282, 
+	154, 282, 304, 308, 308, 76, 73, 282, 
+	154, 282, 309, 282, 282, 282, 90, 310, 
+	282, 73, 282, 154, 282, 282, 282, 282, 
+	282, 309, 282, 311, 312, 313, 314, 76, 
+	73, 282, 154, 282, 282, 100, 282, 315, 
+	312, 316, 316, 76, 73, 282, 154, 282, 
+	312, 316, 316, 76, 73, 282, 154, 282, 
+	90, 317, 282, 73, 282, 154, 282, 318, 
+	318, 282, 73, 282, 154, 282, 319, 282, 
+	282, 320, 282, 154, 282, 154, 282, 321, 
+	282, 322, 282, 319, 282, 282, 282, 282, 
+	154, 282, 90, 282, 318, 318, 282, 73, 
+	282, 154, 282, 318, 317, 282, 73, 282, 
+	154, 282, 323, 99, 324, 325, 80, 73, 
+	282, 154, 282, 99, 324, 325, 80, 73, 
+	282, 154, 282, 324, 324, 80, 73, 282, 
+	154, 282, 326, 96, 327, 328, 83, 73, 
+	282, 154, 282, 96, 327, 328, 83, 73, 
+	282, 154, 282, 327, 327, 83, 73, 282, 
+	154, 282, 329, 93, 330, 331, 86, 73, 
+	282, 154, 282, 93, 330, 331, 86, 73, 
+	282, 154, 282, 330, 330, 86, 73, 282, 
+	154, 282, 332, 90, 318, 333, 282, 73, 
+	282, 154, 282, 90, 318, 333, 282, 73, 
+	282, 154, 282, 311, 312, 316, 316, 76, 
+	73, 282, 154, 282, 311, 312, 313, 316, 
+	76, 73, 282, 154, 282, 282, 100, 282, 
+	309, 282, 334, 282, 318, 318, 282, 73, 
+	282, 154, 282, 282, 282, 282, 282, 309, 
+	282, 309, 282, 282, 282, 318, 318, 282, 
+	73, 282, 154, 282, 282, 282, 282, 282, 
+	309, 282, 309, 282, 282, 282, 318, 310, 
+	282, 73, 282, 154, 282, 282, 282, 282, 
+	282, 309, 282, 303, 304, 308, 308, 76, 
+	73, 282, 154, 282, 303, 304, 305, 308, 
+	76, 73, 282, 154, 282, 282, 102, 282, 
+	301, 282, 335, 282, 318, 318, 282, 73, 
+	282, 154, 282, 282, 282, 282, 282, 301, 
+	282, 301, 282, 282, 282, 318, 318, 282, 
+	73, 282, 154, 282, 282, 282, 282, 282, 
+	301, 282, 301, 282, 282, 282, 318, 302, 
+	282, 73, 282, 154, 282, 282, 282, 282, 
+	282, 301, 282, 295, 296, 300, 300, 76, 
+	73, 282, 154, 282, 295, 296, 297, 300, 
+	76, 73, 282, 154, 282, 282, 104, 282, 
+	293, 282, 336, 282, 318, 318, 282, 73, 
+	282, 154, 282, 282, 282, 282, 282, 293, 
+	282, 293, 282, 282, 282, 318, 318, 282, 
+	73, 282, 154, 282, 282, 282, 282, 282, 
+	293, 282, 293, 282, 282, 282, 318, 294, 
+	282, 73, 282, 154, 282, 282, 282, 282, 
+	282, 293, 282, 287, 288, 292, 292, 76, 
+	73, 282, 154, 282, 287, 288, 289, 292, 
+	76, 73, 282, 154, 282, 282, 106, 282, 
+	285, 282, 337, 282, 318, 318, 282, 73, 
+	282, 154, 282, 282, 282, 282, 282, 285, 
+	282, 285, 282, 282, 282, 318, 318, 282, 
+	73, 282, 154, 282, 282, 282, 282, 282, 
+	285, 282, 285, 282, 282, 282, 318, 286, 
+	282, 73, 282, 154, 282, 282, 282, 282, 
+	282, 285, 282, 107, 75, 75, 76, 73, 
+	338, 338, 338, 338, 144, 338, 150, 151, 
+	284, 284, 76, 73, 282, 154, 282, 107, 
+	75, 75, 76, 73, 338, 340, 341, 342, 
+	343, 112, 109, 339, 344, 339, 339, 143, 
+	339, 345, 341, 343, 343, 112, 109, 339, 
+	344, 339, 341, 343, 343, 112, 109, 339, 
+	344, 339, 346, 339, 339, 339, 125, 347, 
+	339, 109, 339, 344, 339, 339, 339, 339, 
+	339, 346, 339, 348, 349, 350, 351, 112, 
+	109, 339, 344, 339, 339, 141, 339, 352, 
+	349, 353, 353, 112, 109, 339, 344, 339, 
+	349, 353, 353, 112, 109, 339, 344, 339, 
+	354, 339, 339, 339, 125, 355, 339, 109, 
+	339, 344, 339, 339, 339, 339, 339, 354, 
+	339, 356, 357, 358, 359, 112, 109, 339, 
+	344, 339, 339, 139, 339, 360, 357, 361, 
+	361, 112, 109, 339, 344, 339, 357, 361, 
+	361, 112, 109, 339, 344, 339, 362, 339, 
+	339, 339, 125, 363, 339, 109, 339, 344, 
+	339, 339, 339, 339, 339, 362, 339, 364, 
+	365, 366, 367, 112, 109, 339, 344, 339, 
+	339, 137, 339, 368, 365, 369, 369, 112, 
+	109, 339, 344, 339, 365, 369, 369, 112, 
+	109, 339, 344, 339, 370, 339, 339, 339, 
+	125, 371, 339, 109, 339, 344, 339, 339, 
+	339, 339, 339, 370, 339, 372, 373, 374, 
+	375, 112, 109, 339, 344, 339, 339, 135, 
+	339, 376, 373, 377, 377, 112, 109, 339, 
+	344, 339, 373, 377, 377, 112, 109, 339, 
+	344, 339, 125, 378, 339, 109, 339, 344, 
+	339, 379, 379, 339, 109, 339, 344, 339, 
+	380, 339, 339, 381, 339, 344, 339, 344, 
+	339, 382, 339, 383, 339, 380, 339, 339, 
+	339, 339, 344, 339, 125, 339, 379, 379, 
+	339, 109, 339, 344, 339, 379, 378, 339, 
+	109, 339, 344, 339, 384, 134, 385, 386, 
+	115, 109, 339, 344, 339, 134, 385, 386, 
+	115, 109, 339, 344, 339, 385, 385, 115, 
+	109, 339, 344, 339, 387, 131, 388, 389, 
+	118, 109, 339, 344, 339, 131, 388, 389, 
+	118, 109, 339, 344, 339, 388, 388, 118, 
+	109, 339, 344, 339, 390, 128, 391, 392, 
+	121, 109, 339, 344, 339, 128, 391, 392, 
+	121, 109, 339, 344, 339, 391, 391, 121, 
+	109, 339, 344, 339, 393, 125, 379, 394, 
+	339, 109, 339, 344, 339, 125, 379, 394, 
+	339, 109, 339, 344, 339, 372, 373, 377, 
+	377, 112, 109, 339, 344, 339, 372, 373, 
+	374, 377, 112, 109, 339, 344, 339, 339, 
+	135, 339, 370, 339, 395, 339, 379, 379, 
+	339, 109, 339, 344, 339, 339, 339, 339, 
+	339, 370, 339, 370, 339, 339, 339, 379, 
+	379, 339, 109, 339, 344, 339, 339, 339, 
+	339, 339, 370, 339, 370, 339, 339, 339, 
+	379, 371, 339, 109, 339, 344, 339, 339, 
+	339, 339, 339, 370, 339, 364, 365, 369, 
+	369, 112, 109, 339, 344, 339, 364, 365, 
+	366, 369, 112, 109, 339, 344, 339, 339, 
+	137, 339, 362, 339, 396, 339, 379, 379, 
+	339, 109, 339, 344, 339, 339, 339, 339, 
+	339, 362, 339, 362, 339, 339, 339, 379, 
+	379, 339, 109, 339, 344, 339, 339, 339, 
+	339, 339, 362, 339, 362, 339, 339, 339, 
+	379, 363, 339, 109, 339, 344, 339, 339, 
+	339, 339, 339, 362, 339, 356, 357, 361, 
+	361, 112, 109, 339, 344, 339, 356, 357, 
+	358, 361, 112, 109, 339, 344, 339, 339, 
+	139, 339, 354, 339, 397, 339, 379, 379, 
+	339, 109, 339, 344, 339, 339, 339, 339, 
+	339, 354, 339, 354, 339, 339, 339, 379, 
+	379, 339, 109, 339, 344, 339, 339, 339, 
+	339, 339, 354, 339, 354, 339, 339, 339, 
+	379, 355, 339, 109, 339, 344, 339, 339, 
+	339, 339, 339, 354, 339, 348, 349, 353, 
+	353, 112, 109, 339, 344, 339, 348, 349, 
+	350, 353, 112, 109, 339, 344, 339, 339, 
+	141, 339, 346, 339, 398, 339, 379, 379, 
+	339, 109, 339, 344, 339, 339, 339, 339, 
+	339, 346, 339, 346, 339, 339, 339, 379, 
+	379, 339, 109, 339, 344, 339, 339, 339, 
+	339, 339, 346, 339, 346, 339, 339, 339, 
+	379, 347, 339, 109, 339, 344, 339, 339, 
+	339, 339, 339, 346, 339, 340, 341, 343, 
+	343, 112, 109, 339, 344, 339, 148, 149, 
+	150, 151, 399, 284, 76, 73, 282, 154, 
+	155, 155, 144, 282, 282, 148, 282, 161, 
+	400, 163, 164, 4, 1, 160, 165, 160, 
+	160, 35, 160, 168, 149, 150, 151, 401, 
+	402, 76, 403, 160, 404, 160, 155, 144, 
+	160, 160, 168, 160, 107, 405, 405, 76, 
+	403, 160, 165, 160, 160, 144, 160, 406, 
+	160, 160, 407, 160, 404, 160, 404, 160, 
+	408, 160, 205, 160, 406, 160, 160, 160, 
+	160, 404, 160, 168, 160, 220, 107, 405, 
+	405, 76, 403, 160, 165, 160, 160, 160, 
+	160, 160, 168, 160, 410, 409, 411, 411, 
+	409, 146, 409, 412, 409, 411, 411, 409, 
+	146, 409, 412, 409, 413, 409, 409, 414, 
+	409, 412, 409, 412, 409, 415, 409, 416, 
+	409, 413, 409, 409, 409, 409, 412, 409, 
+	148, 338, 338, 338, 338, 338, 338, 338, 
+	338, 338, 155, 338, 338, 338, 338, 148, 
+	338, 0
 };
 
 static const short _indic_syllable_machine_trans_targs[] = {
-	166, 188, 2, 194, 3, 5, 197, 6, 
-	8, 200, 9, 11, 203, 12, 14, 15, 
-	187, 17, 18, 202, 20, 21, 199, 23, 
-	24, 196, 205, 208, 212, 214, 218, 220, 
-	224, 226, 230, 232, 166, 255, 37, 261, 
-	38, 40, 264, 41, 43, 267, 44, 46, 
-	270, 47, 49, 50, 254, 52, 53, 269, 
-	55, 56, 266, 58, 59, 263, 272, 275, 
-	279, 281, 285, 287, 291, 293, 297, 300, 
-	166, 321, 72, 327, 166, 73, 75, 330, 
-	76, 78, 333, 79, 81, 336, 82, 84, 
-	85, 320, 87, 88, 335, 90, 91, 332, 
-	93, 94, 329, 338, 341, 345, 347, 351, 
-	353, 357, 359, 363, 166, 389, 106, 395, 
-	107, 109, 398, 110, 112, 401, 113, 115, 
-	404, 116, 118, 119, 388, 121, 122, 403, 
-	124, 125, 400, 127, 128, 397, 406, 409, 
-	413, 415, 419, 421, 425, 427, 431, 433, 
-	366, 142, 444, 144, 447, 438, 145, 147, 
-	450, 148, 150, 453, 151, 154, 155, 455, 
-	157, 158, 452, 160, 161, 449, 163, 164, 
-	446, 166, 458, 166, 167, 234, 301, 303, 
-	365, 367, 323, 368, 434, 435, 340, 456, 
-	463, 166, 168, 170, 34, 233, 190, 207, 
-	169, 33, 171, 228, 172, 174, 32, 227, 
-	173, 31, 175, 222, 176, 178, 30, 221, 
-	177, 29, 179, 216, 180, 182, 28, 215, 
-	181, 27, 183, 210, 184, 186, 26, 209, 
-	185, 25, 193, 0, 189, 192, 191, 166, 
-	1, 195, 4, 22, 198, 7, 19, 201, 
-	10, 16, 204, 13, 206, 211, 213, 217, 
-	219, 223, 225, 229, 231, 166, 235, 237, 
-	69, 299, 257, 274, 236, 68, 238, 295, 
-	239, 241, 67, 294, 240, 66, 242, 289, 
-	243, 245, 65, 288, 244, 64, 246, 283, 
-	247, 249, 63, 282, 248, 62, 250, 277, 
-	251, 253, 61, 276, 252, 60, 260, 35, 
-	256, 259, 258, 166, 36, 262, 39, 57, 
-	265, 42, 54, 268, 45, 51, 271, 48, 
-	273, 278, 280, 284, 286, 290, 292, 296, 
-	298, 166, 302, 103, 304, 361, 305, 307, 
-	102, 360, 306, 101, 308, 355, 309, 311, 
-	100, 354, 310, 99, 312, 349, 313, 315, 
-	98, 348, 314, 97, 316, 343, 317, 319, 
-	96, 342, 318, 95, 326, 70, 322, 325, 
-	324, 166, 71, 328, 74, 92, 331, 77, 
-	89, 334, 80, 86, 337, 83, 339, 344, 
-	346, 350, 352, 356, 358, 362, 364, 166, 
-	166, 369, 371, 138, 137, 391, 408, 370, 
-	372, 429, 373, 375, 136, 428, 374, 135, 
-	376, 423, 377, 379, 134, 422, 378, 133, 
-	380, 417, 381, 383, 132, 416, 382, 131, 
-	384, 411, 385, 387, 130, 410, 386, 129, 
-	394, 104, 390, 393, 392, 166, 105, 396, 
-	108, 126, 399, 111, 123, 402, 114, 120, 
-	405, 117, 407, 412, 414, 418, 420, 424, 
-	426, 430, 432, 139, 436, 437, 443, 440, 
-	140, 439, 442, 441, 141, 445, 143, 162, 
-	448, 146, 159, 451, 149, 156, 454, 152, 
-	153, 166, 457, 165, 460, 459, 462, 461, 
-	166
+	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, 178, 182, 183, 187, 188, 
+	192, 193, 197, 198, 138, 221, 227, 36, 
+	228, 37, 39, 231, 40, 42, 234, 43, 
+	45, 237, 46, 48, 49, 220, 51, 52, 
+	236, 54, 55, 233, 57, 58, 230, 239, 
+	243, 244, 248, 249, 253, 254, 258, 260, 
+	138, 281, 287, 70, 288, 138, 71, 73, 
+	291, 74, 76, 294, 77, 79, 297, 80, 
+	82, 83, 280, 85, 86, 296, 88, 89, 
+	293, 91, 92, 290, 299, 303, 304, 308, 
+	309, 313, 314, 318, 138, 343, 349, 103, 
+	350, 104, 106, 353, 107, 109, 356, 110, 
+	112, 359, 113, 115, 116, 342, 118, 119, 
+	358, 121, 122, 355, 124, 125, 352, 361, 
+	365, 366, 370, 371, 375, 376, 380, 381, 
+	320, 138, 394, 138, 139, 200, 261, 263, 
+	319, 321, 283, 322, 382, 383, 392, 399, 
+	138, 140, 142, 33, 199, 162, 141, 32, 
+	143, 195, 144, 146, 31, 194, 145, 30, 
+	147, 190, 148, 150, 29, 189, 149, 28, 
+	151, 185, 152, 154, 27, 184, 153, 26, 
+	155, 180, 156, 158, 25, 179, 157, 1, 
+	165, 0, 161, 164, 163, 138, 168, 4, 
+	22, 171, 7, 19, 174, 10, 16, 177, 
+	13, 181, 186, 191, 196, 138, 201, 203, 
+	67, 259, 223, 202, 66, 204, 256, 205, 
+	207, 65, 255, 206, 64, 208, 251, 209, 
+	211, 63, 250, 210, 62, 212, 246, 213, 
+	215, 61, 245, 214, 60, 216, 241, 217, 
+	219, 59, 240, 218, 35, 226, 34, 222, 
+	225, 224, 138, 229, 38, 56, 232, 41, 
+	53, 235, 44, 50, 238, 47, 242, 247, 
+	252, 257, 138, 262, 100, 264, 316, 265, 
+	267, 99, 315, 266, 98, 268, 311, 269, 
+	271, 97, 310, 270, 96, 272, 306, 273, 
+	275, 95, 305, 274, 94, 276, 301, 277, 
+	279, 93, 300, 278, 69, 286, 68, 282, 
+	285, 284, 138, 289, 72, 90, 292, 75, 
+	87, 295, 78, 84, 298, 81, 302, 307, 
+	312, 317, 138, 138, 323, 325, 134, 133, 
+	345, 324, 326, 378, 327, 329, 132, 377, 
+	328, 131, 330, 373, 331, 333, 130, 372, 
+	332, 129, 334, 368, 335, 337, 128, 367, 
+	336, 127, 338, 363, 339, 341, 126, 362, 
+	340, 102, 348, 101, 344, 347, 346, 138, 
+	351, 105, 123, 354, 108, 120, 357, 111, 
+	117, 360, 114, 364, 369, 374, 379, 135, 
+	384, 385, 391, 386, 388, 136, 387, 390, 
+	389, 138, 393, 137, 396, 395, 398, 397, 
+	138
 };
 
 static const char _indic_syllable_machine_trans_actions[] = {
-	1, 0, 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, 2, 3, 0, 0, 2, 
+	1, 0, 2, 0, 2, 0, 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, 2, 
-	4, 0, 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, 2, 6, 2, 6, 2, 
-	6, 2, 6, 2, 7, 0, 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, 
+	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, 
-	6, 0, 2, 0, 2, 0, 0, 0, 
-	2, 0, 0, 2, 0, 0, 0, 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, 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, 
-	0, 2, 0, 0, 2, 0, 0, 2, 
-	0, 0, 2, 0, 2, 2, 2, 2, 
-	2, 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, 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, 
-	2, 17, 6, 0, 6, 6, 6, 0, 
-	0, 6, 6, 0, 6, 6, 6, 0, 
-	0, 6, 6, 0, 6, 6, 6, 0, 
-	0, 6, 6, 0, 6, 6, 6, 0, 
-	0, 6, 6, 0, 6, 0, 0, 0, 
-	0, 18, 0, 2, 0, 0, 2, 0, 
-	0, 2, 0, 0, 2, 0, 2, 2, 
-	2, 2, 2, 2, 2, 2, 2, 19, 
-	20, 2, 0, 0, 0, 0, 2, 2, 
+	6, 8, 0, 11, 2, 2, 6, 0, 
+	12, 12, 0, 2, 6, 2, 2, 0, 
+	13, 2, 0, 0, 2, 0, 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, 21, 0, 2, 
-	0, 0, 2, 0, 0, 2, 0, 0, 
-	2, 0, 2, 2, 2, 2, 2, 2, 
-	2, 2, 2, 0, 0, 22, 2, 0, 
-	0, 0, 0, 0, 0, 2, 0, 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, 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, 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
 };
@@ -937,10 +759,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, 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, 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, 
@@ -969,14 +791,6 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0
 };
 
@@ -998,10 +812,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, 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, 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, 
@@ -1030,14 +844,6 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0
 };
 
@@ -1046,67 +852,59 @@
 	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, 
+	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, 37, 37, 73, 73, 
-	77, 77, 73, 73, 73, 73, 73, 73, 
+	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, 109, 
-	109, 109, 109, 73, 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, 170, 0, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 254, 254, 254, 254, 254, 254, 
-	254, 254, 254, 254, 254, 254, 254, 254, 
-	254, 254, 254, 254, 254, 254, 254, 254, 
-	254, 254, 254, 254, 254, 254, 254, 254, 
-	254, 254, 254, 254, 254, 254, 254, 254, 
-	254, 254, 254, 254, 254, 254, 254, 254, 
-	254, 254, 254, 254, 254, 254, 254, 254, 
-	254, 254, 254, 254, 254, 254, 254, 254, 
-	254, 254, 254, 254, 254, 322, 322, 322, 
-	322, 322, 322, 322, 322, 322, 322, 322, 
-	322, 322, 322, 322, 322, 322, 322, 322, 
-	322, 322, 322, 322, 322, 322, 322, 322, 
-	322, 322, 322, 322, 322, 322, 322, 322, 
-	322, 322, 322, 322, 322, 322, 322, 322, 
-	322, 322, 322, 322, 322, 322, 322, 322, 
-	322, 322, 322, 322, 322, 322, 322, 322, 
-	322, 322, 322, 322, 322, 384, 322, 384, 
-	385, 385, 385, 385, 385, 385, 385, 385, 
-	385, 385, 385, 385, 385, 385, 385, 385, 
-	385, 385, 385, 385, 385, 385, 385, 385, 
-	385, 385, 385, 385, 385, 385, 385, 385, 
-	385, 385, 385, 385, 385, 385, 385, 385, 
-	385, 385, 385, 385, 385, 385, 385, 385, 
-	385, 385, 385, 385, 385, 385, 385, 385, 
-	385, 385, 385, 385, 385, 385, 385, 385, 
-	385, 385, 322, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	186, 186, 186, 186, 186, 186, 186, 186, 
-	474, 474, 474, 474, 474, 474, 474, 384
+	109, 109, 109, 109, 109, 109, 109, 73, 
+	1, 146, 0, 161, 161, 161, 161, 161, 
+	161, 161, 161, 161, 161, 161, 161, 161, 
+	161, 161, 161, 161, 161, 161, 161, 161, 
+	161, 161, 161, 161, 161, 161, 161, 161, 
+	161, 161, 161, 161, 161, 161, 161, 161, 
+	161, 161, 161, 161, 161, 161, 161, 161, 
+	161, 161, 161, 161, 161, 161, 161, 161, 
+	161, 161, 161, 161, 161, 161, 161, 161, 
+	222, 222, 222, 222, 222, 222, 222, 222, 
+	222, 222, 222, 222, 222, 222, 222, 222, 
+	222, 222, 222, 222, 222, 222, 222, 222, 
+	222, 222, 222, 222, 222, 222, 222, 222, 
+	222, 222, 222, 222, 222, 222, 222, 222, 
+	222, 222, 222, 222, 222, 222, 222, 222, 
+	222, 222, 222, 222, 222, 222, 222, 222, 
+	222, 222, 222, 222, 222, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 283, 
+	283, 283, 283, 283, 283, 283, 283, 339, 
+	283, 339, 340, 340, 340, 340, 340, 340, 
+	340, 340, 340, 340, 340, 340, 340, 340, 
+	340, 340, 340, 340, 340, 340, 340, 340, 
+	340, 340, 340, 340, 340, 340, 340, 340, 
+	340, 340, 340, 340, 340, 340, 340, 340, 
+	340, 340, 340, 340, 340, 340, 340, 340, 
+	340, 340, 340, 340, 340, 340, 340, 340, 
+	340, 340, 340, 340, 340, 340, 283, 161, 
+	161, 161, 161, 161, 161, 161, 161, 161, 
+	410, 410, 410, 410, 410, 410, 410, 339
 };
 
-static const int indic_syllable_machine_start = 166;
-static const int indic_syllable_machine_first_final = 166;
+static const int indic_syllable_machine_start = 138;
+static const int indic_syllable_machine_first_final = 138;
 static const int indic_syllable_machine_error = -1;
 
-static const int indic_syllable_machine_en_main = 166;
+static const int indic_syllable_machine_en_main = 138;
 
 
 #line 36 "hb-ot-shape-complex-indic-machine.rl"
@@ -1118,10 +916,9 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
-    for (unsigned int i = last; i < p+1; i++) \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
-    last = p+1; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
@@ -1129,11 +926,11 @@
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te, act;
+  unsigned int p, pe, eof, ts, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 1137 "hb-ot-shape-complex-indic-machine.hh"
+#line 934 "hb-ot-shape-complex-indic-machine.hh"
 	{
 	cs = indic_syllable_machine_start;
 	ts = 0;
@@ -1141,16 +938,15 @@
 	act = 0;
 	}
 
-#line 113 "hb-ot-shape-complex-indic-machine.rl"
+#line 112 "hb-ot-shape-complex-indic-machine.rl"
 
 
   p = 0;
   pe = eof = buffer->len;
 
-  unsigned int last = 0;
   unsigned int syllable_serial = 1;
   
-#line 1154 "hb-ot-shape-complex-indic-machine.hh"
+#line 950 "hb-ot-shape-complex-indic-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -1164,7 +960,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 1168 "hb-ot-shape-complex-indic-machine.hh"
+#line 964 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 	_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -1287,7 +1083,7 @@
 #line 88 "hb-ot-shape-complex-indic-machine.rl"
 	{act = 6;}
 	break;
-#line 1291 "hb-ot-shape-complex-indic-machine.hh"
+#line 1087 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 _again:
@@ -1296,7 +1092,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 1300 "hb-ot-shape-complex-indic-machine.hh"
+#line 1096 "hb-ot-shape-complex-indic-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -1312,7 +1108,7 @@
 
 	}
 
-#line 122 "hb-ot-shape-complex-indic-machine.rl"
+#line 120 "hb-ot-shape-complex-indic-machine.rl"
 
 }
 

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl	2018-10-19 23:02:01 UTC (rev 48949)
@@ -52,7 +52,6 @@
 RS    = 13;
 Repha = 15;
 Ra    = 16;
-CM    = 17;
 Symbol= 18;
 CS    = 19;
 
@@ -68,15 +67,16 @@
 syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}?;
 halant_group = (z?.H.(ZWJ.N?)?);
 final_halant_group = halant_group | H.ZWNJ;
-medial_group = CM?;
-halant_or_matra_group = (final_halant_group | (H.ZWJ)? matra_group{0,4});
+halant_or_matra_group = (final_halant_group | matra_group{0,4});
 
+complex_syllable_tail = (halant_group.cn){0,4} halant_or_matra_group syllable_tail;
 
-consonant_syllable =	(Repha|CS)? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
-vowel_syllable =	reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail);
-standalone_cluster =	((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} 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);
+standalone_cluster =	((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? complex_syllable_tail;
 symbol_cluster = 	symbol syllable_tail;
-broken_cluster =	reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
+broken_cluster =	reph? n? complex_syllable_tail;
 other =			any;
 
 main := |*
@@ -93,10 +93,9 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
-    for (unsigned int i = last; i < p+1; i++) \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
-    last = p+1; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
@@ -104,7 +103,7 @@
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te, act;
+  unsigned int p, pe, eof, ts, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   %%{
@@ -115,7 +114,6 @@
   p = 0;
   pe = eof = buffer->len;
 
-  unsigned int last = 0;
   unsigned int syllable_serial = 1;
   %%{
     write exec;

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -95,12 +95,7 @@
  * Indic shaper.
  */
 
-struct feature_list_t {
-  hb_tag_t tag;
-  hb_ot_map_feature_flags_t flags;
-};
-
-static const feature_list_t
+static const hb_ot_map_feature_t
 indic_features[] =
 {
   /*
@@ -107,17 +102,17 @@
    * Basic features.
    * These features are applied in order, one at a time, after initial_reordering.
    */
-  {HB_TAG('n','u','k','t'), F_GLOBAL},
-  {HB_TAG('a','k','h','n'), F_GLOBAL},
-  {HB_TAG('r','p','h','f'), F_NONE},
-  {HB_TAG('r','k','r','f'), F_GLOBAL},
-  {HB_TAG('p','r','e','f'), F_NONE},
-  {HB_TAG('b','l','w','f'), F_NONE},
-  {HB_TAG('a','b','v','f'), F_NONE},
-  {HB_TAG('h','a','l','f'), F_NONE},
-  {HB_TAG('p','s','t','f'), F_NONE},
-  {HB_TAG('v','a','t','u'), F_GLOBAL},
-  {HB_TAG('c','j','c','t'), F_GLOBAL},
+  {HB_TAG('n','u','k','t'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('a','k','h','n'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('r','p','h','f'),        F_MANUAL_JOINERS},
+  {HB_TAG('r','k','r','f'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('p','r','e','f'),        F_MANUAL_JOINERS},
+  {HB_TAG('b','l','w','f'),        F_MANUAL_JOINERS},
+  {HB_TAG('a','b','v','f'),        F_MANUAL_JOINERS},
+  {HB_TAG('h','a','l','f'),        F_MANUAL_JOINERS},
+  {HB_TAG('p','s','t','f'),        F_MANUAL_JOINERS},
+  {HB_TAG('v','a','t','u'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('c','j','c','t'), F_GLOBAL_MANUAL_JOINERS},
   /*
    * Other features.
    * These features are applied all at once, after final_reordering.
@@ -124,13 +119,16 @@
    * Default Bengali font in Windows for example has intermixed
    * lookups for init,pres,abvs,blws features.
    */
-  {HB_TAG('i','n','i','t'), F_NONE},
-  {HB_TAG('p','r','e','s'), F_GLOBAL},
-  {HB_TAG('a','b','v','s'), F_GLOBAL},
-  {HB_TAG('b','l','w','s'), F_GLOBAL},
-  {HB_TAG('p','s','t','s'), F_GLOBAL},
-  {HB_TAG('h','a','l','n'), F_GLOBAL},
-  /* Positioning features, though we don't care about the types. */
+  {HB_TAG('i','n','i','t'),        F_MANUAL_JOINERS},
+  {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('h','a','l','n'), F_GLOBAL_MANUAL_JOINERS},
+  /*
+   * Positioning features.
+   * We don't care about the types.
+   */
   {HB_TAG('d','i','s','t'), F_GLOBAL},
   {HB_TAG('a','b','v','m'), F_GLOBAL},
   {HB_TAG('b','l','w','m'), F_GLOBAL},
@@ -158,12 +156,13 @@
   _BLWS,
   _PSTS,
   _HALN,
+
   _DIST,
   _ABVM,
   _BLWM,
 
   INDIC_NUM_FEATURES,
-  INDIC_BASIC_FEATURES = INIT /* Don't forget to update this! */
+  INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */
 };
 
 static void
@@ -191,26 +190,28 @@
   /* Do this before any lookups have been applied. */
   map->add_gsub_pause (setup_syllables);
 
-  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+  map->enable_feature (HB_TAG('l','o','c','l'));
   /* The Indic specs do not require ccmp, but we apply it here since if
    * there is a use of it, it's typically at the beginning. */
-  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+  map->enable_feature (HB_TAG('c','c','m','p'));
 
 
   unsigned int i = 0;
   map->add_gsub_pause (initial_reordering);
+
   for (; i < INDIC_BASIC_FEATURES; i++) {
-    map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
+    map->add_feature (indic_features[i]);
     map->add_gsub_pause (nullptr);
   }
+
   map->add_gsub_pause (final_reordering);
-  for (; i < INDIC_NUM_FEATURES; i++) {
-    map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
-  }
 
-  map->add_global_bool_feature (HB_TAG('c','a','l','t'));
-  map->add_global_bool_feature (HB_TAG('c','l','i','g'));
+  for (; i < INDIC_NUM_FEATURES; i++)
+    map->add_feature (indic_features[i]);
 
+  map->enable_feature (HB_TAG('c','a','l','t'));
+  map->enable_feature (HB_TAG('c','l','i','g'));
+
   map->add_gsub_pause (clear_syllables);
 }
 
@@ -217,7 +218,7 @@
 static void
 override_features_indic (hb_ot_shape_planner_t *plan)
 {
-  plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+  plan->map.disable_feature (HB_TAG('l','i','g','a'));
 }
 
 
@@ -273,6 +274,7 @@
   const indic_config_t *config;
 
   bool is_old_spec;
+  bool uniscribe_bug_compatible;
   mutable hb_atomic_int_t virama_glyph;
 
   would_substitute_feature_t rphf;
@@ -298,6 +300,7 @@
     }
 
   indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
+  indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible;
   indic_plan->virama_glyph.set_relaxed (-1);
 
   /* Use zero-context would_substitute() matching for new-spec of the main
@@ -328,6 +331,275 @@
   free (data);
 }
 
+static void
+_output_with_dotted_circle (hb_buffer_t *buffer)
+{
+  hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu);
+  _hb_glyph_info_reset_continuation (&dottedcircle);
+
+  buffer->next_glyph ();
+}
+
+static void
+preprocess_text_indic (const hb_ot_shape_plan_t *plan,
+		       hb_buffer_t              *buffer,
+		       hb_font_t                *font)
+{
+  /* UGLY UGLY UGLY business of adding dotted-circle in the middle of
+   * vowel-sequences that look like another vowel.  Data for each script
+   * collected from Unicode 11 book, tables named "Vowel Letters" with
+   * "Use" and "Do Not Use" columns.
+   *
+   * https://github.com/harfbuzz/harfbuzz/issues/1019
+   */
+  bool processed = false;
+  buffer->clear_output ();
+  unsigned int count = buffer->len;
+  switch ((unsigned) buffer->props.script)
+  {
+    case HB_SCRIPT_DEVANAGARI:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	switch (buffer->cur().codepoint)
+	{
+	  case 0x0905u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x093Au: case 0x093Bu: case 0x093Eu: case 0x0945u:
+	      case 0x0946u: case 0x0949u: case 0x094Au: case 0x094Bu:
+	      case 0x094Cu: case 0x094Fu: case 0x0956u: case 0x0957u:
+		matched = true;
+		break;
+	    }
+	    break;
+	  case 0x0906u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x093Au: case 0x0945u: case 0x0946u: case 0x0947u:
+	      case 0x0948u:
+		matched = true;
+		break;
+	    }
+	    break;
+	  case 0x0909u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x0941u:
+		matched = true;
+		break;
+	    }
+	    break;
+	  case 0x090Fu:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x0945u: case 0x0946u: case 0x0947u:
+		matched = true;
+		break;
+	    }
+	    break;
+	  case 0x0930u:
+	    if (0x094Du == buffer->cur(1).codepoint &&
+		buffer->idx + 2 < count &&
+	        0x0907u == buffer->cur(2).codepoint)
+	    {
+	      buffer->next_glyph ();
+	      buffer->next_glyph ();
+	      buffer->output_glyph (0x25CCu);
+	    }
+	    break;
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
+    case HB_SCRIPT_BENGALI:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	switch (buffer->cur().codepoint)
+	{
+	  case 0x0985u:
+	    matched = 0x09BE == buffer->cur(1).codepoint;
+	    break;
+	  case 0x098Bu:
+	    matched = 0x09C3 == buffer->cur(1).codepoint;
+	    break;
+	  case 0x098Cu:
+	    matched = 0x09E2 == buffer->cur(1).codepoint;
+	    break;
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
+    case HB_SCRIPT_GURMUKHI:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	switch (buffer->cur().codepoint)
+	{
+	  case 0x0A05u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x0A3Eu: case 0x0A48u: case 0x0A4Cu:
+		matched = true;
+		break;
+	    }
+	    break;
+	  case 0x0A72u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x0A3Fu: case 0x0A40u: case 0x0A47u:
+		matched = true;
+		break;
+	    }
+	    break;
+	  case 0x0A73u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x0A41u: case 0x0A42u: case 0x0A4Bu:
+		matched = true;
+		break;
+	    }
+	    break;
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
+    case HB_SCRIPT_GUJARATI:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	switch (buffer->cur().codepoint)
+	{
+	  case 0x0A85u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x0ABEu: case 0x0AC5u: case 0x0AC7u: case 0x0AC8u:
+	      case 0x0AC9u: case 0x0ACBu: case 0x0ACCu:
+		matched = true;
+		break;
+	    }
+	    break;
+	  case 0x0AC5u:
+	    matched = 0x0ABE == buffer->cur(1).codepoint;
+	    break;
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
+    case HB_SCRIPT_ORIYA:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	switch (buffer->cur().codepoint)
+	{
+	  case 0x0B05u:
+	    matched = 0x0B3E == buffer->cur(1).codepoint;
+	    break;
+	  case 0x0B0Fu: case 0x0B13u:
+	    matched = 0x0B57 == buffer->cur(1).codepoint;
+	    break;
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
+    case HB_SCRIPT_TELUGU:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	switch (buffer->cur().codepoint)
+	{
+	  case 0x0C12u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x0C4Cu: case 0x0C55u:
+		matched = true;
+		break;
+	    }
+	    break;
+	  case 0x0C3Fu: case 0x0C46u: case 0xC4Au:
+	    matched = 0x0C55 == buffer->cur(1).codepoint;
+	    break;
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
+    case HB_SCRIPT_KANNADA:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	switch (buffer->cur().codepoint)
+	{
+	  case 0x0C89u: case 0x0C8Bu:
+	    matched = 0x0CBE == buffer->cur(1).codepoint;
+	    break;
+	  case 0x0C92u:
+	    matched = 0x0CCC == buffer->cur(1).codepoint;
+	    break;
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
+    case HB_SCRIPT_MALAYALAM:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	switch (buffer->cur().codepoint)
+	{
+	  case 0x0D07u: case 0x0D09u:
+	    matched = 0x0D57 == buffer->cur(1).codepoint;
+	    break;
+	  case 0x0D0Eu:
+	    matched = 0x0D46 == buffer->cur(1).codepoint;
+	    break;
+	  case 0x0D12u:
+	    switch (buffer->cur(1).codepoint)
+	    {
+	      case 0x0D3Eu: case 0x0D57u:
+		matched = true;
+		break;
+	    }
+	    break;
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
+    default:
+      break;
+  }
+  if (processed)
+  {
+    if (buffer->idx < count)
+      buffer->next_glyph ();
+    if (likely (buffer->successful))
+      buffer->swap_buffers ();
+  }
+}
+
 static indic_position_t
 consonant_position_from_face (const indic_shape_plan_t *indic_plan,
 			      const hb_codepoint_t consonant,
@@ -717,7 +989,7 @@
     indic_position_t last_pos = POS_START;
     for (unsigned int i = start; i < end; i++)
     {
-      if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_H))))
+      if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | FLAG (OT_H))))
       {
 	info[i].indic_position() = last_pos;
 	if (unlikely (info[i].indic_category() == OT_H &&
@@ -913,10 +1185,12 @@
 				       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... */
 
-  if (hb_options ().uniscribe_bug_compatible)
+  if (indic_plan->uniscribe_bug_compatible)
   {
     /* For dotted-circle, this is what Uniscribe does:
      * If dotted-circle is the last glyph, it just does nothing.
@@ -958,7 +1232,8 @@
 		       hb_font_t *font,
 		       hb_buffer_t *buffer)
 {
-  /* 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;
@@ -1356,7 +1631,7 @@
        * Uniscribe doesn't do this.
        * TEST: U+0930,U+094D,U+0915,U+094B,U+094D
        */
-      if (!hb_options ().uniscribe_bug_compatible &&
+      if (!indic_plan->uniscribe_bug_compatible &&
 	  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) {
@@ -1462,7 +1737,7 @@
   /*
    * Finish off the clusters and go home!
    */
-  if (hb_options ().uniscribe_bug_compatible)
+  if (indic_plan->uniscribe_bug_compatible)
   {
     switch ((hb_tag_t) plan->props.script)
     {
@@ -1609,13 +1884,13 @@
   override_features_indic,
   data_create_indic,
   data_destroy_indic,
-  nullptr, /* preprocess_text */
+  preprocess_text_indic,
   nullptr, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
   decompose_indic,
   compose_indic,
   setup_masks_indic,
-  nullptr, /* disable_otl */
+  HB_TAG_NONE, /* gpos_tag */
   nullptr, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -29,9 +29,7 @@
 
 #include "hb.hh"
 
-
 #include "hb-ot-shape-complex.hh"
-#include "hb-ot-shape.hh" /* XXX Remove */
 
 
 /* buffer var allocations */
@@ -64,19 +62,17 @@
   OT_Coeng = 14, /* Khmer-style Virama. */
   OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
   OT_Ra = 16,
-  OT_CM = 17,  /* Consonant-Medial. */
+  OT_CM = 17,  /* Consonant-Medial; Unused by Indic shaper. */
   OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
   OT_CS = 19
 };
 
-#define MEDIAL_FLAGS (FLAG (OT_CM))
-
 /* Note:
  *
  * We treat Vowels and placeholders as if they were consonants.  This is safe because Vowels
  * cannot happen in a consonant syllable.  The plus side however is, we can call the
  * consonant syllable logic from the vowel syllable function and get it all right! */
-#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
 #define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
 
 
@@ -125,7 +121,7 @@
   INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA	= OT_Repha,
   INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED		= OT_X, /* Don't care. */
   INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED		= OT_CM,
-  INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA	= OT_N,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA	= OT_CM,
   INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER	= OT_CS,
   INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK		= OT_SM, /* https://github.com/harfbuzz/harfbuzz/issues/552 */
   INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER		= OT_Coeng,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -34,123 +34,193 @@
 
 #line 36 "hb-ot-shape-complex-khmer-machine.hh"
 static const unsigned char _khmer_syllable_machine_trans_keys[] = {
-	7u, 7u, 1u, 16u, 13u, 13u, 1u, 16u, 7u, 13u, 7u, 7u, 1u, 16u, 13u, 13u, 
-	1u, 16u, 7u, 13u, 1u, 16u, 3u, 14u, 3u, 14u, 5u, 14u, 3u, 14u, 5u, 14u, 
-	8u, 8u, 3u, 13u, 3u, 8u, 8u, 8u, 3u, 8u, 3u, 14u, 3u, 14u, 5u, 14u, 
-	3u, 14u, 5u, 14u, 8u, 8u, 3u, 13u, 3u, 8u, 8u, 8u, 3u, 8u, 3u, 14u, 
-	3u, 14u, 7u, 13u, 7u, 7u, 1u, 16u, 0
+	5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, 
+	5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 
+	5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 16u, 1u, 29u, 5u, 29u, 
+	5u, 29u, 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 5u, 26u, 
+	5u, 29u, 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, 
+	5u, 29u, 0
 };
 
 static const char _khmer_syllable_machine_key_spans[] = {
-	1, 16, 1, 16, 7, 1, 16, 1, 
-	16, 7, 16, 12, 12, 10, 12, 10, 
-	1, 11, 6, 1, 6, 12, 12, 10, 
-	12, 10, 1, 11, 6, 1, 6, 12, 
-	12, 7, 1, 16
+	22, 17, 22, 17, 16, 17, 22, 17, 
+	22, 17, 16, 17, 22, 17, 16, 17, 
+	22, 17, 22, 17, 22, 16, 29, 25, 
+	25, 25, 1, 18, 25, 25, 25, 22, 
+	25, 25, 1, 18, 25, 25, 16, 25, 
+	25
 };
 
 static const short _khmer_syllable_machine_index_offsets[] = {
-	0, 2, 19, 21, 38, 46, 48, 65, 
-	67, 84, 92, 109, 122, 135, 146, 159, 
-	170, 172, 184, 191, 193, 200, 213, 226, 
-	237, 250, 261, 263, 275, 282, 284, 291, 
-	304, 317, 325, 327
+	0, 23, 41, 64, 82, 99, 117, 140, 
+	158, 181, 199, 216, 234, 257, 275, 292, 
+	310, 333, 351, 374, 392, 415, 432, 462, 
+	488, 514, 540, 542, 561, 587, 613, 639, 
+	662, 688, 714, 716, 735, 761, 787, 804, 
+	830
 };
 
 static const char _khmer_syllable_machine_indicies[] = {
-	1, 0, 2, 2, 0, 0, 0, 0, 
+	1, 1, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 2, 
+	3, 0, 0, 0, 0, 4, 0, 1, 
+	1, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 3, 
+	0, 1, 1, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 2, 0, 3, 0, 4, 4, 0, 
+	0, 3, 0, 0, 0, 0, 4, 0, 
+	5, 5, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 4, 0, 1, 0, 
-	0, 0, 0, 0, 5, 0, 7, 6, 
-	8, 8, 6, 6, 6, 6, 6, 6, 
-	6, 6, 6, 6, 6, 6, 6, 8, 
-	6, 9, 6, 10, 10, 6, 6, 6, 
-	6, 6, 6, 6, 6, 6, 6, 6, 
-	6, 6, 10, 6, 7, 6, 6, 6, 
-	6, 6, 11, 6, 4, 4, 13, 12, 
-	14, 15, 7, 16, 12, 12, 4, 4, 
-	11, 17, 12, 4, 12, 19, 18, 20, 
-	21, 1, 22, 18, 18, 18, 18, 5, 
-	23, 18, 24, 18, 21, 21, 1, 22, 
-	18, 18, 18, 18, 18, 23, 18, 21, 
-	21, 1, 22, 18, 18, 18, 18, 18, 
-	23, 18, 25, 18, 21, 21, 1, 22, 
-	18, 18, 18, 18, 18, 26, 18, 21, 
-	21, 1, 22, 18, 18, 18, 18, 18, 
-	26, 18, 27, 18, 28, 18, 29, 18, 
-	18, 22, 18, 18, 18, 18, 3, 18, 
-	30, 18, 18, 18, 18, 22, 18, 22, 
-	18, 28, 18, 18, 18, 18, 22, 18, 
-	19, 18, 21, 21, 1, 22, 18, 18, 
-	18, 18, 18, 23, 18, 32, 31, 33, 
-	33, 7, 16, 31, 31, 31, 31, 31, 
-	34, 31, 33, 33, 7, 16, 31, 31, 
-	31, 31, 31, 34, 31, 35, 31, 33, 
-	33, 7, 16, 31, 31, 31, 31, 31, 
-	36, 31, 33, 33, 7, 16, 31, 31, 
-	31, 31, 31, 36, 31, 37, 31, 38, 
-	31, 39, 31, 31, 16, 31, 31, 31, 
-	31, 9, 31, 40, 31, 31, 31, 31, 
-	16, 31, 16, 31, 38, 31, 31, 31, 
-	31, 16, 31, 13, 31, 41, 33, 7, 
-	16, 31, 31, 31, 31, 11, 34, 31, 
-	13, 31, 33, 33, 7, 16, 31, 31, 
-	31, 31, 31, 34, 31, 7, 42, 42, 
-	42, 42, 42, 11, 42, 7, 42, 10, 
-	10, 42, 42, 42, 42, 42, 42, 42, 
-	42, 42, 42, 42, 42, 42, 10, 42, 
+	4, 0, 6, 6, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 6, 0, 7, 7, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 8, 0, 9, 9, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 10, 0, 0, 
+	0, 0, 4, 0, 9, 9, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 10, 0, 11, 11, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 12, 0, 
+	0, 0, 0, 4, 0, 11, 11, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 12, 0, 13, 
+	13, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 13, 0, 
+	15, 15, 14, 14, 14, 14, 14, 14, 
+	14, 14, 14, 14, 14, 14, 14, 14, 
+	16, 14, 15, 15, 17, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 17, 17, 
+	17, 17, 16, 17, 17, 17, 17, 18, 
+	17, 19, 19, 17, 17, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 17, 17, 
+	17, 18, 17, 20, 20, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 17, 17, 
+	17, 17, 20, 17, 21, 21, 17, 17, 
+	17, 17, 17, 17, 17, 17, 17, 17, 
+	17, 17, 17, 17, 22, 17, 23, 23, 
+	17, 17, 17, 17, 17, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 24, 17, 
+	17, 17, 17, 18, 17, 23, 23, 17, 
+	17, 17, 17, 17, 17, 17, 17, 17, 
+	17, 17, 17, 17, 17, 24, 17, 25, 
+	25, 17, 17, 17, 17, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 17, 26, 
+	17, 17, 17, 17, 18, 17, 25, 25, 
+	17, 17, 17, 17, 17, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 26, 17, 
+	15, 15, 17, 17, 17, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 17, 27, 
+	16, 17, 17, 17, 17, 18, 17, 28, 
+	28, 17, 17, 17, 17, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 28, 17, 
+	13, 13, 29, 29, 30, 30, 29, 29, 
+	29, 29, 2, 2, 29, 31, 29, 13, 
+	29, 29, 29, 29, 16, 20, 29, 29, 
+	29, 18, 24, 26, 22, 29, 33, 33, 
+	32, 32, 32, 32, 32, 32, 32, 34, 
+	32, 32, 32, 32, 32, 2, 3, 6, 
+	32, 32, 32, 4, 10, 12, 8, 32, 
+	35, 35, 32, 32, 32, 32, 32, 32, 
+	32, 36, 32, 32, 32, 32, 32, 32, 
+	3, 6, 32, 32, 32, 4, 10, 12, 
+	8, 32, 5, 5, 32, 32, 32, 32, 
+	32, 32, 32, 36, 32, 32, 32, 32, 
+	32, 32, 4, 6, 32, 32, 32, 32, 
+	32, 32, 8, 32, 6, 32, 7, 7, 
+	32, 32, 32, 32, 32, 32, 32, 36, 
+	32, 32, 32, 32, 32, 32, 8, 6, 
+	32, 37, 37, 32, 32, 32, 32, 32, 
+	32, 32, 36, 32, 32, 32, 32, 32, 
+	32, 10, 6, 32, 32, 32, 4, 32, 
+	32, 8, 32, 38, 38, 32, 32, 32, 
+	32, 32, 32, 32, 36, 32, 32, 32, 
+	32, 32, 32, 12, 6, 32, 32, 32, 
+	4, 10, 32, 8, 32, 35, 35, 32, 
+	32, 32, 32, 32, 32, 32, 34, 32, 
+	32, 32, 32, 32, 32, 3, 6, 32, 
+	32, 32, 4, 10, 12, 8, 32, 15, 
+	15, 39, 39, 39, 39, 39, 39, 39, 
+	39, 39, 39, 39, 39, 39, 39, 16, 
+	39, 39, 39, 39, 18, 39, 41, 41, 
+	40, 40, 40, 40, 40, 40, 40, 42, 
+	40, 40, 40, 40, 40, 40, 16, 20, 
+	40, 40, 40, 18, 24, 26, 22, 40, 
+	19, 19, 40, 40, 40, 40, 40, 40, 
+	40, 42, 40, 40, 40, 40, 40, 40, 
+	18, 20, 40, 40, 40, 40, 40, 40, 
+	22, 40, 20, 40, 21, 21, 40, 40, 
+	40, 40, 40, 40, 40, 42, 40, 40, 
+	40, 40, 40, 40, 22, 20, 40, 43, 
+	43, 40, 40, 40, 40, 40, 40, 40, 
+	42, 40, 40, 40, 40, 40, 40, 24, 
+	20, 40, 40, 40, 18, 40, 40, 22, 
+	40, 44, 44, 40, 40, 40, 40, 40, 
+	40, 40, 42, 40, 40, 40, 40, 40, 
+	40, 26, 20, 40, 40, 40, 18, 24, 
+	40, 22, 40, 28, 28, 39, 39, 39, 
+	39, 39, 39, 39, 39, 39, 39, 39, 
+	39, 39, 28, 39, 45, 45, 40, 40, 
+	40, 40, 40, 40, 40, 46, 40, 40, 
+	40, 40, 40, 27, 16, 20, 40, 40, 
+	40, 18, 24, 26, 22, 40, 41, 41, 
+	40, 40, 40, 40, 40, 40, 40, 46, 
+	40, 40, 40, 40, 40, 40, 16, 20, 
+	40, 40, 40, 18, 24, 26, 22, 40, 
 	0
 };
 
 static const char _khmer_syllable_machine_trans_targs[] = {
-	10, 14, 17, 20, 11, 21, 10, 24, 
-	27, 30, 31, 32, 10, 22, 33, 34, 
-	26, 35, 10, 12, 4, 0, 16, 3, 
-	13, 15, 1, 10, 18, 2, 19, 10, 
-	23, 5, 8, 25, 6, 10, 28, 7, 
-	29, 9, 10
+	22, 1, 30, 24, 25, 3, 26, 5, 
+	27, 7, 28, 9, 29, 23, 22, 11, 
+	32, 22, 33, 13, 34, 15, 35, 17, 
+	36, 19, 37, 40, 39, 22, 31, 38, 
+	22, 0, 10, 2, 4, 6, 8, 22, 
+	22, 12, 14, 16, 18, 20, 21
 };
 
 static const char _khmer_syllable_machine_trans_actions[] = {
-	1, 2, 2, 0, 2, 2, 3, 2, 
-	2, 0, 2, 2, 6, 2, 0, 0, 
-	0, 0, 7, 2, 0, 0, 0, 0, 
-	2, 2, 0, 8, 0, 0, 0, 9, 
-	2, 0, 0, 2, 0, 10, 0, 0, 
-	0, 0, 11
+	1, 0, 2, 2, 2, 0, 0, 0, 
+	2, 0, 2, 0, 2, 2, 3, 0, 
+	4, 5, 2, 0, 0, 0, 2, 0, 
+	2, 0, 2, 4, 4, 8, 9, 0, 
+	10, 0, 0, 0, 0, 0, 0, 11, 
+	12, 0, 0, 0, 0, 0, 0
 };
 
 static const char _khmer_syllable_machine_to_state_actions[] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 4, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 6, 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 _khmer_syllable_machine_from_state_actions[] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 5, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 7, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0
 };
 
 static const unsigned char _khmer_syllable_machine_eof_trans[] = {
-	1, 1, 1, 1, 1, 7, 7, 7, 
-	7, 7, 0, 19, 19, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 32, 32, 
-	32, 32, 32, 32, 32, 32, 32, 32, 
-	32, 43, 43, 43
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 15, 18, 18, 18, 18, 
+	18, 18, 18, 18, 18, 18, 0, 33, 
+	33, 33, 33, 33, 33, 33, 33, 40, 
+	41, 41, 41, 41, 41, 41, 40, 41, 
+	41
 };
 
-static const int khmer_syllable_machine_start = 10;
-static const int khmer_syllable_machine_first_final = 10;
+static const int khmer_syllable_machine_start = 22;
+static const int khmer_syllable_machine_first_final = 22;
 static const int khmer_syllable_machine_error = -1;
 
-static const int khmer_syllable_machine_en_main = 10;
+static const int khmer_syllable_machine_en_main = 22;
 
 
 #line 36 "hb-ot-shape-complex-khmer-machine.rl"
@@ -157,15 +227,14 @@
 
 
 
-#line 74 "hb-ot-shape-complex-khmer-machine.rl"
+#line 80 "hb-ot-shape-complex-khmer-machine.rl"
 
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
-    for (unsigned int i = last; i < p+1; i++) \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
-    last = p+1; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
@@ -173,11 +242,11 @@
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te, act HB_UNUSED;
+  unsigned int p, pe, eof, ts, te, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 181 "hb-ot-shape-complex-khmer-machine.hh"
+#line 250 "hb-ot-shape-complex-khmer-machine.hh"
 	{
 	cs = khmer_syllable_machine_start;
 	ts = 0;
@@ -185,16 +254,15 @@
 	act = 0;
 	}
 
-#line 95 "hb-ot-shape-complex-khmer-machine.rl"
+#line 100 "hb-ot-shape-complex-khmer-machine.rl"
 
 
   p = 0;
   pe = eof = buffer->len;
 
-  unsigned int last = 0;
   unsigned int syllable_serial = 1;
   
-#line 198 "hb-ot-shape-complex-khmer-machine.hh"
+#line 266 "hb-ot-shape-complex-khmer-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -204,11 +272,11 @@
 		goto _test_eof;
 _resume:
 	switch ( _khmer_syllable_machine_from_state_actions[cs] ) {
-	case 5:
+	case 7:
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 212 "hb-ot-shape-complex-khmer-machine.hh"
+#line 280 "hb-ot-shape-complex-khmer-machine.hh"
 	}
 
 	_keys = _khmer_syllable_machine_trans_keys + (cs<<1);
@@ -231,47 +299,63 @@
 	{te = p+1;}
 	break;
 	case 8:
-#line 68 "hb-ot-shape-complex-khmer-machine.rl"
-	{te = p+1;{ found_syllable (consonant_syllable); }}
+#line 76 "hb-ot-shape-complex-khmer-machine.rl"
+	{te = p+1;{ found_syllable (non_khmer_cluster); }}
 	break;
 	case 10:
-#line 69 "hb-ot-shape-complex-khmer-machine.rl"
-	{te = p+1;{ found_syllable (broken_cluster); }}
-	break;
-	case 6:
-#line 70 "hb-ot-shape-complex-khmer-machine.rl"
-	{te = p+1;{ found_syllable (non_khmer_cluster); }}
-	break;
-	case 7:
-#line 68 "hb-ot-shape-complex-khmer-machine.rl"
+#line 74 "hb-ot-shape-complex-khmer-machine.rl"
 	{te = p;p--;{ found_syllable (consonant_syllable); }}
 	break;
-	case 9:
-#line 69 "hb-ot-shape-complex-khmer-machine.rl"
+	case 12:
+#line 75 "hb-ot-shape-complex-khmer-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
 	case 11:
-#line 70 "hb-ot-shape-complex-khmer-machine.rl"
+#line 76 "hb-ot-shape-complex-khmer-machine.rl"
 	{te = p;p--;{ found_syllable (non_khmer_cluster); }}
 	break;
 	case 1:
-#line 68 "hb-ot-shape-complex-khmer-machine.rl"
+#line 74 "hb-ot-shape-complex-khmer-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
 	break;
-	case 3:
-#line 69 "hb-ot-shape-complex-khmer-machine.rl"
+	case 5:
+#line 75 "hb-ot-shape-complex-khmer-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
 	break;
-#line 266 "hb-ot-shape-complex-khmer-machine.hh"
+	case 3:
+#line 1 "NONE"
+	{	switch( act ) {
+	case 2:
+	{{p = ((te))-1;} found_syllable (broken_cluster); }
+	break;
+	case 3:
+	{{p = ((te))-1;} found_syllable (non_khmer_cluster); }
+	break;
 	}
+	}
+	break;
+	case 4:
+#line 1 "NONE"
+	{te = p+1;}
+#line 75 "hb-ot-shape-complex-khmer-machine.rl"
+	{act = 2;}
+	break;
+	case 9:
+#line 1 "NONE"
+	{te = p+1;}
+#line 76 "hb-ot-shape-complex-khmer-machine.rl"
+	{act = 3;}
+	break;
+#line 350 "hb-ot-shape-complex-khmer-machine.hh"
+	}
 
 _again:
 	switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
-	case 4:
+	case 6:
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 275 "hb-ot-shape-complex-khmer-machine.hh"
+#line 359 "hb-ot-shape-complex-khmer-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -287,7 +371,7 @@
 
 	}
 
-#line 104 "hb-ot-shape-complex-khmer-machine.rl"
+#line 108 "hb-ot-shape-complex-khmer-machine.rl"
 
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer-machine.rl	2018-10-19 23:02:01 UTC (rev 48949)
@@ -40,28 +40,34 @@
 # Same order as enum khmer_category_t.  Not sure how to avoid duplication.
 C    = 1;
 V    = 2;
-N    = 3;
 ZWNJ = 5;
 ZWJ  = 6;
-M    = 7;
-SM   = 8;
 PLACEHOLDER = 11;
 DOTTEDCIRCLE = 12;
-RS    = 13;
-Coeng = 14;
-Ra    = 16;
+Coeng= 14;
+Ra   = 16;
+Robatic = 20;
+Xgroup  = 21;
+Ygroup  = 22;
+VAbv = 26;
+VBlw = 27;
+VPre = 28;
+VPst = 29;
 
-c = (C | Ra | V);		# is_consonant
-n = ((ZWNJ?.RS)? (N.N?)?);	# is_consonant_modifier
-z = ZWJ|ZWNJ;			# is_joiner
+c = (C | Ra | V);
+cn = c.((ZWJ|ZWNJ)?.Robatic)?;
+joiner = (ZWJ | ZWNJ);
+xgroup = (joiner*.Xgroup)*;
+ygroup = Ygroup*;
 
-cn = c.n?;
-matra_group = z?.M.N?;
-syllable_tail = (SM.SM?)?;
+# This grammar was experimentally extracted from what Uniscribe allows.
 
+matra_group = VPre? xgroup VBlw? xgroup (joiner?.VAbv)? xgroup VPst?;
+syllable_tail = xgroup matra_group xgroup (Coeng.c)? ygroup;
 
-broken_cluster =	n? (Coeng.cn)* matra_group* (Coeng.cn)? syllable_tail;
-consonant_syllable =	(c|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster;
+
+broken_cluster =	(Coeng.cn)* syllable_tail;
+consonant_syllable =	(cn|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster;
 other =			any;
 
 main := |*
@@ -75,10 +81,9 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
-    for (unsigned int i = last; i < p+1; i++) \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
-    last = p+1; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
@@ -86,7 +91,7 @@
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te, act HB_UNUSED;
+  unsigned int p, pe, eof, ts, te, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   %%{
@@ -97,7 +102,6 @@
   p = 0;
   pe = eof = buffer->len;
 
-  unsigned int last = 0;
   unsigned int syllable_serial = 1;
   %%{
     write exec;

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -32,12 +32,7 @@
  * Khmer shaper.
  */
 
-struct feature_list_t {
-  hb_tag_t tag;
-  hb_ot_map_feature_flags_t flags;
-};
-
-static const feature_list_t
+static const hb_ot_map_feature_t
 khmer_features[] =
 {
   /*
@@ -44,20 +39,23 @@
    * Basic features.
    * These features are applied in order, one at a time, after reordering.
    */
-  {HB_TAG('p','r','e','f'), F_NONE},
-  {HB_TAG('b','l','w','f'), F_NONE},
-  {HB_TAG('a','b','v','f'), F_NONE},
-  {HB_TAG('p','s','t','f'), F_NONE},
-  {HB_TAG('c','f','a','r'), F_NONE},
+  {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS},
+  {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS},
+  {HB_TAG('a','b','v','f'), F_MANUAL_JOINERS},
+  {HB_TAG('p','s','t','f'), F_MANUAL_JOINERS},
+  {HB_TAG('c','f','a','r'), F_MANUAL_JOINERS},
   /*
    * Other features.
    * These features are applied all at once.
    */
-  {HB_TAG('p','r','e','s'), F_GLOBAL},
-  {HB_TAG('a','b','v','s'), F_GLOBAL},
-  {HB_TAG('b','l','w','s'), F_GLOBAL},
-  {HB_TAG('p','s','t','s'), F_GLOBAL},
-  /* Positioning features, though we don't care about the types. */
+  {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
+  /*
+   * Positioning features.
+   * We don't care about the types.
+   */
   {HB_TAG('d','i','s','t'), F_GLOBAL},
   {HB_TAG('a','b','v','m'), F_GLOBAL},
   {HB_TAG('b','l','w','m'), F_GLOBAL},
@@ -77,12 +75,13 @@
   _ABVS,
   _BLWS,
   _PSTS,
+
   _DIST,
   _ABVM,
   _BLWM,
 
   KHMER_NUM_FEATURES,
-  KHMER_BASIC_FEATURES = _PRES /* Don't forget to update this! */
+  KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */
 };
 
 static void
@@ -117,22 +116,20 @@
    *
    * https://github.com/harfbuzz/harfbuzz/issues/974
    */
-  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
-  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+  map->enable_feature (HB_TAG('l','o','c','l'));
+  map->enable_feature (HB_TAG('c','c','m','p'));
 
   unsigned int i = 0;
-  for (; i < KHMER_BASIC_FEATURES; i++) {
-    map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
-  }
+  for (; i < KHMER_BASIC_FEATURES; i++)
+    map->add_feature (khmer_features[i]);
 
   map->add_gsub_pause (clear_syllables);
 
-  for (; i < KHMER_NUM_FEATURES; i++) {
-    map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
-  }
+  for (; i < KHMER_NUM_FEATURES; i++)
+    map->add_feature (khmer_features[i]);
 
-  map->add_global_bool_feature (HB_TAG('c','a','l','t'));
-  map->add_global_bool_feature (HB_TAG('c','l','i','g'));
+  map->enable_feature (HB_TAG('c','a','l','t'));
+  map->enable_feature (HB_TAG('c','l','i','g'));
 
 }
 
@@ -142,10 +139,10 @@
   /* Uniscribe does not apply 'kern' in Khmer. */
   if (hb_options ().uniscribe_bug_compatible)
   {
-    plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+    plan->map.disable_feature (HB_TAG('k','e','r','n'));
   }
 
-  plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+  plan->map.disable_feature (HB_TAG('l','i','g','a'));
 }
 
 
@@ -244,7 +241,6 @@
 		   hb_font_t                *font HB_UNUSED)
 {
   HB_BUFFER_ALLOCATE_VAR (buffer, khmer_category);
-  HB_BUFFER_ALLOCATE_VAR (buffer, khmer_position);
 
   /* We cannot setup masks here.  We save information about characters
    * and setup masks later on in a pause-callback. */
@@ -333,7 +329,7 @@
     }
 
     /* Reorder left matra piece. */
-    else if (info[i].khmer_position() == POS_PRE_M)
+    else if (info[i].khmer_category() == OT_VPre)
     {
       /* Move to the start. */
       buffer->merge_clusters (start, i + 1);
@@ -435,7 +431,6 @@
     initial_reordering_syllable (plan, font->face, buffer, start, end);
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
-  HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_position);
 }
 
 static void
@@ -501,7 +496,7 @@
   decompose_khmer,
   compose_khmer,
   setup_masks_khmer,
-  nullptr, /* disable_otl */
+  HB_TAG_NONE, /* gpos_tag */
   nullptr, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -34,43 +34,22 @@
 
 /* buffer var allocations */
 #define khmer_category() indic_category() /* khmer_category_t */
-#define khmer_position() indic_position() /* khmer_position_t */
 
 
-typedef indic_category_t khmer_category_t;
-typedef indic_position_t khmer_position_t;
-
-
-static inline khmer_position_t
-matra_position_khmer (khmer_position_t side)
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum khmer_category_t
 {
-  switch ((int) side)
-  {
-    case POS_PRE_C:
-      return POS_PRE_M;
+  OT_Robatic = 20,
+  OT_Xgroup  = 21,
+  OT_Ygroup  = 22,
 
-    case POS_POST_C:
-    case POS_ABOVE_C:
-    case POS_BELOW_C:
-      return POS_AFTER_POST;
+  OT_VAbv    = 26,
+  OT_VBlw    = 27,
+  OT_VPre    = 28,
+  OT_VPst    = 29,
+};
 
-    default:
-      return side;
-  };
-}
-
-static inline bool
-is_consonant_or_vowel (const hb_glyph_info_t &info)
-{
-  return is_one_of (info, CONSONANT_FLAGS | FLAG (OT_V));
-}
-
-static inline bool
-is_coeng (const hb_glyph_info_t &info)
-{
-  return is_one_of (info, FLAG (OT_Coeng));
-}
-
 static inline void
 set_khmer_properties (hb_glyph_info_t &info)
 {
@@ -77,47 +56,58 @@
   hb_codepoint_t u = info.codepoint;
   unsigned int type = hb_indic_get_categories (u);
   khmer_category_t cat = (khmer_category_t) (type & 0x7Fu);
-  khmer_position_t pos = (khmer_position_t) (type >> 8);
+  indic_position_t pos = (indic_position_t) (type >> 8);
 
 
   /*
    * Re-assign category
+   *
+   * These categories are experimentally extracted from what Uniscribe allows.
    */
+  switch (u)
+  {
+    case 0x179Au:
+      cat = (khmer_category_t) OT_Ra;
+      break;
 
-  if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */
-  else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CDu, 0x17D1u) ||
-		     u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */
-  {
-    /* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier.
-     * https://github.com/roozbehp/unicode-data/issues/5 */
-    cat = OT_M;
-    pos = POS_ABOVE_C;
+    case 0x17CCu:
+    case 0x17C9u:
+    case 0x17CAu:
+      cat = OT_Robatic;
+      break;
+
+    case 0x17C6u:
+    case 0x17CBu:
+    case 0x17CDu:
+    case 0x17CEu:
+    case 0x17CFu:
+    case 0x17D0u:
+    case 0x17D1u:
+      cat = OT_Xgroup;
+      break;
+
+    case 0x17C7u:
+    case 0x17C8u:
+    case 0x17DDu:
+    case 0x17D3u: /* Just guessing. Uniscribe doesn't categorize it. */
+      cat = OT_Ygroup;
+      break;
   }
-  else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u))) cat = OT_PLACEHOLDER;
-  else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
 
-
   /*
    * Re-assign position.
    */
+  if (cat == (khmer_category_t) OT_M)
+    switch ((int) pos)
+    {
+      case POS_PRE_C:	cat = OT_VPre; break;
+      case POS_BELOW_C:	cat = OT_VBlw; break;
+      case POS_ABOVE_C:	cat = OT_VAbv; break;
+      case POS_POST_C:	cat = OT_VPst; break;
+      default: assert (0);
+    };
 
-  if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS))
-  {
-    pos = POS_BASE_C;
-    if (u == 0x179Au)
-      cat = OT_Ra;
-  }
-  else if (cat == OT_M)
-  {
-    pos = matra_position_khmer (pos);
-  }
-  else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_A) | FLAG (OT_Symbol))))
-  {
-    pos = POS_SMVD;
-  }
-
   info.khmer_category() = cat;
-  info.khmer_position() = pos;
 }
 
 

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -283,10 +283,9 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
-    for (unsigned int i = last; i < p+1; i++) \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
-    last = p+1; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
@@ -294,11 +293,11 @@
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  unsigned int p, pe, eof, ts, te, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 302 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 301 "hb-ot-shape-complex-myanmar-machine.hh"
 	{
 	cs = myanmar_syllable_machine_start;
 	ts = 0;
@@ -306,16 +305,15 @@
 	act = 0;
 	}
 
-#line 115 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
 
 
   p = 0;
   pe = eof = buffer->len;
 
-  unsigned int last = 0;
   unsigned int syllable_serial = 1;
   
-#line 319 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 317 "hb-ot-shape-complex-myanmar-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -329,7 +327,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 333 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 331 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 	_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -379,7 +377,7 @@
 #line 90 "hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
 	break;
-#line 383 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 381 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 _again:
@@ -388,7 +386,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 392 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 390 "hb-ot-shape-complex-myanmar-machine.hh"
 	}
 
 	if ( ++p != pe )
@@ -404,7 +402,7 @@
 
 	}
 
-#line 124 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 122 "hb-ot-shape-complex-myanmar-machine.rl"
 
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl	2018-10-19 23:02:01 UTC (rev 48949)
@@ -95,10 +95,9 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
-    for (unsigned int i = last; i < p+1; i++) \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
-    last = p+1; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
@@ -106,7 +105,7 @@
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  unsigned int p, pe, eof, ts, te, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   %%{
@@ -117,7 +116,6 @@
   p = 0;
   pe = eof = buffer->len;
 
-  unsigned int last = 0;
   unsigned int syllable_serial = 1;
   %%{
     write exec;

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -54,7 +54,14 @@
   HB_TAG('a','b','v','s'),
   HB_TAG('b','l','w','s'),
   HB_TAG('p','s','t','s'),
-  /* Positioning features, though we don't care about the types. */
+};
+static const hb_tag_t
+positioning_features[] =
+{
+  /*
+   * Positioning features.
+   * We don't care about the types.
+   */
   HB_TAG('d','i','s','t'),
   /* Pre-release version of Windows 8 Myanmar font had abvm,blwm
    * features.  The released Windows 8 version of the font (as well
@@ -89,27 +96,33 @@
   /* Do this before any lookups have been applied. */
   map->add_gsub_pause (setup_syllables);
 
-  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+  map->enable_feature (HB_TAG('l','o','c','l'));
   /* The Indic specs do not require ccmp, but we apply it here since if
    * there is a use of it, it's typically at the beginning. */
-  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+  map->enable_feature (HB_TAG('c','c','m','p'));
 
 
   map->add_gsub_pause (initial_reordering);
+
   for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
   {
-    map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+    map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
     map->add_gsub_pause (nullptr);
   }
+
   map->add_gsub_pause (final_reordering);
+
   for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
-    map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+    map->enable_feature (other_features[i], F_MANUAL_ZWJ);
+
+  for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
+    map->enable_feature (positioning_features[i]);
 }
 
 static void
 override_features_myanmar (hb_ot_shape_planner_t *plan)
 {
-  plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+  plan->map.disable_feature (HB_TAG('l','i','g','a'));
 }
 
 
@@ -362,6 +375,25 @@
 }
 
 
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
+{
+  collect_features_myanmar,
+  override_features_myanmar,
+  nullptr, /* data_create */
+  nullptr, /* data_destroy */
+  nullptr, /* preprocess_text */
+  nullptr, /* postprocess_glyphs */
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
+  nullptr, /* decompose */
+  nullptr, /* compose */
+  setup_masks_myanmar,
+  HB_TAG_NONE, /* gpos_tag */
+  nullptr, /* reorder_marks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
+  false, /* fallback_position */
+};
+
+
 /* Uniscribe seems to have a shaper for 'mymr' that is like the
  * generic shaper, except that it zeros mark advances GDEF_LATE. */
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
@@ -376,26 +408,30 @@
   nullptr, /* decompose */
   nullptr, /* compose */
   nullptr, /* setup_masks */
-  nullptr, /* disable_otl */
+  HB_TAG_NONE, /* gpos_tag */
   nullptr, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
 
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
+
+/* Ugly Zawgyi encoding.
+ * Disable all auto processing.
+ * https://github.com/harfbuzz/harfbuzz/issues/1162 */
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_zawgyi =
 {
-  collect_features_myanmar,
-  override_features_myanmar,
+  nullptr, /* collect_features */
+  nullptr, /* override_features */
   nullptr, /* data_create */
   nullptr, /* data_destroy */
   nullptr, /* preprocess_text */
   nullptr, /* postprocess_glyphs */
-  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
+  HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
   nullptr, /* decompose */
   nullptr, /* compose */
-  setup_masks_myanmar,
-  nullptr, /* disable_otl */
+  nullptr, /* setup_masks */
+  HB_TAG_NONE, /* gpos_tag */
   nullptr, /* reorder_marks */
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -64,7 +64,7 @@
 {
   hb_codepoint_t u = info.codepoint;
   unsigned int type = hb_indic_get_categories (u);
-  indic_category_t cat = (indic_category_t) (type & 0x7Fu);
+  unsigned int cat = type & 0x7Fu;
   indic_position_t pos = (indic_position_t) (type >> 8);
 
   /* Myanmar
@@ -71,12 +71,12 @@
    * https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze
    */
   if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)))
-    cat = (indic_category_t) OT_VS;
+    cat = OT_VS;
 
   switch (u)
   {
     case 0x104Eu:
-      cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
+      cat = OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
       break;
 
     case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u:
@@ -83,23 +83,23 @@
     case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u:
     case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu:
     case 0x25FEu:
-      cat = (indic_category_t) OT_GB;
+      cat = OT_GB;
       break;
 
     case 0x1004u: case 0x101Bu: case 0x105Au:
-      cat = (indic_category_t) OT_Ra;
+      cat = OT_Ra;
       break;
 
     case 0x1032u: case 0x1036u:
-      cat = (indic_category_t) OT_A;
+      cat = OT_A;
       break;
 
     case 0x1039u:
-      cat = (indic_category_t) OT_H;
+      cat = OT_H;
       break;
 
     case 0x103Au:
-      cat = (indic_category_t) OT_As;
+      cat = OT_As;
       break;
 
     case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u:
@@ -107,47 +107,47 @@
     case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u:
     case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u:
     case 0x1097u: case 0x1098u: case 0x1099u:
-      cat = (indic_category_t) OT_D;
+      cat = OT_D;
       break;
 
     case 0x1040u:
-      cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
+      cat = OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
       break;
 
     case 0x103Eu: case 0x1060u:
-      cat = (indic_category_t) OT_MH;
+      cat = OT_MH;
       break;
 
     case 0x103Cu:
-      cat = (indic_category_t) OT_MR;
+      cat = OT_MR;
       break;
 
     case 0x103Du: case 0x1082u:
-      cat = (indic_category_t) OT_MW;
+      cat = OT_MW;
       break;
 
     case 0x103Bu: case 0x105Eu: case 0x105Fu:
-      cat = (indic_category_t) OT_MY;
+      cat = OT_MY;
       break;
 
     case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au:
     case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu:
-      cat = (indic_category_t) OT_PT;
+      cat = OT_PT;
       break;
 
     case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u:
     case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du:
     case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu:
-      cat = (indic_category_t) OT_SM;
+      cat = OT_SM;
       break;
 
     case 0x104Au: case 0x104Bu:
-      cat = (indic_category_t) OT_P;
+      cat = OT_P;
       break;
 
     case 0xAA74u: case 0xAA75u: case 0xAA76u:
       /* https://github.com/roozbehp/unicode-data/issues/3 */
-      cat = (indic_category_t) OT_C;
+      cat = OT_C;
       break;
   }
 
@@ -155,15 +155,15 @@
   {
     switch ((int) pos)
     {
-      case POS_PRE_C:	cat = (indic_category_t) OT_VPre;
-			pos = POS_PRE_M;                  break;
-      case POS_ABOVE_C:	cat = (indic_category_t) OT_VAbv; break;
-      case POS_BELOW_C:	cat = (indic_category_t) OT_VBlw; break;
-      case POS_POST_C:	cat = (indic_category_t) OT_VPst; break;
+      case POS_PRE_C:	cat = OT_VPre;
+			pos = POS_PRE_M; break;
+      case POS_ABOVE_C:	cat = OT_VAbv;   break;
+      case POS_BELOW_C:	cat = OT_VBlw;   break;
+      case POS_POST_C:	cat = OT_VPst;   break;
     }
   }
 
-  info.myanmar_category() = (myanmar_category_t) cat;
+  info.myanmar_category() = cat;
   info.myanmar_position() = pos;
 }
 

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-thai.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -324,9 +324,9 @@
     }
 
     /* Is SARA AM. Decompose and reorder. */
-    hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
-				    hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
-    buffer->replace_glyphs (1, 2, decomposed);
+    hb_glyph_info_t &nikhahit = buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u));
+    _hb_glyph_info_set_continuation (&nikhahit);
+    buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u));
     if (unlikely (!buffer->successful))
       return;
 
@@ -357,7 +357,8 @@
 	buffer->merge_out_clusters (start - 1, end);
     }
   }
-  buffer->swap_buffers ();
+  if (likely (buffer->successful))
+    buffer->swap_buffers ();
 
   /* If font has Thai GSUB, we are done. */
   if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])
@@ -376,7 +377,7 @@
   nullptr, /* decompose */
   nullptr, /* compose */
   nullptr, /* setup_masks */
-  nullptr, /* disable_otl */
+  HB_TAG_NONE, /* gpos_tag */
   nullptr, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   false,/* fallback_position */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-tibetan.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -1,63 +0,0 @@
-/*
- * Copyright © 2010,2012  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-shape-complex.hh"
-
-
-static const hb_tag_t tibetan_features[] =
-{
-  HB_TAG('a','b','v','s'),
-  HB_TAG('b','l','w','s'),
-  HB_TAG('a','b','v','m'),
-  HB_TAG('b','l','w','m'),
-  HB_TAG_NONE
-};
-
-static void
-collect_features_tibetan (hb_ot_shape_planner_t *plan)
-{
-  for (const hb_tag_t *script_features = tibetan_features; script_features && *script_features; script_features++)
-    plan->map.add_global_bool_feature (*script_features);
-}
-
-
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan =
-{
-  collect_features_tibetan,
-  nullptr, /* override_features */
-  nullptr, /* data_create */
-  nullptr, /* data_destroy */
-  nullptr, /* preprocess_text */
-  nullptr, /* postprocess_glyphs */
-  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
-  nullptr, /* decompose */
-  nullptr, /* compose */
-  nullptr, /* setup_masks */
-  nullptr, /* disable_otl */
-  nullptr, /* reorder_marks */
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
-  true, /* fallback_position */
-};

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -36,227 +36,266 @@
 
 #line 38 "hb-ot-shape-complex-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-	12u, 12u, 1u, 15u, 1u, 1u, 12u, 12u, 0u, 43u, 21u, 21u, 8u, 39u, 8u, 39u, 
-	1u, 15u, 1u, 1u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 
-	8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 
-	8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 13u, 21u, 4u, 4u, 13u, 13u, 8u, 39u, 
-	8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 
-	8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 
-	8u, 39u, 1u, 15u, 12u, 12u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u, 42u, 42u, 
-	1u, 5u, 0
+	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
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-	1, 15, 1, 1, 44, 1, 32, 32, 
-	15, 1, 32, 32, 32, 19, 19, 19, 
-	32, 32, 32, 32, 32, 32, 32, 32, 
-	32, 32, 32, 32, 9, 1, 1, 32, 
-	32, 32, 32, 19, 19, 19, 32, 32, 
-	32, 32, 32, 32, 32, 32, 32, 32, 
-	32, 15, 1, 39, 32, 22, 2, 1, 
-	5
+	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
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-	0, 2, 18, 20, 22, 67, 69, 102, 
-	135, 151, 153, 186, 219, 252, 272, 292, 
-	312, 345, 378, 411, 444, 477, 510, 543, 
-	576, 609, 642, 675, 708, 718, 720, 722, 
-	755, 788, 821, 854, 874, 894, 914, 947, 
-	980, 1013, 1046, 1079, 1112, 1145, 1178, 1211, 
-	1244, 1277, 1293, 1295, 1335, 1368, 1391, 1394, 
-	1396
+	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
 };
 
 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, 3, 2, 2, 2, 2, 2, 
 	2, 2, 2, 2, 2, 2, 2, 2, 
-	4, 2, 3, 2, 6, 5, 7, 8, 
+	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, 9, 34, 33, 36, 35, 35, 
-	37, 1, 35, 35, 38, 35, 35, 35, 
-	35, 35, 39, 40, 41, 42, 43, 44, 
-	45, 46, 40, 47, 39, 48, 49, 50, 
-	51, 35, 52, 53, 54, 35, 36, 35, 
-	35, 37, 1, 35, 35, 38, 35, 35, 
-	35, 35, 35, 55, 40, 41, 42, 43, 
-	44, 45, 46, 40, 47, 48, 48, 49, 
-	50, 51, 35, 52, 53, 54, 35, 37, 
-	56, 56, 56, 56, 56, 56, 56, 56, 
-	56, 56, 56, 56, 56, 57, 56, 37, 
-	56, 36, 35, 35, 37, 1, 35, 35, 
-	38, 35, 35, 35, 35, 35, 35, 40, 
-	41, 42, 43, 44, 45, 46, 40, 47, 
-	48, 48, 49, 50, 51, 35, 52, 53, 
-	54, 35, 36, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	40, 41, 42, 43, 44, 35, 35, 35, 
-	35, 35, 35, 49, 50, 51, 35, 52, 
-	53, 54, 35, 36, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 41, 42, 43, 44, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	52, 53, 54, 35, 36, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 42, 43, 44, 35, 
-	36, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 43, 44, 35, 36, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 44, 35, 
-	36, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	42, 43, 44, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 52, 53, 54, 
-	35, 36, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 42, 43, 44, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 53, 
-	54, 35, 36, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 42, 43, 44, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 54, 35, 36, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 41, 42, 43, 44, 35, 35, 
-	35, 35, 35, 35, 49, 50, 51, 35, 
-	52, 53, 54, 35, 36, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 41, 42, 43, 44, 35, 
-	35, 35, 35, 35, 35, 35, 50, 51, 
-	35, 52, 53, 54, 35, 36, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 41, 42, 43, 44, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	51, 35, 52, 53, 54, 35, 36, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 40, 41, 42, 43, 
-	44, 35, 46, 40, 35, 35, 35, 49, 
-	50, 51, 35, 52, 53, 54, 35, 36, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 40, 41, 42, 
-	43, 44, 35, 58, 40, 35, 35, 35, 
-	49, 50, 51, 35, 52, 53, 54, 35, 
-	36, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 40, 41, 
-	42, 43, 44, 35, 35, 40, 35, 35, 
-	35, 49, 50, 51, 35, 52, 53, 54, 
-	35, 36, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 40, 
-	41, 42, 43, 44, 45, 46, 40, 35, 
-	35, 35, 49, 50, 51, 35, 52, 53, 
-	54, 35, 36, 35, 35, 37, 1, 35, 
-	35, 38, 35, 35, 35, 35, 35, 35, 
-	40, 41, 42, 43, 44, 45, 46, 40, 
-	47, 35, 48, 49, 50, 51, 35, 52, 
-	53, 54, 35, 36, 35, 35, 37, 1, 
-	35, 35, 38, 35, 35, 35, 35, 35, 
-	35, 40, 41, 42, 43, 44, 45, 46, 
-	40, 47, 39, 48, 49, 50, 51, 35, 
-	52, 53, 54, 35, 60, 59, 59, 59, 
-	59, 59, 59, 59, 61, 59, 10, 62, 
-	60, 59, 11, 63, 63, 3, 6, 63, 
-	63, 64, 63, 63, 63, 63, 63, 65, 
+	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, 63, 29, 
-	30, 31, 63, 11, 63, 63, 3, 6, 
-	63, 63, 64, 63, 63, 63, 63, 63, 
-	63, 16, 17, 18, 19, 20, 21, 22, 
-	16, 23, 25, 25, 26, 27, 28, 63, 
-	29, 30, 31, 63, 11, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 16, 17, 18, 19, 20, 63, 
-	63, 63, 63, 63, 63, 26, 27, 28, 
-	63, 29, 30, 31, 63, 11, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 17, 18, 19, 20, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 29, 30, 31, 63, 11, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 18, 19, 
-	20, 63, 11, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 19, 20, 63, 11, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	20, 63, 11, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 18, 19, 20, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 29, 
-	30, 31, 63, 11, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 18, 19, 20, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 30, 31, 63, 11, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 18, 19, 20, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 31, 63, 11, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 17, 18, 19, 20, 
-	63, 63, 63, 63, 63, 63, 26, 27, 
-	28, 63, 29, 30, 31, 63, 11, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 17, 18, 19, 
-	20, 63, 63, 63, 63, 63, 63, 63, 
-	27, 28, 63, 29, 30, 31, 63, 11, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 17, 18, 
-	19, 20, 63, 63, 63, 63, 63, 63, 
-	63, 63, 28, 63, 29, 30, 31, 63, 
-	11, 63, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 16, 17, 
-	18, 19, 20, 63, 22, 16, 63, 63, 
-	63, 26, 27, 28, 63, 29, 30, 31, 
-	63, 11, 63, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 16, 
-	17, 18, 19, 20, 63, 66, 16, 63, 
-	63, 63, 26, 27, 28, 63, 29, 30, 
-	31, 63, 11, 63, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	16, 17, 18, 19, 20, 63, 63, 16, 
-	63, 63, 63, 26, 27, 28, 63, 29, 
-	30, 31, 63, 11, 63, 63, 63, 63, 
-	63, 63, 63, 63, 63, 63, 63, 63, 
-	63, 16, 17, 18, 19, 20, 21, 22, 
-	16, 63, 63, 63, 26, 27, 28, 63, 
-	29, 30, 31, 63, 11, 63, 63, 3, 
-	6, 63, 63, 64, 63, 63, 63, 63, 
-	63, 63, 16, 17, 18, 19, 20, 21, 
-	22, 16, 23, 63, 25, 26, 27, 28, 
-	63, 29, 30, 31, 63, 3, 67, 67, 
-	67, 67, 67, 67, 67, 67, 67, 67, 
-	67, 67, 67, 4, 67, 6, 67, 8, 
-	63, 63, 63, 8, 63, 63, 11, 63, 
-	63, 3, 6, 63, 63, 64, 63, 63, 
-	63, 63, 63, 63, 16, 17, 18, 19, 
-	20, 21, 22, 16, 23, 24, 25, 26, 
-	27, 28, 63, 29, 30, 31, 63, 11, 
-	63, 63, 3, 6, 63, 63, 64, 63, 
-	63, 63, 63, 63, 63, 16, 17, 18, 
+	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, 63, 29, 30, 31, 63, 
-	69, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 68, 68, 68, 68, 
-	68, 68, 68, 68, 69, 70, 68, 69, 
-	70, 68, 70, 68, 8, 67, 67, 67, 
-	8, 67, 0
+	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
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
-	4, 8, 4, 31, 2, 4, 1, 5, 
-	6, 4, 28, 4, 49, 50, 51, 53, 
-	33, 34, 35, 36, 37, 44, 45, 47, 
-	52, 48, 41, 42, 43, 38, 39, 40, 
-	56, 4, 4, 4, 4, 7, 0, 27, 
-	11, 12, 13, 14, 15, 22, 23, 25, 
-	26, 19, 20, 21, 16, 17, 18, 10, 
-	4, 9, 24, 4, 29, 30, 4, 4, 
-	3, 32, 46, 4, 4, 54, 55
+	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
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
@@ -264,11 +303,12 @@
 	7, 8, 0, 9, 10, 10, 3, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	3, 3, 0, 0, 0, 0, 0, 0, 
-	0, 11, 12, 13, 14, 7, 0, 7, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	7, 0, 0, 0, 0, 0, 0, 7, 
-	15, 0, 0, 16, 0, 0, 17, 18, 
-	0, 3, 0, 19, 20, 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
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
@@ -279,7 +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
 };
 
 static const char _use_syllable_machine_from_state_actions[] = {
@@ -290,18 +330,18 @@
 	0, 0, 0, 0, 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, 34, 36, 36, 
-	57, 57, 36, 36, 36, 36, 36, 36, 
-	36, 36, 36, 36, 36, 36, 36, 36, 
-	36, 36, 36, 36, 60, 63, 60, 64, 
-	64, 64, 64, 64, 64, 64, 64, 64, 
-	64, 64, 64, 64, 64, 64, 64, 64, 
-	64, 68, 68, 64, 64, 69, 69, 69, 
-	68
+	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
 };
 
 static const int use_syllable_machine_start = 4;
@@ -315,15 +355,14 @@
 
 
 
-#line 141 "hb-ot-shape-complex-use-machine.rl"
+#line 143 "hb-ot-shape-complex-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
-    for (unsigned int i = last; i < p+1; i++) \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
-    last = p+1; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
@@ -331,11 +370,11 @@
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te, act;
+  unsigned int p, pe, eof, ts, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 339 "hb-ot-shape-complex-use-machine.hh"
+#line 378 "hb-ot-shape-complex-use-machine.hh"
 	{
 	cs = use_syllable_machine_start;
 	ts = 0;
@@ -343,16 +382,15 @@
 	act = 0;
 	}
 
-#line 162 "hb-ot-shape-complex-use-machine.rl"
+#line 163 "hb-ot-shape-complex-use-machine.rl"
 
 
   p = 0;
   pe = eof = buffer->len;
 
-  unsigned int last = 0;
   unsigned int syllable_serial = 1;
   
-#line 356 "hb-ot-shape-complex-use-machine.hh"
+#line 394 "hb-ot-shape-complex-use-machine.hh"
 	{
 	int _slen;
 	int _trans;
@@ -366,7 +404,7 @@
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 370 "hb-ot-shape-complex-use-machine.hh"
+#line 408 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -389,59 +427,59 @@
 	{te = p+1;}
 	break;
 	case 12:
-#line 130 "hb-ot-shape-complex-use-machine.rl"
+#line 132 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (independent_cluster); }}
 	break;
 	case 14:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 134 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (standard_cluster); }}
 	break;
 	case 9:
-#line 136 "hb-ot-shape-complex-use-machine.rl"
+#line 138 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (broken_cluster); }}
 	break;
 	case 8:
-#line 137 "hb-ot-shape-complex-use-machine.rl"
+#line 139 "hb-ot-shape-complex-use-machine.rl"
 	{te = p+1;{ found_syllable (non_cluster); }}
 	break;
 	case 11:
-#line 130 "hb-ot-shape-complex-use-machine.rl"
+#line 132 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (independent_cluster); }}
 	break;
 	case 15:
-#line 131 "hb-ot-shape-complex-use-machine.rl"
+#line 133 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (virama_terminated_cluster); }}
 	break;
 	case 13:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 134 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (standard_cluster); }}
 	break;
 	case 17:
-#line 133 "hb-ot-shape-complex-use-machine.rl"
+#line 135 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
 	break;
 	case 16:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 136 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (numeral_cluster); }}
 	break;
 	case 20:
-#line 135 "hb-ot-shape-complex-use-machine.rl"
+#line 137 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (symbol_cluster); }}
 	break;
 	case 18:
-#line 136 "hb-ot-shape-complex-use-machine.rl"
+#line 138 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
 	case 19:
-#line 137 "hb-ot-shape-complex-use-machine.rl"
+#line 139 "hb-ot-shape-complex-use-machine.rl"
 	{te = p;p--;{ found_syllable (non_cluster); }}
 	break;
 	case 1:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 134 "hb-ot-shape-complex-use-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (standard_cluster); }}
 	break;
 	case 4:
-#line 136 "hb-ot-shape-complex-use-machine.rl"
+#line 138 "hb-ot-shape-complex-use-machine.rl"
 	{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
 	break;
 	case 2:
@@ -459,16 +497,16 @@
 	case 3:
 #line 1 "NONE"
 	{te = p+1;}
-#line 136 "hb-ot-shape-complex-use-machine.rl"
+#line 138 "hb-ot-shape-complex-use-machine.rl"
 	{act = 7;}
 	break;
 	case 10:
 #line 1 "NONE"
 	{te = p+1;}
-#line 137 "hb-ot-shape-complex-use-machine.rl"
+#line 139 "hb-ot-shape-complex-use-machine.rl"
 	{act = 8;}
 	break;
-#line 472 "hb-ot-shape-complex-use-machine.hh"
+#line 510 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 _again:
@@ -477,7 +515,7 @@
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 481 "hb-ot-shape-complex-use-machine.hh"
+#line 519 "hb-ot-shape-complex-use-machine.hh"
 	}
 
 	if ( ++p != pe )

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-machine.rl	2018-10-19 23:02:01 UTC (rev 48949)
@@ -88,36 +88,38 @@
 SMBlw	= 42; # SYM_MOD_BELOW
 CS	= 43; # CONS_WITH_STACKER
 
+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
-consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.H.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*;
+consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.h.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*;
 # Override: Allow two MBlw. https://github.com/harfbuzz/harfbuzz/issues/376
 medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?;
 dependent_vowels = VPre* VAbv* VBlw* VPst*;
-vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*;
+vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*;
 final_consonants = FAbv* FBlw* FPst* FM?;
 
+complex_syllable_tail =
+	consonant_modifiers
+	medial_consonants
+	dependent_vowels
+	vowel_modifiers
+	final_consonants
+;
+
 virama_terminated_cluster =
 	(R|CS)? (B | GB) VS?
 	consonant_modifiers
-	ZWJ?.H.ZWJ?
+	ZWJ?.h.ZWJ?
 ;
 standard_cluster =
 	(R|CS)? (B | GB) VS?
-	consonant_modifiers
-	medial_consonants
-	dependent_vowels
-	vowel_modifiers
-	final_consonants
+	complex_syllable_tail
 ;
-
 broken_cluster =
 	R?
-	consonant_modifiers
-	medial_consonants
-	dependent_vowels
-	vowel_modifiers
-	final_consonants
+	complex_syllable_tail
 ;
 
 number_joiner_terminated_cluster = N VS? (HN N VS?)* HN;
@@ -142,10 +144,9 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
-    for (unsigned int i = last; i < p+1; i++) \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
-    last = p+1; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
@@ -153,7 +154,7 @@
 static void
 find_syllables (hb_buffer_t *buffer)
 {
-  unsigned int p, pe, eof, ts HB_UNUSED, te, act;
+  unsigned int p, pe, eof, ts, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   %%{
@@ -164,7 +165,6 @@
   p = 0;
   pe = eof = buffer->len;
 
-  unsigned int last = 0;
   unsigned int syllable_serial = 1;
   %%{
     write exec;

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -24,6 +24,7 @@
 #define GB	USE_GB	/* BASE_OTHER */
 #define H	USE_H	/* HALANT */
 #define HN	USE_HN	/* HALANT_NUM */
+#define HVM	USE_HVM	/* HALANT_OR_VOWEL_MODIFIER */
 #define IND	USE_IND	/* BASE_IND */
 #define N	USE_N	/* BASE_NUM */
 #define O	USE_O	/* OTHER */
@@ -101,7 +102,7 @@
   /* 0990 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 09A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 09B0 */     B,     O,     B,     O,     O,     O,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPre,
-  /* 09C0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,   IND,     O,
+  /* 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,
@@ -134,7 +135,7 @@
   /* 0B10 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 0B30 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VAbv,
-  /* 0B40 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
+  /* 0B40 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPst,     O,     O,  VPst,  VPst,     H,     O,     O,
   /* 0B50 */     O,     O,     O,     O,     O,     O,  VAbv,  VAbv,     O,     O,     O,     O,     B,     B,     O,     B,
   /* 0B60 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0B70 */     O,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
@@ -145,7 +146,7 @@
   /* 0B90 */     B,     O,     B,     B,     B,     B,     O,     O,     O,     B,     B,     O,     B,     O,     B,     B,
   /* 0BA0 */     O,     O,     O,     B,     B,     O,     O,     O,     B,     B,     B,     O,     O,     O,     B,     B,
   /* 0BB0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,  VPst,  VPst,
-  /* 0BC0 */  VAbv,  VPst,  VPst,     O,     O,     O,  VPre,  VPre,  VPre,     O,  VPre,  VPre,  VPre,     H,     O,     O,
+  /* 0BC0 */  VAbv,  VPst,  VPst,     O,     O,     O,  VPre,  VPre,  VPre,     O,  VPst,  VPst,  VPst,     H,     O,     O,
   /* 0BD0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 0BE0 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0BF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
@@ -178,7 +179,7 @@
   /* 0D10 */     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0D20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0D30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,     B,  VPst,  VPst,
-  /* 0D40 */  VPst,  VPst,  VPst,  VBlw,  VBlw,     O,  VPre,  VPre,  VPre,     O,  VPre,  VPre,  VPre,     H,     R,     O,
+  /* 0D40 */  VPst,  VPst,  VPst,  VBlw,  VBlw,     O,  VPre,  VPre,  VPre,     O,  VPst,  VPst,  VPst,     H,     R,     O,
   /* 0D50 */     O,     O,     O,     O,   IND,   IND,   IND,  VPst,     O,     O,     O,     O,     O,     O,     O,     B,
   /* 0D60 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0D70 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,   IND,   IND,   IND,   IND,   IND,   IND,
@@ -190,13 +191,30 @@
   /* 0DA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0DB0 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     O,     O,
   /* 0DC0 */     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     H,     O,     O,     O,     O,  VPst,
-  /* 0DD0 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,     O,  VBlw,     O,  VPst,  VPre,  VPre,  VPre,  VPre,  VPre,  VPre,  VPst,
+  /* 0DD0 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,     O,  VBlw,     O,  VPst,  VPre,  VPst,  VPre,  VPst,  VPst,  VPst,  VPst,
   /* 0DE0 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0DF0 */     O,     O,  VPst,  VPst,     O,     O,     O,     O,
 
-#define use_offset_0x1000u 1360
+#define use_offset_0x0f18u 1360
 
 
+  /* 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,
+  /* 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,
+  /* 0F70 */     O,  VBlw,  VBlw,  VAbv,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw, VMAbv, VMPst,
+  /* 0F80 */  VBlw,  VAbv, VMAbv, VMAbv,  VBlw,   IND, VMAbv, VMAbv,     B,     B,     B,     B,     B,   SUB,   SUB,   SUB,
+  /* 0F90 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
+  /* 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,
+
+#define use_offset_0x1000u 1536
+
+
   /* Myanmar */
 
   /* 1000 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
@@ -210,7 +228,7 @@
   /* 1080 */     B,     B,  MBlw,  VPst,  VPre,  VAbv,  VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw,     B, VMPst,
   /* 1090 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMPst, VMPst,  VPst,  VAbv,     O,     O,
 
-#define use_offset_0x1700u 1520
+#define use_offset_0x1700u 1696
 
 
   /* Tagalog */
@@ -238,12 +256,12 @@
   /* 1780 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1790 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 17A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 17B0 */     B,     B,     B,     B,     O,     O,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VPre,  VPre,
-  /* 17C0 */  VPre,  VPre,  VPre,  VPre,  VPre,  VPre, VMAbv, VMPst,  VPst, VMAbv, VMAbv,    FM,  FAbv, CMAbv,    FM,    FM,
+  /* 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,  VAbv,     O,     O,
   /* 17E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x1900u 1760
+#define use_offset_0x1900u 1936
 
 
   /* Limbu */
@@ -287,7 +305,7 @@
   /* 1A80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
   /* 1A90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x1b00u 2176
+#define use_offset_0x1b00u 2352
 
 
   /* Balinese */
@@ -296,7 +314,7 @@
   /* 1B10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1B30 */     B,     B,     B,     B, CMAbv,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPre,  VPre,
-  /* 1B40 */  VPre,  VPre,  VAbv,  VAbv,     H,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
+  /* 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,
   /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
@@ -319,11 +337,11 @@
 
   /* 1C00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1C10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1C20 */     B,     B,     B,     B,   SUB,   SUB,  VPst,  VPre,  VPre,  VPre,  VPst,  VPst,  VBlw,  FAbv,  FAbv,  FAbv,
+  /* 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,
   /* 1C40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,     B,     B,
 
-#define use_offset_0x1cd0u 2512
+#define use_offset_0x1cd0u 2688
 
 
   /* Vedic Extensions */
@@ -332,13 +350,13 @@
   /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,     O,     O,     O,     O, VMBlw,     O,     O,
   /* 1CF0 */     O,     O, VMPst, VMPst, VMAbv,    CS,    CS, VMPst, VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x1df8u 2560
+#define use_offset_0x1df8u 2736
 
 
   /* Combining Diacritical Marks Supplement */
                                                                          O,     O,     O,    FM,     O,     O,     O,     O,
 
-#define use_offset_0x2008u 2568
+#define use_offset_0x2008u 2744
 
 
   /* General Punctuation */
@@ -345,7 +363,7 @@
                                                                          O,     O,     O,     O,  ZWNJ,   ZWJ,     O,     O,
   /* 2010 */    GB,    GB,    GB,    GB,    GB,     O,     O,     O,
 
-#define use_offset_0x2060u 2584
+#define use_offset_0x2060u 2760
 
   /* 2060 */    WJ,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
@@ -354,7 +372,7 @@
   /* 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,
 
-#define use_offset_0x20f0u 2624
+#define use_offset_0x20f0u 2800
 
 
   /* Combining Diacritical Marks for Symbols */
@@ -361,13 +379,13 @@
 
   /* 20F0 */ VMAbv,     O,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x25c8u 2632
+#define use_offset_0x25c8u 2808
 
 
   /* Geometric Shapes */
                                                                          O,     O,     O,     O,    GB,     O,     O,     O,
 
-#define use_offset_0xa800u 2640
+#define use_offset_0xa800u 2816
 
 
   /* Syloti Nagri */
@@ -454,7 +472,7 @@
   /* AAE0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPre,  VBlw,  VAbv,  VPre,  VPst,
   /* AAF0 */     O,     O,     O,     O,     O, VMPst,     H,     O,
 
-#define use_offset_0xabc0u 3400
+#define use_offset_0xabc0u 3576
 
 
   /* Meetei Mayek */
@@ -464,7 +482,7 @@
   /* ABE0 */     B,     B,     B,  VPst,  VPst,  VAbv,  VPst,  VPst,  VBlw,  VPst,  VPst,     O, VMPst,  VBlw,     O,     O,
   /* ABF0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0xfe00u 3464
+#define use_offset_0xfe00u 3640
 
 
   /* Variation Selectors */
@@ -471,7 +489,7 @@
 
   /* FE00 */    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,
 
-#define use_offset_0x10a00u 3480
+#define use_offset_0x10a00u 3656
 
 
   /* Kharoshthi */
@@ -482,7 +500,7 @@
   /* 10A30 */     B,     B,     B,     B,     B,     B,     O,     O, CMAbv, CMBlw, CMBlw,     O,     O,     O,     O,     H,
   /* 10A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11000u 3560
+#define use_offset_0x11000u 3736
 
 
   /* Brahmi */
@@ -491,7 +509,7 @@
   /* 11010 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11020 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11030 */     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,
-  /* 11040 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11040 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,   HVM,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11050 */     O,     O,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,
   /* 11060 */     N,     N,     N,     N,     N,     N,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11070 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,    HN,
@@ -503,7 +521,7 @@
   /* 110A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 110B0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VAbv,  VAbv,  VPst,  VPst,     H, CMBlw,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11100u 3752
+#define use_offset_0x11100u 3928
 
 
   /* Chakma */
@@ -511,7 +529,7 @@
   /* 11100 */ VMAbv, VMAbv, VMAbv,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11110 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11120 */     B,     B,     B,     B,     B,     B,     B,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPre,  VBlw,  VAbv,  VAbv,
-  /* 11130 */  VBlw,  VAbv,  VAbv,     H, CMAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11130 */  VBlw,  VAbv,  VAbv,     H, CMBlw,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11140 */     O,     O,     O,     O,     B,  VPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Mahajani */
@@ -541,7 +559,7 @@
   /* 11220 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VPst,  VBlw,
   /* 11230 */  VAbv,  VAbv,  VAbv,  VAbv, VMAbv,     H, CMAbv, CMAbv,     O,     O,     O,     O,     O,     O, VMAbv,     O,
 
-#define use_offset_0x11280u 4072
+#define use_offset_0x11280u 4248
 
 
   /* Multani */
@@ -564,12 +582,12 @@
   /* 11310 */     B,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11320 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
   /* 11330 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O, CMBlw, CMBlw,     B,  VPst,  VPst,
-  /* 11340 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
+  /* 11340 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,     O,  VPre,  VPre,     O,     O,  VPst,  VPst,     H,     O,     O,
   /* 11350 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     B,     B,
   /* 11360 */     B,     B,  VPst,  VPst,     O,     O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
   /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
 
-#define use_offset_0x11400u 4320
+#define use_offset_0x11400u 4496
 
 
   /* Newa */
@@ -588,11 +606,11 @@
   /* 11480 */     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11490 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 114A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 114B0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VPre,  VAbv,  VPre,  VPre,  VPst,  VPre, VMAbv,
+  /* 114B0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VPre,  VAbv,  VPst,  VPst,  VPst,  VPst, VMAbv,
   /* 114C0 */ VMAbv, VMPst,     H, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 114D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11580u 4544
+#define use_offset_0x11580u 4720
 
 
   /* Siddham */
@@ -600,7 +618,7 @@
   /* 11580 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11590 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 115A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,
-  /* 115B0 */  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,  VPre,  VPre, VMAbv, VMAbv, VMPst,     H,
+  /* 115B0 */  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPst,  VPst,  VPst, VMAbv, VMAbv, VMPst,     H,
   /* 115C0 */ CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 115D0 */     O,     O,     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,  VBlw,  VBlw,     O,     O,
   /* 115E0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
@@ -635,7 +653,7 @@
   /* 11720 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VBlw,  VAbv,  VAbv,  VAbv,     O,     O,     O,     O,
   /* 11730 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
 
-#define use_offset_0x11800u 4992
+#define use_offset_0x11800u 5168
 
 
   /* Dogra */
@@ -645,7 +663,7 @@
   /* 11820 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,
   /* 11830 */  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMPst,     H, CMBlw,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11a00u 5056
+#define use_offset_0x11a00u 5232
 
 
   /* Zanabazar Square */
@@ -664,7 +682,7 @@
   /* 11A80 */     B,     B,     B,     B,     O,     O,     R,     R,     R,     R,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,
   /* 11A90 */  FBlw,  FBlw,  FBlw,  FBlw,  FBlw,  FBlw, VMAbv, VMPst, CMAbv,     H,     O,     O,     O,     B,     O,     O,
 
-#define use_offset_0x11c00u 5216
+#define use_offset_0x11c00u 5392
 
 
   /* Bhaiksuki */
@@ -685,7 +703,7 @@
   /* 11CA0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 11CB0 */  VBlw,  VPre,  VBlw,  VAbv,  VPst, VMAbv, VMAbv,     O,
 
-#define use_offset_0x11d00u 5400
+#define use_offset_0x11d00u 5576
 
 
   /* Masaram Gondi */
@@ -705,7 +723,7 @@
   /* 11D90 */  VAbv,  VAbv,     O,  VPst,  VPst, VMAbv, VMPst,     H,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11DA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
-#define use_offset_0x11ee0u 5576
+#define use_offset_0x11ee0u 5752
 
 
   /* Makasar */
@@ -713,7 +731,7 @@
   /* 11EE0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11EF0 */     B,     B,    GB,  VAbv,  VBlw,  VPre,  VPst,     O,
 
-}; /* Table items: 5600; occupancy: 73% */
+}; /* Table items: 5776; occupancy: 74% */
 
 USE_TABLE_ELEMENT_TYPE
 hb_use_get_category (hb_codepoint_t u)
@@ -725,6 +743,7 @@
       if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
       if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u];
       if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u];
+      if (hb_in_range<hb_codepoint_t> (u, 0x0F18u, 0x0FC7u)) return use_table[u - 0x0F18u + use_offset_0x0f18u];
       break;
 
     case 0x1u:
@@ -782,6 +801,7 @@
 #undef GB
 #undef H
 #undef HN
+#undef HVM
 #undef IND
 #undef N
 #undef O

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -86,7 +86,14 @@
   HB_TAG('h','a','l','n'),
   HB_TAG('p','r','e','s'),
   HB_TAG('p','s','t','s'),
-  /* Positioning features, though we don't care about the types. */
+};
+static const hb_tag_t
+positioning_features[] =
+{
+  /*
+   * Positioning features.
+   * We don't care about the types.
+   */
   HB_TAG('d','i','s','t'),
   HB_TAG('a','b','v','m'),
   HB_TAG('b','l','w','m'),
@@ -122,33 +129,37 @@
   map->add_gsub_pause (setup_syllables);
 
   /* "Default glyph pre-processing group" */
-  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
-  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
-  map->add_global_bool_feature (HB_TAG('n','u','k','t'));
-  map->add_global_bool_feature (HB_TAG('a','k','h','n'));
+  map->enable_feature (HB_TAG('l','o','c','l'));
+  map->enable_feature (HB_TAG('c','c','m','p'));
+  map->enable_feature (HB_TAG('n','u','k','t'));
+  map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ);
 
   /* "Reordering group" */
   map->add_gsub_pause (clear_substitution_flags);
-  map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ);
+  map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ);
   map->add_gsub_pause (record_rphf);
   map->add_gsub_pause (clear_substitution_flags);
-  map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ);
+  map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ);
   map->add_gsub_pause (record_pref);
 
   /* "Orthographic unit shaping group" */
   for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
-    map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+    map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
 
   map->add_gsub_pause (reorder);
 
   /* "Topographical features" */
   for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++)
-    map->add_feature (arabic_features[i], 1, F_NONE);
+    map->add_feature (arabic_features[i]);
   map->add_gsub_pause (nullptr);
 
-  /* "Standard typographic presentation" and "Positional feature application" */
+  /* "Standard typographic presentation" */
   for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
-    map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+    map->enable_feature (other_features[i], F_MANUAL_ZWJ);
+
+  /* "Positional feature application" */
+  for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
+    map->enable_feature (positioning_features[i]);
 }
 
 struct use_shape_plan_t
@@ -586,7 +597,7 @@
   nullptr, /* decompose */
   compose_use,
   setup_masks_use,
-  nullptr, /* disable_otl */
+  HB_TAG_NONE, /* gpos_tag */
   nullptr, /* reorder_marks */
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
   false, /* fallback_position */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -88,7 +88,10 @@
   USE_VMPre	= 23,	/* VOWEL_MOD_PRE */
   USE_SMAbv	= 41,	/* SYM_MOD_ABOVE */
   USE_SMBlw	= 42,	/* SYM_MOD_BELOW */
-  USE_CS	= 43	/* CONS_WITH_STACKER */
+  USE_CS	= 43,	/* CONS_WITH_STACKER */
+
+  /* https://github.com/harfbuzz/harfbuzz/issues/1102 */
+  USE_HVM	= 44,	/* HALANT_OR_VOWEL_MODIFIER */
 };
 
 HB_INTERNAL USE_TABLE_ELEMENT_TYPE

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -29,11 +29,11 @@
 
 #include "hb.hh"
 
+#include "hb-ot-layout.hh"
 #include "hb-ot-shape.hh"
 #include "hb-ot-shape-normalize.hh"
 
 
-
 /* buffer var allocations, used by complex shapers */
 #define complex_var_u8_0()	var2.u8[2]
 #define complex_var_u8_1()	var2.u8[3]
@@ -58,8 +58,8 @@
   HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \
   HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
   HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \
   HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
-  HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \
   HB_COMPLEX_SHAPER_IMPLEMENT (use) \
   /* ^--- Add new shapers here */
 
@@ -69,7 +69,7 @@
   /* collect_features()
    * Called during shape_plan().
    * Shapers should use plan->map to add their features and callbacks.
-   * May be nullptr.
+   * May be NULL.
    */
   void (*collect_features) (hb_ot_shape_planner_t *plan);
 
@@ -77,7 +77,7 @@
    * Called during shape_plan().
    * Shapers should use plan->map to override features and add callbacks after
    * common features are added.
-   * May be nullptr.
+   * May be NULL.
    */
   void (*override_features) (hb_ot_shape_planner_t *plan);
 
@@ -93,7 +93,7 @@
    * Called when the shape_plan is being destroyed.
    * plan->data is passed here for destruction.
    * If nullptr is returned, means a plan failure.
-   * May be nullptr.
+   * May be NULL.
    */
   void (*data_destroy) (void *data);
 
@@ -101,7 +101,7 @@
   /* preprocess_text()
    * Called during shape().
    * Shapers can use to modify text before shaping starts.
-   * May be nullptr.
+   * May be NULL.
    */
   void (*preprocess_text) (const hb_ot_shape_plan_t *plan,
 			   hb_buffer_t              *buffer,
@@ -110,7 +110,7 @@
   /* postprocess_glyphs()
    * Called during shape().
    * Shapers can use to modify glyphs after shaping ends.
-   * May be nullptr.
+   * May be NULL.
    */
   void (*postprocess_glyphs) (const hb_ot_shape_plan_t *plan,
 			      hb_buffer_t              *buffer,
@@ -121,7 +121,7 @@
 
   /* decompose()
    * Called during shape()'s normalization.
-   * May be nullptr.
+   * May be NULL.
    */
   bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
 		     hb_codepoint_t  ab,
@@ -130,7 +130,7 @@
 
   /* compose()
    * Called during shape()'s normalization.
-   * May be nullptr.
+   * May be NULL.
    */
   bool (*compose) (const hb_ot_shape_normalize_context_t *c,
 		   hb_codepoint_t  a,
@@ -141,24 +141,22 @@
    * Called during shape().
    * Shapers should use map to get feature masks and set on buffer.
    * Shapers may NOT modify characters.
-   * May be nullptr.
+   * May be NULL.
    */
   void (*setup_masks) (const hb_ot_shape_plan_t *plan,
 		       hb_buffer_t              *buffer,
 		       hb_font_t                *font);
 
-  /* disable_otl()
-   * Called during shape().
-   * If set and returns true, GDEF/GSUB/GPOS of the font are ignored
-   * and fallback operations used.
-   * May be nullptr.
+  /* gpos_tag()
+   * If not HB_TAG_NONE, then must match found GPOS script tag for
+   * GPOS to be applied.  Otherwise, fallback positioning will be used.
    */
-  bool (*disable_otl) (const hb_ot_shape_plan_t *plan);
+  hb_tag_t gpos_tag;
 
   /* reorder_marks()
    * Called during shape().
    * Shapers can use to modify ordering of combining marks.
-   * May be nullptr.
+   * May be NULL.
    */
   void (*reorder_marks) (const hb_ot_shape_plan_t *plan,
 			 hb_buffer_t              *buffer,
@@ -234,12 +232,6 @@
       return &_hb_ot_complex_shaper_hangul;
 
 
-    /* Unicode-2.0 additions */
-    case HB_SCRIPT_TIBETAN:
-
-      return &_hb_ot_complex_shaper_tibetan;
-
-
     /* Unicode-1.1 additions */
     case HB_SCRIPT_HEBREW:
 
@@ -246,13 +238,6 @@
       return &_hb_ot_complex_shaper_hebrew;
 
 
-    /* ^--- Add new shapers here */
-
-#if 0
-    /* Unicode-4.1 additions */
-    case HB_SCRIPT_NEW_TAI_LUE:
-#endif
-
     /* Unicode-1.1 additions */
     case HB_SCRIPT_BENGALI:
     case HB_SCRIPT_DEVANAGARI:
@@ -270,11 +255,13 @@
       /* If the designer designed the font for the 'DFLT' script,
        * (or we ended up arbitrarily pick 'latn'), use the default shaper.
        * Otherwise, use the specific shaper.
-       * Note that for some simple scripts, there may not be *any*
-       * GSUB/GPOS needed, so there may be no scripts found! */
+       *
+       * If it's indy3 tag, send to USE. */
       if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
 	  planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
 	return &_hb_ot_complex_shaper_default;
+      else if ((planner->map.chosen_script[0] & 0x000000FF) == '3')
+	return &_hb_ot_complex_shaper_use;
       else
 	return &_hb_ot_complex_shaper_indic;
 
@@ -291,7 +278,7 @@
 
 
     /* Unicode-2.0 additions */
-    //case HB_SCRIPT_TIBETAN:
+    case HB_SCRIPT_TIBETAN:
 
     /* Unicode-3.0 additions */
     //case HB_SCRIPT_MONGOLIAN:
@@ -359,9 +346,9 @@
 
     /* Unicode-8.0 additions */
     case HB_SCRIPT_AHOM:
-    //case HB_SCRIPT_MULTANI:
 
     /* Unicode-9.0 additions */
+    //case HB_SCRIPT_ADLAM:
     case HB_SCRIPT_BHAIKSUKI:
     case HB_SCRIPT_MARCHEN:
     case HB_SCRIPT_NEWA:
@@ -374,7 +361,9 @@
     /* Unicode-11.0 additions */
     case HB_SCRIPT_DOGRA:
     case HB_SCRIPT_GUNJALA_GONDI:
+    //case HB_SCRIPT_HANIFI_ROHINGYA:
     case HB_SCRIPT_MAKASAR:
+    //case HB_SCRIPT_SOGDIAN:
 
       /* If the designer designed the font for the 'DFLT' script,
        * (or we ended up arbitrarily pick 'latn'), use the default shaper.
@@ -386,6 +375,10 @@
 	return &_hb_ot_complex_shaper_default;
       else
 	return &_hb_ot_complex_shaper_use;
+
+    /* https://github.com/harfbuzz/harfbuzz/issues/1162 */
+    case HB_SCRIPT_MYANMAR_ZAWGYI:
+      return &_hb_ot_complex_shaper_myanmar_zawgyi;
   }
 }
 

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -25,7 +25,7 @@
  */
 
 #include "hb-ot-shape-fallback.hh"
-#include "hb-ot-layout-gsubgpos.hh"
+#include "hb-ot-kern-table.hh"
 
 static unsigned int
 recategorize_combining_class (hb_codepoint_t u,
@@ -162,9 +162,9 @@
 }
 
 void
-_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
-						   hb_font_t *font HB_UNUSED,
-						   hb_buffer_t  *buffer)
+_hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
+						        hb_font_t *font HB_UNUSED,
+						        hb_buffer_t  *buffer)
 {
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
@@ -417,9 +417,9 @@
 }
 
 void
-_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
-				hb_font_t *font,
-				hb_buffer_t  *buffer)
+_hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
+				     hb_font_t *font,
+				     hb_buffer_t  *buffer)
 {
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
@@ -435,60 +435,38 @@
 }
 
 
-/* Performs old-style TrueType kerning. */
-void
-_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
-			    hb_font_t *font,
-			    hb_buffer_t  *buffer)
+struct hb_ot_shape_fallback_kern_driver_t
 {
-  if (!plan->has_kern) return;
+  hb_ot_shape_fallback_kern_driver_t (hb_font_t   *font_,
+				      hb_buffer_t *buffer) :
+    font (font_), direction (buffer->props.direction) {}
 
-  OT::hb_ot_apply_context_t c (1, font, buffer);
-  c.set_lookup_mask (plan->kern_mask);
-  c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
-  OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
-  skippy_iter.init (&c);
-
-  unsigned int count = buffer->len;
-  hb_glyph_info_t *info = buffer->info;
-  hb_glyph_position_t *pos = buffer->pos;
-  for (unsigned int idx = 0; idx < count;)
+  hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
   {
-    skippy_iter.reset (idx, 1);
-    if (!skippy_iter.next ())
-    {
-      idx++;
-      continue;
-    }
+    hb_position_t kern = 0;
+    font->get_glyph_kerning_for_direction (first, second,
+					   direction,
+					   &kern, &kern);
+    return kern;
+  }
 
-    hb_position_t x_kern, y_kern;
-    font->get_glyph_kerning_for_direction (info[idx].codepoint,
-					   info[skippy_iter.idx].codepoint,
-					   buffer->props.direction,
-					   &x_kern, &y_kern);
+  hb_font_t *font;
+  hb_direction_t direction;
+};
 
-    if (x_kern)
-    {
-      hb_position_t kern1 = x_kern >> 1;
-      hb_position_t kern2 = x_kern - kern1;
-      pos[idx].x_advance += kern1;
-      pos[skippy_iter.idx].x_advance += kern2;
-      pos[skippy_iter.idx].x_offset += kern2;
-      buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
-    }
-
-    if (y_kern)
-    {
-      hb_position_t kern1 = y_kern >> 1;
-      hb_position_t kern2 = y_kern - kern1;
-      pos[idx].y_advance += kern1;
-      pos[skippy_iter.idx].y_advance += kern2;
-      pos[skippy_iter.idx].y_offset += kern2;
-      buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
-    }
-
-    idx = skippy_iter.idx;
-  }
+/* Performs font-assisted kerning. */
+void
+_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
+			    hb_font_t *font,
+			    hb_buffer_t *buffer)
+{
+  if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
+      !font->has_glyph_h_kerning_func () :
+      !font->has_glyph_v_kerning_func ())
+    return;
+  hb_ot_shape_fallback_kern_driver_t driver (font, buffer);
+  hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver);
+  machine.kern (font, buffer, plan->kern_mask, false);
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -32,13 +32,13 @@
 #include "hb-ot-shape.hh"
 
 
-HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
-						 hb_font_t *font,
-						 hb_buffer_t  *buffer);
+HB_INTERNAL void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
+						      hb_font_t *font,
+						      hb_buffer_t  *buffer);
 
-HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
-								    hb_font_t *font,
-								    hb_buffer_t  *buffer);
+HB_INTERNAL void _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
+									 hb_font_t *font,
+									 hb_buffer_t  *buffer);
 
 
 HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -264,16 +264,7 @@
     decompose_current_character (c, short_circuit);
 }
 
-static inline void
-decompose_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool might_short_circuit, bool always_short_circuit)
-{
-  if (likely (c->buffer->idx + 1 == end))
-    decompose_current_character (c, might_short_circuit);
-  else
-    decompose_multi_char_cluster (c, end, always_short_circuit);
-}
 
-
 static int
 compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
 {
@@ -294,6 +285,16 @@
   _hb_buffer_assert_unicode_vars (buffer);
 
   hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
+  if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_AUTO)
+  {
+    if (plan->has_gpos_mark)
+      // https://github.com/harfbuzz/harfbuzz/issues/653#issuecomment-423905920
+      //mode = HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED;
+      mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
+    else
+      mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
+  }
+
   const hb_ot_shape_normalize_context_t c = {
     plan,
     buffer,
@@ -318,105 +319,81 @@
 
   /* First round, decompose */
 
-  buffer->clear_output ();
-  count = buffer->len;
-  for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
+  bool all_simple = true;
   {
-    unsigned int end;
-    for (end = buffer->idx + 1; end < count; end++)
-      if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))))
-        break;
+    buffer->clear_output ();
+    count = buffer->len;
+    buffer->idx = 0;
+    do
+    {
+      unsigned int end;
+      for (end = buffer->idx + 1; end < count; end++)
+	if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))))
+	  break;
 
-    decompose_cluster (&c, end, might_short_circuit, always_short_circuit);
-  }
-  buffer->swap_buffers ();
+      if (end < count)
+	end--; /* Leave one base for the marks to cluster with. */
 
+      /* From idx to end are simple clusters. */
+      if (might_short_circuit)
+      {
+        unsigned int done = font->get_nominal_glyphs (end - buffer->idx,
+						      &buffer->cur().codepoint,
+						      sizeof (buffer->info[0]),
+						      &buffer->cur().glyph_index(),
+						      sizeof (buffer->info[0]));
+	buffer->next_glyphs (done);
+      }
+      while (buffer->idx < end && buffer->successful)
+	decompose_current_character (&c, might_short_circuit);
 
-  /* Second round, reorder (inplace) */
+      if (buffer->idx == count || !buffer->successful)
+	break;
 
-  count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-  {
-    if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
-      continue;
+      all_simple = false;
 
-    unsigned int end;
-    for (end = i + 1; end < count; end++)
-      if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
-        break;
+      /* Find all the marks now. */
+      for (end = buffer->idx + 1; end < count; end++)
+	if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end])))
+	  break;
 
-    /* We are going to do a O(n^2).  Only do this if the sequence is short. */
-    if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
-      i = end;
-      continue;
+      /* idx to end is one non-simple cluster. */
+      decompose_multi_char_cluster (&c, end, always_short_circuit);
     }
-
-    buffer->sort (i, end, compare_combining_class);
-
-    if (plan->shaper->reorder_marks)
-      plan->shaper->reorder_marks (plan, buffer, i, end);
-
-    i = end;
+    while (buffer->idx < count && buffer->successful);
+    buffer->swap_buffers ();
   }
 
 
-  if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
-      mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
-    return;
+  /* Second round, reorder (inplace) */
 
-  /* Third round, recompose */
-
-  /* As noted in the comment earlier, we don't try to combine
-   * ccc=0 chars with their previous Starter. */
-
-  buffer->clear_output ();
-  count = buffer->len;
-  unsigned int starter = 0;
-  buffer->next_glyph ();
-  while (buffer->idx < count && buffer->successful)
+  if (!all_simple)
   {
-    hb_codepoint_t composed, glyph;
-    if (/* We don't try to compose a non-mark character with it's preceding starter.
-	 * This is both an optimization to avoid trying to compose every two neighboring
-	 * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
-	 * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
-	HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
+    count = buffer->len;
+    for (unsigned int i = 0; i < count; i++)
     {
-      if (/* If there's anything between the starter and this char, they should have CCC
-	   * smaller than this character's. */
-	  (starter == buffer->out_len - 1 ||
-	   info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
-	  /* And compose. */
-	  c.compose (&c,
-		     buffer->out_info[starter].codepoint,
-		     buffer->cur().codepoint,
-		     &composed) &&
-	  /* And the font has glyph for the composite. */
-	  font->get_nominal_glyph (composed, &glyph))
-      {
-	/* Composes. */
-	buffer->next_glyph (); /* Copy to out-buffer. */
-	if (unlikely (!buffer->successful))
-	  return;
-	buffer->merge_out_clusters (starter, buffer->out_len);
-	buffer->out_len--; /* Remove the second composable. */
-	/* Modify starter and carry on. */
-	buffer->out_info[starter].codepoint = composed;
-	buffer->out_info[starter].glyph_index() = glyph;
-	_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
+      if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
+	continue;
 
+      unsigned int end;
+      for (end = i + 1; end < count; end++)
+	if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
+	  break;
+
+      /* We are going to do a O(n^2).  Only do this if the sequence is short. */
+      if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
+	i = end;
 	continue;
       }
-    }
 
-    /* Blocked, or doesn't compose. */
-    buffer->next_glyph ();
+      buffer->sort (i, end, compare_combining_class);
 
-    if (info_cc (buffer->prev()) == 0)
-      starter = buffer->out_len - 1;
+      if (plan->shaper->reorder_marks)
+	plan->shaper->reorder_marks (plan, buffer, i, end);
+
+      i = end;
+    }
   }
-  buffer->swap_buffers ();
-
   if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
   {
     /* For all CGJ, check if it prevented any reordering at all.
@@ -430,4 +407,63 @@
 	_hb_glyph_info_unhide (&buffer->info[i]);
       }
   }
+
+
+  /* Third round, recompose */
+
+  if (!all_simple &&
+      (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS ||
+       mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT))
+  {
+    /* As noted in the comment earlier, we don't try to combine
+     * ccc=0 chars with their previous Starter. */
+
+    buffer->clear_output ();
+    count = buffer->len;
+    unsigned int starter = 0;
+    buffer->next_glyph ();
+    while (buffer->idx < count && buffer->successful)
+    {
+      hb_codepoint_t composed, glyph;
+      if (/* We don't try to compose a non-mark character with it's preceding starter.
+	   * This is both an optimization to avoid trying to compose every two neighboring
+	   * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
+	   * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
+	  HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
+      {
+	if (/* If there's anything between the starter and this char, they should have CCC
+	     * smaller than this character's. */
+	    (starter == buffer->out_len - 1 ||
+	     info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
+	    /* And compose. */
+	    c.compose (&c,
+		       buffer->out_info[starter].codepoint,
+		       buffer->cur().codepoint,
+		       &composed) &&
+	    /* And the font has glyph for the composite. */
+	    font->get_nominal_glyph (composed, &glyph))
+	{
+	  /* Composes. */
+	  buffer->next_glyph (); /* Copy to out-buffer. */
+	  if (unlikely (!buffer->successful))
+	    return;
+	  buffer->merge_out_clusters (starter, buffer->out_len);
+	  buffer->out_len--; /* Remove the second composable. */
+	  /* Modify starter and carry on. */
+	  buffer->out_info[starter].codepoint = composed;
+	  buffer->out_info[starter].glyph_index() = glyph;
+	  _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
+
+	  continue;
+	}
+      }
+
+      /* Blocked, or doesn't compose. */
+      buffer->next_glyph ();
+
+      if (info_cc (buffer->prev()) == 0)
+	starter = buffer->out_len - 1;
+    }
+    buffer->swap_buffers ();
+  }
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -38,10 +38,11 @@
 enum hb_ot_shape_normalization_mode_t {
   HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
   HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
-  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
-  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* Never composes base-to-base */
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */
 
-  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS
+  HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* See hb-ot-shape-normalize.cc for logic. */
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_AUTO
 };
 
 HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper,

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -36,32 +36,111 @@
 #include "hb-ot-shape-normalize.hh"
 
 #include "hb-ot-face.hh"
-#include "hb-ot-layout.hh"
-#include "hb-unicode.hh"
+
 #include "hb-set.hh"
 
-#include "hb-ot-layout-gsubgpos.hh"
 #include "hb-aat-layout.hh"
 
-static hb_tag_t common_features[] = {
-  HB_TAG('c','c','m','p'),
-  HB_TAG('l','o','c','l'),
-  HB_TAG('m','a','r','k'),
-  HB_TAG('m','k','m','k'),
-  HB_TAG('r','l','i','g'),
-};
 
+static bool
+_hb_apply_morx (hb_face_t *face)
+{
+  if (hb_options ().aat &&
+      hb_aat_layout_has_substitution (face))
+    return true;
 
-static hb_tag_t horizontal_features[] = {
-  HB_TAG('c','a','l','t'),
-  HB_TAG('c','l','i','g'),
-  HB_TAG('c','u','r','s'),
-  HB_TAG('k','e','r','n'),
-  HB_TAG('l','i','g','a'),
-  HB_TAG('r','c','l','t'),
+  return !hb_ot_layout_has_substitution (face) &&
+	 hb_aat_layout_has_substitution (face);
+}
+
+void
+hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
+				const int          *coords,
+				unsigned int        num_coords)
+{
+  plan.props = props;
+  plan.shaper = shaper;
+  map.compile (plan.map, coords, num_coords);
+
+  plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
+  plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
+  plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
+  plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
+  plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
+  hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
+		      HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
+  plan.kern_mask = plan.map.get_mask (kern_tag);
+
+  plan.requested_kerning = !!plan.kern_mask;
+  bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX;
+  bool disable_gpos = plan.shaper->gpos_tag &&
+		      plan.shaper->gpos_tag != plan.map.chosen_script[1];
+
+  /*
+   * Decide who provides glyph classes. GDEF or Unicode.
+   */
+
+  if (!hb_ot_layout_has_glyph_classes (face))
+    plan.fallback_glyph_classes = true;
+
+  /*
+   * Decide who does substitutions. GSUB, morx, or fallback.
+   */
+
+  plan.apply_morx = _hb_apply_morx (face);
+
+  /*
+   * Decide who does positioning. GPOS, kerx, kern, or fallback.
+   */
+
+  if (hb_options ().aat && hb_aat_layout_has_positioning (face))
+    plan.apply_kerx = true;
+  else if (!disable_gpos && hb_ot_layout_has_positioning (face))
+    plan.apply_gpos = true;
+  else if (hb_aat_layout_has_positioning (face))
+    plan.apply_kerx = true;
+
+  if (plan.requested_kerning && !plan.apply_kerx && !has_gpos_kern)
+  {
+    /* Apparently Apple applies kerx if GPOS kern was not applied. */
+    if (hb_aat_layout_has_positioning (face))
+      plan.apply_kerx = true;
+    if (hb_ot_layout_has_kerning (face))
+      plan.apply_kern = true;
+    else
+      plan.fallback_kerning = true;
+  }
+
+  plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
+  if (!plan.apply_gpos && !plan.apply_kerx)
+    plan.fallback_mark_positioning = true;
+
+  /* Currently we always apply trak. */
+  plan.apply_trak = hb_aat_layout_has_tracking (face);
+}
+
+
+static const hb_ot_map_feature_t
+common_features[] =
+{
+  {HB_TAG('c','c','m','p'), F_GLOBAL},
+  {HB_TAG('l','o','c','l'), F_GLOBAL},
+  {HB_TAG('m','a','r','k'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('m','k','m','k'), F_GLOBAL_MANUAL_JOINERS},
+  {HB_TAG('r','l','i','g'), F_GLOBAL},
 };
 
 
+static const hb_ot_map_feature_t
+horizontal_features[] =
+{
+  {HB_TAG('c','a','l','t'), F_GLOBAL},
+  {HB_TAG('c','l','i','g'), F_GLOBAL},
+  {HB_TAG('c','u','r','s'), F_GLOBAL},
+  {HB_TAG('k','e','r','n'), F_GLOBAL_HAS_FALLBACK},
+  {HB_TAG('l','i','g','a'), F_GLOBAL},
+  {HB_TAG('r','c','l','t'), F_GLOBAL},
+};
 
 static void
 hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
@@ -71,17 +150,17 @@
 {
   hb_ot_map_builder_t *map = &planner->map;
 
-  map->add_global_bool_feature (HB_TAG('r','v','r','n'));
+  map->enable_feature (HB_TAG('r','v','r','n'));
   map->add_gsub_pause (nullptr);
 
   switch (props->direction) {
     case HB_DIRECTION_LTR:
-      map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
-      map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
+      map->enable_feature (HB_TAG ('l','t','r','a'));
+      map->enable_feature (HB_TAG ('l','t','r','m'));
       break;
     case HB_DIRECTION_RTL:
-      map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
-      map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
+      map->enable_feature (HB_TAG ('r','t','l','a'));
+      map->add_feature (HB_TAG ('r','t','l','m'));
       break;
     case HB_DIRECTION_TTB:
     case HB_DIRECTION_BTT:
@@ -90,21 +169,27 @@
       break;
   }
 
-  map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE);
-  map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE);
-  map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE);
+  /* Automatic fractions. */
+  map->add_feature (HB_TAG ('f','r','a','c'));
+  map->add_feature (HB_TAG ('n','u','m','r'));
+  map->add_feature (HB_TAG ('d','n','o','m'));
 
+  /* Random! */
+  map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE);
+
+  map->enable_feature (HB_TAG('H','A','R','F'));
+
   if (planner->shaper->collect_features)
     planner->shaper->collect_features (planner);
 
+  map->enable_feature (HB_TAG('B','U','Z','Z'));
+
   for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
-    map->add_global_bool_feature (common_features[i]);
+    map->add_feature (common_features[i]);
 
   if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
     for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
-      map->add_feature (horizontal_features[i], 1, F_GLOBAL |
-			(horizontal_features[i] == HB_TAG('k','e','r','n') ?
-			 F_HAS_FALLBACK : F_NONE));
+      map->add_feature (horizontal_features[i]);
   else
   {
     /* We really want to find a 'vert' feature if there's any in the font, no
@@ -111,17 +196,19 @@
      * matter which script/langsys it is listed (or not) under.
      * See various bugs referenced from:
      * https://github.com/harfbuzz/harfbuzz/issues/63 */
-    map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH);
+    map->enable_feature (HB_TAG ('v','e','r','t'), F_GLOBAL_SEARCH);
   }
 
   if (planner->shaper->override_features)
     planner->shaper->override_features (planner);
 
-  for (unsigned int i = 0; i < num_user_features; i++) {
+  for (unsigned int i = 0; i < num_user_features; i++)
+  {
     const hb_feature_t *feature = &user_features[i];
-    map->add_feature (feature->tag, feature->value,
-		      (feature->start == 0 && feature->end == (unsigned int) -1) ?
-		       F_GLOBAL : F_NONE);
+    map->add_feature (feature->tag,
+		      (feature->start == HB_FEATURE_GLOBAL_START &&
+		       feature->end == HB_FEATURE_GLOBAL_END) ?  F_GLOBAL : F_NONE,
+		      feature->value);
   }
 }
 
@@ -184,7 +271,12 @@
 
   hb_ot_shape_planner_t planner (shape_plan);
 
-  planner.shaper = hb_ot_shape_complex_categorize (&planner);
+  /* Ugly that we have to do this here...
+   * If we are going to apply morx, choose default shaper. */
+  if (_hb_apply_morx (planner.face))
+    planner.shaper = &_hb_ot_complex_shaper_default;
+  else
+    planner.shaper = hb_ot_shape_complex_categorize (&planner);
 
   hb_ot_shape_collect_features (&planner, &shape_plan->props,
 				user_features, num_user_features);
@@ -229,8 +321,6 @@
   unsigned int        num_user_features;
 
   /* Transient stuff */
-  bool fallback_positioning;
-  bool fallback_glyph_classes;
   hb_direction_t target_direction;
 };
 
@@ -244,10 +334,39 @@
 static void
 hb_set_unicode_props (hb_buffer_t *buffer)
 {
+  /* Implement enough of Unicode Graphemes here that shaping
+   * in reverse-direction wouldn't break graphemes.  Namely,
+   * we mark all marks and ZWJ and ZWJ,Extended_Pictographic
+   * sequences as continuations.  The foreach_grapheme()
+   * macro uses this bit.
+   *
+   * https://www.unicode.org/reports/tr29/#Regex_Definitions
+   */
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
+  {
     _hb_glyph_info_set_unicode_props (&info[i], buffer);
+
+    /* Marks are already set as continuation by the above line.
+     * Handle Emoji_Modifier and ZWJ-continuation. */
+    if (unlikely (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL &&
+		  hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F3FBu, 0x1F3FFu)))
+    {
+	_hb_glyph_info_set_continuation (&info[i]);
+    }
+    else if (unlikely (_hb_glyph_info_is_zwj (&info[i])))
+    {
+      _hb_glyph_info_set_continuation (&info[i]);
+      if (i + 1 < count &&
+	  _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint))
+      {
+        i++;
+	_hb_glyph_info_set_unicode_props (&info[i], buffer);
+	_hb_glyph_info_set_continuation (&info[i]);
+      }
+    }
+  }
 }
 
 static void
@@ -255,8 +374,7 @@
 {
   if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
       buffer->context_len[0] ||
-      _hb_glyph_info_get_general_category (&buffer->info[0]) !=
-      HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+      !_hb_glyph_info_is_unicode_mark (&buffer->info[0]))
     return;
 
   if (!font->has_glyph (0x25CCu))
@@ -285,26 +403,12 @@
   if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII))
     return;
 
-  /* Loop duplicated in hb_ensure_native_direction(), and in _hb-coretext.cc */
-  unsigned int base = 0;
-  unsigned int count = buffer->len;
-  hb_glyph_info_t *info = buffer->info;
-  for (unsigned int i = 1; i < count; i++)
-  {
-    if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])) &&
-		!_hb_glyph_info_is_joiner (&info[i])))
-    {
-      if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
-	buffer->merge_clusters (base, i);
-      else
-	buffer->unsafe_to_break (base, i);
-      base = i;
-    }
-  }
   if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
-    buffer->merge_clusters (base, count);
+    foreach_grapheme (buffer, start, end)
+      buffer->merge_clusters (start, end);
   else
-    buffer->unsafe_to_break (base, count);
+    foreach_grapheme (buffer, start, end)
+      buffer->unsafe_to_break (start, end);
 }
 
 static void
@@ -322,25 +426,17 @@
       (HB_DIRECTION_IS_VERTICAL   (direction) &&
        direction != HB_DIRECTION_TTB))
   {
-    /* Same loop as hb_form_clusters().
-     * Since form_clusters() merged clusters already, we don't merge. */
-    unsigned int base = 0;
-    unsigned int count = buffer->len;
-    hb_glyph_info_t *info = buffer->info;
-    for (unsigned int i = 1; i < count; i++)
-    {
-      if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))))
+
+    if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
+      foreach_grapheme (buffer, start, end)
       {
-	if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
-	  buffer->merge_clusters (base, i);
-	buffer->reverse_range (base, i);
-
-	base = i;
+	buffer->merge_clusters (start, end);
+	buffer->reverse_range (start, end);
       }
-    }
-    if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
-      buffer->merge_clusters (base, count);
-    buffer->reverse_range (base, count);
+    else
+      foreach_grapheme (buffer, start, end)
+	/* form_clusters() merged clusters already, we don't merge. */
+	buffer->reverse_range (start, end);
 
     buffer->reverse ();
 
@@ -352,7 +448,7 @@
 /* Substitute */
 
 static inline void
-hb_ot_mirror_chars (hb_ot_shape_context_t *c)
+hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
 {
   if (HB_DIRECTION_IS_FORWARD (c->target_direction))
     return;
@@ -373,7 +469,7 @@
 }
 
 static inline void
-hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
+hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
 {
   if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
       !c->plan->has_frac)
@@ -423,7 +519,7 @@
 }
 
 static inline void
-hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
+hb_ot_shape_initialize_masks (const hb_ot_shape_context_t *c)
 {
   hb_ot_map_t *map = &c->plan->map;
   hb_buffer_t *buffer = c->buffer;
@@ -433,7 +529,7 @@
 }
 
 static inline void
-hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
+hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c)
 {
   hb_ot_map_t *map = &c->plan->map;
   hb_buffer_t *buffer = c->buffer;
@@ -455,7 +551,7 @@
 }
 
 static void
-hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
+hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c)
 {
   hb_buffer_t *buffer = c->buffer;
 
@@ -474,7 +570,7 @@
 }
 
 static void
-hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
+hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c)
 {
   hb_buffer_t *buffer = c->buffer;
 
@@ -485,26 +581,16 @@
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   hb_glyph_position_t *pos = buffer->pos;
-  unsigned int i = 0;
-  for (i = 0; i < count; i++)
-  {
-    if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i])))
-      break;
-  }
 
-  /* No default-ignorables found; return. */
-  if (i == count)
-    return;
-
-  hb_codepoint_t space;
+  hb_codepoint_t invisible = c->buffer->invisible;
   if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) &&
-      c->font->get_nominal_glyph (' ', &space))
+      (invisible || c->font->get_nominal_glyph (' ', &invisible)))
   {
-    /* Replace default-ignorables with a zero-advance space glyph. */
-    for (/*continue*/; i < count; i++)
+    /* Replace default-ignorables with a zero-advance invisible glyph. */
+    for (unsigned int i = 0; i < count; i++)
     {
       if (_hb_glyph_info_is_default_ignorable (&info[i]))
-	info[i].codepoint = space;
+	info[i].codepoint = invisible;
     }
   }
   else
@@ -511,8 +597,8 @@
   {
     /* Merge clusters and delete default-ignorables.
      * NOTE! We can't use out-buffer as we have positioning data. */
-    unsigned int j = i;
-    for (; i < count; i++)
+    unsigned int j = 0;
+    for (unsigned int i = 0; i < count; i++)
     {
       if (_hb_glyph_info_is_default_ignorable (&info[i]))
       {
@@ -567,7 +653,7 @@
 }
 
 static inline void
-hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
+hb_synthesize_glyph_classes (const hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
   hb_glyph_info_t *info = c->buffer->info;
@@ -593,7 +679,7 @@
 }
 
 static inline void
-hb_ot_substitute_default (hb_ot_shape_context_t *c)
+hb_ot_substitute_default (const hb_ot_shape_context_t *c)
 {
   hb_buffer_t *buffer = c->buffer;
 
@@ -606,8 +692,8 @@
   hb_ot_shape_setup_masks (c);
 
   /* This is unfortunate to go here, but necessary... */
-  if (c->fallback_positioning)
-    _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
+  if (c->plan->fallback_mark_positioning)
+    _hb_ot_shape_fallback_mark_position_recategorize_marks (c->plan, c->font, buffer);
 
   hb_ot_map_glyphs_fast (buffer);
 
@@ -615,23 +701,23 @@
 }
 
 static inline void
-hb_ot_substitute_complex (hb_ot_shape_context_t *c)
+hb_ot_substitute_complex (const hb_ot_shape_context_t *c)
 {
   hb_buffer_t *buffer = c->buffer;
 
   hb_ot_layout_substitute_start (c->font, buffer);
 
-  if (!hb_ot_layout_has_glyph_classes (c->face))
+  if (c->plan->fallback_glyph_classes)
     hb_synthesize_glyph_classes (c);
 
-  c->plan->substitute (c->font, buffer);
-
-  if (0) /* XXX Call morx instead. */
-    hb_aat_layout_substitute (c->font, c->buffer);
+  if (unlikely (c->plan->apply_morx))
+    hb_aat_layout_substitute (c->plan, c->font, c->buffer);
+  else
+    c->plan->substitute (c->font, buffer);
 }
 
 static inline void
-hb_ot_substitute (hb_ot_shape_context_t *c)
+hb_ot_substitute (const hb_ot_shape_context_t *c)
 {
   hb_ot_substitute_default (c);
 
@@ -671,7 +757,7 @@
 }
 
 static inline void
-hb_ot_position_default (hb_ot_shape_context_t *c)
+hb_ot_position_default (const hb_ot_shape_context_t *c)
 {
   hb_direction_t direction = c->buffer->props.direction;
   unsigned int count = c->buffer->len;
@@ -705,7 +791,7 @@
 }
 
 static inline void
-hb_ot_position_complex (hb_ot_shape_context_t *c)
+hb_ot_position_complex (const hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
   hb_glyph_info_t *info = c->buffer->info;
@@ -720,7 +806,7 @@
    * If fallback positinoing happens or GPOS is present, we don't
    * care.
    */
-  bool adjust_offsets_when_zeroing = c->fallback_positioning &&
+  bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning &&
 				     !c->plan->shaper->fallback_position &&
 				     HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
 
@@ -735,33 +821,40 @@
 
   hb_ot_layout_position_start (c->font, c->buffer);
 
-  switch (c->plan->shaper->zero_width_marks)
-  {
-    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
-      zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
-      break;
+  if (!c->plan->apply_kerx)
+    switch (c->plan->shaper->zero_width_marks)
+    {
+      case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+	zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
+	break;
 
-    default:
-    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
-    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
-      break;
-  }
+      default:
+      case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+      case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+	break;
+    }
 
-  if (likely (!c->fallback_positioning))
+  if (c->plan->apply_gpos)
     c->plan->position (c->font, c->buffer);
+  else if (c->plan->apply_kerx)
+    hb_aat_layout_position (c->plan, c->font, c->buffer);
 
-  switch (c->plan->shaper->zero_width_marks)
-  {
-    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
-      zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
-      break;
+  if (c->plan->apply_trak)
+    hb_aat_layout_track (c->plan, c->font, c->buffer);
 
-    default:
-    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
-    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
-      break;
-  }
+  if (!c->plan->apply_kerx)
+    switch (c->plan->shaper->zero_width_marks)
+    {
+      case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+	zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
+	break;
 
+      default:
+      case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+      case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+	break;
+    }
+
   /* Finishing off GPOS has to follow a certain order. */
   hb_ot_layout_position_finish_advances (c->font, c->buffer);
   hb_ot_zero_width_default_ignorables (c);
@@ -776,7 +869,7 @@
 }
 
 static inline void
-hb_ot_position (hb_ot_shape_context_t *c)
+hb_ot_position (const hb_ot_shape_context_t *c)
 {
   c->buffer->clear_positions ();
 
@@ -784,8 +877,8 @@
 
   hb_ot_position_complex (c);
 
-  if (c->fallback_positioning && c->plan->shaper->fallback_position)
-    _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
+  if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
+    _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
 
   if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
     hb_buffer_reverse (c->buffer);
@@ -792,12 +885,12 @@
 
   /* Visual fallback goes here. */
 
-  if (c->fallback_positioning)
+  if (c->plan->apply_kern)
+    hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask);
+  else if (c->plan->fallback_kerning)
     _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
 
   _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
-
-  //hb_aat_layout_position (c->font, c->buffer);
 }
 
 static inline void
@@ -844,11 +937,6 @@
 			      (unsigned) HB_BUFFER_MAX_OPS_MIN);
   }
 
-  bool disable_otl = c->plan->shaper->disable_otl && c->plan->shaper->disable_otl (c->plan);
-  //c->fallback_substitute     = disable_otl || !hb_ot_layout_has_substitution (c->face);
-  c->fallback_positioning    = disable_otl || !hb_ot_layout_has_positioning (c->face);
-  c->fallback_glyph_classes  = disable_otl || !hb_ot_layout_has_glyph_classes (c->face);
-
   /* Save the original direction, we use it later. */
   c->target_direction = c->buffer->props.direction;
 

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -30,7 +30,7 @@
 #include "hb.hh"
 
 #include "hb-ot-map.hh"
-#include "hb-ot-layout.hh"
+#include "hb-shape-plan.hh"
 
 
 
@@ -42,10 +42,21 @@
   const void *data;
   hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask;
   hb_mask_t kern_mask;
-  unsigned int has_frac : 1;
-  unsigned int has_kern : 1;
-  unsigned int has_mark : 1;
 
+  bool requested_kerning : 1;
+  bool has_frac : 1;
+  bool has_gpos_mark : 1;
+  bool fallback_glyph_classes : 1;
+  bool fallback_kerning : 1;
+  bool fallback_mark_positioning : 1;
+
+  bool apply_gpos : 1;
+  bool apply_kerx : 1;
+  bool apply_kern : 1;
+  bool apply_morx : 1;
+  bool apply_trak : 1;
+
+
   inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
   {
     unsigned int table_index;
@@ -83,27 +94,10 @@
 			 shaper (nullptr),
 			 map (face, &props) {}
 
-  inline void compile (hb_ot_shape_plan_t &plan,
-		       const int          *coords,
-		       unsigned int        num_coords)
-  {
-    plan.props = props;
-    plan.shaper = shaper;
-    map.compile (plan.map, coords, num_coords);
+  HB_INTERNAL void compile (hb_ot_shape_plan_t &plan,
+			    const int          *coords,
+			    unsigned int        num_coords);
 
-    plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
-    plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
-    plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
-    plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
-
-    plan.kern_mask = plan.map.get_mask (HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
-					HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
-
-    plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
-    plan.has_kern = !!plan.kern_mask;
-    plan.has_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
-  }
-
   private:
   HB_DISALLOW_COPY_AND_ASSIGN (hb_ot_shape_planner_t);
 };

Added: 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	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -0,0 +1,2064 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ *   ./gen-tag-table.py languagetags language-subtag-registry
+ *
+ * on files with these headers:
+ *
+ * <meta name="updated_at" content="2018-09-07 07:45 PM" />
+ * File-Date: 2018-08-08
+ */
+
+#ifndef HB_OT_TAG_TABLE_HH
+#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 */
+};
+
+static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == 3u, "");
+
+/**
+ * hb_ot_tags_from_complex_language:
+ * @lang_str: a BCP 47 language tag to convert.
+ * @limit: a pointer to the end of the substring of @lang_str to consider for
+ * conversion.
+ * @count: maximum number of language tags to retrieve (IN) and actual number of
+ * language tags retrieved (OUT). If no tags are retrieved, it is not modified.
+ * @tags: array of size at least @language_count to store the language tag
+ * results
+ *
+ * Converts a multi-subtag BCP 47 language tag to language tags.
+ *
+ * Return value: Whether any language systems were retrieved.
+ **/
+static bool
+hb_ot_tags_from_complex_language (const char   *lang_str,
+				  const char   *limit,
+				  unsigned int *count /* IN/OUT */,
+				  hb_tag_t     *tags /* OUT */)
+{
+  if (subtag_matches (lang_str, limit, "-fonnapa"))
+  {
+    /* Undetermined; North American Phonetic Alphabet */
+    tags[0] = HB_TAG('A','P','P','H');  /* Phonetic transcription—Americanist conventions */
+    *count = 1;
+    return true;
+  }
+  if (subtag_matches (lang_str, limit, "-polyton"))
+  {
+    /* Modern Greek (1453-); Polytonic Greek */
+    tags[0] = HB_TAG('P','G','R',' ');  /* Polytonic Greek */
+    *count = 1;
+    return true;
+  }
+  if (subtag_matches (lang_str, limit, "-provenc"))
+  {
+    /* Occitan (post 1500); Provençal */
+    tags[0] = HB_TAG('P','R','O',' ');  /* Provençal / Old Provençal */
+    *count = 1;
+    return true;
+  }
+  if (subtag_matches (lang_str, limit, "-fonipa"))
+  {
+    /* Undetermined; International Phonetic Alphabet */
+    tags[0] = HB_TAG('I','P','P','H');  /* Phonetic transcription—IPA conventions */
+    *count = 1;
+    return true;
+  }
+  if (subtag_matches (lang_str, limit, "-geok"))
+  {
+    /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */
+    tags[0] = HB_TAG('K','G','E',' ');  /* Khutsuri Georgian */
+    *count = 1;
+    return true;
+  }
+  if (subtag_matches (lang_str, limit, "-syre"))
+  {
+    /* Undetermined; Syriac (Estrangelo variant) */
+    tags[0] = HB_TAG('S','Y','R','E');  /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */
+    *count = 1;
+    return true;
+  }
+  if (subtag_matches (lang_str, limit, "-syrj"))
+  {
+    /* Undetermined; Syriac (Western variant) */
+    tags[0] = HB_TAG('S','Y','R','J');  /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */
+    *count = 1;
+    return true;
+  }
+  if (subtag_matches (lang_str, limit, "-syrn"))
+  {
+    /* Undetermined; Syriac (Eastern variant) */
+    tags[0] = HB_TAG('S','Y','R','N');  /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */
+    *count = 1;
+    return true;
+  }
+  switch (lang_str[0])
+  {
+  case 'a':
+    if (0 == strcmp (&lang_str[1], "rt-lojban"))
+    {
+      /* Lojban */
+      tags[0] = HB_TAG('J','B','O',' ');  /* Lojban */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'c':
+    if (lang_matches (&lang_str[1], "do-hant-hk"))
+    {
+      /* Min Dong Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "do-hant-mo"))
+    {
+      /* Min Dong Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "jy-hant-hk"))
+    {
+      /* Jinyu Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "jy-hant-mo"))
+    {
+      /* Jinyu Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "mn-hant-hk"))
+    {
+      /* Mandarin Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "mn-hant-mo"))
+    {
+      /* Mandarin Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "px-hant-hk"))
+    {
+      /* Pu-Xian Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "px-hant-mo"))
+    {
+      /* Pu-Xian Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "zh-hant-hk"))
+    {
+      /* Huizhou Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "zh-hant-mo"))
+    {
+      /* Huizhou Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "zo-hant-hk"))
+    {
+      /* Min Zhong Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "zo-hant-mo"))
+    {
+      /* Min Zhong Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "do-hans"))
+    {
+      /* Min Dong Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "do-hant"))
+    {
+      /* Min Dong Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "jy-hans"))
+    {
+      /* Jinyu Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "jy-hant"))
+    {
+      /* Jinyu Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "mn-hans"))
+    {
+      /* Mandarin Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "mn-hant"))
+    {
+      /* Mandarin Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "px-hans"))
+    {
+      /* Pu-Xian Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "px-hant"))
+    {
+      /* Pu-Xian Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "zh-hans"))
+    {
+      /* Huizhou Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "zh-hant"))
+    {
+      /* Huizhou Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "zo-hans"))
+    {
+      /* Min Zhong Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "zo-hant"))
+    {
+      /* Min Zhong Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "do-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Min Dong Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "do-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Min Dong Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "do-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Min Dong Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "jy-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Jinyu Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "jy-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Jinyu Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "jy-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Jinyu Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "mn-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Mandarin Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "mn-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Mandarin Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "mn-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Mandarin Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "px-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Pu-Xian Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "px-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Pu-Xian Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "px-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Pu-Xian Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "zh-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Huizhou Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "zh-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Huizhou Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "zh-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Huizhou Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "zo-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Min Zhong Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "zo-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Min Zhong Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "zo-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Min Zhong Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'g':
+    if (lang_matches (&lang_str[1], "an-hant-hk"))
+    {
+      /* Gan Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "an-hant-mo"))
+    {
+      /* Gan Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "an-hans"))
+    {
+      /* Gan Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "an-hant"))
+    {
+      /* Gan Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "a-latg"))
+    {
+      /* Irish */
+      tags[0] = HB_TAG('I','R','T',' ');  /* Irish Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "an-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Gan Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "an-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Gan Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "an-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Gan Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'h':
+    if (lang_matches (&lang_str[1], "ak-hant-hk"))
+    {
+      /* Hakka Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "ak-hant-mo"))
+    {
+      /* Hakka Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "sn-hant-hk"))
+    {
+      /* Xiang Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "sn-hant-mo"))
+    {
+      /* Xiang Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "ak-hans"))
+    {
+      /* Hakka Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "ak-hant"))
+    {
+      /* Hakka Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "sn-hans"))
+    {
+      /* Xiang Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "sn-hant"))
+    {
+      /* Xiang Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "ak-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Hakka Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "ak-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Hakka Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "ak-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Hakka Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "sn-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Xiang Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "sn-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Xiang Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "sn-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Xiang Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'i':
+    if (0 == strcmp (&lang_str[1], "-navajo"))
+    {
+      /* Navajo */
+      unsigned int i;
+      hb_tag_t possible_tags[] = {
+	HB_TAG('N','A','V',' '),  /* Navajo */
+	HB_TAG('A','T','H',' '),  /* Athapaskan */
+      };
+      for (i = 0; i < 2 && i < *count; i++)
+	tags[i] = possible_tags[i];
+      *count = i;
+      return true;
+    }
+    if (0 == strcmp (&lang_str[1], "-hak"))
+    {
+      /* Hakka */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (0 == strcmp (&lang_str[1], "-lux"))
+    {
+      /* Luxembourgish */
+      tags[0] = HB_TAG('L','T','Z',' ');  /* Luxembourgish */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'l':
+    if (lang_matches (&lang_str[1], "zh-hans"))
+    {
+      /* Literary Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'm':
+    if (lang_matches (&lang_str[1], "np-hant-hk"))
+    {
+      /* Min Bei Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "np-hant-mo"))
+    {
+      /* Min Bei Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "np-hans"))
+    {
+      /* Min Bei Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "np-hant"))
+    {
+      /* Min Bei Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "np-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Min Bei Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "np-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Min Bei Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "np-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Min Bei Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'n':
+    if (lang_matches (&lang_str[1], "an-hant-hk"))
+    {
+      /* Min Nan Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "an-hant-mo"))
+    {
+      /* Min Nan Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "an-hans"))
+    {
+      /* Min Nan Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "an-hant"))
+    {
+      /* Min Nan Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "an-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Min Nan Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "an-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Min Nan Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "an-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Min Nan Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strcmp (&lang_str[1], "o-bok"))
+    {
+      /* Norwegian Bokmal */
+      tags[0] = HB_TAG('N','O','R',' ');  /* Norwegian */
+      *count = 1;
+      return true;
+    }
+    if (0 == strcmp (&lang_str[1], "o-nyn"))
+    {
+      /* Norwegian Nynorsk */
+      tags[0] = HB_TAG('N','Y','N',' ');  /* Norwegian Nynorsk (Nynorsk, Norwegian) */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'r':
+    if (0 == strncmp (&lang_str[1], "o-", 2)
+	&& subtag_matches (lang_str, limit, "-md"))
+    {
+      /* Romanian; Moldova */
+      tags[0] = HB_TAG('M','O','L',' ');  /* Moldavian */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'w':
+    if (lang_matches (&lang_str[1], "uu-hant-hk"))
+    {
+      /* Wu Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "uu-hant-mo"))
+    {
+      /* Wu Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "uu-hans"))
+    {
+      /* Wu Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "uu-hant"))
+    {
+      /* Wu Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "uu-", 3)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Wu Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "uu-", 3)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Wu Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "uu-", 3)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Wu Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'y':
+    if (lang_matches (&lang_str[1], "ue-hans"))
+    {
+      /* Yue Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    break;
+  case 'z':
+    if (lang_matches (&lang_str[1], "h-hant-hk"))
+    {
+      /* Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "h-hant-mo"))
+    {
+      /* Chinese */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strcmp (&lang_str[1], "h-min-nan"))
+    {
+      /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "h-hans"))
+    {
+      /* Chinese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (lang_matches (&lang_str[1], "h-hant"))
+    {
+      /* Chinese */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    if (0 == strcmp (&lang_str[1], "h-min"))
+    {
+      /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese */
+      tags[0] = HB_TAG('Z','H','S',' ');  /* Chinese Simplified */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "h-", 2)
+	&& subtag_matches (lang_str, limit, "-hk"))
+    {
+      /* Chinese; Hong Kong */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "h-", 2)
+	&& subtag_matches (lang_str, limit, "-mo"))
+    {
+      /* Chinese; Macao */
+      tags[0] = HB_TAG('Z','H','H',' ');  /* Chinese, Hong Kong SAR */
+      *count = 1;
+      return true;
+    }
+    if (0 == strncmp (&lang_str[1], "h-", 2)
+	&& subtag_matches (lang_str, limit, "-tw"))
+    {
+      /* Chinese; Taiwan, Province of China */
+      tags[0] = HB_TAG('Z','H','T',' ');  /* Chinese Traditional */
+      *count = 1;
+      return true;
+    }
+    break;
+  }
+  return false;
+}
+
+/**
+ * hb_ot_ambiguous_tag_to_language
+ * @tag: A language tag.
+ *
+ * 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.
+ *
+ * Return value: The #hb_language_t corresponding to the BCP 47 language tag,
+ * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.
+ **/
+static hb_language_t
+hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
+{
+  switch (tag)
+  {
+  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 */
+    return hb_language_from_string ("ar", -1);  /* Arabic */
+  case HB_TAG('A','R','K',' '):  /* Rakhine */
+    return hb_language_from_string ("rki", -1);  /* Rakhine */
+  case HB_TAG('A','T','H',' '):  /* Athapaskan */
+    return hb_language_from_string ("ath", -1);  /* Athapascan */
+  case HB_TAG('B','I','K',' '):  /* Bikol */
+    return hb_language_from_string ("bik", -1);  /* Bikol */
+  case HB_TAG('C','P','P',' '):  /* Creoles */
+    return hb_language_from_string ("crp", -1);  /* Creoles and pidgins */
+  case HB_TAG('C','R','R',' '):  /* Carrier */
+    return hb_language_from_string ("crx", -1);  /* Carrier */
+  case HB_TAG('D','N','K',' '):  /* Dinka */
+    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 */
+    return hb_language_from_string ("et", -1);  /* Estonian */
+  case HB_TAG('G','O','N',' '):  /* Gondi */
+    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('I','J','O',' '):  /* Ijo */
+    return hb_language_from_string ("ijo", -1);  /* Ijo */
+  case HB_TAG('I','N','U',' '):  /* Inuktitut */
+    return hb_language_from_string ("iu", -1);  /* Inuktitut */
+  case HB_TAG('I','P','K',' '):  /* Inupiat */
+    return hb_language_from_string ("ik", -1);  /* Inupiaq */
+  case HB_TAG('I','P','P','H'):  /* Phonetic transcription—IPA conventions */
+    return hb_language_from_string ("und-fonipa", -1);  /* Undetermined; International Phonetic Alphabet */
+  case HB_TAG('I','R','T',' '):  /* Irish Traditional */
+    return hb_language_from_string ("ga-Latg", -1);  /* Irish; Latin (Gaelic variant) */
+  case HB_TAG('J','I','I',' '):  /* Yiddish */
+    return hb_language_from_string ("yi", -1);  /* Yiddish */
+  case HB_TAG('K','A','L',' '):  /* Kalenjin */
+    return hb_language_from_string ("kln", -1);  /* Kalenjin */
+  case HB_TAG('K','G','E',' '):  /* Khutsuri Georgian */
+    return hb_language_from_string ("und-Geok", -1);  /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */
+  case HB_TAG('K','N','R',' '):  /* Kanuri */
+    return hb_language_from_string ("kr", -1);  /* Kanuri */
+  case HB_TAG('K','O','K',' '):  /* Konkani */
+    return hb_language_from_string ("kok", -1);  /* Konkani */
+  case HB_TAG('K','U','R',' '):  /* Kurdish */
+    return hb_language_from_string ("ku", -1);  /* Kurdish */
+  case HB_TAG('L','U','H',' '):  /* Luyia */
+    return hb_language_from_string ("luy", -1);  /* Luyia */
+  case HB_TAG('L','V','I',' '):  /* Latvian */
+    return hb_language_from_string ("lv", -1);  /* Latvian */
+  case HB_TAG('M','A','W',' '):  /* Marwari */
+    return hb_language_from_string ("mwr", -1);  /* Marwari */
+  case HB_TAG('M','L','G',' '):  /* Malagasy */
+    return hb_language_from_string ("mg", -1);  /* Malagasy */
+  case HB_TAG('M','L','Y',' '):  /* Malay */
+    return hb_language_from_string ("ms", -1);  /* Malay */
+  case HB_TAG('M','N','G',' '):  /* Mongolian */
+    return hb_language_from_string ("mn", -1);  /* Mongolian */
+  case HB_TAG('M','O','L',' '):  /* Moldavian */
+    return hb_language_from_string ("ro-MD", -1);  /* Romanian; Moldova */
+  case HB_TAG('N','E','P',' '):  /* Nepali */
+    return hb_language_from_string ("ne", -1);  /* Nepali */
+  case HB_TAG('N','I','S',' '):  /* Nisi */
+    return hb_language_from_string ("njz", -1);  /* Nyishi */
+  case HB_TAG('N','O','R',' '):  /* Norwegian */
+    return hb_language_from_string ("no", -1);  /* Norwegian */
+  case HB_TAG('O','J','B',' '):  /* Ojibway */
+    return hb_language_from_string ("oj", -1);  /* Ojibwa */
+  case HB_TAG('O','R','O',' '):  /* Oromo */
+    return hb_language_from_string ("om", -1);  /* Oromo */
+  case HB_TAG('P','A','S',' '):  /* Pashto */
+    return hb_language_from_string ("ps", -1);  /* Pashto */
+  case HB_TAG('P','G','R',' '):  /* Polytonic Greek */
+    return hb_language_from_string ("el-polyton", -1);  /* Modern Greek (1453-); Polytonic Greek */
+  case HB_TAG('P','R','O',' '):  /* Provençal / Old Provençal */
+    return hb_language_from_string ("pro", -1);  /* Old Provençal (to 1500) */
+  case HB_TAG('Q','U','H',' '):  /* Quechua (Bolivia) */
+    return hb_language_from_string ("quh", -1);  /* South Bolivian Quechua */
+  case HB_TAG('Q','V','I',' '):  /* Quechua (Ecuador) */
+    return hb_language_from_string ("qvi", -1);  /* Imbabura Highland Quichua */
+  case HB_TAG('Q','W','H',' '):  /* Quechua (Peru) */
+    return hb_language_from_string ("qwh", -1);  /* Huaylas Ancash Quechua */
+  case HB_TAG('R','A','J',' '):  /* Rajasthani */
+    return hb_language_from_string ("raj", -1);  /* Rajasthani */
+  case HB_TAG('R','O','Y',' '):  /* Romany */
+    return hb_language_from_string ("rom", -1);  /* Romany */
+  case HB_TAG('S','Q','I',' '):  /* Albanian */
+    return hb_language_from_string ("sq", -1);  /* Albanian */
+  case HB_TAG('S','Y','R',' '):  /* Syriac */
+    return hb_language_from_string ("syr", -1);  /* Syriac */
+  case HB_TAG('S','Y','R','E'):  /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */
+    return hb_language_from_string ("und-Syre", -1);  /* Undetermined; Syriac (Estrangelo variant) */
+  case HB_TAG('S','Y','R','J'):  /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */
+    return hb_language_from_string ("und-Syrj", -1);  /* Undetermined; Syriac (Western variant) */
+  case HB_TAG('S','Y','R','N'):  /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */
+    return hb_language_from_string ("und-Syrn", -1);  /* Undetermined; Syriac (Eastern variant) */
+  case HB_TAG('T','M','H',' '):  /* Tamashek */
+    return hb_language_from_string ("tmh", -1);  /* Tamashek */
+  case HB_TAG('T','N','E',' '):  /* Tundra Nenets */
+    return hb_language_from_string ("yrk", -1);  /* Nenets */
+  case HB_TAG('Z','H','H',' '):  /* Chinese, Hong Kong SAR */
+    return hb_language_from_string ("zh-HK", -1);  /* Chinese; Hong Kong */
+  case HB_TAG('Z','H','S',' '):  /* Chinese Simplified */
+    return hb_language_from_string ("zh-Hans", -1);  /* Chinese; Han (Simplified variant) */
+  case HB_TAG('Z','H','T',' '):  /* Chinese Traditional */
+    return hb_language_from_string ("zh-Hant", -1);  /* Chinese; Han (Traditional variant) */
+  default:
+    return HB_LANGUAGE_INVALID;
+  }
+}
+
+#endif /* HB_OT_TAG_TABLE_HH */
+
+/* == End of generated table == */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -36,7 +36,8 @@
 {
   /* This seems to be accurate as of end of 2012. */
 
-  switch ((hb_tag_t) script) {
+  switch ((hb_tag_t) script)
+  {
     case HB_SCRIPT_INVALID:		return HB_OT_TAG_DEFAULT_SCRIPT;
 
     /* KATAKANA and HIRAGANA both map to 'kana' */
@@ -49,8 +50,6 @@
     case HB_SCRIPT_NKO:			return HB_TAG('n','k','o',' ');
     /* Unicode-5.1 additions */
     case HB_SCRIPT_VAI:			return HB_TAG('v','a','i',' ');
-    /* Unicode-5.2 additions */
-    /* Unicode-6.0 additions */
   }
 
   /* Else, just change first char to lowercase and return */
@@ -114,6 +113,18 @@
   return HB_SCRIPT_UNKNOWN;
 }
 
+void
+hb_ot_tags_from_script (hb_script_t  script,
+			hb_tag_t    *script_tag_1,
+			hb_tag_t    *script_tag_2)
+{
+  unsigned int count = 2;
+  hb_tag_t tags[2];
+  hb_ot_tags_from_script_and_language (script, HB_LANGUAGE_INVALID, &count, tags, nullptr, nullptr);
+  *script_tag_1 = count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_SCRIPT;
+  *script_tag_2 = count > 1 ? tags[1] : HB_OT_TAG_DEFAULT_SCRIPT;
+}
+
 /*
  * Complete list at:
  * https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags
@@ -122,28 +133,37 @@
  * So we just do that, and handle the exceptional cases in a switch.
  */
 
-void
-hb_ot_tags_from_script (hb_script_t  script,
-			hb_tag_t    *script_tag_1,
-			hb_tag_t    *script_tag_2)
+static void
+hb_ot_all_tags_from_script (hb_script_t   script,
+			    unsigned int *count /* IN/OUT */,
+			    hb_tag_t     *tags /* OUT */)
 {
-  hb_tag_t new_tag;
+  unsigned int i = 0;
 
-  *script_tag_2 = HB_OT_TAG_DEFAULT_SCRIPT;
-  *script_tag_1 = hb_ot_old_tag_from_script (script);
+  hb_tag_t new_tag = hb_ot_new_tag_from_script (script);
+  if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT))
+  {
+    tags[i++] = new_tag | '3';
+    if (*count > i)
+      tags[i++] = new_tag;
+  }
 
-  new_tag = hb_ot_new_tag_from_script (script);
-  if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT)) {
-    *script_tag_2 = *script_tag_1;
-    *script_tag_1 = new_tag;
+  if (*count > i)
+  {
+    hb_tag_t old_tag = hb_ot_old_tag_from_script (script);
+    if (old_tag != HB_OT_TAG_DEFAULT_SCRIPT)
+      tags[i++] = old_tag;
   }
+
+  *count = i;
 }
 
 hb_script_t
 hb_ot_tag_to_script (hb_tag_t tag)
 {
-  if (unlikely ((tag & 0x000000FFu) == '2'))
-    return hb_ot_new_tag_to_script (tag);
+  unsigned char digit = tag & 0x000000FFu;
+  if (unlikely (digit == '2' || digit == '3'))
+    return hb_ot_new_tag_to_script (tag & 0xFFFFFF32);
 
   return hb_ot_old_tag_to_script (tag);
 }
@@ -151,732 +171,6 @@
 
 /* hb_language_t */
 
-typedef struct {
-  char language[4];
-  hb_tag_t tag;
-} LangTag;
-
-/*
- * Complete list at:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags
- *
- * Generated by intersecting the OpenType language tag list from
- * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
- * 2008-08-04, matching on name, and finally adjusted manually.
- *
- * Updated on 2012-12-07 with more research into remaining codes.
- *
- * Updated on 2013-11-23 based on usage in SIL and Microsoft fonts,
- * the new proposal from Microsoft, and latest ISO 639-3 names.
- *
- * Some items still missing.  Those are commented out at the end.
- * Keep sorted for bsearch.
- *
- * Updated as of 2015-05-06: OT1.7 on MS website has some newer
- * items that we don't have here, eg. Zazaki.  This is the new
- * items in OpenType 1.7 (red items), most of which we have:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags
- */
-
-static const LangTag ot_languages[] = {
-  {"aa",	HB_TAG('A','F','R',' ')},	/* Afar */
-  {"ab",	HB_TAG('A','B','K',' ')},	/* Abkhazian */
-  {"abq",	HB_TAG('A','B','A',' ')},	/* Abaza */
-  {"acf",	HB_TAG('F','A','N',' ')},	/* French Antillean */
-  {"ach",	HB_TAG('A','C','H',' ')},	/* Acoli */
-  {"acr",	HB_TAG('A','C','R',' ')},	/* Achi */
-  {"ada",	HB_TAG('D','N','G',' ')},	/* Dangme */
-  {"ady",	HB_TAG('A','D','Y',' ')},	/* Adyghe */
-  {"af",	HB_TAG('A','F','K',' ')},	/* Afrikaans */
-  {"ahg",	HB_TAG('A','G','W',' ')},	/* Agaw */
-  {"aii",	HB_TAG('S','W','A',' ')},	/* Swadaya Aramaic */
-  {"aio",	HB_TAG('A','I','O',' ')},	/* Aiton */
-  {"aiw",	HB_TAG('A','R','I',' ')},	/* Aari */
-  {"ak",	HB_TAG('T','W','I',' ')},	/* Akan [macrolanguage] */
-  {"aka",	HB_TAG('A','K','A',' ')},	/* Akan */
-  {"alt",	HB_TAG('A','L','T',' ')},	/* [Southern] Altai */
-  {"am",	HB_TAG('A','M','H',' ')},	/* Amharic */
-  {"amf",	HB_TAG('H','B','N',' ')},	/* Hammer-Banna */
-  {"amw",	HB_TAG('S','Y','R',' ')},	/* Western Neo-Aramaic */
-  {"an",	HB_TAG('A','R','G',' ')},	/* Aragonese */
-  {"ang",	HB_TAG('A','N','G',' ')},	/* Old English (ca. 450-1100) */
-  {"ar",	HB_TAG('A','R','A',' ')},	/* Arabic [macrolanguage] */
-  {"arb",	HB_TAG('A','R','A',' ')},	/* Standard Arabic */
-  {"arn",	HB_TAG('M','A','P',' ')},	/* Mapudungun */
-  {"ary",	HB_TAG('M','O','R',' ')},	/* Moroccan Arabic */
-  {"as",	HB_TAG('A','S','M',' ')},	/* Assamese */
-  {"ast",	HB_TAG('A','S','T',' ')},	/* Asturian/Asturleonese/Bable/Leonese */
-  {"ath",	HB_TAG('A','T','H',' ')},	/* Athapaskan [family] */
-  {"atj",	HB_TAG('R','C','R',' ')},	/* R-Cree */
-  {"atv",	HB_TAG('A','L','T',' ')},	/* [Northern] Altai */
-  {"av",	HB_TAG('A','V','R',' ')},	/* Avaric */
-  {"awa",	HB_TAG('A','W','A',' ')},	/* Awadhi */
-  {"ay",	HB_TAG('A','Y','M',' ')},	/* Aymara [macrolanguage] */
-  {"az",	HB_TAG('A','Z','E',' ')},	/* Azerbaijani [macrolanguage] */
-  {"azb",	HB_TAG('A','Z','B',' ')},	/* South Azerbaijani */
-  {"azj",	HB_TAG('A','Z','E',' ')},	/* North Azerbaijani */
-  {"ba",	HB_TAG('B','S','H',' ')},	/* Bashkir */
-  {"bad",	HB_TAG('B','A','D','0')},	/* Banda */
-  {"bai",	HB_TAG('B','M','L',' ')},	/* Bamileke [family] */
-  {"bal",	HB_TAG('B','L','I',' ')},	/* Baluchi [macrolangauge] */
-  {"ban",	HB_TAG('B','A','N',' ')},	/* Balinese */
-  {"bar",	HB_TAG('B','A','R',' ')},	/* Bavarian */
-  {"bbc",	HB_TAG('B','B','C',' ')},	/* Batak Toba */
-  {"bci",	HB_TAG('B','A','U',' ')},	/* Baoulé */
-  {"bcl",	HB_TAG('B','I','K',' ')},	/* Central Bikol */
-  {"bcq",	HB_TAG('B','C','H',' ')},	/* Bench */
-  {"bdy",	HB_TAG('B','D','Y',' ')},	/* Bandjalang */
-  {"be",	HB_TAG('B','E','L',' ')},	/* Belarusian */
-  {"bem",	HB_TAG('B','E','M',' ')},	/* Bemba (Zambia) */
-  {"ber",	HB_TAG('B','E','R',' ')},	/* Berber [family] */
-  {"bfq",	HB_TAG('B','A','D',' ')},	/* Badaga */
-  {"bft",	HB_TAG('B','L','T',' ')},	/* Balti */
-  {"bfu",	HB_TAG('L','A','H',' ')},	/* Lahuli */
-  {"bfy",	HB_TAG('B','A','G',' ')},	/* Baghelkhandi */
-  {"bg",	HB_TAG('B','G','R',' ')},	/* Bulgarian */
-  {"bgc",	HB_TAG('B','G','C',' ')},	/* Haryanvi */
-  {"bgq",	HB_TAG('B','G','Q',' ')},	/* Bagri */
-  {"bgr",	HB_TAG('Q','I','N',' ')},	/* Bawm Chin */
-  {"bhb",	HB_TAG('B','H','I',' ')},	/* Bhili */
-  {"bhk",	HB_TAG('B','I','K',' ')},	/* Albay Bicolano (retired code) */
-  {"bho",	HB_TAG('B','H','O',' ')},	/* Bhojpuri */
-  {"bi",	HB_TAG('B','I','S',' ')},	/* Bislama */
-  {"bik",	HB_TAG('B','I','K',' ')},	/* Bikol [macrolanguage] */
-  {"bin",	HB_TAG('E','D','O',' ')},	/* Bini */
-  {"bjj",	HB_TAG('B','J','J',' ')},	/* Kanauji */
-  {"bjt",	HB_TAG('B','L','N',' ')},	/* Balanta-Ganja */
-  {"bla",	HB_TAG('B','K','F',' ')},	/* Blackfoot */
-  {"ble",	HB_TAG('B','L','N',' ')},	/* Balanta-Kentohe */
-  {"blk",	HB_TAG('B','L','K',' ')},	/* Pa'O/Pa'o Karen */
-  {"bln",	HB_TAG('B','I','K',' ')},	/* Southern Catanduanes Bikol */
-  {"bm",	HB_TAG('B','M','B',' ')},	/* Bambara */
-  {"bn",	HB_TAG('B','E','N',' ')},	/* Bengali */
-  {"bo",	HB_TAG('T','I','B',' ')},	/* Tibetan */
-  {"bpy",	HB_TAG('B','P','Y',' ')},	/* Bishnupriya */
-  {"bqi",	HB_TAG('L','R','C',' ')},	/* Bakhtiari */
-  {"br",	HB_TAG('B','R','E',' ')},	/* Breton */
-  {"bra",	HB_TAG('B','R','I',' ')},	/* Braj Bhasha */
-  {"brh",	HB_TAG('B','R','H',' ')},	/* Brahui */
-  {"brx",	HB_TAG('B','R','X',' ')},	/* Bodo (India) */
-  {"bs",	HB_TAG('B','O','S',' ')},	/* Bosnian */
-  {"btb",	HB_TAG('B','T','I',' ')},	/* Beti (Cameroon) */
-  {"bto",	HB_TAG('B','I','K',' ')},	/* Rinconada Bikol */
-  {"bts",	HB_TAG('B','T','S',' ')},	/* Batak Simalungun */
-  {"bug",	HB_TAG('B','U','G',' ')},	/* Buginese */
-  {"bxr",	HB_TAG('R','B','U',' ')},	/* Russian Buriat */
-  {"byn",	HB_TAG('B','I','L',' ')},	/* Bilen */
-  {"ca",	HB_TAG('C','A','T',' ')},	/* Catalan */
-  {"cak",	HB_TAG('C','A','K',' ')},	/* Kaqchikel */
-  {"cbk",	HB_TAG('C','B','K',' ')},	/* Chavacano */
-  {"cbl",	HB_TAG('Q','I','N',' ')},	/* Bualkhaw Chin */
-  {"cco",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"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')},	/* Chinantec */
-  {"chk",	HB_TAG('C','H','K','0')},	/* Chuukese */
-  {"cho",	HB_TAG('C','H','O',' ')},	/* Choctaw */
-  {"chp",	HB_TAG('C','H','P',' ')},	/* Chipewyan */
-  {"chq",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"chr",	HB_TAG('C','H','R',' ')},	/* Cherokee */
-  {"chy",	HB_TAG('C','H','Y',' ')},	/* Cheyenne */
-  {"chz",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"cja",	HB_TAG('C','J','A',' ')},	/* Western Cham */
-  {"cjm",	HB_TAG('C','J','M',' ')},	/* Eastern Cham */
-  {"cka",	HB_TAG('Q','I','N',' ')},	/* Khumi Awa Chin */
-  {"ckb",	HB_TAG('K','U','R',' ')},	/* Central Kurdish (Sorani) */
-  {"ckt",	HB_TAG('C','H','K',' ')},	/* Chukchi */
-  {"cld",	HB_TAG('S','Y','R',' ')},	/* Chaldean Neo-Aramaic */
-  {"cle",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"cmr",	HB_TAG('Q','I','N',' ')},	/* Mro-Khimi Chin */
-  {"cnb",	HB_TAG('Q','I','N',' ')},	/* Chinbon Chin */
-  {"cnh",	HB_TAG('Q','I','N',' ')},	/* Hakha Chin */
-  {"cnk",	HB_TAG('Q','I','N',' ')},	/* Khumi Chin */
-  {"cnl",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"cnt",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"cnw",	HB_TAG('Q','I','N',' ')},	/* Ngawn Chin */
-  {"cop",	HB_TAG('C','O','P',' ')},	/* Coptic */
-  {"cpa",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"cpp",	HB_TAG('C','P','P',' ')},	/* Creoles */
-  {"cr",	HB_TAG('C','R','E',' ')},	/* Cree */
-  {"cre",	HB_TAG('Y','C','R',' ')},	/* Y-Cree */
-  {"crh",	HB_TAG('C','R','T',' ')},	/* Crimean Tatar */
-  {"crj",	HB_TAG('E','C','R',' ')},	/* [Southern] East Cree */
-  {"crk",	HB_TAG('W','C','R',' ')},	/* West-Cree */
-  {"crl",	HB_TAG('E','C','R',' ')},	/* [Northern] East Cree */
-  {"crm",	HB_TAG('M','C','R',' ')},	/* Moose Cree */
-  {"crx",	HB_TAG('C','R','R',' ')},	/* Carrier */
-  {"cs",	HB_TAG('C','S','Y',' ')},	/* Czech */
-  {"csa",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"csb",	HB_TAG('C','S','B',' ')},	/* Kashubian */
-  {"csh",	HB_TAG('Q','I','N',' ')},	/* Asho Chin */
-  {"cso",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"csy",	HB_TAG('Q','I','N',' ')},	/* Siyin Chin */
-  {"ctd",	HB_TAG('Q','I','N',' ')},	/* Tedim Chin */
-  {"cte",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"ctg",	HB_TAG('C','T','G',' ')},	/* Chittagonian */
-  {"ctl",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"cts",	HB_TAG('B','I','K',' ')},	/* Northern Catanduanes Bikol */
-  {"cu",	HB_TAG('C','S','L',' ')},	/* Church Slavic */
-  {"cuc",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"cuk",	HB_TAG('C','U','K',' ')},	/* San Blas Kuna */
-  {"cv",	HB_TAG('C','H','U',' ')},	/* Chuvash */
-  {"cvn",	HB_TAG('C','C','H','N')},	/* Chinantec */
-  {"cwd",	HB_TAG('D','C','R',' ')},	/* Woods Cree */
-  {"cy",	HB_TAG('W','E','L',' ')},	/* Welsh */
-  {"czt",	HB_TAG('Q','I','N',' ')},	/* Zotung Chin */
-  {"da",	HB_TAG('D','A','N',' ')},	/* Danish */
-  {"dao",	HB_TAG('Q','I','N',' ')},	/* Daai Chin */
-  {"dap",	HB_TAG('N','I','S',' ')},	/* Nisi (India) */
-  {"dar",	HB_TAG('D','A','R',' ')},	/* Dargwa */
-  {"dax",	HB_TAG('D','A','X',' ')},	/* Dayi */
-  {"de",	HB_TAG('D','E','U',' ')},	/* German */
-  {"dgo",	HB_TAG('D','G','O',' ')},	/* Dogri */
-  {"dhd",	HB_TAG('M','A','W',' ')},	/* Dhundari */
-  {"dhg",	HB_TAG('D','H','G',' ')},	/* Dhangu */
-  {"din",	HB_TAG('D','N','K',' ')},	/* Dinka [macrolanguage] */
-  {"diq",	HB_TAG('D','I','Q',' ')},	/* Dimli */
-  {"dje",	HB_TAG('D','J','R',' ')},	/* Zarma */
-  {"djr",	HB_TAG('D','J','R','0')},	/* Djambarrpuyngu */
-  {"dng",	HB_TAG('D','U','N',' ')},	/* Dungan */
-  {"dnj",	HB_TAG('D','N','J',' ')},	/* Dan */
-  {"doi",	HB_TAG('D','G','R',' ')},	/* Dogri [macrolanguage] */
-  {"dsb",	HB_TAG('L','S','B',' ')},	/* Lower Sorbian */
-  {"duj",	HB_TAG('D','U','J',' ')},	/* Dhuwal */
-  {"dv",	HB_TAG('D','I','V',' ')},	/* Dhivehi/Divehi/Maldivian */
-  {"dyu",	HB_TAG('J','U','L',' ')},	/* 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 */
-  {"el",	HB_TAG('E','L','L',' ')},	/* Modern Greek (1453-) */
-  {"emk",	HB_TAG('M','N','K',' ')},	/* Eastern Maninkakan */
-  {"en",	HB_TAG('E','N','G',' ')},	/* English */
-  {"enf",	HB_TAG('F','N','E',' ')},	/* Forest Nenets */
-  {"enh",	HB_TAG('T','N','E',' ')},	/* Tundra Nenets */
-  {"eo",	HB_TAG('N','T','O',' ')},	/* Esperanto */
-  {"eot",	HB_TAG('B','T','I',' ')},	/* Beti (Côte d'Ivoire) */
-  {"es",	HB_TAG('E','S','P',' ')},	/* Spanish */
-  {"esu",	HB_TAG('E','S','U',' ')},	/* Central Yupik */
-  {"et",	HB_TAG('E','T','I',' ')},	/* Estonian [macrolanguage] */
-  {"eu",	HB_TAG('E','U','Q',' ')},	/* Basque */
-  {"eve",	HB_TAG('E','V','N',' ')},	/* Even */
-  {"evn",	HB_TAG('E','V','K',' ')},	/* Evenki */
-  {"fa",	HB_TAG('F','A','R',' ')},	/* Persian [macrolanguage] */
-  {"fan",	HB_TAG('F','A','N','0')},	/* Fang */
-  {"fat",	HB_TAG('F','A','T',' ')},	/* Fanti */
-  {"ff",	HB_TAG('F','U','L',' ')},	/* Fulah [macrolanguage] */
-  {"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 ISO639 code] */
-  {"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/Francoprovençal */
-  {"fuf",	HB_TAG('F','T','A',' ')},	/* Futa */
-  {"fur",	HB_TAG('F','R','L',' ')},	/* Friulian */
-  {"fuv",	HB_TAG('F','U','V',' ')},	/* Nigerian Fulfulde */
-  {"fy",	HB_TAG('F','R','I',' ')},	/* Western Frisian */
-  {"ga",	HB_TAG('I','R','I',' ')},	/* Irish */
-  {"gaa",	HB_TAG('G','A','D',' ')},	/* Ga */
-  {"gag",	HB_TAG('G','A','G',' ')},	/* Gagauz */
-  {"gbm",	HB_TAG('G','A','W',' ')},	/* Garhwali */
-  {"gd",	HB_TAG('G','A','E',' ')},	/* Scottish Gaelic */
-  {"gez",	HB_TAG('G','E','Z',' ')},	/* Ge'ez */
-  {"ggo",	HB_TAG('G','O','N',' ')},	/* Southern Gondi */
-  {"gih",	HB_TAG('G','I','H',' ')},	/* Githabul */
-  {"gil",	HB_TAG('G','I','L','0')},	/* Kiribati (Gilbertese) */
-  {"gkp",	HB_TAG('G','K','P',' ')},	/* 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 */
-  {"gog",	HB_TAG('G','O','G',' ')},	/* Gogo */
-  {"gon",	HB_TAG('G','O','N',' ')},	/* Gondi [macrolanguage] */
-  {"grt",	HB_TAG('G','R','O',' ')},	/* Garo */
-  {"gru",	HB_TAG('S','O','G',' ')},	/* 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 */
-  {"guk",	HB_TAG('G','M','Z',' ')},	/* Gumuz */
-/*{"guk",	HB_TAG('G','U','K',' ')},*/	/* Gumuz (in SIL fonts) */
-  {"guz",	HB_TAG('G','U','Z',' ')},	/* Ekegusii/Gusii */
-  {"gv",	HB_TAG('M','N','X',' ')},	/* Manx */
-  {"ha",	HB_TAG('H','A','U',' ')},	/* Hausa */
-  {"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 */
-  {"hi",	HB_TAG('H','I','N',' ')},	/* Hindi */
-  {"hil",	HB_TAG('H','I','L',' ')},	/* Hiligaynon */
-  {"hlt",	HB_TAG('Q','I','N',' ')},	/* Matu Chin */
-  {"hmn",	HB_TAG('H','M','N',' ')},	/* Hmong */
-  {"hnd",	HB_TAG('H','N','D',' ')},	/* [Southern] Hindko */
-  {"hne",	HB_TAG('C','H','H',' ')},	/* Chattisgarhi */
-  {"hno",	HB_TAG('H','N','D',' ')},	/* [Northern] Hindko */
-  {"ho",	HB_TAG('H','M','O',' ')},	/* Hiri Motu */
-  {"hoc",	HB_TAG('H','O',' ',' ')},	/* Ho */
-  {"hoj",	HB_TAG('H','A','R',' ')},	/* Harauti */
-  {"hr",	HB_TAG('H','R','V',' ')},	/* Croatian */
-  {"hsb",	HB_TAG('U','S','B',' ')},	/* Upper Sorbian */
-  {"ht",	HB_TAG('H','A','I',' ')},	/* Haitian/Haitian Creole */
-  {"hu",	HB_TAG('H','U','N',' ')},	/* Hungarian */
-  {"hy",	HB_TAG('H','Y','E',' ')},	/* 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 */
-  {"ie",	HB_TAG('I','L','E',' ')},	/* Interlingue/Occidental */
-  {"ig",	HB_TAG('I','B','O',' ')},	/* Igbo */
-  {"igb",	HB_TAG('E','B','I',' ')},	/* Ebira */
-  {"ii",	HB_TAG('Y','I','M',' ')},	/* Yi Modern */
-  {"ijc",	HB_TAG('I','J','O',' ')},	/* Izon */
-  {"ijo",	HB_TAG('I','J','O',' ')},	/* Ijo [family] */
-  {"ik",	HB_TAG('I','P','K',' ')},	/* Inupiaq [macrolanguage] */
-  {"ilo",	HB_TAG('I','L','O',' ')},	/* Ilokano */
-  {"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] */
-  {"ja",	HB_TAG('J','A','N',' ')},	/* Japanese */
-  {"jam",	HB_TAG('J','A','M',' ')},	/* Jamaican Creole English */
-  {"jbo",	HB_TAG('J','B','O',' ')},	/* Lojban */
-  {"jv",	HB_TAG('J','A','V',' ')},	/* Javanese */
-  {"ka",	HB_TAG('K','A','T',' ')},	/* Georgian */
-  {"kaa",	HB_TAG('K','R','K',' ')},	/* 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] */
-  {"kat",	HB_TAG('K','G','E',' ')},	/* Khutsuri Georgian */
-  {"kbd",	HB_TAG('K','A','B',' ')},	/* Kabardian */
-  {"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',' ')},	/* Kokni */
-  {"kfa",	HB_TAG('K','O','D',' ')},	/* Kodagu */
-  {"kfr",	HB_TAG('K','A','C',' ')},	/* Kachchi */
-  {"kfx",	HB_TAG('K','U','L',' ')},	/* Kulvi */
-  {"kfy",	HB_TAG('K','M','N',' ')},	/* Kumaoni */
-  {"kg",	HB_TAG('K','O','N',' ')},	/* Kongo [macrolanguage] */
-  {"kha",	HB_TAG('K','S','I',' ')},	/* Khasi */
-  {"khb",	HB_TAG('X','B','D',' ')},	/* Lü */
-  {"kht",	HB_TAG('K','H','N',' ')},	/* Khamti (Microsoft fonts) */
-/*{"kht",	HB_TAG('K','H','T',' ')},*/	/* Khamti (OpenType spec and SIL fonts) */
-  {"khw",	HB_TAG('K','H','W',' ')},	/* Khowar */
-  {"ki",	HB_TAG('K','I','K',' ')},	/* Gikuyu/Kikuyu */
-  {"kiu",	HB_TAG('K','I','U',' ')},	/* Kirmanjki */
-  {"kj",	HB_TAG('K','U','A',' ')},	/* Kuanyama/Kwanyama */
-  {"kjd",	HB_TAG('K','J','D',' ')},	/* Southern Kiwai */
-  {"kjh",	HB_TAG('K','H','A',' ')},	/* Khakass */
-  {"kjp",	HB_TAG('K','J','P',' ')},	/* Pwo Eastern Karen */
-  {"kk",	HB_TAG('K','A','Z',' ')},	/* Kazakh */
-  {"kl",	HB_TAG('G','R','N',' ')},	/* Kalaallisut */
-  {"kln",	HB_TAG('K','A','L',' ')},	/* Kalenjin */
-  {"km",	HB_TAG('K','H','M',' ')},	/* Central Khmer */
-  {"kmb",	HB_TAG('M','B','N',' ')},	/* Kimbundu */
-  {"kmw",	HB_TAG('K','M','O',' ')},	/* Komo (Democratic Republic of Congo) */
-  {"kn",	HB_TAG('K','A','N',' ')},	/* Kannada */
-  {"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] */
-  {"kon",	HB_TAG('K','O','N','0')},	/* Kongo */
-  {"kos",	HB_TAG('K','O','S',' ')},	/* Kosraean */
-  {"kpe",	HB_TAG('K','P','L',' ')},	/* Kpelle [macrolanguage] */
-  {"kpv",	HB_TAG('K','O','Z',' ')},	/* Komi-Zyrian */
-  {"kpy",	HB_TAG('K','Y','K',' ')},	/* Koryak */
-  {"kqy",	HB_TAG('K','R','T',' ')},	/* Koorete */
-  {"kr",	HB_TAG('K','N','R',' ')},	/* Kanuri [macrolanguage] */
-  {"kri",	HB_TAG('K','R','I',' ')},	/* Krio */
-  {"krl",	HB_TAG('K','R','L',' ')},	/* Karelian */
-  {"kru",	HB_TAG('K','U','U',' ')},	/* Kurukh */
-  {"ks",	HB_TAG('K','S','H',' ')},	/* Kashmiri */
-  {"ksh",	HB_TAG('K','S','H','0')},	/* Ripuarian, Kölsch */
-/*{"ksw",	HB_TAG('K','R','N',' ')},*/	/* S'gaw Karen (Microsoft fonts?) */
-  {"ksw",	HB_TAG('K','S','W',' ')},	/* S'gaw Karen (OpenType spec and SIL fonts) */
-  {"ktb",	HB_TAG('K','E','B',' ')},	/* Kebena */
-  {"ktu",	HB_TAG('K','O','N',' ')},	/* Kikongo */
-  {"ku",	HB_TAG('K','U','R',' ')},	/* Kurdish [macrolanguage] */
-  {"kum",	HB_TAG('K','U','M',' ')},	/* Kumyk */
-  {"kv",	HB_TAG('K','O','M',' ')},	/* Komi [macrolanguage] */
-  {"kvd",	HB_TAG('K','U','I',' ')},	/* Kui (Indonesia) */
-  {"kw",	HB_TAG('C','O','R',' ')},	/* Cornish */
-  {"kxc",	HB_TAG('K','M','S',' ')},	/* Komso */
-  {"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 */
-  {"lez",	HB_TAG('L','E','Z',' ')},	/* Lezgi */
-  {"lg",	HB_TAG('L','U','G',' ')},	/* Ganda */
-  {"li",	HB_TAG('L','I','M',' ')},	/* Limburgan/Limburger/Limburgish */
-  {"lif",	HB_TAG('L','M','B',' ')},	/* Limbu */
-  {"lij",	HB_TAG('L','I','J',' ')},	/* Ligurian */
-  {"lis",	HB_TAG('L','I','S',' ')},	/* Lisu */
-  {"ljp",	HB_TAG('L','J','P',' ')},	/* Lampung Api */
-  {"lki",	HB_TAG('L','K','I',' ')},	/* Laki */
-  {"lld",	HB_TAG('L','A','D',' ')},	/* Ladin */
-  {"lmn",	HB_TAG('L','A','M',' ')},	/* 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 */
-  {"lrc",	HB_TAG('L','R','C',' ')},	/* Northern Luri */
-  {"lt",	HB_TAG('L','T','H',' ')},	/* Lithuanian */
-  {"lu",	HB_TAG('L','U','B',' ')},	/* Luba-Katanga */
-  {"lua",	HB_TAG('L','U','B',' ')},	/* Luba-Kasai */
-  {"luo",	HB_TAG('L','U','O',' ')},	/* Luo (Kenya and Tanzania) */
-  {"lus",	HB_TAG('M','I','Z',' ')},	/* Mizo */
-  {"luy",	HB_TAG('L','U','H',' ')},	/* Luyia/Oluluyia [macrolanguage] */
-  {"luz",	HB_TAG('L','R','C',' ')},	/* Southern Luri */
-  {"lv",	HB_TAG('L','V','I',' ')},	/* Latvian */
-  {"lzz",	HB_TAG('L','A','Z',' ')},	/* Laz */
-  {"mad",	HB_TAG('M','A','D',' ')},	/* Madurese */
-  {"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',' ')},	/* Manding/Mandingo [macrolanguage] */
-  {"mdc",	HB_TAG('M','L','E',' ')},	/* Male (Papua New Guinea) */
-  {"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) */
-  {"mer",	HB_TAG('M','E','R',' ')},	/* Meru */
-  {"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',' ')},	/* Low Mari */
-  {"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 */
-  {"mkw",	HB_TAG('M','K','W',' ')},	/* Kituba (Congo) */
-  {"ml",	HB_TAG('M','L','R',' ')},	/* Malayalam */
-  {"mlq",	HB_TAG('M','N','K',' ')},	/* Western Maninkakan */
-  {"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 */
-  {"mns",	HB_TAG('M','A','N',' ')},	/* Mansi */
-  {"mnw",	HB_TAG('M','O','N',' ')},	/* Mon */
-  {"mo",	HB_TAG('M','O','L',' ')},	/* Moldavian */
-  {"moh",	HB_TAG('M','O','H',' ')},	/* Mohawk */
-  {"mos",	HB_TAG('M','O','S',' ')},	/* Mossi */
-  {"mpe",	HB_TAG('M','A','J',' ')},	/* Majang */
-  {"mr",	HB_TAG('M','A','R',' ')},	/* Marathi */
-  {"mrh",	HB_TAG('Q','I','N',' ')},	/* Mara Chin */
-  {"mrj",	HB_TAG('H','M','A',' ')},	/* High Mari */
-  {"ms",	HB_TAG('M','L','Y',' ')},	/* Malay [macrolanguage] */
-  {"msc",	HB_TAG('M','N','K',' ')},	/* Sankaran Maninka */
-  {"mt",	HB_TAG('M','T','S',' ')},	/* Maltese */
-  {"mtr",	HB_TAG('M','A','W',' ')},	/* Mewari */
-  {"mus",	HB_TAG('M','U','S',' ')},	/* Creek */
-  {"mve",	HB_TAG('M','A','W',' ')},	/* Marwari (Pakistan) */
-  {"mwk",	HB_TAG('M','N','K',' ')},	/* Kita Maninkakan */
-  {"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 */
-  {"myq",	HB_TAG('M','N','K',' ')},	/* Forest Maninka (retired code) */
-  {"myv",	HB_TAG('E','R','Z',' ')},	/* Erzya */
-  {"mzn",	HB_TAG('M','Z','N',' ')},	/* Mazanderani */
-  {"na",	HB_TAG('N','A','U',' ')},	/* Nauru */
-  {"nag",	HB_TAG('N','A','G',' ')},	/* Naga-Assamese */
-  {"nah",	HB_TAG('N','A','H',' ')},	/* Nahuatl [family] */
-  {"nap",	HB_TAG('N','A','P',' ')},	/* Neapolitan */
-  {"nb",	HB_TAG('N','O','R',' ')},	/* Norwegian Bokmål */
-  {"nco",	HB_TAG('S','I','B',' ')},	/* Sibe */
-  {"nd",	HB_TAG('N','D','B',' ')},	/* [North] Ndebele */
-  {"ndc",	HB_TAG('N','D','C',' ')},	/* Ndau */
-  {"nds",	HB_TAG('N','D','S',' ')},	/* Low German/Low Saxon */
-  {"ne",	HB_TAG('N','E','P',' ')},	/* Nepali */
-  {"new",	HB_TAG('N','E','W',' ')},	/* Newari */
-  {"ng",	HB_TAG('N','D','G',' ')},	/* Ndonga */
-  {"nga",	HB_TAG('N','G','A',' ')},	/* Ngabaka */
-  {"ngl",	HB_TAG('L','M','W',' ')},	/* Lomwe */
-  {"ngo",	HB_TAG('S','X','T',' ')},	/* Sutu */
-  {"niu",	HB_TAG('N','I','U',' ')},	/* Niuean */
-  {"niv",	HB_TAG('G','I','L',' ')},	/* Gilyak */
-  {"nl",	HB_TAG('N','L','D',' ')},	/* Dutch */
-  {"nn",	HB_TAG('N','Y','N',' ')},	/* Norwegian Nynorsk */
-  {"no",	HB_TAG('N','O','R',' ')},	/* Norwegian [macrolanguage] */
-  {"nod",	HB_TAG('N','T','A',' ')},	/* Northern Thai */
-  {"noe",	HB_TAG('N','O','E',' ')},	/* Nimadi */
-  {"nog",	HB_TAG('N','O','G',' ')},	/* Nogai */
-  {"nov",	HB_TAG('N','O','V',' ')},	/* Novial */
-  {"nqo",	HB_TAG('N','K','O',' ')},	/* N'Ko */
-  {"nr",	HB_TAG('N','D','B',' ')},	/* [South] Ndebele */
-  {"nsk",	HB_TAG('N','A','S',' ')},	/* Naskapi */
-  {"nso",	HB_TAG('S','O','T',' ')},	/* [Northern] Sotho */
-  {"nv",	HB_TAG('N','A','V',' ')},	/* Navajo */
-  {"ny",	HB_TAG('C','H','I',' ')},	/* Chewa/Chichwa/Nyanja */
-  {"nym",	HB_TAG('N','Y','M',' ')},	/* Nyamwezi */
-  {"nyn",	HB_TAG('N','K','L',' ')},	/* Nyankole */
-  {"oc",	HB_TAG('O','C','I',' ')},	/* Occitan (post 1500) */
-  {"oj",	HB_TAG('O','J','B',' ')},	/* Ojibwa [macrolanguage] */
-  {"ojs",	HB_TAG('O','C','R',' ')},	/* Oji-Cree */
-  {"okm",	HB_TAG('K','O','H',' ')},	/* Korean Old Hangul */
-  {"om",	HB_TAG('O','R','O',' ')},	/* Oromo [macrolanguage] */
-  {"or",	HB_TAG('O','R','I',' ')},	/* Oriya */
-  {"os",	HB_TAG('O','S','S',' ')},	/* Ossetian */
-  {"pa",	HB_TAG('P','A','N',' ')},	/* Panjabi */
-  {"pag",	HB_TAG('P','A','G',' ')},	/* Pangasinan */
-  {"pam",	HB_TAG('P','A','M',' ')},	/* Kapampangan/Pampanga */
-  {"pap",	HB_TAG('P','A','P','0')},	/* Papiamento */
-  {"pau",	HB_TAG('P','A','U',' ')},	/* Palauan */
-  {"pcc",	HB_TAG('P','C','C',' ')},	/* Bouyei */
-  {"pcd",	HB_TAG('P','C','D',' ')},	/* Picard */
-  {"pce",	HB_TAG('P','L','G',' ')},	/* [Ruching] Palaung */
-  {"pck",	HB_TAG('Q','I','N',' ')},	/* Paite Chin */
-  {"pdc",	HB_TAG('P','D','C',' ')},	/* Pennsylvania German */
-  {"pes",	HB_TAG('F','A','R',' ')},	/* Iranian Persian */
-  {"phk",	HB_TAG('P','H','K',' ')},	/* Phake */
-  {"pi",	HB_TAG('P','A','L',' ')},	/* Pali */
-  {"pih",	HB_TAG('P','I','H',' ')},	/* Pitcairn-Norfolk */
-  {"pl",	HB_TAG('P','L','K',' ')},	/* Polish */
-  {"pll",	HB_TAG('P','L','G',' ')},	/* [Shwe] Palaung */
-  {"plp",	HB_TAG('P','A','P',' ')},	/* Palpa */
-  {"pms",	HB_TAG('P','M','S',' ')},	/* Piemontese */
-  {"pnb",	HB_TAG('P','N','B',' ')},	/* Western Panjabi */
-  {"poh",	HB_TAG('P','O','H',' ')},	/* Pocomchi */
-  {"pon",	HB_TAG('P','O','N',' ')},	/* Pohnpeian */
-  {"prs",	HB_TAG('D','R','I',' ')},	/* Afghan Persian/Dari */
-  {"ps",	HB_TAG('P','A','S',' ')},	/* Pashto/Pushto [macrolanguage] */
-  {"pt",	HB_TAG('P','T','G',' ')},	/* Portuguese */
-  {"pwo",	HB_TAG('P','W','O',' ')},	/* Pwo Western Karen */
-  {"qu",	HB_TAG('Q','U','Z',' ')},	/* Quechua [macrolanguage] */
-  {"quc",	HB_TAG('Q','U','C',' ')},	/* K'iche'/Quiché */
-  {"quh",	HB_TAG('Q','U','H',' ')},	/* Quechua (Bolivia) */
-  {"quz",	HB_TAG('Q','U','Z',' ')},	/* Cusco Quechua */
-  {"qvi",	HB_TAG('Q','V','I',' ')},	/* Quechua (Ecuador) */
-  {"qwh",	HB_TAG('Q','W','H',' ')},	/* Quechua (Peru) */
-  {"raj",	HB_TAG('R','A','J',' ')},	/* Rajasthani [macrolanguage] */
-  {"rar",	HB_TAG('R','A','R',' ')},	/* Rarotongan */
-  {"rbb",	HB_TAG('P','L','G',' ')},	/* Rumai Palaung */
-  {"rej",	HB_TAG('R','E','J',' ')},	/* Rejang */
-  {"ria",	HB_TAG('R','I','A',' ')},	/* Riang (India) */
-  {"rif",	HB_TAG('R','I','F',' ')},	/* Tarifit */
-  {"ril",	HB_TAG('R','I','A',' ')},	/* Riang (Myanmar) */
-  {"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 */
-  {"rmy",	HB_TAG('R','M','Y',' ')},	/* Vlax Romani */
-  {"rn",	HB_TAG('R','U','N',' ')},	/* Rundi */
-  {"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/Arumanian/Macedo-Romanian */
-  {"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 */
-  {"sam",	HB_TAG('P','A','A',' ')},	/* 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','L','A',' ')},	/* [North] Slavey */
-  {"sd",	HB_TAG('S','N','D',' ')},	/* Sindhi */
-  {"se",	HB_TAG('N','S','M',' ')},	/* Northern Sami */
-  {"seh",	HB_TAG('S','N','A',' ')},	/* Sena */
-  {"sel",	HB_TAG('S','E','L',' ')},	/* Selkup */
-  {"sez",	HB_TAG('Q','I','N',' ')},	/* Senthang Chin */
-  {"sg",	HB_TAG('S','G','O',' ')},	/* Sango */
-  {"sga",	HB_TAG('S','G','A',' ')},	/* Old Irish (to 900) */
-  {"sgs",	HB_TAG('S','G','S',' ')},	/* Samogitian */
-  {"sgw",	HB_TAG('C','H','G',' ')},	/* Sebat Bet Gurage */
-/*{"sgw",	HB_TAG('S','G','W',' ')},*/	/* Sebat Bet Gurage (in SIL fonts) */
-  {"shi",	HB_TAG('S','H','I',' ')},	/* Tachelhit */
-  {"shn",	HB_TAG('S','H','N',' ')},	/* Shan */
-  {"si",	HB_TAG('S','N','H',' ')},	/* Sinhala */
-  {"sid",	HB_TAG('S','I','D',' ')},	/* Sidamo */
-  {"sjd",	HB_TAG('K','S','M',' ')},	/* Kildin Sami */
-  {"sk",	HB_TAG('S','K','Y',' ')},	/* Slovak */
-  {"skr",	HB_TAG('S','R','K',' ')},	/* Seraiki */
-  {"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 */
-  {"sq",	HB_TAG('S','Q','I',' ')},	/* Albanian [macrolanguage] */
-  {"sr",	HB_TAG('S','R','B',' ')},	/* Serbian */
-  {"srr",	HB_TAG('S','R','R',' ')},	/* Serer */
-  {"ss",	HB_TAG('S','W','Z',' ')},	/* Swati */
-  {"st",	HB_TAG('S','O','T',' ')},	/* [Southern] Sotho */
-  {"stq",	HB_TAG('S','T','Q',' ')},	/* Saterfriesisch */
-  {"stv",	HB_TAG('S','I','G',' ')},	/* Silt'e */
-  {"su",	HB_TAG('S','U','N',' ')},	/* Sundanese */
-  {"suk",	HB_TAG('S','U','K',' ')},	/* Sukama */
-  {"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',' ')},	/* Comorian */
-  {"swh",	HB_TAG('S','W','K',' ')},	/* Kiswahili/Swahili */
-  {"swv",	HB_TAG('M','A','W',' ')},	/* Shekhawati */
-  {"sxu",	HB_TAG('S','X','U',' ')},	/* Upper Saxon */
-  {"syc",	HB_TAG('S','Y','R',' ')},	/* Classical 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 */
-  {"tab",	HB_TAG('T','A','B',' ')},	/* Tabasaran */
-  {"tcp",	HB_TAG('Q','I','N',' ')},	/* Tawr Chin */
-  {"tcy",	HB_TAG('T','U','L',' ')},	/* Tulu */
-  {"tcz",	HB_TAG('Q','I','N',' ')},	/* Thado Chin */
-  {"tdd",	HB_TAG('T','D','D',' ')},	/* Tai Nüa */
-  {"te",	HB_TAG('T','E','L',' ')},	/* Telugu */
-  {"tem",	HB_TAG('T','M','N',' ')},	/* Temne */
-  {"tet",	HB_TAG('T','E','T',' ')},	/* Tetum */
-  {"tg",	HB_TAG('T','A','J',' ')},	/* Tajik */
-  {"th",	HB_TAG('T','H','A',' ')},	/* Thai */
-  {"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 */
-  {"tl",	HB_TAG('T','G','L',' ')},	/* Tagalog */
-  {"tmh",	HB_TAG('T','M','H',' ')},	/* Tamashek */
-  {"tn",	HB_TAG('T','N','A',' ')},	/* Tswana */
-  {"to",	HB_TAG('T','G','N',' ')},	/* Tonga (Tonga Islands) */
-  {"tod",	HB_TAG('T','O','D','0')},	/* Toma */
-  {"toi",	HB_TAG('T','N','G',' ')},	/* Tonga */
-  {"tpi",	HB_TAG('T','P','I',' ')},	/* Tok Pisin */
-  {"tr",	HB_TAG('T','R','K',' ')},	/* Turkish */
-  {"tru",	HB_TAG('T','U','A',' ')},	/* Turoyo Aramaic */
-  {"ts",	HB_TAG('T','S','G',' ')},	/* Tsonga */
-  {"tt",	HB_TAG('T','A','T',' ')},	/* Tatar */
-  {"tum",	HB_TAG('T','U','M',' ')},	/* Tumbuka */
-  {"tvl",	HB_TAG('T','V','L',' ')},	/* Tuvalu */
-  {"tw",	HB_TAG('T','W','I',' ')},	/* Twi */
-  {"ty",	HB_TAG('T','H','T',' ')},	/* Tahitian */
-  {"tyv",	HB_TAG('T','U','V',' ')},	/* Tuvin */
-  {"tyz",	HB_TAG('T','Y','Z',' ')},	/* Tày */
-  {"tzm",	HB_TAG('T','Z','M',' ')},	/* Central Atlas Tamazight */
-  {"tzo",	HB_TAG('T','Z','O',' ')},	/* Tzotzil */
-  {"udm",	HB_TAG('U','D','M',' ')},	/* Udmurt */
-  {"ug",	HB_TAG('U','Y','G',' ')},	/* Uighur */
-  {"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 */
-  {"uz",	HB_TAG('U','Z','B',' ')},	/* Uzbek [macrolanguage] */
-  {"uzn",	HB_TAG('U','Z','B',' ')},	/* Northern Uzbek */
-  {"uzs",	HB_TAG('U','Z','B',' ')},	/* Southern Uzbek */
-  {"ve",	HB_TAG('V','E','N',' ')},	/* Venda */
-  {"vec",	HB_TAG('V','E','C',' ')},	/* Venetian */
-  {"vi",	HB_TAG('V','I','T',' ')},	/* Vietnamese */
-  {"vls",	HB_TAG('F','L','E',' ')},	/* Vlaams */
-  {"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) */
-  {"wbm",	HB_TAG('W','A',' ',' ')},	/* Wa */
-  {"wbr",	HB_TAG('W','A','G',' ')},	/* Wagdi */
-  {"wle",	HB_TAG('S','I','G',' ')},	/* Wolane */
-  {"wo",	HB_TAG('W','L','F',' ')},	/* Wolof */
-  {"wry",	HB_TAG('M','A','W',' ')},	/* Merwari */
-  {"wtm",	HB_TAG('W','T','M',' ')},	/* Mewati */
-  {"xal",	HB_TAG('K','L','M',' ')},	/* Kalmyk */
-  {"xan",	HB_TAG('S','E','K',' ')},	/* Sekota */
-  {"xh",	HB_TAG('X','H','S',' ')},	/* Xhosa */
-  {"xjb",	HB_TAG('X','J','B',' ')},	/* Minjangbal */
-  {"xog",	HB_TAG('X','O','G',' ')},	/* Soga */
-  {"xom",	HB_TAG('K','M','O',' ')},	/* Komo (Sudan) */
-  {"xpe",	HB_TAG('X','P','E',' ')},	/* Kpelle (Liberia) */
-  {"xsl",	HB_TAG('S','S','L',' ')},	/* South Slavey */
-  {"xst",	HB_TAG('S','I','G',' ')},	/* Silt'e (retired code) */
-  {"xwo",	HB_TAG('T','O','D',' ')},	/* Written Oirat (Todo) */
-  {"yao",	HB_TAG('Y','A','O',' ')},	/* Yao */
-  {"yap",	HB_TAG('Y','A','P',' ')},	/* Yapese */
-  {"yi",	HB_TAG('J','I','I',' ')},	/* Yiddish [macrolanguage] */
-  {"yo",	HB_TAG('Y','B','A',' ')},	/* Yoruba */
-  {"yos",	HB_TAG('Q','I','N',' ')},	/* Yos, deprecated by IANA in favor of Zou [zom] */
-  {"yso",	HB_TAG('N','I','S',' ')},	/* Nisi (China) */
-  {"za",	HB_TAG('Z','H','A',' ')},	/* Chuang/Zhuang [macrolanguage] */
-  {"zea",	HB_TAG('Z','E','A',' ')},	/* Zeeuws */
-  {"zgh",	HB_TAG('Z','G','H',' ')},	/* Standard Morrocan Tamazigh */
-  {"zne",	HB_TAG('Z','N','D',' ')},	/* Zande */
-  {"zom",	HB_TAG('Q','I','N',' ')},	/* Zou */
-  {"zu",	HB_TAG('Z','U','L',' ')}, 	/* Zulu */
-  {"zum",	HB_TAG('L','R','C',' ')},	/* Kumzari */
-  {"zza",	HB_TAG('Z','Z','A',' ')},	/* Zazaki */
-
-  /* The corresponding languages IDs for the following IDs are unclear,
-   * overlap, or are architecturally weird. Needs more research. */
-
-/*{"chp",	HB_TAG('S','A','Y',' ')},*/	/* Sayisi */
-/*{"cwd",	HB_TAG('T','C','R',' ')},*/	/* TH-Cree */
-/*{"emk",	HB_TAG('E','M','K',' ')},*/	/* Eastern Maninkakan */
-/*{"krc",	HB_TAG('B','A','L',' ')},*/	/* Balkar */
-/*{"??",	HB_TAG('B','C','R',' ')},*/	/* Bible Cree */
-/*{"zh?",	HB_TAG('C','H','N',' ')},*/	/* Chinese (seen in Microsoft fonts) */
-/*{"ar-Syrc?",	HB_TAG('G','A','R',' ')},*/	/* Garshuni */
-/*{"hy?",	HB_TAG('H','Y','E','0')},*/	/* Armenian East (ISO 639-3 hye according to Microsoft, but that’s equivalent to ISO 639-1 hy) */
-/*{"ga-Latg?/"	HB_TAG('I','R','T',' ')},*/	/* Irish Traditional */
-/*{"krc",	HB_TAG('K','A','R',' ')},*/	/* Karachay */
-/*{"ka-Geok?",	HB_TAG('K','G','E',' ')},*/	/* Khutsuri Georgian */
-/*{"kca",	HB_TAG('K','H','K',' ')},*/	/* Khanty-Kazim */
-/*{"kca",	HB_TAG('K','H','S',' ')},*/	/* Khanty-Shurishkar */
-/*{"kca",	HB_TAG('K','H','V',' ')},*/	/* Khanty-Vakhi */
-/*{"kqs, kss",	HB_TAG('K','I','S',' ')},*/	/* Kisii */
-/*{"lua",	HB_TAG('L','U','A',' ')},*/	/* Luba-Lulua */
-/*{"mlq",	HB_TAG('M','L','N',' ')},*/	/* Malinke */
-/*{"nso",	HB_TAG('N','S','O',' ')},*/	/* Sotho, Northern */
-/*{"??",	HB_TAG('M','A','L',' ')},*/	/* Malayalam Traditional */
-/*{"csw",	HB_TAG('N','C','R',' ')},*/	/* N-Cree */
-/*{"csw",	HB_TAG('N','H','C',' ')},*/	/* Norway House Cree */
-/*{"el-polyton",	HB_TAG('P','G','R',' ')},*/	/* Polytonic Greek */
-/*{"bgr, cnh, cnw, czt, sez, tcp, csy, ctd, flm, pck, tcz, zom, cmr, dao, hlt, cka, cnk, mrh, mwg, cbl, cnb, csh",	HB_TAG('Q','I','N',' ')},*/	/* Chin */
-/*{"??",	HB_TAG('Y','I','C',' ')},*/	/* Yi Classic */
-/*{"zh-Latn-pinyin",	HB_TAG('Z','H','P',' ')},*/	/* Chinese Phonetic */
-};
-
-typedef struct {
-  char language[11];
-  hb_tag_t tag;
-} LangTagLong;
-static const LangTagLong ot_languages_zh[] = {
-  /* Store longest-first, if one is a prefix of another. */
-  {"zh-cn",	HB_TAG('Z','H','S',' ')},	/* Chinese (China) */
-  {"zh-hk",	HB_TAG('Z','H','H',' ')},	/* Chinese (Hong Kong) */
-  {"zh-mo",	HB_TAG('Z','H','H',' ')},	/* Chinese (Macao) */
-  {"zh-sg",	HB_TAG('Z','H','S',' ')},	/* Chinese (Singapore) */
-  {"zh-tw",	HB_TAG('Z','H','T',' ')},	/* Chinese (Taiwan) */
-  {"zh-hans",	HB_TAG('Z','H','S',' ')},	/* Chinese (Simplified) */
-  {"zh-hant-hk",HB_TAG('Z','H','H',' ')},	/* Chinese (Hong Kong) */
-  {"zh-hant-mo",HB_TAG('Z','H','H',' ')},	/* Chinese (Macao) */
-  {"zh-hant",	HB_TAG('Z','H','T',' ')},	/* Chinese (Traditional) */
-};
-
 static int
 lang_compare_first_component (const void *pa,
 			      const void *pb)
@@ -895,6 +189,21 @@
   return strncmp (a, b, MAX (da, db));
 }
 
+static bool
+subtag_matches (const char *lang_str,
+		const char *limit,
+		const char *subtag)
+{
+  do {
+    const char *s = strstr (lang_str, subtag);
+    if (!s || s >= limit)
+      return false;
+    if (!ISALNUM (s[strlen (subtag)]))
+      return true;
+    lang_str = s + strlen (subtag);
+  } while (1);
+}
+
 static hb_bool_t
 lang_matches (const char *lang_str, const char *spec)
 {
@@ -904,106 +213,187 @@
 	 (lang_str[len] == '\0' || lang_str[len] == '-');
 }
 
+typedef struct {
+  char language[4];
+  hb_tag_t tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
+} LangTag;
+
+#include "hb-ot-tag-table.hh"
+
+/* The corresponding languages IDs for the following IDs are unclear,
+ * overlap, or are architecturally weird. Needs more research. */
+
+/*{"??",	{HB_TAG('B','C','R',' ')}},*/	/* Bible Cree */
+/*{"zh?",	{HB_TAG('C','H','N',' ')}},*/	/* Chinese (seen in Microsoft fonts) */
+/*{"ar-Syrc?",	{HB_TAG('G','A','R',' ')}},*/	/* Garshuni */
+/*{"??",	{HB_TAG('N','G','R',' ')}},*/	/* Nagari */
+/*{"??",	{HB_TAG('Y','I','C',' ')}},*/	/* Yi Classic */
+/*{"zh?",	{HB_TAG('Z','H','P',' ')}},*/	/* Chinese Phonetic */
+
 hb_tag_t
 hb_ot_tag_from_language (hb_language_t language)
 {
-  const char *lang_str, *s;
+  unsigned int count = 1;
+  hb_tag_t tags[1];
+  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;
+}
 
-  if (language == HB_LANGUAGE_INVALID)
-    return HB_OT_TAG_DEFAULT_LANGUAGE;
+static void
+hb_ot_tags_from_language (const char   *lang_str,
+			  const char   *limit,
+			  const char   *private_use_subtag,
+			  unsigned int *count,
+			  hb_tag_t     *tags)
+{
+  const char *s;
 
-  lang_str = hb_language_to_string (language);
+  /* Check for matches of multiple subtags. */
+  if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags))
+    return;
 
-  s = strstr (lang_str, "x-hbot");
-  if (s) {
-    char tag[4];
-    int i;
-    s += 6;
-    for (i = 0; i < 4 && ISALNUM (s[i]); i++)
-      tag[i] = TOUPPER (s[i]);
-    if (i) {
-      for (; i < 4; i++)
-	tag[i] = ' ';
-      return HB_TAG (tag[0], tag[1], tag[2], tag[3]);
+  /* 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, '-');
+      /* If there is an extended language tag, use it. */
+      if (3 == (extlang_end ? extlang_end - s - 1 : strlen (s + 1)) &&
+	  ISALPHA (s[1]))
+	lang_str = s + 1;
     }
+    lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
+				    ARRAY_LENGTH (ot_languages), sizeof (LangTag),
+				    lang_compare_first_component);
+    if (lang_tag)
+    {
+      unsigned int i;
+      for (i = 0; i < *count && lang_tag->tags[i] != HB_TAG_NONE; i++)
+	tags[i] = lang_tag->tags[i];
+      *count = i;
+      return;
+    }
   }
 
-  /*
-   * "fonipa" is a variant tag in BCP-47, meaning the International Phonetic Alphabet.
-   * It can be applied to any language.
-   */
-  if (strstr (lang_str, "-fonipa")) {
-    return HB_TAG('I','P','P','H');  /* Phonetic transcription—IPA conventions */
+  if (!s)
+    s = lang_str + strlen (lang_str);
+  if (s - lang_str == 3) {
+    /* Assume it's ISO-639-3 and upper-case and use it. */
+    tags[0] = hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u;
+    *count = 1;
+    return;
   }
 
-  /*
-   * "fonnapa" is a variant tag in BCP-47, meaning the North American Phonetic Alphabet
-   * also known as Americanist Phonetic Notation.  It can be applied to any language.
-   */
-  if (strstr (lang_str, "-fonnapa")) {
-    return HB_TAG('A','P','P','H');  /* Phonetic transcription—Americanist conventions */
-  }
+  *count = 0;
+}
 
-  /*
-   * "Syre" is a BCP-47 script tag, meaning the Estrangela variant of the Syriac script.
-   * It can be applied to any language.
-   */
-  if (strstr (lang_str, "-syre")) {
-    return HB_TAG('S','Y','R','E');  /* Estrangela Syriac */
+static bool
+parse_private_use_subtag (const char     *private_use_subtag,
+			  unsigned int   *count,
+			  hb_tag_t       *tags,
+			  const char     *prefix,
+			  unsigned char (*normalize) (unsigned char))
+{
+  if (private_use_subtag && count && tags && *count)
+  {
+    const char *s = strstr (private_use_subtag, prefix);
+    if (s)
+    {
+      char tag[4];
+      int i;
+      s += strlen (prefix);
+      for (i = 0; i < 4 && ISALNUM (s[i]); i++)
+	tag[i] = normalize (s[i]);
+      if (i)
+      {
+	for (; i < 4; i++)
+	  tag[i] = ' ';
+	tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]);
+	if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT)
+	  tags[0] ^= ~0xDFDFDFDF;
+	*count = 1;
+	return false;
+      }
+    }
   }
+  return true;
+}
 
-  /*
-   * "Syrj" is a BCP-47 script tag, meaning the Western variant of the Syriac script.
-   * It can be applied to any language.
-   */
-  if (strstr (lang_str, "-syrj")) {
-    return HB_TAG('S','Y','R','J');  /* Western Syriac */
-  }
+/**
+ * hb_ot_tags_from_script_and_language:
+ * @script: an #hb_script_t to convert.
+ * @language: an #hb_language_t to convert.
+ * @script_count: (allow-none): maximum number of script tags to retrieve (IN)
+ * and actual number of script tags retrieved (OUT)
+ * @script_tags: (out) (allow-none): array of size at least @script_count to store the
+ * script tag results
+ * @language_count: (allow-none): maximum number of language tags to retrieve
+ * (IN) and actual number of language tags retrieved (OUT)
+ * @language_tags: (out) (allow-none): array of size at least @language_count to store
+ * the language tag results
+ *
+ * Converts an #hb_script_t and an #hb_language_t to script and language tags.
+ *
+ * Since: 2.0.0
+ **/
+void
+hb_ot_tags_from_script_and_language (hb_script_t   script,
+				     hb_language_t language,
+				     unsigned int *script_count /* IN/OUT */,
+				     hb_tag_t     *script_tags /* OUT */,
+				     unsigned int *language_count /* IN/OUT */,
+				     hb_tag_t     *language_tags /* OUT */)
+{
+  bool needs_script = true;
 
-  /*
-   * "Syrn" is a BCP-47 script tag, meaning the Eastern variant of the Syriac script.
-   * It can be applied to any language.
-   */
-  if (strstr (lang_str, "-syrn")) {
-    return HB_TAG('S','Y','R','N');  /* Eastern Syriac */
-  }
-
-  /* Find a language matching in the first component */
+  if (language == HB_LANGUAGE_INVALID)
   {
-    const LangTag *lang_tag;
-    lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
-				    ARRAY_LENGTH (ot_languages), sizeof (LangTag),
-				    lang_compare_first_component);
-    if (lang_tag)
-      return lang_tag->tag;
+    if (language_count && language_tags && *language_count)
+      *language_count = 0;
   }
-
-  /* Otherwise, check the Chinese ones */
-  if (0 == lang_compare_first_component (lang_str, "zh"))
+  else
   {
-    unsigned int i;
+    const char *lang_str, *s, *limit, *private_use_subtag;
+    bool needs_language;
 
-    for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++)
+    lang_str = hb_language_to_string (language);
+    limit = nullptr;
+    private_use_subtag = nullptr;
+    if (lang_str[0] == 'x' && lang_str[1] == '-')
     {
-      const LangTagLong *lang_tag;
-      lang_tag = &ot_languages_zh[i];
-      if (lang_matches (lang_str, lang_tag->language))
-	return lang_tag->tag;
+      private_use_subtag = lang_str;
+    } else {
+      for (s = lang_str + 1; *s; s++)
+      {
+	if (s[-1] == '-' && s[1] == '-')
+	{
+	  if (s[0] == 'x')
+	  {
+	    private_use_subtag = s;
+	    if (!limit)
+	      limit = s - 1;
+	    break;
+	  } else if (!limit)
+	  {
+	    limit = s - 1;
+	  }
+	}
+      }
+      if (!limit)
+	limit = s;
     }
 
-    /* Otherwise just return 'ZHS ' */
-    return HB_TAG('Z','H','S',' ');
-  }
+    needs_script = parse_private_use_subtag (private_use_subtag, script_count, script_tags, "-hbsc", TOLOWER);
+    needs_language = parse_private_use_subtag (private_use_subtag, language_count, language_tags, "-hbot", TOUPPER);
 
-  s = strchr (lang_str, '-');
-  if (!s)
-    s = lang_str + strlen (lang_str);
-  if (s - lang_str == 3) {
-    /* Assume it's ISO-639-3 and upper-case and use it. */
-    return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u;
+    if (needs_language && language_count && language_tags && *language_count)
+      hb_ot_tags_from_language (lang_str, limit, private_use_subtag, language_count, language_tags);
   }
 
-  return HB_OT_TAG_DEFAULT_LANGUAGE;
+  if (needs_script && script_count && script_tags && *script_count)
+    hb_ot_all_tags_from_script (script, script_count, script_tags);
 }
 
 /**
@@ -1023,36 +413,16 @@
   if (tag == HB_OT_TAG_DEFAULT_LANGUAGE)
     return nullptr;
 
-  /* struct LangTag has only room for 3-letter language tags. */
-  switch (tag) {
-  case HB_TAG('A','P','P','H'):  /* Phonetic transcription—Americanist conventions */
-    return hb_language_from_string ("und-fonnapa", -1);
-  case HB_TAG('I','P','P','H'):  /* Phonetic transcription—IPA conventions */
-    return hb_language_from_string ("und-fonipa", -1);
-  case HB_TAG('S','Y','R',' '):  /* Syriac [macrolanguage] */
-    return hb_language_from_string ("syr", -1);
-  case HB_TAG('S','Y','R','E'):  /* Estrangela Syriac */
-    return hb_language_from_string ("und-Syre", -1);
-  case HB_TAG('S','Y','R','J'):  /* Western Syriac */
-    return hb_language_from_string ("und-Syrj", -1);
-  case HB_TAG('S','Y','R','N'):  /* Eastern Syriac */
-    return hb_language_from_string ("und-Syrn", -1);
+  {
+    hb_language_t disambiguated_tag = hb_ot_ambiguous_tag_to_language (tag);
+    if (disambiguated_tag != HB_LANGUAGE_INVALID)
+      return disambiguated_tag;
   }
 
   for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
-    if (ot_languages[i].tag == tag)
+    if (ot_languages[i].tags[0] == tag)
       return hb_language_from_string (ot_languages[i].language, -1);
 
-  /* If tag starts with ZH, it's Chinese */
-  if ((tag & 0xFFFF0000u)  == 0x5A480000u) {
-    switch (tag) {
-      case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */
-      case HB_TAG('Z','H','S',' '): return hb_language_from_string ("zh-Hans", -1); /* Simplified */
-      case HB_TAG('Z','H','T',' '): return hb_language_from_string ("zh-Hant", -1); /* Traditional */
-      default: break; /* Fall through */
-    }
-  }
-
   /* Else return a custom language in the form of "x-hbotABCD" */
   {
     unsigned char buf[11] = "x-hbot";
@@ -1067,6 +437,71 @@
   }
 }
 
+/**
+ * hb_ot_tags_to_script_and_language:
+ * @script_tag: a script tag
+ * @language_tag: a language tag
+ * @script: (allow-none): the #hb_script_t corresponding to @script_tag (OUT).
+ * @language: (allow-none): the #hb_language_t corresponding to @script_tag and
+ * @language_tag (OUT).
+ *
+ * Converts a script tag and a language tag to an #hb_script_t and an
+ * #hb_language_t.
+ *
+ * Since: 2.0.0
+ **/
+void
+hb_ot_tags_to_script_and_language (hb_tag_t       script_tag,
+				   hb_tag_t       language_tag,
+				   hb_script_t   *script /* OUT */,
+				   hb_language_t *language /* OUT */)
+{
+  hb_script_t script_out = hb_ot_tag_to_script (script_tag);
+  if (script)
+    *script = script_out;
+  if (language)
+  {
+    unsigned int script_count = 1;
+    hb_tag_t primary_script_tag[1];
+    hb_ot_tags_from_script_and_language (script_out,
+					 HB_LANGUAGE_INVALID,
+					 &script_count,
+					 primary_script_tag,
+					 nullptr, nullptr);
+    *language = hb_ot_tag_to_language (language_tag);
+    if (script_count == 0 || primary_script_tag[0] != script_tag)
+    {
+      unsigned char *buf;
+      const char *lang_str = hb_language_to_string (*language);
+      size_t len = strlen (lang_str);
+      buf = (unsigned char *) malloc (len + 11);
+      if (unlikely (!buf))
+      {
+	*language = nullptr;
+      }
+      else
+      {
+	memcpy (buf, lang_str, len);
+	if (lang_str[0] != 'x' || lang_str[1] != '-') {
+	  buf[len++] = '-';
+	  buf[len++] = 'x';
+	}
+	buf[len++] = '-';
+	buf[len++] = 'h';
+	buf[len++] = 'b';
+	buf[len++] = 's';
+	buf[len++] = 'c';
+	buf[len++] = script_tag >> 24;
+	buf[len++] = (script_tag >> 16) & 0xFF;
+	buf[len++] = (script_tag >> 8) & 0xFF;
+	buf[len++] = script_tag & 0xFF;
+	*language = hb_language_from_string ((char *) buf, len);
+	free (buf);
+      }
+    }
+  }
+}
+
 #ifdef MAIN
 static inline void
 test_langs_sorted (void)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.h	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -39,21 +39,40 @@
 #define HB_OT_TAG_DEFAULT_SCRIPT	HB_TAG ('D', 'F', 'L', 'T')
 #define HB_OT_TAG_DEFAULT_LANGUAGE	HB_TAG ('d', 'f', 'l', 't')
 
+/**
+ * HB_OT_MAX_TAGS_PER_SCRIPT:
+ *
+ * Since: 2.0.0
+ **/
+#define HB_OT_MAX_TAGS_PER_SCRIPT	3u
+/**
+ * HB_OT_MAX_TAGS_PER_LANGUAGE:
+ *
+ * Since: 2.0.0
+ **/
+#define HB_OT_MAX_TAGS_PER_LANGUAGE	3u
+
 HB_EXTERN void
-hb_ot_tags_from_script (hb_script_t  script,
-			hb_tag_t    *script_tag_1,
-			hb_tag_t    *script_tag_2);
+hb_ot_tags_from_script_and_language (hb_script_t   script,
+				     hb_language_t language,
+				     unsigned int *script_count /* IN/OUT */,
+				     hb_tag_t     *script_tags /* OUT */,
+				     unsigned int *language_count /* IN/OUT */,
+				     hb_tag_t     *language_tags /* OUT */);
 
 HB_EXTERN hb_script_t
 hb_ot_tag_to_script (hb_tag_t tag);
 
-HB_EXTERN hb_tag_t
-hb_ot_tag_from_language (hb_language_t language);
-
 HB_EXTERN hb_language_t
 hb_ot_tag_to_language (hb_tag_t tag);
 
+HB_EXTERN void
+hb_ot_tags_to_script_and_language (hb_tag_t       script_tag,
+				   hb_tag_t       language_tag,
+				   hb_script_t   *script /* OUT */,
+				   hb_language_t *language /* OUT */);
 
+
 HB_END_DECLS
 
 #endif /* HB_OT_TAG_H */

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -93,6 +93,7 @@
 	    (value - arrayZ[i-1].fromCoord) + denom/2) / denom;
   }
 
+  public:
   DEFINE_SIZE_ARRAY (2, arrayZ);
 };
 
@@ -108,7 +109,7 @@
 		    c->check_struct (this))))
       return_trace (false);
 
-    const SegmentMaps *map = axisSegmentMapsZ;
+    const SegmentMaps *map = axisSegmentMapsZ.arrayZ;
     unsigned int count = axisCount;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -124,7 +125,7 @@
   {
     unsigned int count = MIN<unsigned int> (coords_length, axisCount);
 
-    const SegmentMaps *map = axisSegmentMapsZ;
+    const SegmentMaps *map = axisSegmentMapsZ.arrayZ;
     for (unsigned int i = 0; i < count; i++)
     {
       coords[i] = map->map (coords[i]);
@@ -139,7 +140,8 @@
   HBUINT16	axisCount;	/* The number of variation axes in the font. This
 				 * must be the same number as axisCount in the
 				 * 'fvar' table. */
-  SegmentMaps	axisSegmentMapsZ[VAR];
+  UnsizedArrayOf<SegmentMaps>
+		axisSegmentMapsZ;
 
   public:
   DEFINE_SIZE_MIN (8);

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -46,7 +46,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  c->check_array (coordinates, coordinates[0].static_size, axis_count));
+		  c->check_array (coordinatesZ.arrayZ, axis_count));
   }
 
   protected:
@@ -53,13 +53,14 @@
   NameID	subfamilyNameID;/* The name ID for entries in the 'name' table
 				 * that provide subfamily names for this instance. */
   HBUINT16	reserved;	/* Reserved for future use — set to 0. */
-  Fixed		coordinates[VAR];/* The coordinates array for this instance. */
+  UnsizedArrayOf<Fixed>
+		coordinatesZ;	/* The coordinates array for this instance. */
   //NameID	postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
   //				  * table that provide PostScript names for this
   //				  * instance. */
 
   public:
-  DEFINE_SIZE_ARRAY (4, coordinates);
+  DEFINE_SIZE_ARRAY (4, coordinatesZ);
 };
 
 struct AxisRecord
@@ -176,7 +177,7 @@
       v = (v - axis.default_value) / (axis.default_value - axis.min_value);
     else
       v = (v - axis.default_value) / (axis.max_value - axis.default_value);
-    return (int) (v * 16384. + (v >= 0. ? .5 : -.5));
+    return (int) (v * 16384.f + (v >= 0.f ? .5f : -.5f));
   }
 
   protected:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -39,7 +39,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  c->check_array (mapData, get_width (), mapCount));
+		  c->check_array (mapDataZ.arrayZ, mapCount, get_width ()));
   }
 
   unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */
@@ -55,7 +55,7 @@
     unsigned int u = 0;
     { /* Fetch it. */
       unsigned int w = get_width ();
-      const HBUINT8 *p = mapData + w * v;
+      const HBUINT8 *p = mapDataZ.arrayZ + w * v;
       for (; w; w--)
 	u = (u << 8) + *p++;
     }
@@ -81,10 +81,11 @@
   HBUINT16	format;		/* A packed field that describes the compressed
 				 * representation of delta-set indices. */
   HBUINT16	mapCount;	/* The number of mapping entries. */
-  HBUINT8		mapData[VAR];	/* The delta-set index mapping data. */
+  UnsizedArrayOf<HBUINT8>
+ 		mapDataZ;	/* The delta-set index mapping data. */
 
   public:
-  DEFINE_SIZE_ARRAY (4, mapData);
+  DEFINE_SIZE_ARRAY (4, mapDataZ);
 };
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -68,7 +68,7 @@
 		  c->check_struct (this) &&
 		  valueRecordSize >= VariationValueRecord::static_size &&
 		  varStore.sanitize (c, this) &&
-		  c->check_array (values, valueRecordSize, valueRecordCount));
+		  c->check_array (valuesZ.arrayZ, valueRecordCount, valueRecordSize));
   }
 
   inline float get_var (hb_tag_t tag,
@@ -75,7 +75,7 @@
 			int *coords, unsigned int coord_count) const
   {
     const VariationValueRecord *record;
-    record = (VariationValueRecord *) bsearch (&tag, values,
+    record = (VariationValueRecord *) bsearch (&tag, valuesZ.arrayZ,
 					       valueRecordCount, valueRecordSize,
 					       tag_compare);
     if (!record)
@@ -101,11 +101,12 @@
   HBUINT16	valueRecordCount;/* The number of value records — may be zero. */
   OffsetTo<VariationStore>
 		varStore;	/* Offset to item variation store table. */
-  HBUINT8		values[VAR];	/* Array of value records. The records must be
+  UnsizedArrayOf<HBUINT8>
+		valuesZ;	/* Array of value records. The records must be
 				 * in binary order of their valueTag field. */
 
   public:
-  DEFINE_SIZE_ARRAY (12, values);
+  DEFINE_SIZE_ARRAY (12, valuesZ);
 };
 
 } /* namespace OT */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot.h	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -33,6 +33,7 @@
 #include "hb-ot-font.h"
 #include "hb-ot-layout.h"
 #include "hb-ot-math.h"
+#include "hb-ot-name.h"
 #include "hb-ot-tag.h"
 #include "hb-ot-shape.h"
 #include "hb-ot-var.h"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -368,8 +368,8 @@
     if (!resize (count))
       return;
     population = other->population;
-    memcpy (pages.arrayZ, other->pages.arrayZ, count * sizeof (pages.arrayZ[0]));
-    memcpy (page_map.arrayZ, other->page_map.arrayZ, count * sizeof (page_map.arrayZ[0]));
+    memcpy (pages.arrayZ(), other->pages.arrayZ(), count * sizeof (pages.arrayZ()[0]));
+    memcpy (page_map.arrayZ(), other->page_map.arrayZ(), count * sizeof (page_map.arrayZ()[0]));
   }
 
   inline bool is_equal (const hb_set_t *other) const

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	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-list.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -39,9 +39,7 @@
 HB_SHAPER_IMPLEMENT (coretext_aat)
 #endif
 
-#ifdef HAVE_OT
 HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
-#endif
 
 #ifdef HAVE_UNISCRIBE
 HB_SHAPER_IMPLEMENT (uniscribe)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -28,6 +28,8 @@
 
 #include "hb-open-type.hh"
 #include "hb-ot-layout-common.hh"
+#include "hb-aat-layout-ankr-table.hh" /* I don't even want to know why... */
+#include "hb-aat-layout-common.hh"
 
 #include "hb-face.hh"
 #include "hb-ot-head-table.hh"
@@ -41,6 +43,8 @@
 DEFINE_NULL_NAMESPACE_BYTES (OT, Index) =  {0xFF,0xFF};
 DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00};
 DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x00};
+/* Hand-coded because Lookup is a template.  Sad. */
+const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF};
 
 
 void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -77,7 +77,7 @@
       return false;
     }
   retry:
-    hb_serialize_context_t serializer (buf.arrayZ, buf_size);
+    hb_serialize_context_t serializer (buf.arrayZ(), buf_size);
     hb_subset_context_t c (plan, &serializer);
     result = table->subset (&c);
     if (serializer.ran_out_of_room)
@@ -179,10 +179,10 @@
       break;
 
     case HB_OT_TAG_GSUB:
-      //result = _subset2<const OT::GSUB> (plan);
+      result = _subset2<const OT::GSUB> (plan);
       break;
     case HB_OT_TAG_GPOS:
-      //result = _subset2<const OT::GPOS> (plan);
+      result = _subset2<const OT::GPOS> (plan);
       break;
 
     default:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucdn.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -16,7 +16,6 @@
 
 #include "hb.hh"
 
-#include "hb-unicode.hh"
 #include "hb-machinery.hh"
 
 #include "ucdn.h"
@@ -182,15 +181,6 @@
     return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
 }
 
-static unsigned int
-hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs HB_UNUSED,
-			hb_codepoint_t unicode,
-			void *user_data HB_UNUSED)
-{
-    int w = ucdn_get_east_asian_width(unicode);
-    return (w == UCDN_EAST_ASIAN_F || w == UCDN_EAST_ASIAN_W) ? 2 : 1;
-}
-
 static hb_unicode_general_category_t
 hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 			 hb_codepoint_t unicode,
@@ -231,16 +221,10 @@
     return ucdn_decompose(ab, a, b);
 }
 
-static unsigned int
-hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
-				hb_codepoint_t u, hb_codepoint_t *decomposed,
-				void *user_data HB_UNUSED)
-{
-    return ucdn_compat_decompose(u, decomposed);
-}
 
-
+#ifdef HB_USE_ATEXIT
 static void free_static_ucdn_funcs (void);
+#endif
 
 static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucdn_unicode_funcs_lazy_loader_t>
 {
@@ -248,10 +232,12 @@
   {
     hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
 
-#define HB_UNICODE_FUNC_IMPLEMENT(name) \
-    hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr);
-      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_UNICODE_FUNC_IMPLEMENT
+    hb_unicode_funcs_set_combining_class_func (funcs, hb_ucdn_combining_class, nullptr, nullptr);
+    hb_unicode_funcs_set_general_category_func (funcs, hb_ucdn_general_category, nullptr, nullptr);
+    hb_unicode_funcs_set_mirroring_func (funcs, hb_ucdn_mirroring, nullptr, nullptr);
+    hb_unicode_funcs_set_script_func (funcs, hb_ucdn_script, nullptr, nullptr);
+    hb_unicode_funcs_set_compose_func (funcs, hb_ucdn_compose, nullptr, nullptr);
+    hb_unicode_funcs_set_decompose_func (funcs, hb_ucdn_decompose, nullptr, nullptr);
 
     hb_unicode_funcs_make_immutable (funcs);
 
@@ -273,6 +259,9 @@
 
 extern "C" HB_INTERNAL
 hb_unicode_funcs_t *
+hb_ucdn_get_unicode_funcs (void);
+
+hb_unicode_funcs_t *
 hb_ucdn_get_unicode_funcs (void)
 {
   return static_ucdn_funcs.get_unconst ();

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -0,0 +1,269 @@
+/* == Start of generated table == */
+/*
+ * The following tables are generated by running:
+ *
+ *   ./gen-emoji-table.py emoji-data.txt
+ *
+ * on file with this header:
+ *
+ * # emoji-data.txt
+ * # Date: 2018-02-07, 07:55:18 GMT
+ * # © 2018 Unicode®, Inc.
+ * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+ * # For terms of use, see http://www.unicode.org/terms_of_use.html
+ * #
+ * # Emoji Data for UTS #51
+ * # Version: 11.0
+ * #
+ * # For documentation and usage, see http://www.unicode.org/reports/tr51
+ */
+
+#ifndef HB_UNICODE_EMOJI_TABLE_HH
+#define HB_UNICODE_EMOJI_TABLE_HH
+
+#include "hb-unicode.hh"
+
+
+static const struct hb_unicode_range_t _hb_unicode_emoji_Extended_Pictographic_table[] =
+{
+  {0x00A9, 0x00A9},
+  {0x00AE, 0x00AE},
+  {0x203C, 0x203C},
+  {0x2049, 0x2049},
+  {0x2122, 0x2122},
+  {0x2139, 0x2139},
+  {0x2194, 0x2199},
+  {0x21A9, 0x21AA},
+  {0x231A, 0x231B},
+  {0x2328, 0x2328},
+  {0x2388, 0x2388},
+  {0x23CF, 0x23CF},
+  {0x23E9, 0x23F3},
+  {0x23F8, 0x23FA},
+  {0x24C2, 0x24C2},
+  {0x25AA, 0x25AB},
+  {0x25B6, 0x25B6},
+  {0x25C0, 0x25C0},
+  {0x25FB, 0x25FE},
+  {0x2600, 0x2605},
+  {0x2607, 0x2612},
+  {0x2614, 0x2615},
+  {0x2616, 0x2617},
+  {0x2618, 0x2618},
+  {0x2619, 0x2619},
+  {0x261A, 0x266F},
+  {0x2670, 0x2671},
+  {0x2672, 0x267D},
+  {0x267E, 0x267F},
+  {0x2680, 0x2685},
+  {0x2690, 0x2691},
+  {0x2692, 0x269C},
+  {0x269D, 0x269D},
+  {0x269E, 0x269F},
+  {0x26A0, 0x26A1},
+  {0x26A2, 0x26B1},
+  {0x26B2, 0x26B2},
+  {0x26B3, 0x26BC},
+  {0x26BD, 0x26BF},
+  {0x26C0, 0x26C3},
+  {0x26C4, 0x26CD},
+  {0x26CE, 0x26CE},
+  {0x26CF, 0x26E1},
+  {0x26E2, 0x26E2},
+  {0x26E3, 0x26E3},
+  {0x26E4, 0x26E7},
+  {0x26E8, 0x26FF},
+  {0x2700, 0x2700},
+  {0x2701, 0x2704},
+  {0x2705, 0x2705},
+  {0x2708, 0x2709},
+  {0x270A, 0x270B},
+  {0x270C, 0x2712},
+  {0x2714, 0x2714},
+  {0x2716, 0x2716},
+  {0x271D, 0x271D},
+  {0x2721, 0x2721},
+  {0x2728, 0x2728},
+  {0x2733, 0x2734},
+  {0x2744, 0x2744},
+  {0x2747, 0x2747},
+  {0x274C, 0x274C},
+  {0x274E, 0x274E},
+  {0x2753, 0x2755},
+  {0x2757, 0x2757},
+  {0x2763, 0x2767},
+  {0x2795, 0x2797},
+  {0x27A1, 0x27A1},
+  {0x27B0, 0x27B0},
+  {0x27BF, 0x27BF},
+  {0x2934, 0x2935},
+  {0x2B05, 0x2B07},
+  {0x2B1B, 0x2B1C},
+  {0x2B50, 0x2B50},
+  {0x2B55, 0x2B55},
+  {0x3030, 0x3030},
+  {0x303D, 0x303D},
+  {0x3297, 0x3297},
+  {0x3299, 0x3299},
+  {0x1F000, 0x1F02B},
+  {0x1F02C, 0x1F02F},
+  {0x1F030, 0x1F093},
+  {0x1F094, 0x1F09F},
+  {0x1F0A0, 0x1F0AE},
+  {0x1F0AF, 0x1F0B0},
+  {0x1F0B1, 0x1F0BE},
+  {0x1F0BF, 0x1F0BF},
+  {0x1F0C0, 0x1F0C0},
+  {0x1F0C1, 0x1F0CF},
+  {0x1F0D0, 0x1F0D0},
+  {0x1F0D1, 0x1F0DF},
+  {0x1F0E0, 0x1F0F5},
+  {0x1F0F6, 0x1F0FF},
+  {0x1F10D, 0x1F10F},
+  {0x1F12F, 0x1F12F},
+  {0x1F16C, 0x1F16F},
+  {0x1F170, 0x1F171},
+  {0x1F17E, 0x1F17E},
+  {0x1F17F, 0x1F17F},
+  {0x1F18E, 0x1F18E},
+  {0x1F191, 0x1F19A},
+  {0x1F1AD, 0x1F1E5},
+  {0x1F201, 0x1F202},
+  {0x1F203, 0x1F20F},
+  {0x1F21A, 0x1F21A},
+  {0x1F22F, 0x1F22F},
+  {0x1F232, 0x1F23A},
+  {0x1F23C, 0x1F23F},
+  {0x1F249, 0x1F24F},
+  {0x1F250, 0x1F251},
+  {0x1F252, 0x1F25F},
+  {0x1F260, 0x1F265},
+  {0x1F266, 0x1F2FF},
+  {0x1F300, 0x1F320},
+  {0x1F321, 0x1F32C},
+  {0x1F32D, 0x1F32F},
+  {0x1F330, 0x1F335},
+  {0x1F336, 0x1F336},
+  {0x1F337, 0x1F37C},
+  {0x1F37D, 0x1F37D},
+  {0x1F37E, 0x1F37F},
+  {0x1F380, 0x1F393},
+  {0x1F394, 0x1F39F},
+  {0x1F3A0, 0x1F3C4},
+  {0x1F3C5, 0x1F3C5},
+  {0x1F3C6, 0x1F3CA},
+  {0x1F3CB, 0x1F3CE},
+  {0x1F3CF, 0x1F3D3},
+  {0x1F3D4, 0x1F3DF},
+  {0x1F3E0, 0x1F3F0},
+  {0x1F3F1, 0x1F3F7},
+  {0x1F3F8, 0x1F3FA},
+  {0x1F400, 0x1F43E},
+  {0x1F43F, 0x1F43F},
+  {0x1F440, 0x1F440},
+  {0x1F441, 0x1F441},
+  {0x1F442, 0x1F4F7},
+  {0x1F4F8, 0x1F4F8},
+  {0x1F4F9, 0x1F4FC},
+  {0x1F4FD, 0x1F4FE},
+  {0x1F4FF, 0x1F4FF},
+  {0x1F500, 0x1F53D},
+  {0x1F546, 0x1F54A},
+  {0x1F54B, 0x1F54F},
+  {0x1F550, 0x1F567},
+  {0x1F568, 0x1F579},
+  {0x1F57A, 0x1F57A},
+  {0x1F57B, 0x1F5A3},
+  {0x1F5A4, 0x1F5A4},
+  {0x1F5A5, 0x1F5FA},
+  {0x1F5FB, 0x1F5FF},
+  {0x1F600, 0x1F600},
+  {0x1F601, 0x1F610},
+  {0x1F611, 0x1F611},
+  {0x1F612, 0x1F614},
+  {0x1F615, 0x1F615},
+  {0x1F616, 0x1F616},
+  {0x1F617, 0x1F617},
+  {0x1F618, 0x1F618},
+  {0x1F619, 0x1F619},
+  {0x1F61A, 0x1F61A},
+  {0x1F61B, 0x1F61B},
+  {0x1F61C, 0x1F61E},
+  {0x1F61F, 0x1F61F},
+  {0x1F620, 0x1F625},
+  {0x1F626, 0x1F627},
+  {0x1F628, 0x1F62B},
+  {0x1F62C, 0x1F62C},
+  {0x1F62D, 0x1F62D},
+  {0x1F62E, 0x1F62F},
+  {0x1F630, 0x1F633},
+  {0x1F634, 0x1F634},
+  {0x1F635, 0x1F640},
+  {0x1F641, 0x1F642},
+  {0x1F643, 0x1F644},
+  {0x1F645, 0x1F64F},
+  {0x1F680, 0x1F6C5},
+  {0x1F6C6, 0x1F6CF},
+  {0x1F6D0, 0x1F6D0},
+  {0x1F6D1, 0x1F6D2},
+  {0x1F6D3, 0x1F6D4},
+  {0x1F6D5, 0x1F6DF},
+  {0x1F6E0, 0x1F6EC},
+  {0x1F6ED, 0x1F6EF},
+  {0x1F6F0, 0x1F6F3},
+  {0x1F6F4, 0x1F6F6},
+  {0x1F6F7, 0x1F6F8},
+  {0x1F6F9, 0x1F6F9},
+  {0x1F6FA, 0x1F6FF},
+  {0x1F774, 0x1F77F},
+  {0x1F7D5, 0x1F7D8},
+  {0x1F7D9, 0x1F7FF},
+  {0x1F80C, 0x1F80F},
+  {0x1F848, 0x1F84F},
+  {0x1F85A, 0x1F85F},
+  {0x1F888, 0x1F88F},
+  {0x1F8AE, 0x1F8FF},
+  {0x1F90C, 0x1F90F},
+  {0x1F910, 0x1F918},
+  {0x1F919, 0x1F91E},
+  {0x1F91F, 0x1F91F},
+  {0x1F920, 0x1F927},
+  {0x1F928, 0x1F92F},
+  {0x1F930, 0x1F930},
+  {0x1F931, 0x1F932},
+  {0x1F933, 0x1F93A},
+  {0x1F93C, 0x1F93E},
+  {0x1F93F, 0x1F93F},
+  {0x1F940, 0x1F945},
+  {0x1F947, 0x1F94B},
+  {0x1F94C, 0x1F94C},
+  {0x1F94D, 0x1F94F},
+  {0x1F950, 0x1F95E},
+  {0x1F95F, 0x1F96B},
+  {0x1F96C, 0x1F970},
+  {0x1F971, 0x1F972},
+  {0x1F973, 0x1F976},
+  {0x1F977, 0x1F979},
+  {0x1F97A, 0x1F97A},
+  {0x1F97B, 0x1F97B},
+  {0x1F97C, 0x1F97F},
+  {0x1F980, 0x1F984},
+  {0x1F985, 0x1F991},
+  {0x1F992, 0x1F997},
+  {0x1F998, 0x1F9A2},
+  {0x1F9A3, 0x1F9AF},
+  {0x1F9B0, 0x1F9B9},
+  {0x1F9BA, 0x1F9BF},
+  {0x1F9C0, 0x1F9C0},
+  {0x1F9C1, 0x1F9C2},
+  {0x1F9C3, 0x1F9CF},
+  {0x1F9D0, 0x1F9E6},
+  {0x1F9E7, 0x1F9FF},
+  {0x1FA00, 0x1FA5F},
+  {0x1FA60, 0x1FA6D},
+  {0x1FA6E, 0x1FFFD},
+};
+
+#endif /* HB_UNICODE_EMOJI_TABLE_HH */
+
+/* == End of generated table == */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -308,6 +308,8 @@
 {
   if (unlikely (hb_object_is_inert (ufuncs)))
     return;
+  if (ufuncs->immutable)
+    return;
 
   ufuncs->immutable = true;
 }
@@ -562,3 +564,19 @@
   241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
   255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
 };
+
+
+/*
+ * Emoji
+ */
+
+#include "hb-unicode-emoji-table.hh"
+
+bool
+_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp)
+{
+  return hb_bsearch_r (&cp, _hb_unicode_emoji_Extended_Pictographic_table,
+		       ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table),
+		       sizeof (hb_unicode_range_t),
+		       hb_unicode_range_t::cmp, nullptr);
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h	2018-10-19 23:02:01 UTC (rev 48949)
@@ -44,7 +44,7 @@
  * HB_UNICODE_MAX
  *
  * Since: 1.9.0
- */
+ **/
 #define HB_UNICODE_MAX 0x10FFFFu
 
 
@@ -230,9 +230,6 @@
 typedef hb_unicode_combining_class_t	(*hb_unicode_combining_class_func_t)	(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
-typedef unsigned int			(*hb_unicode_eastasian_width_func_t)	(hb_unicode_funcs_t *ufuncs,
-										 hb_codepoint_t      unicode,
-										 void               *user_data);
 typedef hb_unicode_general_category_t	(*hb_unicode_general_category_func_t)	(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
@@ -254,32 +251,6 @@
 										 hb_codepoint_t     *b,
 										 void               *user_data);
 
-/**
- * hb_unicode_decompose_compatibility_func_t:
- * @ufuncs: a Unicode function structure
- * @u: codepoint to decompose
- * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
- * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
- *
- * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
- * The complete length of the decomposition will be returned.
- *
- * If @u has no compatibility decomposition, zero should be returned.
- *
- * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
- * compatibility decomposition plus an terminating value of 0.  Consequently, @decompose must be allocated by the caller to be at least this length.  Implementations
- * of this function type must ensure that they do not write past the provided array.
- *
- * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
- */
-typedef unsigned int			(*hb_unicode_decompose_compatibility_func_t)	(hb_unicode_funcs_t *ufuncs,
-											 hb_codepoint_t      u,
-											 hb_codepoint_t     *decomposed,
-											 void               *user_data);
-
-/* See Unicode 6.1 for details on the maximum decomposition length. */
-#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
-
 /* setters */
 
 /**
@@ -299,22 +270,6 @@
 					   void *user_data, hb_destroy_func_t destroy);
 
 /**
- * hb_unicode_funcs_set_eastasian_width_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- **/
-HB_EXTERN void
-hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
-					   hb_unicode_eastasian_width_func_t func,
-					   void *user_data, hb_destroy_func_t destroy);
-
-/**
  * hb_unicode_funcs_set_general_category_func:
  * @ufuncs: a Unicode function structure
  * @func: (closure user_data) (destroy destroy) (scope notified):
@@ -394,22 +349,6 @@
 				     hb_unicode_decompose_func_t func,
 				     void *user_data, hb_destroy_func_t destroy);
 
-/**
- * hb_unicode_funcs_set_decompose_compatibility_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- **/
-HB_EXTERN void
-hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
-						   hb_unicode_decompose_compatibility_func_t func,
-						   void *user_data, hb_destroy_func_t destroy);
-
 /* accessors */
 
 /**
@@ -422,15 +361,6 @@
 			    hb_codepoint_t unicode);
 
 /**
- * hb_unicode_eastasian_width:
- *
- * Since: 0.9.2
- **/
-HB_EXTERN unsigned int
-hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
-			    hb_codepoint_t unicode);
-
-/**
  * hb_unicode_general_category:
  *
  * Since: 0.9.2
@@ -469,11 +399,6 @@
 		      hb_codepoint_t     *a,
 		      hb_codepoint_t     *b);
 
-HB_EXTERN unsigned int
-hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
-				    hb_codepoint_t      u,
-				    hb_codepoint_t     *decomposed);
-
 HB_END_DECLS
 
 #endif /* HB_UNICODE_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -101,24 +101,23 @@
     return ret;
   }
 
-
   inline unsigned int
-  modified_combining_class (hb_codepoint_t unicode)
+  modified_combining_class (hb_codepoint_t u)
   {
     /* XXX This hack belongs to the Myanmar shaper. */
-    if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
+    if (unlikely (u == 0x1037u)) u = 0x103Au;
 
     /* XXX This hack belongs to the USE shaper (for Tai Tham):
      * Reorder SAKOT to ensure it comes after any tone marks. */
-    if (unlikely (unicode == 0x1A60u)) return 254;
+    if (unlikely (u == 0x1A60u)) return 254;
 
     /* XXX This hack belongs to the Tibetan shaper:
      * Reorder PADMA to ensure it comes after any vowel marks. */
-    if (unlikely (unicode == 0x0FC6u)) return 254;
+    if (unlikely (u == 0x0FC6u)) return 254;
     /* Reorder TSA -PHRU to reorder before U+0F74 */
-    if (unlikely (unicode == 0x0F39u)) return 127;
+    if (unlikely (u == 0x0F39u)) return 127;
 
-    return _hb_modified_combining_class[combining_class (unicode)];
+    return _hb_modified_combining_class[combining_class (u)];
   }
 
   static inline hb_bool_t
@@ -267,7 +266,9 @@
 DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
 
 
-/* Modified combining marks */
+/*
+ * Modified combining marks
+ */
 
 /* Hebrew
  *
@@ -360,10 +361,37 @@
 	  FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
 	  FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
 
-#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL(gen_cat) \
-	(FLAG_UNSAFE (gen_cat) & \
-	 (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
-	  FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \
-	  FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL)))
 
+/*
+ * Ranges, used for bsearch tables.
+ */
+
+struct hb_unicode_range_t
+{
+  static int
+  cmp (const void *_key, const void *_item, void *_arg)
+  {
+    hb_codepoint_t cp = *((hb_codepoint_t *) _key);
+    const hb_unicode_range_t *range = (hb_unicode_range_t *) _item;
+
+    if (cp < range->start)
+      return -1;
+    else if (cp <= range->end)
+      return 0;
+    else
+      return +1;
+  }
+
+  hb_codepoint_t start;
+  hb_codepoint_t end;
+};
+
+/*
+ * Emoji.
+ */
+
+HB_INTERNAL bool
+_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp);
+
+
 #endif /* HB_UNICODE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -392,7 +392,7 @@
   name.stringOffset.set (name.get_size ());
   for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++)
   {
-    OT::NameRecord &record = name.nameRecord[i];
+    OT::NameRecord &record = name.nameRecordZ[i];
     record.platformID.set (3);
     record.encodingID.set (1);
     record.languageID.set (0x0409u); /* English */
@@ -717,7 +717,7 @@
       {
         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());
       }
     }
 
@@ -728,7 +728,7 @@
     for (unsigned int i = 0; i < range_records.len; i++)
     {
       range_record_t *range = &range_records[i];
-      range->props.potfRecords = feature_records.arrayZ + reinterpret_cast<uintptr_t> (range->props.potfRecords);
+      range->props.potfRecords = feature_records.arrayZ() + reinterpret_cast<uintptr_t> (range->props.potfRecords);
     }
   }
 
@@ -902,8 +902,8 @@
 				     &items[i].a,
 				     script_tags[i],
 				     language_tag,
-				     range_char_counts.arrayZ,
-				     range_properties.arrayZ,
+				     range_char_counts.arrayZ(),
+				     range_properties.arrayZ(),
 				     range_properties.len,
 				     pchars + chars_offset,
 				     item_chars_len,
@@ -943,8 +943,8 @@
 				     &items[i].a,
 				     script_tags[i],
 				     language_tag,
-				     range_char_counts.arrayZ,
-				     range_properties.arrayZ,
+				     range_char_counts.arrayZ(),
+				     range_properties.arrayZ(),
 				     range_properties.len,
 				     pchars + chars_offset,
 				     log_clusters + chars_offset,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -35,28 +35,35 @@
 struct hb_vector_t
 {
   unsigned int len;
+  private:
   unsigned int allocated; /* == 0 means allocation failed. */
-  Type *arrayZ;
+  Type *arrayZ_;
   Type static_array[StaticSize];
+  public:
 
   void init (void)
   {
     len = 0;
     allocated = ARRAY_LENGTH (static_array);
-    arrayZ = static_array;
+    arrayZ_ = nullptr;
   }
 
+  inline Type * arrayZ (void)
+  { return arrayZ_ ? arrayZ_ : static_array; }
+  inline const Type * arrayZ (void) const
+  { return arrayZ_ ? arrayZ_ : static_array; }
+
   inline Type& operator [] (unsigned int i)
   {
     if (unlikely (i >= len))
       return Crap (Type);
-    return arrayZ[i];
+    return arrayZ()[i];
   }
   inline const Type& operator [] (unsigned int i) const
   {
     if (unlikely (i >= len))
       return Null(Type);
-    return arrayZ[i];
+    return arrayZ()[i];
   }
 
   inline Type *push (void)
@@ -63,7 +70,7 @@
   {
     if (unlikely (!resize (len + 1)))
       return &Crap(Type);
-    return &arrayZ[len - 1];
+    return &arrayZ()[len - 1];
   }
   inline Type *push (const Type& v)
   {
@@ -91,17 +98,17 @@
 
     Type *new_array = nullptr;
 
-    if (arrayZ == static_array)
+    if (!arrayZ_)
     {
       new_array = (Type *) calloc (new_allocated, sizeof (Type));
       if (new_array)
-        memcpy (new_array, arrayZ, len * sizeof (Type));
+        memcpy (new_array, static_array, len * sizeof (Type));
     }
     else
     {
       bool overflows = (new_allocated < allocated) || hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
       if (likely (!overflows))
-        new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type));
+        new_array = (Type *) realloc (arrayZ_, new_allocated * sizeof (Type));
     }
 
     if (unlikely (!new_array))
@@ -110,7 +117,7 @@
       return false;
     }
 
-    arrayZ = new_array;
+    arrayZ_ = new_array;
     allocated = new_allocated;
 
     return true;
@@ -123,7 +130,7 @@
       return false;
 
     if (size > len)
-      memset (arrayZ + len, 0, (size - len) * sizeof (*arrayZ));
+      memset (arrayZ() + len, 0, (size - len) * sizeof (*arrayZ()));
 
     len = size;
     return true;
@@ -137,12 +144,13 @@
 
   inline void remove (unsigned int i)
   {
-     if (unlikely (i >= len))
-       return;
-     memmove (static_cast<void *> (&arrayZ[i]),
-	      static_cast<void *> (&arrayZ[i + 1]),
-	      (len - i - 1) * sizeof (Type));
-     len--;
+    if (unlikely (i >= len))
+      return;
+    Type *array = arrayZ();
+    memmove (static_cast<void *> (&array[i]),
+	     static_cast<void *> (&array[i + 1]),
+	     (len - i - 1) * sizeof (Type));
+    len--;
   }
 
   inline void shrink (int size_)
@@ -153,64 +161,79 @@
   }
 
   template <typename T>
-  inline Type *find (T v) {
+  inline Type *find (T v)
+  {
+    Type *array = arrayZ();
     for (unsigned int i = 0; i < len; i++)
-      if (arrayZ[i] == v)
-	return &arrayZ[i];
+      if (array[i] == v)
+	return &array[i];
     return nullptr;
   }
   template <typename T>
-  inline const Type *find (T v) const {
+  inline const Type *find (T v) const
+  {
+    const Type *array = arrayZ();
     for (unsigned int i = 0; i < len; i++)
-      if (arrayZ[i] == v)
-	return &arrayZ[i];
+      if (array[i] == v)
+	return &array[i];
     return nullptr;
   }
 
   inline void qsort (int (*cmp)(const void*, const void*))
   {
-    ::qsort (arrayZ, len, sizeof (Type), cmp);
+    ::qsort (arrayZ(), len, sizeof (Type), cmp);
   }
 
   inline void qsort (void)
   {
-    ::qsort (arrayZ, len, sizeof (Type), Type::cmp);
+    ::qsort (arrayZ(), len, sizeof (Type), Type::cmp);
   }
 
   inline void qsort (unsigned int start, unsigned int end)
   {
-    ::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp);
+    ::qsort (arrayZ() + start, end - start, sizeof (Type), Type::cmp);
   }
 
   template <typename T>
   inline Type *lsearch (const T &x)
   {
+    Type *array = arrayZ();
     for (unsigned int i = 0; i < len; i++)
-      if (0 == this->arrayZ[i].cmp (&x))
-	return &arrayZ[i];
+      if (0 == array[i].cmp (&x))
+	return &array[i];
     return nullptr;
   }
+  template <typename T>
+  inline const Type *lsearch (const T &x) const
+  {
+    const Type *array = arrayZ();
+    for (unsigned int i = 0; i < len; i++)
+      if (0 == array[i].cmp (&x))
+	return &array[i];
+    return nullptr;
+  }
 
   template <typename T>
   inline Type *bsearch (const T &x)
   {
     unsigned int i;
-    return bfind (x, &i) ? &arrayZ[i] : nullptr;
+    return bfind (x, &i) ? &arrayZ()[i] : nullptr;
   }
   template <typename T>
   inline const Type *bsearch (const T &x) const
   {
     unsigned int i;
-    return bfind (x, &i) ? &arrayZ[i] : nullptr;
+    return bfind (x, &i) ? &arrayZ()[i] : nullptr;
   }
   template <typename T>
   inline bool bfind (const T &x, unsigned int *i) const
   {
     int min = 0, max = (int) this->len - 1;
+    const Type *array = this->arrayZ();
     while (min <= max)
     {
       int mid = (min + max) / 2;
-      int c = this->arrayZ[mid].cmp (&x);
+      int c = array[mid].cmp (&x);
       if (c < 0)
         max = mid - 1;
       else if (c > 0)
@@ -221,17 +244,26 @@
 	return true;
       }
     }
-    if (max < 0 || (max < (int) this->len && this->arrayZ[max].cmp (&x) > 0))
+    if (max < 0 || (max < (int) this->len && array[max].cmp (&x) > 0))
       max++;
     *i = max;
     return false;
   }
 
+  inline void fini_deep (void)
+  {
+    Type *array = arrayZ();
+    unsigned int count = len;
+    for (unsigned int i = 0; i < count; i++)
+      array[i].fini ();
+    fini ();
+  }
+
   inline void fini (void)
   {
-    if (arrayZ != static_array)
-      free (arrayZ);
-    arrayZ = nullptr;
+    if (arrayZ_)
+      free (arrayZ_);
+    arrayZ_ = nullptr;
     allocated = len = 0;
   }
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2018-10-19 23:02:01 UTC (rev 48949)
@@ -35,12 +35,18 @@
 #include "config.h"
 #endif
 
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#if defined (_MSC_VER) && defined (HB_DLL_EXPORT)
+#define HB_EXTERN __declspec (dllexport) extern
+#endif
+
 #include "hb.h"
 #define HB_H_IN
-#ifdef HAVE_OT
 #include "hb-ot.h"
 #define HB_OT_H_IN
-#endif
 
 #include <math.h>
 #include <stdlib.h>
@@ -174,9 +180,11 @@
 # if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC)
 #  define HB_INTERNAL __attribute__((__visibility__("hidden")))
 # elif defined(__MINGW32__)
-   /* We use -export-symbols on mingw32, since it does not support visibility
-    * attribute. */
+   /* We use -export-symbols on mingw32, since it does not support visibility attributes. */
 #  define HB_INTERNAL
+# elif defined (_MSC_VER) && defined (HB_DLL_EXPORT)
+   /* We do not try to export internal symbols on Visual Studio */
+#  define HB_INTERNAL
 #else
 #  define HB_INTERNAL
 #  define HB_NO_VISIBILITY 1
@@ -229,6 +237,15 @@
 #  define HB_FALLTHROUGH /* FALLTHROUGH */
 #endif
 
+#if defined(__clang__)
+/* Disable certain sanitizer errors. */
+/* https://github.com/harfbuzz/harfbuzz/issues/1247 */
+#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
+#else
+#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
+#endif
+
+
 #if defined(_WIN32) || defined(__CYGWIN__)
    /* We need Windows Vista for both Uniscribe backend and for
     * MemoryBarrier.  We don't support compiling on Windows XP,
@@ -237,7 +254,9 @@
 #    undef _WIN32_WINNT
 #  endif
 #  ifndef _WIN32_WINNT
-#    define _WIN32_WINNT 0x0600
+#    if !defined(WINAPI_FAMILY) || !(WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+#      define _WIN32_WINNT 0x0600
+#    endif
 #  endif
 #  ifndef WIN32_LEAN_AND_MEAN
 #    define WIN32_LEAN_AND_MEAN 1
@@ -468,6 +487,14 @@
 #endif
 
 
+/*
+ * For lack of a better place, put Zawgyi script hack here.
+ * https://github.com/harfbuzz/harfbuzz/issues/1162
+ */
+
+#define HB_SCRIPT_MYANMAR_ZAWGYI	((hb_script_t) HB_TAG ('Q','a','a','g'))
+
+
 /* Headers we include for everyone.  Keep sorted.  They express dependency amongst
  * themselves, but no other file should include them.*/
 #include "hb-atomic.hh"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc	2018-10-19 23:02:01 UTC (rev 48949)
@@ -28,13 +28,13 @@
 
 #include "hb-ot-os2-unicode-ranges.hh"
 
-void
+static void
 test (hb_codepoint_t cp, unsigned int bit)
 {
-  if (OT::hb_get_unicode_range_bit (cp) != bit)
+  if (OT::_hb_ot_os2_get_unicode_range_bit (cp) != bit)
   {
     fprintf (stderr, "got incorrect bit (%d) for cp 0x%X. Should have been %d.",
-             OT::hb_get_unicode_range_bit (cp),
+             OT::_hb_ot_os2_get_unicode_range_bit (cp),
              cp,
              bit);
     abort();
@@ -41,7 +41,7 @@
   }
 }
 
-void
+static void
 test_get_unicode_range_bit (void)
 {
   test (0x0000, 0);

Modified: trunk/Build/source/libs/harfbuzz/include/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/include/Makefile.am	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/include/Makefile.am	2018-10-19 23:02:01 UTC (rev 48949)
@@ -33,6 +33,7 @@
 	$(HARFBUZZ_SRC)/hb-ot-font.h \
 	$(HARFBUZZ_SRC)/hb-ot-layout.h \
 	$(HARFBUZZ_SRC)/hb-ot-math.h \
+	$(HARFBUZZ_SRC)/hb-ot-name.h \
 	$(HARFBUZZ_SRC)/hb-ot-shape.h \
 	$(HARFBUZZ_SRC)/hb-ot-tag.h \
 	$(HARFBUZZ_SRC)/hb-ot-var.h

Modified: trunk/Build/source/libs/harfbuzz/include/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/include/Makefile.in	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/include/Makefile.in	2018-10-19 23:02:01 UTC (rev 48949)
@@ -258,9 +258,10 @@
 	$(HARFBUZZ_SRC)/hb-shape-plan.h $(HARFBUZZ_SRC)/hb-unicode.h \
 	$(HARFBUZZ_BLD)/hb-version.h $(HARFBUZZ_SRC)/hb-ot.h \
 	$(HARFBUZZ_SRC)/hb-ot-font.h $(HARFBUZZ_SRC)/hb-ot-layout.h \
-	$(HARFBUZZ_SRC)/hb-ot-math.h $(HARFBUZZ_SRC)/hb-ot-shape.h \
-	$(HARFBUZZ_SRC)/hb-ot-tag.h $(HARFBUZZ_SRC)/hb-ot-var.h \
-	$(HARFBUZZ_SRC)/hb-icu.h $(HARFBUZZ_SRC)/hb-graphite2.h
+	$(HARFBUZZ_SRC)/hb-ot-math.h $(HARFBUZZ_SRC)/hb-ot-name.h \
+	$(HARFBUZZ_SRC)/hb-ot-shape.h $(HARFBUZZ_SRC)/hb-ot-tag.h \
+	$(HARFBUZZ_SRC)/hb-ot-var.h $(HARFBUZZ_SRC)/hb-icu.h \
+	$(HARFBUZZ_SRC)/hb-graphite2.h
 all: all-am
 
 .SUFFIXES:

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2018-10-19 22:06:48 UTC (rev 48948)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2018-10-19 23:02:01 UTC (rev 48949)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [1.9.0])
+m4_define([harfbuzz_version], [2.0.0])



More information about the tex-live-commits mailing list