texlive[48337] Build/source/libs: harfbuzz 1.8.5

commits+kakuto at tug.org commits+kakuto at tug.org
Fri Aug 3 00:27:18 CEST 2018


Revision: 48337
          http://tug.org/svn/texlive?view=revision&revision=48337
Author:   kakuto
Date:     2018-08-03 00:27:18 +0200 (Fri, 03 Aug 2018)
Log Message:
-----------
harfbuzz 1.8.5

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/dump-emoji.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.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-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-glyf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.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-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.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-complex-use.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-private.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-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter-private.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery-private.hh

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/README	2018-08-02 22:27:18 UTC (rev 48337)
@@ -24,7 +24,7 @@
 graphite2 1.3.11 - checked 05mar18
   http://sourceforge.net/projects/silgraphite/files/graphite2/
 
-harfbuzz 1.8.4 - checked 18jul18
+harfbuzz 1.8.5 - checked 03aug18
   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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,3 +1,8 @@
+2018-08-03  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	Import harfbuzz-1.8.5.
+	* version.ac, Makefile.am: Adjusted.
+
 2018-07-18  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	Import harfbuzz-1.8.4.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2018-08-02 22:27:18 UTC (rev 48337)
@@ -44,8 +44,10 @@
 	@HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font-private.hh \
 	@HARFBUZZ_TREE@/src/hb-font.cc \
+	@HARFBUZZ_TREE@/src/hb-iter-private.hh \
 	@HARFBUZZ_TREE@/src/hb-map-private.hh \
 	@HARFBUZZ_TREE@/src/hb-map.cc \
+	@HARFBUZZ_TREE@/src/hb-machinery-private.hh \
 	@HARFBUZZ_TREE@/src/hb-mutex-private.hh \
 	@HARFBUZZ_TREE@/src/hb-object-private.hh \
 	@HARFBUZZ_TREE@/src/hb-open-file-private.hh \

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2018-08-02 22:27:18 UTC (rev 48337)
@@ -707,8 +707,10 @@
 	@HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font-private.hh \
 	@HARFBUZZ_TREE@/src/hb-font.cc \
+	@HARFBUZZ_TREE@/src/hb-iter-private.hh \
 	@HARFBUZZ_TREE@/src/hb-map-private.hh \
 	@HARFBUZZ_TREE@/src/hb-map.cc \
+	@HARFBUZZ_TREE@/src/hb-machinery-private.hh \
 	@HARFBUZZ_TREE@/src/hb-mutex-private.hh \
 	@HARFBUZZ_TREE@/src/hb-object-private.hh \
 	@HARFBUZZ_TREE@/src/hb-open-file-private.hh \

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,3 +1,8 @@
+2018-08-03  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	Imported harfbuzz-1.8.5 source tree from:
+	  http://www.freedesktop.org/software/harfbuzz/release/
+
 2018-07-18  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	Imported harfbuzz-1.8.4 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,4 +1,4 @@
-Changes applied to the harfbuzz-1.8.4/ tree as obtained from:
+Changes applied to the harfbuzz-1.8.5/ 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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/configure	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 1.8.4.
+# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 1.8.5.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -580,8 +580,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='1.8.4'
-PACKAGE_STRING='harfbuzz (TeX Live) 1.8.4'
+PACKAGE_VERSION='1.8.5'
+PACKAGE_STRING='harfbuzz (TeX Live) 1.8.5'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1317,7 +1317,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures harfbuzz (TeX Live) 1.8.4 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 1.8.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1388,7 +1388,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 1.8.4:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 1.8.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1495,7 +1495,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 1.8.4
+harfbuzz (TeX Live) configure 1.8.5
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2131,7 +2131,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by harfbuzz (TeX Live) $as_me 1.8.4, which was
+It was created by harfbuzz (TeX Live) $as_me 1.8.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4054,7 +4054,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='1.8.4'
+ VERSION='1.8.5'
 
 
 # Some tools Automake needs.
@@ -4248,8 +4248,8 @@
 
 HB_VERSION_MAJOR=1
 HB_VERSION_MINOR=8
-HB_VERSION_MICRO=4
-HB_VERSION=1.8.4
+HB_VERSION_MICRO=5
+HB_VERSION=1.8.5
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8140,7 +8140,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by harfbuzz (TeX Live) $as_me 1.8.4, which was
+This file was extended by harfbuzz (TeX Live) $as_me 1.8.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8206,7 +8206,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 1.8.4
+harfbuzz (TeX Live) config.status 1.8.5
 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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,3 +1,1253 @@
+commit 13f4c137c686aed5c2888b5c47d9f16892be0d5e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Aug 1 14:13:59 2018 -0700
+
+    [atomic] Fix Solaris ones to add proper barriers
+
+ src/hb-atomic-private.hh | 52
+ +++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 36 insertions(+), 16 deletions(-)
+
+commit 19dfaa351568887a74cee2c46d6acfcc3fa718ff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Aug 1 14:02:39 2018 -0700
+
+    [atomic] Remove volatile from IBM impl signature
+
+ src/hb-atomic-private.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 2093a3e0cbb98c2daa39f308d50a12f0a719bc81
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Aug 1 14:00:46 2018 -0700
+
+    [atomic] Oops
+
+ src/hb-atomic-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 19b98348ffc660501e518bf48cd63d232f7585e7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Aug 1 13:59:59 2018 -0700
+
+    [atomic] Use read-barrier for get()
+
+ src/hb-atomic-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 006d4f031a30dd04f5bb9c3d1daca187ef6b7f1e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Aug 1 13:59:31 2018 -0700
+
+    [atomic] Some more minor tweaks
+
+ src/hb-atomic-private.hh | 31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+commit 28d03a8afcc1f0ba6d9d0d88f669cc53bb030dd8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Aug 2 00:11:43 2018 +0430
+
+    [ci] Fix Appveyor bot (#1123)
+
+ appveyor.yml | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 1a7fed631880fff8a947ebec9c7427efff581916
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Aug 1 12:15:44 2018 +0430
+
+    Revert "Add a new API, hb_ot_layout_get_feature_name_ids (#976)"
+    (#1121)
+
+    This reverts commit 0c1b287b72e91e0898d75acb5d5acf1c6b9a7498.
+
+ docs/harfbuzz-sections.txt         |  1 -
+ src/hb-ot-layout-common-private.hh | 14 -------
+ src/hb-ot-layout.cc                | 86
+ --------------------------------------
+ src/hb-ot-layout.h                 |  8 ----
+ 4 files changed, 109 deletions(-)
+
+commit dfc86e4b35ffdeb8f73e83511712e75413bbb7d9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Aug 1 00:22:18 2018 -0700
+
+    [atomic] Fix cast to fallback ptr_get()
+
+ src/hb-atomic-private.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7a4d576e81c4de68ea66b2d5fe7712e29d715272
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Aug 1 00:19:25 2018 -0700
+
+    [gobject] Fix copy/paste error
+
+ src/hb-gobject-structs.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ad275627425c9b3c4fb1e69aa408067bd0bb77da
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 23:01:05 2018 -0700
+
+    [atomic] On IBM, use light-weight sync for everything
+
+    lwsync() is a full read/write-barrier.  That's all we need, never
+    need sync().  I'm not sure why an isync() was used in fetch_and_add,
+    but since that's a read-modify-write, I just changed it to have
+    lwsync() on both sides.
+
+ src/hb-atomic-private.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit fd638d215feb058c2294e447cc68f6f50e2b481d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 23:00:15 2018 -0700
+
+    [atomic] Add XXX items around Solaris ops
+
+    Since add_int and cas are both read-modify-write, I wonder if we
+    also need a barrier after them.
+
+ src/hb-atomic-private.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 896ff15ae60a4a4b94c62946e69196b877839bb5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 22:51:38 2018 -0700
+
+    [atomic] Fix get() impl
+
+    Originally, glib's atomic_get was implemented as "memory_barrier;
+    load".
+    I copied this into cairo, fontconfig, and harfbuzz.  However, that's
+    wrong.  Correct way is "load; memory_barrier".  The details are long
+    and hard to fully grasp.  Best to read:
+
+      https://www.kernel.org/doc/Documentation/memory-barriers.txt
+
+    Also see my report against GNOME:
+
+      https://gitlab.gnome.org/GNOME/glib/issues/1449
+
+    Note that this is irrelevant if C++11-like atomic ops are available.
+
+ src/hb-atomic-private.hh | 28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+commit d7a15799d40dac1f9521674a82c3293a7cb42ee4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 22:28:28 2018 -0700
+
+    [gobject] Hook up hb_map_t
+
+ docs/harfbuzz-sections.txt | 2 ++
+ src/hb-gobject-structs.cc  | 1 +
+ src/hb-gobject-structs.h   | 4 ++++
+ src/hb-map.cc              | 6 ++----
+ 4 files changed, 9 insertions(+), 4 deletions(-)
+
+commit 63c74e8d1d85067cbeffe635eb5ed4e8aa130776
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 22:21:21 2018 -0700
+
+    [atomic] Fix fallback impl
+
+ src/hb-atomic-private.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4bc16aca4760ac9ffd8c63bbaea24fc7d234f715
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 21:05:51 2018 -0700
+
+    [atomic] Add get_relaxed / set_relaxed
+
+    To help TSan and be more "correct".
+
+ src/hb-atomic-private.hh         | 37 ++++++++++++++++++++++-------------
+ src/hb-common.cc                 |  4 ++--
+ src/hb-debug.hh                  | 42
+ ++++++++++++++++++++++++++++++++++++++++
+ src/hb-object-private.hh         | 12 ++++++------
+ src/hb-ot-shape-complex-indic.cc | 22 +++++++++++----------
+ src/hb-private.hh                | 28 ---------------------------
+ 6 files changed, 86 insertions(+), 59 deletions(-)
+
+commit 3dd1b88765f6ce91bd0558a16cdd8cf0c1e15d1b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 19:33:37 2018 -0700
+
+    [atomic] Use CONSUME, not ACQUIRE, memory-order for get()
+
+    Although, all implementations just elevate that to ACQUIRE.
+    But requirement for us is just CONSUME.
+
+ src/hb-atomic-private.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 06b91d935da1a40ef9de6697717eb0af1015989e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 19:29:49 2018 -0700
+
+    Revert "[atomic] Make pointer get op relaxed instead of acquire"
+
+    This reverts commit b1e5650c67266dc158f22355fed206cd1c413f70.
+
+    After lots of head-scratching and finally finding the only truly
+    readable source to be the good old:
+
+      https://www.kernel.org/doc/Documentation/memory-barriers.txt
+
+    I've convinced myself that we need consume memory-ordering on get().
+    The location of memory-barrier in a load should be after, not before
+    the load.  That needs fixing.  I'll do that separately.
+
+ src/hb-atomic-private.hh | 34 +++++++++++++++++++++++++---------
+ 1 file changed, 25 insertions(+), 9 deletions(-)
+
+commit 2bdd903c69eb3a34f3d3bf5e4f4c94cd66337117
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Jul 31 17:44:02 2018 -0700
+
+    [subset] limit the max codepoint value to the unicode limit.
+    When collecting all codepoints in the cmap avoid using large amount
+    of memory for fonts that declare coverage over all 32 bit integers.
+
+ src/hb-ot-cmap-table.hh                                   |   9 +++++++--
+ ...mized-hb-subset-get-codepoints-fuzzer-5973295416475648 | Bin 0 ->
+ 109 bytes
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+commit 7278d9df3093a87f99cec9b4cea38bd688c5d020
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Jul 31 17:59:19 2018 -0700
+
+    [subset] Add hb_ot_layout_collect_features to harfbuzz-sections.txt.
+    Add the fuzzer test case for feature collection timeout.
+
+ docs/harfbuzz-sections.txt                             |   1 +
+ ...estcase-minimized-hb-subset-fuzzer-5542653037903872 | Bin 0 ->
+ 160249 bytes
+ 2 files changed, 1 insertion(+)
+
+commit 89733755a48feef0a663e1ea7b8294949581ce7e
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Jul 30 18:10:43 2018 -0700
+
+    [subset] use add_array to populate feature_indexes.
+    This is much faster then calling a bunch of individual add()'s.
+
+ src/hb-ot-layout-common-private.hh |  7 +++++++
+ src/hb-ot-layout.cc                | 40
+ +++++++++++++++++++-------------------
+ 2 files changed, 27 insertions(+), 20 deletions(-)
+
+commit 7d92bef9c5afb319d125f60b0fce4763afeaa686
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Jul 30 17:17:43 2018 -0700
+
+    [subset] collect features first, then use those to collect lookups.
+
+ src/hb-ot-layout.cc | 148
+ +++++++++++++++++++++++++---------------------------
+ src/hb-ot-layout.h  |   7 +++
+ 2 files changed, 78 insertions(+), 77 deletions(-)
+
+commit af876cce3066833c7c34d213a578eec6b09dd5c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 15:27:29 2018 -0700
+
+    [indic] Flip default logic for double-halants in old-school
+
+    Oriya went down from 9 to 2.
+
+    BENGALI: 353725 out of 354188 tests passed. 463 failed (0.130722%)
+    DEVANAGARI: 707311 out of 707394 tests passed. 83 failed (0.0117332%)
+    GUJARATI: 366355 out of 366457 tests passed. 102 failed (0.0278341%)
+    GURMUKHI: 60729 out of 60747 tests passed. 18 failed (0.0296311%)
+    KANNADA: 951300 out of 951913 tests passed. 613 failed (0.0643966%)
+    MALAYALAM: 1048136 out of 1048334 tests passed. 198 failed
+    (0.0188871%)
+    MYANMAR: 1115830 out of 1123883 tests passed. 8053 failed (0.716534%)
+    ORIYA: 42327 out of 42329 tests passed. 2 failed (0.00472489%)
+    SINHALA: 271596 out of 271847 tests passed. 251 failed (0.0923313%)
+    TAMIL: 1091754 out of 1091754 tests passed. 0 failed (0%)
+    TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%)
+
+ src/hb-ot-shape-complex-indic.cc | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit 92ba9905caa060466230f63b428ccee767696464
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 15:19:32 2018 -0700
+
+    [indic] Allow double-halant in old-spec Devanagari
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1071
+
+ src/hb-ot-shape-complex-indic.cc                      |  18
+ ++++++++++++------
+ .../b722a7d09e60421f3efbc706ad348ab47b88567b.ttf      | Bin 0 ->
+ 4672 bytes
+ test/shaping/data/in-house/tests/indic-old-spec.tests |   2 ++
+ 3 files changed, 14 insertions(+), 6 deletions(-)
+
+commit fe099a844b9b8fe05dd4eb187b5ca3769441f012
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 14:20:31 2018 -0700
+
+    [test] Add Khmer tests, with NotoSansKhmer-Regular.ttf
+
+    Note that there's minor positioning differences, and ONE reordering
+    difference between what we get for these and what Uniscribe gets.
+    Probably same as what's described in commit message for
+    1a96cc825dc9c8e3b6eef1403fe0864a1cfc0245
+
+ .../3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf   | Bin 0 -> 24392 bytes
+ test/shaping/data/in-house/tests/khmer-misc.tests  |  89
+ +++++++++++++++++++++
+ 2 files changed, 89 insertions(+)
+
+commit 5772edc0ea8f697c6123e439c5d0c3e813ebeb45
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 14:10:31 2018 -0700
+
+    [khmer] Typo
+
+ src/hb-ot-shape-complex-khmer.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2d6edc9008182c1446951f2c5c04df20094597f8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 13:56:55 2018 -0700
+
+    [test] Add Khmer test texts from recent bugs
+
+ test/shaping/texts/in-house/shaper-khmer/misc.txt | 66
+ +++++++++++++++++++++++
+ 1 file changed, 66 insertions(+)
+
+commit df26a32c8fd22cbd486e2a1014d30b9f38f51cd1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 13:55:53 2018 -0700
+
+    [test] Move things around for shaper updates
+
+ .../texts/in-house/shaper-indic/{indic => }/script-assamese/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-assamese/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-assamese/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-assamese/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../script-assamese/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt
+ | 0
+ .../script-assamese/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt
+ | 0
+ .../{indic => }/script-assamese/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-bengali/misc/misc.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-bengali/misc/reph.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-bengali/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-bengali/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-bengali/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-bengali/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../script-bengali/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../script-bengali/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt
+ | 0
+ .../script-bengali/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt
+ | 0
+ .../{indic => }/script-bengali/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../shaper-indic/{indic => }/script-devanagari/misc/dottedcircle.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-devanagari/misc/eyelash.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-devanagari/misc/joiners.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-devanagari/misc/misc.txt
+ | 0
+ .../shaper-indic/{indic => }/script-devanagari/misc/spec-deviations.txt
+ | 0
+ .../shaper-indic/{indic => }/script-devanagari/misc/tricky-reordering.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-devanagari/utrrs/LICENSE
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-devanagari/utrrs/README
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-devanagari/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalConsonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../codepoint/IndicFontFeatureCodepoint-DevnagariSpecificAddition.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-GenericPunctuation.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../script-devanagari/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt
+ | 0
+ .../script-devanagari/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt
+ | 0
+ .../{indic => }/script-devanagari/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-gujarati/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-gujarati/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-gujarati/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-gujarati/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../script-gujarati/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt
+ | 0
+ .../script-gujarati/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt
+ | 0
+ .../{indic => }/script-gujarati/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-gurmukhi/misc/misc.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-gurmukhi/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-gurmukhi/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-gurmukhi/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-gurmukhi/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-GurmukhiSpecific.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../script-gurmukhi/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt
+ | 0
+ .../script-gurmukhi/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt
+ | 0
+ .../{indic => }/script-gurmukhi/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-kannada/misc/misc.txt
+ | 0
+ .../shaper-indic/{indic => }/script-kannada/misc/right-matras.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-kannada/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-kannada/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-kannada/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalConsonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-kannada/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../script-kannada/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../script-kannada/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt
+ | 0
+ .../{indic => }/script-kannada/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-malayalam/misc/cibu.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-malayalam/misc/dot-reph.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-malayalam/misc/misc.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-malayalam/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-malayalam/utrrs/README
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-malayalam/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-malayalam/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../{indic => }/script-malayalam/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-oriya/misc/bindu.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-oriya/misc/misc.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-oriya/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-oriya/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-oriya/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalConsonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt
+ | 0
+ .../script-oriya/utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-oriya/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-OriyaSpecific.txt
+ | 0
+ .../script-oriya/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../{indic => }/script-oriya/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../in-house/shaper-indic/{indic => }/script-sinhala/misc/extensive.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-sinhala/misc/misc.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-sinhala/misc/reph.txt
+ | 0
+ .../shaper-indic/{indic => }/script-sinhala/misc/split-matras.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-sinhala/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-sinhala/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-sinhala/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Punctuation.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../{indic => }/script-sinhala/utrrs/gpos/IndicFontFeatureGPOS.txt
+ | 0
+ .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Conjunct.txt
+ | 0
+ .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Rakaaraansaya.txt
+ | 0
+ .../{indic => }/script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Repaya.txt
+ | 0
+ .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Special-Cases.txt
+ | 0
+ .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-TouchingLetters.txt
+ | 0
+ .../script-sinhala/utrrs/gsub/IndicFontFeatureGSUB-Yansaya.txt
+ | 0
+ .../{indic => }/script-sinhala/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-tamil/misc/misc.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-tamil/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-tamil/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-tamil/utrrs/SOURCES
+ | 0
+ .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-CurrencySymbols.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Numerics.txt
+ | 0
+ .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../script-tamil/utrrs/codepoint/IndicFontFeatureCodepoint-Symbols.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-TamilSymbol.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../script-tamil/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt
+ | 0
+ .../script-tamil/utrrs/gpos/IndicFontFeatureGPOS-BelowBase.txt
+ | 0
+ .../{indic => }/script-tamil/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-telugu/misc/misc.txt
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-telugu/utrrs/LICENSE
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-telugu/utrrs/README
+ | 0
+ .../texts/in-house/shaper-indic/{indic => }/script-telugu/utrrs/SOURCES
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-AdditionalVowels.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-Consonants.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-DependentVowels.txt
+ | 0
+ .../script-telugu/utrrs/codepoint/IndicFontFeatureCodepoint-Digits.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-IndependentVowels.txt
+ | 0
+ .../script-telugu/utrrs/codepoint/IndicFontFeatureCodepoint-Reserved.txt
+ | 0
+ .../utrrs/codepoint/IndicFontFeatureCodepoint-VariousSigns.txt
+ | 0
+ .../script-telugu/utrrs/gpos/IndicFontFeatureGPOS-AboveBase.txt
+ | 0
+ .../{indic => }/script-telugu/utrrs/gsub/IndicFontFeatureGSUB.txt
+ | 0
+ .../south-east-asian/script-khmer/misc => shaper-khmer}/misc.txt
+ | 0
+ .../script-khmer/misc => shaper-khmer}/other-marks-invalid.txt
+ | 0
+ .../south-east-asian/script-khmer/misc => shaper-khmer}/other-marks.txt
+ | 0
+ .../south-east-asian => shaper-use}/script-javanese/misc.txt
+ | 0
+ 174 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 6ddd669e205cf2c1c3b0a362330b686386f68519
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 13:38:07 2018 -0700
+
+    [khmer] Clear syllables before presentation features
+
+    Probably not what Uniscribe does, but good idea?
+
+ src/hb-ot-shape-complex-khmer.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 8eef1964a708c3db52e5e7312689c4664afa9839
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 13:35:10 2018 -0700
+
+    [khmer] Revert previous change, and remove pauses
+
+    This makes test suite happy again (at 44) while fixing the sequences
+    we were fixing, which were the following with KhmerUI.ttf:
+
+      U+1789,U+17BC
+      U+1789,U+17D2,U+1789
+      U+1789,U+17D2,U+1789,U+17BC
+
+    Fixes rest of https://github.com/harfbuzz/harfbuzz/issues/974
+
+ src/hb-ot-shape-complex-khmer.cc | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+commit 7c658ea2f20a77cac35e8988e54316425396198a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 12:49:02 2018 -0700
+
+    [khmer] Apply ccmp after basic features
+
+    Part of https://github.com/harfbuzz/harfbuzz/issues/974
+
+ src/hb-ot-shape-complex-khmer.cc | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+commit 1a96cc825dc9c8e3b6eef1403fe0864a1cfc0245
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 11:45:32 2018 -0700
+
+    [khmer] Rewrite most of shaper to better follow spec
+
+    Khmer spec has only one reordering phase, and only simple prebase
+    matra and Coeng-Ro reordering.  Implement that.  Specifically,
+    this was done to address recognizing different orders of the matra
+    and Coeng-Ro sequence.  That said, some combinations are now
+    reordered differently from Uniscribe.  Not clear if that's intended
+    or a bug in Uniscribe.  The following two sequences render the same
+    in Uniscribe whereas we reorder them differently:
+
+      U+17A0,U+17D2,U+179A,U+17C2
+      U+17A0,U+17C2,U+17D2,U+179A
+
+    For that reason, our test suite numbers regressed slightly.  Used
+    to be at 34 for fails, now at:
+
+    KHMER: 299080 out of 299124 tests passed. 44 failed (0.0147096%)
+
+    But generally a good change, and removed lots of code.
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1026
+
+ src/hb-ot-shape-complex-indic-private.hh |   4 +-
+ src/hb-ot-shape-complex-khmer.cc         | 460
+ ++++---------------------------
+ src/hb-ot-shape-complex-private.hh       |  13 -
+ 3 files changed, 64 insertions(+), 413 deletions(-)
+
+commit f5152cea423947cd8a85332566443b4e2e091672
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 01:27:04 2018 -0700
+
+    [shaper] Move code around
+
+ src/hb-shaper-private.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 36d0fbbc52bdf2c71da022fb1fdc31eca17078ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 01:15:04 2018 -0700
+
+    [shaper] Remove a macro
+
+ src/hb-shaper-private.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit b1e5650c67266dc158f22355fed206cd1c413f70
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 31 01:02:31 2018 -0700
+
+    [atomic] Make pointer get op relaxed instead of acquire
+
+    We only use it before cmpexch, so relaxed is fine and faster for
+    common case.
+
+ src/hb-atomic-private.hh | 34 +++++++++-------------------------
+ 1 file changed, 9 insertions(+), 25 deletions(-)
+
+commit 66ccd8ac405c9c25b37de9eb467a7382880dda35
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jul 30 17:03:06 2018 -0700
+
+    [serialize] Increase stage count from 8 to 32
+
+    Indic shaper uses many stages.  Now we are provably not limiting
+    functionality whereas the previous limit of 8 was assuming real-world
+    practices.
+
+ src/hb-ot-layout-common-private.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit ee8cf919654cb191e955fe1f89b1ebfb2b8b32ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jul 30 16:59:41 2018 -0700
+
+    [serialize] Remove unused truncate() method
+
+ src/hb-machinery-private.hh | 6 ------
+ 1 file changed, 6 deletions(-)
+
+commit 5edf454aa64aad461c90bd991e7eaf27668b7e6b
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Jul 26 17:42:02 2018 -0700
+
+    [subset] During lookup collection remember the features we've
+    already processed.
+
+ src/hb-ot-layout.cc                                |  26
+ +++++++++++++++++----
+ ...ase-minimized-hb-subset-fuzzer-5670861909524480 | Bin 0 -> 1298 bytes
+ ...b-subset-get-codepoints-fuzzer-6136125075750912 | Bin 0 -> 65816 bytes
+ 3 files changed, 21 insertions(+), 5 deletions(-)
+
+commit 42c183f80355fe7cadac2931a23d389285c8b98c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jul 27 14:55:29 2018 -0700
+
+    Minor
+
+ src/hb-ft.cc       | 5 +++--
+ src/hb-ot-shape.cc | 5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+commit ecab6604e57ea2bb4e78250a7a400e15b3e86f7a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jul 25 17:37:38 2018 -0700
+
+    [serialize] Allocate for markFilteringSet
+
+ src/hb-ot-layout-common-private.hh | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 7f08818c441517f73c5bea0a2a88f494dfc8fa58
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jul 25 17:22:05 2018 -0700
+
+    Minor
+
+ src/hb-iter-private.hh      | 8 +++++---
+ src/hb-machinery-private.hh | 1 -
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+commit 2e25d8f49181ab1d7fda520ae6587d293a982acf
+Author: prrace <philip.race at oracle.com>
+Date:   Fri Jul 27 13:58:27 2018 -0700
+
+    Fix unlikely leaks
+
+ src/hb-ft.cc       | 4 +++-
+ src/hb-ot-shape.cc | 4 +++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit 3c2842cbcf8cded73d1e310379e1a4ca124a6fc2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jul 25 17:07:17 2018 -0700
+
+    Add hb-iter-private.hh
+
+    Unused so far.
+
+ src/Makefile.sources        |   1 +
+ src/hb-iter-private.hh      | 147
+ ++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-machinery-private.hh |   1 +
+ 3 files changed, 149 insertions(+)
+
+commit 92b1e025c639d006f55400bf68fc23bdeaa1c716
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jul 25 16:58:47 2018 -0700
+
+    Move some code from hb-open-type-private.hh to hb-machinery-private.hh
+
+ src/Makefile.sources        |   1 +
+ src/hb-machinery-private.hh | 702
+ ++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-open-type-private.hh | 669
+ +----------------------------------------
+ 3 files changed, 706 insertions(+), 666 deletions(-)
+
+commit 6b11fea99716e22522b563d919ef7c72fe9a3c45
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jul 25 16:01:37 2018 -0700
+
+    [closure] Allocate out set on the stack
+
+ src/hb-ot-layout-gsubgpos-private.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 74467b790154838e86c3ca8df0eaafe82e87f976
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jul 25 14:30:07 2018 -0700
+
+    Fix compile
+
+ src/hb-shaper-private.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit bf90f35302c319ec4699ccbcd1e28b15ef2ec423
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 24 18:00:14 2018 -0700
+
+    [coretext] Add note
+
+ src/hb-shaper-private.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit fb58cb4b5ca7043fa746b1a01790abf53bedfa86
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Jul 25 13:39:17 2018 -0700
+
+    [subset] Only used reachable lookups for gsub closure.
+
+ src/hb-subset-plan.cc | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit c38bd4025f3f6ff4c1a39cc106b8618361a0c62b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 24 09:43:27 2018 -0700
+
+    [closure] Separate in and out glyphs
+
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1107
+
+ src/hb-ot-layout-gsub-table.hh       | 26 ++++++++++++++++++--------
+ src/hb-ot-layout-gsubgpos-private.hh | 16 +++++++++++++++-
+ 2 files changed, 33 insertions(+), 9 deletions(-)
+
+commit 85646fdadb2f102333485e07425361795b4e0412
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Jul 23 15:37:18 2018 -0700
+
+    [subset] Limit the iterations of the closure algorithm.
+    Prevents O(n^2) run times.
+
+ src/hb-ot-layout-common-private.hh | 7 +++++++
+ src/hb-ot-layout.cc                | 5 ++++-
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+commit 94759d4cf8986388399026ef5204ac55ee187180
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jul 23 15:01:39 2018 -0700
+
+    Fix visibility on mingw32
+
+    Should fix bots again.
+
+ src/hb-private.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 61eddbd8ef64dc66e3c42723533d53967e61c9af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jul 23 14:44:10 2018 -0700
+
+    Fix infinite loop in loading num_glyphs within sanitizer
+
+ src/hb-open-type-private.hh | 13 ++++++++++---
+ src/hb-static.cc            |  4 +++-
+ 2 files changed, 13 insertions(+), 4 deletions(-)
+
+commit e22a48ac95a60fac5e1bca26eed7f5623d73a7be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jul 23 13:24:26 2018 -0700
+
+    One more visibility trick
+
+    Should fix Windows build again.
+
+ src/hb-common.cc  |  9 +++++++++
+ src/hb-private.hh | 20 ++------------------
+ src/hb-static.cc  |  4 +++-
+ 3 files changed, 14 insertions(+), 19 deletions(-)
+
+commit e57a638bdec378eed8e83513818c8add3ffae896
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jul 23 12:00:02 2018 -0700
+
+    One more
+
+ src/hb-ot-cmap-table.hh | 40 ++++++++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+commit 36ed163fdd50419e4619c665a4a9dbf97f66c349
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jul 23 11:57:45 2018 -0700
+
+    Remove unnecessary OT:: namespace specifiers
+
+ src/hb-ot-cmap-table.hh       | 30 +++++++++++++++---------------
+ src/hb-ot-color-sbix-table.hh |  4 ++--
+ src/hb-ot-color-svg-table.hh  |  4 ++--
+ src/hb-ot-glyf-table.hh       |  4 ++--
+ src/hb-ot-hmtx-table.hh       |  2 +-
+ src/hb-ot-maxp-table.hh       |  6 +++---
+ src/hb-ot-os2-table.hh        |  4 ++--
+ src/hb-ot-post-table.hh       |  2 +-
+ 8 files changed, 28 insertions(+), 28 deletions(-)
+
+commit c6bc7c38314ea831418fdd1434bbe5afc0875f33
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jul 23 11:46:46 2018 -0700
+
+    Set num glyphs on sanitizer reference_table()
+
+    Move out-of-class definitions of two methods to hb-static so they
+    are accessible in libharfbuzz-subset.
+
+ src/hb-face.cc              | 20 --------------------
+ src/hb-open-type-private.hh |  1 +
+ src/hb-static.cc            | 22 ++++++++++++++++++++++
+ 3 files changed, 23 insertions(+), 20 deletions(-)
+
+commit 9401829d4e93f6f433957fa2d053f3b9d42da557
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jul 22 22:50:58 2018 -0700
+
+    Remove Sanitizer<>
+
+ src/hb-open-type-private.hh | 16 +---------------
+ 1 file changed, 1 insertion(+), 15 deletions(-)
+
+commit 8e3e41272b3896274459c5961aac813ef2666321
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jul 22 22:49:26 2018 -0700
+
+    Port rest of code away from Sanitizer<>
+
+ src/hb-face.cc | 4 ++--
+ src/main.cc    | 3 +--
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+commit d6a8f64045ca3bf4c7d01520909fa0c7dfca4d64
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jul 22 22:47:19 2018 -0700
+
+    Port dump-emoji away from Sanitizer<>
+
+ src/dump-emoji.cc | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit 14f78d2b3bb1e1292efbd6a3e3f0d618179c171a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jul 22 22:45:26 2018 -0700
+
+    .
+
+ src/hb-aat-layout.cc | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 4547051f48ca6aa53309b81a768b5b44c4ab6e3b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jul 22 22:44:22 2018 -0700
+
+    Minor
+
+ src/hb-open-file-private.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 740ae27d5c0f5ff87e2ff489fb49d5db1a0c95be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jul 22 22:40:56 2018 -0700
+
+    Port sbix off of Sanitizer<>
+
+ src/hb-ot-color-sbix-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 9583e0077d0a3a043f8b5bd23925014e04da8d32
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jul 22 22:40:32 2018 -0700
+
+    Port more off of Sanitizer<>
+
+ src/hb-face.cc                |  4 ++--
+ src/hb-open-type-private.hh   |  2 +-
+ src/hb-ot-cmap-table.hh       |  2 +-
+ src/hb-ot-color-cbdt-table.hh |  4 ++--
+ src/hb-ot-color-svg-table.hh  |  4 +---
+ src/hb-ot-glyf-table.hh       |  8 ++++----
+ src/hb-ot-hmtx-table.hh       | 10 +++++-----
+ src/hb-ot-kern-table.hh       |  2 +-
+ src/hb-ot-layout.cc           |  6 +++---
+ src/hb-ot-maxp-table.hh       |  2 +-
+ src/hb-ot-os2-table.hh        |  2 +-
+ src/hb-ot-post-table.hh       |  2 +-
+ src/hb-subset.cc              |  4 +---
+ 13 files changed, 24 insertions(+), 28 deletions(-)
+
+commit e7737b41d793bfce9455d1797eb5e0af60794f23
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jul 22 22:24:31 2018 -0700
+
+    Add sanitizer reference_table, also fix clang build
+
+    Clang is being really peculiar.  Fix with:
+
+    -  inline hb_blob_t *sanitize (hb_blob_t *blob) { return
+    c->sanitize<Type> (blob); }
+    +  inline hb_blob_t *sanitize (hb_blob_t *blob) { return
+    c[0].template/*clang idiosyncrasy*/sanitize_blob<Type> (blob); }
+
+ src/hb-open-type-private.hh | 10 ++++++++--
+ src/hb-ot-post-table.hh     |  2 +-
+ src/hb-subset-glyf.cc       |  2 +-
+ src/hb-uniscribe.cc         |  2 +-
+ 4 files changed, 11 insertions(+), 5 deletions(-)
+
+commit 62fa7cd1ccff4d4448ef84f9cc146464672636aa
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri Apr 13 18:45:37 2018 -0400
+
+    Order Chakma split vowels in accordance with NFC
+
+    Fixes #1105.
+
+ src/gen-use-table.py                               |  10 ++++++++++
+ src/hb-ot-shape-complex-use-table.cc               |   4 ++--
+ src/hb-ot-shape-complex-use.cc                     |  21
+ +--------------------
+ .../2a670df15b73a5dc75a5cc491bde5ac93c5077dc.ttf   | Bin 0 -> 1344 bytes
+ test/shaping/data/in-house/tests/use.tests         |   5 +++++
+ 5 files changed, 18 insertions(+), 22 deletions(-)
+
+commit 0c1b287b72e91e0898d75acb5d5acf1c6b9a7498
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jul 21 21:14:48 2018 +0430
+
+    Add a new API, hb_ot_layout_get_feature_name_ids (#976)
+
+    This new API returns cvXX and ssXX related NameId, things like
+    featUiLabelNameId, featUiTooltipTextNameId, sampleTextNameId,
+    ... of cvXX
+    and UINameId of ssXX, in a unified way.
+
+    However HarfBuzz currently doesn't expose an API for retrieving
+    the actual
+    information associated with NameId from the `name` table and that
+    should be
+    done separately.
+
+ docs/harfbuzz-sections.txt         |  1 +
+ src/hb-ot-layout-common-private.hh | 14 +++++++
+ src/hb-ot-layout.cc                | 86
+ ++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout.h                 |  8 ++++
+ 4 files changed, 109 insertions(+)
+
+commit 93b65d9fe331a217640069fad4159cb7c3ec35e6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Jul 17 23:29:16 2018 +0430
+
+    Remove dump-fon (#1100)
+
+    It had interesting stuffs like EXE parsing and
+    big-endian parsers but added in an attempt to find
+    a solution for #681 which later found not related.
+
+ src/Makefile.am |   4 -
+ src/dump-fon.cc | 555
+ --------------------------------------------------------
+ 2 files changed, 559 deletions(-)
+
+commit d5cd47a69c40966b4d5b5aed87dd7ac6f070c37a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Jul 17 22:32:37 2018 +0430
+
+    Remove AAT's gcid/fmtx (#1099)
+
+    We are not going to use them, at least in the foreseeable future
+
+ src/Makefile.sources     |  2 --
+ src/hb-aat-fmtx-table.hh | 67
+ --------------------------------------------
+ src/hb-aat-gcid-table.hh | 73
+ ------------------------------------------------
+ src/hb-aat-layout.cc     |  2 --
+ 4 files changed, 144 deletions(-)
+
+commit 1e9e344b2ba076a5fd6d57d1705e17a59c3875ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 17 19:17:59 2018 +0200
+
+    Fix hb_face_count() sanitize referencing
+
+ src/hb-face.cc | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit a8cc0b5907e61199334a3a886fe22efe9cc17149
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 17 19:09:03 2018 +0200
+
+    Remove TODO that is not gonna be done
+
+    Previously the idea was to cache sanitize results externally (think,
+    in Fontconfig) and avoid resanitizing every time.  That's, not a good
+    idea.
+
+ src/hb-open-type-private.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit be7073840097c873ce4954c6cffadab175a007d3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 17 18:45:25 2018 +0200
+
+    Move sanitizer code around a bit
+
+ src/hb-aat-layout-common-private.hh |  4 +-
+ src/hb-open-type-private.hh         | 95
+ ++++++++++++++++++++-----------------
+ src/hb-ot-color-sbix-table.hh       | 12 ++---
+ src/hb-ot-layout-common-private.hh  |  3 --
+ 4 files changed, 58 insertions(+), 56 deletions(-)
+
+commit db5d430effce67db57ddea2545694b7275ee8b35
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 17 18:14:45 2018 +0200
+
+    [aat] Update for blob changes
+
+    Also, uncomment code again, just "if (0)" it out, so it doesn't get
+    stale again.
+
+ src/hb-aat-layout.cc        | 58
+ ++-------------------------------------------
+ src/hb-open-type-private.hh | 27 +++++++++++++--------
+ src/hb-ot-layout-private.hh |  1 +
+ src/hb-ot-layout.cc         |  2 ++
+ src/hb-ot-shape.cc          |  6 ++---
+ 5 files changed, 25 insertions(+), 69 deletions(-)
+
+commit 68310a65cba7eed20f8696f4c670bb195677f467
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jul 17 13:20:40 2018 +0200
+
+    1.8.4
+
+ NEWS             | 7 +++++++
+ configure.ac     | 2 +-
+ src/hb-version.h | 4 ++--
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
 commit 04b7b81bcbf19cb85d06d930192d6591ba45ef72
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Tue Jul 17 10:57:01 2018 +0200

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,3 +1,11 @@
+Overview of changes leading to 1.8.5
+Wednesday, August 1, 2018
+====================================
+- Major Khmer shaper improvements to better match Microsoft.
+- Indic bug fixes.
+- Internal improvements to atomic operations.
+
+
 Overview of changes leading to 1.8.4
 Tuesday, July 17, 2018
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [1.8.4],
+        [1.8.5],
         [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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2018-08-02 22:27:18 UTC (rev 48337)
@@ -374,15 +374,11 @@
 endif
 
 check_PROGRAMS += \
-	dump-fon \
 	dump-indic-data \
 	dump-khmer-data \
 	dump-myanmar-data \
 	dump-use-data \
 	$(NULL)
-dump_fon_SOURCES = dump-fon.cc
-dump_fon_CPPFLAGS = $(HBCFLAGS)
-dump_fon_LDADD = libharfbuzz.la $(HBLIBS)
 dump_indic_data_SOURCES = dump-indic-data.cc hb-ot-shape-complex-indic-table.cc
 dump_indic_data_CPPFLAGS = $(HBCFLAGS)
 dump_indic_data_LDADD = libharfbuzz.la $(HBLIBS)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2018-08-02 22:27:18 UTC (rev 48337)
@@ -14,8 +14,10 @@
 	hb-face.cc \
 	hb-font-private.hh \
 	hb-font.cc \
+	hb-iter-private.hh \
 	hb-map-private.hh \
 	hb-map.cc \
+	hb-machinery-private.hh \
 	hb-mutex-private.hh \
 	hb-object-private.hh \
 	hb-open-file-private.hh \
@@ -93,8 +95,6 @@
 	hb-aat-layout-morx-table.hh \
 	hb-aat-layout-trak-table.hh \
 	hb-aat-layout-private.hh \
-	hb-aat-fmtx-table.hh \
-	hb-aat-gcid-table.hh \
 	hb-aat-ltag-table.hh \
 	hb-ot-font.cc \
 	hb-ot-layout.cc \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-emoji.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -233,12 +233,10 @@
   svg.dump (svg_callback);
   svg.fini ();
 
-  OT::Sanitizer<OT::COLR> sanitizerCOLR;
-  hb_blob_t* colr_blob = sanitizerCOLR.sanitize (face->reference_table (HB_OT_TAG_COLR));
+  hb_blob_t* colr_blob = OT::hb_sanitize_context_t().reference_table<OT::COLR> (face);
   const OT::COLR *colr = colr_blob->as<OT::COLR> ();
 
-  OT::Sanitizer<OT::CPAL> sanitizerCPAL;
-  hb_blob_t* cpal_blob = sanitizerCPAL.sanitize (face->reference_table (HB_OT_TAG_CPAL));
+  hb_blob_t* cpal_blob = OT::hb_sanitize_context_t().reference_table<OT::CPAL> (face);
   const OT::CPAL *cpal = cpal_blob->as<OT::CPAL> ();
 
   cairo_font_face_t *cairo_face;

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/dump-fon.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,555 +0,0 @@
-/*
- * 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.
- */
-
-#include "hb-static.cc"
-#include <stdio.h>
-#include <stdlib.h>
-#include "hb-open-type-private.hh"
-
-template <typename Type, int Bytes> struct LEInt;
-
-template <typename Type>
-struct LEInt<Type, 1>
-{
-  public:
-  inline void set (Type V)
-  {
-    v = V;
-  }
-  inline operator Type (void) const
-  {
-    return v;
-  }
-  private: uint8_t v;
-};
-template <typename Type>
-struct LEInt<Type, 2>
-{
-  public:
-  inline void set (Type V)
-  {
-    v[1] = (V >>  8) & 0xFF;
-    v[0] = (V      ) & 0xFF;
-  }
-  inline operator Type (void) const
-  {
-    return (v[1] <<  8)
-         + (v[0]      );
-  }
-  private: uint8_t v[2];
-};
-template <typename Type>
-struct LEInt<Type, 3>
-{
-  public:
-  inline void set (Type V)
-  {
-    v[2] = (V >> 16) & 0xFF;
-    v[1] = (V >>  8) & 0xFF;
-    v[0] = (V      ) & 0xFF;
-  }
-  inline operator Type (void) const
-  {
-    return (v[2] << 16)
-         + (v[1] <<  8)
-         + (v[0]      );
-  }
-  private: uint8_t v[3];
-};
-template <typename Type>
-struct LEInt<Type, 4>
-{
-  public:
-  inline void set (Type V)
-  {
-    v[3] = (V >> 24) & 0xFF;
-    v[2] = (V >> 16) & 0xFF;
-    v[1] = (V >>  8) & 0xFF;
-    v[0] = (V      ) & 0xFF;
-  }
-  inline operator Type (void) const
-  {
-    return (v[3] << 24)
-         + (v[2] << 16)
-         + (v[1] <<  8)
-         + (v[0]      );
-  }
-  private: uint8_t v[4];
-};
-
-template <typename Type, unsigned int Size>
-struct LEIntType
-{
-  inline void set (Type i) { v.set (i); }
-  inline operator Type(void) const { return v; }
-  inline bool sanitize (OT::hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this)));
-  }
-  protected:
-  LEInt<Type, Size> v;
-  public:
-  DEFINE_SIZE_STATIC (Size);
-};
-
-typedef LEIntType<uint8_t,  1> LEUINT8;		/* 8-bit unsigned integer. */
-typedef LEIntType<int8_t,   1> LEINT8;		/* 8-bit signed integer. */
-typedef LEIntType<uint16_t, 2> LEUINT16;	/* 16-bit unsigned integer. */
-typedef LEIntType<int16_t,  2> LEINT16;		/* 16-bit signed integer. */
-typedef LEIntType<uint32_t, 4> LEUINT32;	/* 32-bit unsigned integer. */
-typedef LEIntType<int32_t,  4> LEINT32;		/* 32-bit signed integer. */
-typedef LEIntType<uint32_t, 3> LEUINT24;	/* 24-bit unsigned integer. */
-
-
-struct LE_FONTINFO16
-{
-  inline bool sanitize (OT::hb_sanitize_context_t *c, unsigned int length) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) && c->check_range (this, length)));
-  }
-
-  // https://msdn.microsoft.com/en-us/library/cc194829.aspx
-  enum charset_t
-  {
-    // dfCharSet possible values and the codepage they are indicating to
-    ANSI	= 0x00,	// 1252
-    DEFAULT	= 0x01,	//
-    SYMBOL	= 0x02,	//
-    SHIFTJIS	= 0x80,	// 932
-    HANGUL	= 0x81,	// 949
-    GB2312	= 0x86,	// 936
-    CHINESEBIG5	= 0x88,	// 950
-    GREEK	= 0xA1,	// 1253
-    TURKISH	= 0xA2,	// 1254
-    HEBREW	= 0xB1,	// 1255
-    ARABIC	= 0xB2,	// 1256
-    BALTIC	= 0xBA,	// 1257
-    RUSSIAN	= 0xCC,	// 1251
-    THAI	= 0xDE,	// 874
-    EE		= 0xEE,	// 1250
-    OEM		= 0xFF	//
-  };
-
-  inline const char* get_charset() const
-  {
-    switch (dfCharSet) {
-    case ANSI: return "ISO8859";
-    case DEFAULT: return "WinDefault";
-    case SYMBOL: return "Symbol";
-    case SHIFTJIS: return "JISX0208.1983";
-    case HANGUL: return "MSHangul";
-    case GB2312: return "GB2312.1980";
-    case CHINESEBIG5: return "Big5";
-    case GREEK: return "CP1253";
-    case TURKISH: return "CP1254";
-    case HEBREW: return "CP1255";
-    case ARABIC: return "CP1256";
-    case BALTIC: return "CP1257";
-    case RUSSIAN: return "CP1251";
-    case THAI: return "CP874";
-    case EE: return "CP1250";
-    case OEM: return "OEM";
-    default: return "Unknown";
-    }
-  }
-
-  inline unsigned int get_version () const
-  {
-    return dfVersion;
-  }
-
-  inline unsigned int get_weight () const
-  {
-    return dfWeight;
-  }
-
-  enum weight_t {
-    DONTCARE	= 0,
-    THIN	= 100,
-    EXTRALIGHT	= 200,
-    ULTRALIGHT	= 200,
-    LIGHT	= 300,
-    NORMAL	= 400,
-    REGULAR	= 400,
-    MEDIUM	= 500,
-    SEMIBOLD	= 600,
-    DEMIBOLD	= 600,
-    BOLD	= 700,
-    EXTRABOLD	= 800,
-    ULTRABOLD	= 800,
-    HEAVY	= 900,
-    BLACK	= 900
-  };
-
-  inline void dump () const
-  {
-    // With https://github.com/juanitogan/mkwinfont/blob/master/python/dewinfont.py help
-    // Should be implemented differently eventually, but for now
-    unsigned int ctstart;
-    unsigned int ctsize;
-    if (dfVersion == 0x200)
-    {
-      ctstart = 0x76;
-      ctsize = 4;
-    }
-    else
-    {
-      return; // must of ".fon"s are version 2 and even dewinfont V1 implmentation doesn't seem correct
-      ctstart = 0x94;
-      ctsize = 6;
-    }
-    // unsigned int maxwidth = 0;
-    for (unsigned int i = dfFirstChar; i < dfLastChar; ++i)
-    {
-      unsigned int entry = ctstart + ctsize * (i-dfFirstChar);
-      unsigned int w = (uint16_t) OT::StructAtOffset<LEUINT16> (this, entry);
-
-      unsigned int off;
-      if (ctsize == 4)
-        off = (uint16_t) OT::StructAtOffset<LEUINT16> (this, entry+2);
-      else
-        off = (uint32_t) OT::StructAtOffset<LEUINT32> (this, entry+2);
-
-      unsigned int widthbytes = (w + 7) / 8;
-      for (unsigned int j = 0; j < dfPixHeight; ++j)
-      {
-        for (unsigned int k = 0; k < widthbytes; ++k)
-	{
-	  unsigned int bytepos = off + k * dfPixHeight + j;
-	  const uint8_t b = (uint8_t) OT::StructAtOffset<LEINT8> (this, bytepos);
-	  for (unsigned int a = 128; a > 0; a >>= 1)
-	    printf (b & a ? "x" : ".");
-	}
-	printf ("\n");
-      }
-      printf ("\n\n");
-    }
-  }
-
-  protected:
-  LEUINT16	dfVersion;
-  LEUINT32	dfSize;
-  LEUINT8	dfCopyright[60];
-  LEUINT16	dfType;
-  LEUINT16	dfPoints;
-  LEUINT16	dfVertRes;
-  LEUINT16	dfHorizRes;
-  LEUINT16	dfAscent;
-  LEUINT16	dfInternalLeading;
-  LEUINT16	dfExternalLeading;
-  LEUINT8	dfItalic;
-  LEUINT8	dfUnderline;
-  LEUINT8	dfStrikeOut;
-  LEUINT16	dfWeight; // see weight_t
-  LEUINT8	dfCharSet;  // see charset_t
-  LEUINT16	dfPixWidth;
-  LEUINT16	dfPixHeight;
-  LEUINT8	dfPitchAndFamily;
-  LEUINT16	dfAvgWidth;
-  LEUINT16	dfMaxWidth;
-  LEUINT8	dfFirstChar;
-  LEUINT8	dfLastChar;
-  LEUINT8	dfDefaultChar;
-  LEUINT8	dfBreakChar;
-  LEUINT16	dfWidthBytes;
-  LEUINT32	dfDevice;
-  LEUINT32	dfFace;
-  LEUINT32	dfBitsPointer;
-  LEUINT32	dfBitsOffset;
-  LEUINT8	dfReserved;
-//   LEUINT32	dfFlags;
-//   LEUINT16	dfAspace;
-//   LEUINT16	dfBspace;
-//   LEUINT16	dfCspace;
-//   LEUINT32	dfColorPointer;
-//   LEUINT32	dfReserved1[4];
-  OT::UnsizedArrayOf<LEUINT8>
-		dataZ;
-  public:
-  DEFINE_SIZE_ARRAY (118, dataZ);
-};
-
-struct NE_NAMEINFO
-{
-  friend struct NE_TYPEINFO;
-
-  inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base, unsigned int shift) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  get_font (base, shift).sanitize (c, length << shift)));
-  }
-
-  inline const LE_FONTINFO16& get_font (const void *base, int shift) const
-  {
-    return OT::StructAtOffset<LE_FONTINFO16> (base, offset << shift);
-  }
-
-  enum resource_type_flag_t {
-    NONE     = 0x0000,
-    MOVEABLE = 0x0010,
-    PURE     = 0x0020,
-    PRELOAD  = 0x0040
-  };
-
-  protected:
-  LEUINT16	offset;	// Should be shifted with alignmentShiftCount before use
-  LEUINT16	length;	// Should be shifted with alignmentShiftCount before use
-  LEUINT16	flags;	// resource_type_flag_t
-  LEUINT16	id;
-  LEUINT16	handle;
-  LEUINT16	usage;
-  public:
-  DEFINE_SIZE_STATIC (12);
-};
-
-struct NE_TYPEINFO
-{
-  inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base, unsigned int shift) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && resources.sanitize (c, count, base, shift));
-  }
-
-  inline unsigned int get_size (void) const
-  { return 8 + count * NE_NAMEINFO::static_size; }
-
-  inline const NE_TYPEINFO& next () const
-  {
-    const NE_TYPEINFO& next = OT::StructAfter<NE_TYPEINFO> (*this);
-    if (type_id == 0)
-      return Null(NE_TYPEINFO);
-    return next;
-  }
-
-  inline const LE_FONTINFO16& get_font (unsigned int idx, const void *base, int shift) const
-  {
-    if (idx < count)
-      return resources[idx].get_font (base, shift);
-    return Null(LE_FONTINFO16);
-  }
-
-  inline unsigned int get_count () const
-  {
-    return count;
-  }
-
-  inline unsigned int get_type_id () const
-  {
-    return type_id;
-  }
-
-  enum type_id_t {
-    CURSOR		= 0x8001,
-    BITMAP		= 0x8002,
-    ICON		= 0x8003,
-    MENU		= 0x8004,
-    DIALOG		= 0x8005,
-    STRING		= 0x8006,
-    FONT_DIRECTORY	= 0x8007,
-    FONT		= 0x8008,
-    ACCELERATOR_TABLE	= 0x8009,
-    RESOURCE_DATA	= 0x800a,
-    GROUP_CURSOR	= 0x800c,
-    GROUP_ICON		= 0x800e,
-    VERSION		= 0x8010
-  };
-
-  protected:
-  LEUINT16	type_id; // see type_id_t
-  LEUINT16	count;
-  LEUINT32	resloader;
-  OT::UnsizedArrayOf<NE_NAMEINFO>
-		resources;
-  public:
-  DEFINE_SIZE_ARRAY (8, resources);
-};
-
-struct NE_RESOURCE_TABLE
-{
-  inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-
-    if (!c->check_struct (this))
-      return_trace (false);
-
-    const NE_TYPEINFO* n = &chain;
-    while (n != &Null(NE_TYPEINFO) && c->check_struct (n) && n->get_type_id () != 0)
-    {
-      if (n->get_type_id () == NE_TYPEINFO::FONT)
-	return_trace (n->sanitize (c, base, alignmentShiftCount));
-      n = &n->next();
-    }
-    return_trace (false);
-  }
-
-  inline unsigned int get_shift_value () const
-  {
-    return alignmentShiftCount;
-  }
-
-  inline const NE_TYPEINFO& get_fonts_entry () const
-  {
-    const NE_TYPEINFO* n = &chain;
-    while (n != &Null(NE_TYPEINFO) && n->get_type_id () != 0)
-    {
-      if (n->get_type_id () == NE_TYPEINFO::FONT)
-	return *n;
-      n = &n->next();
-    }
-    return Null(NE_TYPEINFO);
-  }
-
-  protected:
-  LEUINT16	alignmentShiftCount;
-  NE_TYPEINFO	chain;
-  // It is followed by an array of OT::ArrayOf<LEUINT8, LEUINT8> chars;
-  public:
-  DEFINE_SIZE_MIN (2);
-};
-
-// https://github.com/wine-mirror/wine/blob/master/include/winnt.h#L2467
-struct LE_IMAGE_OS2_HEADER
-{
-  inline bool sanitize (OT::hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) && (this+rsrctab).sanitize (c, base)));
-  }
-
-  inline const NE_RESOURCE_TABLE& get_resource_table () const
-  {
-    if (magic != 0x454E) // Only NE containers are support for now, NE == 0x454E
-      return Null(NE_RESOURCE_TABLE);
-    return this+rsrctab;
-  }
-
-  protected:
-  LEUINT16	magic;		/* 00 NE signature 'NE' */
-  LEUINT8	ver;		/* 02 Linker version number */
-  LEUINT8	rev;		/* 03 Linker revision number */
-  LEUINT16	enttab;		/* 04 Offset to entry table relative to NE */
-  LEUINT16	cbenttab;	/* 06 Length of entry table in bytes */
-  LEUINT32	crc;		/* 08 Checksum */
-  LEUINT16	flags;		/* 0c Flags about segments in this file */
-  LEUINT16	autodata;	/* 0e Automatic data segment number */
-  LEUINT16	heap;		/* 10 Initial size of local heap */
-  LEUINT16	stack;		/* 12 Initial size of stack */
-  LEUINT32	csip;		/* 14 Initial CS:IP */
-  LEUINT32	sssp;		/* 18 Initial SS:SP */
-  LEUINT16	cseg;		/* 1c # of entries in segment table */
-  LEUINT16	cmod;		/* 1e # of entries in module reference tab. */
-  LEUINT16	cbnrestab;	/* 20 Length of nonresident-name table     */
-  LEUINT16	segtab;		/* 22 Offset to segment table */
-  OT::OffsetTo<NE_RESOURCE_TABLE, LEUINT16>
-		rsrctab;	/* 24 Offset to resource table */
-  LEUINT16	restab;		/* 26 Offset to resident-name table */
-  LEUINT16	modtab;		/* 28 Offset to module reference table */
-  LEUINT16	imptab;		/* 2a Offset to imported name table */
-  LEUINT32	nrestab;	/* 2c Offset to nonresident-name table */
-  LEUINT16	cmovent;	/* 30 # of movable entry points */
-  LEUINT16	align;		/* 32 Logical sector alignment shift count */
-  LEUINT16	cres;		/* 34 # of resource segments */
-  LEUINT8	exetyp;		/* 36 Flags indicating target OS */
-  LEUINT8	flagsothers;	/* 37 Additional information flags */
-  LEUINT16	pretthunks;	/* 38 Offset to return thunks */
-  LEUINT16	psegrefbytes;	/* 3a Offset to segment ref. bytes */
-  LEUINT16	swaparea;	/* 3c Reserved by Microsoft */
-  LEUINT16	expver;		/* 3e Expected Windows version number */
-  public:
-  DEFINE_SIZE_STATIC (64);
-};
-
-struct LE_IMAGE_DOS_HEADER {
-  inline bool sanitize (OT::hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  get_os2_header ().sanitize (c, this)));
-  }
-
-  inline const LE_IMAGE_OS2_HEADER& get_os2_header () const
-  {
-    return this+e_lfanew;
-  }
-
-  protected:
-  LEUINT16	e_magic;	// Magic number
-  LEUINT16	e_cblp;		// Bytes on last page of file
-  LEUINT16	e_cp;		// Pages in file
-  LEUINT16	e_crlc;		// Relocations
-  LEUINT16	e_cparhdr;	// Size of header in paragraphs
-  LEUINT16	e_minalloc;	// Minimum extra paragraphs needed
-  LEUINT16	e_maxalloc;	// Maximum extra paragraphs needed
-  LEUINT16	e_ss;		// Initial (relative) SS value
-  LEUINT16	e_sp;		// Initial SP value
-  LEUINT16	e_csum;		// Checksum
-  LEUINT16	e_ip;		// Initial IP value
-  LEUINT16	e_cs;		// Initial (relative) CS value
-  LEUINT16	e_lfarlc;	// File address of relocation table
-  LEUINT16	e_ovno;		// Overlay number
-  LEUINT16	e_res_0;	// Reserved words
-  LEUINT16	e_res_1;	// Reserved words
-  LEUINT16	e_res_2;	// Reserved words
-  LEUINT16	e_res_3;	// Reserved words
-  LEUINT16	e_oemid;	// OEM identifier (for e_oeminfo)
-  LEUINT16	e_oeminfo;	// OEM information; e_oemid specific
-  LEUINT16	e_res2_0;	// Reserved words
-  LEUINT16	e_res2_1;	// Reserved words
-  LEUINT16	e_res2_2;	// Reserved words
-  LEUINT16	e_res2_3;	// Reserved words
-  LEUINT16	e_res2_4;	// Reserved words
-  LEUINT16	e_res2_5;	// Reserved words
-  LEUINT16	e_res2_6;	// Reserved words
-  LEUINT16	e_res2_7;	// Reserved words
-  LEUINT16	e_res2_8;	// Reserved words
-  LEUINT16	e_res2_9;	// Reserved words
-  OT::OffsetTo<LE_IMAGE_OS2_HEADER, LEUINT32>
-		e_lfanew;	// File address of new exe header
-  public:
-  DEFINE_SIZE_STATIC (64);
-};
-
-int main (int argc, char** argv) {
-  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
-
-  OT::Sanitizer<LE_IMAGE_DOS_HEADER> sanitizer;
-  hb_blob_t *font_blob = sanitizer.sanitize (blob);
-  const LE_IMAGE_DOS_HEADER* dos_header = font_blob->as<LE_IMAGE_DOS_HEADER> ();
-
-  const NE_RESOURCE_TABLE &rtable = dos_header->get_os2_header ().get_resource_table ();
-  int shift = rtable.get_shift_value ();
-  const NE_TYPEINFO& entry = rtable.get_fonts_entry ();
-  for (unsigned int i = 0; i < entry.get_count (); ++i)
-  {
-    const LE_FONTINFO16& font = entry.get_font (i, dos_header, shift);
-    printf ("version: %x, weight: %d, charset: %s\n", font.get_version (),
-	    font.get_weight (), font.get_charset ());
-    // font.dump ();
-  }
-  return 0;
-}

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2018-08-02 22:27:18 UTC (rev 48337)
@@ -328,6 +328,9 @@
 		# TODO: https://github.com/harfbuzz/harfbuzz/pull/626
 		if U == 0xA8B4: UISC = Consonant_Medial
 
+		# TODO: https://github.com/harfbuzz/harfbuzz/issues/1105
+		if U == 0x11134: UISC = Gemination_Mark
+
 		values = [k for k,v in items if v(U,UISC,UGC)]
 		assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values)
 		USE = values[0]
@@ -356,6 +359,13 @@
 		# https://github.com/roozbehp/unicode-data/issues/8
 		if U == 0x0A51: UIPC = Bottom
 
+		# TODO: https://github.com/harfbuzz/harfbuzz/pull/982
+		if UBlock == 'Chakma' and is_VOWEL (U, UISC, UGC):
+			if UIPC == Top:
+				UIPC = Bottom
+			elif UIPC == Bottom:
+				UIPC = Top
+
 		assert (UIPC in [Not_Applicable, Visual_Order_Left] or
 			USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC)
 

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fmtx-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,67 +0,0 @@
-/*
- * 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_FMTX_TABLE_HH
-#define HB_AAT_FMTX_TABLE_HH
-
-#include "hb-aat-layout-common-private.hh"
-
-/*
- * fmtx -- Font Metrics
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fmtx.html
- */
-#define HB_AAT_TAG_fmtx HB_TAG('f','m','t','x')
-
-
-namespace AAT {
-
-
-struct fmtx
-{
-  static const hb_tag_t tableTag = HB_AAT_TAG_fmtx;
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this)));
-  }
-
-  FixedVersion<>version;		/* Version (set to 0x00020000). */
-  HBUINT32	glyphIndex;		/* The glyph whose points represent the metrics. */
-  HBUINT8	horizontalBefore;	/* Point number for the horizontal ascent. */
-  HBUINT8	horizontalAfter;	/* Point number for the horizontal descent. */
-  HBUINT8	horizontalCaretHead;	/* Point number for the horizontal caret head. */
-  HBUINT8	horizontalCaretBase;	/* Point number for the horizontal caret base. */
-  HBUINT8	verticalBefore;		/* Point number for the vertical ascent. */
-  HBUINT8	verticalAfter;		/* Point number for the vertical descent. */
-  HBUINT8	verticalCaretHead;	/* Point number for the vertical caret head. */
-  HBUINT8	verticalCaretBase;	/* Point number for the vertical caret base. */
-  public:
-  DEFINE_SIZE_STATIC (16);
-};
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_FMTX_TABLE_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-gcid-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -1,73 +0,0 @@
-/*
- * 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_GCID_TABLE_HH
-#define HB_AAT_GCID_TABLE_HH
-
-#include "hb-aat-layout-common-private.hh"
-
-/*
- * gcid -- Glyphs CIDs
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gcid.html
- */
-#define HB_AAT_TAG_gcid HB_TAG('g','c','i','d')
-
-
-namespace AAT {
-
-
-struct gcid
-{
-  static const hb_tag_t tableTag = HB_AAT_TAG_gcid;
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) && CIDs.sanitize (c)));
-  }
-
-  protected:
-  HBUINT16	version;	/* Version number (set to 0) */
-  HBUINT16	format;		/* Data format (set to 0) */
-  HBUINT32	size;		/* Size of the table, including header */
-  HBUINT16	registry;	/* The registry ID */
-  HBUINT8	registryName[64];
-				/* The registry name in ASCII */
-  HBUINT16	order;		/* The order ID */
-  HBUINT8	orderName[64];	/* The order name in ASCII */
-  HBUINT16	supplementVersion;
-				/* The supplement version */
-  ArrayOf<HBUINT16>
-		CIDs;		/* The CIDs for the glyphs in the font,
-				 * starting with glyph 0. If a glyph does not correspond
-				 * to a CID in the identified collection, 0xFFFF is used.
-				 * This should not exceed the number of glyphs in the font. */
-  public:
-  DEFINE_SIZE_ARRAY (144, CIDs);
-};
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_GCID_TABLE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -161,7 +161,7 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (arrayZ.sanitize (c, c->num_glyphs));
+    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
   }
 
   protected:
@@ -625,7 +625,7 @@
 		sanitizer (), lookup_index (0), debug_depth (0)
   {
     sanitizer.init (table);
-    sanitizer.num_glyphs = face->get_num_glyphs ();
+    sanitizer.set_num_glyphs (face->get_num_glyphs ());
     sanitizer.start_processing ();
   }
 

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -36,48 +36,12 @@
 #include "hb-aat-layout-kerx-table.hh"
 #include "hb-aat-layout-morx-table.hh"
 #include "hb-aat-layout-trak-table.hh"
-#include "hb-aat-fmtx-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-aat-gcid-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise.
 
 /*
- * morx/kerx/trak
+ * morx/kerx/trak/ankr
  */
 
-#if 0
-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);
-  }
-  hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
-  const AAT::ankr& ankr = *(layout->ankr.get ());
-  if (blob)
-    *blob = layout->ankr.blob;
-  return ankr;
-}
-
-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);
-  }
-  hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
-  /* XXX this doesn't call set_num_glyphs on sanitizer. */
-  const AAT::kerx& kerx = *(layout->kerx.get ());
-  if (blob)
-    *blob = layout->kerx.blob;
-  return kerx;
-}
-
 static inline const AAT::morx&
 _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
 {
@@ -88,36 +52,16 @@
     return Null(AAT::morx);
   }
   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
-  /* XXX this doesn't call set_num_glyphs on sanitizer. */
   const AAT::morx& morx = *(layout->morx.get ());
   if (blob)
-    *blob = layout->morx.blob;
+    *blob = layout->morx.get_blob ();
   return morx;
 }
 
-static inline const AAT::trak&
-_get_trak (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::trak);
-  }
-  hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
-  const AAT::trak& trak = *(layout->trak.get ());
-  if (blob)
-    *blob = layout->trak.blob;
-  return trak;
-}
-#endif
-
 // static inline void
 // _hb_aat_layout_create (hb_face_t *face)
 // {
-//   OT::Sanitizer<AAT::morx> sanitizer;
-//   sanitizer.set_num_glyphs (face->get_num_glyphs ());
-//   hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_morx));
+//   hb_blob_t *morx_blob = OT::hb_sanitize_context_t().reference_table<AAT::morx> (face);
 //   morx_blob->as<AAT::morx> ();
 
 //   if (0)
@@ -129,13 +73,11 @@
 void
 hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
 {
-#if 0
   hb_blob_t *blob;
   const AAT::morx& morx = _get_morx (font->face, &blob);
 
   AAT::hb_aat_apply_context_t c (font, buffer, blob);
   morx.apply (&c);
-#endif
 }
 
 void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -46,14 +46,16 @@
 /* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */
 
 
-#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE)
+#elif !defined(HB_NO_MT) && defined(__ATOMIC_CONSUME)
 
 /* C++11-style GCC primitives. */
 
 typedef int hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)		__atomic_fetch_add (&(AI), (V), __ATOMIC_ACQ_REL)
+#define hb_atomic_int_impl_add(AI, V)		__atomic_fetch_add ((AI), (V), __ATOMIC_ACQ_REL)
+#define hb_atomic_int_impl_set_relaxed(AI, V)	__atomic_store_n ((AI), (V), __ATOMIC_RELAXED)
+#define hb_atomic_int_impl_get_relaxed(AI)	__atomic_load_n ((AI), __ATOMIC_RELAXED)
 
-#define hb_atomic_ptr_impl_get(P)		__atomic_load_n ((P), __ATOMIC_ACQUIRE)
+#define hb_atomic_ptr_impl_get(P)		__atomic_load_n ((P), __ATOMIC_CONSUME)
 static inline bool
 _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
 {
@@ -60,7 +62,7 @@
   const void *O = O_; // Need lvalue
   return __atomic_compare_exchange_n ((void **) P, (void **) &O, (void *) N, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
 }
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)	(_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)	_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
 
 #elif !defined(HB_NO_MT) && __cplusplus >= 201103L
 
@@ -69,9 +71,11 @@
 #include <atomic>
 
 typedef int hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)		(reinterpret_cast<std::atomic<int> *> (&AI)->fetch_add ((V), std::memory_order_acq_rel))
+#define hb_atomic_int_impl_add(AI, V)		(reinterpret_cast<std::atomic<int> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
+#define hb_atomic_int_impl_set_relaxed(AI, V)	(reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_relaxed))
+#define hb_atomic_int_impl_get_relaxed(AI)	(reinterpret_cast<std::atomic<int> *> (AI)->load (std::memory_order_relaxed))
 
-#define hb_atomic_ptr_impl_get(P)		(reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_acquire))
+#define hb_atomic_ptr_impl_get(P)		(reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_consume))
 static inline bool
 _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
 {
@@ -78,7 +82,7 @@
   const void *O = O_; // Need lvalue
   return reinterpret_cast<std::atomic<const void*> *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed);
 }
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)	(_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)))
+#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__))
@@ -85,11 +89,10 @@
 
 #include <windows.h>
 
-/* MinGW has a convoluted history of supporting MemoryBarrier
- * properly.  As such, define a function to wrap the whole
- * thing. */
-static inline void _HBMemoryBarrier (void) {
+static inline void _hb_memory_barrier (void)
+{
 #if !defined(MemoryBarrier)
+  /* MinGW has a convoluted history of supporting MemoryBarrier. */
   long dummy = 0;
   InterlockedExchange (&dummy, 1);
 #else
@@ -96,20 +99,21 @@
   MemoryBarrier ();
 #endif
 }
+#define _hb_memory_barrier()			_hb_memory_barrier ()
 
 typedef LONG hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)		InterlockedExchangeAdd (&(AI), (V))
+#define hb_atomic_int_impl_add(AI, V)		InterlockedExchangeAdd ((AI), (V))
 
-#define hb_atomic_ptr_impl_get(P)		(_HBMemoryBarrier (), (void *) *(P))
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)	(InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
 
 
 #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
 
+#define _hb_memory_barrier()			__sync_synchronize ()
+
 typedef int hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)		__sync_fetch_and_add (&(AI), (V))
+#define hb_atomic_int_impl_add(AI, V)		__sync_fetch_and_add ((AI), (V))
 
-#define hb_atomic_ptr_impl_get(P)		(void *) (__sync_synchronize (), *(P))
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)	__sync_bool_compare_and_swap ((P), (O), (N))
 
 
@@ -118,13 +122,32 @@
 #include <atomic.h>
 #include <mbarrier.h>
 
+#define _hb_memory_r_barrier()			__machine_r_barrier ()
+#define _hb_memory_w_barrier()			__machine_w_barrier ()
+#define _hb_memory_barrier()			__machine_rw_barrier ()
+
 typedef unsigned int hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)		( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
 
-#define hb_atomic_ptr_impl_get(P)		( ({__machine_rw_barrier ();}), (void *) *(P))
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)	( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
+static inline int _hb_fetch_and_add (hb_atomic_int_impl_t *AI, int V)
+{
+  _hb_memory_w_barrier ();
+  int result = atomic_add_int_nv (AI, V);
+  _hb_memory_r_barrier ();
+  return result;
+}
+static inline bool _hb_compare_and_swap_ptr (const void **P, const void *O, const void *N)
+{
+  _hb_memory_w_barrier ();
+  int result = atomic_cas_ptr ((void **) P, (void *) O, (void *) N) == (void *) O;
+  _hb_memory_r_barrier ();
+  return result;
+}
 
+#define hb_atomic_int_impl_add(AI, V)           _hb_fetch_and_add ((AI), (V))
 
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       _hb_compare_and_swap_ptr ((const void **) (P), (O), (N))
+
+
 #elif !defined(HB_NO_MT) && defined(__APPLE__)
 
 #include <libkern/OSAtomic.h>
@@ -134,11 +157,11 @@
 #include <Availability.h>
 #endif
 
+#define _hb_memory_barrier()			OSMemoryBarrier ()
 
 typedef int32_t hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)		(OSAtomicAdd32Barrier ((V), &(AI)) - (V))
+#define hb_atomic_int_impl_add(AI, V)		(OSAtomicAdd32Barrier ((V), (AI)) - (V))
 
-#define hb_atomic_ptr_impl_get(P)		(OSMemoryBarrier (), (void *) *(P))
 #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
 #else
@@ -154,34 +177,40 @@
 
 #include <builtins.h>
 
+#define _hb_memory_barrier()			__lwsync ()
 
-static inline int _hb_fetch_and_add(volatile int* AI, unsigned int V) {
-  __lwsync();
-  int result = __fetch_and_add(AI, V);
-  __isync();
+typedef int hb_atomic_int_impl_t;
+
+static inline int _hb_fetch_and_add (hb_atomic_int_impl_t *AI, int V)
+{
+  _hb_memory_barrier ();
+  int result = __fetch_and_add (AI, V);
+  _hb_memory_barrier ();
   return result;
 }
-static inline int _hb_compare_and_swaplp(volatile long* P, long O, long N) {
-  __sync();
-  int result = __compare_and_swaplp (P, &O, N);
-  __sync();
+static inline bool _hb_compare_and_swaplp (long *P, long O, long N)
+{
+  _hb_memory_barrier ();
+  bool result = __compare_and_swaplp (P, &O, N);
+  _hb_memory_barrier ();
   return result;
 }
 
-typedef int hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)           _hb_fetch_and_add (&(AI), (V))
+#define hb_atomic_int_impl_add(AI, V)           _hb_fetch_and_add ((AI), (V))
 
-#define hb_atomic_ptr_impl_get(P)               (__sync(), (void *) *(P))
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)       _hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       _hb_compare_and_swaplp ((long *) (P), (long) (O), (long) (N))
+static_assert ((sizeof (long) == sizeof (void *)), "");
 
+
 #elif !defined(HB_NO_MT)
 
 #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
 
+#define _hb_memory_barrier()
+
 typedef volatile int hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)		(((AI) += (V)) - (V))
+#define hb_atomic_int_impl_add(AI, V)		((*(AI) += (V)) - (V))
 
-#define hb_atomic_ptr_impl_get(P)		((void *) *(P))
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)	(* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
 
 
@@ -188,9 +217,10 @@
 #else /* HB_NO_MT */
 
 typedef int hb_atomic_int_impl_t;
-#define hb_atomic_int_impl_add(AI, V)		(((AI) += (V)) - (V))
+#define hb_atomic_int_impl_add(AI, V)		((*(AI) += (V)) - (V))
 
-#define hb_atomic_ptr_impl_get(P)		((void *) *(P))
+#define _hb_memory_barrier()
+
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)	(* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
 
 
@@ -197,22 +227,38 @@
 #endif
 
 
+#ifndef _hb_memory_r_barrier
+#define _hb_memory_r_barrier()			_hb_memory_barrier ()
+#endif
+#ifndef _hb_memory_w_barrier
+#define _hb_memory_w_barrier()			_hb_memory_barrier ()
+#endif
 #ifndef HB_ATOMIC_INT_INIT
 #define HB_ATOMIC_INT_INIT(V)          {V}
 #endif
+#ifndef hb_atomic_int_impl_set_relaxed
+#define hb_atomic_int_impl_set_relaxed(AI, V)	(*(AI) = (V))
+#endif
+#ifndef hb_atomic_int_impl_get_relaxed
+#define hb_atomic_int_impl_get_relaxed(AI)	(*(AI))
+#endif
+#ifndef hb_atomic_ptr_impl_get
+inline void *hb_atomic_ptr_impl_get (void **P)	{ void *v = *P; _hb_memory_r_barrier (); return v; }
+#endif
 
+
 struct hb_atomic_int_t
 {
   mutable hb_atomic_int_impl_t v;
 
-  inline void set_unsafe (int v_) { v = v_; }
-  inline int get_unsafe (void) const { return 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); }
+  inline void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
+  inline int get_relaxed (void) const { return hb_atomic_int_impl_get_relaxed (&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); }
 };
 
 
-#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P)
+#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get((void **) P)
 #define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N))
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -37,7 +37,7 @@
 
 /* hb_options_t */
 
-hb_options_union_t _hb_options;
+hb_atomic_int_t _hb_options;
 
 void
 _hb_options_init (void)
@@ -50,7 +50,7 @@
   u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
 
   /* This is idempotent and threadsafe. */
-  _hb_options = u;
+  _hb_options.set_relaxed (u.i);
 }
 
 
@@ -1069,3 +1069,12 @@
   memcpy (buf, s, len);
   buf[len] = '\0';
 }
+
+/* If there is no visibility control, then hb-static.cc will NOT
+ * define anything.  Instead, we get it to define one set in here
+ * only, so only libharfbuzz.so defines them, not other libs. */
+#ifdef HB_NO_VISIBILITY
+#undef HB_NO_VISIBILITY
+#include "hb-static.cc"
+#define HB_NO_VISIBILITY 1
+#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -28,6 +28,7 @@
 #define HB_DEBUG_HH
 
 #include "hb-private.hh"
+#include "hb-atomic-private.hh"
 #include "hb-dsalgs.hh"
 
 
@@ -35,6 +36,47 @@
 #define HB_DEBUG 0
 #endif
 
+
+/*
+ * Global runtime options.
+ */
+
+struct hb_options_t
+{
+  unsigned int unused : 1; /* In-case sign bit is here. */
+  unsigned int initialized : 1;
+  unsigned int uniscribe_bug_compatible : 1;
+};
+
+union hb_options_union_t {
+  int i;
+  hb_options_t opts;
+};
+static_assert ((sizeof (hb_atomic_int_t) >= sizeof (hb_options_union_t)), "");
+
+HB_INTERNAL void
+_hb_options_init (void);
+
+extern HB_INTERNAL hb_atomic_int_t _hb_options;
+
+static inline hb_options_t
+hb_options (void)
+{
+  /* Make a local copy, so we can access bitfield threadsafely. */
+  hb_options_union_t u;
+  u.i = _hb_options.get_relaxed ();
+
+  if (unlikely (!u.i))
+    _hb_options_init ();
+
+  return u.opts;
+}
+
+
+/*
+ * Debug output (needs enabling at compile time.)
+ */
+
 static inline bool
 _hb_debug (unsigned int level,
 	   unsigned int max_level)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -31,8 +31,6 @@
 #include "hb-face-private.hh"
 #include "hb-blob-private.hh"
 #include "hb-open-file-private.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-maxp-table.hh"
 
 
 
@@ -52,10 +50,13 @@
   if (unlikely (!blob))
     return 0;
 
-  hb_blob_t *sanitized = OT::Sanitizer<OT::OpenTypeFontFile> ().sanitize (blob);
+  /* TODO We shouldn't be sanitizing blob.  Port to run sanitizer and return if not sane. */
+  hb_blob_t *sanitized = OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob));
   const OT::OpenTypeFontFile& ot = *sanitized->as<OT::OpenTypeFontFile> ();
+  unsigned int ret = ot.get_face_count ();
+  hb_blob_destroy (sanitized);
 
-  return ot.get_face_count ();
+  return ret;
 }
 
 /*
@@ -188,7 +189,7 @@
   if (unlikely (!blob))
     blob = hb_blob_get_empty ();
 
-  hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>().sanitize (hb_blob_reference (blob)), index);
+  hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob)), index);
 
   if (unlikely (!closure))
     return hb_face_get_empty ();
@@ -445,15 +446,6 @@
   return face->get_upem ();
 }
 
-void
-hb_face_t::load_upem (void) const
-{
-  hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (reference_table (HB_OT_TAG_head));
-  const OT::head *head_table = head_blob->as<OT::head> ();
-  upem = head_table->get_upem ();
-  hb_blob_destroy (head_blob);
-}
-
 /**
  * hb_face_set_glyph_count:
  * @face: a face.
@@ -489,15 +481,6 @@
   return face->get_num_glyphs ();
 }
 
-void
-hb_face_t::load_num_glyphs (void) const
-{
-  hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (reference_table (HB_OT_TAG_maxp));
-  const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> ();
-  num_glyphs = maxp_table->get_num_glyphs ();
-  hb_blob_destroy (maxp_blob);
-}
-
 /**
  * hb_face_get_table_tags:
  * @face: a face.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -497,7 +497,10 @@
 
   error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
   if (error)
+  {
+    free (buffer);
     return nullptr;
+  }
 
   return hb_blob_create ((const char *) buffer, length,
 			 HB_MEMORY_MODE_WRITABLE,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -71,6 +71,7 @@
 HB_DEFINE_OBJECT_TYPE (font)
 HB_DEFINE_OBJECT_TYPE (font_funcs)
 HB_DEFINE_OBJECT_TYPE (set)
+HB_DEFINE_OBJECT_TYPE (map)
 HB_DEFINE_OBJECT_TYPE (shape_plan)
 HB_DEFINE_OBJECT_TYPE (unicode_funcs)
 HB_DEFINE_VALUE_TYPE (feature)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h	2018-08-02 22:27:18 UTC (rev 48337)
@@ -90,6 +90,10 @@
 #define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ())
 
 HB_EXTERN GType
+hb_gobject_map_get_type (void);
+#define HB_GOBJECT_TYPE_MAP (hb_gobject_map_get_type ())
+
+HB_EXTERN GType
 hb_gobject_shape_plan_get_type (void);
 #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ())
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter-private.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_ITER_PRIVATE_HH
+#define HB_ITER_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* Unified iterator object.
+ *
+ * The goal of this template is to make the same iterator interface
+ * available to all types, and make it very easy and compact to use.
+ * Iterator objects are small, light-weight, objects that can be
+ * copied by value.  If the collection / object being iterated on
+ * is writable, then the iterator points to lvalues, otherwise it
+ * returns rvalues.
+ *
+ * The way to declare, initialize, and use iterators, eg.:
+ *
+ *   Iter<const int *> s (src);
+ *   Iter<int *> t (dst);
+ *   for (; s && t; s++, t++)
+ *     *s = *t;
+ */
+
+template <typename T>
+struct Iter;
+
+#if 0
+template <typename T>
+struct Iter
+{
+  explicit inline Iter (const T &c);
+};
+#endif
+
+template <typename T>
+struct Iter<T *>
+{
+  /* Type of items. */
+  typedef T Value;
+
+  /* Constructors. */
+  inline Iter (T *array_, int length_) :
+    array (array_), length (MAX (length_, 0)) {}
+  template <unsigned int length_>
+  explicit inline Iter (T (&array_)[length_]) :
+    array (array_), length (length_) {}
+
+  /* Emptiness. */
+  inline operator bool (void) const { return bool (length); }
+
+  /* Current item. */
+  inline T &operator * (void)
+  {
+    if (unlikely (!length)) return CrapOrNull(T);
+    return *array;
+  }
+  inline T &operator -> (void)
+  {
+    return (operator *);
+  }
+
+  /* Next. */
+  inline Iter<T *> & operator ++ (void)
+  {
+    if (unlikely (!length)) return *this;
+    array++;
+    length--;
+    return *this;
+  }
+  /* Might return void, or a copy of pre-increment iterator. */
+  inline void operator ++ (int)
+  {
+    if (unlikely (!length)) return;
+    array++;
+    length--;
+  }
+
+  /* Some iterators might implement len(). */
+  inline unsigned int len (void) const { return length; }
+
+  /* Some iterators might implement fast-forward.
+   * Only implement it if it's constant-time. */
+  inline void operator += (unsigned int n)
+  {
+    n = MIN (n, length);
+    array += n;
+    length -= n;
+  }
+
+  /* Some iterators might implement random-access.
+   * Only implement it if it's constant-time. */
+  inline Iter<T *> & operator [] (unsigned int i)
+  {
+    if (unlikely (i >= length)) return CrapOrNull(T);
+    return array[i];
+  }
+
+  private:
+  T *array;
+  unsigned int length;
+};
+
+/* XXX Remove
+ * Just to test these compile. */
+static inline void
+m (void)
+{
+  const int src[10] = {};
+  int dst[20];
+
+  Iter<const int *> s (src);
+  Iter<const int *> s2 (src, 5);
+  Iter<int *> t (dst);
+
+  s2 = s;
+
+  for (; s && t; ++s, ++t)
+   {
+    *t = *s;
+   }
+}
+
+#endif /* HB_ITER_PRIVATE_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery-private.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -0,0 +1,696 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2012,2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_MACHINERY_PRIVATE_HH
+#define HB_MACHINERY_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-iter-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * Casts
+ */
+
+/* Cast to struct T, reference to reference */
+template<typename Type, typename TObject>
+static inline const Type& CastR(const TObject &X)
+{ return reinterpret_cast<const Type&> (X); }
+template<typename Type, typename TObject>
+static inline Type& CastR(TObject &X)
+{ return reinterpret_cast<Type&> (X); }
+
+/* Cast to struct T, pointer to pointer */
+template<typename Type, typename TObject>
+static inline const Type* CastP(const TObject *X)
+{ return reinterpret_cast<const Type*> (X); }
+template<typename Type, typename TObject>
+static inline Type* CastP(TObject *X)
+{ return reinterpret_cast<Type*> (X); }
+
+/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
+ * location pointed to by P plus Ofs bytes. */
+template<typename Type>
+static inline const Type& StructAtOffset(const void *P, unsigned int offset)
+{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
+template<typename Type>
+static inline Type& StructAtOffset(void *P, unsigned int offset)
+{ return * reinterpret_cast<Type*> ((char *) P + offset); }
+
+/* StructAfter<T>(X) returns the struct T& that is placed after X.
+ * Works with X of variable size also.  X must implement get_size() */
+template<typename Type, typename TObject>
+static inline const Type& StructAfter(const TObject &X)
+{ return StructAtOffset<Type>(&X, X.get_size()); }
+template<typename Type, typename TObject>
+static inline Type& StructAfter(TObject &X)
+{ return StructAtOffset<Type>(&X, X.get_size()); }
+
+
+/*
+ * Size checking
+ */
+
+/* Check _assertion in a method environment */
+#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
+  inline void _instance_assertion_on_line_##_line (void) const \
+  { \
+    static_assert ((_assertion), ""); \
+    ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
+  }
+# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
+# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
+
+/* Check that _code compiles in a method environment */
+#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
+  inline void _compiles_assertion_on_line_##_line (void) const \
+  { _code; }
+# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
+# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
+
+
+#define DEFINE_SIZE_STATIC(size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
+  static const unsigned int static_size = (size); \
+  static const unsigned int min_size = (size); \
+  inline unsigned int get_size (void) const { return (size); }
+
+#define DEFINE_SIZE_UNION(size, _member) \
+  DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \
+  static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_MIN(size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
+  static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_ARRAY(size, array) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
+  DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
+  static const unsigned int min_size = (size)
+
+#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) \
+  static const unsigned int min_size = (size)
+
+
+/*
+ * Dispatch
+ */
+
+template <typename Context, typename Return, unsigned int MaxDebugDepth>
+struct hb_dispatch_context_t
+{
+  static const unsigned int max_debug_depth = MaxDebugDepth;
+  typedef Return return_t;
+  template <typename T, typename F>
+  inline bool may_dispatch (const T *obj, const F *format) { return true; }
+  static return_t no_dispatch_return_value (void) { return Context::default_return_value (); }
+};
+
+
+/*
+ * Sanitize
+ */
+
+/* This limits sanitizing time on really broken fonts. */
+#ifndef HB_SANITIZE_MAX_EDITS
+#define HB_SANITIZE_MAX_EDITS 32
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_FACTOR
+#define HB_SANITIZE_MAX_OPS_FACTOR 8
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_MIN
+#define HB_SANITIZE_MAX_OPS_MIN 16384
+#endif
+
+struct hb_sanitize_context_t :
+       hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
+{
+  inline hb_sanitize_context_t (void) :
+	debug_depth (0),
+	start (nullptr), end (nullptr),
+	writable (false), edit_count (0), max_ops (0),
+	blob (nullptr),
+	num_glyphs (65536),
+	num_glyphs_set (false) {}
+
+  inline const char *get_name (void) { return "SANITIZE"; }
+  template <typename T, typename F>
+  inline bool may_dispatch (const T *obj, const F *format)
+  { return format->sanitize (this); }
+  template <typename T>
+  inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
+  static return_t default_return_value (void) { return true; }
+  static return_t no_dispatch_return_value (void) { return false; }
+  bool stop_sublookup_iteration (const return_t r) const { return !r; }
+
+  inline void init (hb_blob_t *b)
+  {
+    this->blob = hb_blob_reference (b);
+    this->writable = false;
+  }
+
+  inline void set_num_glyphs (unsigned int num_glyphs_)
+  {
+    num_glyphs = num_glyphs_;
+    num_glyphs_set = true;
+  }
+  inline unsigned int get_num_glyphs (void) { return num_glyphs; }
+
+  inline void start_processing (void)
+  {
+    this->start = hb_blob_get_data (this->blob, nullptr);
+    this->end = this->start + this->blob->length;
+    assert (this->start <= this->end); /* Must not overflow. */
+    this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
+			 (unsigned) HB_SANITIZE_MAX_OPS_MIN);
+    this->edit_count = 0;
+    this->debug_depth = 0;
+
+    DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
+		     "start [%p..%p] (%lu bytes)",
+		     this->start, this->end,
+		     (unsigned long) (this->end - this->start));
+  }
+
+  inline void end_processing (void)
+  {
+    DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
+		     "end [%p..%p] %u edit requests",
+		     this->start, this->end, this->edit_count);
+
+    hb_blob_destroy (this->blob);
+    this->blob = nullptr;
+    this->start = this->end = nullptr;
+  }
+
+  inline bool check_range (const void *base, unsigned int len) const
+  {
+    const char *p = (const char *) base;
+    bool ok = this->max_ops-- > 0 &&
+	      this->start <= p &&
+	      p <= this->end &&
+	      (unsigned int) (this->end - p) >= len;
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+       "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s",
+       p, p + len, len,
+       this->start, this->end,
+       ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
+
+  inline bool check_array (const void *base, unsigned int record_size, unsigned int len) 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);
+
+    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");
+
+    return likely (ok);
+  }
+
+  template <typename Type>
+  inline bool check_struct (const Type *obj) const
+  {
+    return likely (this->check_range (obj, obj->min_size));
+  }
+
+  inline bool may_edit (const void *base, unsigned int len)
+  {
+    if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
+      return false;
+
+    const char *p = (const char *) base;
+    this->edit_count++;
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+       "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
+       this->edit_count,
+       p, p + len, len,
+       this->start, this->end,
+       this->writable ? "GRANTED" : "DENIED");
+
+    return this->writable;
+  }
+
+  template <typename Type, typename ValueType>
+  inline bool try_set (const Type *obj, const ValueType &v) {
+    if (this->may_edit (obj, obj->static_size)) {
+      const_cast<Type *> (obj)->set (v);
+      return true;
+    }
+    return false;
+  }
+
+  template <typename Type>
+  inline hb_blob_t *sanitize_blob (hb_blob_t *blob)
+  {
+    bool sane;
+
+    init (blob);
+
+  retry:
+    DEBUG_MSG_FUNC (SANITIZE, start, "start");
+
+    start_processing ();
+
+    if (unlikely (!start))
+    {
+      end_processing ();
+      return blob;
+    }
+
+    Type *t = CastP<Type> (const_cast<char *> (start));
+
+    sane = t->sanitize (this);
+    if (sane)
+    {
+      if (edit_count)
+      {
+	DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %d edits; going for second round", edit_count);
+
+        /* sanitize again to ensure no toe-stepping */
+        edit_count = 0;
+	sane = t->sanitize (this);
+	if (edit_count) {
+	  DEBUG_MSG_FUNC (SANITIZE, start, "requested %d edits in second round; FAILLING", edit_count);
+	  sane = false;
+	}
+      }
+    }
+    else
+    {
+      if (edit_count && !writable) {
+        start = hb_blob_get_data_writable (blob, nullptr);
+	end = start + blob->length;
+
+	if (start)
+	{
+	  writable = true;
+	  /* ok, we made it writable by relocating.  try again */
+	  DEBUG_MSG_FUNC (SANITIZE, start, "retry");
+	  goto retry;
+	}
+      }
+    }
+
+    end_processing ();
+
+    DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED");
+    if (sane)
+    {
+      blob->lock ();
+      return blob;
+    }
+    else
+    {
+      hb_blob_destroy (blob);
+      return hb_blob_get_empty ();
+    }
+  }
+
+  template <typename Type>
+  inline hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
+  {
+    if (!num_glyphs_set)
+      set_num_glyphs (face->get_num_glyphs ());
+    return sanitize_blob<Type> (face->reference_table (tableTag));
+  }
+
+  mutable unsigned int debug_depth;
+  const char *start, *end;
+  private:
+  bool writable;
+  unsigned int edit_count;
+  mutable int max_ops;
+  hb_blob_t *blob;
+  unsigned int num_glyphs;
+  bool  num_glyphs_set;
+};
+
+
+/*
+ * Serialize
+ */
+
+struct hb_serialize_context_t
+{
+  inline hb_serialize_context_t (void *start_, unsigned int size)
+  {
+    this->start = (char *) start_;
+    this->end = this->start + size;
+
+    this->ran_out_of_room = false;
+    this->head = this->start;
+    this->debug_depth = 0;
+  }
+
+  template <typename Type>
+  inline Type *start_serialize (void)
+  {
+    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
+		     "start [%p..%p] (%lu bytes)",
+		     this->start, this->end,
+		     (unsigned long) (this->end - this->start));
+
+    return start_embed<Type> ();
+  }
+
+  inline void end_serialize (void)
+  {
+    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
+		     "end [%p..%p] serialized %d bytes; %s",
+		     this->start, this->end,
+		     (int) (this->head - this->start),
+		     this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
+  }
+
+  template <typename Type>
+  inline Type *copy (void)
+  {
+    assert (!this->ran_out_of_room);
+    unsigned int len = this->head - this->start;
+    void *p = malloc (len);
+    if (p)
+      memcpy (p, this->start, len);
+    return reinterpret_cast<Type *> (p);
+  }
+
+  template <typename Type>
+  inline Type *allocate_size (unsigned int size)
+  {
+    if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
+      this->ran_out_of_room = true;
+      return nullptr;
+    }
+    memset (this->head, 0, size);
+    char *ret = this->head;
+    this->head += size;
+    return reinterpret_cast<Type *> (ret);
+  }
+
+  template <typename Type>
+  inline Type *allocate_min (void)
+  {
+    return this->allocate_size<Type> (Type::min_size);
+  }
+
+  template <typename Type>
+  inline Type *start_embed (void)
+  {
+    Type *ret = reinterpret_cast<Type *> (this->head);
+    return ret;
+  }
+
+  template <typename Type>
+  inline Type *embed (const Type &obj)
+  {
+    unsigned int size = obj.get_size ();
+    Type *ret = this->allocate_size<Type> (size);
+    if (unlikely (!ret)) return nullptr;
+    memcpy (ret, obj, size);
+    return ret;
+  }
+
+  template <typename Type>
+  inline Type *extend_min (Type &obj)
+  {
+    unsigned int size = obj.min_size;
+    assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
+    if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
+    return reinterpret_cast<Type *> (&obj);
+  }
+
+  template <typename Type>
+  inline Type *extend (Type &obj)
+  {
+    unsigned int size = obj.get_size ();
+    assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
+    if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
+    return reinterpret_cast<Type *> (&obj);
+  }
+
+  unsigned int debug_depth;
+  char *start, *end, *head;
+  bool ran_out_of_room;
+};
+
+
+/*
+ * Supplier
+ */
+
+template <typename Type>
+struct Supplier
+{
+  inline Supplier (const Type *array, unsigned int len_, unsigned int stride_=sizeof(Type))
+  {
+    head = array;
+    len = len_;
+    stride = stride_;
+  }
+  inline const Type operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= len)) return Type ();
+    return * (const Type *) (const void *) ((const char *) head + stride * i);
+  }
+
+  inline Supplier<Type> & operator += (unsigned int count)
+  {
+    if (unlikely (count > len))
+      count = len;
+    len -= count;
+    head = (const Type *) (const void *) ((const char *) head + stride * count);
+    return *this;
+  }
+
+  private:
+  inline Supplier (const Supplier<Type> &); /* Disallow copy */
+  inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
+
+  unsigned int len;
+  unsigned int stride;
+  const Type *head;
+};
+
+
+/*
+ * Big-endian integers.
+ */
+
+template <typename Type, int Bytes> struct BEInt;
+
+template <typename Type>
+struct BEInt<Type, 1>
+{
+  public:
+  inline void set (Type V)
+  {
+    v = V;
+  }
+  inline operator Type (void) const
+  {
+    return v;
+  }
+  private: uint8_t v;
+};
+template <typename Type>
+struct BEInt<Type, 2>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[0] = (V >>  8) & 0xFF;
+    v[1] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[0] <<  8)
+         + (v[1]      );
+  }
+  private: uint8_t v[2];
+};
+template <typename Type>
+struct BEInt<Type, 3>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[0] = (V >> 16) & 0xFF;
+    v[1] = (V >>  8) & 0xFF;
+    v[2] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[0] << 16)
+         + (v[1] <<  8)
+         + (v[2]      );
+  }
+  private: uint8_t v[3];
+};
+template <typename Type>
+struct BEInt<Type, 4>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[0] = (V >> 24) & 0xFF;
+    v[1] = (V >> 16) & 0xFF;
+    v[2] = (V >>  8) & 0xFF;
+    v[3] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[0] << 24)
+         + (v[1] << 16)
+         + (v[2] <<  8)
+         + (v[3]      );
+  }
+  private: uint8_t v[4];
+};
+
+
+/*
+ * Lazy struct and blob loaders.
+ */
+
+/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
+template <typename T>
+struct hb_lazy_loader_t
+{
+  inline void init (hb_face_t *face_)
+  {
+    face = face_;
+    instance = nullptr;
+  }
+
+  inline void fini (void)
+  {
+    if (instance && instance != &Null(T))
+    {
+      instance->fini();
+      free (instance);
+    }
+  }
+
+  inline const T* get (void) const
+  {
+  retry:
+    T *p = (T *) hb_atomic_ptr_get (&instance);
+    if (unlikely (!p))
+    {
+      p = (T *) calloc (1, sizeof (T));
+      if (unlikely (!p))
+        p = const_cast<T *> (&Null(T));
+      else
+	p->init (face);
+      if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
+      {
+	if (p != &Null(T))
+	  p->fini ();
+	goto retry;
+      }
+    }
+    return p;
+  }
+
+  inline const T* operator-> (void) const
+  {
+    return get ();
+  }
+
+  private:
+  hb_face_t *face;
+  mutable T *instance;
+};
+
+/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
+template <typename T>
+struct hb_table_lazy_loader_t
+{
+  inline void init (hb_face_t *face_)
+  {
+    face = face_;
+    blob = nullptr;
+  }
+
+  inline void fini (void)
+  {
+    hb_blob_destroy (blob);
+  }
+
+  inline hb_blob_t* get_blob (void) const
+  {
+  retry:
+    hb_blob_t *b = (hb_blob_t *) hb_atomic_ptr_get (&blob);
+    if (unlikely (!b))
+    {
+      b = OT::hb_sanitize_context_t().reference_table<T> (face);
+      if (!hb_atomic_ptr_cmpexch (&blob, nullptr, b))
+      {
+	hb_blob_destroy (b);
+	goto retry;
+      }
+      blob = b;
+    }
+    return b;
+  }
+
+  inline const T* get (void) const
+  {
+    hb_blob_t *b = get_blob ();
+    return b->as<T> ();
+  }
+
+  inline const T* operator-> (void) const
+  {
+    return get();
+  }
+
+  private:
+  hb_face_t *face;
+  mutable hb_blob_t *blob;
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_MACHINERY_PRIVATE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -157,8 +157,6 @@
  *
  *
  *
- * Return value:
- *
  * Since: 1.7.7
  **/
 void
@@ -188,7 +186,7 @@
 /**
  * hb_map_del:
  * @map: a map.
- * @codepoint:
+ * @key:
  *
  *
  *
@@ -204,7 +202,7 @@
 /**
  * hb_map_has:
  * @map: a map.
- * @codepoint:
+ * @key:
  *
  *
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -47,14 +47,14 @@
 {
   hb_atomic_int_t ref_count;
 
-  inline void init (int v) { ref_count.set_unsafe (v); }
-  inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
+  inline void init (int v) { ref_count.set_relaxed (v); }
+  inline int get_relaxed (void) const { return ref_count.get_relaxed (); }
   inline int inc (void) { return ref_count.inc (); }
   inline int dec (void) { return ref_count.dec (); }
-  inline void fini (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
+  inline void fini (void) { ref_count.set_relaxed (HB_REFERENCE_COUNT_POISON_VALUE); }
 
-  inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
-  inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; }
+  inline bool is_inert (void) const { return ref_count.get_relaxed () == HB_REFERENCE_COUNT_INERT_VALUE; }
+  inline bool is_valid (void) const { return ref_count.get_relaxed () > 0; }
 };
 
 
@@ -111,7 +111,7 @@
   DEBUG_MSG (OBJECT, (void *) obj,
 	     "%s refcount=%d",
 	     function,
-	     obj ? obj->header.ref_count.get_unsafe () : 0);
+	     obj ? obj->header.ref_count.get_relaxed () : 0);
 }
 
 template <typename Type>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -484,8 +484,6 @@
 
 struct OpenTypeFontFile
 {
-  static const hb_tag_t tableTag	= HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */
-
   enum {
     CFFTag		= HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */
     TrueTypeTag	= HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -32,485 +32,13 @@
 #include "hb-private.hh"
 #include "hb-blob-private.hh"
 #include "hb-face-private.hh"
+#include "hb-machinery-private.hh"
 
 
 namespace OT {
 
 
-
 /*
- * Casts
- */
-
-/* Cast to struct T, reference to reference */
-template<typename Type, typename TObject>
-static inline const Type& CastR(const TObject &X)
-{ return reinterpret_cast<const Type&> (X); }
-template<typename Type, typename TObject>
-static inline Type& CastR(TObject &X)
-{ return reinterpret_cast<Type&> (X); }
-
-/* Cast to struct T, pointer to pointer */
-template<typename Type, typename TObject>
-static inline const Type* CastP(const TObject *X)
-{ return reinterpret_cast<const Type*> (X); }
-template<typename Type, typename TObject>
-static inline Type* CastP(TObject *X)
-{ return reinterpret_cast<Type*> (X); }
-
-/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
- * location pointed to by P plus Ofs bytes. */
-template<typename Type>
-static inline const Type& StructAtOffset(const void *P, unsigned int offset)
-{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
-template<typename Type>
-static inline Type& StructAtOffset(void *P, unsigned int offset)
-{ return * reinterpret_cast<Type*> ((char *) P + offset); }
-
-/* StructAfter<T>(X) returns the struct T& that is placed after X.
- * Works with X of variable size also.  X must implement get_size() */
-template<typename Type, typename TObject>
-static inline const Type& StructAfter(const TObject &X)
-{ return StructAtOffset<Type>(&X, X.get_size()); }
-template<typename Type, typename TObject>
-static inline Type& StructAfter(TObject &X)
-{ return StructAtOffset<Type>(&X, X.get_size()); }
-
-
-
-/*
- * Size checking
- */
-
-/* Check _assertion in a method environment */
-#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
-  inline void _instance_assertion_on_line_##_line (void) const \
-  { \
-    static_assert ((_assertion), ""); \
-    ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
-  }
-# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
-# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
-
-/* Check that _code compiles in a method environment */
-#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
-  inline void _compiles_assertion_on_line_##_line (void) const \
-  { _code; }
-# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
-# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
-
-
-#define DEFINE_SIZE_STATIC(size) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
-  static const unsigned int static_size = (size); \
-  static const unsigned int min_size = (size); \
-  inline unsigned int get_size (void) const { return (size); }
-
-#define DEFINE_SIZE_UNION(size, _member) \
-  DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \
-  static const unsigned int min_size = (size)
-
-#define DEFINE_SIZE_MIN(size) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
-  static const unsigned int min_size = (size)
-
-#define DEFINE_SIZE_ARRAY(size, array) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
-  DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
-  static const unsigned int min_size = (size)
-
-#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) \
-  static const unsigned int min_size = (size)
-
-
-
-/*
- * Dispatch
- */
-
-template <typename Context, typename Return, unsigned int MaxDebugDepth>
-struct hb_dispatch_context_t
-{
-  static const unsigned int max_debug_depth = MaxDebugDepth;
-  typedef Return return_t;
-  template <typename T, typename F>
-  inline bool may_dispatch (const T *obj, const F *format) { return true; }
-  static return_t no_dispatch_return_value (void) { return Context::default_return_value (); }
-};
-
-
-/*
- * Sanitize
- */
-
-/* This limits sanitizing time on really broken fonts. */
-#ifndef HB_SANITIZE_MAX_EDITS
-#define HB_SANITIZE_MAX_EDITS 32
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_FACTOR
-#define HB_SANITIZE_MAX_OPS_FACTOR 8
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_MIN
-#define HB_SANITIZE_MAX_OPS_MIN 16384
-#endif
-
-struct hb_sanitize_context_t :
-       hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
-{
-  inline hb_sanitize_context_t (void) :
-	debug_depth (0),
-	start (nullptr), end (nullptr),
-	writable (false), edit_count (0), max_ops (0),
-	blob (nullptr),
-	num_glyphs (0) {}
-
-  inline const char *get_name (void) { return "SANITIZE"; }
-  template <typename T, typename F>
-  inline bool may_dispatch (const T *obj, const F *format)
-  { return format->sanitize (this); }
-  template <typename T>
-  inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
-  static return_t default_return_value (void) { return true; }
-  static return_t no_dispatch_return_value (void) { return false; }
-  bool stop_sublookup_iteration (const return_t r) const { return !r; }
-
-  inline void init (hb_blob_t *b)
-  {
-    this->blob = hb_blob_reference (b);
-    this->writable = false;
-  }
-
-  inline void start_processing (void)
-  {
-    this->start = hb_blob_get_data (this->blob, nullptr);
-    this->end = this->start + this->blob->length;
-    assert (this->start <= this->end); /* Must not overflow. */
-    this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
-			 (unsigned) HB_SANITIZE_MAX_OPS_MIN);
-    this->edit_count = 0;
-    this->debug_depth = 0;
-
-    DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
-		     "start [%p..%p] (%lu bytes)",
-		     this->start, this->end,
-		     (unsigned long) (this->end - this->start));
-  }
-
-  inline void end_processing (void)
-  {
-    DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
-		     "end [%p..%p] %u edit requests",
-		     this->start, this->end, this->edit_count);
-
-    hb_blob_destroy (this->blob);
-    this->blob = nullptr;
-    this->start = this->end = nullptr;
-  }
-
-  inline bool check_range (const void *base, unsigned int len) const
-  {
-    const char *p = (const char *) base;
-    bool ok = this->max_ops-- > 0 &&
-	      this->start <= p &&
-	      p <= this->end &&
-	      (unsigned int) (this->end - p) >= len;
-
-    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
-       "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s",
-       p, p + len, len,
-       this->start, this->end,
-       ok ? "OK" : "OUT-OF-RANGE");
-
-    return likely (ok);
-  }
-
-  inline bool check_array (const void *base, unsigned int record_size, unsigned int len) 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);
-
-    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");
-
-    return likely (ok);
-  }
-
-  template <typename Type>
-  inline bool check_struct (const Type *obj) const
-  {
-    return likely (this->check_range (obj, obj->min_size));
-  }
-
-  inline bool may_edit (const void *base, unsigned int len)
-  {
-    if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
-      return false;
-
-    const char *p = (const char *) base;
-    this->edit_count++;
-
-    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
-       "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
-       this->edit_count,
-       p, p + len, len,
-       this->start, this->end,
-       this->writable ? "GRANTED" : "DENIED");
-
-    return this->writable;
-  }
-
-  template <typename Type, typename ValueType>
-  inline bool try_set (const Type *obj, const ValueType &v) {
-    if (this->may_edit (obj, obj->static_size)) {
-      const_cast<Type *> (obj)->set (v);
-      return true;
-    }
-    return false;
-  }
-
-  mutable unsigned int debug_depth;
-  const char *start, *end;
-  bool writable;
-  unsigned int edit_count;
-  mutable int max_ops;
-  hb_blob_t *blob;
-  unsigned int num_glyphs;
-};
-
-
-
-/* Template to sanitize an object. */
-template <typename Type>
-struct Sanitizer
-{
-  inline Sanitizer (void) {}
-
-  inline hb_blob_t *sanitize (hb_blob_t *blob) {
-    bool sane;
-
-    /* TODO is_sane() stuff */
-
-    c->init (blob);
-
-  retry:
-    DEBUG_MSG_FUNC (SANITIZE, c->start, "start");
-
-    c->start_processing ();
-
-    if (unlikely (!c->start)) {
-      c->end_processing ();
-      return blob;
-    }
-
-    Type *t = CastP<Type> (const_cast<char *> (c->start));
-
-    sane = t->sanitize (c);
-    if (sane) {
-      if (c->edit_count) {
-	DEBUG_MSG_FUNC (SANITIZE, c->start, "passed first round with %d edits; going for second round", c->edit_count);
-
-        /* sanitize again to ensure no toe-stepping */
-        c->edit_count = 0;
-	sane = t->sanitize (c);
-	if (c->edit_count) {
-	  DEBUG_MSG_FUNC (SANITIZE, c->start, "requested %d edits in second round; FAILLING", c->edit_count);
-	  sane = false;
-	}
-      }
-    } else {
-      unsigned int edit_count = c->edit_count;
-      if (edit_count && !c->writable) {
-        c->start = hb_blob_get_data_writable (blob, nullptr);
-	c->end = c->start + blob->length;
-
-	if (c->start) {
-	  c->writable = true;
-	  /* ok, we made it writable by relocating.  try again */
-	  DEBUG_MSG_FUNC (SANITIZE, c->start, "retry");
-	  goto retry;
-	}
-      }
-    }
-
-    c->end_processing ();
-
-    DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED");
-    if (sane)
-    {
-      blob->lock ();
-      return blob;
-    }
-    else
-    {
-      hb_blob_destroy (blob);
-      return hb_blob_get_empty ();
-    }
-  }
-
-  inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; }
-
-  private:
-  hb_sanitize_context_t c[1];
-};
-
-
-
-/*
- * Serialize
- */
-
-
-struct hb_serialize_context_t
-{
-  inline hb_serialize_context_t (void *start_, unsigned int size)
-  {
-    this->start = (char *) start_;
-    this->end = this->start + size;
-
-    this->ran_out_of_room = false;
-    this->head = this->start;
-    this->debug_depth = 0;
-  }
-
-  template <typename Type>
-  inline Type *start_serialize (void)
-  {
-    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
-		     "start [%p..%p] (%lu bytes)",
-		     this->start, this->end,
-		     (unsigned long) (this->end - this->start));
-
-    return start_embed<Type> ();
-  }
-
-  inline void end_serialize (void)
-  {
-    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
-		     "end [%p..%p] serialized %d bytes; %s",
-		     this->start, this->end,
-		     (int) (this->head - this->start),
-		     this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
-
-  }
-
-  template <typename Type>
-  inline Type *copy (void)
-  {
-    assert (!this->ran_out_of_room);
-    unsigned int len = this->head - this->start;
-    void *p = malloc (len);
-    if (p)
-      memcpy (p, this->start, len);
-    return reinterpret_cast<Type *> (p);
-  }
-
-  template <typename Type>
-  inline Type *allocate_size (unsigned int size)
-  {
-    if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
-      this->ran_out_of_room = true;
-      return nullptr;
-    }
-    memset (this->head, 0, size);
-    char *ret = this->head;
-    this->head += size;
-    return reinterpret_cast<Type *> (ret);
-  }
-
-  template <typename Type>
-  inline Type *allocate_min (void)
-  {
-    return this->allocate_size<Type> (Type::min_size);
-  }
-
-  template <typename Type>
-  inline Type *start_embed (void)
-  {
-    Type *ret = reinterpret_cast<Type *> (this->head);
-    return ret;
-  }
-
-  template <typename Type>
-  inline Type *embed (const Type &obj)
-  {
-    unsigned int size = obj.get_size ();
-    Type *ret = this->allocate_size<Type> (size);
-    if (unlikely (!ret)) return nullptr;
-    memcpy (ret, obj, size);
-    return ret;
-  }
-
-  template <typename Type>
-  inline Type *extend_min (Type &obj)
-  {
-    unsigned int size = obj.min_size;
-    assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
-    if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
-    return reinterpret_cast<Type *> (&obj);
-  }
-
-  template <typename Type>
-  inline Type *extend (Type &obj)
-  {
-    unsigned int size = obj.get_size ();
-    assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
-    if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
-    return reinterpret_cast<Type *> (&obj);
-  }
-
-  inline void truncate (void *new_head)
-  {
-    assert (this->start < new_head && new_head <= this->head);
-    this->head = (char *) new_head;
-  }
-
-  unsigned int debug_depth;
-  char *start, *end, *head;
-  bool ran_out_of_room;
-};
-
-template <typename Type>
-struct Supplier
-{
-  inline Supplier (const Type *array, unsigned int len_, unsigned int stride_=sizeof(Type))
-  {
-    head = array;
-    len = len_;
-    stride = stride_;
-  }
-  inline const Type operator [] (unsigned int i) const
-  {
-    if (unlikely (i >= len)) return Type ();
-    return * (const Type *) (const void *) ((const char *) head + stride * i);
-  }
-
-  inline Supplier<Type> & operator += (unsigned int count)
-  {
-    if (unlikely (count > len))
-      count = len;
-    len -= count;
-    head = (const Type *) (const void *) ((const char *) head + stride * count);
-    return *this;
-  }
-
-  private:
-  inline Supplier (const Supplier<Type> &); /* Disallow copy */
-  inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
-
-  unsigned int len;
-  unsigned int stride;
-  const Type *head;
-};
-
-
-/*
  *
  * The OpenType Font File: Data Types
  */
@@ -523,78 +51,6 @@
  * Int types
  */
 
-
-template <typename Type, int Bytes> struct BEInt;
-
-template <typename Type>
-struct BEInt<Type, 1>
-{
-  public:
-  inline void set (Type V)
-  {
-    v = V;
-  }
-  inline operator Type (void) const
-  {
-    return v;
-  }
-  private: uint8_t v;
-};
-template <typename Type>
-struct BEInt<Type, 2>
-{
-  public:
-  inline void set (Type V)
-  {
-    v[0] = (V >>  8) & 0xFF;
-    v[1] = (V      ) & 0xFF;
-  }
-  inline operator Type (void) const
-  {
-    return (v[0] <<  8)
-         + (v[1]      );
-  }
-  private: uint8_t v[2];
-};
-template <typename Type>
-struct BEInt<Type, 3>
-{
-  public:
-  inline void set (Type V)
-  {
-    v[0] = (V >> 16) & 0xFF;
-    v[1] = (V >>  8) & 0xFF;
-    v[2] = (V      ) & 0xFF;
-  }
-  inline operator Type (void) const
-  {
-    return (v[0] << 16)
-         + (v[1] <<  8)
-         + (v[2]      );
-  }
-  private: uint8_t v[3];
-};
-template <typename Type>
-struct BEInt<Type, 4>
-{
-  public:
-  inline void set (Type V)
-  {
-    v[0] = (V >> 24) & 0xFF;
-    v[1] = (V >> 16) & 0xFF;
-    v[2] = (V >>  8) & 0xFF;
-    v[3] = (V      ) & 0xFF;
-  }
-  inline operator Type (void) const
-  {
-    return (v[0] << 24)
-         + (v[1] << 16)
-         + (v[2] <<  8)
-         + (v[3]      );
-  }
-  private: uint8_t v[4];
-};
-
 /* Integer types in big-endian order and no alignment requirement */
 template <typename Type, unsigned int Size>
 struct IntType
@@ -765,7 +221,6 @@
 };
 
 
-
 /*
  * Template subclasses of Offset that do the dereferencing.
  * Use: (base+offset)
@@ -831,7 +286,6 @@
  * Array Types
  */
 
-
 /* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */
 template <typename Type>
 struct UnsizedArrayOf
@@ -913,7 +367,6 @@
   }
 };
 
-
 /* An array with a number of elements. */
 template <typename Type, typename LenType=HBUINT16>
 struct ArrayOf
@@ -1066,7 +519,6 @@
   }
 };
 
-
 /* An array starting at second element. */
 template <typename Type, typename LenType=HBUINT16>
 struct HeadlessArrayOf
@@ -1131,10 +583,7 @@
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
 
-
-/*
- * An array with sorted elements.  Supports binary searching.
- */
+/* An array with sorted elements.  Supports binary searching. */
 template <typename Type, typename LenType=HBUINT16>
 struct SortedArrayOf : ArrayOf<Type, LenType>
 {
@@ -1159,10 +608,7 @@
   }
 };
 
-/*
- * Binary-search arrays
- */
-
+/* Binary-search arrays */
 struct BinSearchHeader
 {
   inline operator uint32_t (void) const { return len; }
@@ -1198,101 +644,6 @@
 struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
 
 
-/* Lazy struct and blob loaders. */
-
-/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
-template <typename T>
-struct hb_lazy_loader_t
-{
-  inline void init (hb_face_t *face_)
-  {
-    face = face_;
-    instance = nullptr;
-  }
-
-  inline void fini (void)
-  {
-    if (instance && instance != &Null(T))
-    {
-      instance->fini();
-      free (instance);
-    }
-  }
-
-  inline const T* get (void) const
-  {
-  retry:
-    T *p = (T *) hb_atomic_ptr_get (&instance);
-    if (unlikely (!p))
-    {
-      p = (T *) calloc (1, sizeof (T));
-      if (unlikely (!p))
-        p = const_cast<T *> (&Null(T));
-      else
-	p->init (face);
-      if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
-      {
-	if (p != &Null(T))
-	  p->fini ();
-	goto retry;
-      }
-    }
-    return p;
-  }
-
-  inline const T* operator-> (void) const
-  {
-    return get ();
-  }
-
-  private:
-  hb_face_t *face;
-  mutable T *instance;
-};
-
-/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
-template <typename T>
-struct hb_table_lazy_loader_t
-{
-  inline void init (hb_face_t *face_)
-  {
-    face = face_;
-    blob = nullptr;
-  }
-
-  inline void fini (void)
-  {
-    hb_blob_destroy (blob);
-  }
-
-  inline const T* get (void) const
-  {
-  retry:
-    hb_blob_t *blob_ = (hb_blob_t *) hb_atomic_ptr_get (&blob);
-    if (unlikely (!blob_))
-    {
-      blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
-      if (!hb_atomic_ptr_cmpexch (&blob, nullptr, blob_))
-      {
-	hb_blob_destroy (blob_);
-	goto retry;
-      }
-      blob = blob_;
-    }
-    return blob_->as<T> ();
-  }
-
-  inline const T* operator-> (void) const
-  {
-    return get();
-  }
-
-  private:
-  hb_face_t *face;
-  mutable hb_blob_t *blob;
-};
-
-
 } /* namespace OT */
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -37,6 +37,9 @@
  */
 #define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
 
+#ifndef HB_MAX_UNICODE_CODEPOINT_VALUE
+#define HB_MAX_UNICODE_CODEPOINT_VALUE 0x10FFFF
+#endif
 
 namespace OT {
 
@@ -437,8 +440,10 @@
   {
     for (unsigned int i = 0; i < this->groups.len; i++) {
       hb_set_add_range (out,
-			this->groups[i].startCharCode,
-			this->groups[i].endCharCode);
+			MIN ((unsigned int) this->groups[i].startCharCode,
+			     (unsigned int) HB_MAX_UNICODE_CODEPOINT_VALUE),
+			MIN ((unsigned int) this->groups[i].endCharCode,
+			     (unsigned int) HB_MAX_UNICODE_CODEPOINT_VALUE));
     }
   }
 
@@ -800,37 +805,37 @@
   {
     hb_serialize_context_t c (dest, dest_sz);
 
-    OT::cmap *cmap = c.start_serialize<OT::cmap> ();
-    if (unlikely (!c.extend_min (*cmap)))
+    cmap *table = c.start_serialize<cmap> ();
+    if (unlikely (!c.extend_min (*table)))
     {
       return false;
     }
 
-    cmap->version.set (0);
+    table->version.set (0);
 
-    if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 3)))
+    if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ 3)))
       return false;
 
     // TODO(grieger): Convert the below to a for loop
 
     // Format 4, Plat 0 Encoding Record
-    EncodingRecord &format4_plat0_rec = cmap->encodingRecord[0];
+    EncodingRecord &format4_plat0_rec = table->encodingRecord[0];
     format4_plat0_rec.platformID.set (0); // Unicode
     format4_plat0_rec.encodingID.set (3);
 
     // Format 4, Plat 3 Encoding Record
-    EncodingRecord &format4_plat3_rec = cmap->encodingRecord[1];
+    EncodingRecord &format4_plat3_rec = table->encodingRecord[1];
     format4_plat3_rec.platformID.set (3); // Windows
     format4_plat3_rec.encodingID.set (1); // Unicode BMP
 
     // Format 12 Encoding Record
-    EncodingRecord &format12_rec = cmap->encodingRecord[2];
+    EncodingRecord &format12_rec = table->encodingRecord[2];
     format12_rec.platformID.set (3); // Windows
     format12_rec.encodingID.set (10); // Unicode UCS-4
 
     // Write out format 4 sub table
     {
-      CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, cmap);
+      CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table);
       format4_plat3_rec.subtable.set (format4_plat0_rec.subtable);
       subtable.u.format.set (4);
 
@@ -841,7 +846,7 @@
 
     // Write out format 12 sub table.
     {
-      CmapSubtable &subtable = format12_rec.subtable.serialize (&c, cmap);
+      CmapSubtable &subtable = format12_rec.subtable.serialize (&c, table);
       subtable.u.format.set (12);
 
       CmapSubtableFormat12 &format12 = subtable.u.format12;
@@ -894,39 +899,39 @@
   {
     inline void init (hb_face_t *face)
     {
-      this->blob = OT::Sanitizer<OT::cmap>().sanitize (face->reference_table (HB_OT_TAG_cmap));
-      const OT::cmap *cmap = this->blob->as<OT::cmap> ();
-      const OT::CmapSubtable *subtable = nullptr;
-      const OT::CmapSubtableFormat14 *subtable_uvs = nullptr;
+      this->blob = hb_sanitize_context_t().reference_table<cmap> (face);
+      const cmap *table = this->blob->as<cmap> ();
+      const CmapSubtable *subtable = nullptr;
+      const CmapSubtableFormat14 *subtable_uvs = nullptr;
 
       bool symbol = false;
       /* 32-bit subtables. */
-      if (!subtable) subtable = cmap->find_subtable (3, 10);
-      if (!subtable) subtable = cmap->find_subtable (0, 6);
-      if (!subtable) subtable = cmap->find_subtable (0, 4);
+      if (!subtable) subtable = table->find_subtable (3, 10);
+      if (!subtable) subtable = table->find_subtable (0, 6);
+      if (!subtable) subtable = table->find_subtable (0, 4);
       /* 16-bit subtables. */
-      if (!subtable) subtable = cmap->find_subtable (3, 1);
-      if (!subtable) subtable = cmap->find_subtable (0, 3);
-      if (!subtable) subtable = cmap->find_subtable (0, 2);
-      if (!subtable) subtable = cmap->find_subtable (0, 1);
-      if (!subtable) subtable = cmap->find_subtable (0, 0);
+      if (!subtable) subtable = table->find_subtable (3, 1);
+      if (!subtable) subtable = table->find_subtable (0, 3);
+      if (!subtable) subtable = table->find_subtable (0, 2);
+      if (!subtable) subtable = table->find_subtable (0, 1);
+      if (!subtable) subtable = table->find_subtable (0, 0);
       if (!subtable)
       {
-	subtable = cmap->find_subtable (3, 0);
+	subtable = table->find_subtable (3, 0);
 	if (subtable) symbol = true;
       }
       /* Meh. */
-      if (!subtable) subtable = &Null(OT::CmapSubtable);
+      if (!subtable) subtable = &Null(CmapSubtable);
 
       /* UVS subtable. */
       if (!subtable_uvs)
       {
-	const OT::CmapSubtable *st = cmap->find_subtable (0, 5);
+	const CmapSubtable *st = table->find_subtable (0, 5);
 	if (st && st->u.format == 14)
 	  subtable_uvs = &st->u.format14;
       }
       /* Meh. */
-      if (!subtable_uvs) subtable_uvs = &Null(OT::CmapSubtableFormat14);
+      if (!subtable_uvs) subtable_uvs = &Null(CmapSubtableFormat14);
 
       this->uvs_table = subtable_uvs;
 
@@ -933,18 +938,18 @@
       this->get_glyph_data = subtable;
       if (unlikely (symbol))
       {
-	this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
+	this->get_glyph_func = get_glyph_from_symbol<CmapSubtable>;
 	this->get_all_codepoints_func = null_get_all_codepoints_func;
       } else {
 	switch (subtable->u.format) {
 	/* Accelerate format 4 and format 12. */
 	default:
-	  this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;
+	  this->get_glyph_func = get_glyph_from<CmapSubtable>;
 	  this->get_all_codepoints_func = null_get_all_codepoints_func;
 	  break;
 	case 12:
-	  this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>;
-	  this->get_all_codepoints_func = get_all_codepoints_from<OT::CmapSubtableFormat12>;
+	  this->get_glyph_func = get_glyph_from<CmapSubtableFormat12>;
+	  this->get_all_codepoints_func = get_all_codepoints_from<CmapSubtableFormat12>;
 	  break;
 	case  4:
 	  {
@@ -977,9 +982,9 @@
 						  variation_selector,
 						  glyph))
       {
-	case OT::GLYPH_VARIANT_NOT_FOUND:		return false;
-	case OT::GLYPH_VARIANT_FOUND:		return true;
-	case OT::GLYPH_VARIANT_USE_DEFAULT:	break;
+	case GLYPH_VARIANT_NOT_FOUND:	return false;
+	case GLYPH_VARIANT_FOUND:	return true;
+	case GLYPH_VARIANT_USE_DEFAULT:	break;
       }
 
       return get_nominal_glyph (unicode, glyph);
@@ -1046,9 +1051,9 @@
     const void *get_glyph_data;
     hb_cmap_get_all_codepoints_func_t get_all_codepoints_func;
 
-    OT::CmapSubtableFormat4::accelerator_t format4_accel;
+    CmapSubtableFormat4::accelerator_t format4_accel;
 
-    const OT::CmapSubtableFormat14 *uvs_table;
+    const CmapSubtableFormat14 *uvs_table;
     hb_blob_t *blob;
   };
 

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -394,8 +394,8 @@
     {
       upem = hb_face_get_upem (face);
 
-      cblc_blob = Sanitizer<CBLC>().sanitize (face->reference_table (HB_OT_TAG_CBLC));
-      cbdt_blob = Sanitizer<CBDT>().sanitize (face->reference_table (HB_OT_TAG_CBDT));
+      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) {

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -68,7 +68,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-		  imageOffsetsZ.sanitize_shallow (c, c->num_glyphs + 1));
+		  imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1));
   }
 
   protected:
@@ -96,14 +96,9 @@
   {
     inline void init (hb_face_t *face)
     {
-      num_glyphs = hb_face_get_glyph_count (face);
-
-      OT::Sanitizer<OT::sbix> sanitizer;
-      sanitizer.set_num_glyphs (num_glyphs);
-      sbix_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_sbix));
+      sbix_blob = hb_sanitize_context_t().reference_table<sbix> (face);
       sbix_len = hb_blob_get_length (sbix_blob);
-      sbix_table = sbix_blob->as<OT::sbix> ();
-
+      sbix_table = sbix_blob->as<sbix> ();
     }
 
     inline void fini (void)
@@ -134,7 +129,6 @@
 
     unsigned int sbix_len;
     unsigned int num_glyphs;
-
   };
 
   protected:

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -96,11 +96,9 @@
   {
     inline void init (hb_face_t *face)
     {
-      OT::Sanitizer<OT::SVG> sanitizer;
-      svg_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_SVG));
+      svg_blob = hb_sanitize_context_t().reference_table<SVG> (face);
       svg_len = hb_blob_get_length (svg_blob);
-      svg = svg_blob->as<OT::SVG> ();
-
+      svg = svg_blob->as<SVG> ();
     }
 
     inline void fini (void)

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -103,7 +103,7 @@
   static bool
   _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
   {
-    hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_head));
+    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);
 
@@ -110,7 +110,7 @@
     if (unlikely (!head_prime_blob))
       return false;
 
-    OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
+    head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
     head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1);
     bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
 
@@ -236,7 +236,7 @@
     {
       memset (this, 0, sizeof (accelerator_t));
 
-      hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head));
+      hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (face);
       const head *head_table = head_blob->as<head> ();
       if (head_table == &Null(head) || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
       {
@@ -247,9 +247,9 @@
       short_offset = 0 == head_table->indexToLocFormat;
       hb_blob_destroy (head_blob);
 
-      loca_blob = Sanitizer<loca>().sanitize (face->reference_table (HB_OT_TAG_loca));
+      loca_blob = hb_sanitize_context_t().reference_table<loca> (face);
       loca_table = loca_blob->as<loca> ();
-      glyf_blob = Sanitizer<glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf));
+      glyf_blob = hb_sanitize_context_t().reference_table<glyf> (face);
       glyf_table = glyf_blob->as<glyf> ();
 
       num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1;

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -69,7 +69,7 @@
   inline bool subset_update_header (hb_subset_plan_t *plan,
                                     unsigned int num_hmetrics) const
   {
-    hb_blob_t *src_blob = OT::Sanitizer<H> ().sanitize (plan->source->reference_table (H::tableTag));
+    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);
 
@@ -195,7 +195,7 @@
       bool got_font_extents = false;
       if (T::os2Tag)
       {
-	hb_blob_t *os2_blob = Sanitizer<os2> ().sanitize (face->reference_table (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))
@@ -208,7 +208,7 @@
 	hb_blob_destroy (os2_blob);
       }
 
-      hb_blob_t *_hea_blob = Sanitizer<H> ().sanitize (face->reference_table (H::tableTag));
+      hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table<H> (face);
       const H *_hea_table = _hea_blob->as<H> ();
       num_advances = _hea_table->numberOfLongMetrics;
       if (!got_font_extents)
@@ -222,7 +222,7 @@
 
       has_font_extents = got_font_extents;
 
-      blob = Sanitizer<hmtxvmtx> ().sanitize (face->reference_table (T::tableTag));
+      blob = 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);
@@ -240,7 +240,7 @@
       }
       table = blob->as<hmtxvmtx> ();
 
-      var_blob = Sanitizer<HVARVVAR> ().sanitize (face->reference_table (T::variationsTag));
+      var_blob = hb_sanitize_context_t().reference_table<HVARVVAR> (face, T::variationsTag);
       var_table = var_blob->as<HVARVVAR> ();
     }
 

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -362,7 +362,7 @@
   {
     inline void init (hb_face_t *face)
     {
-      blob = Sanitizer<kern>().sanitize (face->reference_table (HB_OT_TAG_kern));
+      blob = hb_sanitize_context_t().reference_table<kern> (face);
       table = blob->as<kern> ();
       table_length = blob->length;
     }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -41,6 +41,15 @@
 #ifndef HB_MAX_CONTEXT_LENGTH
 #define HB_MAX_CONTEXT_LENGTH	64
 #endif
+#ifndef HB_CLOSURE_MAX_STAGES
+/*
+ * The maximum number of times a lookup can be applied during shaping.
+ * Used to limit the number of iterations of the closure algorithm.
+ * This must be larger than the number of times add_pause() is
+ * called in a collect_features call of any shaper.
+ */
+#define HB_CLOSURE_MAX_STAGES	32
+#endif
 
 
 namespace OT {
@@ -181,6 +190,11 @@
     }
     return this->len;
   }
+
+  inline void add_indexes_to (hb_set_t* output /* OUT */) const
+  {
+    output->add_array (arrayZ, len);
+  }
 };
 
 
@@ -199,6 +213,8 @@
 					   unsigned int *feature_count /* IN/OUT */,
 					   unsigned int *feature_indexes /* OUT */) const
   { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
+  inline void add_feature_indexes_to (hb_set_t *feature_indexes) const
+  { featureIndex.add_indexes_to (feature_indexes); }
 
   inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; }
   inline unsigned int get_required_feature_index (void) const
@@ -540,9 +556,6 @@
 	  c->try_set (&featureParams, new_offset) &&
 	  !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
 	return_trace (false);
-
-      if (c->edit_count > 1)
-        c->edit_count--; /* This was a "legitimate" edit; don't contribute to error count. */
     }
 
     return_trace (true);
@@ -597,6 +610,14 @@
   inline OffsetArrayOf<SubTableType>& get_subtables (void)
   { return CastR<OffsetArrayOf<SubTableType> > (subTable); }
 
+  inline unsigned int get_size (void) const
+  {
+    const HBUINT16 &markFilteringSet = StructAfter<const HBUINT16> (subTable);
+    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
+      return (const char *) &StructAfter<const char> (markFilteringSet) - (const char *) this;
+    return (const char *) &markFilteringSet - (const char *) this;
+  }
+
   inline unsigned int get_type (void) const { return lookupType; }
 
   /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
@@ -639,6 +660,7 @@
     if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
     {
+      if (unlikely (!c->extend (*this))) return_trace (false);
       HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
       markFilteringSet.set (lookup_props >> 16);
     }

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -47,7 +47,7 @@
        * https://github.com/harfbuzz/harfbuzz/issues/363 */
       hb_codepoint_t glyph_id = iter.get_glyph ();
       if (c->glyphs->has (glyph_id))
-	c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
+	c->out->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
     }
   }
 
@@ -132,7 +132,7 @@
       if (unlikely (iter.get_coverage () >= count))
         break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
-	c->glyphs->add (substitute[iter.get_coverage ()]);
+	c->out->add (substitute[iter.get_coverage ()]);
     }
   }
 
@@ -263,7 +263,7 @@
     TRACE_CLOSURE (this);
     unsigned int count = substitute.len;
     for (unsigned int i = 0; i < count; i++)
-      c->glyphs->add (substitute[i]);
+      c->out->add (substitute[i]);
   }
 
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -464,7 +464,7 @@
 	const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
 	unsigned int count = alt_set.len;
 	for (unsigned int i = 0; i < count; i++)
-	  c->glyphs->add (alt_set[i]);
+	  c->out->add (alt_set[i]);
       }
     }
   }
@@ -605,7 +605,7 @@
     for (unsigned int i = 1; i < count; i++)
       if (!c->glyphs->has (component[i]))
         return;
-    c->glyphs->add (ligGlyph);
+    c->out->add (ligGlyph);
   }
 
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -957,7 +957,7 @@
       if (unlikely (iter.get_coverage () >= count))
         break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
-	c->glyphs->add (substitute[iter.get_coverage ()]);
+	c->out->add (substitute[iter.get_coverage ()]);
     }
   }
 
@@ -1163,7 +1163,12 @@
       return_trace (HB_VOID);
 
     c->set_recurse_func (dispatch_closure_recurse_func);
-    return_trace (dispatch (c));
+
+    hb_closure_context_t::return_t ret = dispatch (c);
+
+    c->flush ();
+
+    return_trace (ret);
   }
 
   inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -1265,7 +1270,12 @@
   {
     if (!c->should_visit_lookup (lookup_index))
       return HB_VOID;
-    return dispatch_recurse_func (c, lookup_index);
+
+    hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index);
+
+    c->flush ();
+
+    return ret;
   }
 
   template <typename context_t>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -69,12 +69,13 @@
 
   bool is_lookup_done (unsigned int lookup_index)
   {
-    // Have we visited this lookup with the current set of glyphs?
+    /* Have we visited this lookup with the current set of glyphs? */
     return done_lookups->get (lookup_index) == glyphs->get_population ();
   }
 
   hb_face_t *face;
   hb_set_t *glyphs;
+  hb_auto_t<hb_set_t> out[1];
   recurse_func_t recurse_func;
   unsigned int nesting_level_left;
   unsigned int debug_depth;
@@ -90,8 +91,19 @@
 			  debug_depth (0),
                           done_lookups (done_lookups_) {}
 
+  ~hb_closure_context_t (void)
+  {
+    flush ();
+  }
+
   void set_recurse_func (recurse_func_t func) { recurse_func = func; }
 
+  void flush (void)
+  {
+    hb_set_union (glyphs, out);
+    hb_set_clear (out);
+  }
+
   private:
   hb_map_t *done_lookups;
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -176,6 +176,7 @@
   OT::hb_table_lazy_loader_t<struct OT::MATH> math;
   OT::hb_table_lazy_loader_t<struct OT::fvar> fvar;
   OT::hb_table_lazy_loader_t<struct OT::avar> avar;
+  OT::hb_table_lazy_loader_t<struct AAT::morx> morx;
 
   unsigned int gsub_lookup_count;
   unsigned int gpos_lookup_count;

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -54,18 +54,19 @@
   if (unlikely (!layout))
     return nullptr;
 
-  layout->gdef_blob = OT::Sanitizer<OT::GDEF>().sanitize (face->reference_table (HB_OT_TAG_GDEF));
+  layout->gdef_blob = OT::hb_sanitize_context_t().reference_table<OT::GDEF> (face);
   layout->gdef = layout->gdef_blob->as<OT::GDEF> ();
 
-  layout->gsub_blob = OT::Sanitizer<OT::GSUB>().sanitize (face->reference_table (HB_OT_TAG_GSUB));
+  layout->gsub_blob = OT::hb_sanitize_context_t().reference_table<OT::GSUB> (face);
   layout->gsub = layout->gsub_blob->as<OT::GSUB> ();
 
-  layout->gpos_blob = OT::Sanitizer<OT::GPOS>().sanitize (face->reference_table (HB_OT_TAG_GPOS));
+  layout->gpos_blob = OT::hb_sanitize_context_t().reference_table<OT::GPOS> (face);
   layout->gpos = layout->gpos_blob->as<OT::GPOS> ();
 
   layout->math.init (face);
   layout->fvar.init (face);
   layout->avar.init (face);
+  layout->morx.init (face);
 
   {
     /*
@@ -215,6 +216,7 @@
   layout->math.fini ();
   layout->fvar.fini ();
   layout->avar.fini ();
+  layout->morx.fini ();
 
   free (layout);
 }
@@ -518,6 +520,19 @@
   return l.has_required_feature ();
 }
 
+static void
+_hb_ot_layout_language_add_feature_indexes_to (hb_face_t    *face,
+                                               hb_tag_t      table_tag,
+                                               unsigned int  script_index,
+                                               unsigned int  language_index,
+                                               hb_set_t     *feature_indexes /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+  l.add_feature_indexes_to (feature_indexes);
+}
+
+
 unsigned int
 hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
 					   hb_tag_t      table_tag,
@@ -656,12 +671,12 @@
 }
 
 static void
-_hb_ot_layout_collect_lookups_features (hb_face_t      *face,
-					hb_tag_t        table_tag,
-					unsigned int    script_index,
-					unsigned int    language_index,
-					const hb_tag_t *features,
-					hb_set_t       *lookup_indexes /* OUT */)
+_hb_ot_layout_collect_features_features (hb_face_t      *face,
+                                         hb_tag_t        table_tag,
+                                         unsigned int    script_index,
+                                         unsigned int    language_index,
+                                         const hb_tag_t *features,
+                                         hb_set_t       *feature_indexes /* OUT */)
 {
   if (!features)
   {
@@ -672,33 +687,14 @@
 						    language_index,
 						    &required_feature_index,
 						    nullptr))
-      _hb_ot_layout_collect_lookups_lookups (face,
-					     table_tag,
-					     required_feature_index,
-					     lookup_indexes);
+      feature_indexes->add (required_feature_index);
 
     /* All features */
-    unsigned int feature_indices[32];
-    unsigned int offset, len;
-
-    offset = 0;
-    do {
-      len = ARRAY_LENGTH (feature_indices);
-      hb_ot_layout_language_get_feature_indexes (face,
-						 table_tag,
-						 script_index,
-						 language_index,
-						 offset, &len,
-						 feature_indices);
-
-      for (unsigned int i = 0; i < len; i++)
-	_hb_ot_layout_collect_lookups_lookups (face,
-					       table_tag,
-					       feature_indices[i],
-					       lookup_indexes);
-
-      offset += len;
-    } while (len == ARRAY_LENGTH (feature_indices));
+    _hb_ot_layout_language_add_feature_indexes_to (face,
+                                                   table_tag,
+                                                   script_index,
+                                                   language_index,
+                                                   feature_indexes);
   }
   else
   {
@@ -711,28 +707,25 @@
 					      language_index,
 					      *features,
 					      &feature_index))
-        _hb_ot_layout_collect_lookups_lookups (face,
-					       table_tag,
-					       feature_index,
-					       lookup_indexes);
+        feature_indexes->add (feature_index);
     }
   }
 }
 
 static void
-_hb_ot_layout_collect_lookups_languages (hb_face_t      *face,
-					 hb_tag_t        table_tag,
-					 unsigned int    script_index,
-					 const hb_tag_t *languages,
-					 const hb_tag_t *features,
-					 hb_set_t       *lookup_indexes /* OUT */)
+_hb_ot_layout_collect_features_languages (hb_face_t      *face,
+                                          hb_tag_t        table_tag,
+                                          unsigned int    script_index,
+                                          const hb_tag_t *languages,
+                                          const hb_tag_t *features,
+                                          hb_set_t       *feature_indexes /* OUT */)
 {
-  _hb_ot_layout_collect_lookups_features (face,
-					  table_tag,
-					  script_index,
-					  HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
-					  features,
-					  lookup_indexes);
+  _hb_ot_layout_collect_features_features (face,
+                                           table_tag,
+                                           script_index,
+                                           HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
+                                           features,
+                                           feature_indexes);
 
   if (!languages)
   {
@@ -742,12 +735,12 @@
 								script_index,
 								0, nullptr, nullptr);
     for (unsigned int language_index = 0; language_index < count; language_index++)
-      _hb_ot_layout_collect_lookups_features (face,
-					      table_tag,
-					      script_index,
-					      language_index,
-					      features,
-					      lookup_indexes);
+      _hb_ot_layout_collect_features_features (face,
+                                               table_tag,
+                                               script_index,
+                                               language_index,
+                                               features,
+                                               feature_indexes);
   }
   else
   {
@@ -759,28 +752,28 @@
 					     script_index,
 					     *languages,
 					     &language_index))
-        _hb_ot_layout_collect_lookups_features (face,
-						table_tag,
-						script_index,
-						language_index,
-						features,
-						lookup_indexes);
+        _hb_ot_layout_collect_features_features (face,
+                                                 table_tag,
+                                                 script_index,
+                                                 language_index,
+                                                 features,
+                                                 feature_indexes);
     }
   }
 }
 
 /**
- * hb_ot_layout_collect_lookups:
+ * hb_ot_layout_collect_features:
  *
- * Since: 0.9.8
+ * Since: 1.8.5
  **/
 void
-hb_ot_layout_collect_lookups (hb_face_t      *face,
-			      hb_tag_t        table_tag,
-			      const hb_tag_t *scripts,
-			      const hb_tag_t *languages,
-			      const hb_tag_t *features,
-			      hb_set_t       *lookup_indexes /* OUT */)
+hb_ot_layout_collect_features (hb_face_t      *face,
+                               hb_tag_t        table_tag,
+                               const hb_tag_t *scripts,
+                               const hb_tag_t *languages,
+                               const hb_tag_t *features,
+                               hb_set_t       *feature_indexes /* OUT */)
 {
   if (!scripts)
   {
@@ -789,12 +782,12 @@
 							     table_tag,
 							     0, nullptr, nullptr);
     for (unsigned int script_index = 0; script_index < count; script_index++)
-      _hb_ot_layout_collect_lookups_languages (face,
-					       table_tag,
-					       script_index,
-					       languages,
-					       features,
-					       lookup_indexes);
+      _hb_ot_layout_collect_features_languages (face,
+                                                table_tag,
+                                                script_index,
+                                                languages,
+                                                features,
+                                                feature_indexes);
   }
   else
   {
@@ -805,17 +798,36 @@
 					  table_tag,
 					  *scripts,
 					  &script_index))
-        _hb_ot_layout_collect_lookups_languages (face,
-						 table_tag,
-						 script_index,
-						 languages,
-						 features,
-						 lookup_indexes);
+        _hb_ot_layout_collect_features_languages (face,
+                                                  table_tag,
+                                                  script_index,
+                                                  languages,
+                                                  features,
+                                                  feature_indexes);
     }
   }
 }
 
 /**
+ * hb_ot_layout_collect_lookups:
+ *
+ * Since: 0.9.8
+ **/
+void
+hb_ot_layout_collect_lookups (hb_face_t      *face,
+			      hb_tag_t        table_tag,
+			      const hb_tag_t *scripts,
+			      const hb_tag_t *languages,
+			      const hb_tag_t *features,
+			      hb_set_t       *lookup_indexes /* OUT */)
+{
+  hb_auto_t<hb_set_t> feature_indexes;
+  hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes);
+  for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID; hb_set_next (&feature_indexes, &feature_index);)
+    _hb_ot_layout_collect_lookups_lookups (face, table_tag, feature_index, lookup_indexes);
+}
+
+/**
  * hb_ot_layout_lookup_collect_glyphs:
  *
  * Since: 0.9.7
@@ -969,6 +981,7 @@
   OT::hb_closure_context_t c (face, glyphs, &done_lookups);
   const OT::GSUB& gsub = _get_gsub (face);
 
+  unsigned int iteration_count = 0;
   unsigned int glyphs_length;
   do
   {
@@ -983,7 +996,9 @@
       for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
         gsub.get_lookup (i).closure (&c, i);
     }
-  } while (glyphs_length != glyphs->get_population ());
+    iteration_count++;
+  } while (iteration_count <= HB_CLOSURE_MAX_STAGES
+           && glyphs_length != glyphs->get_population ());
 }
 
 /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2018-08-02 22:27:18 UTC (rev 48337)
@@ -194,6 +194,13 @@
 hb_ot_layout_table_get_lookup_count (hb_face_t    *face,
 				     hb_tag_t      table_tag);
 
+HB_EXTERN void
+hb_ot_layout_collect_features (hb_face_t      *face,
+                               hb_tag_t        table_tag,
+                               const hb_tag_t *scripts,
+                               const hb_tag_t *languages,
+                               const hb_tag_t *features,
+                               hb_set_t       *feature_indexes /* OUT */);
 
 HB_EXTERN void
 hb_ot_layout_collect_lookups (hb_face_t      *face,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -100,7 +100,7 @@
 
   inline bool subset (hb_subset_plan_t *plan) const
   {
-    hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_maxp));
+    hb_blob_t *maxp_blob = hb_sanitize_context_t().reference_table<maxp> (plan->source);
     hb_blob_t *maxp_prime_blob = hb_blob_copy_writable_or_fail (maxp_blob);
     hb_blob_destroy (maxp_blob);
 
@@ -107,7 +107,7 @@
     if (unlikely (!maxp_prime_blob)) {
       return false;
     }
-    OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr);
+    maxp *maxp_prime = (maxp *) hb_blob_get_data (maxp_prime_blob, nullptr);
 
     maxp_prime->set_num_glyphs (plan->glyphs.len);
     if (plan->drop_hints)
@@ -118,7 +118,7 @@
     return result;
   }
 
-  static inline void drop_hint_fields (hb_subset_plan_t *plan, OT::maxp *maxp_prime)
+  static inline void drop_hint_fields (hb_subset_plan_t *plan, maxp *maxp_prime)
   {
     if (maxp_prime->version.major == 1)
     {

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -51,12 +51,12 @@
 
   inline bool subset (hb_subset_plan_t *plan) const
   {
-    hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_os2));
+    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);
 
-    OT::os2 *os2_prime = (OT::os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr);
+    os2 *os2_prime = (os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr);
     if (unlikely (!os2_prime)) {
       hb_blob_destroy (os2_prime_blob);
       return false;

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -85,7 +85,7 @@
   inline bool subset (hb_subset_plan_t *plan) const
   {
     unsigned int post_prime_length;
-    hb_blob_t *post_blob = OT::Sanitizer<post>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_post));
+    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);
     post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
     hb_blob_destroy (post_blob);
@@ -110,7 +110,7 @@
     {
       index_to_offset.init ();
 
-      blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post));
+      blob = hb_sanitize_context_t().reference_table<post> (face);
       const post *table = blob->as<post> ();
       unsigned int table_length = blob->length;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -300,7 +300,9 @@
   0x0CB0u, /* Kannada */
   0x0D30u, /* Malayalam */	/* No Reph, Logical Repha */
 
-  0x0DBBu, /* Sinhala */		/* Reph formed only with ZWJ */
+  0x0DBBu, /* Sinhala */	/* Reph formed only with ZWJ */
+
+  0x179Au, /* Khmer */
 };
 
 static inline bool

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -251,10 +251,10 @@
 {
   ASSERT_POD ();
 
-  inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
+  inline bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
   {
-    hb_codepoint_t glyph = virama_glyph;
-    if (unlikely (virama_glyph == (hb_codepoint_t) -1))
+    hb_codepoint_t glyph = virama_glyph.get_relaxed ();
+    if (unlikely (glyph == (hb_codepoint_t) -1))
     {
       if (!config->virama || !font->get_nominal_glyph (config->virama, &glyph))
 	glyph = 0;
@@ -262,8 +262,8 @@
        * Maybe one day... */
 
       /* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph
-       * during shape planning...  Instead, overwrite it here.  It's safe.  Don't worry! */
-      virama_glyph = glyph;
+       * during shape planning...  Instead, overwrite it here. */
+      virama_glyph.set_relaxed ((int) glyph);
     }
 
     *pglyph = glyph;
@@ -273,7 +273,7 @@
   const indic_config_t *config;
 
   bool is_old_spec;
-  mutable hb_codepoint_t virama_glyph;
+  mutable hb_atomic_int_t virama_glyph;
 
   would_substitute_feature_t rphf;
   would_substitute_feature_t pref;
@@ -298,7 +298,7 @@
     }
 
   indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
-  indic_plan->virama_glyph = (hb_codepoint_t) -1;
+  indic_plan->virama_glyph.set_relaxed (-1);
 
   /* Use zero-context would_substitute() matching for new-spec of the main
    * Indic scripts, and scripts with one spec only, but not for old-specs.
@@ -419,7 +419,7 @@
     return;
 
   hb_codepoint_t virama;
-  if (indic_plan->get_virama_glyph (font, &virama))
+  if (indic_plan->load_virama_glyph (font, &virama))
   {
     hb_face_t *face = font->face;
     unsigned int count = buffer->len;
@@ -667,10 +667,10 @@
    * last consonant.
    *
    * Reports suggest that in some scripts Uniscribe does this only if there
-   * is *not* a Halant after last consonant already (eg. Kannada), while it
-   * does it unconditionally in other scripts (eg. Malayalam, Bengali).  We
-   * don't currently know about other scripts, so we whitelist Malayalam and
-   * Bengali for now.
+   * is *not* a Halant after last consonant already.  We know that is the
+   * case for Kannada, while it reorders unconditionally in other scripts,
+   * eg. Malayalam, Bengali, and Devanagari.  We don't currently know about
+   * other scripts, so we blacklist Kannada.
    *
    * Kannada test case:
    * U+0C9A,U+0CCD,U+0C9A,U+0CCD
@@ -681,15 +681,19 @@
    * U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D
    * With lohit-ttf-20121122/Lohit-Malayalam.ttf
    *
-   * Bengali test case
+   * Bengali test case:
    * U+0998,U+09CD,U+09AF,U+09CD
    * With Windows XP vrinda.ttf
    * https://github.com/harfbuzz/harfbuzz/issues/1073
+   *
+   * Devanagari test case:
+   * U+091F,U+094D,U+0930,U+094D
+   * With chandas.ttf
+   * https://github.com/harfbuzz/harfbuzz/issues/1071
    */
   if (indic_plan->is_old_spec)
   {
-    bool disallow_double_halants = buffer->props.script != HB_SCRIPT_MALAYALAM &&
-				   buffer->props.script != HB_SCRIPT_BENGALI;
+    bool disallow_double_halants = buffer->props.script == HB_SCRIPT_KANNADA;
     for (unsigned int i = base + 1; i < end; i++)
       if (info[i].indic_category() == OT_H)
       {
@@ -1036,9 +1040,11 @@
    * phase, and that might have messed up our properties.  Recover
    * from a particular case of that where we're fairly sure that a
    * class of OT_H is desired but has been lost. */
-  if (indic_plan->virama_glyph)
+  /* We don't call load_virama_glyph(), since we know it's already
+   * loaded. */
+  hb_codepoint_t virama_glyph = indic_plan->virama_glyph.get_relaxed ();
+  if (virama_glyph)
   {
-    unsigned int virama_glyph = indic_plan->virama_glyph;
     for (unsigned int i = start; i < end; i++)
       if (info[i].codepoint == virama_glyph &&
 	  _hb_glyph_info_ligated (&info[i]) &&

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-khmer.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -42,7 +42,7 @@
 {
   /*
    * Basic features.
-   * These features are applied in order, one at a time, after initial_reordering.
+   * These features are applied in order, one at a time, after reordering.
    */
   {HB_TAG('p','r','e','f'), F_NONE},
   {HB_TAG('b','l','w','f'), F_NONE},
@@ -51,9 +51,7 @@
   {HB_TAG('c','f','a','r'), F_NONE},
   /*
    * Other features.
-   * These features are applied all at once, after final_reordering.
-   * Default Bengali font in Windows for example has intermixed
-   * lookups for init,pres,abvs,blws features.
+   * These features are applied all at once.
    */
   {HB_TAG('p','r','e','s'), F_GLOBAL},
   {HB_TAG('a','b','v','s'), F_GLOBAL},
@@ -92,14 +90,10 @@
 		 hb_font_t *font,
 		 hb_buffer_t *buffer);
 static void
-initial_reordering (const hb_ot_shape_plan_t *plan,
-		    hb_font_t *font,
-		    hb_buffer_t *buffer);
+reorder (const hb_ot_shape_plan_t *plan,
+	 hb_font_t *font,
+	 hb_buffer_t *buffer);
 static void
-final_reordering (const hb_ot_shape_plan_t *plan,
-		  hb_font_t *font,
-		  hb_buffer_t *buffer);
-static void
 clear_syllables (const hb_ot_shape_plan_t *plan,
 		 hb_font_t *font,
 		 hb_buffer_t *buffer);
@@ -111,20 +105,28 @@
 
   /* Do this before any lookups have been applied. */
   map->add_gsub_pause (setup_syllables);
+  map->add_gsub_pause (reorder);
 
+  /* Testing suggests that Uniscribe does NOT pause between basic
+   * features.  Test with KhmerUI.ttf and the following three
+   * sequences:
+   *
+   *   U+1789,U+17BC
+   *   U+1789,U+17D2,U+1789
+   *   U+1789,U+17D2,U+1789,U+17BC
+   *
+   * https://github.com/harfbuzz/harfbuzz/issues/974
+   */
   map->add_global_bool_feature (HB_TAG('l','o','c','l'));
-  /* The Indic specs do not require ccmp, but we apply it here since if
-   * there is a use of it, it's typically at the beginning. */
   map->add_global_bool_feature (HB_TAG('c','c','m','p'));
 
-
   unsigned int i = 0;
-  map->add_gsub_pause (initial_reordering);
   for (; i < KHMER_BASIC_FEATURES; i++) {
     map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
-    map->add_gsub_pause (nullptr);
   }
-  map->add_gsub_pause (final_reordering);
+
+  map->add_gsub_pause (clear_syllables);
+
   for (; i < KHMER_NUM_FEATURES; i++) {
     map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
   }
@@ -132,7 +134,6 @@
   map->add_global_bool_feature (HB_TAG('c','a','l','t'));
   map->add_global_bool_feature (HB_TAG('c','l','i','g'));
 
-  map->add_gsub_pause (clear_syllables);
 }
 
 static void
@@ -264,163 +265,59 @@
     buffer->unsafe_to_break (start, end);
 }
 
-static int
-compare_khmer_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
-{
-  int a = pa->khmer_position();
-  int b = pb->khmer_position();
 
-  return a < b ? -1 : a == b ? 0 : +1;
-}
-
-
 /* Rules from:
  * https://docs.microsoft.com/en-us/typography/script-development/devanagari */
 
 static void
-initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
-				       hb_face_t *face,
-				       hb_buffer_t *buffer,
-				       unsigned int start, unsigned int end)
+reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
+			    hb_face_t *face,
+			    hb_buffer_t *buffer,
+			    unsigned int start, unsigned int end)
 {
   const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data;
   hb_glyph_info_t *info = buffer->info;
 
-  /* 1. Khmer shaping assumes that a syllable will begin with a Cons, IndV, or Number. */
-
-  /* The first consonant is always the base. */
-  unsigned int base = start;
-  info[base].khmer_position() = POS_BASE_C;
-
-  /* Mark all subsequent consonants as below. */
-  for (unsigned int i = base + 1; i < end; i++)
-    if (is_consonant_or_vowel (info[i]))
-      info[i].khmer_position() = POS_BELOW_C;
-
-  /* Mark final consonants.  A final consonant is one appearing after a matra,
-   * like in Khmer. */
-  for (unsigned int i = base + 1; i < end; i++)
-    if (info[i].khmer_category() == OT_M) {
-      for (unsigned int j = i + 1; j < end; j++)
-        if (is_consonant_or_vowel (info[j])) {
-	  info[j].khmer_position() = POS_FINAL_C;
-	  break;
-	}
-      break;
-    }
-
-  /* Attach misc marks to previous char to move with them. */
+  /* Setup masks. */
   {
-    khmer_position_t last_pos = POS_START;
-    for (unsigned int i = start; i < end; i++)
-    {
-      if ((FLAG_UNSAFE (info[i].khmer_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_Coeng))))
-      {
-	info[i].khmer_position() = last_pos;
-	if (unlikely (info[i].khmer_category() == OT_Coeng &&
-		      info[i].khmer_position() == POS_PRE_M))
-	{
-	  /*
-	   * Uniscribe doesn't move the Halant with Left Matra.
-	   * TEST: U+092B,U+093F,U+094DE
-	   * We follow.  This is important for the Sinhala
-	   * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA
-	   * where U+0DD9 is a left matra and U+0DCA is the virama.
-	   * We don't want to move the virama with the left matra.
-	   * TEST: U+0D9A,U+0DDA
-	   */
-	  for (unsigned int j = i; j > start; j--)
-	    if (info[j - 1].khmer_position() != POS_PRE_M) {
-	      info[i].khmer_position() = info[j - 1].khmer_position();
-	      break;
-	    }
-	}
-      } else if (info[i].khmer_position() != POS_SMVD) {
-        last_pos = (khmer_position_t) info[i].khmer_position();
-      }
-    }
+    /* Post-base */
+    hb_mask_t mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF];
+    for (unsigned int i = start + 1; i < end; i++)
+      info[i].mask  |= mask;
   }
-  /* For post-base consonants let them own anything before them
-   * since the last consonant or matra. */
-  {
-    unsigned int last = base;
-    for (unsigned int i = base + 1; i < end; i++)
-      if (is_consonant_or_vowel (info[i]))
-      {
-	for (unsigned int j = last + 1; j < i; j++)
-	  if (info[j].khmer_position() < POS_SMVD)
-	    info[j].khmer_position() = info[i].khmer_position();
-	last = i;
-      } else if (info[i].khmer_category() == OT_M)
-        last = i;
-  }
 
+  unsigned int num_coengs = 0;
+  for (unsigned int i = start + 1; i < end; i++)
   {
-    /* Use syllable() for sort accounting temporarily. */
-    unsigned int syllable = info[start].syllable();
-    for (unsigned int i = start; i < end; i++)
-      info[i].syllable() = i - start;
+    /* """
+     * When a COENG + (Cons | IndV) combination are found (and subscript count
+     * is less than two) the character combination is handled according to the
+     * subscript type of the character following the COENG.
+     *
+     * ...
+     *
+     * Subscript Type 2 - The COENG + RO characters are reordered to immediately
+     * before the base glyph. Then the COENG + RO characters are assigned to have
+     * the 'pref' OpenType feature applied to them.
+     * """
+     */
+    if (info[i].khmer_category() == OT_Coeng && num_coengs <= 2 && i + 1 < end)
+    {
+      num_coengs++;
 
-    /* Sit tight, rock 'n roll! */
-    hb_stable_sort (info + start, end - start, compare_khmer_order);
-    /* Find base again */
-    base = end;
-    for (unsigned int i = start; i < end; i++)
-      if (info[i].khmer_position() == POS_BASE_C)
+      if (info[i + 1].khmer_category() == OT_Ra)
       {
-	base = i;
-	break;
-      }
+	for (unsigned int j = 0; j < 2; j++)
+	  info[i + j].mask |= khmer_plan->mask_array[PREF];
 
-    if (unlikely (end - start >= 127))
-      buffer->merge_clusters (start, end);
-    else
-      /* Note!  syllable() is a one-byte field. */
-      for (unsigned int i = base; i < end; i++)
-	if (info[i].syllable() != 255)
-	{
-	  unsigned int max = i;
-	  unsigned int j = start + info[i].syllable();
-	  while (j != i)
-	  {
-	    max = MAX (max, j);
-	    unsigned int next = start + info[j].syllable();
-	    info[j].syllable() = 255; /* So we don't process j later again. */
-	    j = next;
-	  }
-	  if (i != max)
-	    buffer->merge_clusters (i, max + 1);
-	}
+	/* Move the Coeng,Ro sequence to the start. */
+	buffer->merge_clusters (start, i + 2);
+	hb_glyph_info_t t0 = info[i];
+	hb_glyph_info_t t1 = info[i + 1];
+	memmove (&info[start + 2], &info[start], (i - start) * sizeof (info[0]));
+	info[start] = t0;
+	info[start + 1] = t1;
 
-    /* Put syllable back in. */
-    for (unsigned int i = start; i < end; i++)
-      info[i].syllable() = syllable;
-  }
-
-  /* Setup masks now */
-
-  {
-    hb_mask_t mask;
-
-    /* Post-base */
-    mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF];
-    for (unsigned int i = base + 1; i < end; i++)
-      info[i].mask  |= mask;
-  }
-
-  unsigned int pref_len = 2;
-  if (khmer_plan->mask_array[PREF] && base + pref_len < end)
-  {
-    /* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */
-    for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
-      hb_codepoint_t glyphs[2];
-      for (unsigned int j = 0; j < pref_len; j++)
-        glyphs[j] = info[i + j].codepoint;
-      if (khmer_plan->pref.would_substitute (glyphs, pref_len, face))
-      {
-	for (unsigned int j = 0; j < pref_len; j++)
-	  info[i++].mask |= khmer_plan->mask_array[PREF];
-
 	/* Mark the subsequent stuff with 'cfar'.  Used in Khmer.
 	 * Read the feature spec.
 	 * This allows distinguishing the following cases with MS Khmer fonts:
@@ -428,12 +325,22 @@
 	 * U+1784,U+17D2,U+1782,U+17D2,U+179A
 	 */
 	if (khmer_plan->mask_array[CFAR])
-	  for (; i < end; i++)
-	    info[i].mask |= khmer_plan->mask_array[CFAR];
+	  for (unsigned int j = i + 2; j < end; j++)
+	    info[j].mask |= khmer_plan->mask_array[CFAR];
 
-	break;
+	num_coengs = 2; /* Done. */
       }
     }
+
+    /* Reorder left matra piece. */
+    else if (info[i].khmer_position() == POS_PRE_M)
+    {
+      /* Move to the start. */
+      buffer->merge_clusters (start, i + 1);
+      hb_glyph_info_t t = info[i];
+      memmove (&info[start + 1], &info[start], (i - start) * sizeof (info[0]));
+      info[start] = t;
+    }
   }
 }
 
@@ -448,7 +355,7 @@
   {
     case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
     case consonant_syllable:
-     initial_reordering_consonant_syllable (plan, face, buffer, start, end);
+     reorder_consonant_syllable (plan, face, buffer, start, end);
      break;
 
     case non_khmer_cluster:
@@ -518,263 +425,26 @@
 }
 
 static void
-initial_reordering (const hb_ot_shape_plan_t *plan,
-		    hb_font_t *font,
-		    hb_buffer_t *buffer)
+reorder (const hb_ot_shape_plan_t *plan,
+	 hb_font_t *font,
+	 hb_buffer_t *buffer)
 {
   insert_dotted_circles (plan, font, buffer);
 
   foreach_syllable (buffer, start, end)
     initial_reordering_syllable (plan, font->face, buffer, start, end);
-}
 
-static void
-final_reordering_syllable (const hb_ot_shape_plan_t *plan,
-			   hb_buffer_t *buffer,
-			   unsigned int start, unsigned int end)
-{
-  const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data;
-  hb_glyph_info_t *info = buffer->info;
-
-
-  /* This function relies heavily on halant glyphs.  Lots of ligation
-   * and possibly multiple substitutions happened prior to this
-   * phase, and that might have messed up our properties.  Recover
-   * from a particular case of that where we're fairly sure that a
-   * class of OT_Coeng is desired but has been lost. */
-  if (khmer_plan->virama_glyph)
-  {
-    unsigned int virama_glyph = khmer_plan->virama_glyph;
-    for (unsigned int i = start; i < end; i++)
-      if (info[i].codepoint == virama_glyph &&
-	  _hb_glyph_info_ligated (&info[i]) &&
-	  _hb_glyph_info_multiplied (&info[i]))
-      {
-        /* This will make sure that this glyph passes is_coeng() test. */
-	info[i].khmer_category() = OT_Coeng;
-	_hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
-      }
-  }
-
-
-  /* 4. Final reordering:
-   *
-   * After the localized forms and basic shaping forms GSUB features have been
-   * applied (see below), the shaping engine performs some final glyph
-   * reordering before applying all the remaining font features to the entire
-   * syllable.
-   */
-
-  bool try_pref = !!khmer_plan->mask_array[PREF];
-
-  /* Find base again */
-  unsigned int base;
-  for (base = start; base < end; base++)
-    if (info[base].khmer_position() >= POS_BASE_C)
-    {
-      if (try_pref && base + 1 < end)
-      {
-	for (unsigned int i = base + 1; i < end; i++)
-	  if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0)
-	  {
-	    if (!(_hb_glyph_info_substituted (&info[i]) &&
-		  _hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
-	    {
-	      /* Ok, this was a 'pref' candidate but didn't form any.
-	       * Base is around here... */
-	      base = i;
-	      while (base < end && is_coeng (info[base]))
-		base++;
-	      info[base].khmer_position() = POS_BASE_C;
-
-	      try_pref = false;
-	    }
-	    break;
-	  }
-      }
-
-      if (start < base && info[base].khmer_position() > POS_BASE_C)
-        base--;
-      break;
-    }
-  if (base == end && start < base &&
-      is_one_of (info[base - 1], FLAG (OT_ZWJ)))
-    base--;
-  if (base < end)
-    while (start < base &&
-	   is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_Coeng))))
-      base--;
-
-
-  /*   o Reorder matras:
-   *
-   *     If a pre-base matra character had been reordered before applying basic
-   *     features, the glyph can be moved closer to the main consonant based on
-   *     whether half-forms had been formed. Actual position for the matra is
-   *     defined as “after last standalone halant glyph, after initial matra
-   *     position and before the main consonant”. If ZWJ or ZWNJ follow this
-   *     halant, position is moved after it.
-   */
-
-  if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */
-  {
-    /* If we lost track of base, alas, position before last thingy. */
-    unsigned int new_pos = base == end ? base - 2 : base - 1;
-
-    while (new_pos > start &&
-	   !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_Coeng)))))
-      new_pos--;
-
-    /* If we found no Halant we are done.
-     * Otherwise only proceed if the Halant does
-     * not belong to the Matra itself! */
-    if (is_coeng (info[new_pos]) &&
-	info[new_pos].khmer_position() != POS_PRE_M)
-    {
-      /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
-      if (new_pos + 1 < end && is_joiner (info[new_pos + 1]))
-	new_pos++;
-    }
-    else
-      new_pos = start; /* No move. */
-
-    if (start < new_pos && info[new_pos].khmer_position () != POS_PRE_M)
-    {
-      /* Now go see if there's actually any matras... */
-      for (unsigned int i = new_pos; i > start; i--)
-	if (info[i - 1].khmer_position () == POS_PRE_M)
-	{
-	  unsigned int old_pos = i - 1;
-	  if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */
-	    base--;
-
-	  hb_glyph_info_t tmp = info[old_pos];
-	  memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0]));
-	  info[new_pos] = tmp;
-
-	  /* Note: this merge_clusters() is intentionally *after* the reordering.
-	   * Indic matra reordering is special and tricky... */
-	  buffer->merge_clusters (new_pos, MIN (end, base + 1));
-
-	  new_pos--;
-	}
-    } else {
-      for (unsigned int i = start; i < base; i++)
-	if (info[i].khmer_position () == POS_PRE_M) {
-	  buffer->merge_clusters (i, MIN (end, base + 1));
-	  break;
-	}
-    }
-  }
-
-
-  /*   o Reorder pre-base-reordering consonants:
-   *
-   *     If a pre-base-reordering consonant is found, reorder it according to
-   *     the following rules:
-   */
-
-  if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */
-  {
-    for (unsigned int i = base + 1; i < end; i++)
-      if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0)
-      {
-	/*       1. Only reorder a glyph produced by substitution during application
-	 *          of the <pref> feature. (Note that a font may shape a Ra consonant with
-	 *          the feature generally but block it in certain contexts.)
-	 */
-        /* Note: We just check that something got substituted.  We don't check that
-	 * the <pref> feature actually did it...
-	 *
-	 * Reorder pref only if it ligated. */
-	if (_hb_glyph_info_ligated_and_didnt_multiply (&info[i]))
-	{
-	  /*
-	   *       2. Try to find a target position the same way as for pre-base matra.
-	   *          If it is found, reorder pre-base consonant glyph.
-	   *
-	   *       3. If position is not found, reorder immediately before main
-	   *          consonant.
-	   */
-
-	  unsigned int new_pos = base;
-	  while (new_pos > start &&
-		 !(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_Coeng))))
-	    new_pos--;
-
-	  /* In Khmer coeng model, a H,Ra can go *after* matras.  If it goes after a
-	   * split matra, it should be reordered to *before* the left part of such matra. */
-	  if (new_pos > start && info[new_pos - 1].khmer_category() == OT_M)
-	  {
-	    unsigned int old_pos = i;
-	    for (unsigned int j = base + 1; j < old_pos; j++)
-	      if (info[j].khmer_category() == OT_M)
-	      {
-		new_pos--;
-		break;
-	      }
-	  }
-
-	  if (new_pos > start && is_coeng (info[new_pos - 1]))
-	  {
-	    /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
-	    if (new_pos < end && is_joiner (info[new_pos]))
-	      new_pos++;
-	  }
-
-	  {
-	    unsigned int old_pos = i;
-
-	    buffer->merge_clusters (new_pos, old_pos + 1);
-	    hb_glyph_info_t tmp = info[old_pos];
-	    memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0]));
-	    info[new_pos] = tmp;
-
-	    if (new_pos <= base && base < old_pos)
-	      base++;
-	  }
-	}
-
-        break;
-      }
-  }
-
-
-  /*
-   * Finish off the clusters and go home!
-   */
-  if (hb_options ().uniscribe_bug_compatible)
-  {
-    /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
-     * This means, half forms are submerged into the main consonant's cluster.
-     * This is unnecessary, and makes cursor positioning harder, but that's what
-     * Uniscribe does. */
-    buffer->merge_clusters (start, end);
-  }
-}
-
-
-static void
-final_reordering (const hb_ot_shape_plan_t *plan,
-		  hb_font_t *font HB_UNUSED,
-		  hb_buffer_t *buffer)
-{
-  unsigned int count = buffer->len;
-  if (unlikely (!count)) return;
-
-  foreach_syllable (buffer, start, end)
-    final_reordering_syllable (plan, buffer, start, end);
-
   HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
   HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_position);
 }
 
-
 static void
 clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
 		 hb_font_t *font HB_UNUSED,
 		 hb_buffer_t *buffer)
 {
+  /* TODO: In USE, we clear syllables right after reorder.  Figure out
+   * what Uniscribe does. */
   hb_glyph_info_t *info = buffer->info;
   unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -279,20 +279,7 @@
 	return &_hb_ot_complex_shaper_indic;
 
     case HB_SCRIPT_KHMER:
-      /* A number of Khmer fonts in the wild don't have a 'pref' feature,
-       * and as such won't shape properly via the Indic shaper;
-       * however, they typically have 'liga' / 'clig' features that implement
-       * the necessary "reordering" by means of ligature substitutions.
-       * So we send such pref-less fonts through the generic shaper instead. */
-      if (planner->map.found_script[0] &&
-	  hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
-					      planner->map.script_index[0],
-					      planner->map.language_index[0],
-					      HB_TAG ('p','r','e','f'),
-					      nullptr))
 	return &_hb_ot_complex_shaper_khmer;
-      else
-	return &_hb_ot_complex_shaper_default;
 
     case HB_SCRIPT_MYANMAR:
       if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -510,8 +510,8 @@
 
   /* 11100 */ VMAbv, VMAbv, VMAbv,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11110 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11120 */     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VAbv,  VAbv,
-  /* 11130 */  VAbv,  VBlw,  VBlw,     H,  VAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11120 */     B,     B,     B,     B,     B,     B,     B,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPre,  VBlw,  VAbv,  VAbv,
+  /* 11130 */  VBlw,  VAbv,  VAbv,     H, CMAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11140 */     O,     O,     O,     O,     B,  VPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Mahajani */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -561,25 +561,6 @@
 }
 
 static bool
-decompose_use (const hb_ot_shape_normalize_context_t *c,
-                hb_codepoint_t  ab,
-                hb_codepoint_t *a,
-                hb_codepoint_t *b)
-{
-  switch (ab)
-  {
-    /* Chakma:
-     * Special case where the Unicode decomp gives matras in the wrong order
-     * for cluster validation.
-     */
-    case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true;
-    case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true;
-  }
-
-  return (bool) c->unicode->decompose (ab, a, b);
-}
-
-static bool
 compose_use (const hb_ot_shape_normalize_context_t *c,
 	     hb_codepoint_t  a,
 	     hb_codepoint_t  b,
@@ -602,7 +583,7 @@
   nullptr, /* preprocess_text */
   nullptr, /* postprocess_glyphs */
   HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
-  decompose_use,
+  nullptr, /* decompose */
   compose_use,
   setup_masks_use,
   nullptr, /* disable_otl */

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -41,7 +41,7 @@
 #include "hb-set-private.hh"
 
 #include "hb-ot-layout-gsubgpos-private.hh"
-//#include "hb-aat-layout-private.hh"
+#include "hb-aat-layout-private.hh"
 
 static hb_tag_t common_features[] = {
   HB_TAG('c','c','m','p'),
@@ -194,7 +194,10 @@
   if (plan->shaper->data_create) {
     plan->data = plan->shaper->data_create (plan);
     if (unlikely (!plan->data))
+    {
+      free (plan);
       return nullptr;
+    }
   }
 
   return plan;
@@ -623,8 +626,8 @@
 
   c->plan->substitute (c->font, buffer);
 
-  /* XXX Call morx instead. */
-  //hb_aat_layout_substitute (c->font, c->buffer);
+  if (0) /* XXX Call morx instead. */
+    hb_aat_layout_substitute (c->font, c->buffer);
 }
 
 static inline void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -161,8 +161,12 @@
 #ifndef HB_INTERNAL
 # if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC)
 #  define HB_INTERNAL __attribute__((__visibility__("hidden")))
-# else
+# elif defined(__MINGW32__)
+   /* We use -export-symbols on mingw32, since it does not support visibility
+    * attribute. */
 #  define HB_INTERNAL
+#else
+#  define HB_INTERNAL
 #  define HB_NO_VISIBILITY 1
 # endif
 #endif
@@ -375,16 +379,8 @@
 
 #define HB_NULL_POOL_SIZE 264
 
-#ifdef HB_NO_VISIBILITY
-static
-#else
 extern HB_INTERNAL
-#endif
-hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]
-#ifdef HB_NO_VISIBILITY
-= {}
-#endif
-;
+hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
 
 /* Generic nul-content Null objects. */
 template <typename Type>
@@ -413,16 +409,8 @@
  * for correct operation. It only exist to catch and divert program logic bugs instead of
  * causing bad memory access. So, races there are not actually introducing incorrectness
  * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */
-#ifdef HB_NO_VISIBILITY
-static
-#else
 extern HB_INTERNAL
-#endif
-/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]
-#ifdef HB_NO_VISIBILITY
-= {}
-#endif
-;
+/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
 
 /* CRAP pool: Common Region for Access Protection. */
 template <typename Type>
@@ -537,34 +525,6 @@
 #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
 
 
-/* Global runtime options. */
-
-struct hb_options_t
-{
-  unsigned int initialized : 1;
-  unsigned int uniscribe_bug_compatible : 1;
-};
-
-union hb_options_union_t {
-  unsigned int i;
-  hb_options_t opts;
-};
-static_assert ((sizeof (int) == sizeof (hb_options_union_t)), "");
-
-HB_INTERNAL void
-_hb_options_init (void);
-
-extern HB_INTERNAL hb_options_union_t _hb_options;
-
-static inline hb_options_t
-hb_options (void)
-{
-  if (unlikely (!_hb_options.i))
-    _hb_options_init ();
-
-  return _hb_options.opts;
-}
-
 /* Size signifying variable-sized array */
 #define VAR 1
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-private.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-private.hh	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-private.hh	2018-08-02 22:27:18 UTC (rev 48337)
@@ -49,21 +49,10 @@
 _hb_shapers_get (void);
 
 
-/* For embedding in face / font / ... */
-struct hb_shaper_data_t {
-#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-};
-
-#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
-
 /* Means: succeeded, but don't need to keep any data. */
 #define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
-
 /* Means: tried but failed to create. */
 #define HB_SHAPER_DATA_INVALID ((void *) -1)
-#define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID)
 
 #define HB_SHAPER_DATA_TYPE_NAME(shaper, object)	hb_##shaper##_shaper_##object##_data_t
 #define HB_SHAPER_DATA_TYPE(shaper, object)		struct HB_SHAPER_DATA_TYPE_NAME(shaper, object)
@@ -97,6 +86,10 @@
   retry: \
   HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \
   if (likely (data) && !(condition)) { \
+    /* 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. */ \
     /* Drop and recreate. */ \
     /* If someone dropped it in the mean time, throw it away and don't touch it. \
      * Otherwise, destruct it. */ \
@@ -117,8 +110,17 @@
       goto retry; \
     } \
   } \
-  return data != nullptr && !HB_SHAPER_DATA_IS_INVALID (data); \
+  return data != nullptr && (void *) data != HB_SHAPER_DATA_INVALID; \
 }
 
 
+/* For embedding in face / font / ... */
+struct hb_shaper_data_t {
+#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+};
+#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
+
+
 #endif /* HB_SHAPER_PRIVATE_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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -25,8 +25,34 @@
  */
 
 #include "hb-private.hh"
+#include "hb-face-private.hh"
+#include "hb-open-type-private.hh"
+#include "hb-ot-head-table.hh"
+#include "hb-ot-maxp-table.hh"
 
 #ifndef HB_NO_VISIBILITY
+
 hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {};
 /*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {};
+
+void
+hb_face_t::load_num_glyphs (void) const
+{
+  OT::hb_sanitize_context_t c = OT::hb_sanitize_context_t();
+  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 ();
+  hb_blob_destroy (maxp_blob);
+}
+
+void
+hb_face_t::load_upem (void) const
+{
+  hb_blob_t *head_blob = OT::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);
+}
+
 #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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -292,7 +292,7 @@
                          hb_blob_t       **glyf_prime, /* OUT */
                          hb_blob_t       **loca_prime /* OUT */)
 {
-  hb_blob_t *glyf_blob = OT::Sanitizer<OT::glyf>().sanitize (plan->source->reference_table (HB_OT_TAG_glyf));
+  hb_blob_t *glyf_blob = OT::hb_sanitize_context_t().reference_table<OT::glyf> (plan->source);
   const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr);
 
   OT::glyf::accelerator_t glyf;

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-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -56,11 +56,15 @@
 static void
 _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
 {
-  // TODO(grieger): This uses all lookups, instead collect
-  //                the set of lookups that are relevant.
-  //                See fontTools implementation.
+  hb_auto_t<hb_set_t> lookup_indices;
+  hb_ot_layout_collect_lookups (face,
+                                HB_OT_TAG_GSUB,
+                                nullptr,
+                                nullptr,
+                                nullptr,
+                                &lookup_indices);
   hb_ot_layout_lookups_substitute_closure (face,
-                                           nullptr,
+                                           &lookup_indices,
                                            gids_to_retain);
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -78,9 +78,7 @@
 static bool
 _subset (hb_subset_plan_t *plan)
 {
-  OT::Sanitizer<TableType> sanitizer;
-
-  hb_blob_t *source_blob = sanitizer.sanitize (plan->source->reference_table (TableType::tableTag));
+  hb_blob_t *source_blob = OT::hb_sanitize_context_t().reference_table<TableType> (plan->source);
   const TableType *table = source_blob->as<TableType> ();
 
   hb_tag_t tag = TableType::tableTag;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -358,7 +358,7 @@
    * full, PS. All of them point to the same name data with our unique name.
    */
 
-  blob = OT::Sanitizer<OT::OpenTypeFontFile>().sanitize (blob);
+  blob = OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (blob);
 
   unsigned int length, new_length, name_str_len;
   const char *orig_sfnt_data = hb_blob_get_data (blob, &length);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2018-08-02 22:27:18 UTC (rev 48337)
@@ -51,8 +51,7 @@
   const char *font_data = hb_blob_get_data (blob, &len);
   printf ("Opened font file %s: %d bytes long\n", argv[1], len);
 
-  Sanitizer<OpenTypeFontFile> sanitizer;
-  hb_blob_t *font_blob = sanitizer.sanitize (blob);
+  hb_blob_t *font_blob = hb_sanitize_context_t().sanitize_blob<OpenTypeFontFile> (blob);
   const OpenTypeFontFile* sanitized = font_blob->as<OpenTypeFontFile> ();
   if (sanitized == &Null(OpenTypeFontFile))
   {

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2018-08-02 21:40:10 UTC (rev 48336)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2018-08-02 22:27:18 UTC (rev 48337)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [1.8.4])
+m4_define([harfbuzz_version], [1.8.5])



More information about the tex-live-commits mailing list