texlive[49193] Build/source/libs: harfbuzz-2.1.3

commits+kakuto at tug.org commits+kakuto at tug.org
Mon Nov 19 05:05:48 CET 2018


Revision: 49193
          http://tug.org/svn/texlive?view=revision&revision=49193
Author:   kakuto
Date:     2018-11-19 05:05:47 +0100 (Mon, 19 Nov 2018)
Log Message:
-----------
harfbuzz-2.1.3

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/harfbuzz/ChangeLog
    trunk/Build/source/libs/harfbuzz/Makefile.am
    trunk/Build/source/libs/harfbuzz/Makefile.in
    trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
    trunk/Build/source/libs/harfbuzz/configure
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
    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-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.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-object.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-sbix-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-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-base-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.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-math.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-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-var.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-impl.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-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/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/README	2018-11-19 04:05:47 UTC (rev 49193)
@@ -25,7 +25,7 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 2.1.1 - checked 06nov18
+harfbuzz 2.1.3 - checked 19nov18
   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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1,3 +1,8 @@
+2018-11-19  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	Import harfbuzz-2.1.3.
+	* version.ac, Makefile.am: Adjusted.
+
 2018-11-06  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	Import harfbuzz-2.1.1.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2018-11-19 04:05:47 UTC (rev 49193)
@@ -46,6 +46,7 @@
 	@HARFBUZZ_TREE@/src/hb-font.hh \
 	@HARFBUZZ_TREE@/src/hb-font.cc \
 	@HARFBUZZ_TREE@/src/hb-iter.hh \
+	@HARFBUZZ_TREE@/src/hb-kern.hh \
 	@HARFBUZZ_TREE@/src/hb-map.hh \
 	@HARFBUZZ_TREE@/src/hb-map.cc \
 	@HARFBUZZ_TREE@/src/hb-machinery.hh \
@@ -66,6 +67,7 @@
 	@HARFBUZZ_TREE@/src/hb-ot-kern-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-maxp-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name-table.hh \
+	@HARFBUZZ_TREE@/src/hb-ot-stat-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name-language.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-name-language.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name.cc \
@@ -107,7 +109,9 @@
 	@HARFBUZZ_TREE@/src/hb-aat-layout-ankr-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-bsln-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-feat-table.hh \
+	@HARFBUZZ_TREE@/src/hb-aat-layout-just-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-kerx-table.hh \
+	@HARFBUZZ_TREE@/src/hb-aat-layout-lcar-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-morx-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-trak-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout.hh \

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2018-11-19 04:05:47 UTC (rev 49193)
@@ -715,8 +715,8 @@
 	@HARFBUZZ_TREE@/src/hb-dsalgs.hh \
 	@HARFBUZZ_TREE@/src/hb-face.hh @HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font.hh @HARFBUZZ_TREE@/src/hb-font.cc \
-	@HARFBUZZ_TREE@/src/hb-iter.hh @HARFBUZZ_TREE@/src/hb-map.hh \
-	@HARFBUZZ_TREE@/src/hb-map.cc \
+	@HARFBUZZ_TREE@/src/hb-iter.hh @HARFBUZZ_TREE@/src/hb-kern.hh \
+	@HARFBUZZ_TREE@/src/hb-map.hh @HARFBUZZ_TREE@/src/hb-map.cc \
 	@HARFBUZZ_TREE@/src/hb-machinery.hh \
 	@HARFBUZZ_TREE@/src/hb-mutex.hh @HARFBUZZ_TREE@/src/hb-null.hh \
 	@HARFBUZZ_TREE@/src/hb-object.hh \
@@ -734,6 +734,7 @@
 	@HARFBUZZ_TREE@/src/hb-ot-kern-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-maxp-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name-table.hh \
+	@HARFBUZZ_TREE@/src/hb-ot-stat-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name-language.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-name-language.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-name.cc \
@@ -769,7 +770,9 @@
 	@HARFBUZZ_TREE@/src/hb-aat-layout-ankr-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-bsln-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-feat-table.hh \
+	@HARFBUZZ_TREE@/src/hb-aat-layout-just-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-kerx-table.hh \
+	@HARFBUZZ_TREE@/src/hb-aat-layout-lcar-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-morx-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-trak-table.hh \
 	@HARFBUZZ_TREE@/src/hb-aat-layout.hh \

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1,3 +1,8 @@
+2018-11-19  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	Imported harfbuzz-2.1.3 source tree from:
+	  http://www.freedesktop.org/software/harfbuzz/release/
+
 2018-11-06  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	Imported harfbuzz-2.1.1 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1,4 +1,4 @@
-Changes applied to the harfbuzz-2.1.1/ tree as obtained from:
+Changes applied to the harfbuzz-2.1.3/ 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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/configure	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.1.1.
+# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.1.3.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -580,8 +580,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='2.1.1'
-PACKAGE_STRING='harfbuzz (TeX Live) 2.1.1'
+PACKAGE_VERSION='2.1.3'
+PACKAGE_STRING='harfbuzz (TeX Live) 2.1.3'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1317,7 +1317,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures harfbuzz (TeX Live) 2.1.1 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 2.1.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1388,7 +1388,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.1.1:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.1.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1495,7 +1495,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 2.1.1
+harfbuzz (TeX Live) configure 2.1.3
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2131,7 +2131,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by harfbuzz (TeX Live) $as_me 2.1.1, which was
+It was created by harfbuzz (TeX Live) $as_me 2.1.3, 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='2.1.1'
+ VERSION='2.1.3'
 
 
 # Some tools Automake needs.
@@ -4248,8 +4248,8 @@
 
 HB_VERSION_MAJOR=2
 HB_VERSION_MINOR=1
-HB_VERSION_MICRO=1
-HB_VERSION=2.1.1
+HB_VERSION_MICRO=3
+HB_VERSION=2.1.3
 
 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 2.1.1, which was
+This file was extended by harfbuzz (TeX Live) $as_me 2.1.3, 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 2.1.1
+harfbuzz (TeX Live) config.status 2.1.3
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1,3 +1,2457 @@
+commit e3a1a8350a6a7933b0a100194985f4425ab9de19
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 16:53:25 2018 -0800
+
+    2.1.3
+
+ NEWS             | 6 ++++++
+ configure.ac     | 2 +-
+ src/hb-version.h | 4 ++--
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+commit 9714e114b88893bd962b1bcf36382bdacbc4866c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 16:52:42 2018 -0800
+
+    Fix recent commits
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0328a1ce41611ed981d41384ae5727479699f3a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 16:48:28 2018 -0800
+
+    Revert b4c61130324455bfd42095b01fa14ac901e441f1
+
+    Was causing more trouble than it solved.  We use unsigned for
+    indexing,
+    and it's not helpful to allow that wrapping to negative integers on
+    32bit machines.  The only way we could work around it would have been
+    by accepting int64_t arg, but that's overkill.
+
+    Ignore the MSVC 2008 build issue.  We don't support that compiler.
+
+ src/hb-open-type.hh | 17 ++++-------------
+ 1 file changed, 4 insertions(+), 13 deletions(-)
+
+commit 52f61cdb87b67ef42a25288d8624170d0b6d3a25
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 16:41:59 2018 -0800
+
+    Detect over/under-flow in UnsizedArray::operator[]
+
+    Was causing bad substitutions in mort table because of
+    WordOffsetToIndex()
+    producing negative numbers that were cast to unsigned int and
+    returned as
+    large numbers (which was desirable, so they would be rejected),
+    but then
+    they were cast to int when passed to this operator and acting as small
+    negative integers, which was bad...
+
+    Detect overflow.  Ouch, however, now I see this still fails on 32-bit.
+    Guess I'm going to revert an earlier change.
+
+ src/hb-open-type.hh | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+commit 6910ff03e66f5f4c9eb5592262d414ef7d91df04
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 16:11:02 2018 -0800
+
+    [aat] Fix mort shaping
+
+    Ouch!
+
+ src/hb-aat-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fdb29ab2b0058c9813f9fc44c83dd9048db92d16
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 15:38:11 2018 -0800
+
+    2.1.2
+
+ NEWS             | 13 ++++++++++++-
+ configure.ac     |  2 +-
+ src/hb-version.h |  4 ++--
+ 3 files changed, 15 insertions(+), 4 deletions(-)
+
+commit cff4c6087fdb667a40f54f20ca3c49251bf076de
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 15:04:41 2018 -0800
+
+    Fix vertical fallback space sign
+
+    Ouch!
+
+    Follow-up to cf203af8a33591c163b63dbdf0fd341bc4606190
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1343
+
+ src/hb-ot-shape-fallback.cc                   |  8 ++++----
+ test/shaping/data/in-house/tests/spaces.tests | 22 +++++++++++-----------
+ 2 files changed, 15 insertions(+), 15 deletions(-)
+
+commit 7a97f7074052a5d746af29f0743abd20682b09a2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 14:46:40 2018 -0800
+
+    Don't apply GPOS if applying morx
+
+    That's what Apple does, and it wouldn't degrade our OpenType
+    performance.
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1348
+
+ src/hb-ot-shape.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit eafd515639497098436ecf4c7b836e231bced323
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 14:45:56 2018 -0800
+
+    Prefer morx table if GSUB is empty (no scripts)
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1348
+
+ src/hb-ot-shape.cc | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit aa06574823e27c4dbb378d2467a3e6f6f36af9fe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 14:31:05 2018 -0800
+
+    Minor
+
+ src/hb-aat-layout-trak-table.hh | 2 +-
+ src/hb-ot-layout-gdef-table.hh  | 2 +-
+ src/hb-ot-layout-gsubgpos.hh    | 2 +-
+ src/hb-ot-math-table.hh         | 2 +-
+ src/hb-ot-var-fvar-table.hh     | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 50d1a41c08ad3508a94240b52df03c383ae8f1f8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 08:52:57 2018 -0500
+
+    [coretext] Hopefully the last one
+
+ src/hb-coretext.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0aab861f9cda6fba5ce71562d9f087d924e8a161
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 08:43:25 2018 -0500
+
+    [coretext] Another round
+
+ src/hb-coretext.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 0809b76a9a1d7bd53818df7e83a9c81e664dfe0e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 08:29:47 2018 -0500
+
+    [coretext] One more try..
+
+ src/hb-coretext.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 78bd4475946f2d255539306e4b1115f408c54b54
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 04:10:53 2018 -0500
+
+    [coretext] One more try
+
+ src/hb-coretext.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fd27a23c824bbbd4f4c7e75701cc5d287289704b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 03:57:12 2018 -0500
+
+    [coretext] Another build fix attemt
+
+ src/hb-coretext.cc | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 729aedf0da90cbf11235a35588cfdc06ba87a784
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 03:26:46 2018 -0500
+
+    [directwrite] Fix build
+
+ src/hb-directwrite.cc | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit cfb9771a3b096006cbae98438f1ba101d222e0e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 03:24:22 2018 -0500
+
+    [coretext] Try to fix
+
+ src/hb-coretext.cc  | 48 ++++++++++++++++++++++++++++++++++++++----------
+ src/hb-machinery.hh | 15 +++++----------
+ src/hb-shaper.hh    | 44 --------------------------------------------
+ 3 files changed, 43 insertions(+), 64 deletions(-)
+
+commit e3e9547365417e547beec84494c8bf6e4e2947fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 02:55:29 2018 -0500
+
+    [coretext] Unbreak build
+
+ src/hb-coretext.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ce5da0f36a2ece29c387810a060531df15ad6c7b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 02:29:13 2018 -0500
+
+    [shaper] Rewrite shaper data code to be more template-driven than
+    macro-driven
+
+ src/hb-coretext.cc       |  17 +++----
+ src/hb-directwrite.cc    |   9 +---
+ src/hb-face.cc           |  12 +----
+ src/hb-face.hh           |  13 ++----
+ src/hb-fallback-shape.cc |   5 --
+ src/hb-font.cc           |  14 ++----
+ src/hb-font.hh           |  12 ++---
+ src/hb-graphite2.cc      |  11 ++---
+ src/hb-machinery.hh      |  14 ++----
+ src/hb-ot-shape.cc       |   5 --
+ src/hb-shape-plan.cc     |   4 +-
+ src/hb-shaper-impl.hh    |   9 +---
+ src/hb-shaper.hh         | 117
+ ++++++++++++++++++++++++++++++++---------------
+ src/hb-uniscribe.cc      |  32 +++++--------
+ 14 files changed, 127 insertions(+), 147 deletions(-)
+
+commit cb4bf85b14afb3761a85e3da130f2844ac94a49d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 02:02:24 2018 -0500
+
+    [hdmx] Fix bounds checking
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11351
+
+ src/hb-ot-hdmx-table.hh | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit af727b4e629f8b07d7afb809be69d053827f6a51
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 01:55:39 2018 -0500
+
+    [hdmx] Minor
+
+ src/hb-ot-hdmx-table.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 9e9f16c92debecb4caf533fa112898dfec116d98
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 16 01:48:26 2018 -0500
+
+    [subset] Remove invalid glyphs from glypset to retain
+
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/1388
+
+ src/hb-subset-plan.cc | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+commit 11aa0468ac2c62ff734ba6b0f6eb43d1bd6f602b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 15 23:10:56 2018 +0330
+
+    [subset] minor, adjust spaces
+
+ src/hb-open-type.hh            |  70 ++++++------
+ src/hb-ot-cmap-table.hh        | 182 +++++++++++++++----------------
+ src/hb-ot-glyf-table.hh        | 242
+ ++++++++++++++++++++---------------------
+ src/hb-ot-hdmx-table.hh        |  20 ++--
+ src/hb-ot-hmtx-table.hh        |  14 +--
+ src/hb-ot-layout-common.hh     |  77 ++++++-------
+ src/hb-ot-layout-gpos-table.hh |  16 +--
+ src/hb-ot-layout-gsub-table.hh |   4 +-
+ src/hb-ot-layout-gsubgpos.hh   |  88 +++++++--------
+ src/hb-ot-os2-table.hh         |  24 ++--
+ src/hb-ot-post-table.hh        |  26 ++---
+ src/hb-subset-glyf.cc          | 182 +++++++++++++++----------------
+ src/hb-subset-glyf.hh          |   6 +-
+ src/hb-subset-input.cc         |   4 +-
+ src/hb-subset-plan.cc          |  32 +++---
+ src/hb-subset-plan.hh          |  12 +-
+ src/hb-subset.cc               |  46 ++++----
+ src/hb-subset.h                |   7 +-
+ util/hb-subset.cc              |   2 +-
+ 19 files changed, 510 insertions(+), 544 deletions(-)
+
+commit d7c50ff0d65192fd2b7b80704e227fa108c06de3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 15 23:10:49 2018 +0330
+
+    [math] minor, adjust spaces
+
+ src/hb-ot-math-table.hh | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+commit cabe433fbb81d314ad9e3cbed768dd13983a4477
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 15 02:48:50 2018 -0500
+
+    [base] Add TODO items
+
+ src/hb-ot-layout-base-table.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 3bf1ce748fa89316dd32de28bfdc636495e657fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 14 21:08:54 2018 -0500
+
+    [shaper] Rename
+
+ src/hb-shape-plan.cc |  2 +-
+ src/hb-shape.cc      |  2 +-
+ src/hb-shaper.cc     | 16 ++++++++--------
+ src/hb-shaper.hh     |  4 ++--
+ 4 files changed, 12 insertions(+), 12 deletions(-)
+
+commit c221dc0ba70fd4af94d8f735a9cef1ab92cc6ede
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 14 14:49:34 2018 -0500
+
+    [ot-shape] Move code around
+
+ src/hb-aat-layout-common.hh |  4 ++--
+ src/hb-aat-layout.cc        |  8 ++++----
+ src/hb-aat-layout.hh        |  6 +++---
+ src/hb-ot-layout.cc         |  2 +-
+ src/hb-ot-layout.hh         |  2 +-
+ src/hb-ot-shape.cc          | 44
+ +++++++++++++++++++++++++++++---------------
+ src/hb-ot-shape.hh          |  6 +++---
+ 7 files changed, 43 insertions(+), 29 deletions(-)
+
+commit 7867c2bad05fe48f9e4a1b776fb7da67b747fb4e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Nov 14 22:13:50 2018 +0330
+
+    [STAT] Add table parsing (#1384)
+
+ src/Makefile.sources    |   1 +
+ src/hb-ot-face.hh       |   2 +
+ src/hb-ot-font.cc       |   4 +-
+ src/hb-ot-hmtx-table.hh |  11 +-
+ src/hb-ot-stat-table.hh | 280
+ ++++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 290 insertions(+), 8 deletions(-)
+
+commit 48d16c2ab2b181c733accd4fd9730963e59b6323
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 14 09:56:30 2018 -0500
+
+    [hmtx] Fix signedness issue
+
+    Fixes
+    https://github.com/harfbuzz/harfbuzz/issues/1248#issuecomment-438689499
+
+ src/hb-ot-hmtx-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 29db2a44a6b7a28ade5e288779dbf5a200b43acd
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Nov 14 12:13:16 2018 +0330
+
+    [ot-color/svg] Note that it can be gzipped
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a9c27d576ffe4452d1a3dae73964a8f4d6dcc088
+Merge: 3c3eb5ea e543e1a0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Nov 14 08:29:17 2018 +0330
+
+    Merge pull request #1383 from punchcutter/master
+
+    Add test for https://github.com/harfbuzz/harfbuzz/issues/1379
+
+commit e543e1a0858bb5d7384d82600a789d40b62d9821
+Author: punchcutter <zarijoscha at gmail.com>
+Date:   Tue Nov 13 20:44:27 2018 -0800
+
+    Add Grantha test
+
+ .../fonts/dcf774ca21062e7439f98658b18974ea8b956d0c.ttf   | Bin 0 ->
+ 2568 bytes
+ test/shaping/data/in-house/tests/use.tests               |   1 +
+ 2 files changed, 1 insertion(+)
+
+commit 3c3eb5ea9ccf34d33e94f83b9961b3a5e903d196
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 13 21:10:10 2018 -0500
+
+    [aat] Disable fallback mark advance zeroing and positioning if
+    morx applied
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1357
+
+ src/hb-ot-shape.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit dc4225ccd1d16a1139cbc6092353db9ed03e8980
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 13 20:48:46 2018 -0500
+
+    Don't retry creating again and again in lazy_loader if create failed
+
+    Still does that if get_null() returns nullptr.  Our shaper data
+    objects
+    are like that.  Shrug.
+
+ src/hb-machinery.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit 086235f59310ed77542d4916d31a4285c68630ff
+Merge: 2092f595 c565fc3f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 13 19:50:25 2018 -0500
+
+    Merge pull request #1382 from punchcutter/master
+
+    Change USE Category for Grantha Virama
+
+commit 2092f595c7a4c591cace41cb99d31620fa6d5fa4
+Merge: 475be9d5 eee5b5ed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 13 19:49:06 2018 -0500
+
+    Merge pull request #1380 from kbrow1i/cygwin
+
+    Don't use Win32 API on Cygwin
+
+commit c565fc3fb3b14c02e30af28b9d4d4289b0d2e162
+Author: punchcutter <zarijoscha at gmail.com>
+Date:   Tue Nov 13 12:51:10 2018 -0800
+
+    Change USE Category for Grantha Virama
+    https://github.com/harfbuzz/harfbuzz/issues/1379
+
+ src/gen-use-table.py                 | 3 ++-
+ src/hb-ot-shape-complex-use-table.cc | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+commit 475be9d5c672db6e1764d9425ed7fdaa0dff35c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 13 13:01:13 2018 -0500
+
+    Fix Windows build
+
+ src/hb-atomic.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit fc44dea341f1750fec801faed66656b8a58dcded
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 13 11:54:33 2018 -0500
+
+    Use atomic ints for upem and num_glyphs on face
+
+ src/hb-aat-layout-lcar-table.hh |  3 ++-
+ src/hb-face.cc                  | 10 +++++-----
+ src/hb-face.hh                  | 24 ++++++++++++++----------
+ src/hb-ot-color-sbix-table.hh   |  2 +-
+ src/hb-static.cc                | 13 +++++++++----
+ 5 files changed, 31 insertions(+), 21 deletions(-)
+
+commit 9579ed9755d7c3e47435c55881c9841a5f60ad7e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 13 11:45:12 2018 -0500
+
+    Make atomic types' internal values non-mutable
+
+    This resulted from confusion previously...
+
+ src/hb-atomic.hh | 10 +++++-----
+ src/hb-object.hh |  2 +-
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit c52d5bcd9405dbaa9289d720d9f0853aeac6b244
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 13 11:41:29 2018 -0500
+
+    [ot-face] Add 'head' table
+
+ src/hb-ot-face.hh       |  1 +
+ src/hb-ot-glyf-table.hh | 11 +++--------
+ src/hb-static.cc        |  5 +----
+ 3 files changed, 5 insertions(+), 12 deletions(-)
+
+commit eee5b5ed04f588f618a2251397dd5b850c378627
+Author: Ken Brown <kbrown at cornell.edu>
+Date:   Mon Nov 12 21:05:39 2018 -0500
+
+    Don't use Win32 API on Cygwin
+
+    Cygwin is a Posix platform to the extent possible.  It should use the
+    Posix API except in special circumstances.
+
+ src/hb-atomic.hh                           |  2 +-
+ src/hb-blob.cc                             | 10 +++++-----
+ src/hb-mutex.hh                            |  2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh |  2 +-
+ src/hb.hh                                  |  2 +-
+ 5 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 56f541d0001f6d7e2e35cdd15217bdf52ebf8391
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 19:46:37 2018 -0500
+
+    [shape-plan] Remove unused code
+
+ src/hb-shape-plan.hh | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+commit 6c22f3fd95617a8c3cd558858c6758a0d548d370
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 19:26:01 2018 -0500
+
+    [shape-plan] Implement fine-grained caching plans with user-features
+
+    Only tag, value, and global-ness of features are considered, not their
+    start/end offsets.
+
+ src/hb-shape-plan.cc | 69
+ ++++++++++++++++++++++++++++++----------------------
+ src/hb-shape-plan.hh | 17 ++-----------
+ 2 files changed, 42 insertions(+), 44 deletions(-)
+
+commit cc8428756a1b18b0445c2c5fbb38e05453693dad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 18:48:10 2018 -0500
+
+    [shape-plan] Cache shape plans with variations based on variation
+    indices
+
+ src/hb-aat-map.cc    |  4 +---
+ src/hb-aat-map.hh    |  4 +---
+ src/hb-ot-map.cc     | 18 +++++------------
+ src/hb-ot-map.hh     |  6 +++---
+ src/hb-ot-shape.cc   | 13 +++++--------
+ src/hb-ot-shape.hh   | 28 +++++++++++++++++++++++---
+ src/hb-shape-plan.cc | 55
+ ++++------------------------------------------------
+ src/hb-shape-plan.hh | 23 ++++++++++++++++++----
+ 8 files changed, 63 insertions(+), 88 deletions(-)
+
+commit 8284cb9fb3600268e06d8a2ba8400700510de7a5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 18:18:20 2018 -0500
+
+    [shape-plan] Refactor more
+
+ src/hb-shape-plan.cc | 46 ++++++++++++++++++++++++++--------------------
+ 1 file changed, 26 insertions(+), 20 deletions(-)
+
+commit 1082338525c96206f43785e283e41b3e959871fd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 18:05:02 2018 -0500
+
+    [shape-plan] Only use shape-plan key to initialize hb_ot_shape_plan_t
+
+    Such that we don't accidentally use info not in the cache key.
+
+ src/hb-ot-shape.cc   | 25 +++++++++++--------------
+ src/hb-ot-shape.hh   |  8 +++-----
+ src/hb-shape-plan.cc |  7 +------
+ 3 files changed, 15 insertions(+), 25 deletions(-)
+
+commit 7ac03f88a22325fb4d6b77ee7694ad11f6a99bcb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 17:50:30 2018 -0500
+
+    [shape-plan] Minor
+
+ src/hb-shape-plan.cc | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+commit c7be933439af1bc8251b2b19df75b42bd0f3bdb5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 17:49:15 2018 -0500
+
+    [shape-plan] Refactor some more
+
+ src/hb-shape-plan.cc | 147
+ ++++++++++++++++++++++++++++-----------------------
+ src/hb-shape-plan.hh |  15 ++++++
+ 2 files changed, 95 insertions(+), 67 deletions(-)
+
+commit fc27777833e052dab91ca5777802e6c4e956deb4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 17:27:34 2018 -0500
+
+    [shape-plan] Refactor more
+
+ src/hb-shape-plan.cc | 44 +++++++++++++++++++++++---------------------
+ 1 file changed, 23 insertions(+), 21 deletions(-)
+
+commit 566612295b7c9bc003e9f1723f2491113724b788
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 17:19:45 2018 -0500
+
+    [shape-plan] Turn hb_shape_plan_proposal_t into hb_shape_plan_key_t
+
+    And include it in hb_shape_plan_t itself.
+
+ src/hb-shape-plan.cc | 206
+ +++++++++++++++++++--------------------------------
+ src/hb-shape-plan.hh |  27 +++----
+ 2 files changed, 92 insertions(+), 141 deletions(-)
+
+commit af123bd1b814b4fb881ea3d11f1ef0bcced75942
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 16:27:08 2018 -0500
+
+    Add hb_memcmp()
+
+ src/hb-dsalgs.hh | 17 ++++++++++++-----
+ src/hb-set.hh    |  2 +-
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+commit 65456bff37ef61094c35574a35c96f6437fd6015
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 16:15:26 2018 -0500
+
+    [shape-plan] Minor
+
+ src/hb-shape-plan.cc | 15 ++++++++-------
+ src/hb-shape-plan.hh |  9 +++++----
+ 2 files changed, 13 insertions(+), 11 deletions(-)
+
+commit 1db672a5e903de39f955e70b8814c275ccbe1b5c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 16:05:09 2018 -0500
+
+    [shaper] Rename
+
+ src/hb-shape-plan.cc |  2 +-
+ src/hb-shape.cc      |  2 +-
+ src/hb-shaper.cc     | 16 ++++++++--------
+ src/hb-shaper.hh     |  4 ++--
+ 4 files changed, 12 insertions(+), 12 deletions(-)
+
+commit 5212cd8af2171b9d0e9b78196e7758c37f148b80
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 14:25:18 2018 -0500
+
+    [fuzzing] Add new test
+
+ ...zz-testcase-minimized-hb-shape-fuzzer-5754863779053568 | Bin 0 ->
+ 100 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 274f4c726f461f49f54a79557d63bf95d22903cf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 14:24:36 2018 -0500
+
+    Rename check_array2() to check_array()
+
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ src/hb-machinery.hh             | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit e014405a214bceff3a1ce80f0b98273c44078e82
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 14:23:31 2018 -0500
+
+    Rename check_array(array, a, b) to check_range()
+
+ src/hb-aat-layout-common.hh    |  8 ++++++--
+ src/hb-machinery.hh            | 31 +++++++++++++++++++++++--------
+ src/hb-open-type.hh            |  4 +++-
+ src/hb-ot-layout-common.hh     |  5 +++--
+ src/hb-ot-layout-gpos-table.hh | 11 ++++++++---
+ src/hb-ot-var-hvar-table.hh    |  4 +++-
+ src/hb-ot-var-mvar-table.hh    |  4 +++-
+ 7 files changed, 49 insertions(+), 18 deletions(-)
+
+commit c8f4cc49272d8bcd47706a6306a625d724349f5a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 14:11:29 2018 -0500
+
+    [kerx] Fix integer overflow in multiply
+
+    Fixes https://oss-fuzz.com/v2/testcase-detail/5754863779053568
+
+ src/hb-aat-layout-kerx-table.hh |  2 +-
+ src/hb-machinery.hh             | 29 ++++++++++++++++-------------
+ 2 files changed, 17 insertions(+), 14 deletions(-)
+
+commit 1300f027a938d8898cdc9abbcad71afadf70e6e6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 13:56:48 2018 -0500
+
+    [kerx] Minor tweak on previous commit
+
+ src/hb-aat-layout-kerx-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit d6666b3866037c9d3e8a497958af9ba8d2f47a73
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 13:21:14 2018 -0500
+
+    [fuzzing] Remove limited-edition build of libraries
+
+    Use normal, production, shared libraries.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1237
+
+ src/Makefile.am          | 31 -------------------------------
+ test/fuzzing/Makefile.am | 39 +++++++++++++--------------------------
+ 2 files changed, 13 insertions(+), 57 deletions(-)
+
+commit a549aa14a0b60436a16f7f8924a5b5f82b4d5b7e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 12 13:01:22 2018 -0500
+
+    [kerx] Protect against stack underflow
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11367
+
+ src/hb-aat-layout-kerx-table.hh                            |   2 +-
+ ...uzz-testcase-minimized-hb-shape-fuzzer-5691469793329152 | Bin 0 ->
+ 69 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 3e284e02c2a5da758526360a45364a330b8ab8e9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 22:51:34 2018 -0500
+
+    [shape-plan] Minor
+
+ src/hb-ot-shape.cc   | 26 ++++++++++++++------------
+ src/hb-ot-shape.hh   | 15 ++++++++-------
+ src/hb-shape-plan.cc |  3 ++-
+ 3 files changed, 24 insertions(+), 20 deletions(-)
+
+commit 420c9de6447cdb491184e7f8caf0811b0c962c05
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 22:38:05 2018 -0500
+
+    [shape-plan] Minor rename
+
+ src/hb-shape-plan.cc | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 77bd0a6458a9169df59f6be667a8eb79bd353dc9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 22:08:48 2018 -0500
+
+    Add variation coords to shape_plan proposal
+
+    This is the root cause of bug worked around in
+    19e77e01bc13f44138e1d50533327d314dd0a018.
+
+    Still no shape plan caching for variations though.
+
+ src/hb-shape-plan.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 9c767d075d0be85227b8dc146061de9bd24f3fec
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 22:03:15 2018 -0500
+
+    Minor
+
+ src/hb-shape-plan.cc | 31 +++++++++++++------------------
+ 1 file changed, 13 insertions(+), 18 deletions(-)
+
+commit f521a28b4aad1566664cf14d70a911728ee0b962
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 21:32:01 2018 -0500
+
+    Embed hb_ot_shape_plan_t into hb_shape_plan_t
+
+    No other shaper will need shape_plan_data, by definition.  So, remove
+    abstraction layer and always create hb_ot_shape_plan_t as part of
+    hb_shape_plan_t.
+
+ src/hb-coretext.cc       | 45 ----------------------
+ src/hb-directwrite.cc    | 21 ----------
+ src/hb-fallback-shape.cc | 22 -----------
+ src/hb-graphite2.cc      | 22 -----------
+ src/hb-ot-shape.cc       | 99
+ ++++++++++++++++++++++--------------------------
+ src/hb-ot-shape.hh       | 21 +++++-----
+ src/hb-shape-plan.cc     | 22 ++++++-----
+ src/hb-shape-plan.hh     |  3 +-
+ src/hb-uniscribe.cc      | 22 -----------
+ 9 files changed, 70 insertions(+), 207 deletions(-)
+
+commit fabb01210433ce1c6d5f630bc270f82a8a4a4014
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 17:10:23 2018 -0500
+
+    Remove wrong comment
+
+ src/hb-shape-plan.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 1fd183ee1c40e2eedf86b5e82d1b547c5650ebf5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 16:47:52 2018 -0500
+
+    Finish off eecccc919ce15f60ae7ef9da5cfb311b4aa05c63
+
+ src/hb-machinery.hh | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+commit 1beacdded9cd1e4467b52244cdfd8497516eb107
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 16:35:28 2018 -0500
+
+    Minor
+
+ src/hb-coretext.cc       | 8 ++++----
+ src/hb-directwrite.cc    | 4 ++--
+ src/hb-fallback-shape.cc | 4 ++--
+ src/hb-graphite2.cc      | 4 ++--
+ src/hb-ot-shape.cc       | 4 ++--
+ src/hb-shaper.hh         | 3 ++-
+ src/hb-uniscribe.cc      | 4 ++--
+ 7 files changed, 16 insertions(+), 15 deletions(-)
+
+commit e88d47b7f2f9aee5b0b3cdc0b8f708884175a71f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 16:25:43 2018 -0500
+
+    Minor
+
+ src/hb-face.cc | 2 +-
+ src/hb-face.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 55c66c7c56c1ecd493f51fe66fd434b28addfb41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 16:09:38 2018 -0500
+
+    Revert "Declare Null() constexpr"
+
+    This reverts commit 442a72d95ab1fb3a47b486d8d1eb68e909d0ffb8.
+
+    Doesn't make sense.  No idea how my local compilers where happy
+    with it!
+
+ src/hb-null.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 98c6f03ccdd0630282ea0b166f66dcfb2a9c1f51
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 15:54:20 2018 -0500
+
+    Minor
+
+ src/hb-face.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 442a72d95ab1fb3a47b486d8d1eb68e909d0ffb8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 15:51:23 2018 -0500
+
+    Declare Null() constexpr
+
+ src/hb-null.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit eecccc919ce15f60ae7ef9da5cfb311b4aa05c63
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 15:48:47 2018 -0500
+
+    Don't store to null object
+
+    Ouch :).
+
+ src/hb-machinery.hh | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+commit 903856ab505cbc6b756d7b904650df72e90f67a7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 15:45:58 2018 -0500
+
+    Remove unused function
+
+ src/hb-machinery.hh | 5 -----
+ 1 file changed, 5 deletions(-)
+
+commit 0e0af11c62c6a55248a5d3c8868da91ef36384c5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 12:54:16 2018 -0500
+
+    [hdmx] Renames
+
+ src/hb-ot-hdmx-table.hh | 46
+ +++++++++++++++++++++++-----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+commit da6aa3b0333de3f2169a5cfcb33374e1b2fe346e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 11:40:57 2018 -0500
+
+    Add hb_blob_ptr_t.destroy()
+
+ src/hb-blob.hh                 | 1 +
+ src/hb-ot-cmap-table.hh        | 2 +-
+ src/hb-ot-color-cbdt-table.hh  | 4 ++--
+ src/hb-ot-color-sbix-table.hh  | 2 +-
+ src/hb-ot-color-svg-table.hh   | 2 +-
+ src/hb-ot-glyf-table.hh        | 4 ++--
+ src/hb-ot-hmtx-table.hh        | 6 +++---
+ src/hb-ot-layout-gdef-table.hh | 2 +-
+ src/hb-ot-layout-gsubgpos.hh   | 2 +-
+ src/hb-ot-name-table.hh        | 2 +-
+ src/hb-ot-post-table.hh        | 2 +-
+ 11 files changed, 15 insertions(+), 14 deletions(-)
+
+commit bb9abb4efd7d72198ffe8abb137ccf07ae17743e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 00:39:52 2018 -0500
+
+    [hmtx/port] Use hb_blob_ptr_t
+
+ src/hb-ot-hmtx-table.hh | 24 ++++++++++--------------
+ src/hb-ot-post-table.hh | 11 +++++------
+ 2 files changed, 15 insertions(+), 20 deletions(-)
+
+commit 0e2680a6e8d16afd38ffdb6e8cf244150a5e3837
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 00:28:47 2018 -0500
+
+    [cmap] Port to hb_blob_ptr_t
+
+    Although didn't need it...
+
+ src/hb-ot-cmap-table.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 0b0fad3ea8888d57d1e077077f5897d1901c5371
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 00:26:55 2018 -0500
+
+    [color] Port to hb_blob_ptr_t
+
+    Fix hb_blob_ptr_t::get_length () as well.
+
+ src/hb-blob.hh                |  2 +-
+ src/hb-ot-color-cbdt-table.hh | 38 +++++++++++++-------------------------
+ src/hb-ot-color-sbix-table.hh | 10 ++++------
+ src/hb-ot-color-svg-table.hh  | 11 +++++------
+ src/hb-ot-glyf-table.hh       | 22 ++++++++--------------
+ 5 files changed, 31 insertions(+), 52 deletions(-)
+
+commit 925b7a214f06b83b6f2278052656dabc4ebdd6b7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 00:17:30 2018 -0500
+
+    Comment
+
+ src/hb-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dcb63868333ba8e229fd8756377151440dd9fd23
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 00:16:17 2018 -0500
+
+    [shape-plan] Remove use of custom null object
+
+ src/hb-shape-plan.cc | 24 ------------------------
+ src/hb-shape-plan.hh |  1 -
+ 2 files changed, 25 deletions(-)
+
+commit 109891d49876de4de14a91adefbdf681c2b9acc2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 00:15:08 2018 -0500
+
+    [shape-plan] Make null object all zeros
+
+    To remove custom null object next..
+
+ src/hb-shape-plan.cc | 8 ++++----
+ src/hb-shape-plan.hh | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 34185ff3bc7ece5620145fc05da07c79da950f34
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 00:12:30 2018 -0500
+
+    [blob] Use default null object
+
+ src/hb-blob.cc | 12 ------------
+ src/hb-blob.hh |  1 -
+ 2 files changed, 13 deletions(-)
+
+commit 2ee1d9f555fba60342bab63294a6dacca10466de
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Nov 11 00:11:28 2018 -0500
+
+    [blob] Change null object memory mode to DUPLICATE
+
+    We never rely on that being equal to readonly.  Just not being
+    writable.  Maybe not even that given that the object is inert.
+
+    In prep for next commit, using default null pool.
+
+ src/hb-blob.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5d0078a48b246e713817e5bb6b4efada9618bea3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 23:52:15 2018 -0500
+
+    Add hb_blob_ptr_t
+
+    Use in a couple of places.  Push to bots to see how many unhappy
+    before
+    I convert the rest.
+
+ src/hb-blob.hh                 | 23 +++++++++++++++++++++++
+ src/hb-ot-layout-gdef-table.hh |  5 ++---
+ src/hb-ot-layout-gsubgpos.hh   |  8 +++-----
+ src/hb-ot-layout.cc            | 14 ++++++--------
+ src/hb-ot-name-table.hh        | 12 +++++-------
+ 5 files changed, 39 insertions(+), 23 deletions(-)
+
+commit e44046ec499949884b9b77c4c9937ad381386850
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 22:41:35 2018 -0500
+
+    Minor
+
+ src/hb-ot-layout.cc | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 752bd8a192af209f44dacaf1d3510d0bfc6354b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 21:13:13 2018 -0500
+
+    [kerx] Fix Format1 tupleKern sanitization
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11312
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11305
+
+ src/hb-aat-layout-kerx-table.hh                            |   6 +++---
+ ...uzz-testcase-minimized-hb-shape-fuzzer-5629524117553152 | Bin 0 ->
+ 93 bytes
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit f9e0552debc45afedd86c848484bcd169af62dc2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 21:01:49 2018 -0500
+
+    [fuzzing] Make "make lib" faster and more usable
+
+ src/Makefile.am          |  2 +-
+ test/fuzzing/Makefile.am | 12 +++++++-----
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+commit 4674655841bb810e7b68f03431d7b5a7c34c6f20
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 20:11:10 2018 -0500
+
+    Minor
+
+ src/hb-ot-shape-complex-arabic-fallback.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit a953b647507fe2ae8f5187fbfb04e69d2a2952e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 20:10:03 2018 -0500
+
+    Revert parts of previous commit that made clang unhappy
+
+ src/hb-machinery.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1d66cdcf770e45d995a318592352e4349faecb71
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 19:54:08 2018 -0500
+
+    Better fix for MSVC 2008
+
+    Follow up on b4c61130324455bfd42095b01fa14ac901e441f1
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1374
+
+ src/hb-machinery.hh            | 8 ++++----
+ src/hb-open-type.hh            | 8 ++++++++
+ src/hb-ot-cmap-table.hh        | 4 ++--
+ src/hb-ot-layout-gpos-table.hh | 4 ++--
+ src/hb-ot-var-avar-table.hh    | 9 ++++-----
+ 5 files changed, 20 insertions(+), 13 deletions(-)
+
+commit b4c61130324455bfd42095b01fa14ac901e441f1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 16:35:39 2018 -0500
+
+    Try fixing MSVC 2008 build
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1374
+
+ src/hb-open-type.hh | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+commit f2e942f3023e3c5cb3e732ee7b4782b3df170a85
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 16:11:14 2018 -0500
+
+    Fix hb_bytes_t's unused template array constructor
+
+ src/hb-dsalgs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6213a75b68825037fbaf6f5ad4eef66e8bad4b3c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 16:09:21 2018 -0500
+
+    Add trivial casts to hb_bytes_t
+
+ src/hb-dsalgs.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 8bb97d2ce140b7fe81d0726c32e024d887e0be1c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 15:54:33 2018 -0500
+
+    Revert back hb_bytes_t.cmp() to the scheme it was
+
+    But fix UBSan complaint.
+
+    There's nothing in hb_bytes_t that guarantees lexical ordering, and
+    ordering by length first is much faster.
+
+ src/hb-dsalgs.hh | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+commit 534e1d7694c96f61e853daef481b41274d5d16d8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 15:43:16 2018 -0500
+
+    Fix hb_bytes_t.cmp() for realz this time
+
+ src/hb-dsalgs.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit 929f07dbfc8b8c40771d27a502f6e5842c1c1e90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 15:38:48 2018 -0500
+
+    Fix hb_bytes_t.cmp()
+
+    Ouch!
+
+ src/hb-dsalgs.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 5547bfa9f2815df727fa524b0ea0f136a6f955b7
+Merge: 3a9fa8c0 1d82b476
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 15:35:12 2018 -0500
+
+    Merge pull request #1376 from ebraminio/minor
+
+    [colr/feat/trak] minor
+
+commit 1d82b4761d0a2e2e0be002e8a6bfe060f7b6dec3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Nov 10 18:08:11 2018 +0330
+
+    [colr/feat/trak] minor
+
+ src/hb-aat-layout-feat-table.hh | 14 +++++++-------
+ src/hb-aat-layout-trak-table.hh | 35 +++++++++++++++++++----------------
+ src/hb-ot-color-colr-table.hh   | 18 ++++++------------
+ 3 files changed, 32 insertions(+), 35 deletions(-)
+
+commit 3a9fa8c026bf28bf87e20ec95327f74fd7070b74
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 01:56:37 2018 -0500
+
+    [qsort] Fix O(N^2) behavior if all array elements are the same
+
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11327
+
+    Reported as https://github.com/noporpoise/sort_r/issues/7
+
+ src/hb-dsalgs.hh                                        |  15
+ +++++++++++----
+ ...-testcase-minimized-hb-shape-fuzzer-5634443633491968 | Bin 0 ->
+ 41814 bytes
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+commit b308aaccf0773e252880b9b887f3d3d1dec00168
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 00:37:17 2018 -0500
+
+    [post] Minor
+
+ src/hb-ot-post-table.hh | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+commit 4111c3b8cd1b1c44f722877614ec1ee25111e78c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 00:26:36 2018 -0500
+
+    [post] Move sanitize close to data fields
+
+ src/hb-ot-post-table.hh | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit e26e6dbb336e48a5898738dbbd9e56e3a00b7bed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Nov 10 00:19:50 2018 -0500
+
+    [post] Remove unnecessary hb_nonnull_ptr_t<>
+
+ src/hb-ot-post-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6b8178c6499f8d0ee45a57332af778af0e48d1b5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Nov 10 02:42:08 2018 +0330
+
+    [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5f97fe9956274d9de4e7813d7f2e850d9ffd8224
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 9 10:01:50 2018 -0500
+
+    Fix a few MSVC 2008 warnings
+
+    https://github.com/harfbuzz/harfbuzz/issues/1374
+
+ src/hb-set.hh    | 4 ++--
+ src/hb-vector.hh | 3 +++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+commit f51bb6ee7bd4ebca9b432851adc527ec086360fe
+Merge: 2d987110 b986fead
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 8 14:42:40 2018 -0500
+
+    Merge pull request #1358 from ebraminio/lcar
+
+    Hook AAT's lcar to _get_ligature_carets
+
+commit b986fead0aee52d219ce85dd49c9109bfaf31801
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Nov 5 12:31:58 2018 +0330
+
+    Hook AAT's lcar to _get_ligature_carets
+
+ src/Makefile.sources               |   1 +
+ src/hb-aat-layout-lcar-table.hh    |  92
+ +++++++++++++++++++++++++++++++++++++
+ src/hb-ot-face.hh                  |   1 +
+ src/hb-ot-layout-gdef-table.hh     |   6 +--
+ src/hb-ot-layout.cc                |  17 ++++---
+ test/api/Makefile.am               |   1 +
+ test/api/fonts/lcar.ttf            | Bin 0 -> 808 bytes
+ test/api/test-ot-ligature-carets.c |  67 +++++++++++++++++++++++++++
+ 8 files changed, 175 insertions(+), 10 deletions(-)
+
+commit 2d987110c067ccbf63b1399d2a87820121925e39
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 8 21:46:26 2018 +0330
+
+    [aat] Minor
+
+ src/hb-aat-layout-just-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 9fae611740f514e5fc101a18c4551a20b4a47b59
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Nov 8 12:17:09 2018 -0500
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/DISABLED          |  1 +
+ test/shaping/data/text-rendering-tests/Makefile.sources  |  2 +-
+ .../data/text-rendering-tests/tests/MORX-31.tests        | 16
+ ++++++++--------
+ 3 files changed, 10 insertions(+), 9 deletions(-)
+
+commit b989507fa6b36eb9950001d4e28f3946ffbe75f9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 8 20:48:54 2018 +0330
+
+    [aat] Minor (#1369)
+
+ src/hb-aat-layout-just-table.hh | 11 ++++++-----
+ src/hb-aat-layout-trak-table.hh | 12 ++++++------
+ 2 files changed, 12 insertions(+), 11 deletions(-)
+
+commit f90423847b07ff9c9f66be6dfa3b6071f9c7d9d3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 8 19:17:02 2018 +0330
+
+    [just] Initial table implementation (#1364)
+
+    A starting point, its sanitization is not tested however
+
+ src/Makefile.sources            |   1 +
+ src/hb-aat-layout-just-table.hh | 416
+ ++++++++++++++++++++++++++++++++++++++++
+ src/hb-aat-layout.cc            |   1 +
+ 3 files changed, 418 insertions(+)
+
+commit b8b00fb3c60d23efca5720db15555c4a01c56a45
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 8 18:53:14 2018 +0330
+
+    [aat] Support Lookup<OffsetTo<>>, needed by just and lcar (#1368)
+
+ src/hb-aat-layout-common.hh | 57
+ +++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-open-type.hh         | 11 +++++++++
+ 2 files changed, 68 insertions(+)
+
+commit 073d0a9fbcf4f9cf44878f3f91afa27615b14e5c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 8 10:59:50 2018 +0330
+
+    [ci] minor
+
+ .circleci/config.yml | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 15326826bf20f1f3d5ef3ddde2ad17b0ccbfa605
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 21:58:04 2018 -0500
+
+    [aat] Ignore cross-stream offset of deleted-glyphs
+
+    I think it makes sense to accumulate it, but Ned tells me that's
+    what CoreText does.
+
+ src/hb-aat-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0bf76154f1bb15aa2fc361eb725977313f103a58
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 19:11:43 2018 -0500
+
+    [fuzzing] Take whatever text we can
+
+ test/fuzzing/hb-shape-fuzzer.cc | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+commit 517a1bac97b6273e03562deefcca129648698c31
+Merge: 9d502769 b18a56a2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 18:40:48 2018 -0500
+
+    Merge pull request #1362 from harfbuzz/cross-kern
+
+    Vastly improve kern/kerx tables, including cross-stream "kerning"
+
+commit b18a56a290bf5330e81019b33f15e6951dd86a8b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 18:13:22 2018 -0500
+
+    [kerx] Comment
+
+ src/hb-aat-layout-kerx-table.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 006386be3a069199ebaf22bcc55fa7233c62e0d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 18:04:53 2018 -0500
+
+    [kern] Implement negative state numbers
+
+    Let the fuzzing bots rip this code apart...
+
+ src/hb-aat-layout-common.hh     | 90
+ ++++++++++++++++++++++++++++++-----------
+ src/hb-aat-layout-kerx-table.hh | 10 -----
+ 2 files changed, 66 insertions(+), 34 deletions(-)
+
+commit 29c5302376ff2bc8f04b0fc0efba3ce40ef564a7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 17:29:37 2018 -0500
+
+    [morx] Minor
+
+ src/hb-aat-layout-morx-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 385f78b3123f268e4c7ff423621e5ce9e8a5c54b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 17:19:21 2018 -0500
+
+    [aat] Remove deleted-glyhs after applying kerx/kern
+
+    Finally:  Fixes https://github.com/harfbuzz/harfbuzz/issues/1356
+
+    Test case:
+    $ ./hb-shape GeezaPro.ttc -u U+0628,U+064A,U+064E,U+0651,U+0629
+    [u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1 at 0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656]
+
+    The mark positioning (kern table CrossStream kerning) only works
+    if deleted
+    glyph (as result of ligation) is still in stream and pushed through
+    the
+    state machine.
+
+ src/hb-aat-layout-morx-table.hh |  16 -------
+ src/hb-aat-layout.cc            |  30 ++++++++++--
+ src/hb-aat-layout.hh            |  12 +++--
+ src/hb-ot-layout-gpos-table.hh  |   6 +--
+ src/hb-ot-layout.cc             |  60 +++++++++++++++++++++--
+ src/hb-ot-layout.hh             |  23 +++++----
+ src/hb-ot-shape.cc              | 102
+ ++++++++++++++--------------------------
+ 7 files changed, 142 insertions(+), 107 deletions(-)
+
+commit 1909072235e59eb80f9169300279b65779b932a4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 16:42:16 2018 -0500
+
+    [aat] Add debug info to state machine
+
+ src/hb-aat-layout-common.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit ca23567f41a2d6389f6fd2483a994cf5aa6aeaf8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 16:19:51 2018 -0500
+
+    Disable fallback mark positioning if kern table has cross-stream
+    kerning
+
+    Happens even if the cross-stream kerning is for cursive attachment
+    only.  Oh well..
+
+ src/hb-ot-layout.cc |  6 ++++++
+ src/hb-ot-layout.hh |  3 +++
+ src/hb-ot-shape.cc  | 14 ++++++--------
+ src/hb-ot-shape.hh  |  2 +-
+ 4 files changed, 16 insertions(+), 9 deletions(-)
+
+commit 5cf6f94dfd30a468ab8464435e846811c39d9226
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 16:07:22 2018 -0500
+
+    Don't apply both kerx and kern
+
+    Ouch!
+
+ src/hb-ot-shape.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 41cff7afc916048810a7ea4aa33ecdee7401df74
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 16:05:36 2018 -0500
+
+    Minor
+
+ src/hb-ot-shape.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 9af983af24788afad4b37bd2297b86cdca7c5c29
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 16:03:09 2018 -0500
+
+    [kern] Switch to dispatch
+
+ src/hb-aat-layout-kerx-table.hh |  7 +++++--
+ src/hb-ot-kern-table.hh         | 28 +++++++++++++++-------------
+ src/hb-ot-layout.cc             |  6 ++----
+ 3 files changed, 22 insertions(+), 19 deletions(-)
+
+commit bc06e2805ae55f5c152dfb70ee91c75830ad8f54
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 16:02:40 2018 -0500
+
+    [kerx/kern] Add has_cross_stream()
+
+ src/hb-aat-layout-kerx-table.hh | 15 +++++++++++++++
+ src/hb-ot-kern-table.hh         |  9 +++++++++
+ 2 files changed, 24 insertions(+)
+
+commit ea579f9ccc87718d4c2ca8945a997e6679428a12
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 15:44:40 2018 -0500
+
+    [kerx] Fix peculiar indexing that was needed previously
+
+    Not needed now that we use GPOS attachment for cursive kerx.
+
+ src/hb-aat-layout-kerx-table.hh | 20 +++++++-------------
+ 1 file changed, 7 insertions(+), 13 deletions(-)
+
+commit 6ee6cd93d8c61389cf242e42a531cc6e7214b21a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 15:40:55 2018 -0500
+
+    [GPOS] Only mark unsafe-to-break if kerning happened
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1365
+
+ src/hb-ot-layout-gpos-table.hh | 56
+ ++++++++++++++++++++++++------------------
+ 1 file changed, 32 insertions(+), 24 deletions(-)
+
+commit 501a364d9bb6c5828f9d660bae8b6e93b158b275
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 15:02:16 2018 -0500
+
+    [GPOS] Add TODO item
+
+ src/hb-ot-layout-gpos-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 7a9629f2f11a11d1c064662a08a0172ac2001668
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 14:52:36 2018 -0500
+
+    [kerx] Implement CrossStream kerning for non-state-machine subtables
+
+    Untested.
+
+ src/hb-aat-layout-kerx-table.hh | 12 ++++++------
+ src/hb-kern.hh                  | 43
+ +++++++++++++++++++++++++++++------------
+ src/hb-ot-kern-table.hh         |  4 ++--
+ 3 files changed, 39 insertions(+), 20 deletions(-)
+
+commit 0eb4157011e78c332d781e28b54b020aa08957c0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 14:42:15 2018 -0500
+
+    [kerx] Disable backwards-kerning for non-state-machine tables
+
+    That's what the spec says for Backwards flag, only applicable to
+    formats 1 and 4.
+
+ src/hb-aat-layout-kerx-table.hh | 8 +++-----
+ src/hb-ot-kern-table.hh         | 2 +-
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+commit b2f687c2569a3cc0b1cd0335c5ca0f8d193f8a39
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 14:38:29 2018 -0500
+
+    [kerx] Use GPOS attachment facilities for CrossStream kerning
+
+ src/hb-aat-layout-kerx-table.hh | 51
+ ++++++++++++++++++++++++++++-------------
+ 1 file changed, 35 insertions(+), 16 deletions(-)
+
+commit e10a856eb24ae45e301c3ffa778caa4c0a995bb9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 14:11:48 2018 -0500
+
+    [kerx] Format
+
+ src/hb-aat-layout-kerx-table.hh | 58
+ ++++++++++++++++++++---------------------
+ 1 file changed, 28 insertions(+), 30 deletions(-)
+
+commit 649cc3ef2773950b0b5884d9d1caf414aac888bf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 14:04:04 2018 -0500
+
+    [kerx] Don't disable crossKerning if kern feature is off
+
+ src/hb-aat-layout-kerx-table.hh | 9 +++++----
+ src/hb-ot-shape.cc              | 2 +-
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+commit 0c3b061ac244fa8a8657366e1b95523503fdf7be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 13:58:41 2018 -0500
+
+    [kern] Apply erlier, where GPOS/kerx are applied
+
+ src/hb-aat-layout-kerx-table.hh |  3 +--
+ src/hb-ot-shape-fallback.cc     |  9 +++++++++
+ src/hb-ot-shape.cc              | 12 +++++-------
+ 3 files changed, 15 insertions(+), 9 deletions(-)
+
+commit f4bad0086e40c70d66d6514f038ddda1411657c8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 13:51:17 2018 -0500
+
+    [kerx] Implement tupleKerning for Format1
+
+    Untested.
+
+ src/hb-aat-layout-kerx-table.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 39b4ef6f18605e85c68cbcec534e137fc831dbca
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 13:48:45 2018 -0500
+
+    [kerx] Better sanitize tupleKerning
+
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 14772da06f9c67d0d40712369e26064e3dee2a91
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 13:40:22 2018 -0500
+
+    [kern/kerx] Share KernTable, renamed to KerxTable
+
+ src/hb-aat-layout-kerx-table.hh |  77 ++++++++++++++++++++++--------
+ src/hb-ot-kern-table.hh         | 103
+ ++--------------------------------------
+ 2 files changed, 61 insertions(+), 119 deletions(-)
+
+commit c038f5be6b70b8edffc701dd3e4e3cd08d14e2f0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 13:35:06 2018 -0500
+
+    [fallback] Minor
+
+ src/hb-ot-shape-fallback.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit db6e658e8c0c4953c2f026f6a67a5d2fb4bdc204
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 13:33:23 2018 -0500
+
+    [kern/kerx] More towards sharing KernTable
+
+ src/hb-aat-layout-kerx-table.hh | 48 ++++++++++++++++++---------------
+ src/hb-ot-kern-table.hh         | 59
+ ++++++++++++++++++++++++++++-------------
+ 2 files changed, 67 insertions(+), 40 deletions(-)
+
+commit 89ec095979bde94bd203ed2c394f6e40629e9e78
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 13:10:05 2018 -0500
+
+    [kern] Disable Format1 and Format3 for OT-style tables
+
+ src/hb-ot-kern-table.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit ab57bcae0fd4505c80bb4ccdef6838bb2805ce79
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 13:04:21 2018 -0500
+
+    [kern] Minor
+
+ src/hb-ot-kern-table.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 30af5b4a4c2071599dc87bc092a7329befcc45cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:57:10 2018 -0500
+
+    [kern] Move code
+
+ src/hb-ot-kern-table.hh | 118
+ +++++++++++++++++++++++++-----------------------
+ 1 file changed, 62 insertions(+), 56 deletions(-)
+
+commit 1ff300464a1075b8cd5311970afbbcf4bb3b6f3d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:51:49 2018 -0500
+
+    [kern] Massage more
+
+ src/hb-ot-kern-table.hh | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+commit 8e9f6cd0fddd572e048487aae3141d3dbb1b99cb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:49:20 2018 -0500
+
+    [kerx] More minor
+
+ src/hb-aat-layout-kerx-table.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit f8c3df7d4a685bb86a1c15a5ef95485e8ef30305
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:48:06 2018 -0500
+
+    [kern/kerx] Minor
+
+ src/hb-aat-layout-kerx-table.hh |  5 +++--
+ src/hb-ot-kern-table.hh         | 19 ++++++++++---------
+ 2 files changed, 13 insertions(+), 11 deletions(-)
+
+commit f5e0a63a22f91720a997f5070b84e982e57de661
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:32:39 2018 -0500
+
+    [kern/kerx] Towards sharing KernTable
+
+ src/hb-aat-layout-kerx-table.hh |  4 ++--
+ src/hb-ot-kern-table.hh         | 19 +++++++------------
+ 2 files changed, 9 insertions(+), 14 deletions(-)
+
+commit 330508497d301c0ba5d5fb5d0900b62c191aabb5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:27:44 2018 -0500
+
+    [kern/kerx] Minor
+
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ src/hb-ot-kern-table.hh         | 5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit 1a5ef8490034f4bd8965a3c71d34a5930ebe11b7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:19:52 2018 -0500
+
+    [kern/kerx] Share Format2
+
+    This, enables Format2 for kern table, which was disabled before.
+
+ src/hb-aat-layout-kerx-table.hh |  6 ++++
+ src/hb-ot-kern-table.hh         | 73
+ +----------------------------------------
+ 2 files changed, 7 insertions(+), 72 deletions(-)
+
+commit 8faec4e33486616fdc0d690ad80d4a38a73c8182
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:16:38 2018 -0500
+
+    [kerx] Towards merging Format2
+
+ src/hb-aat-layout-kerx-table.hh | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+commit d5c0ca210fef315fd039e5b1825a865f36606a3f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 12:08:44 2018 -0500
+
+    [aat] Minor
+
+ src/hb-aat-layout-common.hh | 16 ++++++++++------
+ src/hb-ot-kern-table.hh     |  4 ++--
+ 2 files changed, 12 insertions(+), 8 deletions(-)
+
+commit e72e041c3cda164b2ffb02d770b35d0d70954818
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:56:36 2018 -0500
+
+    [kerx] Rename
+
+ src/hb-aat-layout-kerx-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 241ba7da518adee334fff105ae19dfb051868a57
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:51:40 2018 -0500
+
+    [morx/kerx] Rename types
+
+ src/hb-aat-layout-common.hh     |  4 ++--
+ src/hb-aat-layout-kerx-table.hh | 17 +++++++++--------
+ src/hb-aat-layout-morx-table.hh |  4 ++--
+ src/hb-ot-kern-table.hh         |  4 ++--
+ 4 files changed, 15 insertions(+), 14 deletions(-)
+
+commit c808e444da12840ac3ab1d78569504b9b7e876f9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:28:36 2018 -0500
+
+    [kern/kerx] Share Format1 subtable
+
+ src/hb-aat-layout-kerx-table.hh |   9 +-
+ src/hb-ot-kern-table.hh         | 187
+ +---------------------------------------
+ 2 files changed, 4 insertions(+), 192 deletions(-)
+
+commit a244190afa90ac253724a2ff23a3bdf0c507d0e6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:43:25 2018 -0500
+
+    [kerx] Minor
+
+ src/hb-aat-layout-kerx-table.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 2a720911964a00ad607ff712be09ea3ea0925c9b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:25:55 2018 -0500
+
+    [kerx] Minor
+
+ src/hb-aat-layout-kerx-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit f5f4ca7871ec2be2b5666a7b9e6e5e28133b8393
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:21:09 2018 -0500
+
+    [kern/kerx] Enable crossStream kerning in vertical
+
+    CoreText doesn't, but no reason we shouldn't do.
+
+ src/hb-aat-layout-kerx-table.hh | 8 ++++----
+ src/hb-ot-kern-table.hh         | 8 ++++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+commit d5c88af4a23bffc09840c43e6b1403b64a9f74d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:20:14 2018 -0500
+
+    [kerx] More towards sharing Format1
+
+ src/hb-aat-layout-kerx-table.hh | 35 +++++++++++++++++++++++++++++++----
+ src/hb-aat-layout-morx-table.hh | 10 ++++++----
+ 2 files changed, 37 insertions(+), 8 deletions(-)
+
+commit b693fd0dc6c7979dcacdff060ecf12a2e107071d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:05:28 2018 -0500
+
+    [morx] Simplify
+
+ src/hb-aat-layout-morx-table.hh | 27 +++++++++++----------------
+ 1 file changed, 11 insertions(+), 16 deletions(-)
+
+commit ce3451dc2aad2241c148953842e696e9f53b5deb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 11:02:04 2018 -0500
+
+    [kerx] Towards sharing Format1
+
+ src/hb-aat-layout-kerx-table.hh | 61
+ +++++++++++++++++++++++++++++++----------
+ 1 file changed, 47 insertions(+), 14 deletions(-)
+
+commit e890753ebbf0d20c1c86796837918d530610df3b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 10:58:50 2018 -0500
+
+    [morx] Minor
+
+ src/hb-aat-layout-morx-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 5b17853547ca6848ee652ef6990a81bb345ac06f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 10:45:25 2018 -0500
+
+    [kern/kerx] Share Format0
+
+ src/hb-aat-layout-kerx-table.hh | 22 +++++++++++++-----
+ src/hb-ot-kern-table.hh         | 50
+ ++++++-----------------------------------
+ 2 files changed, 23 insertions(+), 49 deletions(-)
+
+commit c97dde5d55929df394fbe57c1ba1a725592c6732
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 10:39:39 2018 -0500
+
+    [kern/kerx] Towards merge more
+
+ src/hb-aat-layout-kerx-table.hh | 75
+ ++++++++++++++++++++++++++++++-----------
+ src/hb-kern.hh                  | 33 ------------------
+ src/hb-ot-kern-table.hh         |  7 ++--
+ 3 files changed, 58 insertions(+), 57 deletions(-)
+
+commit 540ccc38b0f95804d08047f8b2d059bfd1e09337
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 10:33:46 2018 -0500
+
+    [kern/kerx] More towards sharing
+
+ src/hb-aat-layout-kerx-table.hh |  7 ++++---
+ src/hb-ot-kern-table.hh         | 10 +++++++---
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+commit d0f8f4c200670bc0bfbffbf301139a3613865a7f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 10:25:25 2018 -0500
+
+    [kern] Move kern machine to hb-kern.hh
+
+ src/Makefile.sources            |   1 +
+ src/hb-aat-layout-kerx-table.hh |   5 +-
+ src/hb-kern.hh                  | 153
+ ++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-kern-table.hh         | 115 +-----------------------------
+ src/hb-ot-shape-fallback.cc     |   2 +-
+ 5 files changed, 157 insertions(+), 119 deletions(-)
+
+commit a6acff252c72457ecfa856fd6c57081b3a4290dd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 10:19:46 2018 -0500
+
+    [kerx] Towards sharing subtables with kern
+
+ src/hb-aat-layout-kerx-table.hh | 41
+ +++++++++++++++++++++++------------------
+ 1 file changed, 23 insertions(+), 18 deletions(-)
+
+commit befac337ca2c705e2cea60a9a92e40e0dbbc40aa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 09:53:02 2018 -0500
+
+    [kern] Remove Override business
+
+    Not used in any fonts.  Not well-specified when mixing kerning with
+    Cross-Stream positioning.
+
+ src/hb-ot-kern-table.hh | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+commit 9d5027696e418b7c2a5ccbc18faafe6b9290d08b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 09:16:53 2018 -0500
+
+    [post] Return true on truncation
+
+    Client can check that buffer was completely filled out and reallocate.
+
+ src/hb-ot-post-table.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 7d91f07edf29c4923716af6cee8eb94f948ac91f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 09:14:42 2018 -0500
+
+    [post] Protect against huge empty tables
+
+ src/hb-ot-post-table.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 5ed816ab5900ac4ff7feca3d98cbd92e62fd1754
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 09:13:51 2018 -0500
+
+    [post] Minor
+
+ src/hb-ot-post-table.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 64f0becd89cc2b0136c7dc1609abc9f957525cf8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 09:10:55 2018 -0500
+
+    [post] Fix bound checking
+
+ src/hb-ot-post-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7ec694ddf25a313483044256f7ed88b644432e15
+Author: HinTak <htl10 at users.sourceforge.net>
+Date:   Wed Nov 7 13:19:36 2018 +0000
+
+    Use non-GRID-fitted values for metrics (#1363)
+
+    * Use non-GRID-fitted values for metrics
+
+    See freetype/src/base/ftobjs.c:ft_recompute_scaled_metrics() and
+    the usage of GRID_FIT_METRICS inside.
+
+    Fixes https://github.com/behdad/harfbuzz/issues/1262
+
+    * Update hb-ft.cc
+
+ src/hb-ft.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 59e04e42312293c30714a666c4479e209aec3c0e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 00:25:48 2018 -0500
+
+    [kern/kerx] Fix cursive joining
+
+    Tested with Waseem TTC:
+
+    $ hb-shape Waseem.ttc جحخج
+    [F1Jeem_R2=3 at 0,180+479|M1Khah_L2_R2=2 at 0,682+403|M1Hah_L2_R2=1 at 0,1184+403|I1Jeem_L2=0 at 0,1184+744]
+
+ src/hb-aat-layout-kerx-table.hh | 2 ++
+ src/hb-ot-kern-table.hh         | 2 ++
+ 2 files changed, 4 insertions(+)
+
+commit 8d0f797139e853d13cb2383d541c2e691d9dbae3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 7 00:04:40 2018 -0500
+
+    [kern/kerx] Fix "reset" magic value
+
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ src/hb-ot-kern-table.hh         | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 0123976a0c1e2f629252969a7ff632dc2b1dbbc9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 21:45:40 2018 -0500
+
+    [kerx] Adjust CrossStream kern to match 'kern' table
+
+ src/hb-aat-layout-kerx-table.hh | 62
+ +++++++++++++++++++++++++++++++----------
+ 1 file changed, 48 insertions(+), 14 deletions(-)
+
+commit 80a33b9ac351d81793f35a92e0255ffbf5ceb8b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 21:41:28 2018 -0500
+
+    [kern] More tweaks
+
+    Solves a mystery or two.  I'm fairly confident this is what CoreText
+    does now.
+
+ src/hb-ot-kern-table.hh | 40 ++++++++++++++++++++++------------------
+ 1 file changed, 22 insertions(+), 18 deletions(-)
+
+commit 564e8ac0465d8ced3a98ecb55d09ffaa45eefc2f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 21:04:40 2018 -0500
+
+    [kern] Adjust some more
+
+    Getting closer.  So many open questions still...
+
+ src/hb-ot-kern-table.hh | 36 ++++++++++++++++++++++--------------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+commit 4d003b8503f9c984abe2ac0de8c526a276ea8e54
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 21:04:02 2018 -0500
+
+    [kern] Add TODO
+
+ src/hb-ot-kern-table.hh | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 9810f0b80e5b6580a7a15debcec073dfc9ca759f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 19:24:04 2018 -0500
+
+    [kern] Minor
+
+ src/hb-ot-kern-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9c04b6058306cd4b2123a33a7cbeb47505434217
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 18:35:58 2018 -0500
+
+    [kern] In Format1, adjust how kerning is done
+
+    In a series of kerns in one action, kern all but last glyph forward,
+    and the last one backward.  Seems to better match what CoreText
+    is doing.
+
+    Test cases, with GeezaPro Arabic:
+
+    $ ./hb-shape GeezaPro_10_10.ttc -u U+0631,U+0628
+    [u0628.beh=1+1415|u0631.reh=0 at -202,0+700]
+
+    $ ./hb-shape GeezaPro_10_10.ttc -u U+0628,U+064F
+    [u064f.damma=0 at 0,-250+-250|u0628.beh=0 at 250,0+1665]
+
+    In a later change, I'll make kern machine avoid producing negative
+    kerns.
+
+ src/hb-ot-kern-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e8c47724638c29d78001905610c662de99c59cad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 17:16:04 2018 -0500
+
+    [kern] XXX Negate CrossKerning sign
+
+    Not sure why, but seems to better match GeezaPro Arabic w CoreText.
+
+    Quite possibly I'm doing something very wrong...
+
+ src/hb-ot-kern-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 01bf43ac01576a6415336cc56c74bb1a872566d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 14:48:42 2018 -0500
+
+    [kern] Implement CrossStream kerning
+
+ src/hb-aat-layout-kerx-table.hh | 75
+ ++++++++++++++++++++++++++---------------
+ src/hb-ot-kern-table.hh         | 63 ++++++++++++++++++++++++++++------
+ 2 files changed, 101 insertions(+), 37 deletions(-)
+
+commit b11830c09e0d78bbdaf86ef02191d00b3d8256c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 15:23:18 2018 -0500
+
+    [kern] Improve Format 2
+
+    Still disabled.
+
+ src/hb-aat-layout-common.hh | 20 +++++++++-----------
+ src/hb-ot-kern-table.hh     | 35 ++++++-----------------------------
+ 2 files changed, 15 insertions(+), 40 deletions(-)
+
+commit c0383c6bb725bed2a48485988a427348384f3f87
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 15:07:19 2018 -0500
+
+    Minor
+
+ src/hb-aat-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 10e6f708f30986bab9f7b506935f2555d6b79ff4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 13:32:13 2018 -0500
+
+    [kern] Minor
+
+ src/hb-ot-kern-table.hh | 30 +++++++++++-------------------
+ 1 file changed, 11 insertions(+), 19 deletions(-)
+
+commit 164eedd9181345d84d5f8059475ad4b97784fd46
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 13:18:27 2018 -0500
+
+    [kern] Minor
+
+ src/hb-ot-kern-table.hh | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit 220a5991baa213b7bd173ea02090dc6fc8aef655
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 13:51:39 2018 -0500
+
+    [kern/kerx] Fix trace numbering
+
+ src/hb-aat-layout-kerx-table.hh | 1 +
+ src/hb-ot-kern-table.hh         | 1 +
+ 2 files changed, 2 insertions(+)
+
+commit bfafe208da11817b5ebf3751f02af2dcdf57bd19
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 12:11:45 2018 -0500
+
+    [kern] Switch to dispatch
+
+ src/hb-aat-layout-kerx-table.hh | 12 ++++++------
+ src/hb-ot-kern-table.hh         | 31 +++++++++++++++----------------
+ 2 files changed, 21 insertions(+), 22 deletions(-)
+
+commit 213fa3bf711dae5028e3d041e305cdd35223de77
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 12:07:15 2018 -0500
+
+    [kern] Refactor to include header in each subtable type
+
+ src/hb-ot-kern-table.hh | 189
+ +++++++++++++++++++++++-------------------------
+ 1 file changed, 91 insertions(+), 98 deletions(-)
+
+commit b0da2cd0b9c1346b7cda5997fb799e895e34aace
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 11:16:45 2018 -0500
+
+    [kern] Some more
+
+ src/hb-ot-kern-table.hh | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+commit 75b00b51c8fca5d605c479333eb3abd608623613
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 11:13:40 2018 -0500
+
+    [kern] Renames
+
+ src/hb-ot-kern-table.hh | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+commit 5c3ccbc634158ba9f84d365c9a31a596f6d8825b
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Tue Nov 6 18:10:56 2018 +0200
+
+    Another missing backlash
+
+    Did this ever work?
+
+ test/api/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d29602b962c13836f4c0d46796bc693f66f9b9fe
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Tue Nov 6 18:07:47 2018 +0200
+
+    Add missing backslash
+
+ test/api/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9bddfde25dc8c302c765a1e9a8a2c38c4a836e2e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 11:03:34 2018 -0500
+
+    [util] Fix up previous commit
+
+ util/options.cc | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 3ec2e4fa7bec07ec181a0390e5f5fd695abee611
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 10:49:19 2018 -0500
+
+    [util] Don't terminate string after a a 0 in -u
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1361
+
+ util/options.cc | 4 +++-
+ util/options.hh | 2 ++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 8790b2740a334f1789fb0cf329f2b8ac9733793c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 10:24:54 2018 -0500
+
+    [fuzzing] Fix test
+
+ test/fuzzing/hb-shape-fuzzer.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 3af0a7edd0c99aaef846ae787056d7664bc69d35
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 10:20:57 2018 -0500
+
+    [fuzzing] Add make check-valgrind
+
+ test/fuzzing/Makefile.am | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit b062378ce640eb418cb413b595b79cc81a193209
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 10:20:36 2018 -0500
+
+    [test] Minor
+
+ test/api/.valgrind-suppressions | 0
+ test/api/Makefile.am            | 2 +-
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 37f421c951c853dff165df6731d0ab9c46350790
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 6 10:03:38 2018 -0500
+
+    Minor
+
+ src/hb-ot-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b6112e5ea4d08fcbfa8f7cb4ef3903514a6e99f3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Nov 6 11:42:47 2018 +0330
+
+    [test] Fix -Weverything bot complain
+
+ test/api/test-ot-name.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a49df419f04b4065fc7f70a77c5cbc453e6ba906
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Nov 6 11:26:30 2018 +0330
+
+    [test] Test hb_ot_name_{list_names,get_utf8} on test-ot-name
+
+ test/api/test-ot-name.c | 27 ++++++++++++++++++++++++---
+ 1 file changed, 24 insertions(+), 3 deletions(-)
+
+commit 9139cc23ea9fb339be9426860e0c72038d32a2ab
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Nov 6 11:17:14 2018 +0330
+
+    Fix link issue of some of the bots
+
+    e.g. https://circleci.com/gh/harfbuzz/harfbuzz/52410
+
+ src/hb-ot-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 98b37f0c109d0f7454e91c9563c56d1903d6d496
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Nov 6 09:16:28 2018 +0330
+
+    [mort] Fix table detection logic
+
+    mort really needs some initial tests at least.
+
+ src/hb-aat-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fa3ebf845fcffa827600fc4ca9fdde3aaa99f4c5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:34:07 2018 -0500
+
+    Simplify some more
+
+ src/hb-aat-layout.cc | 10 +++++-----
+ src/hb-ot-layout.cc  |  2 +-
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 61f52231f430c72e1b66b76dabb018cfe45a01d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:28:52 2018 -0500
+
+    [math] Shorten names a bit
+
+ src/hb-ot-math-table.hh |  4 ++--
+ src/hb-ot-math.cc       | 33 +++++++++++++++++++--------------
+ 2 files changed, 21 insertions(+), 16 deletions(-)
+
+commit 737efbe65583a71d7df9ae7b423d9fb1d68599b7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:26:29 2018 -0500
+
+    [ot-layout] Simplify GSUB/GPOS access
+
+    This concludes simplifying table access to face->table.XXXX.
+
+ src/hb-ot-layout.cc | 31 +++++++++++++------------------
+ 1 file changed, 13 insertions(+), 18 deletions(-)
+
+commit 5e68cec17913e9f6e98e5017a56c78a5614e4030
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:23:57 2018 -0500
+
+    [ot-layout] Simplify GDEF access
+
+ src/hb-ot-layout.cc | 44 ++++++++++++++++----------------------------
+ 1 file changed, 16 insertions(+), 28 deletions(-)
+
+commit 33b006cc51b0d27cbe1d8ed498bbf2b548cb6554
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:19:04 2018 -0500
+
+    [ot-layout] Simplify some access
+
+ src/hb-ot-layout-gdef-table.hh |  2 +-
+ src/hb-ot-layout-gpos-table.hh |  9 +++++----
+ src/hb-ot-layout-gsub-table.hh |  9 +++++----
+ src/hb-ot-layout-gsubgpos.hh   |  2 +-
+ src/hb-ot-layout.hh            | 12 +-----------
+ 5 files changed, 13 insertions(+), 21 deletions(-)
+
+commit db35409f0db9faf91a10defc81e4d6d60dc7822a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:11:46 2018 -0500
+
+    [ot-layout] Remove ensures
+
+ src/hb-ot-layout.cc | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+commit 9198de7b9b6020c1e3d6a48783e36db7e1f7e99a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:10:37 2018 -0500
+
+    [ot-font] Remove ensure
+
+ src/hb-ot-font.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit ea6d9b661fc3cf6bc4366feeb7694c0b712abfae
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:09:29 2018 -0500
+
+    [ot-face] Remove a few ensures
+
+ src/hb-face.cc | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 0fe7a745c9a323a3fc76beb011b6ab8919cf905b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 23:08:33 2018 -0500
+
+    [ot-face] Simplify more table access
+
+ src/hb-face.cc      |  6 +++---
+ src/hb-ot-face.hh   |  3 ---
+ src/hb-ot-font.cc   |  4 +---
+ src/hb-ot-layout.cc | 34 +++++++++++++++++-----------------
+ 4 files changed, 21 insertions(+), 26 deletions(-)
+
+commit a35c92cbe771a75df40412fd248ad06f6a0cfebf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 22:58:43 2018 -0500
+
+    [ot-face] Simplify table access
+
+    Yoohoo!
+
+ src/hb-aat-layout.cc | 107
+ ++++++++++-----------------------------------------
+ src/hb-ot-color.cc   |  66 ++++++++-----------------------
+ src/hb-ot-layout.cc  |  20 ++--------
+ src/hb-ot-math.cc    |  47 ++++++++--------------
+ src/hb-ot-name.cc    |  11 +-----
+ src/hb-ot-var.cc     |  33 ++++------------
+ 6 files changed, 64 insertions(+), 220 deletions(-)
+
+commit 914b595f2598d5bdb2c750832d567a57d45db84e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 22:39:50 2018 -0500
+
+    [ot-face] Include hb-ot-face directly in hb_face_t
+
+    Simplifying access coming next.
+
+ src/hb-face.cc     |  4 ++++
+ src/hb-face.hh     |  3 +++
+ src/hb-ot-face.cc  | 24 ++----------------------
+ src/hb-ot-face.hh  | 39 +++++++++++++++------------------------
+ src/hb-ot-font.cc  | 24 ++++++++++++------------
+ src/hb-ot-math.cc  |  3 +--
+ src/hb-ot-shape.cc |  5 +++--
+ 7 files changed, 40 insertions(+), 62 deletions(-)
+
+commit 56ba998cddbb2ba5d24fb0b02d2bf77a46c0f23f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 19:49:54 2018 -0500
+
+    [cmap] Push get_nominal_glyphs down into cmap accelerator
+
+ src/hb-ot-cmap-table.hh | 21 +++++++++++++++++++++
+ src/hb-ot-font.cc       | 13 +++----------
+ 2 files changed, 24 insertions(+), 10 deletions(-)
+
+commit 36d85dce25abd079252d973f804220bf7b97e987
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 19:46:29 2018 -0500
+
+    [cmap] Use hb_nonnullptr_t
+
+ src/hb-ot-cmap-table.hh | 34 ++++++++++++++--------------------
+ 1 file changed, 14 insertions(+), 20 deletions(-)
+
+commit 8be74d85534534dbdd39a0a6f496e26e9f3e661d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 5 18:47:22 2018 -0500
+
+    2.1.1
+
+ NEWS             | 8 ++++++++
+ configure.ac     | 2 +-
+ src/hb-version.h | 4 ++--
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
 commit 6482fda519ca7d173e3bcb3717aa30e237f04b25
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Mon Nov 5 15:03:18 2018 -0500

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1,4 +1,21 @@
-Overview of changes leading to 2.1.1
+Overview of changes leading to 2.1.3
+Friday, November 16, 2018
+====================================
+- Fix AAT 'mort' shaping, which was broken in 2.1.2
+
+
+Overview of changes leading to 2.1.2
+Friday, November 16, 2018
+====================================
+- Various internal changes.
+- AAT shaping improvements:
+  o Implement kern table Format 1 state-machine-based kerning.
+  o Implement cross-stream kerning (cursive positioning, etc).
+  o Ignore emptyish GSUB tables (zero scripts) if morx present.
+  o Don't apply GPOS if morx is being applied.  Matches Apple.
+
+
+-Overview of changes leading to 2.1.1
 Monday, November 5, 2018
 ====================================
 - AAT improvements:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [2.1.1],
+        [2.1.3],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2018-11-19 04:05:47 UTC (rev 49193)
@@ -15,7 +15,6 @@
 # Convenience targets:
 lib: $(BUILT_SOURCES) libharfbuzz.la
 libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES)
-fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la
 
 lib_LTLIBRARIES = libharfbuzz.la
 
@@ -169,36 +168,6 @@
 pkgconfig_DATA += harfbuzz-subset.pc
 EXTRA_DIST += harfbuzz-subset.pc.in
 
-FUZZING_CPPFLAGS = \
-	-DHB_MAX_NESTING_LEVEL=3 \
-	-DHB_SANITIZE_MAX_EDITS=3 \
-	-DHB_SANITIZE_MAX_OPS_FACTOR=3 \
-	-DHB_SANITIZE_MAX_OPS_MIN=128 \
-	-DHB_BUFFER_MAX_LEN_FACTOR=3 \
-	-DHB_BUFFER_MAX_LEN_MIN=8 \
-	-DHB_BUFFER_MAX_LEN_DEFAULT=128 \
-	-DHB_BUFFER_MAX_OPS_FACTOR=8 \
-	-DHB_BUFFER_MAX_OPS_MIN=64 \
-	-DHB_BUFFER_MAX_OPS_DEFAULT=1024 \
-	$(NULL)
-EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la
-
-libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS)
-libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES)
-libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS)
-libharfbuzz_fuzzing_la_LDFLAGS = $(AM_LDFLAGS)
-libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD)
-EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES)
-CLEANFILES += libharfbuzz-fuzzing.la
-
-libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS)
-libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES)
-libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS)
-libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS)
-libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD)
-EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES)
-CLEANFILES += libharfbuzz-subset-fuzzing.la
-
 if HAVE_ICU
 if HAVE_ICU_BUILTIN
 HBCFLAGS += $(ICU_CFLAGS)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2018-11-19 04:05:47 UTC (rev 49193)
@@ -16,6 +16,7 @@
 	hb-font.hh \
 	hb-font.cc \
 	hb-iter.hh \
+	hb-kern.hh \
 	hb-map.hh \
 	hb-map.cc \
 	hb-machinery.hh \
@@ -99,7 +100,9 @@
 	hb-aat-layout-ankr-table.hh \
 	hb-aat-layout-bsln-table.hh \
 	hb-aat-layout-feat-table.hh \
+	hb-aat-layout-just-table.hh \
 	hb-aat-layout-kerx-table.hh \
+	hb-aat-layout-lcar-table.hh \
 	hb-aat-layout-morx-table.hh \
 	hb-aat-layout-trak-table.hh \
 	hb-aat-layout.hh \
@@ -155,6 +158,7 @@
 	hb-ot-shape-fallback.hh \
 	hb-ot-shape-fallback.cc \
 	hb-ot-shape.hh \
+	hb-ot-stat-table.hh \
 	hb-ot-var.cc \
 	hb-ot-var-avar-table.hh \
 	hb-ot-var-fvar-table.hh \

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2018-11-19 04:05:47 UTC (rev 49193)
@@ -200,7 +200,8 @@
 	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
+	# https://github.com/harfbuzz/harfbuzz/issues/1379
+	return U in [0x11046, 0x1134D]
 def is_HALANT_NUM(U, UISC, UGC):
 	return UISC == Number_Joiner
 def is_ZWNJ(U, UISC, UGC):

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -58,6 +58,11 @@
     TRACE_SANITIZE (this);
     return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
   }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (arrayZ.sanitize (c, c->get_num_glyphs (), base));
+  }
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 0 */
@@ -80,6 +85,11 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) && value.sanitize (c));
   }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && value.sanitize (c, base));
+  }
 
   GlyphID	last;		/* Last GlyphID in this segment */
   GlyphID	first;		/* First GlyphID in this segment */
@@ -105,6 +115,11 @@
     TRACE_SANITIZE (this);
     return_trace (segments.sanitize (c));
   }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (segments.sanitize (c, base));
+  }
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 2 */
@@ -135,6 +150,14 @@
 		  first <= last &&
 		  valuesZ.sanitize (c, base, last - first + 1));
   }
+  template <typename T2>
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base, T2 user_data) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  first <= last &&
+		  valuesZ.sanitize (c, base, last - first + 1, user_data));
+  }
 
   GlyphID	last;		/* Last GlyphID in this segment */
   GlyphID	first;		/* First GlyphID in this segment */
@@ -162,6 +185,11 @@
     TRACE_SANITIZE (this);
     return_trace (segments.sanitize (c, this));
   }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (segments.sanitize (c, this, base));
+  }
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 4 */
@@ -183,6 +211,11 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) && value.sanitize (c));
   }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && value.sanitize (c, base));
+  }
 
   GlyphID	glyph;		/* Last GlyphID */
   T		value;		/* The lookup value (only one) */
@@ -207,6 +240,11 @@
     TRACE_SANITIZE (this);
     return_trace (entries.sanitize (c));
   }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (entries.sanitize (c, base));
+  }
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 6 */
@@ -233,6 +271,11 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
   }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount, base));
+  }
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 8 */
@@ -328,6 +371,20 @@
     default:return_trace (true);
     }
   }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    switch (u.format) {
+    case 0: return_trace (u.format0.sanitize (c, base));
+    case 2: return_trace (u.format2.sanitize (c, base));
+    case 4: return_trace (u.format4.sanitize (c, base));
+    case 6: return_trace (u.format6.sanitize (c, base));
+    case 8: return_trace (u.format8.sanitize (c, base));
+    case 10: return_trace (false); /* No need to support format10 apparently */
+    default:return_trace (true);
+    }
+  }
 
   protected:
   union {
@@ -365,7 +422,7 @@
 enum { DELETED_GLYPH = 0xFFFF };
 
 /*
- * Extended State Table
+ * (Extended) State Table
  */
 
 template <typename T>
@@ -430,13 +487,13 @@
     CLASS_END_OF_LINE = 3,
   };
 
-  inline unsigned int new_state (unsigned int newState) const
-  { return Types::extended ? newState : (newState - stateArrayTable) / nClasses; }
+  inline int new_state (unsigned int newState) const
+  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / nClasses; }
 
   inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
   {
     if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
-    return (this+classTable).get_class (glyph_id, num_glyphs);
+    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
   }
 
   inline const Entry<Extra> *get_entries () const
@@ -444,7 +501,7 @@
     return (this+entryTable).arrayZ;
   }
 
-  inline const Entry<Extra> *get_entryZ (unsigned int state, unsigned int klass) const
+  inline const Entry<Extra> *get_entryZ (int state, unsigned int klass) const
   {
     if (unlikely (klass >= nClasses)) return nullptr;
 
@@ -452,6 +509,7 @@
     const Entry<Extra> *entries = (this+entryTable).arrayZ;
 
     unsigned int entry = states[state * nClasses + klass];
+    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
 
     return &entries[entry];
   }
@@ -467,28 +525,73 @@
     const Entry<Extra> *entries = (this+entryTable).arrayZ;
 
     unsigned int num_classes = nClasses;
+    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
+      return_trace (false);
+    unsigned int row_stride = num_classes * states[0].static_size;
 
-    unsigned int num_states = 1;
+    /* Apple 'kern' table has this peculiarity:
+     *
+     * "Because the stateTableOffset in the state table header is (strictly
+     * speaking) redundant, some 'kern' tables use it to record an initial
+     * state where that should not be StartOfText. To determine if this is
+     * done, calculate what the stateTableOffset should be. If it's different
+     * from the actual stateTableOffset, use it as the initial state."
+     *
+     * We implement this by calling the initial state zero, but allow *negative*
+     * states if the start state indeed was not the first state.  Since the code
+     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
+     * tables are not affected since those address states by index, not offset.
+     */
+
+    int min_state = 0;
+    int max_state = 0;
     unsigned int num_entries = 0;
 
-    unsigned int state = 0;
+    int state_pos = 0;
+    int state_neg = 0;
     unsigned int entry = 0;
-    while (state < num_states)
+    while (min_state < state_neg || state_pos <= max_state)
     {
-      if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
-	return_trace (false);
+      if (min_state < state_neg)
+      {
+	/* Negative states. */
+	if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
+	  return_trace (false);
+	if (unlikely (!c->check_range (&states[min_state * num_classes],
+				       -min_state,
+				       row_stride)))
+	  return_trace (false);
+	if ((c->max_ops -= state_neg - min_state) < 0)
+	  return_trace (false);
+	{ /* Sweep new states. */
+	  const HBUSHORT *stop = &states[min_state * num_classes];
+	  if (unlikely (stop > states))
+	    return_trace (false);
+	  for (const HBUSHORT *p = states; stop < p; p--)
+	    num_entries = MAX<unsigned int> (num_entries, *(p - 1) + 1);
+	  state_neg = min_state;
+	}
+      }
 
-      if (unlikely (!c->check_array (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 HBUSHORT *stop = &states[num_states * num_classes];
-	for (const HBUSHORT *p = &states[state * num_classes]; p < stop; p++)
-	  num_entries = MAX<unsigned int> (num_entries, *p + 1);
-	state = num_states;
+      if (state_pos <= max_state)
+      {
+	/* Positive states. */
+	if (unlikely (!c->check_range (states,
+				       max_state + 1,
+				       row_stride)))
+	  return_trace (false);
+	if ((c->max_ops -= max_state - state_pos + 1) < 0)
+	  return_trace (false);
+	{ /* Sweep new states. */
+	  if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
+	    return_trace (false);
+	  const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
+	  if (unlikely (stop < states))
+	    return_trace (false);
+	  for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
+	    num_entries = MAX<unsigned int> (num_entries, *p + 1);
+	  state_pos = max_state + 1;
+	}
       }
 
       if (unlikely (!c->check_array (entries, num_entries)))
@@ -499,8 +602,9 @@
 	const Entry<Extra> *stop = &entries[num_entries];
 	for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
 	{
-	  unsigned int newState = new_state (p->newState);
-	  num_states = MAX<unsigned int> (num_states, newState + 1);
+	  int newState = new_state (p->newState);
+	  min_state = MIN (min_state, newState);
+	  max_state = MAX (max_state, newState);
 	}
 	entry = num_entries;
       }
@@ -528,27 +632,25 @@
 
 struct ClassTable
 {
-  inline unsigned int get_class (hb_codepoint_t glyph_id) const
+  inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int outOfRange) const
   {
-    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? classArrayZ[glyph_id - firstGlyph] : 1;
+    unsigned int i = glyph_id - firstGlyph;
+    return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
   }
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && classArrayZ.sanitize (c, glyphCount));
+    return_trace (c->check_struct (this) && classArray.sanitize (c));
   }
   protected:
-  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). */
-  UnsizedArrayOf<HBUINT8>
-		classArrayZ;	/* The class codes (indexed by glyph index minus
-				 * firstGlyph). */
+  GlyphID		firstGlyph;	/* First glyph index included in the trimmed array. */
+  ArrayOf<HBUINT8>	classArray;	/* The class codes (indexed by glyph index minus
+					 * firstGlyph). */
   public:
-  DEFINE_SIZE_ARRAY (4, classArrayZ);
+  DEFINE_SIZE_ARRAY (4, classArray);
 };
 
-struct MortTypes
+struct ObsoleteTypes
 {
   static const bool extended = false;
   typedef HBUINT16 HBUINT;
@@ -555,9 +657,11 @@
   typedef HBUINT8 HBUSHORT;
   struct ClassType : ClassTable
   {
-    inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs HB_UNUSED) const
+    inline unsigned int get_class (hb_codepoint_t glyph_id,
+				   unsigned int num_glyphs HB_UNUSED,
+				   unsigned int outOfRange) const
     {
-      return ClassTable::get_class (glyph_id);
+      return ClassTable::get_class (glyph_id, outOfRange);
     }
   };
   template <typename T>
@@ -575,7 +679,7 @@
     return offsetToIndex (2 * offset, base, array);
   }
 };
-struct MorxTypes
+struct ExtendedTypes
 {
   static const bool extended = true;
   typedef HBUINT32 HBUINT;
@@ -582,10 +686,12 @@
   typedef HBUINT16 HBUSHORT;
   struct ClassType : Lookup<HBUINT16>
   {
-    inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
+    inline unsigned int get_class (hb_codepoint_t glyph_id,
+				   unsigned int num_glyphs,
+				   unsigned int outOfRange) const
     {
       const HBUINT16 *v = get_value (glyph_id, num_glyphs);
-      return v ? *v : 1;
+      return v ? *v : outOfRange;
     }
   };
   template <typename T>
@@ -620,7 +726,7 @@
     if (!c->in_place)
       buffer->clear_output ();
 
-    unsigned int state = StateTable<Types, EntryData>::STATE_START_OF_TEXT;
+    int state = StateTable<Types, EntryData>::STATE_START_OF_TEXT;
     bool last_was_dont_advance = false;
     for (buffer->idx = 0; buffer->successful;)
     {
@@ -627,6 +733,7 @@
       unsigned int klass = buffer->idx < buffer->len ?
 			   machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) :
 			   (unsigned) StateTable<Types, EntryData>::CLASS_END_OF_TEXT;
+      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
       const Entry<EntryData> *entry = machine.get_entryZ (state, klass);
       if (unlikely (!entry))
 	break;
@@ -659,6 +766,7 @@
       last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0;
 
       state = machine.new_state (entry->newState);
+      DEBUG_MSG (APPLY, nullptr, "s%d", state);
 
       if (buffer->idx == buffer->len)
 	break;
@@ -693,7 +801,7 @@
   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;
+  const hb_ot_shape_plan_t *plan;
   hb_font_t *font;
   hb_face_t *face;
   hb_buffer_t *buffer;
@@ -705,7 +813,7 @@
   unsigned int lookup_index;
   unsigned int debug_depth;
 
-  HB_INTERNAL hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_,
+  HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
 				      hb_font_t *font_,
 				      hb_buffer_t *buffer_,
 				      hb_blob_t *blob = const_cast<hb_blob_t *> (&Null(hb_blob_t)));

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -54,13 +54,6 @@
 
 struct FeatureName
 {
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  (base+settingTable).sanitize (c, nSettings)));
-  }
-
   enum {
     Exclusive = 0x8000,		/* If set, the feature settings are mutually exclusive. */
     NotDefault = 0x4000,	/* If clear, then the setting with an index of 0 in
@@ -75,6 +68,13 @@
 				 * as the default. */
   };
 
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  (base+settingTable).sanitize (c, nSettings)));
+  }
+
   protected:
   HBUINT16	feature;	/* Feature type. */
   HBUINT16	nSettings;	/* The number of records in the setting name array. */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -0,0 +1,417 @@
+/*
+ * 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_AAT_LAYOUT_JUST_TABLE_HH
+#define HB_AAT_LAYOUT_JUST_TABLE_HH
+
+#include "hb-aat-layout-common.hh"
+#include "hb-ot-layout.hh"
+#include "hb-open-type.hh"
+
+#include "hb-aat-layout-morx-table.hh"
+
+/*
+ * just -- Justification
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6just.html
+ */
+#define HB_AAT_TAG_just HB_TAG('j','u','s','t')
+
+
+namespace AAT {
+
+using namespace OT;
+
+
+struct ActionSubrecordHeader
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  HBUINT16 	actionClass; 	/* The JustClass value associated with this
+				 * ActionSubrecord. */
+  HBUINT16 	actionType; 	/* The type of postcompensation action. */
+  HBUINT16 	actionLength;	/* Length of this ActionSubrecord record, which
+				 * must be a multiple of 4. */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct DecompositionAction
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  ActionSubrecordHeader
+		header;
+  Fixed		lowerLimit; 	/* If the distance factor is less than this value,
+				 * then the ligature is decomposed. */
+  Fixed		upperLimit; 	/* If the distance factor is greater than this value,
+				 * then the ligature is decomposed. */
+  HBUINT16 	order;		/* Numerical order in which this ligature will
+				 * be decomposed; you may want infrequent ligatures
+				 * to decompose before more frequent ones. The ligatures
+				 * on the line of text will decompose in increasing
+				 * value of this field. */
+  ArrayOf<HBUINT16>
+		decomposedglyphs;
+				/* Number of 16-bit glyph indexes that follow;
+				 * the ligature will be decomposed into these glyphs.
+				 *
+				 * Array of decomposed glyphs. */
+  public:
+  DEFINE_SIZE_ARRAY (18, decomposedglyphs);
+};
+
+struct UnconditionalAddGlyphAction
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  ActionSubrecordHeader
+		header;
+  GlyphID	addGlyph;	/* Glyph that should be added if the distance factor
+				 * is growing. */
+
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct ConditionalAddGlyphAction
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  ActionSubrecordHeader
+		header;
+  Fixed 	substThreshold; /* Distance growth factor (in ems) at which
+				 * this glyph is replaced and the growth factor
+				 * recalculated. */
+  GlyphID 	addGlyph; 	/* Glyph to be added as kashida. If this value is
+				 * 0xFFFF, no extra glyph will be added. Note that
+				 * generally when a glyph is added, justification
+				 * will need to be redone. */
+  GlyphID 	substGlyph; 	/* Glyph to be substituted for this glyph if the
+				 * growth factor equals or exceeds the value of
+				 * substThreshold. */
+  public:
+  DEFINE_SIZE_STATIC (14);
+};
+
+struct DuctileGlyphAction
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  ActionSubrecordHeader
+		header;
+  HBUINT32 	variationAxis;	/* The 4-byte tag identifying the ductile axis.
+				 * This would normally be 0x64756374 ('duct'),
+				 * but you may use any axis the font contains. */
+  Fixed 	minimumLimit; 	/* The lowest value for the ductility axis tha
+				 * still yields an acceptable appearance. Normally
+				 * this will be 1.0. */
+  Fixed 	noStretchValue; /* This is the default value that corresponds to
+				 * no change in appearance. Normally, this will
+				 * be 1.0. */
+  Fixed 	maximumLimit; 	/* The highest value for the ductility axis that
+				 * still yields an acceptable appearance. */
+  public:
+  DEFINE_SIZE_STATIC (22);
+};
+
+struct RepeatedAddGlyphAction
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  ActionSubrecordHeader
+		header;
+  HBUINT16 	flags;		/* Currently unused; set to 0. */
+  GlyphID 	glyph;		/* Glyph that should be added if the distance factor
+				 * is growing. */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+struct ActionSubrecord
+{
+  inline unsigned int get_length (void) const { return u.header.actionLength; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    switch (u.header.actionType)
+    {
+    case 0:  return_trace (u.decompositionAction.sanitize (c));
+    case 1:  return_trace (u.unconditionalAddGlyphAction.sanitize (c));
+    case 2:  return_trace (u.conditionalAddGlyphAction.sanitize (c));
+    // case 3: return_trace (u.stretchGlyphAction.sanitize (c));
+    case 4:  return_trace (u.decompositionAction.sanitize (c));
+    case 5:  return_trace (u.decompositionAction.sanitize (c));
+    default: return_trace (true);
+    }
+  }
+
+  protected:
+  union	{
+  ActionSubrecordHeader		header;
+  DecompositionAction		decompositionAction;
+  UnconditionalAddGlyphAction	unconditionalAddGlyphAction;
+  ConditionalAddGlyphAction	conditionalAddGlyphAction;
+  /* StretchGlyphAction stretchGlyphAction; -- Not supported by CoreText */
+  DuctileGlyphAction		ductileGlyphAction;
+  RepeatedAddGlyphAction	repeatedAddGlyphAction;
+  } u;				/* Data. The format of this data depends on
+				 * the value of the actionType field. */
+  public:
+  DEFINE_SIZE_UNION (6, header);
+};
+
+struct PostcompensationActionChain
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    unsigned int offset = min_size;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      const ActionSubrecord& subrecord = StructAtOffset<ActionSubrecord> (this, offset);
+      if (unlikely (!subrecord.sanitize (c))) return_trace (false);
+      offset += subrecord.get_length ();
+    }
+
+    return_trace (true);
+  }
+
+  protected:
+  HBUINT32	count;
+
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct JustWidthDeltaEntry
+{
+  enum Flags
+  {
+    Reserved1		=0xE000,/* Reserved. You should set these bits to zero. */
+    UnlimiteGap		=0x1000,/* The glyph can take unlimited gap. When this
+				 * glyph participates in the justification process,
+				 * it and any other glyphs on the line having this
+				 * bit set absorb all the remaining gap. */
+    Reserved2		=0x0FF0,/* Reserved. You should set these bits to zero. */
+    Priority		=0x000F /* The justification priority of the glyph. */
+  };
+
+  enum Priority
+  {
+    Kashida		= 0,	/* Kashida priority. This is the highest priority
+				 * during justification. */
+    Whitespace		= 1,	/* Whitespace priority. Any whitespace glyphs (as
+				 * identified in the glyph properties table) will
+				 * get this priority. */
+    InterCharacter	= 2,	/* Inter-character priority. Give this to any
+				 * remaining glyphs. */
+    NullPriority	= 3	/* Null priority. You should set this priority for
+				 * glyphs that only participate in justification
+				 * after the above priorities. Normally all glyphs
+				 * have one of the previous three values. If you
+				 * don't want a glyph to participate in justification,
+				 * and you don't want to set its factors to zero,
+				 * you may instead assign it to the null priority. */
+  };
+
+  protected:
+  Fixed		beforeGrowLimit;/* The ratio by which the advance width of the
+				 * glyph is permitted to grow on the left or top side. */
+  Fixed		beforeShrinkLimit;
+				/* The ratio by which the advance width of the
+				 * glyph is permitted to shrink on the left or top side. */
+  Fixed		afterGrowLimit;	/* The ratio by which the advance width of the glyph
+				 * is permitted to shrink on the left or top side. */
+  Fixed		afterShrinkLimit;
+				/* The ratio by which the advance width of the glyph
+				 * is at most permitted to shrink on the right or
+				 * bottom side. */
+  HBUINT16	growFlags;	/* Flags controlling the grow case. */
+  HBUINT16	shrinkFlags;	/* Flags controlling the shrink case. */
+
+  public:
+  DEFINE_SIZE_STATIC (20);
+};
+
+struct WidthDeltaPair
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  HBUINT32	justClass;	/* The justification category associated
+				 * with the wdRecord field. Only 7 bits of
+				 * this field are used. (The other bits are
+				 * used as padding to guarantee longword
+				 * alignment of the following record). */
+  JustWidthDeltaEntry
+		wdRecord;	/* The actual width delta record. */
+
+  public:
+  DEFINE_SIZE_STATIC (24);
+};
+  
+typedef OT::LArrayOf<WidthDeltaPair> WidthDeltaCluster;
+
+struct JustificationCategory
+{
+  typedef void EntryData;
+
+  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. */
+    MarkCategory	=0x3F80,/* The justification category for the marked
+				 * glyph if nonzero. */
+    CurrentCategory	=0x007F /* The justification category for the current
+				 * glyph if nonzero. */
+  };
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  morphHeader.sanitize (c) &&
+			  stHeader.sanitize (c)));
+  }
+
+  protected:
+  ChainSubtable<ObsoleteTypes>
+		morphHeader;	/* Metamorphosis-style subtable header. */
+  StateTable<ObsoleteTypes, EntryData>
+		stHeader;	/* The justification insertion state table header */
+  public:
+  DEFINE_SIZE_STATIC (30);
+};
+
+struct JustificationHeader
+{
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  justClassTable.sanitize (c, base, base) &&
+			  wdcTable.sanitize (c, base) &&
+			  pcTable.sanitize (c, base) &&
+			  lookupTable.sanitize (c, base)));
+  }
+
+  protected:
+  OffsetTo<JustificationCategory>
+		justClassTable;	/* Offset to the justification category state table. */
+  OffsetTo<WidthDeltaCluster>
+  		wdcTable;	/* Offset from start of justification table to start
+				 * of the subtable containing the width delta factors
+				 * for the glyphs in your font.
+				 *
+				 * The width delta clusters table. */
+  OffsetTo<PostcompensationActionChain>
+		pcTable;	/* Offset from start of justification table to start
+				 * of postcompensation subtable (set to zero if none).
+				 *
+				 * The postcompensation subtable, if present in the font. */
+  Lookup<OffsetTo<WidthDeltaCluster> >
+  		lookupTable;	/* Lookup table associating glyphs with width delta
+				 * clusters. See the description of Width Delta Clusters
+				 * table for details on how to interpret the lookup values. */
+
+  public:
+  DEFINE_SIZE_MIN (8);
+};
+
+struct just
+{
+  static const hb_tag_t tableTag = HB_AAT_TAG_just;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+
+    return_trace (likely (c->check_struct (this) &&
+			  version.major == 1 &&
+			  horizData.sanitize (c, this, this) &&
+			  vertData.sanitize (c, this, this)));
+  }
+
+  protected:
+  FixedVersion<>version;	/* Version of the justification table
+				 * (0x00010000u for version 1.0). */
+  HBUINT16	format; 	/* Format of the justification table (set to 0). */
+  OffsetTo<JustificationHeader>
+		horizData;	/* Byte offset from the start of the justification table
+				 * to the header for tables that contain justification
+				 * information for horizontal text.
+				 * If you are not including this information,
+				 * store 0. */
+  OffsetTo<JustificationHeader>
+		vertData;	/* ditto, vertical */
+
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+} /* namespace AAT */
+
+
+#endif /* HB_AAT_LAYOUT_JUST_TABLE_HH */

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -28,10 +28,8 @@
 #ifndef HB_AAT_LAYOUT_KERX_TABLE_HH
 #define HB_AAT_LAYOUT_KERX_TABLE_HH
 
-#include "hb-open-type.hh"
-#include "hb-aat-layout-common.hh"
-#include "hb-ot-layout-gpos-table.hh"
-#include "hb-ot-kern-table.hh"
+#include "hb-kern.hh"
+#include "hb-aat-layout-ankr-table.hh"
 
 /*
  * kerx -- Extended Kerning
@@ -55,29 +53,54 @@
 
   unsigned int offset = value;
   const FWORD *pv = &StructAtOffset<FWORD> (base, offset);
-  if (unlikely (!pv->sanitize (&c->sanitizer))) return 0;
+  if (unlikely (!c->sanitizer.check_array (pv, tupleCount))) return 0;
   return *pv;
 }
 
 
-struct KerxSubTableHeader
+struct hb_glyph_pair_t
 {
+  hb_codepoint_t left;
+  hb_codepoint_t right;
+};
+
+struct KernPair
+{
+  inline int get_kerning (void) const
+  { return value; }
+
+  inline int cmp (const hb_glyph_pair_t &o) const
+  {
+    int ret = left.cmp (o.left);
+    if (ret) return ret;
+    return right.cmp (o.right);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this)));
+    return_trace (c->check_struct (this));
   }
 
+  protected:
+  GlyphID	left;
+  GlyphID	right;
+  FWORD		value;
   public:
-  HBUINT32	length;
-  HBUINT32	coverage;
-  HBUINT32	tupleCount;
-  public:
-  DEFINE_SIZE_STATIC (12);
+  DEFINE_SIZE_STATIC (6);
 };
 
+template <typename KernSubTableHeader>
 struct KerxSubTableFormat0
 {
+  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,
 			  hb_aat_apply_context_t *c) const
   {
@@ -85,7 +108,7 @@
     int i = pairs.bsearch (pair);
     if (i == -1) return 0;
     int v = pairs[i].get_kerning ();
-    return kerxTupleKern (v, header.tupleCount, this, c);
+    return kerxTupleKern (v, header.tuple_count (), this, c);
   }
 
   inline bool apply (hb_aat_apply_context_t *c) const
@@ -95,8 +118,11 @@
     if (!c->plan->requested_kerning)
       return false;
 
+    if (header.coverage & header.Backwards)
+      return false;
+
     accelerator_t accel (*this, c);
-    hb_kern_machine_t<accelerator_t> machine (accel);
+    hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
     machine.kern (c->font, c->buffer, c->plan->kern_mask);
 
     return_trace (true);
@@ -119,20 +145,33 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  pairs.sanitize (c)));
+    return_trace (likely (pairs.sanitize (c)));
   }
 
   protected:
-  KerxSubTableHeader	header;
-  BinSearchArrayOf<KernPair, HBUINT32>
+  KernSubTableHeader	header;
+  BinSearchArrayOf<KernPair, typename KernSubTableHeader::Types::HBUINT>
 			pairs;	/* Sorted kern records. */
   public:
-  DEFINE_SIZE_ARRAY (28, pairs);
+  DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 16, pairs);
 };
 
-struct KerxSubTableFormat1
+
+template <bool extended>
+struct Format1Entry;
+
+template <>
+struct Format1Entry<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. */
+  };
+
   struct EntryData
   {
     HBUINT16	kernActionIndex;/* Index into the kerning value array. If
@@ -142,44 +181,78 @@
     DEFINE_SIZE_STATIC (2);
   };
 
+  static inline bool performAction (const Entry<EntryData> *entry)
+  { return entry->data.kernActionIndex != 0xFFFF; }
+
+  static inline unsigned int kernActionIndex (const Entry<EntryData> *entry)
+  { return entry->data.kernActionIndex; }
+};
+template <>
+struct Format1Entry<false>
+{
+  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. */
+    Offset		= 0x3FFF,	/* Byte offset from beginning of subtable to the
+					 * value table for the glyphs on the kerning stack. */
+
+    Reset		= 0x0000,	/* Not supported? */
+  };
+
+  typedef void EntryData;
+
+  static inline bool performAction (const Entry<EntryData> *entry)
+  { return entry->flags & Offset; }
+
+  static inline unsigned int kernActionIndex (const Entry<EntryData> *entry)
+  { return entry->flags & Offset; }
+};
+
+template <typename KernSubTableHeader>
+struct KerxSubTableFormat1
+{
+  typedef typename KernSubTableHeader::Types Types;
+  typedef typename Types::HBUINT HBUINT;
+
+  typedef Format1Entry<Types::extended> Format1EntryT;
+  typedef typename Format1EntryT::EntryData EntryData;
+
   struct driver_context_t
   {
     static const bool in_place = true;
-    enum Flags
+    enum
     {
-      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. */
+      DontAdvance	= Format1EntryT::DontAdvance,
     };
 
-    inline driver_context_t (const KerxSubTableFormat1 *table,
+    inline driver_context_t (const KerxSubTableFormat1 *table_,
 			     hb_aat_apply_context_t *c_) :
 	c (c_),
+	table (table_),
 	/* 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) {}
+	depth (0),
+	crossStream (table->header.coverage & table->header.CrossStream) {}
 
-    inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
+    inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
 			       const Entry<EntryData> *entry)
     {
-      return entry->data.kernActionIndex != 0xFFFF;
+      return Format1EntryT::performAction (entry);
     }
-    inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
+    inline bool transition (StateTableDriver<Types, EntryData> *driver,
 			    const Entry<EntryData> *entry)
     {
       hb_buffer_t *buffer = driver->buffer;
       unsigned int flags = entry->flags;
 
-      if (flags & Reset)
-      {
+      if (flags & Format1EntryT::Reset)
 	depth = 0;
-      }
 
-      if (flags & Push)
+      if (flags & Format1EntryT::Push)
       {
 	if (likely (depth < ARRAY_LENGTH (stack)))
 	  stack[depth++] = buffer->idx;
@@ -187,10 +260,14 @@
 	  depth = 0; /* Probably not what CoreText does, but better? */
       }
 
-      if (entry->data.kernActionIndex != 0xFFFF)
+      if (Format1EntryT::performAction (entry) && depth)
       {
-	const FWORD *actions = &kernAction[entry->data.kernActionIndex];
-	if (!c->sanitizer.check_array (actions, depth))
+	unsigned int tuple_count = MAX (1u, table->header.tuple_count ());
+
+	unsigned int kern_idx = Format1EntryT::kernActionIndex (entry);
+	kern_idx = Types::offsetToIndex (kern_idx, &table->machine, kernAction.arrayZ);
+	const FWORD *actions = &kernAction[kern_idx];
+	if (!c->sanitizer.check_array (actions, depth, tuple_count))
 	{
 	  depth = 0;
 	  return false;
@@ -197,31 +274,76 @@
 	}
 
 	hb_mask_t kern_mask = c->plan->kern_mask;
-	for (unsigned int i = 0; i < depth; i++)
+
+	/* From Apple 'kern' spec:
+	 * "Each pops one glyph from the kerning stack and applies the kerning value to it.
+	 * The end of the list is marked by an odd value... */
+	bool last = false;
+	while (!last && depth)
 	{
-	  /* 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)
+	  unsigned int idx = stack[--depth];
+	  int v = *actions;
+	  actions += tuple_count;
+	  if (idx >= buffer->len) continue;
+
+	  /* "The end of the list is marked by an odd value..." */
+	  last = v & 1;
+	  v &= ~1;
+
+	  hb_glyph_position_t &o = buffer->pos[idx];
+
+	  /* Testing shows that CoreText only applies kern (cross-stream or not)
+	   * if none has been applied by previous subtables.  That is, it does
+	   * NOT seem to accumulate as otherwise implied by specs. */
+
+	  /* The following flag is undocumented in the spec, but described
+	   * in the 'kern' table example. */
+	  if (v == -0x8000)
 	  {
-	    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+	    o.attach_type() = ATTACH_TYPE_NONE;
+	    o.attach_chain() = 0;
+	    o.x_offset = o.y_offset = 0;
+	  }
+	  else if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+	  {
+	    if (crossStream)
 	    {
-	      buffer->pos[idx].x_advance += c->font->em_scale_x (v);
-	      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+	      if (buffer->pos[idx].attach_type() && !buffer->pos[idx].y_offset)
+	      {
+		o.y_offset = c->font->em_scale_y (v);
+		buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+	      }
+	    }
+	    else if (buffer->info[idx].mask & kern_mask)
+	    {
+	      if (!buffer->pos[idx].x_offset)
+	      {
+		buffer->pos[idx].x_advance += c->font->em_scale_x (v);
 		buffer->pos[idx].x_offset += c->font->em_scale_x (v);
+	      }
 	    }
-	    else
+	  }
+	  else
+	  {
+	    if (crossStream)
 	    {
-	      buffer->pos[idx].y_advance += c->font->em_scale_y (v);
-	      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+	      /* CoreText doesn't do crossStream kerning in vertical.  We do. */
+	      if (buffer->pos[idx].attach_type() && !buffer->pos[idx].x_offset)
+	      {
+		o.x_offset = c->font->em_scale_x (v);
+		buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+	      }
+	    }
+	    else if (buffer->info[idx].mask & kern_mask)
+	    {
+	      if (!buffer->pos[idx].y_offset)
+	      {
+		buffer->pos[idx].y_advance += c->font->em_scale_y (v);
 		buffer->pos[idx].y_offset += c->font->em_scale_y (v);
+	      }
 	    }
 	  }
 	}
-	depth = 0;
       }
 
       return true;
@@ -229,9 +351,11 @@
 
     private:
     hb_aat_apply_context_t *c;
+    const KerxSubTableFormat1 *table;
     const UnsizedArrayOf<FWORD> &kernAction;
     unsigned int stack[8];
     unsigned int depth;
+    bool crossStream;
   };
 
   inline bool apply (hb_aat_apply_context_t *c) const
@@ -238,15 +362,13 @@
   {
     TRACE_APPLY (this);
 
-    if (!c->plan->requested_kerning)
+    if (!c->plan->requested_kerning &&
+	!(header.coverage & header.CrossStream))
       return false;
 
-    if (header.tupleCount)
-      return_trace (false); /* TODO kerxTupleKern */
-
     driver_context_t dc (this, c);
 
-    StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->font->face);
+    StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->font->face);
     driver.drive (&dc);
 
     return_trace (true);
@@ -261,25 +383,29 @@
   }
 
   protected:
-  KerxSubTableHeader				header;
-  StateTable<MorxTypes, EntryData>		machine;
-  LOffsetTo<UnsizedArrayOf<FWORD>, false>	kernAction;
+  KernSubTableHeader				header;
+  StateTable<Types, EntryData>			machine;
+  OffsetTo<UnsizedArrayOf<FWORD>, HBUINT, false>kernAction;
   public:
-  DEFINE_SIZE_STATIC (32);
+  DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 5 * sizeof (HBUINT));
 };
 
+template <typename KernSubTableHeader>
 struct KerxSubTableFormat2
 {
+  typedef typename KernSubTableHeader::Types Types;
+  typedef typename Types::HBUINT HBUINT;
+
   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 ();
-    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 l = (this+leftClassTable).get_class (left, num_glyphs, 0);
+    unsigned int r = (this+rightClassTable).get_class (right, num_glyphs, 0);
     unsigned int offset = l + r;
     const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
     if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
-    return kerxTupleKern (*v, header.tupleCount, this, c);
+    return kerxTupleKern (*v, header.tuple_count (), this, c);
   }
 
   inline bool apply (hb_aat_apply_context_t *c) const
@@ -289,8 +415,11 @@
     if (!c->plan->requested_kerning)
       return false;
 
+    if (header.coverage & header.Backwards)
+      return false;
+
     accelerator_t accel (*this, c);
-    hb_kern_machine_t<accelerator_t> machine (accel);
+    hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
     machine.kern (c->font, c->buffer, c->plan->kern_mask);
 
     return_trace (true);
@@ -318,24 +447,33 @@
 			  c->check_range (this, array)));
   }
 
+  /* Note:
+   * OT kern table specifies ClassTable as having 16-bit entries, whereas
+   * AAT kern table specifies them as having 8bit entries.
+   * I've not seen any fonts with this format in kern table.
+   * We follow AAT. */
+
   protected:
-  KerxSubTableHeader	header;
-  HBUINT32		rowWidth;	/* The width, in bytes, of a row in the table. */
-  LOffsetTo<Lookup<HBUINT16>, false>
+  KernSubTableHeader	header;
+  HBUINT		rowWidth;	/* The width, in bytes, of a row in the table. */
+  OffsetTo<typename Types::ClassType, HBUINT, false>
 			leftClassTable;	/* Offset from beginning of this subtable to
 					 * left-hand class table. */
-  LOffsetTo<Lookup<HBUINT16>, false>
+  OffsetTo<typename Types::ClassType, HBUINT, false>
 			rightClassTable;/* Offset from beginning of this subtable to
 					 * right-hand class table. */
-  LOffsetTo<UnsizedArrayOf<FWORD>, false>
+  OffsetTo<UnsizedArrayOf<FWORD>, HBUINT, false>
 			 array;		/* Offset from beginning of this subtable to
 					 * the start of the kerning array. */
   public:
-  DEFINE_SIZE_STATIC (28);
+  DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 4 * sizeof (HBUINT));
 };
 
+template <typename KernSubTableHeader>
 struct KerxSubTableFormat4
 {
+  typedef ExtendedTypes Types;
+
   struct EntryData
   {
     HBUINT16	ankrActionIndex;/* Either 0xFFFF (for no action) or the index of
@@ -372,16 +510,15 @@
 	mark_set (false),
 	mark (0) {}
 
-    inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
+    inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
 			       const Entry<EntryData> *entry)
     {
       return entry->data.ankrActionIndex != 0xFFFF;
     }
-    inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
+    inline bool transition (StateTableDriver<Types, 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)
       {
@@ -457,7 +594,7 @@
 	buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
       }
 
-      if (flags & Mark)
+      if (entry->flags & Mark)
       {
 	mark_set = true;
 	mark = buffer->idx;
@@ -480,7 +617,7 @@
 
     driver_context_t dc (this, c);
 
-    StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->font->face);
+    StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->font->face);
     driver.drive (&dc);
 
     return_trace (true);
@@ -495,14 +632,14 @@
   }
 
   protected:
-  KerxSubTableHeader	header;
-  StateTable<MorxTypes, EntryData>
-			machine;
-  HBUINT32		flags;
+  KernSubTableHeader		header;
+  StateTable<Types, EntryData>	machine;
+  HBUINT32			flags;
   public:
-  DEFINE_SIZE_STATIC (32);
+  DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 20);
 };
 
+template <typename KernSubTableHeader>
 struct KerxSubTableFormat6
 {
   enum Flags
@@ -518,7 +655,7 @@
     unsigned int num_glyphs = c->sanitizer.get_num_glyphs ();
     if (is_long ())
     {
-      const U::Long &t = u.l;
+      const typename 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;
@@ -526,17 +663,17 @@
       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 kerxTupleKern (*v, header.tupleCount, &(this+vector), c);
+      return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c);
     }
     else
     {
-      const U::Short &t = u.s;
+      const typename 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 kerxTupleKern (*v, header.tupleCount, &(this+vector), c);
+      return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c);
     }
   }
 
@@ -547,8 +684,11 @@
     if (!c->plan->requested_kerning)
       return false;
 
+    if (header.coverage & header.Backwards)
+      return false;
+
     accelerator_t accel (*this, c);
-    hb_kern_machine_t<accelerator_t> machine (accel);
+    hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
     machine.kern (c->font, c->buffer, c->plan->kern_mask);
 
     return_trace (true);
@@ -568,7 +708,7 @@
 			     u.s.columnIndexTable.sanitize (c, this) &&
 			     c->check_range (this, u.s.array)
 			   )) &&
-			  (header.tupleCount == 0 ||
+			  (header.tuple_count () == 0 ||
 			   c->check_range (this, vector))));
   }
 
@@ -586,7 +726,7 @@
   };
 
   protected:
-  KerxSubTableHeader		header;
+  KernSubTableHeader		header;
   HBUINT32			flags;
   HBUINT16			rowCount;
   HBUINT16			columnCount;
@@ -607,30 +747,52 @@
   } u;
   LOffsetTo<UnsizedArrayOf<FWORD>, false>	vector;
   public:
-  DEFINE_SIZE_STATIC (36);
+  DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 24);
 };
 
-struct KerxTable
+
+struct KerxSubTableHeader
 {
-  friend struct kerx;
+  typedef ExtendedTypes Types;
 
-  inline unsigned int get_size (void) const { return u.header.length; }
-  inline unsigned int get_type (void) const { return u.header.coverage & SubtableType; }
+  inline unsigned int tuple_count (void) const { return tupleCount; }
+  inline bool is_horizontal (void) const { return !(coverage & Vertical); }
 
   enum Coverage
   {
-    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. */
+    Vertical	= 0x80000000u,	/* Set if table has vertical kerning values. */
+    CrossStream	= 0x40000000u,	/* Set if table has cross-stream kerning values. */
+    Variation	= 0x20000000u,	/* Set if table has variation kerning values. */
+    Backwards	= 0x10000000u,	/* 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	= 0x0FFFFF00u,	/* Reserved, set to zero. */
+    SubtableType= 0x000000FFu,	/* Subtable type. */
   };
 
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  public:
+  HBUINT32	length;
+  HBUINT32	coverage;
+  HBUINT32	tupleCount;
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct KerxSubTable
+{
+  friend struct kerx;
+
+  inline unsigned int get_size (void) const { return u.header.length; }
+  inline unsigned int get_type (void) const { return u.header.coverage & u.header.SubtableType; }
+
   template <typename context_t>
   inline typename context_t::return_t dispatch (context_t *c) const
   {
@@ -637,12 +799,12 @@
     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 ());
+    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 ());
     }
   }
 
@@ -656,16 +818,16 @@
     return_trace (dispatch (c));
   }
 
-protected:
+  public:
   union {
-  KerxSubTableHeader	header;
-  KerxSubTableFormat0	format0;
-  KerxSubTableFormat1	format1;
-  KerxSubTableFormat2	format2;
-  KerxSubTableFormat4	format4;
-  KerxSubTableFormat6	format6;
+  KerxSubTableHeader				header;
+  KerxSubTableFormat0<KerxSubTableHeader>	format0;
+  KerxSubTableFormat1<KerxSubTableHeader>	format1;
+  KerxSubTableFormat2<KerxSubTableHeader>	format2;
+  KerxSubTableFormat4<KerxSubTableHeader>	format4;
+  KerxSubTableFormat6<KerxSubTableHeader>	format6;
   } u;
-public:
+  public:
   DEFINE_SIZE_MIN (12);
 };
 
@@ -674,74 +836,143 @@
  * The 'kerx' Table
  */
 
-struct kerx
+template <typename T>
+struct KerxTable
 {
-  static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
+  /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
+  inline const T* thiz (void) const { return static_cast<const T *> (this); }
 
-  inline bool has_data (void) const { return version != 0; }
+  inline bool has_cross_stream (void) const
+  {
+    typedef typename T::SubTable SubTable;
 
-  inline void apply (hb_aat_apply_context_t *c) const
+    const SubTable *st = &thiz()->firstSubTable;
+    unsigned int count = thiz()->tableCount;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (st->u.header.coverage & st->u.header.CrossStream)
+        return true;
+      st = &StructAfter<SubTable> (*st);
+    }
+    return false;
+  }
+
+  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
+    typedef typename T::SubTable SubTable;
+
+    int v = 0;
+    const SubTable *st = &thiz()->firstSubTable;
+    unsigned int count = thiz()->tableCount;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if ((st->u.header.coverage & (st->u.header.Variation | st->u.header.CrossStream)) ||
+	  !st->u.header.is_horizontal ())
+        continue;
+      v += st->get_kerning (left, right);
+      st = &StructAfter<SubTable> (*st);
+    }
+    return v;
+  }
+
+  inline bool apply (AAT::hb_aat_apply_context_t *c) const
+  {
+    typedef typename T::SubTable SubTable;
+
+    bool ret = false;
+    bool seenCrossStream = false;
     c->set_lookup_index (0);
-    const KerxTable *table = &firstTable;
-    unsigned int count = tableCount;
+    const SubTable *st = &thiz()->firstSubTable;
+    unsigned int count = thiz()->tableCount;
     for (unsigned int i = 0; i < count; i++)
     {
       bool reverse;
 
-      if (table->u.header.coverage & (KerxTable::CrossStream))
-	goto skip; /* We do NOT handle cross-stream. */
+      if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation))
+        goto skip;
 
-      if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
-	  bool (table->u.header.coverage & KerxTable::Vertical))
+      if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ())
 	goto skip;
 
-      reverse = bool (table->u.header.coverage & KerxTable::Backwards) !=
+      reverse = bool (st->u.header.coverage & st->u.header.Backwards) !=
 		HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
 
-      if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
+      if (!c->buffer->message (c->font, "start %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index))
 	goto skip;
 
+      if (!seenCrossStream &&
+	  (st->u.header.coverage & st->u.header.CrossStream))
+      {
+        /* Attach all glyphs into a chain. */
+        seenCrossStream = true;
+	hb_glyph_position_t *pos = c->buffer->pos;
+	unsigned int count = c->buffer->len;
+	for (unsigned int i = 0; i < count; i++)
+	{
+	  pos[i].attach_type() = ATTACH_TYPE_CURSIVE;
+	  pos[i].attach_chain() = HB_DIRECTION_IS_FORWARD (c->buffer->props.direction) ? -1 : +1;
+	  /* We intentionally don't set HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT,
+	   * since there needs to be a non-zero attachment for post-positioning to
+	   * be needed. */
+	}
+      }
+
       if (reverse)
 	c->buffer->reverse ();
 
-      c->sanitizer.set_object (*table);
+      c->sanitizer.set_object (*st);
 
-      /* 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);
+      ret |= st->dispatch (c);
 
       if (reverse)
 	c->buffer->reverse ();
 
-      (void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index);
+      (void) c->buffer->message (c->font, "end %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index);
 
     skip:
-      table = &StructAfter<KerxTable> (*table);
+      st = &StructAfter<SubTable> (*st);
+      c->set_lookup_index (c->lookup_index + 1);
     }
+
+    return ret;
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!version.sanitize (c) || version < 2 ||
-	!tableCount.sanitize (c))
+    if (unlikely (!thiz()->version.sanitize (c) ||
+		  thiz()->version < T::minVersion ||
+		  !thiz()->tableCount.sanitize (c)))
       return_trace (false);
 
-    const KerxTable *table = &firstTable;
-    unsigned int count = tableCount;
+    typedef typename T::SubTable SubTable;
+
+    const SubTable *st = &thiz()->firstSubTable;
+    unsigned int count = thiz()->tableCount;
     for (unsigned int i = 0; i < count; i++)
     {
-      if (!table->sanitize (c))
+      if (unlikely (!st->sanitize (c)))
 	return_trace (false);
-      table = &StructAfter<KerxTable> (*table);
+      st = &StructAfter<SubTable> (*st);
     }
 
     return_trace (true);
   }
+};
 
+struct kerx : KerxTable<kerx>
+{
+  friend struct KerxTable<kerx>;
+
+  static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
+  static const uint16_t minVersion = 2;
+
+  typedef KerxSubTableHeader SubTableHeader;
+  typedef SubTableHeader::Types Types;
+  typedef KerxSubTable SubTable;
+
+  inline bool has_data (void) const { return version; }
+
   protected:
   HBUINT16	version;	/* The version number of the extended kerning table
 				 * (currently 2, 3, or 4). */
@@ -748,7 +979,7 @@
   HBUINT16	unused;		/* Set to 0. */
   HBUINT32	tableCount;	/* The number of subtables included in the extended kerning
 				 * table. */
-  KerxTable	firstTable;	/* Subtables. */
+  SubTable	firstSubTable;	/* Subtables. */
 /*subtableGlyphCoverageArray*/	/* Only if version >= 3. We don't use. */
 
   public:
@@ -755,6 +986,7 @@
   DEFINE_SIZE_MIN (8);
 };
 
+
 } /* namespace AAT */
 
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -0,0 +1,93 @@
+/*
+ * 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_AAT_LAYOUT_LCAR_TABLE_HH
+#define HB_AAT_LAYOUT_LCAR_TABLE_HH
+
+#include "hb-open-type.hh"
+#include "hb-aat-layout-common.hh"
+
+/*
+ * lcar -- Ligature caret
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html
+ */
+#define HB_AAT_TAG_lcar HB_TAG('l','c','a','r')
+
+
+namespace AAT {
+
+typedef ArrayOf<HBINT16> LigCaretClassEntry;
+
+struct lcar
+{
+  static const hb_tag_t tableTag = HB_AAT_TAG_lcar;
+
+  inline unsigned int get_lig_carets (hb_font_t      *font,
+				      hb_direction_t  direction,
+				      hb_codepoint_t  glyph,
+				      unsigned int    start_offset,
+				      unsigned int   *caret_count /* IN/OUT */,
+				      hb_position_t  *caret_array /* OUT */) const
+  {
+    const OffsetTo<LigCaretClassEntry>* entry_offset = lookup.get_value (glyph,
+									 font->face->get_num_glyphs ());
+    const LigCaretClassEntry& array = entry_offset ? this+*entry_offset : Null (LigCaretClassEntry);
+    if (caret_count && *caret_count)
+    {
+      const HBINT16 *arr = array.sub_array (start_offset, caret_count);
+      unsigned int count = *caret_count;
+      for (unsigned int i = 0; i < count; ++i)
+	switch (format)
+	{
+	case 0: caret_array[i] = font->em_scale_dir (arr[i], direction); break;
+	case 1:
+	  hb_position_t x, y;
+	  font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y);
+	  caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
+	  break;
+	}
+    }
+    return array.len;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  version.major == 1 &&
+			  lookup.sanitize (c, this)));
+  }
+
+  protected:
+  FixedVersion<>version;	/* Version number of the ligature caret table */
+  HBUINT16	format;		/* Format of the ligature caret table. */
+  Lookup<OffsetTo<LigCaretClassEntry> >
+		lookup;		/* data Lookup table associating glyphs */
+
+  public:
+  DEFINE_SIZE_MIN (8);
+};
+
+} /* namespace AAT */
+
+#endif /* HB_AAT_LAYOUT_LCAR_TABLE_HH */

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -375,7 +375,7 @@
     Reserved		= 0x1FFF,	/* These bits are reserved and should be set to 0. */
   };
 
-  typedef struct
+  struct EntryData
   {
     HBUINT16	ligActionIndex;	/* Index to the first ligActionTable entry
 				 * for processing this group, if indicated
@@ -382,14 +382,12 @@
 				 * by the flags. */
     public:
     DEFINE_SIZE_STATIC (2);
-  } EntryData;
+  };
 
-  template <typename Flags>
-  static inline bool performAction (Flags flags)
-  { return flags & PerformAction; }
+  static inline bool performAction (const Entry<EntryData> *entry)
+  { return entry->flags & PerformAction; }
 
-  template <typename Entry, typename Flags>
-  static inline unsigned int ligActionIndex (Entry &entry, Flags flags)
+  static inline unsigned int ligActionIndex (const Entry<EntryData> *entry)
   { return entry->data.ligActionIndex; }
 };
 template <>
@@ -408,13 +406,11 @@
 
   typedef void EntryData;
 
-  template <typename Flags>
-  static inline bool performAction (Flags flags)
-  { return flags & Offset; }
+  static inline bool performAction (const Entry<EntryData> *entry)
+  { return entry->flags & Offset; }
 
-  template <typename Entry, typename Flags>
-  static inline unsigned int ligActionIndex (Entry &entry, Flags flags)
-  { return flags & 0x3FFF; }
+  static inline unsigned int ligActionIndex (const Entry<EntryData> *entry)
+  { return entry->flags & Offset; }
 };
 
 
@@ -428,11 +424,11 @@
 
   struct driver_context_t
   {
+    static const bool in_place = false;
     enum
     {
       DontAdvance	= LigatureEntryT::DontAdvance,
     };
-    static const bool in_place = false;
     enum LigActionFlags
     {
       LigActionLast	= 0x80000000,	/* This is the last action in the list. This also
@@ -458,16 +454,15 @@
     inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
 			       const Entry<EntryData> *entry)
     {
-      return LigatureEntryT::performAction (entry->flags);
+      return LigatureEntryT::performAction (entry);
     }
     inline bool transition (StateTableDriver<Types, EntryData> *driver,
 			    const Entry<EntryData> *entry)
     {
       hb_buffer_t *buffer = driver->buffer;
-      unsigned int flags = entry->flags;
 
-      DEBUG_MSG (APPLY, nullptr, "Ligature transition at %d", buffer->idx);
-      if (flags & LigatureEntryT::SetComponent)
+      DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx);
+      if (entry->flags & LigatureEntryT::SetComponent)
       {
         if (unlikely (match_length >= ARRAY_LENGTH (match_positions)))
 	  return false;
@@ -477,16 +472,13 @@
 	  match_length--;
 
 	match_positions[match_length++] = buffer->out_len;
-	DEBUG_MSG (APPLY, nullptr, "Set component at %d", buffer->out_len);
+	DEBUG_MSG (APPLY, nullptr, "Set component at %u", buffer->out_len);
       }
 
-      if (LigatureEntryT::performAction (flags))
+      if (LigatureEntryT::performAction (entry))
       {
-	DEBUG_MSG (APPLY, nullptr, "Perform action with %d", match_length);
+	DEBUG_MSG (APPLY, nullptr, "Perform action with %u", match_length);
 	unsigned int end = buffer->out_len;
-	unsigned int action_idx = LigatureEntryT::ligActionIndex (entry, flags);
-	unsigned int action;
-	unsigned int ligature_idx = 0;
 
 	if (unlikely (!match_length))
 	  return true;
@@ -495,8 +487,13 @@
 	  return false; // TODO Work on previous instead?
 
 	unsigned int cursor = match_length;
+
+	unsigned int action_idx = LigatureEntryT::ligActionIndex (entry);
 	action_idx = Types::offsetToIndex (action_idx, table, ligAction.arrayZ);
 	const HBUINT32 *actionData = &ligAction[action_idx];
+
+	unsigned int ligature_idx = 0;
+	unsigned int action;
         do
 	{
 	  if (unlikely (!cursor))
@@ -507,7 +504,7 @@
 	    break;
 	  }
 
-	  DEBUG_MSG (APPLY, nullptr, "Moving to stack position %d", cursor - 1);
+	  DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1);
 	  buffer->move_to (match_positions[--cursor]);
 
 	  if (unlikely (!actionData->sanitize (&c->sanitizer))) return false;
@@ -523,7 +520,7 @@
 	  if (unlikely (!componentData.sanitize (&c->sanitizer))) return false;
 	  ligature_idx += componentData;
 
-	  DEBUG_MSG (APPLY, nullptr, "Action store %d last %d",
+	  DEBUG_MSG (APPLY, nullptr, "Action store %u last %u",
 		     bool (action & LigActionStore),
 		     bool (action & LigActionLast));
 	  if (action & (LigActionStore | LigActionLast))
@@ -533,7 +530,7 @@
 	    if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false;
 	    hb_codepoint_t lig = ligatureData;
 
-	    DEBUG_MSG (APPLY, nullptr, "Produced ligature %d", lig);
+	    DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig);
 	    buffer->replace_glyph (lig);
 
 	    unsigned int lig_end = match_positions[match_length - 1] + 1;
@@ -1109,21 +1106,6 @@
     }
   }
 
-  inline static void remove_deleted_glyphs (hb_buffer_t *buffer)
-  {
-    if (unlikely (!buffer->successful)) return;
-
-    buffer->clear_output ();
-    for (buffer->idx = 0; buffer->idx < buffer->len && buffer->successful;)
-    {
-      if (unlikely (buffer->cur().codepoint == DELETED_GLYPH))
-        buffer->skip_glyph ();
-      else
-        buffer->next_glyph ();
-    }
-    buffer->swap_buffers ();
-  }
-
   inline void apply (hb_aat_apply_context_t *c) const
   {
     if (unlikely (!c->buffer->successful)) return;
@@ -1136,7 +1118,6 @@
       if (unlikely (!c->buffer->successful)) return;
       chain = &StructAfter<Chain<Types> > (*chain);
     }
-    remove_deleted_glyphs (c->buffer);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -1169,11 +1150,11 @@
   DEFINE_SIZE_MIN (8);
 };
 
-struct morx : mortmorx<MorxTypes>
+struct morx : mortmorx<ExtendedTypes>
 {
   static const hb_tag_t tableTag	= HB_AAT_TAG_morx;
 };
-struct mort : mortmorx<MortTypes>
+struct mort : mortmorx<ObsoleteTypes>
 {
   static const hb_tag_t tableTag	= HB_AAT_TAG_mort;
 };

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -147,9 +147,9 @@
   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));
+    return_trace (likely (c->check_struct (this) &&
+			  sizeTable.sanitize (c, base, nSizes) &&
+			  trackTable.sanitize (c, nTracks, base, nSizes)));
   }
 
   protected:
@@ -169,17 +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 has_data (void) const { return version.to_int (); }
 
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-
-    return_trace (unlikely (c->check_struct (this) &&
-			    horizData.sanitize (c, this, this) &&
-			    vertData.sanitize (c, this, this)));
-  }
-
   inline bool apply (hb_aat_apply_context_t *c) const
   {
     TRACE_APPLY (this);
@@ -221,15 +212,27 @@
     return_trace (true);
   }
 
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+
+    return_trace (likely (c->check_struct (this) &&
+			  version.major == 1 &&
+			  horizData.sanitize (c, this, this) &&
+			  vertData.sanitize (c, this, this)));
+  }
+
   protected:
-  FixedVersion<>	version;	/* Version of the tracking table
+  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. */
+  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_STATIC (12);

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -31,6 +31,7 @@
 #include "hb-aat-layout-ankr-table.hh"
 #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-aat-layout-feat-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-aat-layout-kerx-table.hh"
 #include "hb-aat-layout-morx-table.hh"
 #include "hb-aat-layout-trak-table.hh"
@@ -134,7 +135,7 @@
  * hb_aat_apply_context_t
  */
 
-AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_,
+AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
 						     hb_font_t *font_,
 						     hb_buffer_t *buffer_,
 						     hb_blob_t *blob) :
@@ -172,81 +173,12 @@
  * mort/morx/kerx/trak
  */
 
-static inline const AAT::mort&
-_get_mort (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::mort);
-  }
-  const AAT::mort& mort = *(hb_ot_face_data (face)->mort);
-  if (blob)
-    *blob = hb_ot_face_data (face)->mort.get_blob ();
-  return mort;
-}
-static inline const AAT::morx&
-_get_morx (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::morx);
-  }
-  const AAT::morx& morx = *(hb_ot_face_data (face)->morx);
-  if (blob)
-    *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);
-  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);
-  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);
-}
-static inline const AAT::ltag&
-_get_ltag (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::ltag);
-  return *(hb_ot_face_data (face)->ltag);
-}
 
-
 void
 hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
 			   hb_aat_map_t *map)
 {
-  const AAT::morx& morx = _get_morx (mapper->face, nullptr);
+  const AAT::morx& morx = *mapper->face->table.morx;
   if (morx.has_data ())
   {
     morx.compile_flags (mapper, map);
@@ -253,7 +185,7 @@
     return;
   }
 
-  const AAT::mort& mort = _get_mort (mapper->face, nullptr);
+  const AAT::mort& mort = *mapper->face->table.mort;
   if (mort.has_data ())
   {
     mort.compile_flags (mapper, map);
@@ -262,80 +194,106 @@
 }
 
 
-hb_bool_t
+bool
 hb_aat_layout_has_substitution (hb_face_t *face)
 {
-  return _get_morx (face).has_data () ||
-	 _get_mort (face).has_data ();
+  return face->table.morx->has_data () ||
+	 face->table.mort->has_data ();
 }
 
 void
-hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
+hb_aat_layout_substitute (const 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);
+  hb_blob_t *morx_blob = font->face->table.morx.get_blob ();
+  const AAT::morx& morx = *morx_blob->as<AAT::morx> ();
   if (morx.has_data ())
   {
-    AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+    AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob);
     morx.apply (&c);
     return;
   }
 
-  const AAT::mort& mort = _get_mort (font->face, &blob);
+  hb_blob_t *mort_blob = font->face->table.mort.get_blob ();
+  const AAT::mort& mort = *mort_blob->as<AAT::mort> ();
   if (mort.has_data ())
   {
-    AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+    AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob);
     mort.apply (&c);
     return;
   }
 }
 
+void
+hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer)
+{
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  hb_glyph_position_t *pos = buffer->pos;
+  for (unsigned int i = 0; i < count; i++)
+    if (unlikely (info[i].codepoint == AAT::DELETED_GLYPH))
+      pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0;
+}
 
-hb_bool_t
+static bool
+is_deleted_glyph (const hb_glyph_info_t *info)
+{
+  return info->codepoint == AAT::DELETED_GLYPH;
+}
+
+void
+hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
+{
+  hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
+}
+
+
+
+bool
 hb_aat_layout_has_positioning (hb_face_t *face)
 {
-  return _get_kerx (face).has_data ();
+  return face->table.kerx->has_data ();
 }
 
 void
-hb_aat_layout_position (hb_ot_shape_plan_t *plan,
+hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
 			hb_font_t *font,
 			hb_buffer_t *buffer)
 {
-  hb_blob_t *blob;
-  const AAT::kerx& kerx = _get_kerx (font->face, &blob);
+  hb_blob_t *kerx_blob = font->face->table.kerx.get_blob ();
+  const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> ();
 
-  hb_blob_t *ankr_blob;
-  const AAT::ankr& ankr = _get_ankr (font->face, &ankr_blob);
+  hb_blob_t *ankr_blob = font->face->table.ankr.get_blob ();;
+  const AAT::ankr& ankr = *font->face->table.ankr;
 
-  AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+  AAT::hb_aat_apply_context_t c (plan, font, buffer, kerx_blob);
   c.set_ankr_table (&ankr, ankr_blob->data + ankr_blob->length);
   kerx.apply (&c);
 }
 
-hb_bool_t
+
+bool
 hb_aat_layout_has_tracking (hb_face_t *face)
 {
-  return _get_trak (face).has_data ();
+  return face->table.trak->has_data ();
 }
 
 void
-hb_aat_layout_track (hb_ot_shape_plan_t *plan,
+hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
 		     hb_font_t *font,
 		     hb_buffer_t *buffer)
 {
-  const AAT::trak& trak = _get_trak (font->face);
+  const AAT::trak& trak = *font->face->table.trak;
 
   AAT::hb_aat_apply_context_t c (plan, font, buffer);
   trak.apply (&c);
 }
 
+
 hb_language_t
 _hb_aat_language_get (hb_face_t *face,
 		      unsigned int i)
 {
-  return _get_ltag (face).get_language (i);
+  return face->table.ltag->get_language (i);
 }

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -56,27 +56,33 @@
 hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
 			   hb_aat_map_t *map);
 
-HB_INTERNAL hb_bool_t
+HB_INTERNAL bool
 hb_aat_layout_has_substitution (hb_face_t *face);
 
 HB_INTERNAL void
-hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
+hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
 			  hb_font_t *font,
 			  hb_buffer_t *buffer);
 
-HB_INTERNAL hb_bool_t
+HB_INTERNAL void
+hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer);
+
+HB_INTERNAL void
+hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer);
+
+HB_INTERNAL bool
 hb_aat_layout_has_positioning (hb_face_t *face);
 
 HB_INTERNAL void
-hb_aat_layout_position (hb_ot_shape_plan_t *plan,
+hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
 			hb_font_t *font,
 			hb_buffer_t *buffer);
 
-HB_INTERNAL hb_bool_t
+HB_INTERNAL bool
 hb_aat_layout_has_tracking (hb_face_t *face);
 
 HB_INTERNAL void
-hb_aat_layout_track (hb_ot_shape_plan_t *plan,
+hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
 		     hb_font_t *font,
 		     hb_buffer_t *buffer);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -51,9 +51,7 @@
 }
 
 void
-hb_aat_map_builder_t::compile (hb_aat_map_t  &m,
-			       const int    *coords HB_UNUSED,
-			       unsigned int  num_coords HB_UNUSED)
+hb_aat_map_builder_t::compile (hb_aat_map_t  &m)
 {
   /* Sort features and merge duplicates */
   if (features.len)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -60,9 +60,7 @@
 
   HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1);
 
-  HB_INTERNAL void compile (hb_aat_map_t  &m,
-			    const int    *coords,
-			    unsigned int  num_coords);
+  HB_INTERNAL void compile (hb_aat_map_t  &m);
 
   public:
   struct feature_info_t

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -100,7 +100,7 @@
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)	_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
 
 
-#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
+#elif !defined(HB_NO_MT) && defined(_WIN32)
 
 #include <windows.h>
 
@@ -257,10 +257,10 @@
 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; }
+inline int hb_atomic_int_impl_get (const 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; }
+inline void *hb_atomic_ptr_impl_get (void ** const P)	{ void *v = *P; _hb_memory_r_barrier (); return v; }
 #endif
 
 
@@ -267,14 +267,14 @@
 #define HB_ATOMIC_INT_INIT(V)          {V}
 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 void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
+  inline void set (int v_) { 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); }
 
-  mutable int v;
+  int v;
 };
 
 
@@ -285,7 +285,7 @@
   typedef typename hb_remove_pointer<P>::value T;
 
   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 void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, 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 ((void **) &v, (void *) old, (void *) new_); }
@@ -293,7 +293,7 @@
   inline T * operator -> (void) const { return get (); }
   template <typename C> inline operator C * (void) const { return get (); }
 
-  mutable T *v;
+  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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -53,18 +53,6 @@
  **/
 
 
-DEFINE_NULL_INSTANCE (hb_blob_t) =
-{
-  HB_OBJECT_HEADER_STATIC,
-
-  nullptr, /* data */
-  0, /* length */
-  HB_MEMORY_MODE_READONLY, /* mode */
-
-  nullptr, /* user_data */
-  nullptr  /* destroy */
-};
-
 /**
  * hb_blob_create: (skip)
  * @data: Pointer to blob data.
@@ -493,7 +481,7 @@
 # include <fcntl.h>
 #endif
 
-#if defined(_WIN32) || defined(__CYGWIN__)
+#ifdef _WIN32
 # include <windows.h>
 #else
 # ifndef O_BINARY
@@ -509,12 +497,12 @@
 {
   char *contents;
   unsigned long length;
-#if defined(_WIN32) || defined(__CYGWIN__)
+#ifdef _WIN32
   HANDLE mapping;
 #endif
 };
 
-#if (defined(HAVE_MMAP) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP)
+#if (defined(HAVE_MMAP) || defined(_WIN32)) && !defined(HB_NO_MMAP)
 static void
 _hb_mapped_file_destroy (void *file_)
 {
@@ -521,7 +509,7 @@
   hb_mapped_file_t *file = (hb_mapped_file_t *) file_;
 #ifdef HAVE_MMAP
   munmap (file->contents, file->length);
-#elif defined(_WIN32) || defined(__CYGWIN__)
+#elif defined(_WIN32)
   UnmapViewOfFile (file->contents);
   CloseHandle (file->mapping);
 #else
@@ -572,7 +560,7 @@
 fail_without_close:
   free (file);
 
-#elif (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP)
+#elif defined(_WIN32) && !defined(HB_NO_MMAP)
   hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t));
   if (unlikely (!file)) return hb_blob_get_empty ();
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -77,7 +77,30 @@
   void *user_data;
   hb_destroy_func_t destroy;
 };
-DECLARE_NULL_INSTANCE (hb_blob_t);
 
 
+/*
+ * hb_blob_ptr_t
+ */
+
+template <typename P>
+struct hb_blob_ptr_t
+{
+  typedef typename hb_remove_pointer<P>::value T;
+
+  inline hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {}
+  inline hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; }
+  inline const T * operator -> (void) const { return get (); }
+  inline const T & operator * (void) const { return *get (); }
+  template <typename C> inline operator const C * (void) const { return get (); }
+  inline operator const char * (void) const { return (const char *) get (); }
+  inline const T * get (void) const { return b->as<T> (); }
+  inline hb_blob_t * get_blob (void) const { return b.get_raw (); }
+  inline unsigned int get_length (void) const { return b.get ()->length; }
+  inline void destroy (void) { hb_blob_destroy (b.get ()); b = nullptr; }
+
+  hb_nonnull_ptr_t<hb_blob_t> b;
+};
+
+
 #endif /* HB_BLOB_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -26,8 +26,6 @@
  * Google Author(s): Behdad Esfahbod
  */
 
-#define HB_SHAPER coretext
-
 #include "hb.hh"
 #include "hb-shaper-impl.hh"
 
@@ -101,11 +99,6 @@
 }
 
 
-HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
-HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
-	fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5
-)
-
 static CTFontDescriptorRef
 get_last_resort_font_desc (void)
 {
@@ -312,8 +305,7 @@
 CGFontRef
 hb_coretext_face_get_cg_font (hb_face_t *face)
 {
-  if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
-  return (CGFontRef) HB_SHAPER_DATA_GET (face);
+  return (CGFontRef) (const void *) face->data.coretext;
 }
 
 
@@ -321,8 +313,9 @@
 _hb_coretext_shaper_font_data_create (hb_font_t *font)
 {
   hb_face_t *face = font->face;
-  if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
-  CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
+  const hb_coretext_face_data_t *face_data = face->data.coretext;
+  if (unlikely (!face_data)) return nullptr;
+  CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
 
   CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem));
 
@@ -341,6 +334,38 @@
   CFRelease ((CTFontRef) data);
 }
 
+static const hb_coretext_font_data_t *
+hb_coretext_font_data_sync (hb_font_t *font)
+{
+retry:
+  const hb_coretext_font_data_t *data = font->data.coretext;
+  if (unlikely (!data)) return nullptr;
+
+  if (fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) > .5)
+  {
+    /* XXX-MT-bug
+     * Note that evaluating condition above can be dangerous if another thread
+     * got here first and destructed data.  That's, as always, bad use pattern.
+     * If you modify the font (change font size), other threads must not be
+     * using it at the same time.  However, since this check is delayed to
+     * when one actually tries to shape something, this is a XXX race condition
+     * (and the only one we have that I know of) right now.  Ie. you modify the
+     * font size in one thread, then (supposedly safely) try to use it from two
+     * or more threads and BOOM!  I'm not sure how to fix this.  We want RCU.
+     */
+
+    /* Drop and recreate. */
+    /* If someone dropped it in the mean time, throw it away and don't touch it.
+     * Otherwise, destruct it. */
+    if (likely (font->data.coretext.cmpexch (const_cast<hb_coretext_font_data_t *> (data), nullptr)))
+      _hb_coretext_shaper_font_data_destroy (const_cast<hb_coretext_font_data_t *> (data));
+    else
+      goto retry;
+  }
+  return font->data.coretext;
+}
+
+
 /*
  * Since: 1.7.2
  */
@@ -359,7 +384,7 @@
   hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
 
   /* Let there be dragons here... */
-  HB_SHAPER_DATA (HB_SHAPER, font).set_relaxed ((hb_coretext_font_data_t *) CFRetain (ct_font));
+  font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font));
 
   return font;
 }
@@ -367,35 +392,12 @@
 CTFontRef
 hb_coretext_font_get_ct_font (hb_font_t *font)
 {
-  if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr;
-  return (CTFontRef) HB_SHAPER_DATA_GET (font);
+  const hb_coretext_font_data_t *data = hb_coretext_font_data_sync (font);
+  return data ? (CTFontRef) data : nullptr;
 }
 
 
-
 /*
- * shaper shape_plan data
- */
-
-struct hb_coretext_shape_plan_data_t {};
-
-hb_coretext_shape_plan_data_t *
-_hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
-					     const hb_feature_t *user_features HB_UNUSED,
-					     unsigned int        num_user_features HB_UNUSED,
-					     const int          *coords HB_UNUSED,
-					     unsigned int        num_coords HB_UNUSED)
-{
-  return (hb_coretext_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shape_plan_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
  * shaper
  */
 
@@ -450,8 +452,8 @@
                     unsigned int        num_features)
 {
   hb_face_t *face = font->face;
-  CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
-  CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font);
+  CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
+  CTFontRef ct_font = (CTFontRef) hb_coretext_font_data_sync (font);
 
   CGFloat ct_font_size = CTFontGetSize (ct_font);
   CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
@@ -1152,9 +1154,6 @@
  * AAT shaper
  */
 
-HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, face)
-HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font)
-
 /*
  * shaper face data
  */
@@ -1172,7 +1171,7 @@
     if (hb_blob_get_length (blob))
     {
       hb_blob_destroy (blob);
-      return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
+      return face->data.coretext ? (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
     }
     hb_blob_destroy (blob);
   }
@@ -1195,7 +1194,7 @@
 hb_coretext_aat_font_data_t *
 _hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
 {
-  return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
+  return font->data.coretext ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
 }
 
 void
@@ -1205,28 +1204,6 @@
 
 
 /*
- * shaper shape_plan data
- */
-
-struct hb_coretext_aat_shape_plan_data_t {};
-
-hb_coretext_aat_shape_plan_data_t *
-_hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
-					     const hb_feature_t *user_features HB_UNUSED,
-					     unsigned int        num_user_features HB_UNUSED,
-					     const int          *coords HB_UNUSED,
-					     unsigned int        num_coords HB_UNUSED)
-{
-  return (hb_coretext_aat_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shape_plan_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
  * shaper
  */
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -23,7 +23,6 @@
  */
 
 #include "hb.hh"
-#define HB_SHAPER directwrite
 #include "hb-shaper-impl.hh"
 
 #include <DWrite_1.h>
@@ -31,10 +30,6 @@
 #include "hb-directwrite.h"
 
 
-HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, face)
-HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, font)
-
-
 /*
  * hb-directwrite uses new/delete syntatically but as we let users
  * to override malloc/free, we will redefine new/delete so users
@@ -240,8 +235,6 @@
 hb_directwrite_font_data_t *
 _hb_directwrite_shaper_font_data_create (hb_font_t *font)
 {
-  if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return nullptr;
-
   hb_directwrite_font_data_t *data = new hb_directwrite_font_data_t;
   if (unlikely (!data))
     return nullptr;
@@ -256,27 +249,6 @@
 }
 
 
-/*
- * shaper shape_plan data
- */
-
-struct hb_directwrite_shape_plan_data_t {};
-
-hb_directwrite_shape_plan_data_t *
-_hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
-					       const hb_feature_t *user_features HB_UNUSED,
-					       unsigned int        num_user_features HB_UNUSED,
-					       const int          *coords HB_UNUSED,
-					       unsigned int        num_coords HB_UNUSED)
-{
-  return (hb_directwrite_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shape_plan_data_t *data HB_UNUSED)
-{
-}
-
 // Most of TextAnalysis is originally written by Bas Schouten for Mozilla project
 // but now is relicensed to MIT for HarfBuzz use
 class TextAnalysis
@@ -555,8 +527,8 @@
   float               lineWidth)
 {
   hb_face_t *face = font->face;
-  hb_directwrite_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
-  hb_directwrite_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+  const hb_directwrite_face_data_t *face_data = face->data.directwrite;
+  const hb_directwrite_font_data_t *font_data = font->data.directwrite;
   IDWriteFactory *dwriteFactory = face_data->dwriteFactory;
   IDWriteFontFace *fontFace = face_data->fontFace;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -264,6 +264,17 @@
 /* A const version, but does not detect erratically being called on pointers. */
 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
 
+
+static inline int
+hb_memcmp (const void *a, const void *b, unsigned int len)
+{
+  /* It's illegal to pass NULL to memcmp(), even if len is zero.
+   * So, wrap it.
+   * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
+  if (!len) return 0;
+  return memcmp (a, b, len);
+}
+
 static inline bool
 hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
 {
@@ -356,7 +367,12 @@
 }
 
 
-/* From https://github.com/noporpoise/sort_r */
+/* From https://github.com/noporpoise/sort_r
+ * With following modifications:
+ *
+ * 10 November 2018:
+ * https://github.com/noporpoise/sort_r/issues/7
+ */
 
 /* Isaac Turner 29 April 2014 Public Domain */
 
@@ -412,7 +428,7 @@
 
     /* Use median of first, middle and last items as pivot */
     char *x, *y, *xend, ch;
-    char *pl, *pr;
+    char *pl, *pm, *pr;
     char *last = b+w*(nel-1), *tmp;
     char *l[3];
     l[0] = b;
@@ -434,13 +450,15 @@
     pr = last;
 
     while(pl < pr) {
-      for(; pl < pr; pl += w) {
+      pm = pl+((pr-pl+1)>>1);
+      for(; pl < pm; pl += w) {
         if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
           pr -= w; /* pivot now at pl */
           break;
         }
       }
-      for(; pl < pr; pr -= w) {
+      pm = pl+((pr-pl)>>1);
+      for(; pm < pr; pr -= w) {
         if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
           pl += w; /* pivot now at pr */
           break;
@@ -517,8 +535,11 @@
   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 hb_bytes_t (const T& array) : arrayZ ((const char *) array.arrayZ), len (array.len * sizeof (array.arrayZ[0])) {}
 
+  inline operator const void * (void) const { return arrayZ; }
+  inline operator const char * (void) const { return arrayZ; }
+
   inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
 
   inline int cmp (const hb_bytes_t &a) const
@@ -525,8 +546,7 @@
   {
     if (len != a.len)
       return (int) a.len - (int) len;
-
-    return memcmp (a.arrayZ, arrayZ, len);
+    return hb_memcmp (a.arrayZ, arrayZ, len);
   }
   static inline int cmp (const void *pa, const void *pb)
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -87,16 +87,10 @@
   nullptr, /* destroy */
 
   0,    /* index */
-  1000, /* upem */
-  0,    /* num_glyphs */
+  HB_ATOMIC_INT_INIT (1000), /* upem */
+  HB_ATOMIC_INT_INIT (0),    /* num_glyphs */
 
-  {
-#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID),
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-  },
-
-  HB_ATOMIC_PTR_INIT (nullptr), /* shape_plans */
+  /* Zero for the rest is fine. */
 };
 
 
@@ -129,9 +123,11 @@
   face->user_data = user_data;
   face->destroy = destroy;
 
-  face->upem = 0;
-  face->num_glyphs = (unsigned int) -1;
+  face->num_glyphs.set_relaxed (-1);
 
+  face->data.init0 (face);
+  face->table.init0 (face);
+
   return face;
 }
 
@@ -271,9 +267,8 @@
     node = next;
   }
 
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
+  face->data.fini ();
+  face->table.fini ();
 
   if (face->destroy)
     face->destroy (face->user_data);
@@ -442,7 +437,7 @@
   if (hb_object_is_immutable (face))
     return;
 
-  face->upem = upem;
+  face->upem.set_relaxed (upem);
 }
 
 /**
@@ -477,7 +472,7 @@
   if (hb_object_is_immutable (face))
     return;
 
-  face->num_glyphs = glyph_count;
+  face->num_glyphs.set_relaxed (glyph_count);
 }
 
 /**
@@ -547,8 +542,7 @@
 hb_face_collect_unicodes (hb_face_t *face,
 			  hb_set_t  *out)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
-  hb_ot_face_data (face)->cmap->collect_unicodes (out);
+  face->table.cmap->collect_unicodes (out);
 }
 
 /**
@@ -564,8 +558,7 @@
 hb_face_collect_variation_selectors (hb_face_t *face,
 				     hb_set_t  *out)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
-  hb_ot_face_data (face)->cmap->collect_variation_selectors (out);
+  face->table.cmap->collect_variation_selectors (out);
 }
 
 /**
@@ -582,8 +575,7 @@
 				    hb_codepoint_t variation_selector,
 				    hb_set_t  *out)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
-  hb_ot_face_data (face)->cmap->collect_variation_unicodes (variation_selector, out);
+  face->table.cmap->collect_variation_unicodes (variation_selector, out);
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -33,6 +33,7 @@
 
 #include "hb-shaper.hh"
 #include "hb-shape-plan.hh"
+#include "hb-ot-face.hh"
 
 
 /*
@@ -39,6 +40,10 @@
  * hb_face_t
  */
 
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
 struct hb_face_t
 {
   hb_object_header_t header;
@@ -48,10 +53,11 @@
   hb_destroy_func_t          destroy;
 
   unsigned int index;			/* Face index in a collection, zero-based. */
-  mutable unsigned int upem;		/* Units-per-EM. */
-  mutable unsigned int num_glyphs;	/* Number of glyphs. */
+  mutable hb_atomic_int_t upem;		/* Units-per-EM. */
+  mutable hb_atomic_int_t num_glyphs;	/* Number of glyphs. */
 
-  struct hb_shaper_data_t shaper_data;	/* Various shaper data. */
+  hb_shaper_object_dataset_t<hb_face_t> data;/* Various shaper data. */
+  hb_ot_face_t table;			/* All the face's tables. */
 
   /* Cache */
   struct plan_node_t
@@ -77,29 +83,27 @@
 
   inline HB_PURE_FUNC unsigned int get_upem (void) const
   {
-    if (unlikely (!upem))
-      load_upem ();
-    return upem;
+    unsigned int ret = upem.get_relaxed ();
+    if (unlikely (!ret))
+    {
+      return load_upem ();
+    }
+    return ret;
   }
 
   inline unsigned int get_num_glyphs (void) const
   {
-    if (unlikely (num_glyphs == (unsigned int) -1))
-      load_num_glyphs ();
-    return num_glyphs;
+    unsigned int ret = num_glyphs.get_relaxed ();
+    if (unlikely (ret == (unsigned int) -1))
+      return load_num_glyphs ();
+    return ret;
   }
 
   private:
-  HB_INTERNAL void load_upem (void) const;
-  HB_INTERNAL void load_num_glyphs (void) const;
+  HB_INTERNAL unsigned int load_upem (void) const;
+  HB_INTERNAL unsigned int load_num_glyphs (void) const;
 };
 DECLARE_NULL_INSTANCE (hb_face_t);
 
-#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
 
-
 #endif /* HB_FACE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -24,14 +24,9 @@
  * Google Author(s): Behdad Esfahbod
  */
 
-#define HB_SHAPER fallback
 #include "hb-shaper-impl.hh"
 
 
-HB_SHAPER_DATA_ENSURE_DEFINE(fallback, face)
-HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font)
-
-
 /*
  * shaper face data
  */
@@ -69,28 +64,6 @@
 
 
 /*
- * shaper shape_plan data
- */
-
-struct hb_fallback_shape_plan_data_t {};
-
-hb_fallback_shape_plan_data_t *
-_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
-					    const hb_feature_t *user_features HB_UNUSED,
-					    unsigned int        num_user_features HB_UNUSED,
-					    const int          *coords HB_UNUSED,
-					    unsigned int        num_coords HB_UNUSED)
-{
-  return (hb_fallback_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shape_plan_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
  * shaper
  */
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1306,15 +1306,9 @@
   0, /* num_coords */
   nullptr, /* coords */
 
-  const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t), /* klass */
-  nullptr, /* user_data */
-  nullptr, /* destroy */
+  const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
 
-  {
-#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID),
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-  }
+  /* Zero for the rest is fine. */
 };
 
 
@@ -1332,7 +1326,7 @@
   font->parent = hb_font_get_empty ();
   font->face = hb_face_reference (face);
   font->klass = hb_font_funcs_get_empty ();
-
+  font->data.init0 (font);
   font->x_scale = font->y_scale = hb_face_get_upem (face);
 
   return font;
@@ -1448,9 +1442,7 @@
 {
   if (!hb_object_destroy (font)) return;
 
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
+  font->data.fini ();
 
   if (font->destroy)
     font->destroy (font->user_data);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -96,6 +96,10 @@
  * hb_font_t
  */
 
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, font);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
 struct hb_font_t
 {
   hb_object_header_t header;
@@ -119,7 +123,7 @@
   void              *user_data;
   hb_destroy_func_t  destroy;
 
-  struct hb_shaper_data_t shaper_data;
+  hb_shaper_object_dataset_t<hb_font_t> data; /* Various shaper data. */
 
 
   /* Convert from font-space to user-space */
@@ -609,11 +613,5 @@
 };
 DECLARE_NULL_INSTANCE (hb_font_t);
 
-#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
 
-
 #endif /* HB_FONT_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -466,9 +466,9 @@
   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;
-  metrics->line_gap = ft_face->size->metrics.height - (ft_face->size->metrics.ascender - ft_face->size->metrics.descender);
+  metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale);
+  metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale);
+  metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender);
   if (font->y_scale < 0)
   {
     metrics->ascender = -metrics->ascender;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -26,7 +26,6 @@
  * Google Author(s): Behdad Esfahbod
  */
 
-#define HB_SHAPER graphite2
 #include "hb-shaper-impl.hh"
 
 #include "hb-graphite2.h"
@@ -46,10 +45,6 @@
  **/
 
 
-HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face)
-HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, font)
-
-
 /*
  * shaper face data
  */
@@ -185,8 +180,8 @@
 gr_face *
 hb_graphite2_face_get_gr_face (hb_face_t *face)
 {
-  if (unlikely (!hb_graphite2_shaper_face_data_ensure (face))) return nullptr;
-  return HB_SHAPER_DATA_GET (face)->grface;
+  const hb_graphite2_face_data_t *data = face->data.graphite2;
+  return data ? data->grface : nullptr;
 }
 
 
@@ -221,28 +216,6 @@
 
 
 /*
- * shaper shape_plan data
- */
-
-struct hb_graphite2_shape_plan_data_t {};
-
-hb_graphite2_shape_plan_data_t *
-_hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
-					     const hb_feature_t *user_features HB_UNUSED,
-					     unsigned int        num_user_features HB_UNUSED,
-					     const int          *coords HB_UNUSED,
-					     unsigned int        num_coords HB_UNUSED)
-{
-  return (hb_graphite2_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shape_plan_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
  * shaper
  */
 
@@ -263,7 +236,7 @@
 		     unsigned int        num_features)
 {
   hb_face_t *face = font->face;
-  gr_face *grface = HB_SHAPER_DATA_GET (face)->grface;
+  gr_face *grface = face->data.graphite2->grface;
 
   const char *lang = hb_language_to_string (hb_buffer_get_language (buffer));
   const char *lang_end = lang ? strchr (lang, '-') : nullptr;

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2017  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_KERN_HH
+#define HB_KERN_HH
+
+#include "hb-open-type.hh"
+#include "hb-aat-layout-common.hh"
+#include "hb-ot-layout-gpos-table.hh"
+
+
+namespace OT {
+
+
+template <typename Driver>
+struct hb_kern_machine_t
+{
+  hb_kern_machine_t (const Driver &driver_,
+		     bool crossStream_ = false) :
+		       driver (driver_),
+		       crossStream (crossStream_) {}
+
+  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);
+	if (crossStream)
+	{
+	  pos[j].y_offset = kern;
+	  buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+	}
+	else
+	{
+	  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);
+	if (crossStream)
+	{
+	  pos[j].x_offset = kern;
+	  buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+	}
+	else
+	{
+	  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;
+  bool crossStream;
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_KERN_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -110,17 +110,17 @@
   static const unsigned int min_size = (size)
 
 #define DEFINE_SIZE_ARRAY(size, array) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])); \
-  DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \
+  DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
   enum { min_size = (size) }
 
 #define DEFINE_SIZE_ARRAY_SIZED(size, array) \
-	inline unsigned int get_size (void) const { return (size - array.min_size + array.get_size ()); } \
+	inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \
 	DEFINE_SIZE_ARRAY(size, array)
 
 #define DEFINE_SIZE_ARRAY2(size, array1, array2) \
   DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
-  DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
+  DEFINE_COMPILES_ASSERTION ((void) (array1)[0].static_size; (void) (array2)[0].static_size) \
   static const unsigned int min_size = (size)
 
 
@@ -298,7 +298,8 @@
     this->start = this->end = nullptr;
   }
 
-  inline bool check_range (const void *base, unsigned int len) const
+  inline bool check_range (const void *base,
+			   unsigned int len) const
   {
     const char *p = (const char *) base;
     bool ok = this->start <= p &&
@@ -316,22 +317,39 @@
   }
 
   template <typename T>
-  inline bool check_array (const T *base, unsigned int len, unsigned int record_size = T::static_size) const
+  inline bool check_range (const T *base,
+			   unsigned int a,
+			   unsigned int b) const
   {
-    const char *p = (const char *) base;
-    bool overflows = hb_unsigned_mul_overflows (len, record_size);
-    unsigned int array_size = record_size * len;
-    bool ok = !overflows && this->check_range (base, array_size);
+    return !hb_unsigned_mul_overflows (a, b) &&
+	   this->check_range (base, a * b);
+  }
 
-    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
-       "check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s",
-       p, p + (record_size * len), record_size, len, (unsigned int) array_size,
-       this->start, this->end,
-       overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE");
+  template <typename T>
+  inline bool check_range (const T *base,
+			   unsigned int a,
+			   unsigned int b,
+			   unsigned int c) const
+  {
+    return !hb_unsigned_mul_overflows (a, b) &&
+	   this->check_range (base, a * b, c);
+  }
 
-    return likely (ok);
+  template <typename T>
+  inline bool check_array (const T *base,
+			   unsigned int len) const
+  {
+    return this->check_range (base, len, T::static_size);
   }
 
+  template <typename T>
+  inline bool check_array (const T *base,
+			   unsigned int a,
+			   unsigned int b) const
+  {
+    return this->check_range (base, a, b, T::static_size);
+  }
+
   template <typename Type>
   inline bool check_struct (const Type *obj) const
   {
@@ -734,21 +752,18 @@
     return *(((Data **) (void *) this) - WheresData);
   }
 
+  inline bool is_inert (void) const { return !get_data (); }
+
   template <typename Stored, typename Subclass>
-  inline Stored * call_create (void) const
-  {
-    Data *data = this->get_data ();
-    return likely (data) ? Subclass::create (data) : nullptr;
-  }
+  inline Stored * call_create (void) const { return Subclass::create (get_data ()); }
 };
 template <>
 struct hb_data_wrapper_t<void, 0>
 {
+  inline bool is_inert (void) const { return false; }
+
   template <typename Stored, typename Funcs>
-  inline Stored * call_create (void) const
-  {
-    return Funcs::create ();
-  }
+  inline Stored * call_create (void) const { return Funcs::create (); }
 };
 
 template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; };
@@ -775,33 +790,23 @@
   {
   retry:
     Stored *p = instance.get ();
-    if (unlikely (p && !this->instance.cmpexch (p, nullptr)))
+    if (unlikely (p && !cmpexch (p, nullptr)))
       goto retry;
     do_destroy (p);
   }
 
-  inline Stored * do_create (void) const
-  {
-    Stored *p = this->template call_create<Stored, Funcs> ();
-    if (unlikely (!p))
-      p = const_cast<Stored *> (Funcs::get_null ());
-    return p;
-  }
   static inline void do_destroy (Stored *p)
   {
-    if (p && p != Funcs::get_null ())
+    if (p && p != const_cast<Stored *> (Funcs::get_null ()))
       Funcs::destroy (p);
   }
 
   inline const Returned * operator -> (void) const { return get (); }
   inline const Returned & operator * (void) const { return *get (); }
+  explicit_operator inline operator bool (void) const
+  { return get_stored () != Funcs::get_null (); }
   template <typename C> inline operator const C * (void) const { return get (); }
 
-  inline Data * get_data (void) const
-  {
-    return *(((Data **) this) - WheresData);
-  }
-
   inline Stored * get_stored (void) const
   {
   retry:
@@ -808,8 +813,14 @@
     Stored *p = this->instance.get ();
     if (unlikely (!p))
     {
-      p = do_create ();
-      if (unlikely (!this->instance.cmpexch (nullptr, p)))
+      if (unlikely (this->is_inert ()))
+	return const_cast<Stored *> (Funcs::get_null ());
+
+      p = this->template call_create<Stored, Funcs> ();
+      if (unlikely (!p))
+	p = const_cast<Stored *> (Funcs::get_null ());
+
+      if (unlikely (!cmpexch (nullptr, p)))
       {
         do_destroy (p);
 	goto retry;
@@ -822,15 +833,10 @@
     return this->instance.get_relaxed ();
   }
 
-  inline void set_stored (Stored *instance_)
+  inline bool cmpexch (Stored *current, Stored *value) const
   {
-    /* This *must* be called when there are no other threads accessing.
-     * However, to make TSan, etc, happy, we using cmpexch. */
-  retry:
-    Stored *p = this->instance.get ();
-    if (unlikely (!this->instance.cmpexch (p, instance_)))
-      goto retry;
-    do_destroy (p);
+    /* This *must* be called when there are no other threads accessing. */
+    return this->instance.cmpexch (current, value);
   }
 
   inline const Returned * get (void) const { return Funcs::convert (get_stored ()); }
@@ -862,7 +868,7 @@
     free (p);
   }
 
-  private:
+//  private:
   /* Must only have one pointer. */
   hb_atomic_ptr_t<Stored *> instance;
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -48,7 +48,7 @@
 /* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */
 
 
-#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
+#elif !defined(HB_NO_MT) && defined(_WIN32)
 
 #include <windows.h>
 typedef CRITICAL_SECTION hb_mutex_impl_t;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -194,7 +194,7 @@
 struct hb_object_header_t
 {
   hb_reference_count_t ref_count;
-  hb_atomic_int_t writable;
+  mutable hb_atomic_int_t writable;
   hb_atomic_ptr_t<hb_user_data_array_t> user_data;
 };
 #define HB_OBJECT_HEADER_STATIC \

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -58,7 +58,7 @@
 {
   typedef Type type;
   inline void set (Type i) { v.set (i); }
-  inline operator Type(void) const { return v; }
+  inline operator Type (void) const { return v; }
   inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
   inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
   static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
@@ -173,7 +173,7 @@
   }
 
   public:
-  DEFINE_SIZE_STATIC (sizeof(Type));
+  DEFINE_SIZE_STATIC (sizeof (Type));
 };
 
 typedef Offset<HBUINT16> Offset16;
@@ -211,7 +211,7 @@
 template <typename FixedType=HBUINT16>
 struct FixedVersion
 {
-  inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; }
+  inline uint32_t to_int (void) const { return (major << (sizeof (FixedType) * 8)) + minor; }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -222,7 +222,7 @@
   FixedType major;
   FixedType minor;
   public:
-  DEFINE_SIZE_STATIC (2 * sizeof(FixedType));
+  DEFINE_SIZE_STATIC (2 * sizeof (FixedType));
 };
 
 
@@ -241,12 +241,12 @@
 
   inline const Type& operator () (const void *base) const
   {
-    if (unlikely (this->is_null ())) return Null(Type);
+    if (unlikely (this->is_null ())) return Null (Type);
     return StructAtOffset<const Type> (base, *this);
   }
   inline Type& operator () (void *base) const
   {
-    if (unlikely (this->is_null ())) return Crap(Type);
+    if (unlikely (this->is_null ())) return Crap (Type);
     return StructAtOffset<Type> (base, *this);
   }
 
@@ -258,7 +258,7 @@
   template <typename T>
   inline void serialize_subset (hb_subset_context_t *c, const T &src, const void *base)
   {
-    if (&src == &Null(T))
+    if (&src == &Null (T))
     {
       this->set (0);
       return;
@@ -319,7 +319,7 @@
     if (!has_null) return false;
     return c->try_set (this, 0);
   }
-  DEFINE_SIZE_STATIC (sizeof(OffsetType));
+  DEFINE_SIZE_STATIC (sizeof (OffsetType));
 };
 template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {};
 template <typename Base, typename OffsetType, bool has_null, typename Type>
@@ -335,10 +335,22 @@
 template <typename Type>
 struct UnsizedArrayOf
 {
+  enum { item_size = Type::static_size };
+
   HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type);
 
-  inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
-  inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
+  inline const Type& operator [] (unsigned int i) const
+  {
+    const Type *p = &arrayZ[i];
+    if (unlikely (p < arrayZ)) return Null (Type); /* Overflowed. */
+    return *p;
+  }
+  inline Type& operator [] (unsigned int i)
+  {
+    Type *p = &arrayZ[i];
+    if (unlikely (p < arrayZ)) return Crap (Type); /* Overflowed. */
+    return *p;
+  }
 
   template <typename T> inline operator T * (void) { return arrayZ; }
   template <typename T> inline operator const T * (void) const { return arrayZ; }
@@ -371,7 +383,7 @@
     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!arrayZ[i].sanitize (c, base)))
-        return_trace (false);
+	return_trace (false);
     return_trace (true);
   }
   template <typename T>
@@ -381,7 +393,7 @@
     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
-        return_trace (false);
+	return_trace (false);
     return_trace (true);
   }
 
@@ -427,6 +439,8 @@
 template <typename Type, typename LenType=HBUINT16>
 struct ArrayOf
 {
+  enum { item_size = Type::static_size };
+
   HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType);
 
   inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
@@ -443,12 +457,12 @@
 
   inline const Type& operator [] (unsigned int i) const
   {
-    if (unlikely (i >= len)) return Null(Type);
+    if (unlikely (i >= len)) return Null (Type);
     return arrayZ[i];
   }
   inline Type& operator [] (unsigned int i)
   {
-    if (unlikely (i >= len)) return Crap(Type);
+    if (unlikely (i >= len)) return Crap (Type);
     return arrayZ[i];
   }
 
@@ -499,7 +513,7 @@
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!arrayZ[i].sanitize (c, base)))
-        return_trace (false);
+	return_trace (false);
     return_trace (true);
   }
   template <typename T>
@@ -510,7 +524,7 @@
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
-        return_trace (false);
+	return_trace (false);
     return_trace (true);
   }
 
@@ -520,7 +534,7 @@
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
       if (!this->arrayZ[i].cmp (x))
-        return i;
+	return i;
     return -1;
   }
 
@@ -558,12 +572,12 @@
 {
   inline const Type& operator [] (unsigned int i) const
   {
-    if (unlikely (i >= this->len)) return Null(Type);
+    if (unlikely (i >= this->len)) return Null (Type);
     return this+this->arrayZ[i];
   }
   inline const Type& operator [] (unsigned int i)
   {
-    if (unlikely (i >= this->len)) return Crap(Type);
+    if (unlikely (i >= this->len)) return Crap (Type);
     return this+this->arrayZ[i];
   }
 
@@ -595,16 +609,18 @@
 template <typename Type, typename LenType=HBUINT16>
 struct HeadlessArrayOf
 {
+  enum { item_size = Type::static_size };
+
   HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (HeadlessArrayOf, Type, LenType);
 
   inline const Type& operator [] (unsigned int i) const
   {
-    if (unlikely (i >= lenP1 || !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 >= lenP1 || !i)) return Crap(Type);
+    if (unlikely (i >= lenP1 || !i)) return Crap (Type);
     return arrayZ[i-1];
   }
   inline unsigned int get_size (void) const
@@ -665,12 +681,12 @@
 
   inline const Type& operator [] (unsigned int i) const
   {
-    if (unlikely (i > lenM1)) return Null(Type);
+    if (unlikely (i > lenM1)) return Null (Type);
     return arrayZ[i];
   }
   inline Type& operator [] (unsigned int i)
   {
-    if (unlikely (i > lenM1)) return Crap(Type);
+    if (unlikely (i > lenM1)) return Crap (Type);
     return arrayZ[i];
   }
   inline unsigned int get_size (void) const
@@ -684,7 +700,7 @@
     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 (false);
     return_trace (true);
   }
 
@@ -717,12 +733,9 @@
     {
       int mid = ((unsigned int) min + (unsigned int) max) / 2;
       int c = arr[mid].cmp (x);
-      if (c < 0)
-        max = mid - 1;
-      else if (c > 0)
-        min = mid + 1;
-      else
-        return mid;
+      if (c < 0) max = mid - 1;
+      else if (c > 0) min = mid + 1;
+      else return mid;
     }
     return -1;
   }
@@ -793,11 +806,13 @@
 template <typename Type>
 struct VarSizedBinSearchArrayOf
 {
+  enum { item_size = Type::static_size };
+
   HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type);
 
   inline const Type& operator [] (unsigned int i) const
   {
-    if (unlikely (i >= header.nUnits)) return Null(Type);
+    if (unlikely (i >= header.nUnits)) return Null (Type);
     return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
   }
   inline Type& operator [] (unsigned int i)
@@ -830,9 +845,20 @@
     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 (false);
     return_trace (true);
   }
+  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 = header.nUnits;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!(*this)[i].sanitize (c, base, user_data)))
+	return_trace (false);
+    return_trace (true);
+  }
 
   template <typename T>
   inline const Type *bsearch (const T &key) const
@@ -844,12 +870,9 @@
       int mid = ((unsigned int) min + (unsigned int) 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;
+      if (c < 0) max = mid - 1;
+      else if (c > 0) min = mid + 1;
+      else return p;
     }
     return nullptr;
   }
@@ -860,7 +883,9 @@
     TRACE_SANITIZE (this);
     return_trace (header.sanitize (c) &&
 		  Type::static_size <= header.unitSize &&
-		  c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize));
+		  c->check_range (bytesZ.arrayZ,
+				  header.nUnits,
+				  header.unitSize));
   }
 
   protected:

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -53,7 +53,7 @@
   {
     for (unsigned int i = 0; i < 256; i++)
       if (glyphIdArray[i])
-        out->add (i);
+	out->add (i);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -82,8 +82,8 @@
   };
 
   bool serialize (hb_serialize_context_t *c,
-                  const hb_subset_plan_t *plan,
-                  const hb_vector_t<segment_plan> &segments)
+		  const hb_subset_plan_t *plan,
+		  const hb_vector_t<segment_plan> &segments)
   {
     TRACE_SERIALIZE (this);
 
@@ -96,8 +96,8 @@
     this->entrySelector.set (MAX (1u, hb_bit_storage (segments.len)) - 1);
     this->searchRange.set (2 * (1u << this->entrySelector));
     this->rangeShift.set (segments.len * 2 > this->searchRange
-                          ? 2 * segments.len - this->searchRange
-                          : 0);
+			  ? 2 * segments.len - this->searchRange
+			  : 0);
 
     HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
     c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
@@ -114,40 +114,40 @@
       start_count[i].set (segments[i].start_code);
       if (segments[i].use_delta)
       {
-        hb_codepoint_t cp = segments[i].start_code;
-        hb_codepoint_t start_gid = 0;
-        if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF))
-          return_trace (false);
-        id_delta[i].set (start_gid - segments[i].start_code);
+	hb_codepoint_t cp = segments[i].start_code;
+	hb_codepoint_t start_gid = 0;
+	if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF))
+	  return_trace (false);
+	id_delta[i].set (start_gid - segments[i].start_code);
       } else {
-        id_delta[i].set (0);
-        unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1;
-        HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints);
-        if (glyph_id_array == nullptr)
-          return_trace (false);
-        // From the cmap spec:
-        //
-        // id_range_offset[i]/2
-        // + (cp - segments[i].start_code)
-        // + (id_range_offset + i)
-        // =
-        // glyph_id_array + (cp - segments[i].start_code)
-        //
-        // So, solve for id_range_offset[i]:
-        //
-        // id_range_offset[i]
-        // =
-        // 2 * (glyph_id_array - id_range_offset - i)
-        id_range_offset[i].set (2 * (
-            glyph_id_array - id_range_offset - i));
-        for (unsigned int j = 0; j < num_codepoints; j++)
-        {
-          hb_codepoint_t cp = segments[i].start_code + j;
-          hb_codepoint_t new_gid;
-          if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
-            return_trace (false);
-          glyph_id_array[j].set (new_gid);
-        }
+	id_delta[i].set (0);
+	unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1;
+	HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints);
+	if (glyph_id_array == nullptr)
+	  return_trace (false);
+	// From the cmap spec:
+	//
+	// id_range_offset[i]/2
+	// + (cp - segments[i].start_code)
+	// + (id_range_offset + i)
+	// =
+	// glyph_id_array + (cp - segments[i].start_code)
+	//
+	// So, solve for id_range_offset[i]:
+	//
+	// id_range_offset[i]
+	// =
+	// 2 * (glyph_id_array - id_range_offset - i)
+	id_range_offset[i].set (2 * (
+	    glyph_id_array - id_range_offset - i));
+	for (unsigned int j = 0; j < num_codepoints; j++)
+	{
+	  hb_codepoint_t cp = segments[i].start_code + j;
+	  hb_codepoint_t new_gid;
+	  if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
+	    return_trace (false);
+	  glyph_id_array[j].set (new_gid);
+	}
       }
     }
 
@@ -161,23 +161,23 @@
     {
       // Parallel array entries
       segment_size +=
-            2  // end count
-          + 2  // start count
-          + 2  // delta
-          + 2; // range offset
+	    2  // end count
+	  + 2  // start count
+	  + 2  // delta
+	  + 2; // range offset
 
       if (!segments[i].use_delta)
-        // Add bytes for the glyph index array entries for this segment.
-        segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2;
+	// Add bytes for the glyph index array entries for this segment.
+	segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2;
     }
 
     return min_size
-        + 2 // Padding
-        + segment_size;
+	+ 2 // Padding
+	+ segment_size;
   }
 
   static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
-                                            hb_vector_t<segment_plan> *segments)
+					    hb_vector_t<segment_plan> *segments)
   {
     segment_plan *segment = nullptr;
     hb_codepoint_t last_gid = 0;
@@ -191,24 +191,22 @@
 	return false;
       }
 
-      if (cp > 0xFFFF) {
-        // We are now outside of unicode BMP, stop adding to this cmap.
-        break;
-      }
+      /* Stop adding to cmap if we are now outside of unicode BMP. */
+      if (cp > 0xFFFF) break;
 
-      if (!segment
-          || cp != segment->end_code + 1u)
+      if (!segment ||
+	  cp != segment->end_code + 1u)
       {
-        segment = segments->push ();
-        segment->start_code.set (cp);
-        segment->end_code.set (cp);
-        segment->use_delta = true;
+	segment = segments->push ();
+	segment->start_code.set (cp);
+	segment->end_code.set (cp);
+	segment->use_delta = true;
       } else {
-        segment->end_code.set (cp);
-        if (last_gid + 1u != new_gid)
-          // gid's are not consecutive in this segment so delta
-          // cannot be used.
-          segment->use_delta = false;
+	segment->end_code.set (cp);
+	if (last_gid + 1u != new_gid)
+	  // gid's are not consecutive in this segment so delta
+	  // cannot be used.
+	  segment->use_delta = false;
       }
 
       last_gid = new_gid;
@@ -253,7 +251,7 @@
       unsigned int i;
       while (min <= max)
       {
-        int mid = ((unsigned int) min + (unsigned int) max) / 2;
+	int mid = ((unsigned int) min + (unsigned int) max) / 2;
 	if (codepoint < startCount[mid])
 	  max = mid - 1;
 	else if (codepoint > endCount[mid])
@@ -296,7 +294,7 @@
     {
       unsigned int count = this->segCount;
       if (count && this->startCount[count - 1] == 0xFFFFu)
-        count--; /* Skip sentinel segment. */
+	count--; /* Skip sentinel segment. */
       for (unsigned int i = 0; i < count; i++)
       {
 	unsigned int rangeOffset = this->idRangeOffset[i];
@@ -438,7 +436,7 @@
     unsigned int count = glyphIdArray.len;
     for (unsigned int i = 0; i < count; i++)
       if (glyphIdArray[i])
-        out->add (start + i);
+	out->add (start + i);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -495,7 +493,7 @@
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-                         const hb_vector_t<CmapSubtableLongGroup> &group_data)
+			 const hb_vector_t<CmapSubtableLongGroup> &group_data)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
@@ -523,7 +521,7 @@
 
 
   bool serialize (hb_serialize_context_t *c,
-                  const hb_vector_t<CmapSubtableLongGroup> &groups)
+		  const hb_vector_t<CmapSubtableLongGroup> &groups)
   {
     if (unlikely (!c->extend_min (*this))) return false;
 
@@ -540,7 +538,7 @@
   }
 
   static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
-                                            hb_vector_t<CmapSubtableLongGroup> *groups)
+					    hb_vector_t<CmapSubtableLongGroup> *groups)
   {
     CmapSubtableLongGroup *group = nullptr;
 
@@ -555,14 +553,12 @@
 
       if (!group || !_is_gid_consecutive (group, cp, new_gid))
       {
-        group = groups->push ();
-        group->startCharCode.set (cp);
-        group->endCharCode.set (cp);
-        group->glyphID.set (new_gid);
-      } else
-      {
-        group->endCharCode.set (cp);
+	group = groups->push ();
+	group->startCharCode.set (cp);
+	group->endCharCode.set (cp);
+	group->glyphID.set (new_gid);
       }
+      else group->endCharCode.set (cp);
     }
 
     DEBUG_MSG(SUBSET, nullptr, "cmap");
@@ -636,7 +632,7 @@
   }
 
   public:
-  DEFINE_SIZE_ARRAY (4, arrayZ);
+  DEFINE_SIZE_ARRAY (4, *this);
 };
 
 struct UVSMapping
@@ -668,7 +664,7 @@
   }
 
   public:
-  DEFINE_SIZE_ARRAY (4, arrayZ);
+  DEFINE_SIZE_ARRAY (4, *this);
 };
 
 struct VariationSelectorRecord
@@ -855,12 +851,12 @@
 
   struct subset_plan
   {
-    inline size_t final_size() const
+    inline size_t final_size () const
     {
       return 4 // header
-          +  8 * 3 // 3 EncodingRecord
-          +  CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
-          +  CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
+	  +  8 * 3 // 3 EncodingRecord
+	  +  CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
+	  +  CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
     }
 
     hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
@@ -876,9 +872,9 @@
   }
 
   inline bool _create_plan (const hb_subset_plan_t *plan,
-                            subset_plan *cmap_plan) const
+			    subset_plan *cmap_plan) const
   {
-    if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
+    if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
       return false;
 
     return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
@@ -885,7 +881,7 @@
   }
 
   inline bool _subset (const hb_subset_plan_t *plan,
-                       const subset_plan &cmap_subset_plan,
+		       const subset_plan &cmap_subset_plan,
 		       size_t dest_sz,
 		       void *dest) const
   {
@@ -927,7 +923,7 @@
 
       CmapSubtableFormat4 &format4 = subtable.u.format4;
       if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments)))
-        return false;
+	return false;
     }
 
     // Write out format 12 sub table.
@@ -937,7 +933,7 @@
 
       CmapSubtableFormat12 &format12 = subtable.u.format12;
       if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
-        return false;
+	return false;
     }
 
     c.end_serialize ();
@@ -956,7 +952,7 @@
     }
 
     // We now know how big our blob needs to be
-    size_t dest_sz = cmap_subset_plan.final_size();
+    size_t dest_sz = cmap_subset_plan.final_size ();
     void *dest = malloc (dest_sz);
     if (unlikely (!dest)) {
       DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz);
@@ -971,11 +967,11 @@
     }
 
     // all done, write the blob into dest
-    hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest,
-                                            dest_sz,
-                                            HB_MEMORY_MODE_READONLY,
-                                            dest,
-                                            free);
+    hb_blob_t *cmap_prime = hb_blob_create ((const char *) dest,
+					    dest_sz,
+					    HB_MEMORY_MODE_READONLY,
+					    dest,
+					    free);
     bool result =  plan->add_table (HB_OT_TAG_cmap, cmap_prime);
     hb_blob_destroy (cmap_prime);
     return result;
@@ -1007,7 +1003,7 @@
     }
 
     /* Meh. */
-    return &Null(CmapSubtable);
+    return &Null (CmapSubtable);
   }
 
   struct accelerator_t
@@ -1014,25 +1010,22 @@
   {
     inline void init (hb_face_t *face)
     {
-      this->blob = hb_sanitize_context_t().reference_table<cmap> (face);
-      const cmap *table = this->blob->as<cmap> ();
+      this->table = hb_sanitize_context_t ().reference_table<cmap> (face);
       bool symbol;
-      subtableZ = table->find_best_subtable (&symbol);
-
-      /* UVS subtable. */
-      subtable_uvsZ = &Null(CmapSubtableFormat14);
+      this->subtable = table->find_best_subtable (&symbol);
+      this->subtable_uvs = &Null (CmapSubtableFormat14);
       {
 	const CmapSubtable *st = table->find_subtable (0, 5);
 	if (st && st->u.format == 14)
-	  subtable_uvsZ = &st->u.format14;
+	  subtable_uvs = &st->u.format14;
       }
 
-      this->get_glyph_data = subtableZ;
+      this->get_glyph_data = subtable;
       if (unlikely (symbol))
       {
 	this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>;
       } else {
-	switch (subtableZ->u.format) {
+	switch (subtable->u.format) {
 	/* Accelerate format 4 and format 12. */
 	default:
 	  this->get_glyph_funcZ = get_glyph_from<CmapSubtable>;
@@ -1042,7 +1035,7 @@
 	  break;
 	case  4:
 	  {
-	    this->format4_accel.init (&subtableZ->u.format4);
+	    this->format4_accel.init (&subtable->u.format4);
 	    this->get_glyph_data = &this->format4_accel;
 	    this->get_glyph_funcZ = this->format4_accel.get_glyph_func;
 	  }
@@ -1053,7 +1046,7 @@
 
     inline void fini (void)
     {
-      hb_blob_destroy (this->blob);
+      this->table.destroy ();
     }
 
     inline bool get_nominal_glyph (hb_codepoint_t  unicode,
@@ -1062,15 +1055,35 @@
       if (unlikely (!this->get_glyph_funcZ)) return false;
       return this->get_glyph_funcZ (this->get_glyph_data, unicode, 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) const
+    {
+      if (unlikely (!this->get_glyph_funcZ)) return 0;
 
+      hb_cmap_get_glyph_func_t get_glyph_funcZ = this->get_glyph_funcZ;
+      const void *get_glyph_data = this->get_glyph_data;
+
+      unsigned int done;
+      for (done = 0;
+	   done < count && get_glyph_funcZ (get_glyph_data, *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;
+    }
+
     inline bool get_variation_glyph (hb_codepoint_t  unicode,
 				     hb_codepoint_t  variation_selector,
 				     hb_codepoint_t *glyph) const
     {
-      if (unlikely (!this->subtable_uvsZ)) return false;
-      switch (this->subtable_uvsZ->get_glyph_variant (unicode,
-						      variation_selector,
-						      glyph))
+      switch (this->subtable_uvs->get_glyph_variant (unicode,
+						     variation_selector,
+						     glyph))
       {
 	case GLYPH_VARIANT_NOT_FOUND:	return false;
 	case GLYPH_VARIANT_FOUND:	return true;
@@ -1082,19 +1095,16 @@
 
     inline void collect_unicodes (hb_set_t *out) const
     {
-      if (unlikely (!this->subtableZ)) return;
-      subtableZ->collect_unicodes (out);
+      subtable->collect_unicodes (out);
     }
     inline void collect_variation_selectors (hb_set_t *out) const
     {
-      if (unlikely (!this->subtable_uvsZ)) return;
-      subtable_uvsZ->collect_variation_selectors (out);
+      subtable_uvs->collect_variation_selectors (out);
     }
     inline void collect_variation_unicodes (hb_codepoint_t variation_selector,
 					    hb_set_t *out) const
     {
-      if (unlikely (!this->subtable_uvsZ)) return;
-      subtable_uvsZ->collect_variation_unicodes (variation_selector, out);
+      subtable_uvs->collect_variation_unicodes (variation_selector, out);
     }
 
     protected:
@@ -1134,8 +1144,8 @@
     }
 
     private:
-    const CmapSubtable *subtableZ;
-    const CmapSubtableFormat14 *subtable_uvsZ;
+    hb_nonnull_ptr_t<const CmapSubtable> subtable;
+    hb_nonnull_ptr_t<const CmapSubtableFormat14> subtable_uvs;
 
     hb_cmap_get_glyph_func_t get_glyph_funcZ;
     const void *get_glyph_data;
@@ -1142,7 +1152,7 @@
 
     CmapSubtableFormat4::accelerator_t format4_accel;
 
-    hb_blob_t *blob;
+    hb_blob_ptr_t<cmap> table;
   };
 
   protected:

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -384,26 +384,16 @@
   {
     inline void init (hb_face_t *face)
     {
+      cblc = hb_sanitize_context_t().reference_table<CBLC> (face);
+      cbdt = hb_sanitize_context_t().reference_table<CBDT> (face);
+
       upem = hb_face_get_upem (face);
-
-      cblc_blob = hb_sanitize_context_t().reference_table<CBLC> (face);
-      cbdt_blob = hb_sanitize_context_t().reference_table<CBDT> (face);
-      cbdt_len = hb_blob_get_length (cbdt_blob);
-
-      if (hb_blob_get_length (cblc_blob) == 0) {
-	cblc = nullptr;
-	cbdt = nullptr;
-	return;  /* Not a bitmap font. */
-      }
-      cblc = cblc_blob->as<CBLC> ();
-      cbdt = cbdt_blob->as<CBDT> ();
-
     }
 
     inline void fini (void)
     {
-      hb_blob_destroy (this->cblc_blob);
-      hb_blob_destroy (this->cbdt_blob);
+      this->cblc.destroy ();
+      this->cbdt.destroy ();
     }
 
     inline bool get_extents (hb_font_t *font, hb_codepoint_t glyph,
@@ -423,6 +413,7 @@
 	return false;
 
       {
+	unsigned int cbdt_len = cbdt.get_length ();
 	if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
 	  return false;
 
@@ -475,6 +466,7 @@
 	return hb_blob_get_empty ();
 
       {
+	unsigned int cbdt_len = cbdt.get_length ();
 	if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
 	  return hb_blob_get_empty ();
 
@@ -485,7 +477,7 @@
 	      return hb_blob_get_empty ();
 	    const GlyphBitmapDataFormat17& glyphFormat17 =
 	      StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
-	    return hb_blob_create_sub_blob (cbdt_blob,
+	    return hb_blob_create_sub_blob (cbdt.get_blob (),
 					    image_offset + GlyphBitmapDataFormat17::min_size,
 					    glyphFormat17.data.len);
 	  }
@@ -494,7 +486,7 @@
 	      return hb_blob_get_empty ();
 	    const GlyphBitmapDataFormat18& glyphFormat18 =
 	      StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
-	    return hb_blob_create_sub_blob (cbdt_blob,
+	    return hb_blob_create_sub_blob (cbdt.get_blob (),
 					    image_offset + GlyphBitmapDataFormat18::min_size,
 					    glyphFormat18.data.len);
 	  }
@@ -503,7 +495,7 @@
 	      return hb_blob_get_empty ();
 	    const GlyphBitmapDataFormat19& glyphFormat19 =
 	      StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
-	    return hb_blob_create_sub_blob (cbdt_blob,
+	    return hb_blob_create_sub_blob (cbdt.get_blob (),
 					    image_offset + GlyphBitmapDataFormat19::min_size,
 					    glyphFormat19.data.len);
 	  }
@@ -513,16 +505,12 @@
       return hb_blob_get_empty ();
     }
 
-    inline bool has_data () const
-    { return cbdt_len; }
+    inline bool has_data () const { return cbdt.get_length (); }
 
     private:
-    hb_blob_t *cblc_blob;
-    hb_blob_t *cbdt_blob;
-    hb_nonnull_ptr_t<const CBLC> cblc;
-    hb_nonnull_ptr_t<const CBDT> cbdt;
+    hb_blob_ptr_t<CBLC> cblc;
+    hb_blob_ptr_t<CBDT> cbdt;
 
-    unsigned int cbdt_len;
     unsigned int upem;
   };
 

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -103,7 +103,12 @@
 					unsigned int        *count, /* IN/OUT.  May be NULL. */
 					hb_ot_color_layer_t *layers /* OUT.     May be NULL. */) const
   {
-    const BaseGlyphRecord &record = get_glyph_record (glyph);
+    const BaseGlyphRecord *rec = (BaseGlyphRecord *) bsearch (&glyph,
+							      &(this+baseGlyphsZ),
+							      numBaseGlyphs,
+							      sizeof (BaseGlyphRecord),
+							      BaseGlyphRecord::cmp);
+    const BaseGlyphRecord &record = rec ? *rec : Null (BaseGlyphRecord);
 
     hb_array_t<const LayerRecord> all_layers ((this+layersZ).arrayZ, numLayers);
     hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
@@ -129,17 +134,6 @@
 			  (this+layersZ).sanitize (c, numLayers)));
   }
 
-  private:
-  inline const BaseGlyphRecord &get_glyph_record (hb_codepoint_t glyph_id) const
-  {
-    const BaseGlyphRecord *rec = (BaseGlyphRecord *) bsearch (&glyph_id,
-							      &(this+baseGlyphsZ),
-							      numBaseGlyphs,
-							      sizeof (BaseGlyphRecord),
-							      BaseGlyphRecord::cmp);
-    return rec ? *rec : Null(BaseGlyphRecord);
-  }
-
   protected:
   HBUINT16	version;	/* Table version number (starts at 0). */
   HBUINT16	numBaseGlyphs;	/* Number of Base Glyph Records. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -140,14 +140,13 @@
   {
     inline void init (hb_face_t *face)
     {
-      sbix_blob = hb_sanitize_context_t().reference_table<sbix> (face);
-      table = sbix_blob->as<sbix> ();
+      table = hb_sanitize_context_t().reference_table<sbix> (face);
       num_glyphs = face->get_num_glyphs ();
     }
 
     inline void fini (void)
     {
-      hb_blob_destroy (sbix_blob);
+      table.destroy ();
     }
 
     inline bool has_data () const
@@ -169,7 +168,7 @@
 				     int            *y_offset,
 				     unsigned int   *available_ppem) const
     {
-      return choose_strike (font).get_glyph_blob (glyph_id, sbix_blob,
+      return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (),
 						  HB_TAG ('p','n','g',' '),
 						  x_offset, y_offset,
 						  num_glyphs, available_ppem);
@@ -250,7 +249,7 @@
       /* Convert to font units. */
       if (strike_ppem)
       {
-	double scale = font->face->upem / (double) strike_ppem;
+	double scale = font->face->get_upem () / (double) strike_ppem;
 	extents->x_bearing = round (extents->x_bearing * scale);
 	extents->y_bearing = round (extents->y_bearing * scale);
 	extents->width = round (extents->width * scale);
@@ -263,8 +262,7 @@
     }
 
     private:
-    hb_blob_t *sbix_blob;
-    hb_nonnull_ptr_t<const sbix> table;
+    hb_blob_ptr_t<sbix> table;
 
     unsigned int num_glyphs;
   };

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -81,25 +81,24 @@
   {
     inline void init (hb_face_t *face)
     {
-      svg_blob = hb_sanitize_context_t().reference_table<SVG> (face);
-      table = svg_blob->as<SVG> ();
+      table = hb_sanitize_context_t().reference_table<SVG> (face);
     }
 
     inline void fini (void)
     {
-      hb_blob_destroy (svg_blob);
+      table.destroy ();
     }
 
     inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
     {
-      return table->get_glyph_entry (glyph_id).reference_blob (svg_blob, table->svgDocEntries);
+      return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (),
+							       table->svgDocEntries);
     }
 
     inline bool has_data () const { return table->has_data (); }
 
     private:
-    hb_blob_t *svg_blob;
-    hb_nonnull_ptr_t<const SVG> table;
+    hb_blob_ptr_t<SVG> table;
   };
 
   inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -50,42 +50,6 @@
  **/
 
 
-static inline const OT::COLR&
-_get_colr (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::COLR);
-  return *(hb_ot_face_data (face)->COLR);
-}
-
-static inline const OT::CBDT_accelerator_t&
-_get_cbdt (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t);
-  return *(hb_ot_face_data (face)->CBDT);
-}
-
-static inline const OT::CPAL&
-_get_cpal (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CPAL);
-  return *(hb_ot_face_data (face)->CPAL);
-}
-
-static inline const OT::sbix_accelerator_t&
-_get_sbix (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix_accelerator_t);
-  return *(hb_ot_face_data (face)->sbix);
-}
-
-static inline const OT::SVG_accelerator_t&
-_get_svg (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG_accelerator_t);
-  return *(hb_ot_face_data (face)->SVG);
-}
-
-
 /*
  * CPAL
  */
@@ -102,7 +66,7 @@
 hb_bool_t
 hb_ot_color_has_palettes (hb_face_t *face)
 {
-  return _get_cpal (face).has_data ();
+  return face->table.CPAL->has_data ();
 }
 
 /**
@@ -117,7 +81,7 @@
 unsigned int
 hb_ot_color_palette_get_count (hb_face_t *face)
 {
-  return _get_cpal (face).get_palette_count ();
+  return face->table.CPAL->get_palette_count ();
 }
 
 /**
@@ -137,7 +101,7 @@
 hb_ot_color_palette_get_name_id (hb_face_t *face,
 				 unsigned int palette_index)
 {
-  return _get_cpal (face).get_palette_name_id (palette_index);
+  return face->table.CPAL->get_palette_name_id (palette_index);
 }
 
 /**
@@ -153,7 +117,7 @@
 hb_ot_color_palette_color_get_name_id (hb_face_t *face,
 				       unsigned int color_index)
 {
-  return _get_cpal (face).get_color_name_id (color_index);
+  return face->table.CPAL->get_color_name_id (color_index);
 }
 
 /**
@@ -169,7 +133,7 @@
 hb_ot_color_palette_get_flags (hb_face_t *face,
 			       unsigned int palette_index)
 {
-  return _get_cpal(face).get_palette_flags (palette_index);
+  return face->table.CPAL->get_palette_flags (palette_index);
 }
 
 /**
@@ -203,7 +167,7 @@
 				unsigned int  *colors_count  /* IN/OUT.  May be NULL. */,
 				hb_color_t    *colors        /* OUT.     May be NULL. */)
 {
-  return _get_cpal (face).get_palette_colors (palette_index, start_offset, colors_count, colors);
+  return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors);
 }
 
 
@@ -222,7 +186,7 @@
 hb_bool_t
 hb_ot_color_has_layers (hb_face_t *face)
 {
-  return _get_colr (face).has_data ();
+  return face->table.COLR->has_data ();
 }
 
 /**
@@ -245,7 +209,7 @@
 			      unsigned int        *count, /* IN/OUT.  May be NULL. */
 			      hb_ot_color_layer_t *layers /* OUT.     May be NULL. */)
 {
-  return _get_colr (face).get_glyph_layers (glyph, start_offset, count, layers);
+  return face->table.COLR->get_glyph_layers (glyph, start_offset, count, layers);
 }
 
 
@@ -266,7 +230,7 @@
 hb_bool_t
 hb_ot_color_has_svg (hb_face_t *face)
 {
-  return _get_svg (face).has_data ();
+  return face->table.SVG->has_data ();
 }
 
 /**
@@ -274,7 +238,7 @@
  * @face:  a font face.
  * @glyph: a svg glyph index.
  *
- * Get SVG document for a glyph.
+ * Get SVG document for a glyph. The blob may be either plain text or gzip-encoded.
  *
  * Returns: (transfer full): respective svg blob of the glyph, if available.
  *
@@ -283,7 +247,7 @@
 hb_blob_t *
 hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
 {
-  return _get_svg (face).reference_blob_for_glyph (glyph);
+  return face->table.SVG->reference_blob_for_glyph (glyph);
 }
 
 
@@ -304,7 +268,7 @@
 hb_bool_t
 hb_ot_color_has_png (hb_face_t *face)
 {
-  return _get_cbdt (face).has_data () || _get_sbix (face).has_data ();
+  return face->table.CBDT->has_data () || face->table.sbix->has_data ();
 }
 
 /**
@@ -325,11 +289,11 @@
 {
   hb_blob_t *blob = hb_blob_get_empty ();
 
-  if (_get_sbix (font->face).has_data ())
-    blob = _get_sbix (font->face).reference_png (font, glyph, nullptr, nullptr, nullptr);
+  if (font->face->table.sbix->has_data ())
+    blob = font->face->table.sbix->reference_png (font, glyph, nullptr, nullptr, nullptr);
 
-  if (!blob->length && _get_cbdt (font->face).has_data ())
-    blob = _get_cbdt (font->face).reference_png (font, glyph);
+  if (!blob->length && font->face->table.CBDT->has_data ())
+    blob = font->face->table.CBDT->reference_png (font, glyph);
 
   return blob;
 }

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -40,7 +40,7 @@
 #include "hb-ot-layout-gpos-table.hh"
 
 
-void hb_ot_face_data_t::init0 (hb_face_t *face)
+void hb_ot_face_t::init0 (hb_face_t *face)
 {
   this->face = face;
 #define HB_OT_TABLE(Namespace, Type) Type.init0 ();
@@ -49,7 +49,7 @@
 #undef HB_OT_ACCELERATOR
 #undef HB_OT_TABLE
 }
-void hb_ot_face_data_t::fini (void)
+void hb_ot_face_t::fini (void)
 {
 #define HB_OT_TABLE(Namespace, Type) Type.fini ();
 #define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
@@ -57,23 +57,3 @@
 #undef HB_OT_ACCELERATOR
 #undef HB_OT_TABLE
 }
-
-hb_ot_face_data_t *
-_hb_ot_face_data_create (hb_face_t *face)
-{
-  hb_ot_face_data_t *data = (hb_ot_face_data_t *) calloc (1, sizeof (hb_ot_face_data_t));
-  if (unlikely (!data))
-    return nullptr;
-
-  data->init0 (face);
-
-  return data;
-}
-
-void
-_hb_ot_face_data_destroy (hb_ot_face_data_t *data)
-{
-  data->fini ();
-  free (data);
-}
-

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -34,28 +34,37 @@
 #include "hb-machinery.hh"
 
 
-#define hb_ot_face_data(face) ((hb_ot_face_data_t *) face->shaper_data.ot.get_relaxed ())
-
-
 /*
- * hb_ot_face_data_t
+ * hb_ot_face_t
  */
 
-/* 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_TABLES \
+    /* OpenType fundamentals. */ \
+    HB_OT_TABLE(OT, head) \
+    HB_OT_ACCELERATOR(OT, cmap) \
+    HB_OT_ACCELERATOR(OT, hmtx) \
+    HB_OT_ACCELERATOR(OT, vmtx) \
+    HB_OT_ACCELERATOR(OT, post) \
+    HB_OT_TABLE(OT, kern) \
+    HB_OT_ACCELERATOR(OT, glyf) \
+    HB_OT_TABLE(OT, VORG) \
+    HB_OT_ACCELERATOR(OT, name) \
+    HB_OT_TABLE(OT, OS2) \
+    HB_OT_TABLE(OT, STAT) \
     /* OpenType shaping. */ \
     HB_OT_ACCELERATOR(OT, GDEF) \
     HB_OT_ACCELERATOR(OT, GSUB) \
     HB_OT_ACCELERATOR(OT, GPOS) \
+    HB_OT_TABLE(OT, BASE) \
     HB_OT_TABLE(OT, JSTF) \
-    HB_OT_TABLE(OT, BASE) \
     /* AAT shaping. */ \
+    HB_OT_TABLE(AAT, mort) \
     HB_OT_TABLE(AAT, morx) \
-    HB_OT_TABLE(AAT, mort) \
     HB_OT_TABLE(AAT, kerx) \
     HB_OT_TABLE(AAT, ankr) \
     HB_OT_TABLE(AAT, trak) \
+    HB_OT_TABLE(AAT, lcar) \
+    HB_OT_TABLE(AAT, ltag) \
     /* OpenType variations. */ \
     HB_OT_TABLE(OT, fvar) \
     HB_OT_TABLE(OT, avar) \
@@ -62,16 +71,6 @@
     HB_OT_TABLE(OT, MVAR) \
     /* OpenType math. */ \
     HB_OT_TABLE(OT, MATH) \
-    /* OpenType fundamentals. */ \
-    HB_OT_ACCELERATOR(OT, cmap) \
-    HB_OT_ACCELERATOR(OT, hmtx) \
-    HB_OT_ACCELERATOR(OT, vmtx) \
-    HB_OT_ACCELERATOR(OT, post) \
-    HB_OT_TABLE(OT, kern) \
-    HB_OT_ACCELERATOR(OT, glyf) \
-    HB_OT_TABLE(OT, VORG) \
-    HB_OT_ACCELERATOR(OT, name) \
-    HB_OT_TABLE(AAT, ltag) \
     /* OpenType color fonts. */ \
     HB_OT_TABLE(OT, COLR) \
     HB_OT_TABLE(OT, CPAL) \
@@ -87,7 +86,7 @@
 #undef HB_OT_ACCELERATOR
 #undef HB_OT_TABLE
 
-struct hb_ot_face_data_t
+struct hb_ot_face_t
 {
   HB_INTERNAL void init0 (hb_face_t *face);
   HB_INTERNAL void fini (void);
@@ -115,11 +114,4 @@
 };
 
 
-HB_INTERNAL hb_ot_face_data_t *
-_hb_ot_face_data_create (hb_face_t *face);
-
-HB_INTERNAL void
-_hb_ot_face_data_destroy (hb_ot_face_data_t *data);
-
-
 #endif /* HB_OT_FACE_HH */

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -33,10 +33,12 @@
 #include "hb-ot-face.hh"
 
 #include "hb-ot-cmap-table.hh"
+#include "hb-ot-glyf-table.hh"
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-kern-table.hh"
+#include "hb-ot-os2-table.hh"
 #include "hb-ot-post-table.hh"
-#include "hb-ot-glyf-table.hh"
+#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-ot-vorg-table.hh"
 #include "hb-ot-color-cbdt-table.hh"
 #include "hb-ot-color-sbix-table.hh"
@@ -61,7 +63,7 @@
 			 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;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   return ot_face->cmap->get_nominal_glyph (unicode, glyph);
 }
 
@@ -75,17 +77,10 @@
 			  unsigned int glyph_stride,
 			  void *user_data HB_UNUSED)
 {
-  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;
-  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;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
+  return ot_face->cmap->get_nominal_glyphs (count,
+					    first_unicode, unicode_stride,
+					    first_glyph, glyph_stride);
 }
 
 static hb_bool_t
@@ -96,7 +91,7 @@
 			   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;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   return ot_face->cmap->get_variation_glyph (unicode, variation_selector, glyph);
 }
 
@@ -109,7 +104,7 @@
 			    unsigned advance_stride,
 			    void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
 
   for (unsigned int i = 0; i < count; i++)
@@ -129,7 +124,7 @@
 			    unsigned advance_stride,
 			    void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
 
   for (unsigned int i = 0; i < count; i++)
@@ -148,7 +143,7 @@
 			  hb_position_t *y,
 			  void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
 
   *x = font->get_glyph_h_advance (glyph) / 2;
 
@@ -182,7 +177,7 @@
 			 hb_glyph_extents_t *extents,
 			 void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   bool ret = ot_face->sbix->get_extents (font, glyph, extents);
   if (!ret)
     ret = ot_face->glyf->get_extents (glyph, extents);
@@ -203,7 +198,7 @@
                       char *name, unsigned int size,
                       void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   return ot_face->post->get_glyph_name (glyph, name, size);
 }
 
@@ -214,7 +209,7 @@
                            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;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   return ot_face->post->get_glyph_from_name (name, len, glyph);
 }
 
@@ -224,7 +219,7 @@
 			  hb_font_extents_t *metrics,
 			  void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
   metrics->ascender = font->em_scale_y (hmtx.ascender);
   metrics->descender = font->em_scale_y (hmtx.descender);
@@ -239,7 +234,7 @@
 			  hb_font_extents_t *metrics,
 			  void *user_data HB_UNUSED)
 {
-  const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
+  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
   metrics->ascender = font->em_scale_x (vmtx.ascender);
   metrics->descender = font->em_scale_x (vmtx.descender);
@@ -305,11 +300,8 @@
 void
 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_face = hb_ot_face_data (font->face);
-
   hb_font_set_funcs (font,
 		     _hb_ot_get_font_funcs (),
-		     ot_face,
+		     &font->face->table,
 		     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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -102,7 +102,7 @@
   static bool
   _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
   {
-    hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source);
+    hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source);
     hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
     hb_blob_destroy (head_blob);
 
@@ -120,9 +120,9 @@
   struct GlyphHeader
   {
     HBINT16		numberOfContours;	/* If the number of contours is
-                                                 * greater than or equal to zero,
-                                                 * this is a simple glyph; if negative,
-                                                 * this is a composite glyph. */
+						 * greater than or equal to zero,
+						 * this is a simple glyph; if negative,
+						 * this is a composite glyph. */
     FWORD		xMin;			/* Minimum x for coordinate data. */
     FWORD		yMin;			/* Minimum y for coordinate data. */
     FWORD		xMax;			/* Maximum x for coordinate data. */
@@ -149,28 +149,23 @@
     };
 
     HBUINT16 flags;
-    HBUINT16 glyphIndex;
+    GlyphID  glyphIndex;
 
     inline unsigned int get_size (void) const
     {
       unsigned int size = min_size;
-      if (flags & ARG_1_AND_2_ARE_WORDS) {
-        // arg1 and 2 are int16
-        size += 4;
-      } else {
-        // arg1 and 2 are int8
-        size += 2;
-      }
-      if (flags & WE_HAVE_A_SCALE) {
-        // One x 16 bit (scale)
-        size += 2;
-      } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
-        // Two x 16 bit (xscale, yscale)
-        size += 4;
-      } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
-        // Four x 16 bit (xscale, scale01, scale10, yscale)
-        size += 8;
-      }
+      // arg1 and 2 are int16
+      if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
+      // arg1 and 2 are int8
+      else size += 2;
+
+      // One x 16 bit (scale)
+      if (flags & WE_HAVE_A_SCALE) size += 2;
+      // Two x 16 bit (xscale, yscale)
+      else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
+      // Four x 16 bit (xscale, scale01, scale10, yscale)
+      else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
+
       return size;
     }
 
@@ -198,7 +193,7 @@
       {
 	return (const char *) composite >= glyph_start
 	  && ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
-	  && ((const char *) composite + composite->get_size()) <= glyph_end;
+	  && ((const char *) composite + composite->get_size ()) <= glyph_end;
       }
     };
 
@@ -212,15 +207,15 @@
       const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0);
       if (glyph_header.numberOfContours < 0)
       {
-        const CompositeGlyphHeader *possible =
+	const CompositeGlyphHeader *possible =
 	  &StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
 
 	iterator->glyph_start = glyph_data;
 	iterator->glyph_end = (const char *) glyph_data + length;
 	if (!iterator->in_range (possible))
-          return false;
-        iterator->current = possible;
-        return true;
+	  return false;
+	iterator->current = possible;
+	return true;
       }
 
       return false;
@@ -235,30 +230,22 @@
     {
       memset (this, 0, sizeof (accelerator_t));
 
-      hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (face);
-      const head *head_table = head_blob->as<head> ();
-      if (head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
-      {
+      const OT::head &head = *face->table.head;
+      if (head.indexToLocFormat > 1 || head.glyphDataFormat != 0)
 	/* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
-	hb_blob_destroy (head_blob);
 	return;
-      }
-      short_offset = 0 == head_table->indexToLocFormat;
-      hb_blob_destroy (head_blob);
+      short_offset = 0 == head.indexToLocFormat;
 
-      loca_blob = hb_sanitize_context_t().reference_table<loca> (face);
-      loca_table = loca_blob->as<loca> ();
-      glyf_blob = hb_sanitize_context_t().reference_table<glyf> (face);
-      glyf_table = glyf_blob->as<glyf> ();
+      loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
+      glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
 
-      num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1;
-      glyf_len = hb_blob_get_length (glyf_blob);
+      num_glyphs = MAX (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
     }
 
     inline void fini (void)
     {
-      hb_blob_destroy (loca_blob);
-      hb_blob_destroy (glyf_blob);
+      loca_table.destroy ();
+      glyf_table.destroy ();
     }
 
     /*
@@ -274,7 +261,7 @@
 
       unsigned int start_offset, end_offset;
       if (!get_offsets (glyph, &start_offset, &end_offset))
-        return false; /* glyph not found */
+	return false; /* glyph not found */
 
       return CompositeGlyphHeader::get_iterator ((const char *) this->glyf_table + start_offset,
 						 end_offset - start_offset,
@@ -290,11 +277,10 @@
     };
 
     /* based on FontTools _g_l_y_f.py::trim */
-    inline bool remove_padding(unsigned int start_offset,
-                               unsigned int *end_offset) const
+    inline bool remove_padding (unsigned int start_offset,
+				unsigned int *end_offset) const
     {
-      if (*end_offset - start_offset < GlyphHeader::static_size)
-        return true;
+      if (*end_offset - start_offset < GlyphHeader::static_size) return true;
 
       const char *glyph = ((const char *) glyf_table) + start_offset;
       const char * const glyph_end = glyph + (*end_offset - start_offset);
@@ -302,74 +288,70 @@
       int16_t num_contours = (int16_t) glyph_header.numberOfContours;
 
       if (num_contours < 0)
-        /* Trimming for composites not implemented.
-         * If removing hints it falls out of that. */
-        return true;
+	/* Trimming for composites not implemented.
+	 * If removing hints it falls out of that. */
+	return true;
       else if (num_contours > 0)
       {
-        /* simple glyph w/contours, possibly trimmable */
-        glyph += GlyphHeader::static_size + 2 * num_contours;
+	/* simple glyph w/contours, possibly trimmable */
+	glyph += GlyphHeader::static_size + 2 * num_contours;
 
-        if (unlikely (glyph + 2 >= glyph_end)) return false;
-        uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16>(glyph - 2, 0) + 1;
-        uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16>(glyph, 0);
+	if (unlikely (glyph + 2 >= glyph_end)) return false;
+	uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
+	uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16> (glyph, 0);
 
-        glyph += 2 + nInstructions;
-        if (unlikely (glyph + 2 >= glyph_end)) return false;
+	glyph += 2 + nInstructions;
+	if (unlikely (glyph + 2 >= glyph_end)) return false;
 
-        unsigned int coordBytes = 0;
-        unsigned int coordsWithFlags = 0;
-        while (glyph < glyph_end)
-        {
-          uint8_t flag = (uint8_t) *glyph;
-          glyph++;
+	unsigned int coordBytes = 0;
+	unsigned int coordsWithFlags = 0;
+	while (glyph < glyph_end)
+	{
+	  uint8_t flag = (uint8_t) *glyph;
+	  glyph++;
 
-          unsigned int repeat = 1;
-          if (flag & FLAG_REPEAT)
-          {
-            if (glyph >= glyph_end)
-            {
-              DEBUG_MSG(SUBSET, nullptr, "Bad flag");
-              return false;
-            }
-            repeat = ((uint8_t) *glyph) + 1;
-            glyph++;
-          }
+	  unsigned int repeat = 1;
+	  if (flag & FLAG_REPEAT)
+	  {
+	    if (glyph >= glyph_end)
+	    {
+	      DEBUG_MSG(SUBSET, nullptr, "Bad flag");
+	      return false;
+	    }
+	    repeat = ((uint8_t) *glyph) + 1;
+	    glyph++;
+	  }
 
-          unsigned int xBytes, yBytes;
-          xBytes = yBytes = 0;
-          if (flag & FLAG_X_SHORT)
-            xBytes = 1;
-          else if ((flag & FLAG_X_SAME) == 0)
-            xBytes = 2;
+	  unsigned int xBytes, yBytes;
+	  xBytes = yBytes = 0;
+	  if (flag & FLAG_X_SHORT) xBytes = 1;
+	  else if ((flag & FLAG_X_SAME) == 0) xBytes = 2;
 
-          if (flag & FLAG_Y_SHORT)
-            yBytes = 1;
-          else if ((flag & FLAG_Y_SAME) == 0)
-            yBytes = 2;
+	  if (flag & FLAG_Y_SHORT) yBytes = 1;
+	  else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;
 
-          coordBytes += (xBytes + yBytes) * repeat;
-          coordsWithFlags += repeat;
-          if (coordsWithFlags >= nCoordinates)
-            break;
-        }
+	  coordBytes += (xBytes + yBytes) * repeat;
+	  coordsWithFlags += repeat;
+	  if (coordsWithFlags >= nCoordinates)
+	    break;
+	}
 
-        if (coordsWithFlags != nCoordinates)
-        {
-          DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags);
-          return false;
-        }
-        glyph += coordBytes;
+	if (coordsWithFlags != nCoordinates)
+	{
+	  DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags);
+	  return false;
+	}
+	glyph += coordBytes;
 
-        if (glyph < glyph_end)
-          *end_offset -= glyph_end - glyph;
+	if (glyph < glyph_end)
+	  *end_offset -= glyph_end - glyph;
       }
       return true;
     }
 
     inline bool get_offsets (hb_codepoint_t  glyph,
-                             unsigned int   *start_offset /* OUT */,
-                             unsigned int   *end_offset   /* OUT */) const
+			     unsigned int   *start_offset /* OUT */,
+			     unsigned int   *end_offset   /* OUT */) const
     {
       if (unlikely (glyph >= num_glyphs))
 	return false;
@@ -376,62 +358,62 @@
 
       if (short_offset)
       {
-        const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
+	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.arrayZ;
+	const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
 
 	*start_offset = offsets[glyph];
 	*end_offset   = offsets[glyph + 1];
       }
 
-      if (*start_offset > *end_offset || *end_offset > glyf_len)
+      if (*start_offset > *end_offset || *end_offset > glyf_table.get_length ())
 	return false;
 
       return true;
     }
 
-    inline bool get_instruction_offsets(unsigned int start_offset,
-                                        unsigned int end_offset,
-                                        unsigned int *instruction_start /* OUT */,
-                                        unsigned int *instruction_end /* OUT */) const
+    inline bool get_instruction_offsets (unsigned int start_offset,
+					 unsigned int end_offset,
+					 unsigned int *instruction_start /* OUT */,
+					 unsigned int *instruction_end /* OUT */) const
     {
       if (end_offset - start_offset < GlyphHeader::static_size)
       {
-        *instruction_start = 0;
-        *instruction_end = 0;
-        return true; /* Empty glyph; no instructions. */
+	*instruction_start = 0;
+	*instruction_end = 0;
+	return true; /* Empty glyph; no instructions. */
       }
       const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
       int16_t num_contours = (int16_t) glyph_header.numberOfContours;
       if (num_contours < 0)
       {
-        CompositeGlyphHeader::Iterator composite_it;
-        if (unlikely (!CompositeGlyphHeader::get_iterator (
-            (const char*) this->glyf_table + start_offset,
-             end_offset - start_offset, &composite_it))) return false;
-        const CompositeGlyphHeader *last;
-        do {
-          last = composite_it.current;
-        } while (composite_it.move_to_next());
+	CompositeGlyphHeader::Iterator composite_it;
+	if (unlikely (!CompositeGlyphHeader::get_iterator (
+	    (const char*) this->glyf_table + start_offset,
+	     end_offset - start_offset, &composite_it))) return false;
+	const CompositeGlyphHeader *last;
+	do {
+	  last = composite_it.current;
+	} while (composite_it.move_to_next ());
 
-        if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
-          *instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size();
-        else
-          *instruction_start = end_offset;
-        *instruction_end = end_offset;
-        if (unlikely (*instruction_start > *instruction_end))
-        {
-          DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset);
-          return false;
-        }
+	if ((uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
+	  *instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size ();
+	else
+	  *instruction_start = end_offset;
+	*instruction_end = end_offset;
+	if (unlikely (*instruction_start > *instruction_end))
+	{
+	  DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset);
+	  return false;
+	}
       }
       else
       {
-        unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
+	unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
 	if (unlikely (instruction_length_offset + 2 > end_offset))
 	{
 	  DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength.");
@@ -438,7 +420,7 @@
 	  return false;
 	}
 
-        const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
+	const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
 	unsigned int start = instruction_length_offset + 2;
 	unsigned int end = start + (uint16_t) instruction_length;
 	if (unlikely (end > end_offset)) // Out of bounds of the current glyph
@@ -448,7 +430,7 @@
 	}
 
 	*instruction_start = start;
-        *instruction_end = end;
+	*instruction_end = end;
       }
       return true;
     }
@@ -458,7 +440,7 @@
     {
       unsigned int start_offset, end_offset;
       if (!get_offsets (glyph, &start_offset, &end_offset))
-        return false;
+	return false;
 
       if (end_offset - start_offset < GlyphHeader::static_size)
 	return true; /* Empty glyph; zero extents. */
@@ -476,11 +458,8 @@
     private:
     bool short_offset;
     unsigned int num_glyphs;
-    hb_nonnull_ptr_t<const loca> loca_table;
-    hb_nonnull_ptr_t<const glyf> glyf_table;
-    hb_blob_t *loca_blob;
-    hb_blob_t *glyf_blob;
-    unsigned int glyf_len;
+    hb_blob_ptr_t<loca> loca_table;
+    hb_blob_ptr_t<glyf> glyf_table;
   };
 
   protected:

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -44,15 +44,15 @@
   struct SubsetView
   {
     const DeviceRecord *source_device_record;
-    unsigned int size_device_record;
+    unsigned int sizeDeviceRecord;
     hb_subset_plan_t *subset_plan;
 
-    inline void init(const DeviceRecord *source_device_record,
-		     unsigned int size_device_record,
-		     hb_subset_plan_t   *subset_plan)
+    inline void init (const DeviceRecord *source_device_record,
+		      unsigned int sizeDeviceRecord,
+		      hb_subset_plan_t   *subset_plan)
     {
       this->source_device_record = source_device_record;
-      this->size_device_record = size_device_record;
+      this->sizeDeviceRecord = sizeDeviceRecord;
       this->subset_plan = subset_plan;
     }
 
@@ -63,15 +63,12 @@
 
     inline const HBUINT8* operator [] (unsigned int i) const
     {
-      if (unlikely (i >= len())) return nullptr;
+      if (unlikely (i >= len ())) return nullptr;
       hb_codepoint_t gid = this->subset_plan->glyphs [i];
 
-      const HBUINT8* width = &(this->source_device_record->widthsZ[gid]);
-
-      if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record)
-	return width;
-      else
-	return nullptr;
+      if (gid >= sizeDeviceRecord - DeviceRecord::min_size)
+        return nullptr;
+      return &(this->source_device_record->widthsZ[gid]);
     }
   };
 
@@ -84,18 +81,18 @@
   {
     TRACE_SERIALIZE (this);
 
-    unsigned int size = get_size (subset_view.len());
+    unsigned int size = get_size (subset_view.len ());
     if (unlikely (!c->allocate_size<DeviceRecord> (size)))
     {
-      DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.",
-                 size);
+      DEBUG_MSG(SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.",
+		 size);
       return_trace (false);
     }
 
-    this->pixel_size.set (subset_view.source_device_record->pixel_size);
-    this->max_width.set (subset_view.source_device_record->max_width);
+    this->pixelSize.set (subset_view.source_device_record->pixelSize);
+    this->maxWidth.set (subset_view.source_device_record->maxWidth);
 
-    for (unsigned int i = 0; i < subset_view.len(); i++)
+    for (unsigned int i = 0; i < subset_view.len (); i++)
     {
       const HBUINT8 *width = subset_view[i];
       if (!width)
@@ -109,16 +106,16 @@
     return_trace (true);
   }
 
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int size_device_record) const
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int sizeDeviceRecord) const
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-			  c->check_range (this, size_device_record)));
+			  c->check_range (this, sizeDeviceRecord)));
   }
 
-  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). */
+  HBUINT8			pixelSize;	/* Pixel size for following widths (as ppem). */
+  HBUINT8			maxWidth;	/* Maximum width. */
+  UnsizedArrayOf<HBUINT8>	widthsZ;	/* Array of widths (numGlyphs is from the 'maxp' table). */
   public:
   DEFINE_SIZE_ARRAY (2, widthsZ);
 };
@@ -130,13 +127,15 @@
 
   inline unsigned int get_size (void) const
   {
-    return min_size + num_records * size_device_record;
+    return min_size + numRecords * sizeDeviceRecord;
   }
 
   inline const DeviceRecord& operator [] (unsigned int i) const
   {
-    if (unlikely (i >= num_records)) return Null(DeviceRecord);
-    return StructAtOffset<DeviceRecord> (&this->dataZ, i * size_device_record);
+    /* XXX Null(DeviceRecord) is NOT safe as it's num-glyphs lengthed.
+     * https://github.com/harfbuzz/harfbuzz/issues/1300 */
+    if (unlikely (i >= numRecords)) return Null (DeviceRecord);
+    return StructAtOffset<DeviceRecord> (&this->firstDeviceRecord, i * sizeDeviceRecord);
   }
 
   inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
@@ -146,13 +145,13 @@
     if (unlikely (!c->extend_min ((*this))))  return_trace (false);
 
     this->version.set (source_hdmx->version);
-    this->num_records.set (source_hdmx->num_records);
-    this->size_device_record.set (DeviceRecord::get_size (plan->glyphs.len));
+    this->numRecords.set (source_hdmx->numRecords);
+    this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->glyphs.len));
 
-    for (unsigned int i = 0; i < source_hdmx->num_records; i++)
+    for (unsigned int i = 0; i < source_hdmx->numRecords; i++)
     {
       DeviceRecord::SubsetView subset_view;
-      subset_view.init (&(*source_hdmx)[i], source_hdmx->size_device_record, plan);
+      subset_view.init (&(*source_hdmx)[i], source_hdmx->sizeDeviceRecord, plan);
 
       if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view))
 	return_trace (false);
@@ -163,7 +162,7 @@
 
   static inline size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan)
   {
-    return min_size + source_hdmx->num_records * DeviceRecord::get_size (plan->glyphs.len);
+    return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->glyphs.len);
   }
 
   inline bool subset (hb_subset_plan_t *plan) const
@@ -200,19 +199,19 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && version == 0 &&
-		  !hb_unsigned_mul_overflows (num_records, size_device_record) &&
-		  size_device_record >= DeviceRecord::min_size &&
-		  c->check_range (this, get_size()));
+    return_trace (c->check_struct (this) &&
+		  !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
+		  sizeDeviceRecord >= DeviceRecord::min_size &&
+		  c->check_range (this, get_size ()));
   }
 
   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. */
-  UnsizedArrayOf<HBUINT8>	dataZ;			/* Array of device records. */
+  HBUINT16		version;		/* Table version number (0) */
+  HBUINT16		numRecords;		/* Number of device records. */
+  HBUINT32		sizeDeviceRecord;	/* Size of a device record, 32-bit aligned. */
+  DeviceRecord		firstDeviceRecord;	/* Array of device records. */
   public:
-  DEFINE_SIZE_ARRAY (8, dataZ);
+  DEFINE_SIZE_MIN (8);
 };
 
 } /* 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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -66,10 +66,10 @@
 
 
   inline bool subset_update_header (hb_subset_plan_t *plan,
-                                    unsigned int num_hmetrics) const
+				    unsigned int num_hmetrics) const
   {
-    hb_blob_t *src_blob = hb_sanitize_context_t().reference_table<H> (plan->source, H::tableTag);
-    hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail(src_blob);
+    hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (plan->source, H::tableTag);
+    hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
     hb_blob_destroy (src_blob);
 
     if (unlikely (!dest_blob)) {
@@ -96,8 +96,8 @@
     hb_vector_t<hb_codepoint_t> &gids = plan->glyphs;
     unsigned int num_advances = gids.len;
     unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]);
-    while (num_advances > 1
-        && last_advance == _mtx.get_advance (gids[num_advances - 2]))
+    while (num_advances > 1 &&
+	   last_advance == _mtx.get_advance (gids[num_advances - 2]))
     {
       num_advances--;
     }
@@ -104,7 +104,7 @@
 
     /* alloc the new table */
     size_t dest_sz = num_advances * 4
-                  + (gids.len - num_advances) * 2;
+		  + (gids.len - num_advances) * 2;
     void *dest = (void *) malloc (dest_sz);
     if (unlikely (!dest))
     {
@@ -113,7 +113,7 @@
     DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in src has %d advances, %d lsbs", HB_UNTAG(T::tableTag), _mtx.num_advances, _mtx.num_metrics - _mtx.num_advances);
     DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in dest has %d advances, %d lsbs, %u bytes", HB_UNTAG(T::tableTag), num_advances, gids.len - num_advances, (unsigned int) dest_sz);
 
-    const char *source_table = hb_blob_get_data (_mtx.blob, nullptr);
+    const char *source_table = hb_blob_get_data (_mtx.table.get_blob (), nullptr);
     // Copy everything over
     LongMetric * old_metrics = (LongMetric *) source_table;
     FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances);
@@ -194,17 +194,14 @@
       bool got_font_extents = false;
       if (T::os2Tag)
       {
-	hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table<OS2> (face);
-	const OS2 *os2_table = os2_blob->as<OS2> ();
 #define USE_TYPO_METRICS (1u<<7)
-	if (0 != (os2_table->fsSelection & USE_TYPO_METRICS))
+	if (0 != (face->table.OS2->fsSelection & USE_TYPO_METRICS))
 	{
-	  ascender = abs (os2_table->sTypoAscender);
-	  descender = -abs (os2_table->sTypoDescender);
-	  line_gap = os2_table->sTypoLineGap;
+	  ascender = abs (face->table.OS2->sTypoAscender);
+	  descender = -abs (face->table.OS2->sTypoDescender);
+	  line_gap = face->table.OS2->sTypoLineGap;
 	  got_font_extents = (ascender | descender) != 0;
 	}
-	hb_blob_destroy (os2_blob);
       }
 
       hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table<H> (face);
@@ -221,10 +218,10 @@
 
       has_font_extents = got_font_extents;
 
-      blob = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag);
+      table = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag);
 
       /* Cap num_metrics() and num_advances() based on table length. */
-      unsigned int len = hb_blob_get_length (blob);
+      unsigned int len = table.get_length ();
       if (unlikely (num_advances * 4 > len))
 	num_advances = len / 4;
       num_metrics = num_advances + (len - 4 * num_advances) / 2;
@@ -234,19 +231,17 @@
       if (unlikely (!num_advances))
       {
 	num_metrics = num_advances = 0;
-	hb_blob_destroy (blob);
-	blob = hb_blob_get_empty ();
+	table.destroy ();
+	table = hb_blob_get_empty ();
       }
-      table = blob->as<hmtxvmtx> ();
 
-      var_blob = hb_sanitize_context_t().reference_table<HVARVVAR> (face, T::variationsTag);
-      var_table = var_blob->as<HVARVVAR> ();
+      var_table = hb_sanitize_context_t().reference_table<HVARVVAR> (face, T::variationsTag);
     }
 
     inline void fini (void)
     {
-      hb_blob_destroy (blob);
-      hb_blob_destroy (var_blob);
+      table.destroy ();
+      var_table.destroy ();
     }
 
     /* TODO Add variations version. */
@@ -282,7 +277,7 @@
                                      hb_font_t      *font) const
     {
       unsigned int advance = get_advance (glyph);
-      if (likely(glyph < num_metrics))
+      if (likely (glyph < num_metrics))
       {
 	advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
       }
@@ -291,9 +286,9 @@
 
     public:
     bool has_font_extents;
-    unsigned short ascender;
-    unsigned short descender;
-    unsigned short line_gap;
+    int ascender;
+    int descender;
+    int line_gap;
 
     protected:
     unsigned int num_metrics;
@@ -301,10 +296,8 @@
     unsigned int default_advance;
 
     private:
-    const hmtxvmtx *table;
-    hb_blob_t *blob;
-    const HVARVVAR *var_table;
-    hb_blob_t *var_blob;
+    hb_blob_ptr_t<hmtxvmtx> table;
+    hb_blob_ptr_t<HVARVVAR> var_table;
   };
 
   protected:

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -27,91 +27,9 @@
 #ifndef HB_OT_KERN_TABLE_HH
 #define HB_OT_KERN_TABLE_HH
 
-#include "hb-open-type.hh"
-#include "hb-ot-shape.hh"
-#include "hb-ot-layout-gsubgpos.hh"
-#include "hb-aat-layout-common.hh"
+#include "hb-aat-layout-kerx-table.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
@@ -123,290 +41,7 @@
 namespace OT {
 
 
-struct hb_glyph_pair_t
-{
-  hb_codepoint_t left;
-  hb_codepoint_t right;
-};
-
-struct KernPair
-{
-  inline int get_kerning (void) const
-  { return value; }
-
-  inline int cmp (const hb_glyph_pair_t &o) const
-  {
-    int ret = left.cmp (o.left);
-    if (ret) return ret;
-    return right.cmp (o.right);
-  }
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  protected:
-  GlyphID	left;
-  GlyphID	right;
-  FWORD		value;
-  public:
-  DEFINE_SIZE_STATIC (6);
-};
-
-struct KernSubTableFormat0
-{
-  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 bool apply (AAT::hb_aat_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-
-    if (!c->plan->requested_kerning)
-      return false;
-
-    hb_kern_machine_t<KernSubTableFormat0> 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 (pairs.sanitize (c));
-  }
-
-  protected:
-  BinSearchArrayOf<KernPair> pairs;	/* Array of kerning pairs. */
-  public:
-  DEFINE_SIZE_ARRAY (8, pairs);
-};
-
-struct KernSubTableFormat1
-{
-  typedef void EntryData;
-
-  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. */
-      Offset		= 0x3FFF,	/* Byte offset from beginning of subtable to the
-					 * value table for the glyphs on the kerning stack. */
-    };
-
-    inline driver_context_t (const KernSubTableFormat1 *table_,
-			     AAT::hb_aat_apply_context_t *c_) :
-	c (c_),
-	table (table_),
-	/* 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 (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver HB_UNUSED,
-			       const AAT::Entry<EntryData> *entry)
-    {
-      return entry->flags & Offset;
-    }
-    inline bool transition (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver,
-			    const AAT::Entry<EntryData> *entry)
-    {
-      hb_buffer_t *buffer = driver->buffer;
-      unsigned int flags = entry->flags;
-
-      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->flags & Offset)
-      {
-	unsigned int kernIndex = AAT::MortTypes::offsetToIndex (entry->flags & Offset, &table->machine, kernAction.arrayZ);
-	const FWORD *actions = &kernAction[kernIndex];
-	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)
-	  {
-	    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
-	    {
-	      buffer->pos[idx].x_advance += c->font->em_scale_x (v);
-	      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
-		buffer->pos[idx].x_offset += c->font->em_scale_x (v);
-	    }
-	    else
-	    {
-	      buffer->pos[idx].y_advance += c->font->em_scale_y (v);
-	      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
-		buffer->pos[idx].y_offset += c->font->em_scale_y (v);
-	    }
-	  }
-	}
-	depth = 0;
-      }
-
-      return true;
-    }
-
-    private:
-    AAT::hb_aat_apply_context_t *c;
-    const KernSubTableFormat1 *table;
-    const UnsizedArrayOf<FWORD> &kernAction;
-    unsigned int stack[8];
-    unsigned int depth;
-  };
-
-  inline bool apply (AAT::hb_aat_apply_context_t *c) const
-  {
-    TRACE_APPLY (this);
-
-    if (!c->plan->requested_kerning)
-      return false;
-
-    driver_context_t dc (this, c);
-
-    AAT::StateTableDriver<AAT::MortTypes, 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) &&
-			  machine.sanitize (c)));
-  }
-
-  protected:
-  AAT::StateTable<AAT::MortTypes, EntryData>		machine;
-  OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false>	kernAction;
-  public:
-  DEFINE_SIZE_STATIC (10);
-};
-
-struct KernClassTable
-{
-  inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  classes.sanitize (c));
-  }
-
-  protected:
-  HBUINT16		firstGlyph;	/* First glyph in class range. */
-  ArrayOf<HBUINT16>	classes;	/* Glyph classes. */
-  public:
-  DEFINE_SIZE_ARRAY (4, classes);
-};
-
-struct KernSubTableFormat2
-{
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
-			  AAT::hb_aat_apply_context_t *c) 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. */
-    return 0;
-    unsigned int l = (this+leftClassTable).get_class (left);
-    unsigned int r = (this+rightClassTable).get_class (right);
-    unsigned int offset = l + r;
-    const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
-#if 0
-    if (unlikely ((const char *) v < (const char *) &array ||
-		  (const char *) v > (const char *) end - 2))
-#endif
-      return 0;
-    return *v;
-  }
-
-  inline bool apply (AAT::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);
-  }
-
-  struct accelerator_t
-  {
-    const KernSubTableFormat2 &table;
-    AAT::hb_aat_apply_context_t *c;
-
-    inline accelerator_t (const KernSubTableFormat2 &table_,
-			  AAT::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); }
-  };
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (true); /* Disabled.  See above. */
-    return_trace (c->check_struct (this) &&
-		  leftClassTable.sanitize (c, this) &&
-		  rightClassTable.sanitize (c, this) &&
-		  array.sanitize (c, this));
-  }
-
-  protected:
-  HBUINT16	rowWidth;	/* The width, in bytes, of a row in the table. */
-  OffsetTo<KernClassTable>
-		leftClassTable;	/* Offset from beginning of this subtable to
-				 * left-hand class table. */
-  OffsetTo<KernClassTable>
-		rightClassTable;/* Offset from beginning of this subtable to
-				 * right-hand class table. */
-  OffsetTo<FWORD>
-		array;		/* Offset from beginning of this subtable to
-				 * the start of the kerning array. */
-  public:
-  DEFINE_SIZE_MIN (8);
-};
-
+template <typename KernSubTableHeader>
 struct KernSubTableFormat3
 {
   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
@@ -431,7 +66,10 @@
     if (!c->plan->requested_kerning)
       return false;
 
-    hb_kern_machine_t<KernSubTableFormat3> machine (*this);
+    if (header.coverage & header.Backwards)
+      return false;
+
+    hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
     machine.kern (c->font, c->buffer, c->plan->kern_mask);
 
     return_trace (true);
@@ -448,34 +86,35 @@
   }
 
   protected:
-  HBUINT16	glyphCount;	/* The number of glyphs in this font. */
-  HBUINT8	kernValueCount;	/* The number of kerning values. */
-  HBUINT8	leftClassCount;	/* The number of left-hand classes. */
-  HBUINT8	rightClassCount;/* The number of right-hand classes. */
-  HBUINT8	flags;		/* Set to zero (reserved for future use). */
-  UnsizedArrayOf<FWORD>
-		kernValueZ;	/* The kerning values.
-				 * Length kernValueCount. */
+  KernSubTableHeader	header;
+  HBUINT16		glyphCount;	/* The number of glyphs in this font. */
+  HBUINT8		kernValueCount;	/* The number of kerning values. */
+  HBUINT8		leftClassCount;	/* The number of left-hand classes. */
+  HBUINT8		rightClassCount;/* The number of right-hand classes. */
+  HBUINT8		flags;		/* Set to zero (reserved for future use). */
+  UnsizedArrayOf<FWORD>	kernValueZ;	/* The kerning values.
+					 * Length kernValueCount. */
 #if 0
-  UnsizedArrayOf<HBUINT8>
-		leftClass;	/* The left-hand classes.
-				 * Length glyphCount. */
-  UnsizedArrayOf<HBUINT8>
-		RightClass;	/* The right-hand classes.
-				 * Length glyphCount. */
-  UnsizedArrayOf<HBUINT8>
-		kernIndex;	/* The indices into the kernValue array.
-				 * Length leftClassCount * rightClassCount */
+  UnsizedArrayOf<HBUINT8>leftClass;	/* The left-hand classes.
+					 * Length glyphCount. */
+  UnsizedArrayOf<HBUINT8>rightClass;	/* The right-hand classes.
+					 * Length glyphCount. */
+  UnsizedArrayOf<HBUINT8>kernIndex;	/* The indices into the kernValue array.
+					 * Length leftClassCount * rightClassCount */
 #endif
   public:
-  DEFINE_SIZE_ARRAY (6, kernValueZ);
+  DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
 };
 
+template <typename KernSubTableHeader>
 struct KernSubTable
 {
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int format) const
+  inline unsigned int get_size (void) const { return u.header.length; }
+  inline unsigned int get_type (void) const { return u.header.format; }
+
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
-    switch (format) {
+    switch (get_type ()) {
     /* This method hooks up to hb_font_t's get_h_kerning.  Only support Format0. */
     case 0: return u.format0.get_kerning (left, right);
     default:return 0;
@@ -482,36 +121,37 @@
     }
   }
 
-  inline void apply (AAT::hb_aat_apply_context_t *c, unsigned int format) const
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
   {
-    /* TODO Switch to dispatch(). */
-    switch (format) {
-    case 0: u.format0.apply (c); return;
-    case 1: u.format1.apply (c); return;
-    case 2: u.format2.apply (c); return;
-    case 3: u.format3.apply (c); return;
-    default:			 return;
+    unsigned int subtable_type = get_type ();
+    TRACE_DISPATCH (this, subtable_type);
+    switch (subtable_type) {
+    case 0:	return_trace (c->dispatch (u.format0));
+    case 1:	return_trace (u.header.apple ? c->dispatch (u.format1) : c->default_return_value ());
+    case 2:	return_trace (c->dispatch (u.format2));
+    case 3:	return_trace (u.header.apple ? c->dispatch (u.format3) : c->default_return_value ());
+    default:	return_trace (c->default_return_value ());
     }
   }
 
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
+  inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    switch (format) {
-    case 0: return_trace (u.format0.sanitize (c));
-    case 1: return_trace (u.format1.sanitize (c));
-    case 2: return_trace (u.format2.sanitize (c));
-    case 3: return_trace (u.format3.sanitize (c));
-    default:return_trace (true);
-    }
+    if (unlikely (!u.header.sanitize (c) ||
+		  u.header.length < u.header.min_size ||
+		  !c->check_range (this, u.header.length))) return_trace (false);
+
+    return_trace (dispatch (c));
   }
 
-  protected:
+  public:
   union {
-  KernSubTableFormat0	format0;
-  KernSubTableFormat1	format1;
-  KernSubTableFormat2	format2;
-  KernSubTableFormat3	format3;
+  KernSubTableHeader				header;
+  AAT::KerxSubTableFormat0<KernSubTableHeader>	format0;
+  AAT::KerxSubTableFormat1<KernSubTableHeader>	format1;
+  AAT::KerxSubTableFormat2<KernSubTableHeader>	format2;
+  KernSubTableFormat3<KernSubTableHeader>	format3;
   } u;
   public:
   DEFINE_SIZE_MIN (0);
@@ -518,204 +158,113 @@
 };
 
 
-template <typename T>
-struct KernSubTableWrapper
+struct KernOTSubTableHeader
 {
-  /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
-  inline const T* thiz (void) const { return static_cast<const T *> (this); }
+  static const bool apple = false;
+  typedef AAT::ObsoleteTypes Types;
 
-  inline bool is_supported (void) const
-  { return !(thiz()->coverage & T::CheckFlags); }
+  inline unsigned int tuple_count (void) const { return 0; }
+  inline bool is_horizontal (void) const { return (coverage & Horizontal); }
 
-  inline bool is_horizontal (void) const
-  { return (thiz()->coverage & T::Direction) == T::CheckHorizontal; }
+  enum Coverage
+  {
+    Horizontal	= 0x01u,
+    Minimum	= 0x02u,
+    CrossStream	= 0x04u,
+    Override	= 0x08u,
 
-  inline bool is_override (void) const
-  { return bool (thiz()->coverage & T::Override); }
+    /* Not supported: */
+    Backwards	= 0x00u,
+    Variation	= 0x00u,
+  };
 
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-  { return thiz()->subtable.get_kerning (left, right, thiz()->format); }
-
-  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-  { return is_supported () && is_horizontal () ? get_kerning (left, right) : 0; }
-
-  inline void apply (AAT::hb_aat_apply_context_t *c) const
-  { thiz()->subtable.apply (c, thiz()->format); }
-
-  inline unsigned int get_size (void) const { return thiz()->length; }
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (thiz()) &&
-		  thiz()->length >= T::min_size &&
-		  c->check_range (thiz(), thiz()->length) &&
-		  thiz()->subtable.sanitize (c, thiz()->format));
+    return_trace (c->check_struct (this));
   }
+
+  public:
+  HBUINT16	versionZ;	/* Unused. */
+  HBUINT16	length;		/* Length of the subtable (including this header). */
+  HBUINT8	format;		/* Subtable format. */
+  HBUINT8	coverage;	/* Coverage bits. */
+  public:
+  DEFINE_SIZE_STATIC (6);
 };
 
-template <typename T>
-struct KernTable
+struct KernOT : AAT::KerxTable<KernOT>
 {
-  /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
-  inline const T* thiz (void) const { return static_cast<const T *> (this); }
+  friend struct AAT::KerxTable<KernOT>;
 
-  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()->dataZ);
-    unsigned int count = thiz()->nTables;
-    for (unsigned int i = 0; i < count; i++)
-    {
-      if (st->is_supported () && st->is_override ())
-        v = 0;
-      v += st->get_h_kerning (left, right);
-      st = &StructAfter<typename T::SubTableWrapper> (*st);
-    }
-    return v;
-  }
+  static const hb_tag_t tableTag = HB_OT_TAG_kern;
+  static const uint16_t minVersion = 0;
 
-  inline void apply (AAT::hb_aat_apply_context_t *c) const
-  {
-    c->set_lookup_index (0);
-    const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
-    unsigned int count = thiz()->nTables;
-    /* If there's an override subtable, skip subtables before that. */
-    unsigned int last_override = 0;
-    for (unsigned int i = 0; i < count; i++)
-    {
-      if (st->is_supported () && st->is_override ())
-        last_override = i;
-      st = &StructAfter<typename T::SubTableWrapper> (*st);
-    }
-    st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
-    for (unsigned int i = 0; i < count; i++)
-    {
-      if (!st->is_supported ())
-        goto skip;
+  typedef KernOTSubTableHeader SubTableHeader;
+  typedef SubTableHeader::Types Types;
+  typedef KernSubTable<SubTableHeader> SubTable;
 
-      if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->is_horizontal ())
-	goto skip;
+  protected:
+  HBUINT16	version;	/* Version--0x0000u */
+  HBUINT16	tableCount;	/* Number of subtables in the kerning table. */
+  SubTable	firstSubTable;	/* Subtables. */
+  public:
+  DEFINE_SIZE_MIN (4);
+};
 
-      if (i < last_override)
-	goto skip;
 
-      if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index))
-	goto skip;
+struct KernAATSubTableHeader
+{
+  static const bool apple = true;
+  typedef AAT::ObsoleteTypes Types;
 
-      c->sanitizer.set_object (*st);
+  inline unsigned int tuple_count (void) const { return 0; }
+  inline bool is_horizontal (void) const { return !(coverage & Vertical); }
 
-      st->apply (c);
+  enum Coverage
+  {
+    Vertical	= 0x80u,
+    CrossStream	= 0x40u,
+    Variation	= 0x20u,
 
-      (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index);
+    /* Not supported: */
+    Backwards	= 0x00u,
+  };
 
-    skip:
-      st = &StructAfter<typename T::SubTableWrapper> (*st);
-    }
-  }
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!c->check_struct (thiz()) ||
-		  thiz()->version != T::VERSION))
-      return_trace (false);
-
-    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 (unlikely (!st->sanitize (c)))
-	return_trace (false);
-      st = &StructAfter<typename T::SubTableWrapper> (*st);
-    }
-
-    return_trace (true);
+    return_trace (c->check_struct (this));
   }
-};
 
-struct KernOT : KernTable<KernOT>
-{
-  friend struct KernTable<KernOT>;
-
-  static const uint16_t VERSION = 0x0000u;
-
-  struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
-  {
-    friend struct KernTable<KernOT>;
-    friend struct KernSubTableWrapper<SubTableWrapper>;
-
-    enum Coverage
-    {
-      Direction		= 0x01u,
-      Minimum		= 0x02u,
-      CrossStream	= 0x04u,
-      Override		= 0x08u,
-
-      Variation		= 0x00u, /* Not supported. */
-
-      CheckFlags	= 0x06u,
-      CheckHorizontal	= 0x01u
-    };
-
-    protected:
-    HBUINT16	versionZ;	/* Unused. */
-    HBUINT16	length;		/* Length of the subtable (including this header). */
-    HBUINT8	format;		/* Subtable format. */
-    HBUINT8	coverage;	/* Coverage bits. */
-    KernSubTable subtable;	/* Subtable data. */
-    public:
-    DEFINE_SIZE_MIN (6);
-  };
-
-  protected:
-  HBUINT16			version;	/* Version--0x0000u */
-  HBUINT16			nTables;	/* Number of subtables in the kerning table. */
-  UnsizedArrayOf<HBUINT8>	dataZ;
   public:
-  DEFINE_SIZE_ARRAY (4, dataZ);
+  HBUINT32	length;		/* Length of the subtable (including this header). */
+  HBUINT8	coverage;	/* Coverage bits. */
+  HBUINT8	format;		/* Subtable format. */
+  HBUINT16	tupleIndex;	/* The tuple index (used for variations fonts).
+			       * This value specifies which tuple this subtable covers.
+			       * Note: We don't implement. */
+  public:
+  DEFINE_SIZE_STATIC (8);
 };
 
-struct KernAAT : KernTable<KernAAT>
+struct KernAAT : AAT::KerxTable<KernAAT>
 {
-  friend struct KernTable<KernAAT>;
+  friend struct AAT::KerxTable<KernAAT>;
 
-  static const uint32_t VERSION = 0x00010000u;
+  static const hb_tag_t tableTag = HB_OT_TAG_kern;
+  static const uint32_t minVersion = 0x00010000u;
 
-  struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
-  {
-    friend struct KernTable<KernAAT>;
-    friend struct KernSubTableWrapper<SubTableWrapper>;
+  typedef KernAATSubTableHeader SubTableHeader;
+  typedef SubTableHeader::Types Types;
+  typedef KernSubTable<SubTableHeader> SubTable;
 
-    enum Coverage
-    {
-      Direction		= 0x80u,
-      CrossStream	= 0x40u,
-      Variation		= 0x20u,
-
-      Override		= 0x00u, /* Not supported. */
-
-      CheckFlags	= 0x60u,
-      CheckHorizontal	= 0x00u
-    };
-
-    protected:
-    HBUINT32	length;		/* Length of the subtable (including this header). */
-    HBUINT8	coverage;	/* Coverage bits. */
-    HBUINT8	format;		/* Subtable format. */
-    HBUINT16	tupleIndex;	/* The tuple index (used for variations fonts).
-				 * This value specifies which tuple this subtable covers. */
-    KernSubTable subtable;	/* Subtable data. */
-    public:
-    DEFINE_SIZE_MIN (8);
-  };
-
   protected:
-  HBUINT32			version;	/* Version--0x00010000u */
-  HBUINT32			nTables;	/* Number of subtables in the kerning table. */
-  UnsizedArrayOf<HBUINT8>	dataZ;
+  HBUINT32	version;	/* Version--0x00010000u */
+  HBUINT32	tableCount;	/* Number of subtables in the kerning table. */
+  SubTable	firstSubTable;	/* Subtables. */
   public:
-  DEFINE_SIZE_ARRAY (8, dataZ);
+  DEFINE_SIZE_MIN (8);
 };
 
 struct kern
@@ -722,12 +271,21 @@
 {
   static const hb_tag_t tableTag = HB_OT_TAG_kern;
 
-  inline bool has_data (void) const
-  { return u.version32 != 0; }
+  inline bool has_data (void) const { return u.version32; }
+  inline unsigned int get_type (void) const { return u.major; }
 
+  inline bool has_cross_stream (void) const
+  {
+    switch (get_type ()) {
+    case 0: return u.ot.has_cross_stream ();
+    case 1: return u.aat.has_cross_stream ();
+    default:return false;
+    }
+  }
+
   inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
-    switch (u.major) {
+    switch (get_type ()) {
     case 0: return u.ot.get_h_kerning (left, right);
     case 1: return u.aat.get_h_kerning (left, right);
     default:return 0;
@@ -734,13 +292,18 @@
     }
   }
 
-  inline void apply (AAT::hb_aat_apply_context_t *c) const
+  inline bool apply (AAT::hb_aat_apply_context_t *c) const
+  { return dispatch (c); }
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
   {
-    /* TODO Switch to dispatch(). */
-    switch (u.major) {
-    case 0: u.ot.apply (c);  return;
-    case 1: u.aat.apply (c); return;
-    default:		     return;
+    unsigned int subtable_type = get_type ();
+    TRACE_DISPATCH (this, subtable_type);
+    switch (subtable_type) {
+    case 0:	return_trace (c->dispatch (u.ot));
+    case 1:	return_trace (c->dispatch (u.aat));
+    default:	return_trace (c->default_return_value ());
     }
   }
 
@@ -748,11 +311,7 @@
   {
     TRACE_SANITIZE (this);
     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));
-    default:return_trace (true);
-    }
+    return_trace (dispatch (c));
   }
 
   protected:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -198,6 +198,7 @@
 			   const BaseCoord **min,
 			   const BaseCoord **max) const
   {
+    /* TODO Replace hb_bsearch() with .bsearch(). */
     const FeatMinMaxRecord *minMaxCoord = (const FeatMinMaxRecord *)
 					  hb_bsearch (&feature_tag, featMinMaxRecords.arrayZ,
 						      featMinMaxRecords.len,
@@ -230,7 +231,7 @@
 		maxCoord;	/* Offset to BaseCoord table that defines
 				 * maximum extent value, from the beginning
 				 * of MinMax table (may be NULL) */
-  ArrayOf<FeatMinMaxRecord>
+  SortedArrayOf<FeatMinMaxRecord>
 		featMinMaxRecords;
 				/* Array of FeatMinMaxRecords, in alphabetical
 				 * order by featureTableTag */
@@ -302,6 +303,7 @@
 {
   inline const MinMax &get_min_max (hb_tag_t language_tag) const
   {
+    /* TODO Replace hb_bsearch() with .bsearch(). */
     const BaseLangSysRecord* record = (const BaseLangSysRecord *)
 				      hb_bsearch (&language_tag, baseLangSysRecords.arrayZ,
 						  baseLangSysRecords.len,
@@ -332,7 +334,7 @@
   OffsetTo<MinMax>
 		defaultMinMax;	/* Offset to MinMax table, from beginning of
 				 * BaseScript table (may be NULL) */
-  ArrayOf<BaseLangSysRecord>
+  SortedArrayOf<BaseLangSysRecord>
 		baseLangSysRecords;
 				/* Number of BaseLangSysRecords
 				 * defined — may be zero (0) */
@@ -377,6 +379,7 @@
 {
   inline const BaseScriptRecord *find_record (hb_tag_t script) const
   {
+    /* TODO Replace hb_bsearch() with .bsearch(). */
     return (const BaseScriptRecord *) hb_bsearch (&script, baseScriptRecords.arrayZ,
 						  baseScriptRecords.len,
 						  BaseScriptRecord::static_size,
@@ -400,7 +403,7 @@
   }
 
   protected:
-  ArrayOf<BaseScriptRecord>
+  SortedArrayOf<BaseScriptRecord>
 			baseScriptRecords;
 
   public:

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -131,8 +131,8 @@
     /* If we want to allow non-sorted data, we can lsearch(). */
     int i = this->/*lsearch*/bsearch (tag);
     if (i != -1) {
-        if (index) *index = i;
-        return true;
+      if (index) *index = i;
+      return true;
     } else {
       if (index) *index = Index::NOT_FOUND_INDEX;
       return false;
@@ -526,7 +526,7 @@
   {
     if (tag == HB_TAG ('s','i','z','e'))
       return u.size;
-    return Null(FeatureParamsSize);
+    return Null (FeatureParamsSize);
   }
 
   inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
@@ -533,7 +533,7 @@
   {
     if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
       return u.stylisticSet;
-    return Null(FeatureParamsStylisticSet);
+    return Null (FeatureParamsStylisticSet);
   }
 
   inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
@@ -540,7 +540,7 @@
   {
     if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
       return u.characterVariants;
-    return Null(FeatureParamsCharacterVariants);
+    return Null (FeatureParamsCharacterVariants);
   }
 
   private:
@@ -704,7 +704,7 @@
     for (unsigned int i = 0; i < count; i++) {
       typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type);
       if (c->stop_sublookup_iteration (r))
-        return_trace (r);
+	return_trace (r);
     }
     return_trace (c->default_return_value ());
   }
@@ -790,7 +790,7 @@
       unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
       unsigned int count = get_subtable_count ();
       for (unsigned int i = 1; i < count; i++)
-        if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
+	if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
 	  return_trace (false);
     }
     return_trace (true);
@@ -854,7 +854,7 @@
     unsigned int count = glyphArray.len;
     for (unsigned int i = 0; i < count; i++)
       if (glyphs->has (glyphArray[i]))
-        return true;
+	return true;
     return false;
   }
   inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
@@ -920,7 +920,7 @@
     unsigned int num_ranges = 1;
     for (unsigned int i = 1; i < num_glyphs; i++)
       if (glyphs[i - 1] + 1 != glyphs[i])
-        num_ranges++;
+	num_ranges++;
     rangeRecord.len.set (num_ranges);
     if (unlikely (!c->extend (rangeRecord))) return_trace (false);
 
@@ -932,9 +932,9 @@
 	range++;
 	rangeRecord[range].start = glyphs[i];
 	rangeRecord[range].value.set (i);
-        rangeRecord[range].end = glyphs[i];
+	rangeRecord[range].end = glyphs[i];
       } else {
-        rangeRecord[range].end = glyphs[i];
+	rangeRecord[range].end = glyphs[i];
       }
     glyphs += num_glyphs;
     return_trace (true);
@@ -952,7 +952,7 @@
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
       if (rangeRecord[i].intersects (glyphs))
-        return true;
+	return true;
     return false;
   }
   inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
@@ -964,9 +964,9 @@
       if (range.value <= index &&
 	  index < (unsigned int) range.value + (range.end - range.start) &&
 	  range.intersects (glyphs))
-        return true;
+	return true;
       else if (index < range.value)
-        return false;
+	return false;
     }
     return false;
   }
@@ -976,7 +976,7 @@
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
-        return false;
+	return false;
     return true;
   }
 
@@ -992,8 +992,8 @@
       j = c->rangeRecord.len ? c->rangeRecord[0].start : 0;
       if (unlikely (c->rangeRecord[0].start > c->rangeRecord[0].end))
       {
-        /* Broken table. Skip. */
-        i = c->rangeRecord.len;
+	/* Broken table. Skip. */
+	i = c->rangeRecord.len;
       }
     }
     inline void fini (void) {}
@@ -1002,7 +1002,7 @@
     {
       if (j >= c->rangeRecord[i].end)
       {
-        i++;
+	i++;
 	if (more ())
 	{
 	  hb_codepoint_t old = j;
@@ -1060,7 +1060,7 @@
     unsigned int num_ranges = 1;
     for (unsigned int i = 1; i < num_glyphs; i++)
       if (glyphs[i - 1] + 1 != glyphs[i])
-        num_ranges++;
+	num_ranges++;
     u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2);
     switch (u.format)
     {
@@ -1213,7 +1213,7 @@
     for (unsigned int i = 0; i < count; i++)
     {
       if (classValue[i])
-        continue;
+	continue;
 
       if (start != i)
 	if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i)))
@@ -1232,10 +1232,7 @@
   inline bool add_class (set_t *glyphs, unsigned int klass) const {
     unsigned int count = classValue.len;
     for (unsigned int i = 0; i < count; i++)
-    {
-      if (classValue[i] == klass)
-        glyphs->add (startGlyph + i);
-    }
+      if (classValue[i] == klass) glyphs->add (startGlyph + i);
     return true;
   }
 
@@ -1246,8 +1243,7 @@
     hb_codepoint_t end = startGlyph + classValue.len;
     for (hb_codepoint_t iter = startGlyph - 1;
 	 hb_set_next (glyphs, &iter) && iter < end;)
-      if (classValue[iter - start])
-        return true;
+      if (classValue[iter - start]) return true;
     return false;
   }
   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
@@ -1256,18 +1252,15 @@
     {
       /* Match if there's any glyph that is not listed! */
       hb_codepoint_t g = HB_SET_VALUE_INVALID;
-      if (!hb_set_next (glyphs, &g))
-        return false;
-      if (g < startGlyph)
-        return true;
+      if (!hb_set_next (glyphs, &g)) return false;
+      if (g < startGlyph) return true;
       g = startGlyph + count - 1;
-      if (hb_set_next (glyphs, &g))
-        return true;
+      if (hb_set_next (glyphs, &g)) return true;
       /* Fall through. */
     }
     for (unsigned int i = 0; i < count; i++)
       if (classValue[i] == klass && glyphs->has (startGlyph + i))
-        return true;
+	return true;
     return false;
   }
 
@@ -1317,7 +1310,7 @@
     for (unsigned int i = 0; i < count; i++)
     {
       if (rangeRecord[i].value == klass)
-        if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+	if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
 	  return false;
     }
     return true;
@@ -1329,7 +1322,7 @@
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
       if (rangeRecord[i].intersects (glyphs))
-        return true;
+	return true;
     return false;
   }
   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const
@@ -1348,12 +1341,12 @@
 	g = rangeRecord[i].end;
       }
       if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
-        return true;
+	return true;
       /* Fall through. */
     }
     for (unsigned int i = 0; i < count; i++)
       if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
-        return true;
+	return true;
     return false;
   }
 
@@ -1498,7 +1491,7 @@
       int coord = i < coord_len ? coords[i] : 0;
       float factor = axes[i].evaluate (coord);
       if (factor == 0.f)
-        return 0.;
+	return 0.;
       v *= factor;
     }
     return v;
@@ -1564,10 +1557,11 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  regionIndices.sanitize(c) &&
+		  regionIndices.sanitize (c) &&
 		  shortCount <= regionIndices.len &&
-		  c->check_array (&StructAfter<HBUINT8> (regionIndices),
-				  itemCount, get_row_size ()));
+		  c->check_range (&StructAfter<HBUINT8> (regionIndices),
+				  itemCount,
+				  get_row_size ()));
   }
 
   protected:
@@ -1683,7 +1677,7 @@
     unsigned int count = conditions.len;
     for (unsigned int i = 0; i < count; i++)
       if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len))
-        return false;
+	return false;
     return true;
   }
 
@@ -1941,7 +1935,7 @@
 
 struct Device
 {
-  inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const
+  inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const
   {
     switch (u.b.format)
     {
@@ -1953,7 +1947,7 @@
       return 0;
     }
   }
-  inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const
+  inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const
   {
     switch (u.b.format)
     {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -123,10 +123,8 @@
   inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
   {
     hb_position_t x, y;
-    if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y))
-      return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
-    else
-      return 0;
+    font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y);
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -350,7 +348,7 @@
     ComponentGlyph	= 4
   };
 
-  inline bool has_data (void) const { return version.to_int () != 0; }
+  inline bool has_data (void) const { return version.to_int (); }
   inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
   inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
   { return (this+glyphClassDef).get_class (glyph); }
@@ -410,15 +408,14 @@
 
   struct accelerator_t
   {
-    HB_INTERNAL inline void init (hb_face_t *face);
+    HB_INTERNAL void init (hb_face_t *face);
 
     inline void fini (void)
     {
-      hb_blob_destroy (this->blob);
+      this->table.destroy ();
     }
 
-    hb_blob_t *blob;
-    hb_nonnull_ptr_t<const GDEF> table;
+    hb_blob_ptr_t<GDEF> table;
   };
 
   inline unsigned int get_size (void) const

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -53,7 +53,7 @@
 
 typedef HBUINT16 Value;
 
-typedef Value ValueRecord[VAR];
+typedef UnsizedArrayOf<Value> ValueRecord;
 
 struct ValueFormat : HBUINT16
 {
@@ -103,56 +103,58 @@
   inline unsigned int get_size (void) const
   { return get_len () * Value::static_size; }
 
-  void apply_value (hb_ot_apply_context_t   *c,
+  bool apply_value (hb_ot_apply_context_t   *c,
 		    const void           *base,
 		    const Value          *values,
 		    hb_glyph_position_t  &glyph_pos) const
   {
+    bool ret = false;
     unsigned int format = *this;
-    if (!format) return;
+    if (!format) return ret;
 
     hb_font_t *font = c->font;
-    hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction);
+    bool horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction);
 
-    if (format & xPlacement) glyph_pos.x_offset  += font->em_scale_x (get_short (values++));
-    if (format & yPlacement) glyph_pos.y_offset  += font->em_scale_y (get_short (values++));
+    if (format & xPlacement) glyph_pos.x_offset  += font->em_scale_x (get_short (values++, &ret));
+    if (format & yPlacement) glyph_pos.y_offset  += font->em_scale_y (get_short (values++, &ret));
     if (format & xAdvance) {
-      if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values));
+      if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values, &ret));
       values++;
     }
     /* y_advance values grow downward but font-space grows upward, hence negation */
     if (format & yAdvance) {
-      if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values));
+      if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values, &ret));
       values++;
     }
 
-    if (!has_device ()) return;
+    if (!has_device ()) return ret;
 
     bool use_x_device = font->x_ppem || font->num_coords;
     bool use_y_device = font->y_ppem || font->num_coords;
 
-    if (!use_x_device && !use_y_device) return;
+    if (!use_x_device && !use_y_device) return ret;
 
     const VariationStore &store = c->var_store;
 
     /* pixel -> fractional pixel */
     if (format & xPlaDevice) {
-      if (use_x_device) glyph_pos.x_offset  += (base + get_device (values)).get_x_delta (font, store);
+      if (use_x_device) glyph_pos.x_offset  += (base + get_device (values, &ret)).get_x_delta (font, store);
       values++;
     }
     if (format & yPlaDevice) {
-      if (use_y_device) glyph_pos.y_offset  += (base + get_device (values)).get_y_delta (font, store);
+      if (use_y_device) glyph_pos.y_offset  += (base + get_device (values, &ret)).get_y_delta (font, store);
       values++;
     }
     if (format & xAdvDevice) {
-      if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font, store);
+      if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store);
       values++;
     }
     if (format & yAdvDevice) {
       /* y_advance values grow downward but font-space grows upward, hence negation */
-      if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font, store);
+      if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store);
       values++;
     }
+    return ret;
   }
 
   private:
@@ -175,11 +177,17 @@
 
   static inline OffsetTo<Device>& get_device (Value* value)
   { return *CastP<OffsetTo<Device> > (value); }
-  static inline const OffsetTo<Device>& get_device (const Value* value)
-  { return *CastP<OffsetTo<Device> > (value); }
+  static inline const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
+  {
+    if (worked) *worked |= *value;
+    return *CastP<OffsetTo<Device> > (value);
+  }
 
-  static inline const HBINT16& get_short (const Value* value)
-  { return *CastP<HBINT16> (value); }
+  static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr)
+  {
+    if (worked) *worked |= *value;
+    return *CastP<HBINT16> (value);
+  }
 
   public:
 
@@ -199,13 +207,13 @@
     TRACE_SANITIZE (this);
     unsigned int len = get_len ();
 
-    if (!c->check_array (values, count, get_size ())) return_trace (false);
+    if (!c->check_range (values, count, get_size ())) return_trace (false);
 
     if (!has_device ()) return_trace (true);
 
     for (unsigned int i = 0; i < count; i++) {
       if (!sanitize_value_devices (c, base, values))
-        return_trace (false);
+	return_trace (false);
       values += len;
     }
 
@@ -221,7 +229,7 @@
 
     for (unsigned int i = 0; i < count; i++) {
       if (!sanitize_value_devices (c, base, values))
-        return_trace (false);
+	return_trace (false);
       values += stride;
     }
 
@@ -263,10 +271,10 @@
     unsigned int x_ppem = font->x_ppem;
     unsigned int y_ppem = font->y_ppem;
     hb_position_t cx = 0, cy = 0;
-    hb_bool_t ret;
+    bool ret;
 
     ret = (x_ppem || y_ppem) &&
-	   font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
+	  font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
     *x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate);
     *y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate);
   }
@@ -626,7 +634,7 @@
     for (unsigned int i = 0; i < count; i++)
     {
       if (glyphs->has (record->secondGlyph))
-        return true;
+	return true;
       record = &StructAtOffset<const PairValueRecord> (record, record_size);
     }
     return false;
@@ -667,14 +675,15 @@
       const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid);
       hb_codepoint_t mid_x = record->secondGlyph;
       if (x < mid_x)
-        max = mid - 1;
+	max = mid - 1;
       else if (x > mid_x)
-        min = mid + 1;
+	min = mid + 1;
       else
       {
-        buffer->unsafe_to_break (buffer->idx, pos + 1);
-	valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
-	valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+	/* Note the intentional use of "|" instead of short-circuit "||". */
+	if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) |
+	    valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]))
+	  buffer->unsafe_to_break (buffer->idx, pos + 1);
 	if (len2)
 	  pos++;
 	buffer->idx = pos;
@@ -697,7 +706,10 @@
   {
     TRACE_SANITIZE (this);
     if (!(c->check_struct (this)
-       && c->check_array (&firstPairValueRecord, len, HBUINT16::static_size * closure->stride))) return_trace (false);
+       && c->check_range (&firstPairValueRecord,
+			  len,
+			  HBUINT16::static_size,
+			  closure->stride))) return_trace (false);
 
     unsigned int count = len;
     const PairValueRecord *record = &firstPairValueRecord;
@@ -722,10 +734,10 @@
     for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
+	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (glyphs->has (iter.get_glyph ()) &&
 	  (this+pairSet[iter.get_coverage ()]).intersects (glyphs, valueFormat))
-        return true;
+	return true;
     }
     return false;
   }
@@ -837,10 +849,11 @@
     unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
     if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
 
-    buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
-    valueFormat1.apply_value (c, this, v, buffer->cur_pos());
-    valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+    /* Note the intentional use of "|" instead of short-circuit "||". */
+    if (valueFormat1.apply_value (c, this, v, buffer->cur_pos()) |
+	valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]))
+      buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
 
     buffer->idx = skippy_iter.idx;
     if (len2)
@@ -869,7 +882,9 @@
     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, count, record_size) &&
+    return_trace (c->check_range ((const void *) 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));
   }
@@ -1406,7 +1421,7 @@
       if (id1 == 0) /* Marks belonging to the same base. */
 	goto good;
       else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
-        goto good;
+	goto good;
     } else {
       /* If ligature ids don't match, it may be the case that one of the marks
        * itself is a ligature.  In which case match. */
@@ -1736,18 +1751,21 @@
 }
 
 
+struct GPOS_accelerator_t : GPOS::accelerator_t {};
+
+
 /* Out-of-class implementation for methods recursing */
 
 template <typename context_t>
 /*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
 {
-  const PosLookup &l = _get_gpos_relaxed (c->face)->get_lookup (lookup_index);
+  const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
   return l.dispatch (c);
 }
 
 /*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
 {
-  const PosLookup &l = _get_gpos_relaxed (c->face).get_lookup (lookup_index);
+  const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
   unsigned int saved_lookup_props = c->lookup_props;
   unsigned int saved_lookup_index = c->lookup_index;
   c->set_lookup_index (lookup_index);
@@ -1758,9 +1776,7 @@
   return ret;
 }
 
-struct GPOS_accelerator_t : GPOS::accelerator_t {};
 
-
 } /* 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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -588,7 +588,7 @@
     for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
+	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
 	(this+alternateSet[iter.get_coverage ()]).closure (c);
     }
@@ -602,7 +602,7 @@
     for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
+	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       (this+alternateSet[iter.get_coverage ()]).collect_glyphs (c);
     }
   }
@@ -1487,6 +1487,9 @@
 };
 
 
+struct GSUB_accelerator_t : GSUB::accelerator_t {};
+
+
 /* Out-of-class implementation for methods recursing */
 
 /*static*/ inline bool ExtensionSubst::is_reverse (void) const
@@ -1500,13 +1503,13 @@
 template <typename context_t>
 /*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
 {
-  const SubstLookup &l = _get_gsub_relaxed (c->face).get_lookup (lookup_index);
+  const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
   return l.dispatch (c);
 }
 
 /*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
 {
-  const SubstLookup &l = _get_gsub_relaxed (c->face).get_lookup (lookup_index);
+  const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
   unsigned int saved_lookup_props = c->lookup_props;
   unsigned int saved_lookup_index = c->lookup_index;
   c->set_lookup_index (lookup_index);
@@ -1517,8 +1520,6 @@
   return ret;
 }
 
-struct GSUB_accelerator_t : GSUB::accelerator_t {};
-
 } /* namespace OT */
 
 

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -100,14 +100,14 @@
 
   hb_closure_context_t (hb_face_t *face_,
 			hb_set_t *glyphs_,
-                        hb_map_t *done_lookups_,
-		        unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
+			hb_map_t *done_lookups_,
+			unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
 			  face (face_),
 			  glyphs (glyphs_),
 			  recurse_func (nullptr),
 			  nesting_level_left (nesting_level_left_),
 			  debug_depth (0),
-                          done_lookups (done_lookups_) {}
+			  done_lookups (done_lookups_) {}
 
   ~hb_closure_context_t (void)
   {
@@ -291,7 +291,7 @@
     };
 
     inline may_match_t may_match (const hb_glyph_info_t &info,
-				  const HBUINT16          *glyph_data) const
+				  const HBUINT16        *glyph_data) const
     {
       if (!(info.mask & mask) ||
 	  (syllable && syllable != info.syllable ()))
@@ -298,7 +298,7 @@
 	return MATCH_NO;
 
       if (match_func)
-        return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
+	return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
 
       return MATCH_MAYBE;
     }
@@ -491,7 +491,7 @@
 			iter_input (), iter_context (),
 			font (font_), face (font->face), buffer (buffer_),
 			recurse_func (nullptr),
-			gdef (_get_gdef (face)),
+			gdef (*face->table.GDEF->table),
 			var_store (gdef.get_var_store ()),
 			direction (buffer_->props.direction),
 			lookup_mask (1),
@@ -852,9 +852,9 @@
        * component, otherwise we shouldn't ligate them... */
       if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
       {
-        /* ...unless, we are attached to a base ligature and that base
+	/* ...unless, we are attached to a base ligature and that base
 	 * ligature is ignorable. */
-        if (ligbase == LIGBASE_NOT_CHECKED)
+	if (ligbase == LIGBASE_NOT_CHECKED)
 	{
 	  bool found = false;
 	  const hb_glyph_info_t *out = buffer->out_info;
@@ -876,7 +876,7 @@
 	    ligbase = LIGBASE_MAY_NOT_SKIP;
 	}
 
-        if (ligbase == LIGBASE_MAY_NOT_SKIP)
+	if (ligbase == LIGBASE_MAY_NOT_SKIP)
 	  return_trace (false);
       }
     }
@@ -977,7 +977,7 @@
     {
       if (is_ligature)
       {
-        unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+	unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
 	if (this_comp == 0)
 	  this_comp = last_num_components;
 	unsigned int new_lig_comp = components_so_far - last_num_components +
@@ -999,7 +999,7 @@
     /* Re-adjust components for any marks following. */
     for (unsigned int i = buffer->idx; i < buffer->len; i++) {
       if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
-        unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
+	unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
 	if (!this_comp)
 	  break;
 	unsigned int new_lig_comp = components_so_far - last_num_components +
@@ -1133,7 +1133,7 @@
     int delta = new_len - orig_len;
 
     if (!delta)
-        continue;
+      continue;
 
     /* Recursed lookup changed buffer len.  Adjust.
      *
@@ -1376,7 +1376,7 @@
     unsigned int num_rules = rule.len;
     for (unsigned int i = 0; i < num_rules; i++)
       if ((this+rule[i]).intersects (glyphs, lookup_context))
-        return true;
+	return true;
     return false;
   }
 
@@ -1403,7 +1403,7 @@
     for (unsigned int i = 0; i < num_rules; i++)
     {
       if ((this+rule[i]).would_apply (c, lookup_context))
-        return_trace (true);
+	return_trace (true);
     }
     return_trace (false);
   }
@@ -1415,7 +1415,7 @@
     for (unsigned int i = 0; i < num_rules; i++)
     {
       if ((this+rule[i]).apply (c, lookup_context))
-        return_trace (true);
+	return_trace (true);
     }
     return_trace (false);
   }
@@ -1448,10 +1448,10 @@
     for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
+	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (glyphs->has (iter.get_glyph ()) &&
 	  (this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
-        return true;
+	return true;
     }
     return false;
   }
@@ -1469,7 +1469,7 @@
     for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
+	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
 	(this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
     }
@@ -1564,7 +1564,7 @@
     for (unsigned int i = 0; i < count; i++)
       if (class_def.intersects_class (glyphs, i) &&
 	  (this+ruleSet[i]).intersects (glyphs, lookup_context))
-        return true;
+	return true;
 
     return false;
   }
@@ -1868,15 +1868,15 @@
 }
 
 static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
-						        unsigned int backtrackCount,
-						        const HBUINT16 backtrack[],
-						        unsigned int inputCount, /* Including the first glyph (not matched) */
-						        const HBUINT16 input[], /* Array of input values--start with second glyph */
-						        unsigned int lookaheadCount,
-						        const HBUINT16 lookahead[],
-						        unsigned int lookupCount,
-						        const LookupRecord lookupRecord[],
-						        ChainContextCollectGlyphsLookupContext &lookup_context)
+							unsigned int backtrackCount,
+							const HBUINT16 backtrack[],
+							unsigned int inputCount, /* Including the first glyph (not matched) */
+							const HBUINT16 input[], /* Array of input values--start with second glyph */
+							unsigned int lookaheadCount,
+							const HBUINT16 lookahead[],
+							unsigned int lookupCount,
+							const LookupRecord lookupRecord[],
+							ChainContextCollectGlyphsLookupContext &lookup_context)
 {
   collect_array (c, c->before,
 		 backtrackCount, backtrack,
@@ -1934,10 +1934,10 @@
 			  lookup_context.funcs.match, lookup_context.match_data[2],
 			  match_length, &end_index)
       && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index),
-          apply_lookup (c,
-		       inputCount, match_positions,
-		       lookupCount, lookupRecord,
-		       match_length));
+	  apply_lookup (c,
+			inputCount, match_positions,
+			lookupCount, lookupRecord,
+			match_length));
 }
 
 struct ChainRule
@@ -2044,7 +2044,7 @@
     unsigned int num_rules = rule.len;
     for (unsigned int i = 0; i < num_rules; i++)
       if ((this+rule[i]).intersects (glyphs, lookup_context))
-        return true;
+	return true;
     return false;
   }
   inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
@@ -2069,7 +2069,7 @@
     unsigned int num_rules = rule.len;
     for (unsigned int i = 0; i < num_rules; i++)
       if ((this+rule[i]).would_apply (c, lookup_context))
-        return_trace (true);
+	return_trace (true);
 
     return_trace (false);
   }
@@ -2080,7 +2080,7 @@
     unsigned int num_rules = rule.len;
     for (unsigned int i = 0; i < num_rules; i++)
       if ((this+rule[i]).apply (c, lookup_context))
-        return_trace (true);
+	return_trace (true);
 
     return_trace (false);
   }
@@ -2112,10 +2112,10 @@
     for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
+	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (glyphs->has (iter.get_glyph ()) &&
 	  (this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
-        return true;
+	return true;
     }
     return false;
   }
@@ -2133,7 +2133,7 @@
     for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
+	break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
 	(this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
     }
@@ -2230,7 +2230,7 @@
     for (unsigned int i = 0; i < count; i++)
       if (input_class_def.intersects_class (glyphs, i) &&
 	  (this+ruleSet[i]).intersects (glyphs, lookup_context))
-        return true;
+	return true;
 
     return false;
   }
@@ -2644,10 +2644,10 @@
 
   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;
+    for (unsigned int i = 0; i < subtables.len; i++)
+      if (subtables[i].apply (c))
+	return true;
+    return false;
   }
 
   private:
@@ -2657,7 +2657,7 @@
 
 struct GSUBGPOS
 {
-  inline bool has_data (void) const { return version.to_int () != 0; }
+  inline bool has_data (void) const { return version.to_int (); }
   inline unsigned int get_script_count (void) const
   { return (this+scriptList).len; }
   inline const Tag& get_script_tag (unsigned int i) const
@@ -2702,7 +2702,7 @@
       const Feature *feature = (this+featureVars).find_substitute (variations_index,
 								   feature_index);
       if (feature)
-        return *feature;
+	return *feature;
     }
     return get_feature (feature_index);
   }
@@ -2752,14 +2752,13 @@
   {
     inline void init (hb_face_t *face)
     {
-      this->blob = hb_sanitize_context_t().reference_table<T> (face);
-      table = this->blob->template as<T> ();
+      this->table = hb_sanitize_context_t().reference_table<T> (face);
 
       this->lookup_count = table->get_lookup_count ();
 
       this->accels = (hb_ot_layout_lookup_accelerator_t *) calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t));
       if (unlikely (!this->accels))
-        this->lookup_count = 0;
+	this->lookup_count = 0;
 
       for (unsigned int i = 0; i < this->lookup_count; i++)
 	this->accels[i].init (table->get_lookup (i));
@@ -2770,11 +2769,10 @@
       for (unsigned int i = 0; i < this->lookup_count; i++)
 	this->accels[i].fini ();
       free (this->accels);
-      hb_blob_destroy (this->blob);
+      this->table.destroy ();
     }
 
-    hb_blob_t *blob;
-    hb_nonnull_ptr_t<const T> table;
+    hb_blob_ptr_t<T> table;
     unsigned int lookup_count;
     hb_ot_layout_lookup_accelerator_t *accels;
   };

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -42,7 +42,9 @@
 #include "hb-ot-kern-table.hh"
 #include "hb-ot-name-table.hh"
 
+#include "hb-aat-layout-lcar-table.hh"
 
+
 /**
  * SECTION:hb-ot-layout
  * @title: hb-ot-layout
@@ -53,72 +55,29 @@
  **/
 
 
-static inline const OT::kern&
-_get_kern (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(OT::kern);
-  }
-  const OT::kern& kern = *(hb_ot_face_data (face)->kern);
-  if (blob)
-    *blob = hb_ot_face_data (face)->kern.get_blob ();
-  return kern;
-}
-const OT::GDEF& _get_gdef (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF);
-  return *hb_ot_face_data (face)->GDEF->table;
-}
-static hb_blob_t * _get_gsub_blob (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return hb_blob_get_empty ();
-  return hb_ot_face_data (face)->GSUB->blob;
-}
-static inline const OT::GSUB& _get_gsub (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GSUB);
-  return *hb_ot_face_data (face)->GSUB->table;
-}
-const OT::GSUB& _get_gsub_relaxed (hb_face_t *face)
-{
-  return *hb_ot_face_data (face)->GSUB.get_relaxed ()->table;
-}
-static hb_blob_t * _get_gpos_blob (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return hb_blob_get_empty ();
-  return hb_ot_face_data (face)->GPOS->blob;
-}
-static inline const OT::GPOS& _get_gpos (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GPOS);
-  return *hb_ot_face_data (face)->GPOS->table;
-}
-const OT::GPOS& _get_gpos_relaxed (hb_face_t *face)
-{
-  return *hb_ot_face_data (face)->GPOS.get_relaxed ()->table;
-}
-
-
 /*
  * kern
  */
 
-hb_bool_t
+bool
 hb_ot_layout_has_kerning (hb_face_t *face)
 {
-  return _get_kern (face).has_data ();
+  return face->table.kern->has_data ();
 }
 
+bool
+hb_ot_layout_has_cross_kerning (hb_face_t *face)
+{
+  return face->table.kern->has_cross_stream ();
+}
+
 void
-hb_ot_layout_kern (hb_ot_shape_plan_t *plan,
+hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
 		   hb_font_t *font,
 		   hb_buffer_t  *buffer)
 {
-  hb_blob_t *blob;
-  const AAT::kern& kern = _get_kern (font->face, &blob);
+  hb_blob_t *blob = font->face->table.kern.get_blob ();
+  const AAT::kern& kern = *blob->as<AAT::kern> ();
 
   AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
 
@@ -232,20 +191,18 @@
   return false;
 }
 
-inline void
+void
 OT::GDEF::accelerator_t::init (hb_face_t *face)
 {
-  this->blob = hb_sanitize_context_t().reference_table<GDEF> (face);
+  this->table = hb_sanitize_context_t().reference_table<GDEF> (face);
 
-  if (unlikely (_hb_ot_blacklist_gdef (this->blob->length,
-				       _get_gsub_blob (face)->length,
-				       _get_gpos_blob (face)->length)))
+  if (unlikely (_hb_ot_blacklist_gdef (this->table.get_length (),
+				       face->table.GSUB->table.get_length (),
+				       face->table.GPOS->table.get_length ())))
   {
-    hb_blob_destroy (this->blob);
-    this->blob = hb_blob_get_empty ();
+    hb_blob_destroy (this->table.get_blob ());
+    this->table = hb_blob_get_empty ();
   }
-
-  table = this->blob->as<GDEF> ();
 }
 
 static void
@@ -254,7 +211,7 @@
 {
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
-  const OT::GDEF &gdef = _get_gdef (font->face);
+  const OT::GDEF &gdef = *font->face->table.GDEF->table;
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)
   {
@@ -269,7 +226,7 @@
 hb_bool_t
 hb_ot_layout_has_glyph_classes (hb_face_t *face)
 {
-  return _get_gdef (face).has_glyph_classes ();
+  return face->table.GDEF->table->has_glyph_classes ();
 }
 
 /**
@@ -281,7 +238,7 @@
 hb_ot_layout_get_glyph_class (hb_face_t      *face,
 			      hb_codepoint_t  glyph)
 {
-  return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph);
+  return (hb_ot_layout_glyph_class_t) face->table.GDEF->table->get_glyph_class (glyph);
 }
 
 /**
@@ -294,7 +251,7 @@
 				  hb_ot_layout_glyph_class_t  klass,
 				  hb_set_t                   *glyphs /* OUT */)
 {
-  return _get_gdef (face).get_glyphs_in_class (klass, glyphs);
+  return face->table.GDEF->table->get_glyphs_in_class (klass, glyphs);
 }
 
 unsigned int
@@ -304,7 +261,10 @@
 				unsigned int   *point_count /* IN/OUT */,
 				unsigned int   *point_array /* OUT */)
 {
-  return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array);
+  return face->table.GDEF->table->get_attach_points (glyph,
+						     start_offset,
+						     point_count,
+						     point_array);
 }
 
 unsigned int
@@ -315,7 +275,15 @@
 				  unsigned int   *caret_count /* IN/OUT */,
 				  hb_position_t  *caret_array /* OUT */)
 {
-  return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
+  unsigned int result_caret_count = 0;
+  unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array);
+  if (result)
+  {
+    if (caret_count) *caret_count = result_caret_count;
+  }
+  else
+    result = font->face->table.lcar->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
+  return result;
 }
 
 
@@ -328,8 +296,8 @@
 		    hb_tag_t   table_tag)
 {
   switch (table_tag) {
-    case HB_OT_TAG_GSUB: return _get_gsub (face);
-    case HB_OT_TAG_GPOS: return _get_gpos (face);
+    case HB_OT_TAG_GSUB: return *face->table.GSUB->table;
+    case HB_OT_TAG_GPOS: return *face->table.GPOS->table;
     default:             return Null(OT::GSUBGPOS);
   }
 }
@@ -458,7 +426,7 @@
   return g.get_feature_tags (start_offset, feature_count, feature_tags);
 }
 
-hb_bool_t
+bool
 hb_ot_layout_table_find_feature (hb_face_t    *face,
 				 hb_tag_t      table_tag,
 				 hb_tag_t      feature_tag,
@@ -501,7 +469,12 @@
 				   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);
+  return hb_ot_layout_script_select_language (face,
+					      table_tag,
+					      script_index,
+					      1,
+					      &language_tag,
+					      language_index);
 }
 
 /**
@@ -879,8 +852,6 @@
 				    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;
-
   OT::hb_collect_glyphs_context_t c (face,
 				     glyphs_before,
 				     glyphs_input,
@@ -891,13 +862,13 @@
   {
     case HB_OT_TAG_GSUB:
     {
-      const OT::SubstLookup& l = hb_ot_face_data (face)->GSUB->table->get_lookup (lookup_index);
+      const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
       l.collect_glyphs (&c);
       return;
     }
     case HB_OT_TAG_GPOS:
     {
-      const OT::PosLookup& l = hb_ot_face_data (face)->GPOS->table->get_lookup (lookup_index);
+      const OT::PosLookup& l = face->table.GPOS->table->get_lookup (lookup_index);
       l.collect_glyphs (&c);
       return;
     }
@@ -944,7 +915,7 @@
 hb_bool_t
 hb_ot_layout_has_substitution (hb_face_t *face)
 {
-  return _get_gsub (face).has_data ();
+  return face->table.GSUB->table->has_data ();
 }
 
 /**
@@ -959,23 +930,25 @@
 				      unsigned int          glyphs_length,
 				      hb_bool_t             zero_context)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
-  return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
+  return hb_ot_layout_lookup_would_substitute_fast (face,
+						    lookup_index,
+						    glyphs, glyphs_length,
+						    zero_context);
 }
 
-hb_bool_t
+bool
 hb_ot_layout_lookup_would_substitute_fast (hb_face_t            *face,
 					   unsigned int          lookup_index,
 					   const hb_codepoint_t *glyphs,
 					   unsigned int          glyphs_length,
-					   hb_bool_t             zero_context)
+					   bool                  zero_context)
 {
-  if (unlikely (lookup_index >= hb_ot_face_data (face)->GSUB->lookup_count)) return false;
+  if (unlikely (lookup_index >= face->table.GSUB->lookup_count)) return false;
   OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context);
 
-  const OT::SubstLookup& l = hb_ot_face_data (face)->GSUB->table->get_lookup (lookup_index);
+  const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
 
-  return l.would_apply (&c, &hb_ot_face_data (face)->GSUB->accels[lookup_index]);
+  return l.would_apply (&c, &face->table.GSUB->accels[lookup_index]);
 }
 
 void
@@ -985,6 +958,56 @@
 _hb_ot_layout_set_glyph_props (font, buffer);
 }
 
+void
+hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer,
+				    bool (*filter) (const hb_glyph_info_t *info))
+{
+  /* Merge clusters and delete filtered glyphs.
+   * NOTE! We can't use out-buffer as we have positioning data. */
+  unsigned int j = 0;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  hb_glyph_position_t *pos = buffer->pos;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    if (filter (&info[i]))
+    {
+      /* Merge clusters.
+       * Same logic as buffer->delete_glyph(), but for in-place removal. */
+
+      unsigned int cluster = info[i].cluster;
+      if (i + 1 < count && cluster == info[i + 1].cluster)
+	continue; /* Cluster survives; do nothing. */
+
+      if (j)
+      {
+	/* Merge cluster backward. */
+	if (cluster < info[j - 1].cluster)
+	{
+	  unsigned int mask = info[i].mask;
+	  unsigned int old_cluster = info[j - 1].cluster;
+	  for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
+	    buffer->set_cluster (info[k - 1], cluster, mask);
+	}
+	continue;
+      }
+
+      if (i + 1 < count)
+	buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */
+
+      continue;
+    }
+
+    if (j != i)
+    {
+      info[j] = info[i];
+      pos[j] = pos[i];
+    }
+    j++;
+  }
+  buffer->len = j;
+}
+
 /**
  * hb_ot_layout_lookup_substitute_closure:
  *
@@ -998,7 +1021,7 @@
   hb_map_t done_lookups;
   OT::hb_closure_context_t c (face, glyphs, &done_lookups);
 
-  const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index);
+  const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
 
   l.closure (&c, lookup_index);
 }
@@ -1018,7 +1041,7 @@
 {
   hb_map_t done_lookups;
   OT::hb_closure_context_t c (face, glyphs, &done_lookups);
-  const OT::GSUB& gsub = _get_gsub (face);
+  const OT::GSUB& gsub = *face->table.GSUB->table;
 
   unsigned int iteration_count = 0;
   unsigned int glyphs_length;
@@ -1035,9 +1058,8 @@
       for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
         gsub.get_lookup (i).closure (&c, i);
     }
-    iteration_count++;
-  } while (iteration_count <= HB_CLOSURE_MAX_STAGES
-           && glyphs_length != glyphs->get_population ());
+  } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
+	   glyphs_length != glyphs->get_population ());
 }
 
 /*
@@ -1047,7 +1069,7 @@
 hb_bool_t
 hb_ot_layout_has_positioning (hb_face_t *face)
 {
-  return _get_gpos (face).has_data ();
+  return face->table.GPOS->table->has_data ();
 }
 
 void
@@ -1081,7 +1103,7 @@
 			      unsigned int    *range_start,       /* OUT.  May be NULL */
 			      unsigned int    *range_end          /* OUT.  May be NULL */)
 {
-  const OT::GPOS &gpos = _get_gpos (face);
+  const OT::GPOS &gpos = *face->table.GPOS->table;
   const hb_tag_t tag = HB_TAG ('s','i','z','e');
 
   unsigned int num_features = gpos.get_feature_count ();
@@ -1254,8 +1276,8 @@
   typedef OT::SubstLookup Lookup;
 
   GSUBProxy (hb_face_t *face) :
-    table (*hb_ot_face_data (face)->GSUB->table),
-    accels (hb_ot_face_data (face)->GSUB->accels) {}
+    table (*face->table.GSUB->table),
+    accels (face->table.GSUB->accels) {}
 
   const OT::GSUB &table;
   const OT::hb_ot_layout_lookup_accelerator_t *accels;
@@ -1268,8 +1290,8 @@
   typedef OT::PosLookup Lookup;
 
   GPOSProxy (hb_face_t *face) :
-    table (*hb_ot_face_data (face)->GPOS->table),
-    accels (hb_ot_face_data (face)->GPOS->accels) {}
+    table (*face->table.GPOS->table),
+    accels (face->table.GPOS->accels) {}
 
   const OT::GPOS &table;
   const OT::hb_ot_layout_lookup_accelerator_t *accels;
@@ -1311,10 +1333,8 @@
     if (accel.may_have (buffer->cur().codepoint) &&
 	(buffer->cur().mask & c->lookup_mask) &&
 	c->check_glyph_property (&buffer->cur(), c->lookup_props))
-    {
-     if (accel.apply (c))
-       ret = true;
-    }
+     ret |= accel.apply (c);
+
     /* The reverse lookup doesn't "advance" cursor (for good reason). */
     buffer->idx--;
 
@@ -1427,8 +1447,7 @@
 #if 0
 static const OT::BASE& _get_base (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE);
-  return *hb_ot_face_data (face)->BASE;
+  return *face->table.BASE;
 }
 
 hb_bool_t

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -38,28 +38,21 @@
 #include "hb-set-digest.hh"
 
 
-namespace OT
-{
-  struct GDEF;
-  struct GSUB;
-  struct GPOS;
-}
+struct hb_ot_shape_plan_t;
 
-HB_INTERNAL const OT::GDEF& _get_gdef (hb_face_t *face);
-HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face);
-HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face);
 
-struct hb_ot_shape_plan_t;
-
 /*
  * kern
  */
 
-HB_INTERNAL hb_bool_t
+HB_INTERNAL bool
 hb_ot_layout_has_kerning (hb_face_t *face);
 
+HB_INTERNAL bool
+hb_ot_layout_has_cross_kerning (hb_face_t *face);
+
 HB_INTERNAL void
-hb_ot_layout_kern (hb_ot_shape_plan_t *plan,
+hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
 		   hb_font_t *font,
 		   hb_buffer_t  *buffer);
 
@@ -66,7 +59,7 @@
 
 /* Private API corresponding to hb-ot-layout.h: */
 
-HB_INTERNAL hb_bool_t
+HB_INTERNAL bool
 hb_ot_layout_table_find_feature (hb_face_t    *face,
 				 hb_tag_t      table_tag,
 				 hb_tag_t      feature_tag,
@@ -100,12 +93,12 @@
  * GSUB/GPOS
  */
 
-HB_INTERNAL hb_bool_t
+HB_INTERNAL bool
 hb_ot_layout_lookup_would_substitute_fast (hb_face_t            *face,
 					   unsigned int          lookup_index,
 					   const hb_codepoint_t *glyphs,
 					   unsigned int          glyphs_length,
-					   hb_bool_t             zero_context);
+					   bool                  zero_context);
 
 
 /* Should be called before all the substitute_lookup's are done. */
@@ -113,6 +106,9 @@
 hb_ot_layout_substitute_start (hb_font_t    *font,
 			       hb_buffer_t  *buffer);
 
+HB_INTERNAL void
+hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer,
+				    bool (*filter) (const hb_glyph_info_t *info));
 
 namespace OT {
   struct hb_ot_apply_context_t;
@@ -313,13 +309,13 @@
 
 static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
 
-static inline hb_bool_t
+static inline bool
 _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
 {
   return (info->unicode_props() & UPROPS_MASK_IGNORABLE) &&
 	 !_hb_glyph_info_ligated (info);
 }
-static inline hb_bool_t
+static inline bool
 _hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info)
 {
   return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_HIDDEN))
@@ -373,17 +369,17 @@
   return _hb_glyph_info_get_general_category (info) ==
 	 HB_UNICODE_GENERAL_CATEGORY_FORMAT;
 }
-static inline hb_bool_t
+static inline bool
 _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
 {
   return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWNJ);
 }
-static inline hb_bool_t
+static inline bool
 _hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
 {
   return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ);
 }
-static inline hb_bool_t
+static inline bool
 _hb_glyph_info_is_joiner (const hb_glyph_info_t *info)
 {
   return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ));

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -27,7 +27,7 @@
  */
 
 #include "hb-ot-map.hh"
-
+#include "hb-ot-shape.hh"
 #include "hb-ot-layout.hh"
 
 
@@ -143,9 +143,8 @@
 }
 
 void
-hb_ot_map_builder_t::compile (hb_ot_map_t  &m,
-			      const int    *coords,
-			      unsigned int  num_coords)
+hb_ot_map_builder_t::compile (hb_ot_map_t                  &m,
+			      const hb_ot_shape_plan_key_t &key)
 {
   static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
   unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1;
@@ -282,13 +281,6 @@
   {
     /* Collect lookup indices for features */
 
-    unsigned int variations_index;
-    hb_ot_layout_table_find_feature_variations (face,
-						table_tags[table_index],
-						coords,
-						num_coords,
-						&variations_index);
-
     unsigned int stage_index = 0;
     unsigned int last_num_lookups = 0;
     for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
@@ -297,7 +289,7 @@
 	  required_feature_stage[table_index] == stage)
 	add_lookups (m, table_index,
 		     required_feature_index[table_index],
-		     variations_index,
+		     key.variations_index[table_index],
 		     global_bit_mask);
 
       for (unsigned i = 0; i < m.features.len; i++)
@@ -304,7 +296,7 @@
         if (m.features[i].stage[table_index] == stage)
 	  add_lookups (m, table_index,
 		       m.features[i].index[table_index],
-		       variations_index,
+		       key.variations_index[table_index],
 		       m.features[i].mask,
 		       m.features[i].auto_zwnj,
 		       m.features[i].auto_zwj,

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -188,6 +188,7 @@
   hb_ot_map_feature_flags_t flags;
 };
 
+struct hb_ot_shape_plan_key_t;
 
 struct hb_ot_map_builder_t
 {
@@ -218,9 +219,8 @@
   inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
   { add_pause (1, pause_func); }
 
-  HB_INTERNAL void compile (hb_ot_map_t  &m,
-			    const int    *coords,
-			    unsigned int  num_coords);
+  HB_INTERNAL void compile (hb_ot_map_t                  &m,
+			    const hb_ot_shape_plan_key_t &key);
 
   private:
 

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -74,7 +74,7 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && sanitize_math_value_records(c));
+    return_trace (c->check_struct (this) && sanitize_math_value_records (c));
   }
 
   inline hb_position_t get_value (hb_ot_math_constant_t constant,
@@ -94,7 +94,7 @@
     case HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE:
     case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP:
     case HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT:
-      return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value(font, this);
+      return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value (font, this);
 
     case HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT:
     case HB_OT_MATH_CONSTANT_AXIS_HEIGHT:
@@ -143,7 +143,7 @@
     case HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP:
     case HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN:
     case HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN:
-      return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value(font, this);
+      return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value (font, this);
 
     case HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT:
       return radicalDegreeBottomRaisePercent;
@@ -210,7 +210,7 @@
     unsigned int index = (this+topAccentCoverage).get_coverage (glyph);
     if (index == NOT_COVERED)
       return font->get_glyph_h_advance (glyph) / 2;
-    return topAccentAttachment[index].get_x_value(font, this);
+    return topAccentAttachment[index].get_x_value (font, this);
   }
 
   protected:
@@ -265,7 +265,7 @@
     while (count > 0)
     {
       unsigned int half = count / 2;
-      hb_position_t height = correctionHeight[i + half].get_y_value(font, this);
+      hb_position_t height = correctionHeight[i + half].get_y_value (font, this);
       if (sign * height < sign * correction_height)
       {
 	i += half + 1;
@@ -273,7 +273,7 @@
       } else
 	count = half;
     }
-    return kernValue[i].get_x_value(font, this);
+    return kernValue[i].get_x_value (font, this);
   }
 
   protected:
@@ -368,7 +368,7 @@
 		  mathItalicsCorrectionInfo.sanitize (c, this) &&
 		  mathTopAccentAttachment.sanitize (c, this) &&
 		  extendedShapeCoverage.sanitize (c, this) &&
-		  mathKernInfo.sanitize(c, this));
+		  mathKernInfo.sanitize (c, this));
   }
 
   inline hb_position_t
@@ -425,8 +425,8 @@
   protected:
   GlyphID variantGlyph;       /* Glyph ID for the variant. */
   HBUINT16  advanceMeasurement; /* Advance width/height, in design units, of the
-			       * variant, in the direction of requested
-			       * glyph extension. */
+				 * variant, in the direction of requested
+				 * glyph extension. */
 
   public:
   DEFINE_SIZE_STATIC (4);
@@ -495,8 +495,8 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  italicsCorrection.sanitize(c, this) &&
-		  partRecords.sanitize(c));
+		  italicsCorrection.sanitize (c, this) &&
+		  partRecords.sanitize (c));
   }
 
   inline unsigned int get_parts (hb_direction_t direction,
@@ -540,8 +540,8 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  glyphAssembly.sanitize(c, this) &&
-		  mathGlyphVariantRecord.sanitize(c));
+		  glyphAssembly.sanitize (c, this) &&
+		  mathGlyphVariantRecord.sanitize (c));
   }
 
   inline const MathGlyphAssembly &get_assembly (void) const
@@ -639,7 +639,7 @@
 						  : horizGlyphCoverage;
 
     unsigned int index = (this+coverage).get_coverage (glyph);
-    if (unlikely (index >= count)) return Null(MathGlyphConstruction);
+    if (unlikely (index >= count)) return Null (MathGlyphConstruction);
 
     if (!vertical)
       index += vertGlyphCount;
@@ -684,7 +684,7 @@
 {
   static const hb_tag_t tableTag	= HB_OT_TAG_MATH;
 
-  inline bool has_data (void) const { return version.to_int () != 0; }
+  inline bool has_data (void) const { return version.to_int (); }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -700,10 +700,10 @@
 				     hb_font_t		   *font) const
   { return (this+mathConstants).get_value (constant, font); }
 
-  inline const MathGlyphInfo &get_math_glyph_info (void) const
+  inline const MathGlyphInfo &get_glyph_info (void) const
   { return this+mathGlyphInfo; }
 
-  inline const MathVariants &get_math_variants (void) const
+  inline const MathVariants &get_variants (void) const
   { return this+mathVariants; }
 
   protected:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -40,14 +40,6 @@
  **/
 
 
-static inline const OT::MATH&
-_get_math (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::MATH);
-  hb_ot_face_data_t * data = hb_ot_face_data (face);
-  return *(data->MATH);
-}
-
 /*
  * OT::MATH
  */
@@ -66,7 +58,7 @@
 hb_bool_t
 hb_ot_math_has_data (hb_face_t *face)
 {
-  return _get_math (face).has_data ();
+  return face->table.MATH->has_data ();
 }
 
 /**
@@ -88,8 +80,7 @@
 hb_ot_math_get_constant (hb_font_t *font,
 			 hb_ot_math_constant_t constant)
 {
-  const OT::MATH &math = _get_math (font->face);
-  return math.get_constant(constant, font);
+  return font->face->table.MATH->get_constant(constant, font);
 }
 
 /**
@@ -105,8 +96,7 @@
 hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
 					 hb_codepoint_t glyph)
 {
-  const OT::MATH &math = _get_math (font->face);
-  return math.get_math_glyph_info().get_italics_correction (glyph, font);
+  return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font);
 }
 
 /**
@@ -122,8 +112,7 @@
 hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
 					    hb_codepoint_t glyph)
 {
-  const OT::MATH &math = _get_math (font->face);
-  return math.get_math_glyph_info().get_top_accent_attachment (glyph, font);
+  return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font);
 }
 
 /**
@@ -139,8 +128,7 @@
 hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
 				    hb_codepoint_t glyph)
 {
-  const OT::MATH &math = _get_math (face);
-  return math.get_math_glyph_info().is_extended_shape (glyph);
+  return face->table.MATH->get_glyph_info().is_extended_shape (glyph);
 }
 
 /**
@@ -166,8 +154,10 @@
 			      hb_ot_math_kern_t kern,
 			      hb_position_t correction_height)
 {
-  const OT::MATH &math = _get_math (font->face);
-  return math.get_math_glyph_info().get_kerning (glyph, kern, correction_height, font);
+  return font->face->table.MATH->get_glyph_info().get_kerning (glyph,
+							       kern,
+							       correction_height,
+							       font);
 }
 
 /**
@@ -197,11 +187,10 @@
 			       unsigned int *variants_count, /* IN/OUT */
 			       hb_ot_math_glyph_variant_t *variants /* OUT */)
 {
-  const OT::MATH &math = _get_math (font->face);
-  return math.get_math_variants().get_glyph_variants (glyph, direction, font,
-						      start_offset,
-						      variants_count,
-						      variants);
+  return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font,
+								    start_offset,
+								    variants_count,
+								    variants);
 }
 
 /**
@@ -222,8 +211,7 @@
 hb_ot_math_get_min_connector_overlap (hb_font_t *font,
 				      hb_direction_t direction)
 {
-  const OT::MATH &math = _get_math (font->face);
-  return math.get_math_variants().get_min_connector_overlap (direction, font);
+  return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font);
 }
 
 /**
@@ -255,10 +243,11 @@
 			       hb_ot_math_glyph_part_t *parts, /* OUT */
 			       hb_position_t *italics_correction /* OUT */)
 {
-  const OT::MATH &math = _get_math (font->face);
-  return math.get_math_variants().get_glyph_parts (glyph, direction, font,
-						   start_offset,
-						   parts_count,
-						   parts,
-						   italics_correction);
+  return font->face->table.MATH->get_variants().get_glyph_parts (glyph,
+								 direction,
+								 font,
+								 start_offset,
+								 parts_count,
+								 parts,
+								 italics_correction);
 }

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -179,11 +179,10 @@
   {
     inline void init (hb_face_t *face)
     {
-      this->blob = hb_sanitize_context_t().reference_table<name> (face);
-      this->table = this->blob->as<name> ();
-      assert (this->blob->length >= this->table->stringOffset);
+      this->table = hb_sanitize_context_t().reference_table<name> (face);
+      assert (this->table.get_length () >= this->table->stringOffset);
       this->pool = (this->table+this->table->stringOffset).arrayZ;
-      this->pool_len = this->blob->length - this->table->stringOffset;
+      this->pool_len = this->table.get_length () - this->table->stringOffset;
       const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
 						    this->table->count);
 
@@ -221,7 +220,7 @@
     inline void fini (void)
     {
       this->names.fini ();
-      hb_blob_destroy (this->blob);
+      this->table.destroy ();
     }
 
     inline int get_index (hb_ot_name_id_t   name_id,
@@ -253,11 +252,10 @@
     }
 
     private:
-    hb_blob_t *blob;
     const void *pool;
     unsigned int pool_len;
     public:
-    hb_nonnull_ptr_t<const name> table;
+    hb_blob_ptr_t<name> table;
     hb_vector_t<hb_ot_name_entry_t> names;
   };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -42,13 +42,6 @@
  **/
 
 
-static inline const OT::name_accelerator_t&
-_get_name (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::name_accelerator_t);
-  return *(hb_ot_face_data (face)->name);
-}
-
 /**
  * hb_ot_name_list_names:
  * @face: font face.
@@ -65,7 +58,7 @@
 hb_ot_name_list_names (hb_face_t    *face,
 		       unsigned int *num_entries /* OUT */)
 {
-  const OT::name_accelerator_t &name = _get_name (face);
+  const OT::name_accelerator_t &name = *face->table.name;
   if (num_entries) *num_entries = name.names.len;
   return name.names.arrayZ();
 }
@@ -124,7 +117,7 @@
 		    unsigned int    *text_size /* IN/OUT */,
 		    typename utf_t::codepoint_t *text /* OUT */)
 {
-  const OT::name_accelerator_t &name = _get_name (face);
+  const OT::name_accelerator_t &name = *face->table.name;
 
   if (!language)
     language = hb_language_from_string ("en", 2);

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -50,7 +50,7 @@
 
   inline bool subset (hb_subset_plan_t *plan) const
   {
-    hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table<OS2> (plan->source);
+    hb_blob_t *os2_blob = hb_sanitize_context_t ().reference_table<OS2> (plan->source);
     hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1);
     // TODO(grieger): move to hb_blob_copy_writable_or_fail
     hb_blob_destroy (os2_blob);
@@ -74,7 +74,7 @@
   }
 
   inline void _update_unicode_ranges (const hb_set_t *codepoints,
-                                      HBUINT32 ulUnicodeRange[4]) const
+				      HBUINT32 ulUnicodeRange[4]) const
   {
     for (unsigned int i = 0; i < 4; i++)
       ulUnicodeRange[i].set (0);
@@ -84,24 +84,24 @@
       unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp);
       if (bit < 128)
       {
-        unsigned int block = bit / 32;
-        unsigned int bit_in_block = bit % 32;
-        unsigned int mask = 1 << bit_in_block;
-        ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
+	unsigned int block = bit / 32;
+	unsigned int bit_in_block = bit % 32;
+	unsigned int mask = 1 << bit_in_block;
+	ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
       }
       if (cp >= 0x10000 && cp <= 0x110000)
       {
-        /* the spec says that bit 57 ("Non Plane 0") implies that there's
-           at least one codepoint beyond the BMP; so I also include all
-           the non-BMP codepoints here */
-        ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
+	/* the spec says that bit 57 ("Non Plane 0") implies that there's
+	   at least one codepoint beyond the BMP; so I also include all
+	   the non-BMP codepoints here */
+	ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
       }
     }
   }
 
   static inline void find_min_and_max_codepoint (const hb_set_t *codepoints,
-                                                 uint16_t *min_cp, /* OUT */
-                                                 uint16_t *max_cp  /* OUT */)
+						 uint16_t *min_cp, /* OUT */
+						 uint16_t *max_cp  /* OUT */)
   {
     *min_cp = codepoints->get_min ();
     *max_cp = codepoints->get_max ();

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -49,6 +49,8 @@
 
 struct postV2Tail
 {
+  friend struct post;
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -55,6 +57,7 @@
     return_trace (glyphNameIndex.sanitize (c));
   }
 
+  protected:
   ArrayOf<HBUINT16>	glyphNameIndex;	/* This is not an offset, but is the
 					 * ordinal number of the glyph in 'post'
 					 * string tables. */
@@ -62,6 +65,7 @@
 			namesX;		/* Glyph names with length bytes [variable]
 					 * (a Pascal string). */
 
+  public:
   DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
 };
 
@@ -69,28 +73,15 @@
 {
   static const hb_tag_t tableTag = HB_OT_TAG_post;
 
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!c->check_struct (this)))
-      return_trace (false);
-    if (version.to_int () == 0x00020000)
-    {
-      const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
-      return_trace (v2.sanitize (c));
-    }
-    return_trace (true);
-  }
-
   inline bool subset (hb_subset_plan_t *plan) const
   {
     unsigned int post_prime_length;
-    hb_blob_t *post_blob = hb_sanitize_context_t().reference_table<post>(plan->source);
-    hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::static_size);
+    hb_blob_t *post_blob = hb_sanitize_context_t ().reference_table<post>(plan->source);
+    hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::min_size);
     post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
     hb_blob_destroy (post_blob);
 
-    if (unlikely (!post_prime || post_prime_length != post::static_size))
+    if (unlikely (!post_prime || post_prime_length != post::min_size))
     {
       hb_blob_destroy (post_prime_blob);
       DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length);
@@ -110,21 +101,21 @@
     {
       index_to_offset.init ();
 
-      blob = hb_sanitize_context_t().reference_table<post> (face);
-      const post *table = blob->as<post> ();
-      unsigned int table_length = blob->length;
+      table = hb_sanitize_context_t ().reference_table<post> (face);
+      unsigned int table_length = table.get_length ();
 
       version = table->version.to_int ();
-      if (version != 0x00020000)
-        return;
+      if (version != 0x00020000) return;
 
-      const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
+      const postV2Tail &v2 = table->v2;
 
       glyphNameIndex = &v2.glyphNameIndex;
       pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
 
-      const uint8_t *end = (uint8_t *) table + table_length;
-      for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data)
+      const uint8_t *end = (const uint8_t *) (const void *) table + table_length;
+      for (const uint8_t *data = pool;
+	   index_to_offset.len < 65535 && data < end && data + *data < end;
+	   data += 1 + *data)
 	index_to_offset.push (data - pool);
     }
     inline void fini (void)
@@ -131,7 +122,7 @@
     {
       index_to_offset.fini ();
       free (gids_sorted_by_name.get ());
-      hb_blob_destroy (blob);
+      table.destroy ();
     }
 
     inline bool get_glyph_name (hb_codepoint_t glyph,
@@ -138,14 +129,11 @@
 				char *buf, unsigned int buf_len) const
     {
       hb_bytes_t s = find_glyph_name (glyph);
-      if (!s.len)
-        return false;
-      if (!buf_len)
-	return true;
-      if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
-        return false;
-      strncpy (buf, s.arrayZ, s.len);
-      buf[s.len] = '\0';
+      if (!s.len) return false;
+      if (!buf_len) return true;
+      unsigned int len = MIN (buf_len - 1, s.len);
+      strncpy (buf, s.arrayZ, len);
+      buf[len] = '\0';
       return true;
     }
 
@@ -153,14 +141,11 @@
 				     hb_codepoint_t *glyph) const
     {
       unsigned int count = get_glyph_count ();
-      if (unlikely (!count))
-        return false;
+      if (unlikely (!count)) return false;
 
-      if (len < 0)
-	len = strlen (name);
+      if (len < 0) len = strlen (name);
 
-      if (unlikely (!len))
-	return false;
+      if (unlikely (!len)) return false;
 
     retry:
       uint16_t *gids = gids_sorted_by_name.get ();
@@ -198,10 +183,10 @@
     inline unsigned int get_glyph_count (void) const
     {
       if (version == 0x00010000)
-        return NUM_FORMAT1_NAMES;
+	return NUM_FORMAT1_NAMES;
 
       if (version == 0x00020000)
-        return glyphNameIndex->len;
+	return glyphNameIndex->len;
 
       return 0;
     }
@@ -252,14 +237,23 @@
     }
 
     private:
-    hb_blob_t *blob;
+    hb_blob_ptr_t<post> table;
     uint32_t version;
-    hb_nonnull_ptr_t<const ArrayOf<HBUINT16> > glyphNameIndex;
+    const ArrayOf<HBUINT16> *glyphNameIndex;
     hb_vector_t<uint32_t, 1> index_to_offset;
     const uint8_t *pool;
     hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
   };
 
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  (version.to_int () == 0x00010000 ||
+			   (version.to_int () == 0x00020000 && v2.sanitize (c)) ||
+			   version.to_int () == 0x00030000)));
+  }
+
   public:
   FixedVersion<>version;		/* 0x00010000 for version 1.0
 					 * 0x00020000 for version 2.0
@@ -292,8 +286,8 @@
 					 * is downloaded as a Type 1 font. */
   HBUINT32	maxMemType1;		/* Maximum memory usage when an OpenType font
 					 * is downloaded as a Type 1 font. */
-/*postV2Tail	v2[VAR];*/
-  DEFINE_SIZE_STATIC (32);
+  postV2Tail	v2;
+  DEFINE_SIZE_MIN (32);
 };
 
 struct post_accelerator_t : post::accelerator_t {};

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -202,7 +202,7 @@
   OT::hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
 };
 
-#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256)
+#if defined(_WIN32) && !defined(HB_NO_WIN1256)
 #define HB_WITH_WIN1256
 #endif
 
@@ -212,8 +212,11 @@
 
 struct ManifestLookup
 {
+  public:
   OT::Tag tag;
   OT::OffsetTo<OT::SubstLookup> lookupOffset;
+  public:
+  DEFINE_SIZE_STATIC (6);
 };
 typedef OT::ArrayOf<ManifestLookup> Manifest;
 

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -582,7 +582,7 @@
   /* 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,  VPst,  VPst,     H,     O,     O,
+  /* 11340 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,     O,  VPre,  VPre,     O,     O,  VPst,  VPst,   HVM,     O,     O,
   /* 11350 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     B,     B,
   /* 11360 */     B,     B,  VPst,  VPst,     O,     O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
   /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -25,7 +25,7 @@
  */
 
 #include "hb-ot-shape-fallback.hh"
-#include "hb-ot-kern-table.hh"
+#include "hb-kern.hh"
 
 static unsigned int
 recategorize_combining_class (hb_codepoint_t u,
@@ -464,9 +464,18 @@
       !font->has_glyph_h_kerning_func () :
       !font->has_glyph_v_kerning_func ())
     return;
+
+  bool reverse = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+
+  if (reverse)
+    buffer->reverse ();
+
   hb_ot_shape_fallback_kern_driver_t driver (font, buffer);
-  hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver);
+  OT::hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver);
   machine.kern (font, buffer, plan->kern_mask, false);
+
+  if (reverse)
+    buffer->reverse ();
 }
 
 
@@ -500,16 +509,16 @@
 	case t::SPACE_EM_6:
 	case t::SPACE_EM_16:
 	  if (horizontal)
-	    pos[i].x_advance = (font->x_scale + ((int) space_type)/2) / (int) space_type;
+	    pos[i].x_advance = +(font->x_scale + ((int) space_type)/2) / (int) space_type;
 	  else
-	    pos[i].y_advance = (font->y_scale + ((int) space_type)/2) / (int) space_type;
+	    pos[i].y_advance = -(font->y_scale + ((int) space_type)/2) / (int) space_type;
 	  break;
 
 	case t::SPACE_4_EM_18:
 	  if (horizontal)
-	    pos[i].x_advance = (int64_t) font->x_scale * 4 / 18;
+	    pos[i].x_advance = (int64_t) +font->x_scale * 4 / 18;
 	  else
-	    pos[i].y_advance = (int64_t) font->y_scale * 4 / 18;
+	    pos[i].y_advance = (int64_t) -font->y_scale * 4 / 18;
 	  break;
 
 	case t::SPACE_FIGURE:

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -26,8 +26,6 @@
  * Google Author(s): Behdad Esfahbod
  */
 
-#define HB_SHAPER ot
-#define hb_ot_shape_plan_data_t hb_ot_shape_plan_t
 #include "hb-shaper-impl.hh"
 
 #include "hb-ot-shape.hh"
@@ -52,6 +50,11 @@
  **/
 
 
+static void
+hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
+			      const hb_feature_t             *user_features,
+			      unsigned int                    num_user_features);
+
 static bool
 _hb_apply_morx (hb_face_t *face)
 {
@@ -59,15 +62,20 @@
       hb_aat_layout_has_substitution (face))
     return true;
 
-  return !hb_ot_layout_has_substitution (face) &&
+  /* Ignore empty GSUB tables. */
+  return (!hb_ot_layout_has_substitution (face) ||
+	  !hb_ot_layout_table_get_script_tags (face,
+					       HB_OT_TAG_GSUB,
+					       0, nullptr, nullptr)) &&
 	 hb_aat_layout_has_substitution (face);
 }
 
-hb_ot_shape_planner_t::hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
-						face (master_plan->face_unsafe),
-						props (master_plan->props),
-						map (face, &props),
-						aat_map (face, &props),
+hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t                     *face,
+					      const hb_segment_properties_t *props) :
+						face (face),
+						props (*props),
+						map (face, props),
+						aat_map (face, props),
 						apply_morx (_hb_apply_morx (face)),
 						shaper (apply_morx ?
 						        &_hb_ot_complex_shaper_default :
@@ -74,15 +82,14 @@
 							hb_ot_shape_complex_categorize (this)) {}
 
 void
-hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
-				const int          *coords,
-				unsigned int        num_coords)
+hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t           &plan,
+				const hb_ot_shape_plan_key_t &key)
 {
   plan.props = props;
   plan.shaper = shaper;
-  map.compile (plan.map, coords, num_coords);
+  map.compile (plan.map, key);
   if (apply_morx)
-    aat_map.compile (plan.aat_map, coords, num_coords);
+    aat_map.compile (plan.aat_map);
 
   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'));
@@ -89,7 +96,7 @@
   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);
   plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
-  hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
+  hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ?
 		      HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
   plan.kern_mask = plan.map.get_mask (kern_tag);
   plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
@@ -119,31 +126,92 @@
 
   if (hb_options ().aat && hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
-  else if (!disable_gpos && hb_ot_layout_has_positioning (face))
+  else if (!apply_morx && !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)
+  if (!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))
+    else if (hb_ot_layout_has_kerning (face))
       plan.apply_kern = true;
-    else
-      plan.fallback_kerning = true;
   }
 
+  bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face);
+  plan.zero_marks = !plan.apply_morx && !plan.apply_kerx && !has_kern_mark;
   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;
+  plan.fallback_mark_positioning = !plan.apply_gpos && plan.zero_marks;
 
   /* Currently we always apply trak. */
   plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
 }
 
+bool
+hb_ot_shape_plan_t::init0 (hb_face_t                     *face,
+			   const hb_shape_plan_key_t     *key)
+{
+  map.init ();
+  aat_map.init ();
 
+  hb_ot_shape_planner_t planner (face,
+				 &key->props);
+  hb_ot_shape_collect_features (&planner,
+				key->user_features,
+				key->num_user_features);
+
+  planner.compile (*this, key->ot);
+
+  if (shaper->data_create)
+  {
+    data = shaper->data_create (this);
+    if (unlikely (!data))
+      return false;
+  }
+
+  return true;
+}
+
+void
+hb_ot_shape_plan_t::fini (void)
+{
+  if (shaper->data_destroy)
+    shaper->data_destroy (const_cast<void *> (data));
+
+  map.fini ();
+  aat_map.fini ();
+}
+
+void
+hb_ot_shape_plan_t::substitute (hb_font_t   *font,
+				hb_buffer_t *buffer) const
+{
+  if (unlikely (apply_morx))
+    hb_aat_layout_substitute (this, font, buffer);
+  else
+    map.substitute (this, font, buffer);
+}
+
+void
+hb_ot_shape_plan_t::position (hb_font_t   *font,
+			      hb_buffer_t *buffer) const
+{
+  if (this->apply_gpos)
+    map.position (this, font, buffer);
+  else if (this->apply_kerx)
+    hb_aat_layout_position (this, font, buffer);
+  else if (this->apply_kern)
+    hb_ot_layout_kern (this, font, buffer);
+  else
+    _hb_ot_shape_fallback_kern (this, font, buffer);
+
+  if (this->apply_trak)
+    hb_aat_layout_track (this, font, buffer);
+}
+
+
 static const hb_ot_map_feature_t
 common_features[] =
 {
@@ -168,7 +236,6 @@
 
 static void
 hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
-			      const hb_segment_properties_t  *props,
 			      const hb_feature_t             *user_features,
 			      unsigned int                    num_user_features)
 {
@@ -177,7 +244,7 @@
   map->enable_feature (HB_TAG('r','v','r','n'));
   map->add_gsub_pause (nullptr);
 
-  switch (props->direction) {
+  switch (planner->props.direction) {
     case HB_DIRECTION_LTR:
       map->enable_feature (HB_TAG ('l','t','r','a'));
       map->enable_feature (HB_TAG ('l','t','r','m'));
@@ -216,7 +283,7 @@
   for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
     map->add_feature (common_features[i]);
 
-  if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
+  if (HB_DIRECTION_IS_HORIZONTAL (planner->props.direction))
     for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
       map->add_feature (horizontal_features[i]);
   else
@@ -256,18 +323,17 @@
  * shaper face data
  */
 
-HB_SHAPER_DATA_ENSURE_DEFINE(ot, face)
+struct hb_ot_face_data_t {};
 
 hb_ot_face_data_t *
 _hb_ot_shaper_face_data_create (hb_face_t *face)
 {
-  return _hb_ot_face_data_create (face);
+  return (hb_ot_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
 _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data)
 {
-  _hb_ot_face_data_destroy (data);
 }
 
 
@@ -275,8 +341,6 @@
  * shaper font data
  */
 
-HB_SHAPER_DATA_ENSURE_DEFINE(ot, font)
-
 struct hb_ot_font_data_t {};
 
 hb_ot_font_data_t *
@@ -292,54 +356,6 @@
 
 
 /*
- * shaper shape_plan data
- */
-
-hb_ot_shape_plan_data_t *
-_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan,
-				      const hb_feature_t *user_features,
-				      unsigned int        num_user_features,
-				      const int          *coords,
-				      unsigned int        num_coords)
-{
-  hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
-  if (unlikely (!plan))
-    return nullptr;
-
-  plan->init ();
-
-  hb_ot_shape_planner_t planner (shape_plan);
-
-  hb_ot_shape_collect_features (&planner, &shape_plan->props,
-				user_features, num_user_features);
-
-  planner.compile (*plan, coords, num_coords);
-
-  if (plan->shaper->data_create) {
-    plan->data = plan->shaper->data_create (plan);
-    if (unlikely (!plan->data))
-    {
-      free (plan);
-      return nullptr;
-    }
-  }
-
-  return plan;
-}
-
-void
-_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shape_plan_data_t *plan)
-{
-  if (plan->shaper->data_destroy)
-    plan->shaper->data_destroy (const_cast<void *> (plan->data));
-
-  plan->fini ();
-
-  free (plan);
-}
-
-
-/*
  * shaper
  */
 
@@ -476,7 +492,9 @@
 }
 
 
-/* Substitute */
+/*
+ * Substitute
+ */
 
 static inline void
 hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
@@ -582,10 +600,8 @@
 }
 
 static void
-hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c)
+hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer)
 {
-  hb_buffer_t *buffer = c->buffer;
-
   if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
       (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) ||
       (buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES))
@@ -601,10 +617,9 @@
 }
 
 static void
-hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c)
+hb_ot_hide_default_ignorables (hb_buffer_t *buffer,
+			       hb_font_t   *font)
 {
-  hb_buffer_t *buffer = c->buffer;
-
   if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
       (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES))
     return;
@@ -611,11 +626,10 @@
 
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
-  hb_glyph_position_t *pos = buffer->pos;
 
-  hb_codepoint_t invisible = c->buffer->invisible;
+  hb_codepoint_t invisible = buffer->invisible;
   if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) &&
-      (invisible || c->font->get_nominal_glyph (' ', &invisible)))
+      (invisible || font->get_nominal_glyph (' ', &invisible)))
   {
     /* Replace default-ignorables with a zero-advance invisible glyph. */
     for (unsigned int i = 0; i < count; i++)
@@ -625,49 +639,7 @@
     }
   }
   else
-  {
-    /* Merge clusters and delete default-ignorables.
-     * NOTE! We can't use out-buffer as we have positioning data. */
-    unsigned int j = 0;
-    for (unsigned int i = 0; i < count; i++)
-    {
-      if (_hb_glyph_info_is_default_ignorable (&info[i]))
-      {
-	/* Merge clusters.
-	 * Same logic as buffer->delete_glyph(), but for in-place removal. */
-
-	unsigned int cluster = info[i].cluster;
-	if (i + 1 < count && cluster == info[i + 1].cluster)
-	  continue; /* Cluster survives; do nothing. */
-
-	if (j)
-	{
-	  /* Merge cluster backward. */
-	  if (cluster < info[j - 1].cluster)
-	  {
-	    unsigned int mask = info[i].mask;
-	    unsigned int old_cluster = info[j - 1].cluster;
-	    for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
-	      buffer->set_cluster (info[k - 1], cluster, mask);
-	  }
-	  continue;
-	}
-
-	if (i + 1 < count)
-	  buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */
-
-	continue;
-      }
-
-      if (j != i)
-      {
-	info[j] = info[i];
-	pos[j] = pos[i];
-      }
-      j++;
-    }
-    buffer->len = j;
-  }
+    hb_ot_layout_delete_glyphs_inplace (buffer, _hb_glyph_info_is_default_ignorable);
 }
 
 
@@ -684,10 +656,10 @@
 }
 
 static inline void
-hb_synthesize_glyph_classes (const hb_ot_shape_context_t *c)
+hb_synthesize_glyph_classes (hb_buffer_t *buffer)
 {
-  unsigned int count = c->buffer->len;
-  hb_glyph_info_t *info = c->buffer->info;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
   {
     hb_ot_layout_glyph_props_flags_t klass;
@@ -739,16 +711,13 @@
   hb_ot_layout_substitute_start (c->font, buffer);
 
   if (c->plan->fallback_glyph_classes)
-    hb_synthesize_glyph_classes (c);
+    hb_synthesize_glyph_classes (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);
+  c->plan->substitute (c->font, buffer);
 }
 
 static inline void
-hb_ot_substitute (const hb_ot_shape_context_t *c)
+hb_ot_substitute_pre (const hb_ot_shape_context_t *c)
 {
   hb_ot_substitute_default (c);
 
@@ -757,8 +726,22 @@
   hb_ot_substitute_complex (c);
 }
 
-/* Position */
+static inline void
+hb_ot_substitute_post (const hb_ot_shape_context_t *c)
+{
+  hb_ot_hide_default_ignorables (c->buffer, c->font);
+  if (c->plan->apply_morx)
+    hb_aat_layout_remove_deleted_glyphs (c->buffer);
 
+  if (c->plan->shaper->postprocess_glyphs)
+    c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
+}
+
+
+/*
+ * Position
+ */
+
 static inline void
 adjust_mark_offsets (hb_glyph_position_t *pos)
 {
@@ -852,7 +835,7 @@
 
   hb_ot_layout_position_start (c->font, c->buffer);
 
-  if (!c->plan->apply_kerx)
+  if (c->plan->zero_marks)
     switch (c->plan->shaper->zero_width_marks)
     {
       case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
@@ -865,15 +848,9 @@
 	break;
     }
 
-  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);
+  c->plan->position (c->font, c->buffer);
 
-  if (c->plan->apply_trak)
-    hb_aat_layout_track (c->plan, c->font, c->buffer);
-
-  if (!c->plan->apply_kerx)
+  if (c->plan->zero_marks)
     switch (c->plan->shaper->zero_width_marks)
     {
       case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
@@ -886,9 +863,11 @@
 	break;
     }
 
-  /* Finishing off GPOS has to follow a certain order. */
+  /* Finish off.  Has to follow a certain order. */
   hb_ot_layout_position_finish_advances (c->font, c->buffer);
-  hb_ot_zero_width_default_ignorables (c);
+  hb_ot_zero_width_default_ignorables (c->buffer);
+  if (c->plan->apply_morx)
+    hb_aat_layout_zero_width_deleted_glyphs (c->buffer);
   hb_ot_layout_position_finish_offsets (c->font, c->buffer);
 
   /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
@@ -897,6 +876,9 @@
       c->font->subtract_glyph_h_origin (info[i].codepoint,
 					&pos[i].x_offset,
 					&pos[i].y_offset);
+
+  if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
+    _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
 }
 
 static inline void
@@ -908,19 +890,9 @@
 
   hb_ot_position_complex (c);
 
-  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);
 
-  /* Visual fallback goes here. */
-
-  if (c->plan->apply_kern)
-    hb_ot_layout_kern (c->plan, c->font, c->buffer);
-  else if (c->plan->fallback_kerning)
-    _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
-
   _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
 }
 
@@ -986,14 +958,10 @@
   if (c->plan->shaper->preprocess_text)
     c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
 
-  hb_ot_substitute (c);
+  hb_ot_substitute_pre (c);
   hb_ot_position (c);
+  hb_ot_substitute_post (c);
 
-  hb_ot_hide_default_ignorables (c);
-
-  if (c->plan->shaper->postprocess_glyphs)
-    c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
-
   hb_propagate_flags (c->buffer);
 
   _hb_buffer_deallocate_unicode_vars (c->buffer);
@@ -1013,7 +981,7 @@
 	      const hb_feature_t *features,
 	      unsigned int        num_features)
 {
-  hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features};
+  hb_ot_shape_context_t c = {&shape_plan->ot, font, font->face, buffer, features, num_features};
   hb_ot_shape_internal (&c);
 
   return true;
@@ -1030,8 +998,7 @@
 				  hb_tag_t         table_tag,
 				  hb_set_t        *lookup_indexes /* OUT */)
 {
-  /* XXX Does the first part always succeed? */
-  HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes);
+  shape_plan->ot.collect_lookups (table_tag, lookup_indexes);
 }
 
 

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -31,10 +31,33 @@
 
 #include "hb-ot-map.hh"
 #include "hb-aat-map.hh"
-#include "hb-shape-plan.hh"
 
 
+struct hb_ot_shape_plan_key_t
+{
+  unsigned int variations_index[2];
 
+  inline void init (hb_face_t   *face,
+		    const int   *coords,
+		    unsigned int num_coords)
+  {
+    for (unsigned int table_index = 0; table_index < 2; table_index++)
+      hb_ot_layout_table_find_feature_variations (face,
+						  table_tags[table_index],
+						  coords,
+						  num_coords,
+						  &variations_index[table_index]);
+  }
+
+  inline bool equal (const hb_ot_shape_plan_key_t *other)
+  {
+    return 0 == memcmp (this, other, sizeof (*this));
+  }
+};
+
+
+struct hb_shape_plan_key_t;
+
 struct hb_ot_shape_plan_t
 {
   hb_segment_properties_t props;
@@ -51,8 +74,8 @@
   bool requested_tracking : 1;
   bool has_frac : 1;
   bool has_gpos_mark : 1;
+  bool zero_marks : 1;
   bool fallback_glyph_classes : 1;
-  bool fallback_kerning : 1;
   bool fallback_mark_positioning : 1;
 
   bool apply_gpos : 1;
@@ -61,7 +84,6 @@
   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;
@@ -72,21 +94,17 @@
     }
     map.collect_lookups (table_index, lookups);
   }
-  inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
-  inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); }
 
-  void init (void)
-  {
-    memset (this, 0, sizeof (*this));
-    map.init ();
-    aat_map.init ();
-  }
-  void fini (void) {
-    map.fini ();
-    aat_map.fini ();
-  }
+  HB_INTERNAL bool init0 (hb_face_t                     *face,
+			  const hb_shape_plan_key_t     *key);
+  HB_INTERNAL void fini (void);
+
+  HB_INTERNAL void substitute (hb_font_t *font, hb_buffer_t *buffer) const;
+  HB_INTERNAL void position (hb_font_t *font, hb_buffer_t *buffer) const;
 };
 
+struct hb_shape_plan_t;
+
 struct hb_ot_shape_planner_t
 {
   /* In the order that they are filled in. */
@@ -97,11 +115,11 @@
   bool apply_morx : 1;
   const struct hb_ot_complex_shaper_t *shaper;
 
-  HB_INTERNAL hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan);
+  HB_INTERNAL hb_ot_shape_planner_t (hb_face_t                     *face,
+				     const hb_segment_properties_t *props);
 
-  HB_INTERNAL void compile (hb_ot_shape_plan_t &plan,
-			    const int          *coords,
-			    unsigned int        num_coords);
+  HB_INTERNAL void compile (hb_ot_shape_plan_t           &plan,
+			    const hb_ot_shape_plan_key_t &key);
 };
 
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -0,0 +1,280 @@
+/*
+ * 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_STAT_TABLE_HH
+#define HB_OT_STAT_TABLE_HH
+
+#include "hb-open-type.hh"
+#include "hb-ot-layout-common.hh"
+
+/*
+ * STAT -- Style Attributes
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/stat
+ */
+#define HB_OT_TAG_STAT HB_TAG('S','T','A','T')
+
+
+namespace OT {
+
+enum
+{
+  OLDER_SIBLING_FONT_ATTRIBUTE = 0x0001,	/* If set, this axis value table
+						 * provides axis value information
+						 * that is applicable to other fonts
+						 * within the same font family. This
+						 * is used if the other fonts were
+						 * released earlier and did not include
+						 * information about values for some axis.
+						 * If newer versions of the other
+						 * fonts include the information
+						 * themselves and are present,
+						 * then this record is ignored. */
+  ELIDABLE_AXIS_VALUE_NAME = 0x0002		/* If set, it indicates that the axis
+						 * value represents the “normal” value
+						 * for the axis and may be omitted when
+						 * composing name strings. */
+  // Reserved = 0xFFFC				/* Reserved for future use — set to zero. */
+};
+
+struct StatAxisRecord
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  Tag		axisTag;	/* A tag identifying the axis of design variation. */
+  NameID	axisNameID;	/* The name ID for entries in the 'name' table that
+				 * provide a display string for this axis. */
+  HBUINT16	axisOrdering;	/* A value that applications can use to determine
+				 * primary sorting of face names, or for ordering
+				 * of descriptors when composing family or face names. */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct AxisValueFormat1
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  HBUINT16	format;		/* Format identifier — set to 1. */
+  HBUINT16	axisIndex;	/* Zero-base index into the axis record array
+				 * identifying the axis of design variation
+				 * to which the axis value record applies.
+				 * Must be less than designAxisCount. */
+  HBUINT16	flags;		/* Flags — see below for details. */
+  NameID	valueNameID;	/* The name ID for entries in the 'name' table
+				 * that provide a display string for this
+				 * attribute value. */
+  Fixed		value;		/* A numeric value for this attribute value. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct AxisValueFormat2
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  HBUINT16	format;		/* Format identifier — set to 2. */
+  HBUINT16	axisIndex;	/* Zero-base index into the axis record array
+				 * identifying the axis of design variation
+				 * to which the axis value record applies.
+				 * Must be less than designAxisCount. */
+  HBUINT16	flags;		/* Flags — see below for details. */
+  NameID	valueNameID;	/* The name ID for entries in the 'name' table
+				 * that provide a display string for this
+				 * attribute value. */
+  Fixed		nominalValue;	/* A numeric value for this attribute value. */
+  Fixed		rangeMinValue;	/* The minimum value for a range associated
+				 * with the specified name ID. */
+  Fixed		rangeMaxValue;	/* The maximum value for a range associated
+				 * with the specified name ID. */
+  public:
+  DEFINE_SIZE_STATIC (20);
+};
+
+struct AxisValueFormat3
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  HBUINT16	format;		/* Format identifier — set to 3. */
+  HBUINT16	axisIndex;	/* Zero-base index into the axis record array
+				 * identifying the axis of design variation
+				 * to which the axis value record applies.
+				 * Must be less than designAxisCount. */
+  HBUINT16	flags;		/* Flags — see below for details. */
+  NameID	valueNameID;	/* The name ID for entries in the 'name' table
+				 * that provide a display string for this
+				 * attribute value. */
+  Fixed		value;		/* A numeric value for this attribute value. */
+  Fixed		linkedValue;	/* The numeric value for a style-linked mapping
+				 * from this value. */
+  public:
+  DEFINE_SIZE_STATIC (16);
+};
+
+struct AxisValueRecord
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  HBUINT16	axisIndex;	/* Zero-base index into the axis record array
+				 * identifying the axis to which this value
+				 * applies. Must be less than designAxisCount. */
+  Fixed		value;		/* A numeric value for this attribute value. */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct AxisValueFormat4
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  protected:
+  HBUINT16	format;		/* Format identifier — set to 4. */
+  HBUINT16	axisCount;	/* The total number of axes contributing to
+				 * this axis-values combination. */
+  HBUINT16	flags;		/* Flags — see below for details. */
+  NameID	valueNameID;	/* The name ID for entries in the 'name' table
+				 * that provide a display string for this
+				 * attribute value. */
+  UnsizedArrayOf<AxisValueRecord>
+		axisValues;	/* Array of AxisValue records that provide the
+				 * combination of axis values, one for each
+				 * contributing axis. */
+  public:
+  DEFINE_SIZE_ARRAY (8, axisValues);
+};
+
+struct AxisValue
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (c->check_struct (this)))
+      return_trace (false);
+
+    switch (u.format)
+    {
+    case 1:  return_trace (likely (u.format1.sanitize (c)));
+    case 2:  return_trace (likely (u.format2.sanitize (c)));
+    case 3:  return_trace (likely (u.format3.sanitize (c)));
+    case 4:  return_trace (likely (u.format4.sanitize (c)));
+    default: return_trace (true);
+    }
+  }
+
+  protected:
+  union
+  {
+  HBUINT16		format;
+  AxisValueFormat1	format1;
+  AxisValueFormat2	format2;
+  AxisValueFormat3	format3;
+  AxisValueFormat4	format4;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+struct STAT
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_STAT;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  majorVersion == 1 &&
+			  minorVersion > 0 &&
+			  designAxesOffset.sanitize (c, this, designAxisCount) &&
+			  offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
+  }
+
+  protected:
+  HBUINT16	majorVersion;	/* Major version number of the style attributes
+				 * table — set to 1. */
+  HBUINT16	minorVersion;	/* Minor version number of the style attributes
+				 * table — set to 2. */
+  HBUINT16	designAxisSize;	/* The size in bytes of each axis record. */
+  HBUINT16	designAxisCount;/* The number of design axis records. In a
+				 * font with an 'fvar' table, this value must be
+				 * greater than or equal to the axisCount value
+				 * in the 'fvar' table. In all fonts, must
+				 * be greater than zero if axisValueCount
+				 * is greater than zero. */
+  LOffsetTo<UnsizedArrayOf<StatAxisRecord>, false>
+		designAxesOffset;
+				/* Offset in bytes from the beginning of
+				 * the STAT table to the start of the design
+				 * axes array. If designAxisCount is zero,
+				 * set to zero; if designAxisCount is greater
+				 * than zero, must be greater than zero. */
+  HBUINT16	axisValueCount;	/* The number of axis value tables. */
+  LOffsetTo<UnsizedArrayOf<OffsetTo<AxisValue> >, false>
+		offsetToAxisValueOffsets;
+				/* Offset in bytes from the beginning of
+				 * the STAT table to the start of the design
+				 * axes value offsets array. If axisValueCount
+				 * is zero, set to zero; if axisValueCount is
+				 * greater than zero, must be greater than zero. */
+  NameID	elidedFallbackNameID;
+				/* Name ID used as fallback when projection of
+				 * names into a particular font model produces
+				 * a subfamily name containing only elidable
+				 * elements. */
+  public:
+  DEFINE_SIZE_STATIC (20);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_STAT_TABLE_HH */

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -94,7 +94,7 @@
   }
 
   public:
-  DEFINE_SIZE_ARRAY (2, arrayZ);
+  DEFINE_SIZE_ARRAY (2, *this);
 };
 
 struct avar
@@ -109,7 +109,7 @@
 		    c->check_struct (this))))
       return_trace (false);
 
-    const SegmentMaps *map = axisSegmentMapsZ.arrayZ;
+    const SegmentMaps *map = &firstAxisSegmentMaps;
     unsigned int count = axisCount;
     for (unsigned int i = 0; i < count; i++)
     {
@@ -125,7 +125,7 @@
   {
     unsigned int count = MIN<unsigned int> (coords_length, axisCount);
 
-    const SegmentMaps *map = axisSegmentMapsZ.arrayZ;
+    const SegmentMaps *map = &firstAxisSegmentMaps;
     for (unsigned int i = 0; i < count; i++)
     {
       coords[i] = map->map (coords[i]);
@@ -140,8 +140,7 @@
   HBUINT16	axisCount;	/* The number of variation axes in the font. This
 				 * must be the same number as axisCount in the
 				 * 'fvar' table. */
-  UnsizedArrayOf<SegmentMaps>
-		axisSegmentMapsZ;
+  SegmentMaps   firstAxisSegmentMaps;
 
   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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -88,7 +88,7 @@
 {
   static const hb_tag_t tableTag	= HB_OT_TAG_fvar;
 
-  inline bool has_data (void) const { return version.to_int () != 0; }
+  inline bool has_data (void) const { return version.to_int (); }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -39,7 +39,9 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  c->check_array (mapDataZ.arrayZ, mapCount, get_width ()));
+		  c->check_range (mapDataZ.arrayZ,
+				  mapCount,
+				  get_width ()));
   }
 
   unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */

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-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -68,7 +68,9 @@
 		  c->check_struct (this) &&
 		  valueRecordSize >= VariationValueRecord::static_size &&
 		  varStore.sanitize (c, this) &&
-		  c->check_array (valuesZ.arrayZ, valueRecordCount, valueRecordSize));
+		  c->check_range (valuesZ.arrayZ,
+				  valueRecordCount,
+				  valueRecordSize));
   }
 
   inline float get_var (hb_tag_t tag,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -47,18 +47,6 @@
  * fvar/avar
  */
 
-static inline const OT::fvar&
-_get_fvar (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::fvar);
-  return *(hb_ot_face_data (face)->fvar);
-}
-static inline const OT::avar&
-_get_avar (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::avar);
-  return *(hb_ot_face_data (face)->avar);
-}
 
 /**
  * hb_ot_var_has_data:
@@ -74,7 +62,7 @@
 hb_bool_t
 hb_ot_var_has_data (hb_face_t *face)
 {
-  return _get_fvar (face).has_data ();
+  return face->table.fvar->has_data ();
 }
 
 /**
@@ -85,8 +73,7 @@
 unsigned int
 hb_ot_var_get_axis_count (hb_face_t *face)
 {
-  const OT::fvar &fvar = _get_fvar (face);
-  return fvar.get_axis_count ();
+  return face->table.fvar->get_axis_count ();
 }
 
 /**
@@ -100,8 +87,7 @@
 		    unsigned int     *axes_count /* IN/OUT */,
 		    hb_ot_var_axis_t *axes_array /* OUT */)
 {
-  const OT::fvar &fvar = _get_fvar (face);
-  return fvar.get_axis_infos (start_offset, axes_count, axes_array);
+  return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array);
 }
 
 /**
@@ -115,8 +101,7 @@
 		     unsigned int     *axis_index,
 		     hb_ot_var_axis_t *axis_info)
 {
-  const OT::fvar &fvar = _get_fvar (face);
-  return fvar.find_axis (axis_tag, axis_index, axis_info);
+  return face->table.fvar->find_axis (axis_tag, axis_index, axis_info);
 }
 
 
@@ -135,7 +120,7 @@
   for (unsigned int i = 0; i < coords_length; i++)
     coords[i] = 0;
 
-  const OT::fvar &fvar = _get_fvar (face);
+  const OT::fvar &fvar = *face->table.fvar;
   for (unsigned int i = 0; i < variations_length; i++)
   {
     unsigned int axis_index;
@@ -144,8 +129,7 @@
       coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value);
   }
 
-  const OT::avar &avar = _get_avar (face);
-  avar.map_coords (coords, coords_length);
+  face->table.avar->map_coords (coords, coords_length);
 }
 
 /**
@@ -159,10 +143,9 @@
 			    const float *design_coords, /* IN */
 			    int *normalized_coords /* OUT */)
 {
-  const OT::fvar &fvar = _get_fvar (face);
+  const OT::fvar &fvar = *face->table.fvar;
   for (unsigned int i = 0; i < coords_length; i++)
     normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]);
 
-  const OT::avar &avar = _get_avar (face);
-  avar.map_coords (normalized_coords, coords_length);
+  face->table.avar->map_coords (normalized_coords, coords_length);
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -90,7 +90,7 @@
 
     inline bool is_equal (const page_t *other) const
     {
-      return 0 == memcmp (&v, &other->v, sizeof (v));
+      return 0 == hb_memcmp (&v, &other->v, sizeof (v));
     }
 
     inline unsigned int get_population (void) const
@@ -375,8 +375,8 @@
     if (!resize (count))
       return;
     population = other->population;
-    memcpy (pages, other->pages, count * sizeof (pages[0]));
-    memcpy (page_map, other->page_map, count * sizeof (page_map[0]));
+    memcpy (pages, other->pages, count * pages.item_size);
+    memcpy (page_map, other->page_map, count * page_map.item_size);
   }
 
   inline bool is_equal (const hb_set_t *other) const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -44,90 +44,120 @@
  **/
 
 
-static void
-hb_shape_plan_plan (hb_shape_plan_t    *shape_plan,
-		    const hb_feature_t *user_features,
-		    unsigned int        num_user_features,
-		    const int          *coords,
-		    unsigned int        num_coords,
-		    const char * const *shaper_list)
+/*
+ * hb_shape_plan_key_t
+ */
+
+bool
+hb_shape_plan_key_t::init (bool                           copy,
+			   hb_face_t                     *face,
+			   const hb_segment_properties_t *props,
+			   const hb_feature_t            *user_features,
+			   unsigned int                   num_user_features,
+			   const int                     *coords,
+			   unsigned int                   num_coords,
+			   const char * const            *shaper_list)
 {
-  DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
-		  "num_features=%d num_coords=%d shaper_list=%p",
-		  num_user_features,
-		  num_coords,
-		  shaper_list);
+  hb_feature_t *features = nullptr;
+  if (copy && num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t))))
+    goto bail;
 
-  const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+  this->props = *props;
+  this->num_user_features = num_user_features;
+  this->user_features = copy ? features : user_features;
+  if (copy && num_user_features)
+  {
+    memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
+    /* Make start/end uniform to easier catch bugs. */
+    for (unsigned int i = 0; i < num_user_features; i++)
+    {
+      if (features[0].start != HB_FEATURE_GLOBAL_START)
+	features[0].start = 1;
+      if (features[0].end   != HB_FEATURE_GLOBAL_END)
+	features[0].end   = 2;
+    }
+  }
+  this->shaper_func = nullptr;
+  this->shaper_name = nullptr;
+  this->ot.init (face, coords, num_coords);
 
+  /*
+   * Choose shaper.
+   */
+
 #define HB_SHAPER_PLAN(shaper) \
 	HB_STMT_START { \
-	  if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) \
+	  if (face->data.shaper) \
 	  { \
-	    /* XXX-MT-bug What happened to *ensure*ing this?!!!! */ \
-	    HB_SHAPER_DATA (shaper, shape_plan).set_relaxed ( \
-	      HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, \
-							       user_features, num_user_features, \
-							       coords, num_coords)); \
-	    shape_plan->shaper_func = _hb_##shaper##_shape; \
-	    shape_plan->shaper_name = #shaper; \
-	    return; \
+	    this->shaper_func = _hb_##shaper##_shape; \
+	    this->shaper_name = #shaper; \
+	    return true; \
 	  } \
 	} HB_STMT_END
 
-  if (likely (!shaper_list)) {
-    for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
+  if (unlikely (shaper_list))
+  {
+    for (; *shaper_list; shaper_list++)
       if (false)
 	;
 #define HB_SHAPER_IMPLEMENT(shaper) \
-      else if (shapers[i].func == _hb_##shaper##_shape) \
+      else if (0 == strcmp (*shaper_list, #shaper)) \
 	HB_SHAPER_PLAN (shaper);
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
-  } else {
-    for (; *shaper_list; shaper_list++)
+  }
+  else
+  {
+    const hb_shaper_entry_t *shapers = _hb_shapers_get ();
+    for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
       if (false)
 	;
 #define HB_SHAPER_IMPLEMENT(shaper) \
-      else if (0 == strcmp (*shaper_list, #shaper)) \
+      else if (shapers[i].func == _hb_##shaper##_shape) \
 	HB_SHAPER_PLAN (shaper);
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
   }
+#undef HB_SHAPER_PLAN
 
-#undef HB_SHAPER_PLAN
+bail:
+  ::free (features);
+  return false;
 }
 
+bool
+hb_shape_plan_key_t::user_features_match (const hb_shape_plan_key_t *other)
+{
+  if (this->num_user_features != other->num_user_features)
+    return false;
+  for (unsigned int i = 0; i < num_user_features; i++)
+  {
+    if (this->user_features[i].tag   != other->user_features[i].tag   ||
+	this->user_features[i].value != other->user_features[i].value ||
+	(this->user_features[i].start == HB_FEATURE_GLOBAL_START &&
+	 this->user_features[i].end   == HB_FEATURE_GLOBAL_END) !=
+	(other->user_features[i].start == HB_FEATURE_GLOBAL_START &&
+	 other->user_features[i].end   == HB_FEATURE_GLOBAL_END))
+      return false;
+  }
+  return true;
+}
 
+bool
+hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
+{
+  return hb_segment_properties_equal (&this->props, &other->props) &&
+	 this->user_features_match (other) &&
+	 this->ot.equal (&other->ot) &&
+	 this->shaper_func == other->shaper_func;
+}
+
+
 /*
  * hb_shape_plan_t
  */
 
-DEFINE_NULL_INSTANCE (hb_shape_plan_t) =
-{
-  HB_OBJECT_HEADER_STATIC,
 
-  true, /* default_shaper_list */
-  nullptr, /* face */
-  HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
-
-  nullptr, /* shaper_func */
-  nullptr, /* shaper_name */
-
-  nullptr, /* user_features */
-  0,    /* num_user_featurs */
-
-  nullptr, /* coords */
-  0,    /* num_coords */
-
-  {
-#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID),
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-  },
-};
-
-
 /**
  * hb_shape_plan_create: (Xconstructor)
  * @face: 
@@ -160,7 +190,7 @@
 		       const hb_segment_properties_t *props,
 		       const hb_feature_t            *user_features,
 		       unsigned int                   num_user_features,
-		       const int                     *orig_coords,
+		       const int                     *coords,
 		       unsigned int                   num_coords,
 		       const char * const            *shaper_list)
 {
@@ -171,49 +201,40 @@
 		  num_coords,
 		  shaper_list);
 
+  assert (props->direction != HB_DIRECTION_INVALID);
+
   hb_shape_plan_t *shape_plan;
-  hb_feature_t *features = nullptr;
-  int *coords = nullptr;
 
-  if (unlikely (!face))
-    face = hb_face_get_empty ();
   if (unlikely (!props))
-    return hb_shape_plan_get_empty ();
-  if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t))))
-    return hb_shape_plan_get_empty ();
-  if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int))))
-  {
-    free (features);
-    return hb_shape_plan_get_empty ();
-  }
+    goto bail;
   if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
-  {
-    free (coords);
-    free (features);
-    return hb_shape_plan_get_empty ();
-  }
+    goto bail;
 
-  assert (props->direction != HB_DIRECTION_INVALID);
-
+  if (unlikely (!face))
+    face = hb_face_get_empty ();
   hb_face_make_immutable (face);
-  shape_plan->default_shaper_list = !shaper_list;
   shape_plan->face_unsafe = face;
-  shape_plan->props = *props;
-  shape_plan->num_user_features = num_user_features;
-  shape_plan->user_features = features;
-  if (num_user_features)
-    memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
-  shape_plan->num_coords = num_coords;
-  shape_plan->coords = coords;
-  if (num_coords)
-    memcpy (coords, orig_coords, num_coords * sizeof (int));
 
-  hb_shape_plan_plan (shape_plan,
-		      user_features, num_user_features,
-		      coords, num_coords,
-		      shaper_list);
+  if (unlikely (!shape_plan->key.init (true,
+				       face,
+				       props,
+				       user_features,
+				       num_user_features,
+				       coords,
+				       num_coords,
+				       shaper_list)))
+    goto bail2;
+  if (unlikely (!shape_plan->ot.init0 (face, &shape_plan->key)))
+    goto bail3;
 
   return shape_plan;
+
+bail3:
+  shape_plan->key.free ();
+bail2:
+  free (shape_plan);
+bail:
+  return hb_shape_plan_get_empty ();
 }
 
 /**
@@ -260,13 +281,8 @@
 {
   if (!hb_object_destroy (shape_plan)) return;
 
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-
-  free (shape_plan->user_features);
-  free (shape_plan->coords);
-
+  shape_plan->ot.fini ();
+  shape_plan->key.free ();
   free (shape_plan);
 }
 
@@ -312,7 +328,23 @@
   return hb_object_get_user_data (shape_plan, key);
 }
 
+/**
+ * hb_shape_plan_get_shaper:
+ * @shape_plan: a shape plan.
+ *
+ * 
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.7
+ **/
+const char *
+hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
+{
+  return shape_plan->key.shaper_name;
+}
 
+
 /**
  * hb_shape_plan_execute:
  * @shape_plan: a shape plan.
@@ -337,8 +369,8 @@
   DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
 		  "num_features=%d shaper_func=%p, shaper_name=%s",
 		  num_features,
-		  shape_plan->shaper_func,
-		  shape_plan->shaper_name);
+		  shape_plan->key.shaper_func,
+		  shape_plan->key.shaper_name);
 
   if (unlikely (!buffer->len))
     return true;
@@ -350,12 +382,11 @@
     return false;
 
   assert (shape_plan->face_unsafe == font->face);
-  assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
+  assert (hb_segment_properties_equal (&shape_plan->key.props, &buffer->props));
 
 #define HB_SHAPER_EXECUTE(shaper) \
 	HB_STMT_START { \
-	  return HB_SHAPER_DATA (shaper, shape_plan).get () && \
-		 hb_##shaper##_shaper_font_data_ensure (font) && \
+	  return font->data.shaper && \
 		 _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
 	} HB_STMT_END
 
@@ -362,7 +393,7 @@
   if (false)
     ;
 #define HB_SHAPER_IMPLEMENT(shaper) \
-  else if (shape_plan->shaper_func == _hb_##shaper##_shape) \
+  else if (shape_plan->key.shaper_func == _hb_##shaper##_shape) \
     HB_SHAPER_EXECUTE (shaper);
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
@@ -374,92 +405,9 @@
 
 
 /*
- * caching
+ * Caching
  */
 
-#if 0
-static unsigned int
-hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
-{
-  return hb_segment_properties_hash (&shape_plan->props) +
-	 shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_func;
-}
-#endif
-
-/* User-feature caching is currently somewhat dumb:
- * it only finds matches where the feature array is identical,
- * not cases where the feature lists would be compatible for plan purposes
- * but have different ranges, for example.
- */
-struct hb_shape_plan_proposal_t
-{
-  const hb_segment_properties_t  props;
-  const char * const            *shaper_list;
-  const hb_feature_t            *user_features;
-  unsigned int                   num_user_features;
-  const int                     *coords;
-  unsigned int                   num_coords;
-  hb_shape_func_t               *shaper_func;
-};
-
-static inline hb_bool_t
-hb_shape_plan_user_features_match (const hb_shape_plan_t          *shape_plan,
-				   const hb_shape_plan_proposal_t *proposal)
-{
-  if (proposal->num_user_features != shape_plan->num_user_features)
-    return false;
-  for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
-    if (proposal->user_features[i].tag   != shape_plan->user_features[i].tag   ||
-        proposal->user_features[i].value != shape_plan->user_features[i].value ||
-        proposal->user_features[i].start != shape_plan->user_features[i].start ||
-        proposal->user_features[i].end   != shape_plan->user_features[i].end)
-      return false;
-  return true;
-}
-
-static inline hb_bool_t
-hb_shape_plan_coords_match (const hb_shape_plan_t          *shape_plan,
-			    const hb_shape_plan_proposal_t *proposal)
-{
-  if (proposal->num_coords != shape_plan->num_coords)
-    return false;
-  for (unsigned int i = 0, n = proposal->num_coords; i < n; i++)
-    if (proposal->coords[i] != shape_plan->coords[i])
-      return false;
-  return true;
-}
-
-static hb_bool_t
-hb_shape_plan_matches (const hb_shape_plan_t          *shape_plan,
-		       const hb_shape_plan_proposal_t *proposal)
-{
-  return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
-	 hb_shape_plan_user_features_match (shape_plan, proposal) &&
-	 hb_shape_plan_coords_match (shape_plan, proposal) &&
-	 ((shape_plan->default_shaper_list && !proposal->shaper_list) ||
-	  (shape_plan->shaper_func == proposal->shaper_func));
-}
-
-static inline hb_bool_t
-hb_non_global_user_features_present (const hb_feature_t *user_features,
-				     unsigned int        num_user_features)
-{
-  while (num_user_features) {
-    if (user_features->start != 0 || user_features->end != (unsigned int) -1)
-      return true;
-    num_user_features--;
-    user_features++;
-  }
-  return false;
-}
-
-static inline hb_bool_t
-hb_coords_present (const int *coords HB_UNUSED,
-		   unsigned int num_coords)
-{
-  return num_coords != 0;
-}
-
 /**
  * hb_shape_plan_create_cached:
  * @face: 
@@ -502,64 +450,40 @@
 		  num_user_features,
 		  shaper_list);
 
-  hb_shape_plan_proposal_t proposal = {
-    *props,
-    shaper_list,
-    user_features,
-    num_user_features,
-    nullptr
-  };
+retry:
+  hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans;
 
-  if (shaper_list) {
-    /* Choose shaper.  Adapted from hb_shape_plan_plan().
-     * Must choose shaper exactly the same way as that function. */
-    for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++)
-      if (false)
-	;
-#define HB_SHAPER_IMPLEMENT(shaper) \
-      else if (0 == strcmp (*shaper_item, #shaper) && \
-	       hb_##shaper##_shaper_face_data_ensure (face)) \
-      { \
-	proposal.shaper_func = _hb_##shaper##_shape; \
-	break; \
-      }
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
+  bool dont_cache = hb_object_is_inert (face);
 
-    if (unlikely (!proposal.shaper_func))
+  if (likely (!dont_cache))
+  {
+    hb_shape_plan_key_t key;
+    if (!key.init (false,
+		   face,
+		   props,
+		   user_features,
+		   num_user_features,
+		   coords,
+		   num_coords,
+		   shaper_list))
       return hb_shape_plan_get_empty ();
-  }
 
-
-retry:
-  hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans;
-
-  /* Don't look for plan in the cache if there were variation coordinates XXX Fix me. */
-  if (!hb_coords_present (coords, num_coords))
     for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
-      if (hb_shape_plan_matches (node->shape_plan, &proposal))
+      if (node->shape_plan->key.equal (&key))
       {
         DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
         return hb_shape_plan_reference (node->shape_plan);
       }
+  }
 
-  /* Not found. */
   hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props,
 						       user_features, num_user_features,
 						       coords, num_coords,
 						       shaper_list);
 
-  /* Don't add to the cache if face is inert. */
-  if (unlikely (hb_object_is_inert (face)))
+  if (unlikely (dont_cache))
     return shape_plan;
 
-  /* Don't add the plan to the cache if there were user features with non-global ranges */
-  if (hb_non_global_user_features_present (user_features, num_user_features))
-    return shape_plan;
-  /* Don't add the plan to the cache if there were variation coordinates XXX Fix me. */
-  if (hb_coords_present (coords, num_coords))
-    return shape_plan;
-
   hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
   if (unlikely (!node))
     return shape_plan;
@@ -577,19 +501,3 @@
 
   return hb_shape_plan_reference (shape_plan);
 }
-
-/**
- * hb_shape_plan_get_shaper:
- * @shape_plan: a shape plan.
- *
- * 
- *
- * Return value: (transfer none):
- *
- * Since: 0.9.7
- **/
-const char *
-hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
-{
-  return shape_plan->shaper_name;
-}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2012  Google, Inc.
+ * Copyright © 2012,2018  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -29,38 +29,47 @@
 
 #include "hb.hh"
 #include "hb-shaper.hh"
+#include "hb-ot-shape.hh"
 
 
-struct hb_shape_plan_t
+struct hb_shape_plan_key_t
 {
-  hb_object_header_t header;
+  hb_segment_properties_t  props;
 
-  hb_bool_t default_shaper_list;
-  hb_face_t *face_unsafe; /* We don't carry a reference to face. */
-  hb_segment_properties_t props;
+  const hb_feature_t      *user_features;
+  unsigned int             num_user_features;
 
-  hb_shape_func_t *shaper_func;
-  const char *shaper_name;
+  hb_ot_shape_plan_key_t   ot;
 
-  hb_feature_t *user_features;
-  unsigned int num_user_features;
+  hb_shape_func_t         *shaper_func;
+  const char              *shaper_name;
 
-  int *coords;
-  unsigned int num_coords;
+  HB_INTERNAL inline bool init (bool                           copy,
+				hb_face_t                     *face,
+				const hb_segment_properties_t *props,
+				const hb_feature_t            *user_features,
+				unsigned int                   num_user_features,
+				const int                     *coords,
+				unsigned int                   num_coords,
+				const char * const            *shaper_list);
 
-  struct hb_shaper_data_t shaper_data;
+  HB_INTERNAL inline void free (void)
+  {
+    ::free ((void *) user_features);
+  }
+
+  HB_INTERNAL bool user_features_match (const hb_shape_plan_key_t *other);
+
+  HB_INTERNAL bool equal (const hb_shape_plan_key_t *other);
 };
-DECLARE_NULL_INSTANCE (hb_shape_plan_t);
 
-#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \
-	, const hb_feature_t *user_features \
-	, unsigned int        num_user_features \
-	, const int          *coords \
-	, unsigned int        num_coords
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan);
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+struct hb_shape_plan_t
+{
+  hb_object_header_t header;
+  hb_face_t *face_unsafe; /* We don't carry a reference to face. */
+  hb_shape_plan_key_t key;
+  hb_ot_shape_plan_t ot;
+};
 
 
 #endif /* HB_SHAPE_PLAN_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -63,7 +63,7 @@
     if (unlikely (!shaper_list))
       return nullptr;
 
-    const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+    const hb_shaper_entry_t *shapers = _hb_shapers_get ();
     unsigned int i;
     for (i = 0; i < HB_SHAPERS_COUNT; i++)
       shaper_list[i] = shapers[i].name;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-impl.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-impl.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-impl.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -30,14 +30,9 @@
 #include "hb.hh"
 
 #include "hb-shaper.hh"
+#include "hb-face.hh"
+#include "hb-font.hh"
 #include "hb-shape-plan.hh"
-#include "hb-font.hh"
 #include "hb-buffer.hh"
 
-
-#ifdef HB_SHAPER
-#define HB_SHAPER_DATA_GET(object) HB_SHAPER_DATA (HB_SHAPER, object).get ()
-#endif
-
-
 #endif /* HB_SHAPER_IMPL_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -29,7 +29,7 @@
 #include "hb-machinery.hh"
 
 
-static const hb_shaper_pair_t all_shapers[] = {
+static const hb_shaper_entry_t all_shapers[] = {
 #define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
@@ -39,16 +39,16 @@
 static void free_static_shapers (void);
 #endif
 
-static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t,
+static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_t,
 							  hb_shapers_lazy_loader_t>
 {
-  static inline hb_shaper_pair_t *create (void)
+  static inline hb_shaper_entry_t *create (void)
   {
     char *env = getenv ("HB_SHAPER_LIST");
     if (!env || !*env)
       return nullptr;
 
-    hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers));
+    hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) calloc (1, sizeof (all_shapers));
     if (unlikely (!shapers))
       return nullptr;
 
@@ -68,7 +68,7 @@
 	    0 == strncmp (shapers[j].name, p, end - p))
 	{
 	  /* Reorder this shaper to position i */
-	 struct hb_shaper_pair_t t = shapers[j];
+	 struct hb_shaper_entry_t t = shapers[j];
 	 memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
 	 shapers[i] = t;
 	 i++;
@@ -86,11 +86,11 @@
 
     return shapers;
   }
-  static inline void destroy (const hb_shaper_pair_t *p)
+  static inline void destroy (const hb_shaper_entry_t *p)
   {
     free ((void *) p);
   }
-  static inline const hb_shaper_pair_t *get_null (void)
+  static inline const hb_shaper_entry_t *get_null (void)
   {
     return all_shapers;
   }
@@ -104,7 +104,7 @@
 }
 #endif
 
-const hb_shaper_pair_t *
+const hb_shaper_entry_t *
 _hb_shapers_get (void)
 {
   return static_shapers.get_unconst ();

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -28,6 +28,7 @@
 #define HB_SHAPER_HH
 
 #include "hb.hh"
+#include "hb-machinery.hh"
 
 typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t    *shape_plan,
 				   hb_font_t          *font,
@@ -40,95 +41,94 @@
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 
-struct hb_shaper_pair_t {
+struct hb_shaper_entry_t {
   char name[16];
   hb_shape_func_t *func;
 };
 
-HB_INTERNAL const hb_shaper_pair_t *
+HB_INTERNAL const hb_shaper_entry_t *
 _hb_shapers_get (void);
 
 
-/* Means: succeeded, but don't need to keep any data. */
+template <typename Data, unsigned int WheresData, typename T>
+struct hb_shaper_lazy_loader_t;
+
+#define HB_SHAPER_ORDER(Shaper) \
+  HB_PASTE (HB_SHAPER_ORDER_, Shaper)
+enum hb_shaper_order_t
+{
+  _HB_SHAPER_ORDER_ORDER_ZERO,
+#define HB_SHAPER_IMPLEMENT(Shaper) \
+      HB_SHAPER_ORDER (Shaper),
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+  _HB_SHAPERS_COUNT_PLUS_ONE,
+  HB_SHAPERS_COUNT = _HB_SHAPERS_COUNT_PLUS_ONE - 1,
+};
+
+template <enum hb_shaper_order_t order, typename Object> struct hb_shaper_object_data_type_t;
+
 #define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
-/* Means: tried but failed to create. */
-#define HB_SHAPER_DATA_INVALID ((void *) -1)
-
-#define HB_SHAPER_DATA_TYPE_NAME(shaper, object)	hb_##shaper##_##object##_data_t
-#define HB_SHAPER_DATA_TYPE(shaper, object)		struct HB_SHAPER_DATA_TYPE_NAME(shaper, object)
-#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance)	(* reinterpret_cast<hb_atomic_ptr_t<HB_SHAPER_DATA_TYPE(shaper, object) *> *> (&(instance)->shaper_data.shaper))
-#define HB_SHAPER_DATA(shaper, object)			HB_SHAPER_DATA_INSTANCE(shaper, object, object)
+#define HB_SHAPER_DATA_TYPE(shaper, object)		hb_##shaper##_##object##_data_t
 #define HB_SHAPER_DATA_CREATE_FUNC(shaper, object)	_hb_##shaper##_shaper_##object##_data_create
 #define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object)	_hb_##shaper##_shaper_##object##_data_destroy
-#define HB_SHAPER_DATA_ENSURE_FUNC(shaper, object)	hb_##shaper##_shaper_##object##_data_ensure
 
-#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
-	HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
+#define HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, object) \
+	\
+	struct HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
 	extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
-	HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \
+	HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object); \
 	extern "C" HB_INTERNAL void \
-	HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data); \
-	extern "C" HB_INTERNAL bool \
-	HB_SHAPER_DATA_ENSURE_FUNC (shaper, object) (hb_##object##_t *object)
+	HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *shaper##_##object); \
+	\
+	template <> \
+	struct hb_shaper_object_data_type_t<HB_SHAPER_ORDER (shaper), hb_##object##_t> \
+	{ \
+	  typedef HB_SHAPER_DATA_TYPE(shaper, object) value; \
+	}; \
+	\
+	template <unsigned int WheresData> \
+	struct hb_shaper_lazy_loader_t<hb_##object##_t, WheresData, HB_SHAPER_DATA_TYPE(shaper, object)> \
+		: hb_lazy_loader_t<HB_SHAPER_DATA_TYPE(shaper, object), \
+				   hb_shaper_lazy_loader_t<hb_##object##_t, \
+							   WheresData, \
+							   HB_SHAPER_DATA_TYPE(shaper, object)>, \
+				   hb_##object##_t, WheresData> \
+	{ \
+	  typedef HB_SHAPER_DATA_TYPE(shaper, object) Type; \
+	  static inline Type* create (hb_##object##_t *data) \
+	  { return HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (data); } \
+	  static inline Type *get_null (void) { return nullptr; } \
+	  static inline void destroy (Type *p) { HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (p); } \
+	}; \
+	\
+	static_assert (true, "") /* Require semicolon. */
 
-#define HB_SHAPER_DATA_DESTROY(shaper, object) \
-    if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get ()) \
-      if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
-        HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
 
-#define HB_SHAPER_DATA_ENSURE_DEFINE(shaper, object) \
-	HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, true)
+template <typename Object>
+struct hb_shaper_object_dataset_t
+{
+  inline void init0 (Object *parent_data)
+  {
+    this->parent_data = parent_data;
+#define HB_SHAPER_IMPLEMENT(shaper) shaper.init0 ();
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+  }
+  inline void fini (void)
+  {
+#define HB_SHAPER_IMPLEMENT(shaper) shaper.fini ();
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+  }
 
-#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \
-bool \
-HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
-{\
-  retry: \
-  HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get (); \
-  if (likely (data) && !(condition)) { \
-    /* XXX-MT-bug \
-     * Note that evaluating condition above can be dangerous if another thread \
-     * got here first and destructed data.  That's, as always, bad use pattern. \
-     * If you modify the font (change font size), other threads must not be \
-     * using it at the same time.  However, since this check is delayed to \
-     * when one actually tries to shape something, this is a XXX race condition \
-     * (and the only know we have that I know of) right now.  Ie. you modify the \
-     * font size in one thread, then (supposedly safely) try to use it from two \
-     * or more threads and BOOM!  I'm not sure how to fix this.  We want RCU. \
-     * Maybe when it doesn't matter when we finally implement AAT shaping, as
-     * this (condition) is currently only used by hb-coretext. */ \
-    /* Drop and recreate. */ \
-    /* If someone dropped it in the mean time, throw it away and don't touch it. \
-     * Otherwise, destruct it. */ \
-    if (likely (HB_SHAPER_DATA (shaper, object).cmpexch (data, nullptr))) \
-    { \
-      HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
-    } \
-    goto retry; \
-  } \
-  if (unlikely (!data)) { \
-    data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
-    if (unlikely (!data)) \
-      data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
-    if (unlikely (!HB_SHAPER_DATA (shaper, object).cmpexch (nullptr, data))) { \
-      if (data && \
-	  data != HB_SHAPER_DATA_INVALID && \
-	  data != HB_SHAPER_DATA_SUCCEEDED) \
-	HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
-      goto retry; \
-    } \
-  } \
-  return data != nullptr && (void *) data != HB_SHAPER_DATA_INVALID; \
-}
-
-
-/* For embedding in face / font / ... */
-struct hb_shaper_data_t {
-#define HB_SHAPER_IMPLEMENT(shaper) hb_atomic_ptr_t<void *> shaper;
+  Object *parent_data; /* MUST be JUST before the lazy loaders. */
+#define HB_SHAPER_IMPLEMENT(shaper) \
+	hb_shaper_lazy_loader_t<Object, HB_SHAPER_ORDER(shaper), \
+				typename hb_shaper_object_data_type_t<HB_SHAPER_ORDER(shaper), Object>::value \
+			       > shaper;
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 };
-#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
 
-
 #endif /* HB_SHAPER_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -46,7 +46,7 @@
 const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF};
 
 
-void
+unsigned int
 hb_face_t::load_num_glyphs (void) const
 {
   hb_sanitize_context_t c = hb_sanitize_context_t ();
@@ -53,17 +53,19 @@
   c.set_num_glyphs (0); /* So we don't recurse ad infinitum. */
   hb_blob_t *maxp_blob = c.reference_table<OT::maxp> (this);
   const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> ();
-  num_glyphs = maxp_table->get_num_glyphs ();
+
+  unsigned int ret = maxp_table->get_num_glyphs ();
+  num_glyphs.set_relaxed (ret);
   hb_blob_destroy (maxp_blob);
+  return ret;
 }
 
-void
+unsigned int
 hb_face_t::load_upem (void) const
 {
-  hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (this);
-  const OT::head *head_table = head_blob->as<OT::head> ();
-  upem = head_table->get_upem ();
-  hb_blob_destroy (head_blob);
+  unsigned int ret = table.head->get_upem ();
+  upem.set_relaxed (ret);
+  return ret;
 }
 
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -31,12 +31,12 @@
 
 static bool
 _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
-                                     hb_vector_t<hb_codepoint_t> &glyph_ids,
-                                     hb_bool_t drop_hints,
-                                     bool *use_short_loca /* OUT */,
-                                     unsigned int *glyf_size /* OUT */,
-                                     unsigned int *loca_size /* OUT */,
-                                     hb_vector_t<unsigned int> *instruction_ranges /* OUT */)
+				     hb_vector_t<hb_codepoint_t> &glyph_ids,
+				     hb_bool_t drop_hints,
+				     bool *use_short_loca /* OUT */,
+				     unsigned int *glyf_size /* OUT */,
+				     unsigned int *loca_size /* OUT */,
+				     hb_vector_t<unsigned int> *instruction_ranges /* OUT */)
 {
   unsigned int total = 0;
   for (unsigned int i = 0; i < glyph_ids.len; i++)
@@ -53,8 +53,8 @@
     *instruction_end = 0;
 
     unsigned int start_offset, end_offset;
-    if (unlikely (!(glyf.get_offsets(next_glyph, &start_offset, &end_offset)
-                    && glyf.remove_padding(start_offset, &end_offset))))
+    if (unlikely (!(glyf.get_offsets (next_glyph, &start_offset, &end_offset) &&
+		    glyf.remove_padding (start_offset, &end_offset))))
     {
       DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
       continue;
@@ -64,11 +64,11 @@
 
     if (drop_hints)
     {
-      if (unlikely (!glyf.get_instruction_offsets(start_offset, end_offset,
-                                                  instruction_start, instruction_end)))
+      if (unlikely (!glyf.get_instruction_offsets (start_offset, end_offset,
+						   instruction_start, instruction_end)))
       {
-        DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph);
-        return false;
+	DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph);
+	return false;
       }
     }
 
@@ -80,21 +80,21 @@
   *glyf_size = total;
   *use_short_loca = (total <= 131070);
   *loca_size = (glyph_ids.len + 1)
-      * (*use_short_loca ? sizeof(OT::HBUINT16) : sizeof(OT::HBUINT32));
+      * (*use_short_loca ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32));
 
   DEBUG_MSG(SUBSET, nullptr, "preparing to subset glyf: final size %d, loca size %d, using %s loca",
-            total,
-            *loca_size,
-            *use_short_loca ? "short" : "long");
+	    total,
+	    *loca_size,
+	    *use_short_loca ? "short" : "long");
   return true;
 }
 
 static bool
 _write_loca_entry (unsigned int  id,
-                   unsigned int  offset,
-                   bool          is_short,
-                   void         *loca_prime,
-                   unsigned int  loca_size)
+		   unsigned int  offset,
+		   bool          is_short,
+		   void         *loca_prime,
+		   unsigned int  loca_size)
 {
   unsigned int entry_size = is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32);
   if ((id + 1) * entry_size <= loca_size)
@@ -108,11 +108,11 @@
   }
 
   // Offset was not written because the write is out of bounds.
-  DEBUG_MSG (SUBSET,
-             nullptr,
-             "WARNING: Attempted to write an out of bounds loca entry at index %d. Loca size is %d.",
-             id,
-             loca_size);
+  DEBUG_MSG(SUBSET,
+	    nullptr,
+	    "WARNING: Attempted to write an out of bounds loca entry at index %d. Loca size is %d.",
+	    id,
+	    loca_size);
   return false;
 }
 
@@ -130,15 +130,15 @@
     {
       hb_codepoint_t new_gid;
       if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
-                                      &new_gid))
+				      &new_gid))
 	continue;
 
       ((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid);
-    } while (iterator.move_to_next());
+    } while (iterator.move_to_next ());
   }
 }
 
-static bool _remove_composite_instruction_flag(char *glyf_prime, unsigned int length)
+static bool _remove_composite_instruction_flag (char *glyf_prime, unsigned int length)
 {
   /* remove WE_HAVE_INSTRUCTIONS from flags in dest */
   OT::glyf::CompositeGlyphHeader::Iterator composite_it;
@@ -148,7 +148,7 @@
     glyph = composite_it.current;
     OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&glyph->flags);
     flags->set ( (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS);
-  } while (composite_it.move_to_next());
+  } while (composite_it.move_to_next ());
   return true;
 }
 
@@ -155,13 +155,13 @@
 static bool
 _write_glyf_and_loca_prime (hb_subset_plan_t              *plan,
 			    const OT::glyf::accelerator_t &glyf,
-                            const char                    *glyf_data,
-                            bool                           use_short_loca,
-                            hb_vector_t<unsigned int> &instruction_ranges,
-                            unsigned int                   glyf_prime_size,
-                            char                          *glyf_prime_data /* OUT */,
-                            unsigned int                   loca_prime_size,
-                            char                          *loca_prime_data /* OUT */)
+			    const char                    *glyf_data,
+			    bool                           use_short_loca,
+			    hb_vector_t<unsigned int> &instruction_ranges,
+			    unsigned int                   glyf_prime_size,
+			    char                          *glyf_prime_data /* OUT */,
+			    unsigned int                   loca_prime_size,
+			    char                          *loca_prime_data /* OUT */)
 {
   hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs;
   char *glyf_prime_data_next = glyf_prime_data;
@@ -170,8 +170,8 @@
   for (unsigned int i = 0; i < glyph_ids.len; i++)
   {
     unsigned int start_offset, end_offset;
-    if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)
-                    && glyf.remove_padding(start_offset, &end_offset))))
+    if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset) &&
+		    glyf.remove_padding (start_offset, &end_offset))))
       end_offset = start_offset = 0;
 
     unsigned int instruction_start = instruction_ranges[i * 2];
@@ -181,10 +181,10 @@
 
     if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size)
     {
-      DEBUG_MSG (SUBSET,
-                 nullptr,
-                 "WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)",
-                 i, length);
+      DEBUG_MSG(SUBSET,
+		 nullptr,
+		 "WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)",
+		 i, length);
       return false;
     }
 
@@ -197,18 +197,18 @@
       /* if the instructions end at the end this was a composite glyph, else simple */
       if (instruction_end == end_offset)
       {
-        if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false;
+	if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false;
       }
       else
-        /* zero instruction length, which is just before instruction_start */
-        memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);
+	/* zero instruction length, which is just before instruction_start */
+	memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);
     }
 
     success = success && _write_loca_entry (i,
-                                            glyf_prime_data_next - glyf_prime_data,
-                                            use_short_loca,
-                                            loca_prime_data,
-                                            loca_prime_size);
+					    glyf_prime_data_next - glyf_prime_data,
+					    use_short_loca,
+					    loca_prime_data,
+					    loca_prime_size);
     _update_components (plan, glyf_prime_data_next, length);
 
     // TODO: don't align to two bytes if using long loca.
@@ -216,20 +216,20 @@
   }
 
   success = success && _write_loca_entry (glyph_ids.len,
-                                          glyf_prime_data_next - glyf_prime_data,
-                                          use_short_loca,
-                                          loca_prime_data,
-                                          loca_prime_size);
+					  glyf_prime_data_next - glyf_prime_data,
+					  use_short_loca,
+					  loca_prime_data,
+					  loca_prime_size);
   return success;
 }
 
 static bool
 _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t  &glyf,
-                          const char                     *glyf_data,
-                          hb_subset_plan_t               *plan,
-                          bool                           *use_short_loca,
-                          hb_blob_t                     **glyf_prime /* OUT */,
-                          hb_blob_t                     **loca_prime /* OUT */)
+			  const char                     *glyf_data,
+			  hb_subset_plan_t               *plan,
+			  bool                           *use_short_loca,
+			  hb_blob_t                     **glyf_prime /* OUT */,
+			  hb_blob_t                     **loca_prime /* OUT */)
 {
   // TODO(grieger): Sanity check allocation size for the new table.
   hb_vector_t<hb_codepoint_t> &glyphs_to_retain = plan->glyphs;
@@ -237,16 +237,16 @@
   unsigned int glyf_prime_size;
   unsigned int loca_prime_size;
   hb_vector_t<unsigned int> instruction_ranges;
-  instruction_ranges.init();
+  instruction_ranges.init ();
 
   if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
-                                                      glyphs_to_retain,
-                                                      plan->drop_hints,
-                                                      use_short_loca,
-                                                      &glyf_prime_size,
-                                                      &loca_prime_size,
-                                                      &instruction_ranges))) {
-    instruction_ranges.fini();
+						      glyphs_to_retain,
+						      plan->drop_hints,
+						      use_short_loca,
+						      &glyf_prime_size,
+						      &loca_prime_size,
+						      &instruction_ranges))) {
+    instruction_ranges.fini ();
     return false;
   }
 
@@ -253,27 +253,27 @@
   char *glyf_prime_data = (char *) calloc (1, glyf_prime_size);
   char *loca_prime_data = (char *) calloc (1, loca_prime_size);
   if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data,
-                                             *use_short_loca,
-                                             instruction_ranges,
-                                             glyf_prime_size, glyf_prime_data,
-                                             loca_prime_size, loca_prime_data))) {
+					     *use_short_loca,
+					     instruction_ranges,
+					     glyf_prime_size, glyf_prime_data,
+					     loca_prime_size, loca_prime_data))) {
     free (glyf_prime_data);
     free (loca_prime_data);
-    instruction_ranges.fini();
+    instruction_ranges.fini ();
     return false;
   }
-  instruction_ranges.fini();
+  instruction_ranges.fini ();
 
   *glyf_prime = hb_blob_create (glyf_prime_data,
-                                glyf_prime_size,
-                                HB_MEMORY_MODE_READONLY,
-                                glyf_prime_data,
-                                free);
+				glyf_prime_size,
+				HB_MEMORY_MODE_READONLY,
+				glyf_prime_data,
+				free);
   *loca_prime = hb_blob_create (loca_prime_data,
-                                loca_prime_size,
-                                HB_MEMORY_MODE_READONLY,
-                                loca_prime_data,
-                                free);
+				loca_prime_size,
+				HB_MEMORY_MODE_READONLY,
+				loca_prime_data,
+				free);
   return true;
 }
 
@@ -287,24 +287,24 @@
  **/
 bool
 hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
-                         bool             *use_short_loca, /* OUT */
-                         hb_blob_t       **glyf_prime, /* OUT */
-                         hb_blob_t       **loca_prime /* OUT */)
+			 bool             *use_short_loca, /* OUT */
+			 hb_blob_t       **glyf_prime, /* OUT */
+			 hb_blob_t       **loca_prime /* OUT */)
 {
   hb_blob_t *glyf_blob = hb_sanitize_context_t ().reference_table<OT::glyf> (plan->source);
-  const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr);
+  const char *glyf_data = hb_blob_get_data (glyf_blob, nullptr);
 
   OT::glyf::accelerator_t glyf;
-  glyf.init(plan->source);
+  glyf.init (plan->source);
   bool result = _hb_subset_glyf_and_loca (glyf,
-                                          glyf_data,
-                                          plan,
-                                          use_short_loca,
-                                          glyf_prime,
-                                          loca_prime);
+					  glyf_data,
+					  plan,
+					  use_short_loca,
+					  glyf_prime,
+					  loca_prime);
 
   hb_blob_destroy (glyf_blob);
-  glyf.fini();
+  glyf.fini ();
 
   return result;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -33,8 +33,8 @@
 
 HB_INTERNAL bool
 hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
-                         bool             *use_short_loca, /* OUT */
-                         hb_blob_t       **glyf_prime /* OUT */,
-                         hb_blob_t       **loca_prime /* OUT */);
+			 bool             *use_short_loca, /* OUT */
+			 hb_blob_t       **glyf_prime      /* OUT */,
+			 hb_blob_t       **loca_prime      /* OUT */);
 
 #endif /* HB_SUBSET_GLYF_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -72,7 +72,7 @@
  * Since: 1.8.0
  **/
 void
-hb_subset_input_destroy(hb_subset_input_t *subset_input)
+hb_subset_input_destroy (hb_subset_input_t *subset_input)
 {
   if (!hb_object_destroy (subset_input)) return;
 
@@ -121,7 +121,7 @@
 
 HB_EXTERN void
 hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
-				hb_bool_t drop_layout)
+				 hb_bool_t drop_layout)
 {
   subset_input->drop_layout = drop_layout;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -57,24 +57,35 @@
 {
   hb_set_t lookup_indices;
   hb_ot_layout_collect_lookups (face,
-                                HB_OT_TAG_GSUB,
-                                nullptr,
-                                nullptr,
-                                nullptr,
-                                &lookup_indices);
+				HB_OT_TAG_GSUB,
+				nullptr,
+				nullptr,
+				nullptr,
+				&lookup_indices);
   hb_ot_layout_lookups_substitute_closure (face,
-                                           &lookup_indices,
-                                           gids_to_retain);
+					   &lookup_indices,
+					   gids_to_retain);
 }
 
+static void
+_remove_invalid_gids (hb_set_t *glyphs,
+		      unsigned int num_glyphs)
+{
+  hb_codepoint_t gid = HB_SET_VALUE_INVALID;
+  while (glyphs->next (&gid))
+  {
+    if (gid >= num_glyphs)
+      glyphs->del (gid);
+  }
+}
 
 static hb_set_t *
 _populate_gids_to_retain (hb_face_t *face,
-                          const hb_set_t *unicodes,
-                          bool close_over_gsub,
-                          hb_set_t *unicodes_to_retain,
-                          hb_map_t *codepoint_to_glyph,
-                          hb_vector_t<hb_codepoint_t> *glyphs)
+			  const hb_set_t *unicodes,
+			  bool close_over_gsub,
+			  hb_set_t *unicodes_to_retain,
+			  hb_map_t *codepoint_to_glyph,
+			  hb_vector_t<hb_codepoint_t> *glyphs)
 {
   OT::cmap::accelerator_t cmap;
   OT::glyf::accelerator_t glyf;
@@ -112,6 +123,8 @@
   }
   hb_set_destroy (initial_gids_to_retain);
 
+  _remove_invalid_gids (all_gids_to_retain, face->get_num_glyphs ());
+
   glyphs->alloc (all_gids_to_retain->get_population ());
   gid = HB_SET_VALUE_INVALID;
   while (all_gids_to_retain->next (&gid))
@@ -125,7 +138,7 @@
 
 static void
 _create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
-                                hb_map_t *glyph_map)
+				hb_map_t *glyph_map)
 {
   for (unsigned int i = 0; i < glyphs.len; i++) {
     glyph_map->set (glyphs[i], i);
@@ -144,7 +157,7 @@
  **/
 hb_subset_plan_t *
 hb_subset_plan_create (hb_face_t           *face,
-                       hb_subset_input_t   *input)
+		       hb_subset_input_t   *input)
 {
   hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
 
@@ -163,7 +176,7 @@
 					     plan->codepoint_to_glyph,
 					     &plan->glyphs);
   _create_old_gid_to_new_gid_map (plan->glyphs,
-                                  plan->glyph_map);
+				  plan->glyph_map);
 
   return plan;
 }
@@ -179,7 +192,7 @@
   if (!hb_object_destroy (plan)) return;
 
   hb_set_destroy (plan->unicodes);
-  plan->glyphs.fini();
+  plan->glyphs.fini ();
   hb_face_destroy (plan->source);
   hb_face_destroy (plan->dest);
   hb_map_destroy (plan->codepoint_to_glyph);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -56,7 +56,7 @@
 
   inline bool
   new_gid_for_codepoint (hb_codepoint_t codepoint,
-                         hb_codepoint_t *new_gid) const
+			 hb_codepoint_t *new_gid) const
   {
     hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
     if (old_gid == HB_MAP_VALUE_INVALID)
@@ -67,7 +67,7 @@
 
   inline bool
   new_gid_for_old_gid (hb_codepoint_t old_gid,
-                      hb_codepoint_t *new_gid) const
+		       hb_codepoint_t *new_gid) const
   {
     hb_codepoint_t gid = glyph_map->get (old_gid);
     if (gid == HB_MAP_VALUE_INVALID)
@@ -79,13 +79,13 @@
 
   inline bool
   add_table (hb_tag_t tag,
-             hb_blob_t *contents)
+	     hb_blob_t *contents)
   {
     hb_blob_t *source_blob = source->reference_table (tag);
     DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes",
-              HB_UNTAG(tag),
-              hb_blob_get_length (contents),
-              hb_blob_get_length (source_blob));
+	      HB_UNTAG(tag),
+	      hb_blob_get_length (contents),
+	      hb_blob_get_length (source_blob));
     hb_blob_destroy (source_blob);
     return hb_face_builder_add_table (dest, tag, contents);
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -70,10 +70,10 @@
   {
     hb_vector_t<char> buf;
     unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length);
-    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG(tag), buf_size);
+    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
     if (unlikely (!buf.alloc (buf_size)))
     {
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG(tag), buf_size);
+      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
       return false;
     }
   retry:
@@ -83,10 +83,10 @@
     if (serializer.ran_out_of_room)
     {
       buf_size += (buf_size >> 1) + 32;
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG(tag), buf_size);
+      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
       if (unlikely (!buf.alloc (buf_size)))
       {
-	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG(tag), buf_size);
+	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size);
 	return false;
       }
       goto retry;
@@ -94,21 +94,21 @@
     if (result)
     {
       hb_blob_t *dest_blob = serializer.copy_blob ();
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG(tag), dest_blob->length);
+      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
       result = c.plan->add_table (tag, dest_blob);
       hb_blob_destroy (dest_blob);
     }
     else
     {
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG(tag));
+      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
       result = true;
     }
   }
   else
-    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag));
+    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
 
   hb_blob_destroy (source_blob);
-  DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!");
+  DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
   return result;
 }
 
@@ -124,10 +124,10 @@
   if (source_blob->data)
     result = table->subset (plan);
   else
-    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag));
+    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
 
   hb_blob_destroy (source_blob);
-  DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!");
+  DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
   return result;
 }
 
@@ -134,9 +134,9 @@
 
 static bool
 _subset_table (hb_subset_plan_t *plan,
-               hb_tag_t          tag)
+	       hb_tag_t          tag)
 {
-  DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG(tag));
+  DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG (tag));
   bool result = true;
   switch (tag) {
     case HB_OT_TAG_glyf:
@@ -186,20 +186,20 @@
       break;
 
     default:
-      hb_blob_t *source_table = hb_face_reference_table(plan->source, tag);
+      hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
       if (likely (source_table))
-        result = plan->add_table(tag, source_table);
+	result = plan->add_table (tag, source_table);
       else
-        result = false;
+	result = false;
       hb_blob_destroy (source_table);
       break;
   }
-  DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED");
+  DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG (tag), result ? "ok" : "FAILED");
   return result;
 }
 
 static bool
-_should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag)
+_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
 {
   switch (tag) {
     case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
@@ -248,9 +248,9 @@
  **/
 hb_face_t *
 hb_subset (hb_face_t *source,
-           hb_subset_input_t *input)
+	   hb_subset_input_t *input)
 {
-  if (unlikely (!input || !source)) return hb_face_get_empty();
+  if (unlikely (!input || !source)) return hb_face_get_empty ();
 
   hb_subset_plan_t *plan = hb_subset_plan_create (source, input);
 
@@ -263,10 +263,10 @@
     for (unsigned int i = 0; i < count; i++)
     {
       hb_tag_t tag = table_tags[i];
-      if (_should_drop_table(plan, tag))
+      if (_should_drop_table (plan, tag))
       {
-        DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG(tag));
-        continue;
+	DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag));
+	continue;
       }
       success = success && _subset_table (plan, tag);
     }
@@ -273,7 +273,7 @@
     offset += count;
   } while (success && count == ARRAY_LENGTH (table_tags));
 
-  hb_face_t *result = success ? hb_face_reference(plan->dest) : hb_face_get_empty();
+  hb_face_t *result = success ? hb_face_reference (plan->dest) : hb_face_get_empty ();
   hb_subset_plan_destroy (plan);
   return result;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2018-11-19 04:05:47 UTC (rev 49193)
@@ -62,15 +62,14 @@
 
 HB_EXTERN void
 hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
-				hb_bool_t drop_layout);
+				 hb_bool_t drop_layout);
 HB_EXTERN hb_bool_t
 hb_subset_input_get_drop_layout (hb_subset_input_t *subset_input);
 
 
-/* hb_subset() */
+/* hb_subset () */
 HB_EXTERN hb_face_t *
-hb_subset (hb_face_t *source,
-           hb_subset_input_t *input);
+hb_subset (hb_face_t *source, hb_subset_input_t *input);
 
 
 HB_END_DECLS

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2018-11-19 04:05:47 UTC (rev 49193)
@@ -25,7 +25,6 @@
  */
 
 #include "hb.hh"
-#define HB_SHAPER uniscribe
 #include "hb-shaper-impl.hh"
 
 #include <windows.h>
@@ -314,10 +313,7 @@
   unsigned int index_last;  /* == end - 1 */
 };
 
-HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, face)
-HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, font)
 
-
 /*
  * shaper face data
  */
@@ -503,11 +499,12 @@
  * shaper font data
  */
 
-struct hb_uniscribe_font_data_t {
+struct hb_uniscribe_font_data_t
+{
   HDC hdc;
-  LOGFONTW log_font;
+  mutable LOGFONTW log_font;
   HFONT hfont;
-  SCRIPT_CACHE script_cache;
+  mutable SCRIPT_CACHE script_cache;
   double x_mult, y_mult; /* From LOGFONT space to HB space. */
 };
 
@@ -520,11 +517,8 @@
   lf->lfHeight = - (int) font_size;
   lf->lfCharSet = DEFAULT_CHARSET;
 
-  hb_face_t *face = font->face;
-  hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+  memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName));
 
-  memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName));
-
   return true;
 }
 
@@ -531,8 +525,6 @@
 hb_uniscribe_font_data_t *
 _hb_uniscribe_shaper_font_data_create (hb_font_t *font)
 {
-  if (unlikely (!hb_uniscribe_shaper_face_data_ensure (font->face))) return nullptr;
-
   hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t));
   if (unlikely (!data))
     return nullptr;
@@ -586,43 +578,19 @@
 LOGFONTW *
 hb_uniscribe_font_get_logfontw (hb_font_t *font)
 {
-  if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
-  hb_uniscribe_font_data_t *font_data =  HB_SHAPER_DATA_GET (font);
-  return &font_data->log_font;
+  const hb_uniscribe_font_data_t *data =  font->data.uniscribe;
+  return data ? &data->log_font : nullptr;
 }
 
 HFONT
 hb_uniscribe_font_get_hfont (hb_font_t *font)
 {
-  if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
-  hb_uniscribe_font_data_t *font_data =  HB_SHAPER_DATA_GET (font);
-  return font_data->hfont;
+  const hb_uniscribe_font_data_t *data =  font->data.uniscribe;
+  return data ? data->hfont : nullptr;
 }
 
 
 /*
- * shaper shape_plan data
- */
-
-struct hb_uniscribe_shape_plan_data_t {};
-
-hb_uniscribe_shape_plan_data_t *
-_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
-					     const hb_feature_t *user_features HB_UNUSED,
-					     unsigned int        num_user_features HB_UNUSED,
-					     const int          *coords HB_UNUSED,
-					     unsigned int        num_coords HB_UNUSED)
-{
-  return (hb_uniscribe_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shape_plan_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
  * shaper
  */
 
@@ -635,8 +603,8 @@
 		     unsigned int        num_features)
 {
   hb_face_t *face = font->face;
-  hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
-  hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+  const hb_uniscribe_face_data_t *face_data = face->data.uniscribe;
+  const hb_uniscribe_font_data_t *font_data = font->data.uniscribe;
   hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs;
 
   /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -34,6 +34,9 @@
 template <typename Type, unsigned int StaticSize=8>
 struct hb_vector_t
 {
+  typedef Type ItemType;
+  enum { item_size = sizeof (Type) };
+
   HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, StaticSize);
   inline hb_vector_t (void) { init (); }
   inline ~hb_vector_t (void) { fini (); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2018-11-19 04:05:47 UTC (rev 49193)
@@ -246,7 +246,7 @@
 #endif
 
 
-#if defined(_WIN32) || defined(__CYGWIN__)
+#ifdef _WIN32
    /* We need Windows Vista for both Uniscribe backend and for
     * MemoryBarrier.  We don't support compiling on Windows XP,
     * though we run on it fine. */

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2018-11-19 01:23:16 UTC (rev 49192)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2018-11-19 04:05:47 UTC (rev 49193)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [2.1.1])
+m4_define([harfbuzz_version], [2.1.3])



More information about the tex-live-commits mailing list